pax_global_header 0000666 0000000 0000000 00000000064 13735150555 0014523 g ustar 00root root 0000000 0000000 52 comment=36ad26c3741b6600f12586719bb4082518ca0e9f
php-invoker-3.1.1/ 0000775 0000000 0000000 00000000000 13735150555 0013767 5 ustar 00root root 0000000 0000000 php-invoker-3.1.1/.github/ 0000775 0000000 0000000 00000000000 13735150555 0015327 5 ustar 00root root 0000000 0000000 php-invoker-3.1.1/.github/FUNDING.yml 0000664 0000000 0000000 00000000032 13735150555 0017137 0 ustar 00root root 0000000 0000000 github: sebastianbergmann
php-invoker-3.1.1/.github/workflows/ 0000775 0000000 0000000 00000000000 13735150555 0017364 5 ustar 00root root 0000000 0000000 php-invoker-3.1.1/.github/workflows/ci.yml 0000664 0000000 0000000 00000005212 13735150555 0020502 0 ustar 00root root 0000000 0000000 # https://help.github.com/en/categories/automating-your-workflow-with-github-actions
on:
- "pull_request"
- "push"
name: "CI"
jobs:
coding-guidelines:
name: "Coding Guidelines"
runs-on: "ubuntu-latest"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Run friendsofphp/php-cs-fixer"
run: "php7.3 ./tools/php-cs-fixer fix --diff-format=udiff --dry-run --show-progress=dots --using-cache=no --verbose"
type-checker:
name: "Type Checker"
runs-on: "ubuntu-latest"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Update dependencies with composer"
run: "php7.3 ./tools/composer update --no-ansi --no-interaction --no-progress"
- name: "Run vimeo/psalm"
run: "php7.3 ./tools/psalm --config=psalm.xml --no-progress --shepherd --show-info=false --stats"
backward-compatibility:
name: Backward Compatibility
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Fetch tags
run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- name: Install PHP with extensions
uses: shivammathur/setup-php@v2
with:
php-version: 7.4
coverage: none
extensions: intl
- name: Run roave/backward-compatibility-check
run: ./tools/roave-backward-compatibility-check --from=3.0.0
tests:
name: "Tests"
runs-on: "ubuntu-latest"
strategy:
fail-fast: false
matrix:
php-version:
- "7.3"
- "7.4"
- "8.0"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Install PHP with extensions"
uses: "shivammathur/setup-php@v1"
with:
php-version: "${{ matrix.php-version }}"
coverage: "pcov"
- name: "Cache dependencies installed with composer"
uses: "actions/cache@v1"
with:
path: "~/.composer/cache"
key: "php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }}"
restore-keys: "php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-"
- name: "Install dependencies with composer"
run: "./tools/composer update --no-ansi --no-interaction --no-progress"
- name: "Run tests with phpunit/phpunit"
run: "vendor/bin/phpunit --coverage-clover=coverage.xml"
- name: "Send code coverage report to Codecov.io"
env:
CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}"
run: "bash <(curl -s https://codecov.io/bash) || true"
php-invoker-3.1.1/.gitignore 0000664 0000000 0000000 00000000115 13735150555 0015754 0 ustar 00root root 0000000 0000000 /.idea
/.php_cs
/.php_cs.cache
/.phpunit.result.cache
/composer.lock
/vendor
php-invoker-3.1.1/.phive/ 0000775 0000000 0000000 00000000000 13735150555 0015160 5 ustar 00root root 0000000 0000000 php-invoker-3.1.1/.phive/phars.xml 0000664 0000000 0000000 00000000670 13735150555 0017022 0 ustar 00root root 0000000 0000000
php-invoker-3.1.1/.php_cs.dist 0000664 0000000 0000000 00000017373 13735150555 0016221 0 ustar 00root root 0000000 0000000
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
EOF;
$finder = PhpCsFixer\Finder::create()
->files()
->in(__DIR__ . '/src')
->in(__DIR__ . '/tests');
return PhpCsFixer\Config::create()
->setFinder($finder)
->setRiskyAllowed(true)
->setRules([
'align_multiline_comment' => true,
'array_indentation' => true,
'array_syntax' => ['syntax' => 'short'],
'binary_operator_spaces' => [
'operators' => [
'=' => 'align',
'=>' => 'align',
],
],
'blank_line_after_namespace' => true,
'blank_line_before_statement' => [
'statements' => [
'break',
'continue',
'declare',
'do',
'for',
'foreach',
'if',
'include',
'include_once',
'require',
'require_once',
'return',
'switch',
'throw',
'try',
'while',
'yield',
],
],
'braces' => true,
'cast_spaces' => true,
'class_attributes_separation' => ['elements' => ['const', 'method', 'property']],
'combine_consecutive_issets' => true,
'combine_consecutive_unsets' => true,
'compact_nullable_typehint' => true,
'concat_space' => ['spacing' => 'one'],
'declare_equal_normalize' => ['space' => 'none'],
'declare_strict_types' => true,
'dir_constant' => true,
'elseif' => true,
'encoding' => true,
'full_opening_tag' => true,
'function_declaration' => true,
'global_namespace_import' => [
'import_classes' => true,
'import_constants' => true,
'import_functions' => true,
],
'header_comment' => ['header' => $header, 'separate' => 'none'],
'indentation_type' => true,
'is_null' => true,
'line_ending' => true,
'list_syntax' => ['syntax' => 'short'],
'logical_operators' => true,
'lowercase_cast' => true,
'lowercase_constants' => true,
'lowercase_keywords' => true,
'lowercase_static_reference' => true,
'magic_constant_casing' => true,
'method_argument_space' => ['ensure_fully_multiline' => true],
'modernize_types_casting' => true,
'multiline_comment_opening_closing' => true,
'multiline_whitespace_before_semicolons' => true,
'native_constant_invocation' => false,
'native_function_casing' => false,
'native_function_invocation' => false,
'new_with_braces' => false,
'no_alias_functions' => true,
'no_alternative_syntax' => true,
'no_blank_lines_after_class_opening' => true,
'no_blank_lines_after_phpdoc' => true,
'no_blank_lines_before_namespace' => true,
'no_closing_tag' => true,
'no_empty_comment' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
'no_extra_blank_lines' => true,
'no_homoglyph_names' => true,
'no_leading_import_slash' => true,
'no_leading_namespace_whitespace' => true,
'no_mixed_echo_print' => ['use' => 'print'],
'no_multiline_whitespace_around_double_arrow' => true,
'no_null_property_initialization' => true,
'no_php4_constructor' => true,
'no_short_bool_cast' => true,
'no_short_echo_tag' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_spaces_after_function_name' => true,
'no_spaces_inside_parenthesis' => true,
'no_superfluous_elseif' => true,
'no_superfluous_phpdoc_tags' => [
'allow_mixed' => true,
],
'no_trailing_comma_in_list_call' => true,
'no_trailing_comma_in_singleline_array' => true,
'no_trailing_whitespace' => true,
'no_trailing_whitespace_in_comment' => true,
'no_unneeded_control_parentheses' => true,
'no_unneeded_curly_braces' => true,
'no_unneeded_final_method' => true,
'no_unreachable_default_argument_value' => true,
'no_unset_on_property' => true,
'no_unused_imports' => true,
'no_useless_else' => true,
'no_useless_return' => true,
'no_whitespace_before_comma_in_array' => true,
'no_whitespace_in_blank_line' => true,
'non_printable_character' => true,
'normalize_index_brace' => true,
'object_operator_without_whitespace' => true,
'ordered_class_elements' => [
'order' => [
'use_trait',
'constant_public',
'constant_protected',
'constant_private',
'property_public_static',
'property_protected_static',
'property_private_static',
'property_public',
'property_protected',
'property_private',
'method_public_static',
'construct',
'destruct',
'magic',
'phpunit',
'method_public',
'method_protected',
'method_private',
'method_protected_static',
'method_private_static',
],
],
'ordered_imports' => [
'imports_order' => [
PhpCsFixer\Fixer\Import\OrderedImportsFixer::IMPORT_TYPE_CONST,
PhpCsFixer\Fixer\Import\OrderedImportsFixer::IMPORT_TYPE_FUNCTION,
PhpCsFixer\Fixer\Import\OrderedImportsFixer::IMPORT_TYPE_CLASS,
]
],
'ordered_interfaces' => [
'direction' => 'ascend',
'order' => 'alpha',
],
'phpdoc_add_missing_param_annotation' => false,
'phpdoc_align' => true,
'phpdoc_annotation_without_dot' => true,
'phpdoc_indent' => true,
'phpdoc_no_access' => true,
'phpdoc_no_empty_return' => true,
'phpdoc_no_package' => true,
'phpdoc_order' => true,
'phpdoc_return_self_reference' => true,
'phpdoc_scalar' => true,
'phpdoc_separation' => true,
'phpdoc_single_line_var_spacing' => true,
'phpdoc_summary' => true,
'phpdoc_to_comment' => true,
'phpdoc_trim' => true,
'phpdoc_trim_consecutive_blank_line_separation' => true,
'phpdoc_types' => ['groups' => ['simple', 'meta']],
'phpdoc_types_order' => true,
'phpdoc_var_without_name' => true,
'pow_to_exponentiation' => true,
'protected_to_private' => true,
'return_assignment' => true,
'return_type_declaration' => ['space_before' => 'none'],
'self_accessor' => true,
'semicolon_after_instruction' => true,
'set_type_to_cast' => true,
'short_scalar_cast' => true,
'simplified_null_return' => false,
'single_blank_line_at_eof' => true,
'single_import_per_statement' => true,
'single_line_after_imports' => true,
'single_quote' => true,
'standardize_not_equals' => true,
'ternary_to_null_coalescing' => true,
'trailing_comma_in_multiline_array' => true,
'trim_array_spaces' => true,
'unary_operator_spaces' => true,
'visibility_required' => [
'elements' => [
'const',
'method',
'property',
],
],
'void_return' => true,
'whitespace_after_comma_in_array' => true,
]);
php-invoker-3.1.1/ChangeLog.md 0000664 0000000 0000000 00000002706 13735150555 0016145 0 ustar 00root root 0000000 0000000 # ChangeLog
All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
## [3.1.1] - 2020-09-28
### Changed
* Changed PHP version constraint in `composer.json` from `^7.3 || ^8.0` to `>=7.3`
## [3.1.0] - 2020-08-06
### Changed
* [#14](https://github.com/sebastianbergmann/php-invoker/pull/14): Clear alarm in `finally` block
## [3.0.2] - 2020-06-26
### Added
* This component is now supported on PHP 8
## [3.0.1] - 2020-06-15
### Changed
* Tests etc. are now ignored for archive exports
## [3.0.0] - 2020-02-07
### Added
* Added `canInvokeWithTimeout()` method to check requirements for the functionality provided by this component to work
### Changed
* Moved `"ext-pcntl": "*"` requirement from `require` to `suggest` so that this component can be installed even if `ext/pcntl` is not available
* `invoke()` now raises an exception when the requirements for the functionality provided by this component to work are not met
### Removed
* This component is no longer supported on PHP 7.1 and PHP 7.2
[3.1.1]: https://github.com/sebastianbergmann/php-invoker/compare/3.1.0...3.1.1
[3.1.0]: https://github.com/sebastianbergmann/php-invoker/compare/3.0.2...3.1.0
[3.0.2]: https://github.com/sebastianbergmann/php-invoker/compare/3.0.1...3.0.2
[3.0.1]: https://github.com/sebastianbergmann/php-invoker/compare/3.0.0...3.0.1
[3.0.0]: https://github.com/sebastianbergmann/php-invoker/compare/2.0.0...3.0.0
php-invoker-3.1.1/LICENSE 0000664 0000000 0000000 00000003012 13735150555 0014770 0 ustar 00root root 0000000 0000000 php-invoker
Copyright (c) 2011-2020, Sebastian Bergmann .
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
php-invoker-3.1.1/README.md 0000664 0000000 0000000 00000001306 13735150555 0015246 0 ustar 00root root 0000000 0000000 # phpunit/php-invoker
[](https://github.com/sebastianbergmann/php-invoker/actions)
[](https://shepherd.dev/github/sebastianbergmann/php-invoker)
## Installation
You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
```
composer require phpunit/php-invoker
```
If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
```
composer require --dev phpunit/php-invoker
```
php-invoker-3.1.1/build.xml 0000664 0000000 0000000 00000002054 13735150555 0015611 0 ustar 00root root 0000000 0000000
php-invoker-3.1.1/composer.json 0000664 0000000 0000000 00000002163 13735150555 0016513 0 ustar 00root root 0000000 0000000 {
"name": "phpunit/php-invoker",
"description": "Invoke callables with a timeout",
"type": "library",
"keywords": [
"process"
],
"homepage": "https://github.com/sebastianbergmann/php-invoker/",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-invoker/issues"
},
"prefer-stable": true,
"config": {
"platform": {
"php": "7.3.0"
},
"optimize-autoloader": true,
"sort-packages": true
},
"require": {
"php": ">=7.3"
},
"require-dev": {
"ext-pcntl": "*",
"phpunit/phpunit": "^9.3"
},
"autoload": {
"classmap": [
"src/"
]
},
"autoload-dev": {
"classmap": [
"tests/_fixture/"
]
},
"suggest": {
"ext-pcntl": "*"
},
"extra": {
"branch-alias": {
"dev-master": "3.1-dev"
}
}
}
php-invoker-3.1.1/phpunit.xml 0000664 0000000 0000000 00000001512 13735150555 0016177 0 ustar 00root root 0000000 0000000
tests
src
php-invoker-3.1.1/psalm.xml 0000664 0000000 0000000 00000003555 13735150555 0015635 0 ustar 00root root 0000000 0000000
php-invoker-3.1.1/src/ 0000775 0000000 0000000 00000000000 13735150555 0014556 5 ustar 00root root 0000000 0000000 php-invoker-3.1.1/src/Invoker.php 0000664 0000000 0000000 00000003331 13735150555 0016704 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Invoker;
use const SIGALRM;
use function call_user_func_array;
use function function_exists;
use function pcntl_alarm;
use function pcntl_async_signals;
use function pcntl_signal;
use function sprintf;
use Throwable;
final class Invoker
{
/**
* @var int
*/
private $timeout;
/**
* @throws Throwable
*/
public function invoke(callable $callable, array $arguments, int $timeout)
{
if (!$this->canInvokeWithTimeout()) {
throw new ProcessControlExtensionNotLoadedException(
'The pcntl (process control) extension for PHP is required'
);
}
pcntl_signal(
SIGALRM,
function (): void {
throw new TimeoutException(
sprintf(
'Execution aborted after %d second%s',
$this->timeout,
$this->timeout === 1 ? '' : 's'
)
);
},
true
);
$this->timeout = $timeout;
pcntl_async_signals(true);
pcntl_alarm($timeout);
try {
return call_user_func_array($callable, $arguments);
} finally {
pcntl_alarm(0);
}
}
public function canInvokeWithTimeout(): bool
{
return function_exists('pcntl_signal') && function_exists('pcntl_async_signals') && function_exists('pcntl_alarm');
}
}
php-invoker-3.1.1/src/exceptions/ 0000775 0000000 0000000 00000000000 13735150555 0016737 5 ustar 00root root 0000000 0000000 php-invoker-3.1.1/src/exceptions/Exception.php 0000664 0000000 0000000 00000000551 13735150555 0021407 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Invoker;
use Throwable;
interface Exception extends Throwable
{
}
php-invoker-3.1.1/src/exceptions/ProcessControlExtensionNotLoadedException.php 0000664 0000000 0000000 00000000656 13735150555 0030004 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Invoker;
use RuntimeException;
final class ProcessControlExtensionNotLoadedException extends RuntimeException implements Exception
{
}
php-invoker-3.1.1/src/exceptions/TimeoutException.php 0000664 0000000 0000000 00000000625 13735150555 0022760 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Invoker;
use RuntimeException;
final class TimeoutException extends RuntimeException implements Exception
{
}
php-invoker-3.1.1/tests/ 0000775 0000000 0000000 00000000000 13735150555 0015131 5 ustar 00root root 0000000 0000000 php-invoker-3.1.1/tests/InvokerTest.php 0000664 0000000 0000000 00000004433 13735150555 0020123 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Invoker;
use PHPUnit\Framework\TestCase;
use RuntimeException;
use SebastianBergmann\Invoker\TestFixture\TestCallable;
/**
* @requires extension pcntl
*
* @covers \SebastianBergmann\Invoker\Invoker
*/
final class InvokerTest extends TestCase
{
/**
* @var TestCallable
*/
private $callable;
/**
* @var Invoker
*/
private $invoker;
protected function setUp(): void
{
$this->callable = new TestCallable;
$this->invoker = new Invoker;
}
public function testExecutionOfCallableIsNotAbortedWhenTimeoutIsNotReached(): void
{
$this->assertTrue(
$this->invoker->invoke([$this->callable, 'test'], [0], 1)
);
}
public function testExecutionOfCallableIsAbortedWhenTimeoutIsReached(): void
{
$this->expectException(TimeoutException::class);
$this->expectExceptionMessage('Execution aborted after 1 second');
$this->invoker->invoke([$this->callable, 'test'], [2], 1);
}
public function testRequirementsCanBeChecked(): void
{
$this->assertTrue($this->invoker->canInvokeWithTimeout());
}
public function testAlarmIsClearedWhenCallableTimeoutIsNotReached(): void
{
$this->assertTrue(
$this->invoker->invoke([$this->callable, 'test'], [0], 1)
);
try {
sleep(1);
} catch (TimeoutException $e) {
$this->fail('Alarm timeout was not cleared');
}
}
public function testAlarmIsClearedWhenCallableThrowsException(): void
{
$exception = new RuntimeException;
$callable = static function () use ($exception): void {
throw $exception;
};
try {
$this->invoker->invoke($callable, [], 1);
} catch (RuntimeException $e) {
$this->assertSame($exception, $e);
}
try {
sleep(1);
} catch (TimeoutException $e) {
$this->fail('Alarm timeout was not cleared');
}
}
}
php-invoker-3.1.1/tests/_fixture/ 0000775 0000000 0000000 00000000000 13735150555 0016756 5 ustar 00root root 0000000 0000000 php-invoker-3.1.1/tests/_fixture/TestCallable.php 0000664 0000000 0000000 00000000721 13735150555 0022026 0 ustar 00root root 0000000 0000000
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Invoker\TestFixture;
use function sleep;
final class TestCallable
{
public function test(int $sleep): bool
{
sleep($sleep);
return true;
}
}