From 498df5aeabccb876ef4d51bd907aa2fe39547c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20Hochd=C3=B6rfer?= Date: Tue, 25 Feb 2014 11:44:47 +0100 Subject: [PATCH 1/7] Added additional flag to generate the satis build for a single package. This helps to speed up the satis run if you have a lot of repos. --- src/Composer/Satis/Command/BuildCommand.php | 45 +++++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/src/Composer/Satis/Command/BuildCommand.php b/src/Composer/Satis/Command/BuildCommand.php index 0d46fe30..fc0e8b4b 100644 --- a/src/Composer/Satis/Command/BuildCommand.php +++ b/src/Composer/Satis/Command/BuildCommand.php @@ -50,6 +50,7 @@ protected function configure() ->setDefinition(array( new InputArgument('file', InputArgument::OPTIONAL, 'Json file to use', './satis.json'), new InputArgument('output-dir', InputArgument::OPTIONAL, 'Location where to output built files', null), + new InputArgument('filter-package', InputArgument::OPTIONAL, 'Run the build just for the given package', null), new InputOption('no-html-output', null, InputOption::VALUE_NONE, 'Turn off HTML view'), new InputOption('skip-errors', null, InputOption::VALUE_NONE, 'Skip Download or Archive errors'), )) @@ -101,6 +102,7 @@ protected function execute(InputInterface $input, OutputInterface $output) { $verbose = $input->getOption('verbose'); $configFile = $input->getArgument('file'); + $filterPackage = $input->getArgument('filter-package'); $skipErrors = (bool)$input->getOption('skip-errors'); if (preg_match('{^https?://}i', $configFile)) { @@ -141,7 +143,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } $composer = $this->getApplication()->getComposer(true, $config); - $packages = $this->selectPackages($composer, $output, $verbose, $requireAll, $requireDependencies, $requireDevDependencies, $minimumStability, $skipErrors); + $packages = $this->selectPackages($composer, $output, $verbose, $requireAll, $requireDependencies, $requireDevDependencies, $minimumStability, $skipErrors, $filterPackage); if ($htmlView = !$input->getOption('no-html-output')) { $htmlView = !isset($config['output-html']) || $config['output-html']; @@ -168,7 +170,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } } - private function selectPackages(Composer $composer, OutputInterface $output, $verbose, $requireAll, $requireDependencies, $requireDevDependencies, $minimumStability, $skipErrors) + private function selectPackages(Composer $composer, OutputInterface $output, $verbose, $requireAll, $requireDependencies, $requireDevDependencies, $minimumStability, $skipErrors, $packageFilter = null) { $selected = array(); @@ -198,25 +200,42 @@ private function selectPackages(Composer $composer, OutputInterface $output, $ve $links[] = new Link('__root__', $name, new MultiConstraint(array()), 'requires', '*'); } } else { - // process other repos directly - foreach ($repo->getPackages() as $package) { - // skip aliases - if ($package instanceof AliasPackage) { - continue; + if(!empty($packageFilter)) { + if ($verbose) { + $output->writeln('Trying to find packages '.$packageFilter.' in repo'); } - if ($package->getStability() > BasePackage::$stabilities[$minimumStability]) { - continue; - } - - // add matching package if not yet selected - if (!isset($selected[$package->getUniqueName()])) { + $packages = $repo->findPackages($packageFilter); + foreach($packages as $package) { if ($verbose) { $output->writeln('Selected '.$package->getPrettyName().' ('.$package->getPrettyVersion().')'); } + $selected[$package->getUniqueName()] = $package; } } + else { + // process other repos directly + foreach ($repo->getPackages() as $package) { + // skip aliases + if ($package instanceof AliasPackage) { + continue; + } + + if ($package->getStability() > BasePackage::$stabilities[$minimumStability]) { + continue; + } + + // add matching package if not yet selected + if (!isset($selected[$package->getName()])) { + if ($verbose) { + $output->writeln('Selected '.$package->getPrettyName().' ('.$package->getPrettyVersion().')'); + } + + $selected[$package->getUniqueName()] = $package; + } + } + } } } } else { From c7f8d2090a93f4f6aa3ec2955503c675578386bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20Hochd=C3=B6rfer?= Date: Tue, 25 Feb 2014 12:14:10 +0100 Subject: [PATCH 2/7] Ignore alias packages and minimum stability similar to the default handling of packages. --- src/Composer/Satis/Command/BuildCommand.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Composer/Satis/Command/BuildCommand.php b/src/Composer/Satis/Command/BuildCommand.php index fc0e8b4b..8aaf2b4c 100644 --- a/src/Composer/Satis/Command/BuildCommand.php +++ b/src/Composer/Satis/Command/BuildCommand.php @@ -207,6 +207,15 @@ private function selectPackages(Composer $composer, OutputInterface $output, $ve $packages = $repo->findPackages($packageFilter); foreach($packages as $package) { + // skip aliases + if ($package instanceof AliasPackage) { + continue; + } + + if ($package->getStability() > BasePackage::$stabilities[$minimumStability]) { + continue; + } + if ($verbose) { $output->writeln('Selected '.$package->getPrettyName().' ('.$package->getPrettyVersion().')'); } From 22b0b672f9c2d018a855783be16512e0a9c18d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20Hochd=C3=B6rfer?= Date: Wed, 26 Feb 2014 20:03:19 +0100 Subject: [PATCH 3/7] Added handling for multiple packages in the filtering process. You can now pass a list of packages that satis should built the repos for. --- src/Composer/Satis/Command/BuildCommand.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Composer/Satis/Command/BuildCommand.php b/src/Composer/Satis/Command/BuildCommand.php index 8aaf2b4c..0ba99ff9 100644 --- a/src/Composer/Satis/Command/BuildCommand.php +++ b/src/Composer/Satis/Command/BuildCommand.php @@ -50,7 +50,7 @@ protected function configure() ->setDefinition(array( new InputArgument('file', InputArgument::OPTIONAL, 'Json file to use', './satis.json'), new InputArgument('output-dir', InputArgument::OPTIONAL, 'Location where to output built files', null), - new InputArgument('filter-package', InputArgument::OPTIONAL, 'Run the build just for the given package', null), + new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Packages that should be built, if not provided all packages are.', null), new InputOption('no-html-output', null, InputOption::VALUE_NONE, 'Turn off HTML view'), new InputOption('skip-errors', null, InputOption::VALUE_NONE, 'Skip Download or Archive errors'), )) @@ -102,7 +102,7 @@ protected function execute(InputInterface $input, OutputInterface $output) { $verbose = $input->getOption('verbose'); $configFile = $input->getArgument('file'); - $filterPackage = $input->getArgument('filter-package'); + $packagesFilter = $input->getArgument('packages'); $skipErrors = (bool)$input->getOption('skip-errors'); if (preg_match('{^https?://}i', $configFile)) { @@ -143,7 +143,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } $composer = $this->getApplication()->getComposer(true, $config); - $packages = $this->selectPackages($composer, $output, $verbose, $requireAll, $requireDependencies, $requireDevDependencies, $minimumStability, $skipErrors, $filterPackage); + $packages = $this->selectPackages($composer, $output, $verbose, $requireAll, $requireDependencies, $requireDevDependencies, $minimumStability, $skipErrors, $packagesFilter); if ($htmlView = !$input->getOption('no-html-output')) { $htmlView = !isset($config['output-html']) || $config['output-html']; @@ -170,7 +170,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } } - private function selectPackages(Composer $composer, OutputInterface $output, $verbose, $requireAll, $requireDependencies, $requireDevDependencies, $minimumStability, $skipErrors, $packageFilter = null) + private function selectPackages(Composer $composer, OutputInterface $output, $verbose, $requireAll, $requireDependencies, $requireDevDependencies, $minimumStability, $skipErrors, array $packagesFilter = array()) { $selected = array(); @@ -200,12 +200,13 @@ private function selectPackages(Composer $composer, OutputInterface $output, $ve $links[] = new Link('__root__', $name, new MultiConstraint(array()), 'requires', '*'); } } else { - if(!empty($packageFilter)) { - if ($verbose) { - $output->writeln('Trying to find packages '.$packageFilter.' in repo'); + if(count($packagesFilter) > 0) { + // collect all the packages based on the given $packagesFilter + $packages = array(); + foreach($packagesFilter as $filter) { + $packages += $repo->findPackages($filter); } - $packages = $repo->findPackages($packageFilter); foreach($packages as $package) { // skip aliases if ($package instanceof AliasPackage) { @@ -217,7 +218,7 @@ private function selectPackages(Composer $composer, OutputInterface $output, $ve } if ($verbose) { - $output->writeln('Selected '.$package->getPrettyName().' ('.$package->getPrettyVersion().')'); + $output->writeln('Selected '.$package->getPrettyName().' ('.$package->getPrettyVersion().') based on the given filter options'); } $selected[$package->getUniqueName()] = $package; From 4e9780a980f3270eda98ba9a5797cce9463974f0 Mon Sep 17 00:00:00 2001 From: Bo Thinggaard Date: Thu, 24 Apr 2014 16:34:28 +0200 Subject: [PATCH 4/7] packages.json and web-view is now correctly updated on filtered updates. --- src/Composer/Satis/Command/BuildCommand.php | 65 ++++++++++++++++++--- 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/src/Composer/Satis/Command/BuildCommand.php b/src/Composer/Satis/Command/BuildCommand.php index 0ba99ff9..7cdd9c5e 100644 --- a/src/Composer/Satis/Command/BuildCommand.php +++ b/src/Composer/Satis/Command/BuildCommand.php @@ -12,6 +12,7 @@ namespace Composer\Satis\Command; +use Composer\Package\Loader\ArrayLoader; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputArgument; @@ -154,9 +155,16 @@ protected function execute(InputInterface $input, OutputInterface $output) } $filename = $outputDir.'/packages.json'; - $this->dumpJson($packages, $output, $filename); + $update = !empty($packagesFilter); + $this->dumpJson($packages, $output, $filename, $update); if ($htmlView) { + + // if updating, we need to ge the full picture before trying to generate the web-view. + if ($update) { + $packages = $this->loadJson($filename); + } + $dependencies = array(); foreach ($packages as $package) { foreach ($package->getRequires() as $link) { @@ -190,9 +198,9 @@ private function selectPackages(Composer $composer, OutputInterface $output, $ve } } - if ($requireAll) { - $links = array(); + $links = array(); + if ($requireAll) { foreach ($repos as $repo) { // collect links for composer repos with providers if ($repo instanceof ComposerRepository && $repo->hasProviders()) { @@ -249,9 +257,17 @@ private function selectPackages(Composer $composer, OutputInterface $output, $ve } } } else { - $links = array_values($composer->getPackage()->getRequires()); - } + $links = $composer->getPackage()->getRequires(); + // only pick up packages in our filter, if a filter has been set. + if (count($packagesFilter) > 0) { + $links = array_filter($links, function(Link $link) use ($packagesFilter) { + return in_array($link->getTarget(), $packagesFilter); + }); + } + + $links = array_values($links); + } // process links if any $depsLinks = array(); @@ -387,18 +403,49 @@ private function dumpDownloads(array $config, array &$packages, InputInterface } } - private function dumpJson(array $packages, OutputInterface $output, $filename) + private function dumpJson(array $packages, OutputInterface $output, $filename, $update = false) { - $repo = array('packages' => array()); - $dumper = new ArrayDumper; + $repoJson = new JsonFile($filename); + + // decide if we should do an update or override. + $repo = $update && $repoJson->exists() + ? $repoJson->read() + : array('packages' => array()); + + $dumper = new ArrayDumper; foreach ($packages as $package) { $repo['packages'][$package->getPrettyName()][$package->getPrettyVersion()] = $dumper->dump($package); } $output->writeln('Writing packages.json'); - $repoJson = new JsonFile($filename); $repoJson->write($repo); } + private function loadJson($filename) + { + $packages = array(); + $repoJson = new JsonFile($filename); + + if ($repoJson->exists()) { + $loader = new ArrayLoader(); + $jsonPackages = $repoJson->read(); + $jsonPackages = isset($jsonPackages['packages']) && is_array($jsonPackages['packages']) + ? $jsonPackages['packages'] + : array(); + + foreach ($jsonPackages as $jsonPackage) { + if (is_array($jsonPackage)) { + foreach ($jsonPackage as $jsonVersion) { + if (is_array($jsonVersion)) { + $packages[] = $loader->load($jsonVersion); + } + } + } + } + } + + return $packages; + } + private function dumpWeb(array $packages, OutputInterface $output, PackageInterface $rootPackage, $directory, $template = null, array $dependencies = array()) { $templateDir = $template ? pathinfo($template, PATHINFO_DIRNAME) : __DIR__.'/../../../../views'; From 3274a821f5dba40d8d0b904f3406ede89084fe9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20Hochd=C3=B6rfer?= Date: Fri, 25 Apr 2014 18:35:55 +0200 Subject: [PATCH 5/7] Optimized the generation of the packages.json and index.html in case satis is run for a single package. --- src/Composer/Satis/Command/BuildCommand.php | 24 ++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Composer/Satis/Command/BuildCommand.php b/src/Composer/Satis/Command/BuildCommand.php index 7cdd9c5e..5425834e 100644 --- a/src/Composer/Satis/Command/BuildCommand.php +++ b/src/Composer/Satis/Command/BuildCommand.php @@ -155,16 +155,16 @@ protected function execute(InputInterface $input, OutputInterface $output) } $filename = $outputDir.'/packages.json'; - $update = !empty($packagesFilter); - $this->dumpJson($packages, $output, $filename, $update); + if(!empty($packagesFilter)) { + // in case of an active package filter we need to load the dumped packages.json and merge the + // updated packages in + $oldPackages = $this->loadDumpedPackages($filename, $packagesFilter); + $packages += $oldPackages; + ksort($packages); + } + $this->dumpJson($packages, $output, $filename); if ($htmlView) { - - // if updating, we need to ge the full picture before trying to generate the web-view. - if ($update) { - $packages = $this->loadJson($filename); - } - $dependencies = array(); foreach ($packages as $package) { foreach ($package->getRequires() as $link) { @@ -420,7 +420,7 @@ private function dumpJson(array $packages, OutputInterface $output, $filename, $ $repoJson->write($repo); } - private function loadJson($filename) + private function loadDumpedPackages($filename, array $packagesFilter = array()) { $packages = array(); $repoJson = new JsonFile($filename); @@ -436,7 +436,11 @@ private function loadJson($filename) if (is_array($jsonPackage)) { foreach ($jsonPackage as $jsonVersion) { if (is_array($jsonVersion)) { - $packages[] = $loader->load($jsonVersion); + if(isset($jsonVersion['name']) && in_array($jsonVersion['name'], $packagesFilter)) { + continue; + } + $package = $loader->load($jsonVersion); + $packages[$package->getUniqueName()] = $package; } } } From 262670447f5c5f300ef7513fb99b5c19feb6dad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20Hochd=C3=B6rfer?= Date: Sat, 26 Apr 2014 09:24:26 +0200 Subject: [PATCH 6/7] Minor optimization in foreach loop. --- src/Composer/Satis/Command/BuildCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Composer/Satis/Command/BuildCommand.php b/src/Composer/Satis/Command/BuildCommand.php index 5425834e..18a2253c 100644 --- a/src/Composer/Satis/Command/BuildCommand.php +++ b/src/Composer/Satis/Command/BuildCommand.php @@ -201,6 +201,7 @@ private function selectPackages(Composer $composer, OutputInterface $output, $ve $links = array(); if ($requireAll) { + $filterForPackages = count($packagesFilter) > 0; foreach ($repos as $repo) { // collect links for composer repos with providers if ($repo instanceof ComposerRepository && $repo->hasProviders()) { @@ -208,7 +209,7 @@ private function selectPackages(Composer $composer, OutputInterface $output, $ve $links[] = new Link('__root__', $name, new MultiConstraint(array()), 'requires', '*'); } } else { - if(count($packagesFilter) > 0) { + if($filterForPackages) { // collect all the packages based on the given $packagesFilter $packages = array(); foreach($packagesFilter as $filter) { From 1929e44f1e96b5aaeee52e23aae73ca0db9097f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20Hochd=C3=B6rfer?= Date: Sat, 26 Apr 2014 09:31:45 +0200 Subject: [PATCH 7/7] Got rid of duplicate foreach loop when selecting the packages. --- src/Composer/Satis/Command/BuildCommand.php | 52 +++++++-------------- 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/src/Composer/Satis/Command/BuildCommand.php b/src/Composer/Satis/Command/BuildCommand.php index 18a2253c..fe61efe2 100644 --- a/src/Composer/Satis/Command/BuildCommand.php +++ b/src/Composer/Satis/Command/BuildCommand.php @@ -209,52 +209,36 @@ private function selectPackages(Composer $composer, OutputInterface $output, $ve $links[] = new Link('__root__', $name, new MultiConstraint(array()), 'requires', '*'); } } else { + $packages = array(); if($filterForPackages) { - // collect all the packages based on the given $packagesFilter - $packages = array(); - foreach($packagesFilter as $filter) { + // apply package filter if defined + foreach ($packagesFilter as $filter) { $packages += $repo->findPackages($filter); } + } else { + // process other repos directly + $packages = $repo->getPackages(); + } - foreach($packages as $package) { - // skip aliases - if ($package instanceof AliasPackage) { - continue; - } + foreach ($packages as $package) { + // skip aliases + if ($package instanceof AliasPackage) { + continue; + } - if ($package->getStability() > BasePackage::$stabilities[$minimumStability]) { - continue; - } + if ($package->getStability() > BasePackage::$stabilities[$minimumStability]) { + continue; + } + // add matching package if not yet selected + if (!isset($selected[$package->getName()])) { if ($verbose) { - $output->writeln('Selected '.$package->getPrettyName().' ('.$package->getPrettyVersion().') based on the given filter options'); + $output->writeln('Selected '.$package->getPrettyName().' ('.$package->getPrettyVersion().')'); } $selected[$package->getUniqueName()] = $package; } } - else { - // process other repos directly - foreach ($repo->getPackages() as $package) { - // skip aliases - if ($package instanceof AliasPackage) { - continue; - } - - if ($package->getStability() > BasePackage::$stabilities[$minimumStability]) { - continue; - } - - // add matching package if not yet selected - if (!isset($selected[$package->getName()])) { - if ($verbose) { - $output->writeln('Selected '.$package->getPrettyName().' ('.$package->getPrettyVersion().')'); - } - - $selected[$package->getUniqueName()] = $package; - } - } - } } } } else {