diff --git a/.php_cs.dist b/.php_cs.dist index 388acb5b..3fb594c5 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -28,6 +28,7 @@ return (new PhpCsFixer\Config('satis')) // additionally 'array_syntax' => ['syntax' => 'short'], 'concat_space' => false, + 'declare_strict_types' => true, 'header_comment' => ['header' => $header], 'no_unused_imports' => false, 'no_useless_else' => true, diff --git a/docs/config.md b/docs/config.md index 1cec1f4c..fa27b442 100644 --- a/docs/config.md +++ b/docs/config.md @@ -15,6 +15,7 @@ title: Config "type": "composer", "url": "https://packagist.org" }], + "repositories-dep": [], "require": { "company/package1": "1.2.0", "company/package2": "1.5.2", @@ -28,7 +29,10 @@ title: Config "prefix-url": "https://amazing.cdn.example.org", "whitelist": [ "company/package1" ], "blacklist": [ "company/package2" ], - "checksum": true + "checksum": true, + "ignore-filters": false, + "override-dist-type": true, + "rearchive": true, }, "abandoned": { "company/package": true, @@ -45,6 +49,7 @@ title: Config "config": { }, + "strip-hosts": [], "notify-batch": "https://example.com/endpoint" } ``` diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 8099e7f9..c49cc539 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,7 @@ ensureDirectoryExists($targetDir); $targetDir = realpath($targetDir); - + if ($overrideDistType) { $originalDistType = $package->getDistType(); $package->setDistType($format); @@ -263,9 +265,10 @@ private function archive(DownloadManager $downloadManager, ArchiveManager $archi $path = $targetDir . '/' . $packageName . '.' . $format; $downloaded = $archiveManager->archive($package, $format, $targetDir, null, $ignoreFilters); $filesystem->rename($downloaded, $path); + return $path; - } else { - return $archiveManager->archive($package, $format, $targetDir, null, $ignoreFilters); } + + return $archiveManager->archive($package, $format, $targetDir, null, $ignoreFilters); } } diff --git a/src/Builder/ArchiveBuilderHelper.php b/src/Builder/ArchiveBuilderHelper.php index a2c14166..56080a29 100644 --- a/src/Builder/ArchiveBuilderHelper.php +++ b/src/Builder/ArchiveBuilderHelper.php @@ -1,5 +1,7 @@ getArgument('output-dir') ?? $config['output-dir'] ?? null; - if ($outputDir === null) { + if (null === $outputDir) { throw new \InvalidArgumentException('The output dir must be specified as second argument or be configured inside ' . $input->getArgument('file')); } @@ -138,17 +140,17 @@ private function removeEmptyDirectories($output, $dir, $depth = 2) { $empty = true; $children = @scandir($dir); - if ($children === false) { + if (false === $children) { return false; } foreach ($children as $child) { - if ($child === '.' || $child === '..') { + if ('.' === $child || '..' === $child) { continue; } $path = $dir . DIRECTORY_SEPARATOR . $child; if (is_dir($path) && $depth > 0 - && $this->removeEmptyDirectories($output, $path, $depth -1) + && $this->removeEmptyDirectories($output, $path, $depth - 1) && rmdir($path) ) { $output->writeln(sprintf('Removed empty directory: %s', $path)); @@ -156,6 +158,7 @@ private function removeEmptyDirectories($output, $dir, $depth = 2) $empty = false; } } + return $empty; } } diff --git a/src/PackageSelection/PackageSelection.php b/src/PackageSelection/PackageSelection.php index e3cf33c2..99956505 100644 --- a/src/PackageSelection/PackageSelection.php +++ b/src/PackageSelection/PackageSelection.php @@ -1,5 +1,7 @@ abandoned = $config['abandoned'] ?? []; $this->stripHosts = $this->createStripHostsPatterns($config['strip-hosts'] ?? false); - $this->archiveEndpoint = isset($config['archive']['directory'])? ($config['archive']['prefix-url'] ?? $config['homepage']) . '/': null; - + $this->archiveEndpoint = isset($config['archive']['directory']) ? ($config['archive']['prefix-url'] ?? $config['homepage']) . '/' : null; + $this->homepage = $config['homepage'] ?? null; } @@ -206,12 +208,12 @@ public function select(Composer $composer, $verbose) if ($this->requireDependencies || $this->requireDevDependencies) { // dependencies of required packages might have changed and be part of filtered repos - if ($this->hasRepositoryFilter() && $this->repositoryFilterDep !== true) { + if ($this->hasRepositoryFilter() && true !== $this->repositoryFilterDep) { $this->addRepositories($pool, \array_diff($initialRepos, $repos)); } // additional repositories for dependencies - if (!$this->hasRepositoryFilter() || $this->repositoryFilterDep !== true) { + if (!$this->hasRepositoryFilter() || true !== $this->repositoryFilterDep) { $this->addRepositories($pool, $this->getDepRepos($composer)); } @@ -232,6 +234,7 @@ public function select(Composer $composer, $verbose) public function clean() { $this->applyStripHosts(); + return $this->selected; } @@ -321,16 +324,16 @@ private function createStripHostsPatterns($stripHostsConfig) if (!strlen($entry)) { continue; } - if ($entry === '/private' || $entry === '/local') { + if ('/private' === $entry || '/local' === $entry) { $patterns[] = [$entry]; continue; - } elseif (strpos($entry, ":") !== false) { + } elseif (false !== strpos($entry, ':')) { $type = 'ipv6'; if (!defined('AF_INET6')) { $this->output->writeln('Unable to use IPv6.'); continue; } - } elseif (preg_match("#[^/.\\d]#", $entry) === 0) { + } elseif (0 === preg_match('#[^/.\\d]#', $entry)) { $type = 'ipv4'; } else { $type = 'name'; @@ -338,23 +341,24 @@ private function createStripHostsPatterns($stripHostsConfig) $patterns[] = [$type, $host]; continue; } - @list($host, $mask) = explode("/", $entry, 2); + @list($host, $mask) = explode('/', $entry, 2); $host = @inet_pton($host); - if ($host === false || (int)$mask != $mask) { + if (false === $host || (int) $mask != $mask) { $this->output->writeln(sprintf('Invalid subnet "%s"', $entry)); continue; } - $host = unpack("N*", $host); - if ($mask === null) { - $mask = $type === 'ipv4'? 32: 128; + $host = unpack('N*', $host); + if (null === $mask) { + $mask = 'ipv4' === $type ? 32 : 128; } else { - $mask = (int)$mask; - if ($mask < 0 || $type === 'ipv4' && $mask > 32 || $type === 'ipv6' && $mask > 128) { + $mask = (int) $mask; + if ($mask < 0 || 'ipv4' === $type && $mask > 32 || 'ipv6' === $type && $mask > 128) { continue; } } $patterns[] = [$type, $host, $mask]; } + return $patterns; } @@ -363,7 +367,7 @@ private function createStripHostsPatterns($stripHostsConfig) */ private function applyStripHosts() { - if ($this->stripHosts === false) { + if (false === $this->stripHosts) { return; } foreach ($this->selected as $uniqueName => $package) { @@ -375,22 +379,22 @@ private function applyStripHosts() $sources[] = 'dist'; } foreach ($sources as $i => $s) { - $url = $s === 'source'? $package->getSourceUrl(): $package->getDistUrl(); + $url = 'source' === $s ? $package->getSourceUrl() : $package->getDistUrl(); // skip distURL applied by ArchiveBuilder - if ($s === 'dist' && $this->archiveEndpoint !== null + if ('dist' === $s && null !== $this->archiveEndpoint && substr($url, 0, strlen($this->archiveEndpoint)) === $this->archiveEndpoint ) { continue; } if ($this->matchStripHostsPatterns($url)) { - if ($s === 'dist') { + if ('dist' === $s) { // if the type is not set, ArrayDumper ignores the other properties $package->setDistType(null); } else { $package->setSourceType(null); } unset($sources[$i]); - if (count($sources) === 0) { + if (0 === count($sources)) { $this->output->writeln(sprintf('%s has no source left after applying the strip-hosts filters and will be removed', $package->getUniqueName())); unset($this->selected[$uniqueName]); } @@ -410,40 +414,39 @@ private function matchStripHostsPatterns($url) return true; } if (is_array($this->stripHosts)) { - $url = trim(parse_url($url, PHP_URL_HOST), '[]'); - if (filter_var($url, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) { + if (false !== filter_var($url, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { $urltype = 'ipv4'; - } elseif (filter_var($url, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) { + } elseif (false !== filter_var($url, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { $urltype = 'ipv6'; } else { $urltype = 'name'; } - if ($urltype === 'ipv4' || $urltype === 'ipv6') { + if ('ipv4' === $urltype || 'ipv6' === $urltype) { $urlunpack = unpack('N*', @inet_pton($url)); } foreach ($this->stripHosts as $pattern) { @list($type, $host, $mask) = $pattern; - if ($type === '/local') { - if ($urltype === 'name' && strtolower($url) === 'localhost' - || ($urltype === 'ipv4' || $urltype === 'ipv6') - && filter_var($url, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE) === false + if ('/local' === $type) { + if ('name' === $urltype && 'localhost' === strtolower($url) + || ('ipv4' === $urltype || 'ipv6' === $urltype) + && false === filter_var($url, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE) ) { return true; } - } elseif ($type === '/private') { - if (($urltype === 'ipv4' || $urltype === 'ipv6') - && filter_var($url, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE) === false + } elseif ('/private' === $type) { + if (('ipv4' === $urltype || 'ipv6' === $urltype) + && false === filter_var($url, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE) ) { return true; } - } elseif ($type === 'ipv4' || $type === 'ipv6') { + } elseif ('ipv4' === $type || 'ipv6' === $type) { if ($urltype === $type && $this->matchAddr($urlunpack, $host, $mask)) { return true; } - } elseif ($type === 'name') { - if ($urltype === 'name' && preg_match($host, $url)) { + } elseif ('name' === $type) { + if ('name' === $urltype && preg_match($host, $url)) { return true; } } @@ -468,11 +471,12 @@ private function matchStripHostsPatterns($url) private function matchAddr($addr1, $addr2, $len = 0, $chunklen = 32) { for (; $len > 0; $len -= $chunklen, next($addr1), next($addr2)) { - $shift = $len >= $chunklen? 0: $chunklen - $len; + $shift = $len >= $chunklen ? 0 : $chunklen - $len; if ((current($addr1) >> $shift) !== (current($addr2) >> $shift)) { return false; } } + return true; } @@ -484,7 +488,8 @@ private function matchAddr($addr1, $addr2, $len = 0, $chunklen = 32) * @param RepositoryInterface[] $repos * Array of repositories */ - private function addRepositories(Pool $pool, $repos) { + private function addRepositories(Pool $pool, $repos) + { foreach ($repos as $repo) { try { $pool->addRepository($repo); @@ -579,7 +584,7 @@ private function getAllLinks($repos, $minimumStability, $verbose) /** * Add the linked packages to the selection - * + * * @param Pool $pool * Pool used to search for linked packages * @param Link[]|PackageInterface[] $links @@ -591,18 +596,19 @@ private function getAllLinks($repos, $minimumStability, $verbose) * * @return Link[] */ - private function selectLinks(Pool $pool, $links, bool $isRoot, bool $verbose) { - $depsLinks = $isRoot? []: $links; + private function selectLinks(Pool $pool, $links, bool $isRoot, bool $verbose) + { + $depsLinks = $isRoot ? [] : $links; $policies = [ new DefaultPolicy(true, false), new DefaultPolicy(false, false), new DefaultPolicy(true, true), - new DefaultPolicy(false, true) + new DefaultPolicy(false, true), ]; reset($links); - while (key($links) !== null) { + while (null !== key($links)) { $link = current($links); if (is_a($link, PackageInterface::class)) { @@ -610,7 +616,7 @@ private function selectLinks(Pool $pool, $links, bool $isRoot, bool $verbose) { } elseif (is_a($link, Link::class)) { $name = $link->getTarget(); $matches = $pool->whatProvides($name, $link->getConstraint(), true); - if (\count($matches) === 0) { + if (0 === \count($matches)) { $this->output->writeln('The ' . $name . ' ' . $link->getPrettyConstraint() . ' requirement did not match any package'); } } @@ -652,7 +658,7 @@ private function selectLinks(Pool $pool, $links, bool $isRoot, bool $verbose) { $linkId = $target . ' ' . $dependencyLink->getConstraint(); // prevent loading multiple times the same link if (!isset($depsLinks[$linkId])) { - if ($isRoot === false) { + if (false === $isRoot) { $links[] = $dependencyLink; } $depsLinks[$linkId] = $dependencyLink; @@ -678,12 +684,13 @@ private function getDepRepos(Composer $composer) $depRepos = []; if (\is_array($this->depRepositories)) { $rm = $composer->getRepositoryManager(); - foreach($this->depRepositories as $index => $repoConfig) { - $name = \is_int($index) && isset($repoConfig["url"])? $repoConfig["url"]: $index; - $type = isset($repoConfig["type"])? $repoConfig["type"]: ""; + foreach ($this->depRepositories as $index => $repoConfig) { + $name = \is_int($index) && isset($repoConfig['url']) ? $repoConfig['url'] : $index; + $type = $repoConfig['type'] ?? ''; $depRepos[$index] = $rm->createRepository($type, $repoConfig, $name); } } + return $depRepos; } diff --git a/src/Satis.php b/src/Satis.php index 3b731459..f1194346 100644 --- a/src/Satis.php +++ b/src/Satis.php @@ -1,5 +1,7 @@ @@ -58,9 +60,9 @@ public function setUp() $composerConfig = new ComposerConfig(true, $this->home . '/satis.server'); $composerConfig->merge([ - 'cache-dir'=> $this->home . '/.cache/composer', - 'data-dir'=> $this->home . '/.local/share/composer', - 'home'=> $this->home . '/.config/composer' + 'cache-dir' => $this->home . '/.cache/composer', + 'data-dir' => $this->home . '/.local/share/composer', + 'home' => $this->home . '/.config/composer', ]); $composerConfig->setConfigSource(new JsonConfigSource(new JsonFile($this->home . '/.config/composer/config.json'))); $composerConfig->setAuthConfigSource(new JsonConfigSource(new JsonFile($this->home . '/.config/composer/auth.json'))); @@ -68,7 +70,7 @@ public function setUp() $downloadManager = $this->getMockBuilder('Composer\Downloader\DownloadManager')->disableOriginalConstructor()->getMock(); $downloadManager->method('download')->will( $this->returnCallback( - function($package, $source) { + function ($package, $source) { $filesystem = new \Symfony\Component\Filesystem\Filesystem(); $filesystem->dumpFile(realpath($source) . '/' . 'README.md', '# The demo archive.'); } @@ -87,25 +89,25 @@ function($package, $source) { $this->outputDir = $this->home . '/satis.server'; $this->satisConfig = [ - "name" => "monolog/monolog", - "homepage" => "https://github.com/Seldaek/monolog.git", - "repositories" => [ - [ "type" => "composer", "url" => "https://packagist.org" ] + 'name' => 'monolog/monolog', + 'homepage' => 'https://github.com/Seldaek/monolog.git', + 'repositories' => [ + ['type' => 'composer', 'url' => 'https://packagist.org'], ], - "require" => [ - "monolog/monolog" => "1.13.0" + 'require' => [ + 'monolog/monolog' => '1.13.0', ], - "config" => [ - "secure-http" => false + 'config' => [ + 'secure-http' => false, ], - "require-dependencies" => false, - "require-dev-dependencies" => false, + 'require-dependencies' => false, + 'require-dev-dependencies' => false, 'archive' => [ 'directory' => 'dist', 'format' => 'tar', 'prefix-url' => 'http://satis.localhost:4680', - 'skip-dev' => false - ] + 'skip-dev' => false, + ], ]; } @@ -137,15 +139,16 @@ private function getPackages() $package->setDistType('zip'); $package->setDistUrl('https://api.github.com/repos/Seldaek/monolog/zipball/'); $package->setDistReference('c41c218e239b50446fd883acb1ecfd4b770caeae'); - $package->setReleaseDate(new \DateTime("2015-03-05T01:12:12+00:00")); + $package->setReleaseDate(new \DateTime('2015-03-05T01:12:12+00:00')); $package->setExtra( [ 'branch-alias' => [ - 'dev-master' => '1.13.x-dev' - ] + 'dev-master' => '1.13.x-dev', + ], ] ); $package->setNotificationUrl('https://packagist.org/downloads/'); + return [$package]; } @@ -154,7 +157,7 @@ public function getDataForTestDump() return [ [[], $this->getPackages(), 'monolog-monolog-c41c218e239b50446fd883acb1ecfd4b770caeae-zip-d4a976.tar'], [['archive' => ['override-dist-type' => false]], $this->getPackages(), 'monolog-monolog-c41c218e239b50446fd883acb1ecfd4b770caeae-zip-d4a976.tar'], - [['archive' => ['override-dist-type' => true]], $this->getPackages(), 'monolog-monolog-c41c218e239b50446fd883acb1ecfd4b770caeae-tar-d4a976.tar'] + [['archive' => ['override-dist-type' => true]], $this->getPackages(), 'monolog-monolog-c41c218e239b50446fd883acb1ecfd4b770caeae-tar-d4a976.tar'], ]; } diff --git a/tests/Builder/PackagesBuilderDumpTest.php b/tests/Builder/PackagesBuilderDumpTest.php index 27df5718..77d247eb 100644 --- a/tests/Builder/PackagesBuilderDumpTest.php +++ b/tests/Builder/PackagesBuilderDumpTest.php @@ -1,5 +1,7 @@ 'vendor/project-delta', 'version' => '1.2.3.0', 'require' => [ - 'vendor/project-alpha' => '^1', + 'vendor/project-alpha' => '^1', 'vendor/project-gamma' => '^1', ], ], @@ -279,7 +281,7 @@ public function dataSelect() ], 'require-dev' => [ 'vendor/project-gamma' => '^4', - ] + ], ], 'zeta' => [ 'name' => 'vendor/project-zeta', @@ -310,12 +312,12 @@ public function dataSelect() $packages['gamma2'], $packages['gamma3'], $packages['gamma4'], - ] + ], ]; $repo['delta'] = [ 'type' => 'package', 'url' => 'example.org/project-delta', - 'package' => $packages['delta'] + 'package' => $packages['delta'], ]; foreach ($packages as &$p) { @@ -323,7 +325,7 @@ public function dataSelect() } $data = []; - + $data['Require-all'] = [ $packages, [ @@ -490,7 +492,7 @@ public function dataClean() ], 'source' => [ 'type' => 'git', - 'url' => './git-repo' + 'url' => './git-repo', ], ], 'beta' => [ @@ -544,7 +546,7 @@ public function dataClean() 'epsilon' => ['http://[abcd::]/output/dist/epsilon.zip', 'http://[::1]/epsilon.git'], ], [], - $packages + $packages, ]; $data['Remove local file URLs'] = [ @@ -556,9 +558,9 @@ public function dataClean() 'epsilon' => ['http://[abcd::]/output/dist/epsilon.zip', 'http://[::1]/epsilon.git'], ], [ - 'strip-hosts' => true + 'strip-hosts' => true, ], - $packages + $packages, ]; $data['Remove local IPs'] = [ @@ -571,7 +573,7 @@ public function dataClean() [ 'strip-hosts' => ['/local'], ], - $packages + $packages, ]; $data['Remove private IPs'] = [ @@ -584,7 +586,7 @@ public function dataClean() [ 'strip-hosts' => ['/private'], ], - $packages + $packages, ]; $data['Remove IPv4 with CIDR notation'] = [ @@ -598,7 +600,7 @@ public function dataClean() [ 'strip-hosts' => ['192.168.0.0/24'], ], - $packages + $packages, ]; $data['Remove IPv6 address'] = [ @@ -612,7 +614,7 @@ public function dataClean() [ 'strip-hosts' => ['abcd::'], ], - $packages + $packages, ]; $data['Remove domain'] = [ @@ -625,7 +627,7 @@ public function dataClean() [ 'strip-hosts' => ['example.org'], ], - $packages + $packages, ]; $data['Preserve distURL from ArchiveBuilder'] = [ @@ -640,10 +642,10 @@ public function dataClean() 'strip-hosts' => ['/private'], 'archive' => [ 'directory' => 'dist', - 'prefix-url' => 'http://192.168.0.1' - ] + 'prefix-url' => 'http://192.168.0.1', + ], ], - $packages + $packages, ]; return $data; @@ -675,13 +677,13 @@ public function testClean($expected, $config, $packages) $clean = $selectionRef->getMethod('clean'); $clean->setAccessible(true); - + $cleanPackages = $clean->invokeArgs($selection, []); $sources = []; foreach ($cleanPackages as $name => $package) { $sources[$name] = [ - ($package->getDistType() !== null)? $package->getDistUrl(): null, - ($package->getSourceType() !== null)? $package->getSourceUrl(): null, + (null !== $package->getDistType()) ? $package->getDistUrl() : null, + (null !== $package->getSourceType()) ? $package->getSourceUrl() : null, ]; }