diff --git a/.github/workflows/php-cs-fixer.yml b/.github/workflows/php-cs-fixer.yml new file mode 100644 index 0000000..4f13700 --- /dev/null +++ b/.github/workflows/php-cs-fixer.yml @@ -0,0 +1,23 @@ +name: Check & fix styling + +on: [push,pull_request] + +jobs: + php-cs-fixer: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + with: + ref: ${{ github.head_ref }} + + - name: Run PHP Code Style Fixer + uses: docker://oskarstark/php-cs-fixer-ga + with: + args: --config=.php-cs-fixer.dist.php --allow-risky=yes + + - name: Commit changes + uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: Fix styling diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index cce756c..f80bcd5 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -2,9 +2,9 @@ name: PHP Composer on: push: - branches: [ main ] + branches: [main] pull_request: - branches: [ main ] + branches: [main] jobs: build: @@ -27,9 +27,3 @@ jobs: ${{ runner.os }}-php- - name: Install dependencies run: composer install --prefer-dist --no-progress - - # Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit" - # Docs: https://getcomposer.org/doc/articles/scripts.md - - # - name: Run test suite - # run: composer run-script test diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5ec3375..c4c6394 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -9,13 +9,15 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - php: [8.1, 8.0] - laravel: [8.*] + php: [7.4, 8.0] + laravel: [8.*,7.*] dependency-version: [prefer-stable] include: - - testbench: ^6.23 - laravel: 8.* + - testbench: ^6.23 + laravel: 8.* + - testbench: 5.20 + laravel: 7.* name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} - ${{ matrix.os }} diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml new file mode 100644 index 0000000..fa56639 --- /dev/null +++ b/.github/workflows/update-changelog.yml @@ -0,0 +1,28 @@ +name: "Update Changelog" + +on: + release: + types: [released] + +jobs: + update: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + with: + ref: main + + - name: Update Changelog + uses: stefanzweifel/changelog-updater-action@v1 + with: + latest-version: ${{ github.event.release.name }} + release-notes: ${{ github.event.release.body }} + + - name: Commit updated CHANGELOG + uses: stefanzweifel/git-auto-commit-action@v4 + with: + branch: main + commit_message: Update CHANGELOG + file_pattern: CHANGELOG.md diff --git a/README.md b/README.md index 152ca4f..353a0d0 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ php artisan multi-process:install Features ----------- - [Run process from commands](https://github.com/syrian-open-source/laravel-multi-process/blob/main/docs/commands.md) +- [Run php codes](https://github.com/syrian-open-source/laravel-multi-process/blob/main/docs/php.md) Changelog diff --git a/docs/commands.md b/docs/commands.md index b4261a4..5ac23d7 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -3,26 +3,26 @@ Usage * Define multiple process and execute them by start function. ```shell - $proceses = \SOS\MultiProcess\Facades\MultiProcessFacade::setTasks( + $process = \SOS\MultiProcess\Facades\MultiProcessFacade::setTasks( "php artisan make:model modelName", "php artisan make:model ControllerName", // and you can define unlimited commands ); - $proceses->start(); + $process->start(); ``` * Define multiple process and execute them by run function. ```shell - $proceses = \SOS\MultiProcess\Facades\MultiProcessFacade::setTasks( + $process = \SOS\MultiProcess\Facades\MultiProcessFacade::setTasks( "php artisan make:model modelName", "php artisan make:model ControllerName", // and you can define unlimited commands ); // run function will allows you to get the output from the execution process. - $proceses->run(); + $process->run(); ``` * Add options. @@ -32,7 +32,7 @@ Usage // default options are in multi_process.php file. // you can change them from the file // or you can basicly added them from the setter function. - $proceses = \SOS\MultiProcess\Facades\MultiProcessFacade::setTasks( + $process = \SOS\MultiProcess\Facades\MultiProcessFacade::setTasks( "php artisan make:model modelName", "php artisan make:model ControllerName", // and you can define unlimited commands @@ -41,10 +41,12 @@ Usage 'ideTimeOut' => 60, 'enableOutput' => true, 'processTime' => 3, + + // thorw exceprtion if any task was failed. + 'throwIfTaskNotSuccess' => false, ); // run or start your tasks. - $proceses->start(); + $process->start(); ``` - diff --git a/docs/php.md b/docs/php.md new file mode 100644 index 0000000..bbb9fec --- /dev/null +++ b/docs/php.md @@ -0,0 +1,41 @@ +Usage +-------- +* Define multiple process and execute them by start function, +each task must be a callback function as you can see in the below example. + +```shell + $process = \SOS\MultiProcess\Facades\MultiProcessFacade::setTasks( + function () { + return \Illuminate\Support\Facades\DB::statement('delete from users where id = 5'); + }, function () { + return \Illuminate\Support\Facades\DB::statement('delete from users where id = 6'); + } + ); + $process->runPHP(); +``` +* Add options. + +```shell + + // default options are in multi_process.php file. + // you can change them from the file + // or you can basicly added them from the setter function. + $process = \SOS\MultiProcess\Facades\MultiProcessFacade::setTasks( + "php artisan make:model modelName", + "php artisan make:model ControllerName", + // and you can define unlimited commands + )->setOptions([ + 'timeOut' => 60, + 'ideTimeOut' => 60, + 'enableOutput' => true, + 'processTime' => 3, + + // thorw exceprtion if any task was failed. + 'throwIfTaskNotSuccess' => false, + ); + + // run or start your tasks. + $process->start(); + +``` + diff --git a/src/Classes/MultiProcess.php b/src/Classes/MultiProcess.php index 0c12e02..ec11c46 100644 --- a/src/Classes/MultiProcess.php +++ b/src/Classes/MultiProcess.php @@ -4,6 +4,8 @@ namespace SOS\MultiProcess\Classes; +use Symfony\Component\Process\Exception\ProcessFailedException; +use Symfony\Component\Process\PhpProcess; use Symfony\Component\Process\Process; /** @@ -32,6 +34,7 @@ class MultiProcess 'workingDirectory' => null, 'enableOutput' => true, 'processTime' => 3, + 'throwIfTaskNotSuccess' => false, ]; /** * @@ -165,6 +168,22 @@ public function displayOutputMessage($type, $buffer) } } + /** + * run the php codes + * + * @return \SOS\MultiProcess\Classes\MultiProcess + * @throws \Exception + * @author karam mustafa + */ + public function runPHP() + { + + $this->phpProcess($this->higherOrderRun()); + + $this->resolveNotRunningProcess($this->higherOrderRun()); + + return $this; + } /** * this function will execute run function in symfony component @@ -175,19 +194,9 @@ public function displayOutputMessage($type, $buffer) */ public function run() { - $callback = function (Process $process) { - return $process->run(function ($type, $buffer) { + $this->process($this->higherOrderRun()); - // if we enable the output, then display this message depending on it type. - if ($this->getOptions('enableOutput')) { - $this->displayOutputMessage($type, $buffer); - } - }); - }; - - $this->process($callback); - - $this->resolveNotRunningProcess($callback); + $this->resolveNotRunningProcess($this->higherOrderRun()); return $this; } @@ -213,6 +222,29 @@ public function start() } + /** + * run the php codes from tasks, and each task must be a callback function. + * + * @param $callback + * + * @author karam mustafa + */ + private function phpProcess($callback) + { + while ($task = $this->checkIfCanProcess()) { + + $process = new PhpProcess("getCommandKey()]()} ?>"); + + // Add the process to the processing property + $this->processing[] = $process; + + $callback($process); + + if (!$process->isSuccessful() && $this->getOptions('throwIfTaskNotSuccess')) { + throw new ProcessFailedException($process); + } + } + } /** * this function will set the require config to a symfony process component. @@ -239,6 +271,11 @@ private function process($callback) // this callback could be a start or run function in symfony component // or might be any callback that accept Process parameter as a dependency. $callback($process); + + if (!$process->isSuccessful() && $this->getOptions('throwIfTaskNotSuccess')) { + throw new ProcessFailedException($process); + } + } } @@ -338,4 +375,23 @@ private function checkIfCanProcess() : false; } + /** + * return a callback that execute run function inside process component. + * + * @return \Closure + * @author karam mustafa + */ + private function higherOrderRun() + { + return function (Process $process) { + return $process->run(function ($type, $buffer) { + + // if we enable the output, then display this message depending on it type. + if ($this->getOptions('enableOutput')) { + $this->displayOutputMessage($type, $buffer); + } + }); + }; + } + } diff --git a/src/Facades/MultiProcessFacade.php b/src/Facades/MultiProcessFacade.php index 63f1185..97a05b6 100644 --- a/src/Facades/MultiProcessFacade.php +++ b/src/Facades/MultiProcessFacade.php @@ -11,6 +11,7 @@ * @method MultiProcess setTasks( ...$args) * @method MultiProcess start($callback) * @method MultiProcess run($callback) + * @method MultiProcess runPHP($callback) * @method MultiProcess setOptions($options) */ class MultiProcessFacade extends Facade diff --git a/tests/Feature/PHPTest.php b/tests/Feature/PHPTest.php new file mode 100644 index 0000000..64ce9ae --- /dev/null +++ b/tests/Feature/PHPTest.php @@ -0,0 +1,40 @@ +setTasks( + function () { + echo 'process 1'; + }, + function () { + echo 'process 2'; + }, + function () { + echo 'process 3'; + } + ); + + foreach ($processor->runPHP()->getTasks() as $task) { + $this->assertEquals($task['state'], $completedState); + } + + } +}