From 68baa9ef288700856850b24d3b710c2e4db19d36 Mon Sep 17 00:00:00 2001 From: sebprt Date: Wed, 19 Apr 2023 15:21:13 +0200 Subject: [PATCH 1/4] Added GitHub actions + updated dependencies --- .github/workflows/phpstan-5.yaml | 23 ++++ .github/workflows/phpstan-6.yaml | 23 ++++ .github/workflows/phpstan-7.yaml | 23 ++++ .github/workflows/phpstan-8.yaml | 23 ++++ .github/workflows/quality.yaml | 36 ++++++ .github/workflows/rector.yaml | 28 +++++ .php-cs-fixer.dist.php | 41 +++++++ composer.json | 7 +- composer.lock | 181 ++++++++++++++++++++++++++----- rector.php | 25 +++++ 10 files changed, 380 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/phpstan-5.yaml create mode 100644 .github/workflows/phpstan-6.yaml create mode 100644 .github/workflows/phpstan-7.yaml create mode 100644 .github/workflows/phpstan-8.yaml create mode 100644 .github/workflows/quality.yaml create mode 100644 .github/workflows/rector.yaml create mode 100644 .php-cs-fixer.dist.php create mode 100644 rector.php diff --git a/.github/workflows/phpstan-5.yaml b/.github/workflows/phpstan-5.yaml new file mode 100644 index 0000000..906b4c9 --- /dev/null +++ b/.github/workflows/phpstan-5.yaml @@ -0,0 +1,23 @@ +name: PHPStan level 5 +on: push +jobs: + phpstan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/cache@v3 + with: + path: '**/vendor' + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + - uses: php-actions/composer@v6 + with: + args: --prefer-dist + php_version: '8.2' + - name: PHPStan + uses: php-actions/phpstan@v3 + with: + path: src/ + level: 5 + php_version: '8.2' diff --git a/.github/workflows/phpstan-6.yaml b/.github/workflows/phpstan-6.yaml new file mode 100644 index 0000000..8fe418d --- /dev/null +++ b/.github/workflows/phpstan-6.yaml @@ -0,0 +1,23 @@ +name: PHPStan level 6 +on: push +jobs: + phpstan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/cache@v3 + with: + path: '**/vendor' + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + - uses: php-actions/composer@v6 + with: + args: --prefer-dist + php_version: '8.2' + + - name: PHPStan + uses: php-actions/phpstan@v3 + with: + path: src/ + level: 6 diff --git a/.github/workflows/phpstan-7.yaml b/.github/workflows/phpstan-7.yaml new file mode 100644 index 0000000..e7d8d6e --- /dev/null +++ b/.github/workflows/phpstan-7.yaml @@ -0,0 +1,23 @@ +name: PHPStan level 7 +on: push +jobs: + phpstan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/cache@v3 + with: + path: '**/vendor' + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + - uses: php-actions/composer@v6 + with: + args: --prefer-dist + php_version: '8.2' + + - name: PHPStan + uses: php-actions/phpstan@v3 + with: + path: src/ + level: 7 diff --git a/.github/workflows/phpstan-8.yaml b/.github/workflows/phpstan-8.yaml new file mode 100644 index 0000000..39cebe0 --- /dev/null +++ b/.github/workflows/phpstan-8.yaml @@ -0,0 +1,23 @@ +name: PHPStan level 8 +on: push +jobs: + phpstan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/cache@v3 + with: + path: '**/vendor' + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + - uses: php-actions/composer@v6 + with: + args: --prefer-dist + php_version: '8.2' + + - name: PHPStan + uses: php-actions/phpstan@v3 + with: + path: src/ + level: 8 diff --git a/.github/workflows/quality.yaml b/.github/workflows/quality.yaml new file mode 100644 index 0000000..8e70ec6 --- /dev/null +++ b/.github/workflows/quality.yaml @@ -0,0 +1,36 @@ +name: Quality (PHPStan lvl 4) +on: push +jobs: + cs-fixer: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + - name: Cs-Fixer + run: | + wget -q https://cs.symfony.com/download/php-cs-fixer-v3.phar -O php-cs-fixer + chmod a+x php-cs-fixer + PHP_CS_FIXER_IGNORE_ENV=true ./php-cs-fixer fix src --dry-run + + phpstan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/cache@v3 + with: + path: '**/vendor' + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + - uses: php-actions/composer@v6 + with: + args: --prefer-dist + php_version: '8.2' + + - name: PHPStan + uses: php-actions/phpstan@v3 + with: + path: src/ + level: 4 diff --git a/.github/workflows/rector.yaml b/.github/workflows/rector.yaml new file mode 100644 index 0000000..3a41065 --- /dev/null +++ b/.github/workflows/rector.yaml @@ -0,0 +1,28 @@ +# github action that checks code with Rector +name: Rector + +on: + pull_request: null + +jobs: + rector: + runs-on: ubuntu-latest + if: github.event.pull_request.head.repo.full_name == 'php-etl/sftp-action-flow' + steps: + - uses: actions/checkout@v3 + + - uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + coverage: none + + - uses: "ramsey/composer-install@v2" + + - run: bin/rector --ansi + + - # commit only to core contributors who have repository access + uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: '[rector] Rector fixes' + commit_author: 'GitHub Action ' + commit_user_email: 'action@github.com' diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..218caa4 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,41 @@ +in('src') +; + +return (new PhpCsFixer\Config()) + ->setRiskyAllowed(true) + ->setRules([ + '@PHP82Migration' => true, + '@PHP81Migration' => true, + '@PHP80Migration:risky' => true, + '@PHPUnit84Migration:risky' => true, + '@PSR1' => true, + '@PSR12' => true, + '@PhpCsFixer' => true, + '@Symfony' => true, + 'ternary_to_elvis_operator' => true, + 'set_type_to_cast' => true, + 'self_accessor' => true, + 'psr_autoloading' => true, + 'php_unit_test_annotation' => ['style' => 'annotation'], + 'php_unit_set_up_tear_down_visibility' => true, + 'php_unit_construct' => true, + 'no_useless_sprintf' => true, + 'no_homoglyph_names' => true, + 'native_function_invocation' => true, + 'native_constant_invocation' => true, + 'modernize_types_casting' => true, + 'logical_operators' => true, + 'is_null' => true, + 'function_to_constant' => true, + 'fopen_flag_order' => true, + 'error_suppression' => true, + 'ereg_to_preg' => true, + 'dir_constant' => true, + 'method_chaining_indentation' => false, + ]) + ->setFinder($finder) + ->setCacheFile('.php-cs-fixer.cache') // forward compatibility with 3.x line +; diff --git a/composer.json b/composer.json index 5b43c07..8a7a21e 100644 --- a/composer.json +++ b/composer.json @@ -13,8 +13,8 @@ "prefer-stable": true, "require": { "php": "^8.2", - "psr/log": "^1.1", - "php-etl/action-contracts": "^0.1.0" + "psr/log": "^3.0", + "php-etl/action-contracts": "0.1.*" }, "autoload": { "psr-4": { @@ -28,5 +28,8 @@ }, "config": { "bin-dir": "bin" + }, + "require-dev": { + "rector/rector": "^0.15.24" } } diff --git a/composer.lock b/composer.lock index a8a3468..03fb5d3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,30 +4,29 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "666506f2a1e35f9249daaf81b1f433d7", + "content-hash": "6d88d71e94e267ecb1bcf3d26f0b1ec0", "packages": [ { "name": "php-etl/action-contracts", - "version": "dev-main", + "version": "v0.1.0", "source": { "type": "git", "url": "https://github.com/php-etl/action-contracts.git", - "reference": "0d4ccbb5da2b8685a0a45013efb123c4e9829fa6" + "reference": "42b3f800ab4898e06249b73afad852160d225884" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/action-contracts/zipball/0d4ccbb5da2b8685a0a45013efb123c4e9829fa6", - "reference": "0d4ccbb5da2b8685a0a45013efb123c4e9829fa6", + "url": "https://api.github.com/repos/php-etl/action-contracts/zipball/42b3f800ab4898e06249b73afad852160d225884", + "reference": "42b3f800ab4898e06249b73afad852160d225884", "shasum": "" }, "require": { "php": "^8.2", - "php-etl/bucket-contracts": "^0.1.0" + "php-etl/bucket-contracts": "0.2.*" }, "require-dev": { "rector/rector": "^0.15.0" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -56,34 +55,36 @@ "description": "This library describes contracts for the Action pattern.", "support": { "issues": "https://github.com/php-etl/action-contracts/issues", - "source": "https://github.com/php-etl/action-contracts/tree/main" + "source": "https://github.com/php-etl/action-contracts/tree/v0.1.0" }, - "time": "2023-03-17T15:49:43+00:00" + "time": "2023-04-18T15:03:09+00:00" }, { "name": "php-etl/bucket-contracts", - "version": "v0.1.0", + "version": "v0.2.0", "source": { "type": "git", "url": "https://github.com/php-etl/bucket-contracts.git", - "reference": "b5d682329b7f8ff66e0987f75fad190607c10ddf" + "reference": "e96726f9b89dea7308482fa6c2ce4db0757960ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-etl/bucket-contracts/zipball/b5d682329b7f8ff66e0987f75fad190607c10ddf", - "reference": "b5d682329b7f8ff66e0987f75fad190607c10ddf", + "url": "https://api.github.com/repos/php-etl/bucket-contracts/zipball/e96726f9b89dea7308482fa6c2ce4db0757960ce", + "reference": "e96726f9b89dea7308482fa6c2ce4db0757960ce", "shasum": "" }, "require": { - "php": "^8.0" + "php": "^8.2" }, "require-dev": { - "phpstan/phpstan": "0.12.x-dev" + "friendsofphp/php-cs-fixer": "^3.0", + "phpstan/phpstan": "^1.10", + "rector/rector": "^0.15" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.1.x-dev" + "dev-main": "0.2.x-dev" } }, "autoload": { @@ -108,36 +109,36 @@ "description": "This library describes contracts for the data-interchange buckets.", "support": { "issues": "https://github.com/php-etl/bucket-contracts/issues", - "source": "https://github.com/php-etl/bucket-contracts/tree/v0.1.0" + "source": "https://github.com/php-etl/bucket-contracts/tree/v0.2.0" }, - "time": "2021-09-25T16:53:47+00:00" + "time": "2023-04-03T12:42:10+00:00" }, { "name": "psr/log", - "version": "1.1.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "3.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -158,12 +159,136 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "source": "https://github.com/php-fig/log/tree/3.0.0" }, - "time": "2021-05-03T11:20:27+00:00" + "time": "2021-07-14T16:46:02+00:00" + } + ], + "packages-dev": [ + { + "name": "phpstan/phpstan", + "version": "1.10.13", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "f07bf8c6980b81bf9e49d44bd0caf2e737614a70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/f07bf8c6980b81bf9e49d44bd0caf2e737614a70", + "reference": "f07bf8c6980b81bf9e49d44bd0caf2e737614a70", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2023-04-12T19:29:52+00:00" + }, + { + "name": "rector/rector", + "version": "0.15.24", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "716473919bcfdc27bdd2a32afb72adbf4c224e59" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/716473919bcfdc27bdd2a32afb72adbf4c224e59", + "reference": "716473919bcfdc27bdd2a32afb72adbf4c224e59", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.10.1" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.15-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/0.15.24" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-04-05T08:49:11+00:00" } ], - "packages-dev": [], "aliases": [], "minimum-stability": "dev", "stability-flags": [], diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..8006502 --- /dev/null +++ b/rector.php @@ -0,0 +1,25 @@ +paths([ + __DIR__ . '/src', + __DIR__ . '/tests', + ]); + + // register a single rule + $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class); + + // define sets of rules + $rectorConfig->sets([ + LevelSetList::UP_TO_PHP_82, + PHPUnitLevelSetList::UP_TO_PHPUNIT_100, + ]); +}; From bb275d2ea7ad2ffaa65eea110c4349887b8b16d2 Mon Sep 17 00:00:00 2001 From: sebprt Date: Wed, 19 Apr 2023 15:26:40 +0200 Subject: [PATCH 2/4] Ran php-cs-fixer --- src/Action.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Action.php b/src/Action.php index 48d881d..49343b7 100644 --- a/src/Action.php +++ b/src/Action.php @@ -25,11 +25,11 @@ public function execute(): void { $connection = ssh2_connect($this->host, $this->port); if (!$connection) { - $this->logger->error("Unable to connect to the server. Please check that you are using the correct host and port"); + $this->logger->error('Unable to connect to the server. Please check that you are using the correct host and port'); } if (!ssh2_auth_password($connection, $this->user, $this->password)) { - $this->logger->error("Unable to connect to the server. Please check your login information."); + $this->logger->error('Unable to connect to the server. Please check your login information.'); } $sftp = ssh2_sftp($connection); @@ -39,9 +39,9 @@ public function execute(): void fclose($localFile); if (!$uploaded) { - $this->logger->error("Failed to upload file to the SFTP server."); + $this->logger->error('Failed to upload file to the SFTP server.'); } - $this->logger->info("The file has been uploaded to the SFTP server."); + $this->logger->info('The file has been uploaded to the SFTP server.'); } } From c205fb58b35bde51450063738ebfee8229323f5e Mon Sep 17 00:00:00 2001 From: sebprt Date: Wed, 19 Apr 2023 15:46:20 +0200 Subject: [PATCH 3/4] Improve errors management --- src/Action.php | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/Action.php b/src/Action.php index 49343b7..8a20599 100644 --- a/src/Action.php +++ b/src/Action.php @@ -8,15 +8,15 @@ use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; -final class Action implements ActionInterface +final readonly class Action implements ActionInterface { public function __construct( - private readonly string $host, - private readonly string $user, - private readonly string $password, - private readonly string $port, - private readonly string $localFilePath, - private readonly string $remoteFilePath, + private string $host, + private string $user, + private string $password, + private int $port, + private string $localFilePath, + private string $remoteFilePath, private LoggerInterface $logger = new NullLogger(), ) { } @@ -25,21 +25,33 @@ public function execute(): void { $connection = ssh2_connect($this->host, $this->port); if (!$connection) { - $this->logger->error('Unable to connect to the server. Please check that you are using the correct host and port'); + $this->logger->error('Unable to connect to the server. Please check that you are using the correct host and port and try again.'); + + return; } if (!ssh2_auth_password($connection, $this->user, $this->password)) { - $this->logger->error('Unable to connect to the server. Please check your login information.'); + $this->logger->error('Unable to connect to the server. Please check your login information and try again.'); + + return; } $sftp = ssh2_sftp($connection); $remoteFile = "ssh2.sftp://{$sftp}{$this->remoteFilePath}"; + $localFile = fopen($this->localFilePath, 'r'); + if (false === $localFile) { + $this->logger->error('Impossible to open the local file. Please check if the path is correct and try again.'); + + return; + } $uploaded = file_put_contents($remoteFile, $localFile); fclose($localFile); if (!$uploaded) { $this->logger->error('Failed to upload file to the SFTP server.'); + + return; } $this->logger->info('The file has been uploaded to the SFTP server.'); From c27c57c2b69dc270fc4b338415aefff17247da07 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 19 Apr 2023 13:47:10 +0000 Subject: [PATCH 4/4] [rector] Rector fixes --- bin/phpstan | 120 +++++++++++++++++++++++++++++++++++++++++++++++ bin/phpstan.phar | 120 +++++++++++++++++++++++++++++++++++++++++++++++ bin/rector | 120 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 360 insertions(+) create mode 100755 bin/phpstan create mode 100755 bin/phpstan.phar create mode 100755 bin/rector diff --git a/bin/phpstan b/bin/phpstan new file mode 100755 index 0000000..b82614c --- /dev/null +++ b/bin/phpstan @@ -0,0 +1,120 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + include("phpvfscomposer://" . __DIR__ . '/..'.'/vendor/phpstan/phpstan/phpstan'); + exit(0); + } +} + +include __DIR__ . '/..'.'/vendor/phpstan/phpstan/phpstan'; diff --git a/bin/phpstan.phar b/bin/phpstan.phar new file mode 100755 index 0000000..968d2de --- /dev/null +++ b/bin/phpstan.phar @@ -0,0 +1,120 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + include("phpvfscomposer://" . __DIR__ . '/..'.'/vendor/phpstan/phpstan/phpstan.phar'); + exit(0); + } +} + +include __DIR__ . '/..'.'/vendor/phpstan/phpstan/phpstan.phar'; diff --git a/bin/rector b/bin/rector new file mode 100755 index 0000000..69ec306 --- /dev/null +++ b/bin/rector @@ -0,0 +1,120 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + include("phpvfscomposer://" . __DIR__ . '/..'.'/vendor/rector/rector/bin/rector'); + exit(0); + } +} + +include __DIR__ . '/..'.'/vendor/rector/rector/bin/rector';