diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ff631b0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/.idea +/process.log +/phpcs-report.txt +/composer.lock +/vendor diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..67387a9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,25 @@ +language: php + +php: + - 7.0 + - 7.1 + - 7.2 + - master + +sudo: false + +before_install: + - composer self-update + - composer clear-cache + +install: + - travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest --optimize-autoloader --prefer-stable + +script: + - ./vendor/bin/phpunit --debug + +after_success: + - echo "success!" + +notifications: + email: false diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3900804 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 OSPEK + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..aaec099 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,37 @@ +build: false +shallow_clone: false +platform: 'x86' +clone_folder: C:\projects\ospek +branches: + only: + - windows + +install: + - cinst -y OpenSSL.Light + - SET PATH=C:\Program Files\OpenSSL;%PATH% + - sc config wuauserv start= auto + - net start wuauserv + - cinst -y php + - cd c:\tools\php72 + - copy php.ini-production php.ini + - echo date.timezone="UTC" >> php.ini + - echo extension_dir=ext >> php.ini + - echo extension=php_openssl.dll >> php.ini + - echo mbstring.http_input=pass >> php.ini + - echo mbstring.http_output=pass >> php.ini + - echo sendmail_path=nul >> php.ini + - echo extension=php_mbstring.dll >> php.ini + - echo extension=php_curl.dll >> php.ini + - echo extension=php_pdo_mysql.dll >> php.ini + - echo extension=php_pdo_pgsql.dll >> php.ini + - echo extension=php_pdo_sqlite.dll >> php.ini + - echo extension=php_pgsql.dll >> php.ini + - echo extension=php_gd2.dll >> php.ini + - cd C:\projects\ospek + - SET PATH=C:\tools\php72;%PATH% + - php -r "readfile('http://getcomposer.org/installer');" | php + - php composer.phar install --prefer-source --no-interaction + +test_script: + - cd C:\projects\ospek + - vendor\bin\phpunit.bat --debug \ No newline at end of file diff --git a/asset/icon.png b/asset/icon.png new file mode 100644 index 0000000..1b81d5c Binary files /dev/null and b/asset/icon.png differ diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..75b2eef --- /dev/null +++ b/composer.json @@ -0,0 +1,34 @@ +{ + "name": "ospek/ospek", + "description": "background process", + "keywords": [ + "process", + "background", + "daemon", + "windows", + "Linux", + "osx", + "ospek" + ], + "homepage": "https://os-pek.github.io", + "license": "MIT", + "authors": [ + { + "name": "ospek project", + "email": "os-pek@github.io" + } + ], + "require": { + "php" : ">=7.0.0", + "jolicode/jolinotif": "^2.0" + }, + "minimum-stability": "dev", + "autoload": { + "psr-4": { + "Ospek\\": "src/" + } + }, + "require-dev": { + "phpunit/phpunit": "^7.1@dev|~6.0" + } +} diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..af9c7eb --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,24 @@ + + + + tests + + + + + + + + + + src + + + \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..25735ca --- /dev/null +++ b/readme.md @@ -0,0 +1,7 @@ +[![Build Status](https://travis-ci.org/os-pek/ospek.svg?branch=master)](https://travis-ci.org/os-pek/ospek) + + **Inspired :** + +- [dell_petter ](http://php.net/manual/en/function.exec.php#88704) + +- [composer-client](https://github.com/contao-community-alliance/composer-client) diff --git a/src/OspekBackend.php b/src/OspekBackend.php new file mode 100644 index 0000000..a118570 --- /dev/null +++ b/src/OspekBackend.php @@ -0,0 +1,84 @@ +_command = $cl; + if ($log != null) { + $this->_logFile = $log; + } else { + $this->_logFile = defined('PHP_WINDOWS_VERSION_BUILD')?"NUL":"/dev/null"; + } + $this->_run(); + } + } + private function _run() + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $command = $this->_command.' > '.$this->_logFile; + exec("start /B ".$command." 2>&1"); + } else { + + $command = $this->_command.' > '.$this->_logFile.' 2>&1 & echo $!'; + exec($command, $op); + $this->pid = (int)$op[0]; + } + } + + public function setPid(int $pid) + { + $this->pid = $pid; + } + + public function getPid():int + { + return $this->pid; + } + + public function status():bool + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $process = shell_exec(sprintf('tasklist.exe /FI "PID eq %d" /FO CSV /NH', $this->pid)); + + return in_array($this->pid, str_getcsv($process, ',')); + } + + return (bool) posix_kill($this->pid, 0); + } + + public function start() + { + if ($this->_command !=null) { + $this->_run(); + } + throw new \LengthException("command is empty!"); + } + + public function stop():bool + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + shell_exec(sprintf('taskkill.exe /PID %d', $this->pid)); + return true; + + } else { + + posix_kill($this->pid, SIGTERM); + return true; + } + } + public function getOutput(String $file=null):Array + { + $file = ($file)?$file:$this->_logFile; + if (file_exists($file)) { + return file($file); + } + throw new \RunTimeException("file not found!"); + } +} \ No newline at end of file diff --git a/src/OspekFrontend.php b/src/OspekFrontend.php new file mode 100644 index 0000000..3146b62 --- /dev/null +++ b/src/OspekFrontend.php @@ -0,0 +1,38 @@ +pid = getmypid(); + $this->_notif = ($notif)?true:false; + $this->_joliNotifier = ($notif)?NotifierFactory:: create():false; + } + private function _defaultNotif() + { + $notification = (new Notification())->setTitle('OSPEK')->setBody("process ".$this->pid." has been stopped!")->setIcon(__DIR__ . '/../asset/icon.png')->addOption('sound', 'Frog'); + $this->_joliNotifier->send($notification); + } + public function setNotif(callable $fun) + { + $this->_fun = $fun; + } + + public function __destruct() + { + if ($this->_notif) { + if ($this->_fun!=null) { + ($this->_fun)($this->_joliNotifier, new Notification()); + } else { + $this->_defaultNotif(); + } + } + } +} \ No newline at end of file diff --git a/tests/OspekBackendTest.php b/tests/OspekBackendTest.php new file mode 100644 index 0000000..2dc21aa --- /dev/null +++ b/tests/OspekBackendTest.php @@ -0,0 +1,52 @@ +_ospek = null; + } + + public function testOspekRun() + { + $this->_ospek = new \Ospek\OspekBackend("php tests/loop.php", "process.log"); + sleep(3); + // test getpid() + $this->assertInternalType('int', $this->_ospek->getPid()); + + // test status() + $this->assertTrue($this->_ospek->status()); + + // test getOutput() + $this->assertInternalType('array', $this->_ospek->getOutput()); + + // test stop() + $this->assertTrue($this->_ospek->stop()); + sleep(1); + + // check status after stop + $this->assertFalse($this->_ospek->status()); + // make sure process.log not empty + + $this->assertNotEmpty(file_get_contents("process.log")); + + } + public function testOspekDummy() + { + $this->_ospek = new \Ospek\OspekBackend(); + $this->assertNull($this->_ospek->setPid(1234567)); + $this->assertSame(1234567, $this->_ospek->getPid()); + $this->assertFalse($this->_ospek->status()); + try{ + $this->_ospek->getOutput('fakeeeeeeee/path/file.log'); + } catch(Exception $e){ + $this->assertInstanceOf(RuntimeException::class, $e); + } + + + + } +} + \ No newline at end of file diff --git a/tests/loop.php b/tests/loop.php new file mode 100644 index 0000000..aab210a --- /dev/null +++ b/tests/loop.php @@ -0,0 +1,10 @@ +