From f1a0f3d00f99143bbf8949dce96e7b402673fe43 Mon Sep 17 00:00:00 2001 From: Hugh <64899484@qq.com> Date: Mon, 5 Apr 2021 18:36:44 +0800 Subject: [PATCH] Optimized `phar:build`, which can support `symlink` package. (#3455) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 李铭昕 <715557344@qq.com> --- .github/workflows/test-components.yml | 8 ++++-- CHANGELOG-2.1.md | 1 + src/phar/src/PharBuilder.php | 38 ++++++++++++++++++++++++--- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test-components.yml b/.github/workflows/test-components.yml index b4ca4c339..792186918 100644 --- a/.github/workflows/test-components.yml +++ b/.github/workflows/test-components.yml @@ -4,8 +4,12 @@ on: [ push, pull_request ] jobs: phar: - name: Test for Phar + name: Test for Building PHAR ${{ matrix.no-dev }} runs-on: 'ubuntu-latest' + strategy: + matrix: + no-dev: [ '', '--no-dev' ] + max-parallel: 2 env: SW_VERSION: '4.6.4' steps: @@ -25,7 +29,7 @@ jobs: run: | git clone https://github.com/limingxinleo/hyperf-phar-tester.git --depth 1 cd hyperf-phar-tester - composer update -o --no-dev + composer update -o ${{ matrix.no-dev }} rm -rf vendor/hyperf/phar cp -rf ../src/phar vendor/hyperf/phar composer dump-autoload -o diff --git a/CHANGELOG-2.1.md b/CHANGELOG-2.1.md index 5b65e424f..26b333d0f 100644 --- a/CHANGELOG-2.1.md +++ b/CHANGELOG-2.1.md @@ -10,6 +10,7 @@ ## Optimized - [#3453](https://github.com/hyperf/hyperf/pull/3453) Optimized code for releasing instance in `Hyperf\Utils\Channel\Caller`. +- [#3455](https://github.com/hyperf/hyperf/pull/3455) Optimized `phar:build`, which can support `symlink` package. # v2.1.12 - 2021-03-29 diff --git a/src/phar/src/PharBuilder.php b/src/phar/src/PharBuilder.php index d846e8b66..23d32b342 100644 --- a/src/phar/src/PharBuilder.php +++ b/src/phar/src/PharBuilder.php @@ -177,18 +177,37 @@ class PharBuilder } // Package all of these dependent components into the packages foreach ($installedPackages as $package) { - $dir = $package['name'] . '/'; + // support custom install path + $dir = 'composer/' . $package['install-path'] . '/'; if (isset($package['target-dir'])) { $dir .= trim($package['target-dir'], '/') . '/'; } $dir = $vendorPath . $dir; - $packages[] = new Package($package, $dir); + $packages[] = new Package($package, $this->canonicalize($dir)); } } return $packages; } + /** + * Gets the canonicalize path, like realpath. + * @param mixed $address + */ + public function canonicalize($address) + { + $address = explode('/', $address); + $keys = array_keys($address, '..'); + + foreach ($keys as $keypos => $key) { + array_splice($address, $key - ($keypos * 2 + 1), 2); + } + + $address = implode('/', $address); + return str_replace('./', '', $address); + } + + /** * Gets the relative path relative to the resource bundle. */ @@ -198,7 +217,8 @@ class PharBuilder if (strpos($path, $root) !== 0) { throw new UnexpectedValueException('Path "' . $path . '" is not within base project path "' . $root . '"'); } - return substr($path, strlen($root)) ?? null; + $basePath = substr($path, strlen($root)); + return empty($basePath) ? null : $this->canonicalize($basePath); } /** @@ -301,7 +321,17 @@ EOD; // Add composer depenedencies. foreach ($this->getPackagesDependencies() as $package) { $this->logger->info('Adding dependency "' . $package->getName() . '" from "' . $this->getPathLocalToBase($package->getDirectory()) . '"'); - $targetPhar->addBundle($package->bundle()); + // support package symlink + if (is_link(rtrim($package->getDirectory(), '/'))) { + $bundle = $package->bundle(); + foreach ($bundle as $resource) { + foreach ($resource as $iterator) { + $targetPhar->addFile($iterator->getPathname()); + } + } + } else { + $targetPhar->addBundle($package->bundle()); + } } // Replace ConfigFactory ReadPaths method. $this->logger->info('Replace method "readPaths" in file "vendor/hyperf/config/src/ConfigFactory.php" and change "getRealPath" to "getPathname".');