public function dump(Config $config, InstalledRepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir, $scanPsr0Packages = false, $suffix = '')
    {
        $filesystem = new Filesystem();
        $filesystem->ensureDirectoryExists($config->get('vendor-dir'));
        $basePath = $filesystem->normalizePath(getcwd());
        $vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir')));
        $useGlobalIncludePath = (bool) $config->get('use-include-path');
        $targetDir = $vendorPath . '/' . $targetDir;
        $filesystem->ensureDirectoryExists($targetDir);
        $vendorPathCode = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true);
        $vendorPathCode52 = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathCode);
        $vendorPathToTargetDirCode = $filesystem->findShortestPathCode($vendorPath, realpath($targetDir), true);
        $appBaseDirCode = $filesystem->findShortestPathCode($vendorPath, $basePath, true);
        $appBaseDirCode = str_replace('__DIR__', '$vendorDir', $appBaseDirCode);
        $namespacesFile = <<<EOF
<?php

// autoload_namespaces.php generated by Composer

\$vendorDir = {$vendorPathCode52};
\$baseDir = {$appBaseDirCode};

return array(

EOF;
        $packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getCanonicalPackages());
        $autoloads = $this->parseAutoloads($packageMap, $mainPackage);
        foreach ($autoloads['psr-0'] as $namespace => $paths) {
            $exportedPaths = array();
            foreach ($paths as $path) {
                $exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
            }
            $exportedPrefix = var_export($namespace, true);
            $namespacesFile .= "    {$exportedPrefix} => ";
            if (count($exportedPaths) > 1) {
                $namespacesFile .= "array(" . implode(', ', $exportedPaths) . "),\n";
            } else {
                $namespacesFile .= $exportedPaths[0] . ",\n";
            }
        }
        $namespacesFile .= ");\n";
        $classmapFile = <<<EOF
<?php

// autoload_classmap.php generated by Composer

\$vendorDir = {$vendorPathCode52};
\$baseDir = {$appBaseDirCode};

return array(

EOF;
        // add custom psr-0 autoloading if the root package has a target dir
        $targetDirLoader = null;
        $mainAutoload = $mainPackage->getAutoload();
        if ($mainPackage->getTargetDir() && !empty($mainAutoload['psr-0'])) {
            $levels = count(explode('/', $filesystem->normalizePath($mainPackage->getTargetDir())));
            $prefixes = implode(', ', array_map(function ($prefix) {
                return var_export($prefix, true);
            }, array_keys($mainAutoload['psr-0'])));
            $baseDirFromTargetDirCode = $filesystem->findShortestPathCode($targetDir, $basePath, true);
            $targetDirLoader = <<<EOF

    public static function autoload(\$class)
    {
        \$dir = {$baseDirFromTargetDirCode} . '/';
        \$prefixes = array({$prefixes});
        foreach (\$prefixes as \$prefix) {
            if (0 !== strpos(\$class, \$prefix)) {
                continue;
            }
            \$path = \$dir . implode('/', array_slice(explode('\\\\', \$class), {$levels})).'.php';
            if (!\$path = stream_resolve_include_path(\$path)) {
                return false;
            }
            require \$path;

            return true;
        }
    }

EOF;
        }
        // flatten array
        $classMap = array();
        if ($scanPsr0Packages) {
            foreach ($autoloads['psr-0'] as $namespace => $paths) {
                foreach ($paths as $dir) {
                    $dir = $filesystem->normalizePath($filesystem->isAbsolutePath($dir) ? $dir : $basePath . '/' . $dir);
                    if (!is_dir($dir)) {
                        continue;
                    }
                    $whitelist = sprintf('{%s/%s.+(?<!(?<!/)Test\\.php)$}', preg_quote($dir), strpos($namespace, '_') === false ? preg_quote(strtr($namespace, '\\', '/')) : '');
                    foreach (ClassMapGenerator::createMap($dir, $whitelist) as $class => $path) {
                        if ('' === $namespace || 0 === strpos($class, $namespace)) {
                            if (!isset($classMap[$class])) {
                                $path = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
                                $classMap[$class] = $path . ",\n";
                            }
                        }
                    }
                }
            }
        }
        $autoloads['classmap'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['classmap']));
        foreach ($autoloads['classmap'] as $dir) {
            foreach (ClassMapGenerator::createMap($dir) as $class => $path) {
                $path = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
                $classMap[$class] = $path . ",\n";
            }
        }
        ksort($classMap);
        foreach ($classMap as $class => $code) {
            $classmapFile .= '    ' . var_export($class, true) . ' => ' . $code;
        }
        $classmapFile .= ");\n";
        $filesCode = "";
        $autoloads['files'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['files']));
        foreach ($autoloads['files'] as $functionFile) {
            $filesCode .= '        require ' . $this->getPathCode($filesystem, $basePath, $vendorPath, $functionFile) . ";\n";
        }
        if (!$suffix) {
            $suffix = md5(uniqid('', true));
        }
        file_put_contents($targetDir . '/autoload_namespaces.php', $namespacesFile);
        file_put_contents($targetDir . '/autoload_classmap.php', $classmapFile);
        if ($includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) {
            file_put_contents($targetDir . '/include_paths.php', $includePathFile);
        }
        file_put_contents($vendorPath . '/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix));
        file_put_contents($targetDir . '/autoload_real.php', $this->getAutoloadRealFile(true, true, (bool) $includePathFile, $targetDirLoader, $filesCode, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath));
        // use stream_copy_to_stream instead of copy
        // to work around https://bugs.php.net/bug.php?id=64634
        $sourceLoader = fopen(__DIR__ . '/ClassLoader.php', 'r');
        $targetLoader = fopen($targetDir . '/ClassLoader.php', 'w+');
        stream_copy_to_stream($sourceLoader, $targetLoader);
        fclose($sourceLoader);
        fclose($targetLoader);
        unset($sourceLoader, $targetLoader);
        $this->eventDispatcher->dispatch(ScriptEvents::POST_AUTOLOAD_DUMP);
    }
示例#2
0
 protected function doInstall($localRepo, $installedRepo, $aliases, $devMode = false)
 {
     $minimumStability = $this->package->getMinimumStability();
     $stabilityFlags = $this->package->getStabilityFlags();
     // init vars
     $lockedRepository = null;
     $repositories = null;
     // initialize locker to create aliased packages
     $installFromLock = false;
     if (!$this->update && $this->locker->isLocked($devMode)) {
         $installFromLock = true;
         $lockedRepository = $this->locker->getLockedRepository($devMode);
         $minimumStability = $this->locker->getMinimumStability();
         $stabilityFlags = $this->locker->getStabilityFlags();
     }
     $this->whitelistUpdateDependencies($localRepo, $devMode, $this->package->getRequires(), $this->package->getDevRequires());
     $this->io->write('<info>Loading composer repositories with package information</info>');
     // creating repository pool
     $policy = new DefaultPolicy();
     $pool = new Pool($minimumStability, $stabilityFlags);
     $pool->addRepository($installedRepo, $aliases);
     if ($installFromLock) {
         $pool->addRepository($lockedRepository, $aliases);
     }
     if (!$installFromLock || !$this->locker->isCompleteFormat($devMode)) {
         $repositories = $this->repositoryManager->getRepositories();
         foreach ($repositories as $repository) {
             $pool->addRepository($repository, $aliases);
         }
     }
     // creating requirements request
     $request = new Request($pool);
     $constraint = new VersionConstraint('=', $this->package->getVersion());
     $constraint->setPrettyString($this->package->getPrettyVersion());
     $request->install($this->package->getName(), $constraint);
     if ($this->update) {
         $this->io->write('<info>Updating ' . ($devMode ? 'dev ' : '') . 'dependencies</info>');
         $request->updateAll();
         $links = $devMode ? $this->package->getDevRequires() : $this->package->getRequires();
         foreach ($links as $link) {
             $request->install($link->getTarget(), $link->getConstraint());
         }
     } elseif ($installFromLock) {
         $this->io->write('<info>Installing ' . ($devMode ? 'dev ' : '') . 'dependencies from lock file</info>');
         if (!$this->locker->isCompleteFormat($devMode)) {
             $this->io->write('<warning>Warning: Your lock file is in a deprecated format. It will most likely take a *long* time for composer to install dependencies, and may cause dependency solving issues.</warning>');
         }
         if (!$this->locker->isFresh() && !$devMode) {
             $this->io->write('<warning>Warning: The lock file is not up to date with the latest changes in composer.json, you may be getting outdated dependencies, run update to update them.</warning>');
         }
         foreach ($lockedRepository->getPackages() as $package) {
             $version = $package->getVersion();
             if (isset($aliases[$package->getName()][$version])) {
                 $version = $aliases[$package->getName()][$version]['alias_normalized'];
             }
             $constraint = new VersionConstraint('=', $version);
             $constraint->setPrettyString($package->getPrettyVersion());
             $request->install($package->getName(), $constraint);
         }
     } else {
         $this->io->write('<info>Installing ' . ($devMode ? 'dev ' : '') . 'dependencies</info>');
         $links = $devMode ? $this->package->getDevRequires() : $this->package->getRequires();
         foreach ($links as $link) {
             $request->install($link->getTarget(), $link->getConstraint());
         }
     }
     // fix the version of all installed packages (+ platform) that are not
     // in the current local repo to prevent rogue updates (e.g. non-dev
     // updating when in dev)
     foreach ($installedRepo->getPackages() as $package) {
         if ($package->getRepository() === $localRepo) {
             continue;
         }
         $constraint = new VersionConstraint('=', $package->getVersion());
         $constraint->setPrettyString($package->getPrettyVersion());
         $request->install($package->getName(), $constraint);
     }
     // if the updateWhitelist is enabled, packages not in it are also fixed
     // to the version specified in the lock, or their currently installed version
     if ($this->update && $this->updateWhitelist) {
         if ($this->locker->isLocked($devMode)) {
             $currentPackages = $this->locker->getLockedRepository($devMode)->getPackages();
         } else {
             $currentPackages = $installedRepo->getPackages();
         }
         // collect links from composer as well as installed packages
         $candidates = array();
         foreach ($links as $link) {
             $candidates[$link->getTarget()] = true;
         }
         foreach ($localRepo->getPackages() as $package) {
             $candidates[$package->getName()] = true;
         }
         // fix them to the version in lock (or currently installed) if they are not updateable
         foreach ($candidates as $candidate => $dummy) {
             foreach ($currentPackages as $curPackage) {
                 if ($curPackage->getName() === $candidate) {
                     if ($this->isUpdateable($curPackage)) {
                         break;
                     }
                     $constraint = new VersionConstraint('=', $curPackage->getVersion());
                     $request->install($curPackage->getName(), $constraint);
                 }
             }
         }
     }
     // force dev packages to have the latest links if we update or install from a (potentially new) lock
     $this->processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, 'force-links');
     // solve dependencies
     $solver = new Solver($policy, $pool, $installedRepo);
     try {
         $operations = $solver->solve($request);
     } catch (SolverProblemsException $e) {
         $this->io->write('<error>Your requirements could not be resolved to an installable set of packages.</error>');
         $this->io->write($e->getMessage());
         return false;
     }
     if ($devMode) {
         // remove bogus operations that the solver creates for stuff that was force-updated in the non-dev pass
         // TODO this should not be necessary ideally, but it seems to work around the problem quite well
         foreach ($operations as $index => $op) {
             if ('update' === $op->getJobType() && $op->getInitialPackage()->getUniqueName() === $op->getTargetPackage()->getUniqueName() && $op->getInitialPackage()->getSourceReference() === $op->getTargetPackage()->getSourceReference() && $op->getInitialPackage()->getDistReference() === $op->getTargetPackage()->getDistReference()) {
                 unset($operations[$index]);
             }
         }
     }
     // force dev packages to be updated if we update or install from a (potentially new) lock
     $operations = $this->processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, 'force-updates', $operations);
     // execute operations
     if (!$operations) {
         $this->io->write('Nothing to install or update');
     }
     foreach ($operations as $operation) {
         // collect suggestions
         if ('install' === $operation->getJobType()) {
             foreach ($operation->getPackage()->getSuggests() as $target => $reason) {
                 $this->suggestedPackages[] = array('source' => $operation->getPackage()->getPrettyName(), 'target' => $target, 'reason' => $reason);
             }
         }
         $event = 'Composer\\Script\\ScriptEvents::PRE_PACKAGE_' . strtoupper($operation->getJobType());
         if (defined($event) && $this->runScripts) {
             $this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $operation);
         }
         // not installing from lock, force dev packages' references if they're in root package refs
         if (!$installFromLock) {
             $package = null;
             if ('update' === $operation->getJobType()) {
                 $package = $operation->getTargetPackage();
             } elseif ('install' === $operation->getJobType()) {
                 $package = $operation->getPackage();
             }
             if ($package && $package->isDev()) {
                 $references = $this->package->getReferences();
                 if (isset($references[$package->getName()])) {
                     $package->setSourceReference($references[$package->getName()]);
                     $package->setDistReference($references[$package->getName()]);
                 }
             }
         }
         // output alias operations in verbose mode, or all ops in dry run
         if ($this->dryRun || $this->verbose && false !== strpos($operation->getJobType(), 'Alias')) {
             $this->io->write('  - ' . $operation);
         }
         $this->installationManager->execute($localRepo, $operation);
         $event = 'Composer\\Script\\ScriptEvents::POST_PACKAGE_' . strtoupper($operation->getJobType());
         if (defined($event) && $this->runScripts) {
             $this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $operation);
         }
         if (!$this->dryRun) {
             $localRepo->write();
         }
     }
     return true;
 }
示例#3
0
 protected function doInstall($localRepo, $installedRepo, $platformRepo, $aliases, $withDevReqs)
 {
     // init vars
     $lockedRepository = null;
     $repositories = null;
     // initialize locker to create aliased packages
     $installFromLock = false;
     if (!$this->update && $this->locker->isLocked()) {
         $installFromLock = true;
         try {
             $lockedRepository = $this->locker->getLockedRepository($withDevReqs);
         } catch (\RuntimeException $e) {
             // if there are dev requires, then we really can not install
             if ($this->package->getDevRequires()) {
                 throw $e;
             }
             // no require-dev in composer.json and the lock file was created with no dev info, so skip them
             $lockedRepository = $this->locker->getLockedRepository();
         }
     }
     $this->whitelistUpdateDependencies($localRepo, $withDevReqs, $this->package->getRequires(), $this->package->getDevRequires());
     $this->io->write('<info>Loading composer repositories with package information</info>');
     // creating repository pool
     $policy = $this->createPolicy();
     $pool = $this->createPool();
     $pool->addRepository($installedRepo, $aliases);
     if ($installFromLock) {
         $pool->addRepository($lockedRepository, $aliases);
     }
     if (!$installFromLock) {
         $repositories = $this->repositoryManager->getRepositories();
         foreach ($repositories as $repository) {
             $pool->addRepository($repository, $aliases);
         }
     }
     // creating requirements request
     $request = $this->createRequest($pool, $this->package, $platformRepo);
     if (!$installFromLock) {
         // remove unstable packages from the localRepo if they don't match the current stability settings
         $removedUnstablePackages = array();
         foreach ($localRepo->getPackages() as $package) {
             if (!$pool->isPackageAcceptable($package->getNames(), $package->getStability()) && $this->installationManager->isPackageInstalled($localRepo, $package)) {
                 $removedUnstablePackages[$package->getName()] = true;
                 $request->remove($package->getName(), new VersionConstraint('=', $package->getVersion()));
             }
         }
     }
     if ($this->update) {
         $this->io->write('<info>Updating dependencies' . ($withDevReqs ? ' (including require-dev)' : '') . '</info>');
         $request->updateAll();
         if ($withDevReqs) {
             $links = array_merge($this->package->getRequires(), $this->package->getDevRequires());
         } else {
             $links = $this->package->getRequires();
         }
         foreach ($links as $link) {
             $request->install($link->getTarget(), $link->getConstraint());
         }
         // if the updateWhitelist is enabled, packages not in it are also fixed
         // to the version specified in the lock, or their currently installed version
         if ($this->updateWhitelist) {
             if ($this->locker->isLocked()) {
                 try {
                     $currentPackages = $this->locker->getLockedRepository($withDevReqs)->getPackages();
                 } catch (\RuntimeException $e) {
                     // fetch only non-dev packages from lock if doing a dev update fails due to a previously incomplete lock file
                     $currentPackages = $this->locker->getLockedRepository()->getPackages();
                 }
             } else {
                 $currentPackages = $installedRepo->getPackages();
             }
             // collect packages to fixate from root requirements as well as installed packages
             $candidates = array();
             foreach ($links as $link) {
                 $candidates[$link->getTarget()] = true;
             }
             foreach ($localRepo->getPackages() as $package) {
                 $candidates[$package->getName()] = true;
             }
             // fix them to the version in lock (or currently installed) if they are not updateable
             foreach ($candidates as $candidate => $dummy) {
                 foreach ($currentPackages as $curPackage) {
                     if ($curPackage->getName() === $candidate) {
                         if (!$this->isUpdateable($curPackage) && !isset($removedUnstablePackages[$curPackage->getName()])) {
                             $constraint = new VersionConstraint('=', $curPackage->getVersion());
                             $request->install($curPackage->getName(), $constraint);
                         }
                         break;
                     }
                 }
             }
         }
     } elseif ($installFromLock) {
         $this->io->write('<info>Installing dependencies' . ($withDevReqs ? ' (including require-dev)' : '') . ' from lock file</info>');
         if (!$this->locker->isFresh()) {
             $this->io->write('<warning>Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.</warning>');
         }
         foreach ($lockedRepository->getPackages() as $package) {
             $version = $package->getVersion();
             if (isset($aliases[$package->getName()][$version])) {
                 $version = $aliases[$package->getName()][$version]['alias_normalized'];
             }
             $constraint = new VersionConstraint('=', $version);
             $constraint->setPrettyString($package->getPrettyVersion());
             $request->install($package->getName(), $constraint);
         }
         foreach ($this->locker->getPlatformRequirements($withDevReqs) as $link) {
             $request->install($link->getTarget(), $link->getConstraint());
         }
     } else {
         $this->io->write('<info>Installing dependencies' . ($withDevReqs ? ' (including require-dev)' : '') . '</info>');
         if ($withDevReqs) {
             $links = array_merge($this->package->getRequires(), $this->package->getDevRequires());
         } else {
             $links = $this->package->getRequires();
         }
         foreach ($links as $link) {
             $request->install($link->getTarget(), $link->getConstraint());
         }
     }
     // force dev packages to have the latest links if we update or install from a (potentially new) lock
     $this->processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, 'force-links');
     // solve dependencies
     $solver = new Solver($policy, $pool, $installedRepo);
     try {
         $operations = $solver->solve($request);
     } catch (SolverProblemsException $e) {
         $this->io->write('<error>Your requirements could not be resolved to an installable set of packages.</error>');
         $this->io->write($e->getMessage());
         return false;
     }
     // force dev packages to be updated if we update or install from a (potentially new) lock
     $operations = $this->processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, 'force-updates', $operations);
     // execute operations
     if (!$operations) {
         $this->io->write('Nothing to install or update');
     }
     foreach ($operations as $operation) {
         // collect suggestions
         if ('install' === $operation->getJobType()) {
             foreach ($operation->getPackage()->getSuggests() as $target => $reason) {
                 $this->suggestedPackages[] = array('source' => $operation->getPackage()->getPrettyName(), 'target' => $target, 'reason' => $reason);
             }
         }
         $event = 'Composer\\Script\\ScriptEvents::PRE_PACKAGE_' . strtoupper($operation->getJobType());
         if (defined($event) && $this->runScripts) {
             $this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $operation);
         }
         // not installing from lock, force dev packages' references if they're in root package refs
         if (!$installFromLock) {
             $package = null;
             if ('update' === $operation->getJobType()) {
                 $package = $operation->getTargetPackage();
             } elseif ('install' === $operation->getJobType()) {
                 $package = $operation->getPackage();
             }
             if ($package && $package->isDev()) {
                 $references = $this->package->getReferences();
                 if (isset($references[$package->getName()])) {
                     $package->setSourceReference($references[$package->getName()]);
                     $package->setDistReference($references[$package->getName()]);
                 }
             }
         }
         // output alias operations in verbose mode, or all ops in dry run
         if ($this->dryRun || $this->verbose && false !== strpos($operation->getJobType(), 'Alias')) {
             $this->io->write('  - ' . $operation);
         }
         $this->installationManager->execute($localRepo, $operation);
         $event = 'Composer\\Script\\ScriptEvents::POST_PACKAGE_' . strtoupper($operation->getJobType());
         if (defined($event) && $this->runScripts) {
             $this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $operation);
         }
         if (!$this->dryRun) {
             $localRepo->write();
         }
     }
     return true;
 }
示例#4
0
 protected function doInstall($localRepo, $installedRepo, $aliases, $devMode = false)
 {
     $minimumStability = $this->package->getMinimumStability();
     $stabilityFlags = $this->package->getStabilityFlags();
     // initialize locker to create aliased packages
     if (!$this->update && $this->locker->isLocked($devMode)) {
         $lockedPackages = $this->locker->getLockedPackages($devMode);
         $minimumStability = $this->locker->getMinimumStability();
         $stabilityFlags = $this->locker->getStabilityFlags();
     }
     $this->whitelistUpdateDependencies($localRepo, $devMode, $this->package->getRequires(), $this->package->getDevRequires());
     $this->io->write('<info>Loading composer repositories with package information</info>');
     // creating repository pool
     $pool = new Pool($minimumStability, $stabilityFlags);
     $pool->addRepository($installedRepo);
     foreach ($this->repositoryManager->getRepositories() as $repository) {
         $pool->addRepository($repository);
     }
     // creating requirements request
     $installFromLock = false;
     $request = new Request($pool);
     $constraint = new VersionConstraint('=', $this->package->getVersion());
     $request->install($this->package->getName(), $constraint);
     if ($this->update) {
         $this->io->write('<info>Updating ' . ($devMode ? 'dev ' : '') . 'dependencies</info>');
         $request->updateAll();
         $links = $devMode ? $this->package->getDevRequires() : $this->package->getRequires();
         foreach ($links as $link) {
             $request->install($link->getTarget(), $link->getConstraint());
         }
     } elseif ($this->locker->isLocked($devMode)) {
         $installFromLock = true;
         $this->io->write('<info>Installing ' . ($devMode ? 'dev ' : '') . 'dependencies from lock file</info>');
         if (!$this->locker->isFresh() && !$devMode) {
             $this->io->write('<warning>Your lock file is out of sync with your composer.json, run "composer.phar update" to update dependencies</warning>');
         }
         foreach ($lockedPackages as $package) {
             $version = $package->getVersion();
             foreach ($aliases as $alias) {
                 if ($alias['package'] === $package->getName() && $alias['version'] === $package->getVersion()) {
                     $version = $alias['alias_normalized'];
                     break;
                 }
             }
             $constraint = new VersionConstraint('=', $version);
             $request->install($package->getName(), $constraint);
         }
     } else {
         $this->io->write('<info>Installing ' . ($devMode ? 'dev ' : '') . 'dependencies</info>');
         $links = $devMode ? $this->package->getDevRequires() : $this->package->getRequires();
         foreach ($links as $link) {
             $request->install($link->getTarget(), $link->getConstraint());
         }
     }
     // fix the version of all installed packages (+ platform) that are not
     // in the current local repo to prevent rogue updates (e.g. non-dev
     // updating when in dev)
     foreach ($installedRepo->getPackages() as $package) {
         if ($package->getRepository() === $localRepo) {
             continue;
         }
         $constraint = new VersionConstraint('=', $package->getVersion());
         $request->install($package->getName(), $constraint);
     }
     // if the updateWhitelist is enabled, packages not in it are also fixed
     // to the version specified in the lock, or their currently installed version
     if ($this->update && $this->updateWhitelist) {
         if ($this->locker->isLocked($devMode)) {
             $currentPackages = $this->locker->getLockedPackages($devMode);
         } else {
             $currentPackages = $installedRepo->getPackages();
         }
         // collect links from composer as well as installed packages
         $candidates = array();
         foreach ($links as $link) {
             $candidates[$link->getTarget()] = true;
         }
         foreach ($localRepo->getPackages() as $package) {
             $candidates[$package->getName()] = true;
         }
         // fix them to the version in lock (or currently installed) if they are not updateable
         foreach ($candidates as $candidate => $dummy) {
             foreach ($currentPackages as $curPackage) {
                 if ($curPackage->getName() === $candidate) {
                     if ($this->isUpdateable($curPackage)) {
                         break;
                     }
                     $constraint = new VersionConstraint('=', $curPackage->getVersion());
                     $request->install($curPackage->getName(), $constraint);
                 }
             }
         }
     }
     // prepare solver
     $policy = new DefaultPolicy();
     $solver = new Solver($policy, $pool, $installedRepo);
     // solve dependencies
     try {
         $operations = $solver->solve($request);
     } catch (SolverProblemsException $e) {
         $this->io->write('<error>Your requirements could not be resolved to an installable set of packages.</error>');
         $this->io->write($e->getMessage());
         return false;
     }
     // force dev packages to be updated if we update or install from a (potentially new) lock
     foreach ($localRepo->getPackages() as $package) {
         // skip non-dev packages
         if (!$package->isDev()) {
             continue;
         }
         // skip packages that will be updated/uninstalled
         foreach ($operations as $operation) {
             if ('update' === $operation->getJobType() && $operation->getInitialPackage()->equals($package) || 'uninstall' === $operation->getJobType() && $operation->getPackage()->equals($package)) {
                 continue 2;
             }
         }
         // force update to locked version if it does not match the installed version
         if ($installFromLock) {
             $lockData = $this->locker->getLockData();
             unset($lockedReference);
             foreach ($lockData['packages'] as $lockedPackage) {
                 if (!empty($lockedPackage['source-reference']) && strtolower($lockedPackage['package']) === $package->getName()) {
                     $lockedReference = $lockedPackage['source-reference'];
                     break;
                 }
             }
             if (isset($lockedReference) && $lockedReference !== $package->getSourceReference()) {
                 // changing the source ref to update to will be handled in the operations loop below
                 $operations[] = new UpdateOperation($package, clone $package);
             }
         } else {
             // force update to latest on update
             if ($this->update) {
                 // skip package if the whitelist is enabled and it is not in it
                 if ($this->updateWhitelist && !$this->isUpdateable($package)) {
                     continue;
                 }
                 $newPackage = $this->repositoryManager->findPackage($package->getName(), $package->getVersion());
                 if ($newPackage && $newPackage->getSourceReference() !== $package->getSourceReference()) {
                     $operations[] = new UpdateOperation($package, $newPackage);
                 }
             }
             // force installed package to update to referenced version if it does not match the installed version
             $references = $this->package->getReferences();
             if (isset($references[$package->getName()]) && $references[$package->getName()] !== $package->getSourceReference()) {
                 // changing the source ref to update to will be handled in the operations loop below
                 $operations[] = new UpdateOperation($package, clone $package);
             }
         }
     }
     // execute operations
     if (!$operations) {
         $this->io->write('Nothing to install or update');
     }
     foreach ($operations as $operation) {
         // collect suggestions
         if ('install' === $operation->getJobType()) {
             foreach ($operation->getPackage()->getSuggests() as $target => $reason) {
                 $this->suggestedPackages[] = array('source' => $operation->getPackage()->getPrettyName(), 'target' => $target, 'reason' => $reason);
             }
         }
         $event = 'Composer\\Script\\ScriptEvents::PRE_PACKAGE_' . strtoupper($operation->getJobType());
         if (defined($event) && $this->runScripts) {
             $this->eventDispatcher->dispatchPackageEvent(constant($event), $operation);
         }
         // if installing from lock, restore dev packages' references to their locked state
         if ($installFromLock) {
             $package = null;
             if ('update' === $operation->getJobType()) {
                 $package = $operation->getTargetPackage();
             } elseif ('install' === $operation->getJobType()) {
                 $package = $operation->getPackage();
             }
             if ($package && $package->isDev()) {
                 $lockData = $this->locker->getLockData();
                 foreach ($lockData['packages'] as $lockedPackage) {
                     if (!empty($lockedPackage['source-reference']) && strtolower($lockedPackage['package']) === $package->getName()) {
                         // update commit date to allow recovery in case the commit disappeared
                         if (!empty($lockedPackage['commit-date'])) {
                             $package->setReleaseDate(new \DateTime('@' . $lockedPackage['commit-date']));
                         }
                         $package->setSourceReference($lockedPackage['source-reference']);
                         break;
                     }
                 }
             }
         } else {
             // not installing from lock, force dev packages' references if they're in root package refs
             $package = null;
             if ('update' === $operation->getJobType()) {
                 $package = $operation->getTargetPackage();
             } elseif ('install' === $operation->getJobType()) {
                 $package = $operation->getPackage();
             }
             if ($package && $package->isDev()) {
                 $references = $this->package->getReferences();
                 if (isset($references[$package->getName()])) {
                     $package->setSourceReference($references[$package->getName()]);
                 }
             }
         }
         // output alias operations in verbose mode, or all ops in dry run
         if ($this->dryRun || $this->verbose && false !== strpos($operation->getJobType(), 'Alias')) {
             $this->io->write('  - ' . $operation);
         }
         $this->installationManager->execute($localRepo, $operation);
         $event = 'Composer\\Script\\ScriptEvents::POST_PACKAGE_' . strtoupper($operation->getJobType());
         if (defined($event) && $this->runScripts) {
             $this->eventDispatcher->dispatchPackageEvent(constant($event), $operation);
         }
         if (!$this->dryRun) {
             $localRepo->write();
         }
     }
     return true;
 }
示例#5
0
 protected function doInstall($localRepo, $installedRepo, $aliases, $devMode = false)
 {
     // creating repository pool
     $pool = new Pool();
     $pool->addRepository($installedRepo);
     foreach ($this->repositoryManager->getRepositories() as $repository) {
         $pool->addRepository($repository);
     }
     // creating requirements request
     $installFromLock = false;
     $request = new Request($pool);
     if ($this->update) {
         $this->io->write('<info>Updating ' . ($devMode ? 'dev ' : '') . 'dependencies</info>');
         $request->updateAll();
         $links = $devMode ? $this->package->getDevRequires() : $this->package->getRequires();
         foreach ($links as $link) {
             $request->install($link->getTarget(), $link->getConstraint());
         }
     } elseif ($this->locker->isLocked($devMode)) {
         $installFromLock = true;
         $this->io->write('<info>Installing ' . ($devMode ? 'dev ' : '') . 'dependencies from lock file</info>');
         if (!$this->locker->isFresh() && !$devMode) {
             $this->io->write('<warning>Your lock file is out of sync with your composer.json, run "composer.phar update" to update dependencies</warning>');
         }
         foreach ($this->locker->getLockedPackages($devMode) as $package) {
             $version = $package->getVersion();
             foreach ($aliases as $alias) {
                 if ($alias['package'] === $package->getName() && $alias['version'] === $package->getVersion()) {
                     $version = $alias['alias'];
                     break;
                 }
             }
             $constraint = new VersionConstraint('=', $version);
             $request->install($package->getName(), $constraint);
         }
     } else {
         $this->io->write('<info>Installing ' . ($devMode ? 'dev ' : '') . 'dependencies</info>');
         $links = $devMode ? $this->package->getDevRequires() : $this->package->getRequires();
         foreach ($links as $link) {
             $request->install($link->getTarget(), $link->getConstraint());
         }
     }
     // fix the version all installed packages that are not in the current local repo to prevent rogue updates
     foreach ($installedRepo->getPackages() as $package) {
         if ($package->getRepository() === $localRepo || $package->getRepository() instanceof PlatformRepository) {
             continue;
         }
         $constraint = new VersionConstraint('=', $package->getVersion());
         $request->install($package->getName(), $constraint);
     }
     // prepare solver
     $policy = new DefaultPolicy();
     $solver = new Solver($policy, $pool, $installedRepo);
     // solve dependencies
     try {
         $operations = $solver->solve($request);
     } catch (SolverProblemsException $e) {
         $this->io->write('<error>Your requirements could not be solved to an installable set of packages.</error>');
         $this->io->write($e->getMessage());
         return false;
     }
     // force dev packages to be updated if we update or install from a (potentially new) lock
     if ($this->update || $installFromLock) {
         foreach ($localRepo->getPackages() as $package) {
             // skip non-dev packages
             if (!$package->isDev()) {
                 continue;
             }
             // skip packages that will be updated/uninstalled
             foreach ($operations as $operation) {
                 if ('update' === $operation->getJobType() && $operation->getInitialPackage()->equals($package) || 'uninstall' === $operation->getJobType() && $operation->getPackage()->equals($package)) {
                     continue 2;
                 }
             }
             // force update to latest on update
             if ($this->update) {
                 $newPackage = $this->repositoryManager->findPackage($package->getName(), $package->getVersion());
                 if ($newPackage && $newPackage->getSourceReference() !== $package->getSourceReference()) {
                     $operations[] = new UpdateOperation($package, $newPackage);
                 }
             } elseif ($installFromLock) {
                 // force update to locked version if it does not match the installed version
                 $lockData = $this->locker->getLockData();
                 unset($lockedReference);
                 foreach ($lockData['packages'] as $lockedPackage) {
                     if (!empty($lockedPackage['source-reference']) && strtolower($lockedPackage['package']) === $package->getName()) {
                         $lockedReference = $lockedPackage['source-reference'];
                         break;
                     }
                 }
                 if (isset($lockedReference) && $lockedReference !== $package->getSourceReference()) {
                     // changing the source ref to update to will be handled in the operations loop below
                     $operations[] = new UpdateOperation($package, $package);
                 }
             }
         }
     }
     // anti-alias local repository to allow updates to work fine
     foreach ($localRepo->getPackages() as $package) {
         if ($package instanceof AliasPackage) {
             $package->getRepository()->addPackage(clone $package->getAliasOf());
             $package->getRepository()->removePackage($package);
         }
     }
     // execute operations
     if (!$operations) {
         $this->io->write('Nothing to install or update');
     }
     foreach ($operations as $operation) {
         if ($this->verbose) {
             $this->io->write((string) $operation);
         }
         // collect suggestions
         if ('install' === $operation->getJobType()) {
             foreach ($operation->getPackage()->getSuggests() as $target => $reason) {
                 $this->suggestedPackages[] = array('source' => $operation->getPackage()->getPrettyName(), 'target' => $target, 'reason' => $reason);
             }
         }
         if (!$this->dryRun) {
             $this->eventDispatcher->dispatchPackageEvent(constant('Composer\\Script\\ScriptEvents::PRE_PACKAGE_' . strtoupper($operation->getJobType())), $operation);
             // if installing from lock, restore dev packages' references to their locked state
             if ($installFromLock) {
                 $package = null;
                 if ('update' === $operation->getJobType()) {
                     $package = $operation->getTargetPackage();
                 } elseif ('install' === $operation->getJobType()) {
                     $package = $operation->getPackage();
                 }
                 if ($package && $package->isDev()) {
                     $lockData = $this->locker->getLockData();
                     foreach ($lockData['packages'] as $lockedPackage) {
                         if (!empty($lockedPackage['source-reference']) && strtolower($lockedPackage['package']) === $package->getName()) {
                             $package->setSourceReference($lockedPackage['source-reference']);
                             break;
                         }
                     }
                 }
             }
             $this->installationManager->execute($localRepo, $operation);
             $this->eventDispatcher->dispatchPackageEvent(constant('Composer\\Script\\ScriptEvents::POST_PACKAGE_' . strtoupper($operation->getJobType())), $operation);
             $localRepo->write();
         }
     }
     // reload local repository for the dev pass to work ok with aliases since it was anti-aliased above
     if (!$devMode) {
         $localRepo->reload();
     }
     return true;
 }
示例#6
0
 public function install(IOInterface $io, Composer $composer, EventDispatcher $eventDispatcher, $preferSource = false, $dryRun = false, $verbose = false, $noInstallRecommends = false, $installSuggests = false, $update = false, RepositoryInterface $additionalInstalledRepository = null)
 {
     if ($dryRun) {
         $verbose = true;
     }
     if ($preferSource) {
         $composer->getDownloadManager()->setPreferSource(true);
     }
     // create local repo, this contains all packages that are installed in the local project
     $localRepo = $composer->getRepositoryManager()->getLocalRepository();
     // create installed repo, this contains all local packages + platform packages (php & extensions)
     $installedRepo = new CompositeRepository(array($localRepo, new PlatformRepository()));
     if ($additionalInstalledRepository) {
         $installedRepo->addRepository($additionalInstalledRepository);
     }
     // creating repository pool
     $pool = new Pool();
     $pool->addRepository($installedRepo);
     foreach ($composer->getRepositoryManager()->getRepositories() as $repository) {
         $pool->addRepository($repository);
     }
     // dispatch pre event
     if (!$dryRun) {
         $eventName = $update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD;
         $eventDispatcher->dispatchCommandEvent($eventName);
     }
     // creating requirements request
     $installFromLock = false;
     $request = new Request($pool);
     if ($update) {
         $io->write('<info>Updating dependencies</info>');
         $installedPackages = $installedRepo->getPackages();
         $links = $this->collectLinks($composer->getPackage(), $noInstallRecommends, $installSuggests);
         $request->updateAll();
         foreach ($links as $link) {
             $request->install($link->getTarget(), $link->getConstraint());
         }
     } elseif ($composer->getLocker()->isLocked()) {
         $installFromLock = true;
         $io->write('<info>Installing from lock file</info>');
         if (!$composer->getLocker()->isFresh()) {
             $io->write('<warning>Your lock file is out of sync with your composer.json, run "composer.phar update" to update dependencies</warning>');
         }
         foreach ($composer->getLocker()->getLockedPackages() as $package) {
             $constraint = new VersionConstraint('=', $package->getVersion());
             $request->install($package->getName(), $constraint);
         }
     } else {
         $io->write('<info>Installing dependencies</info>');
         $links = $this->collectLinks($composer->getPackage(), $noInstallRecommends, $installSuggests);
         foreach ($links as $link) {
             $request->install($link->getTarget(), $link->getConstraint());
         }
     }
     // prepare solver
     $installationManager = $composer->getInstallationManager();
     $policy = new DependencyResolver\DefaultPolicy();
     $solver = new DependencyResolver\Solver($policy, $pool, $installedRepo);
     // solve dependencies
     $operations = $solver->solve($request);
     // execute operations
     if (!$operations) {
         $io->write('<info>Nothing to install/update</info>');
     }
     // force dev packages to be updated to latest reference on update
     if ($update) {
         foreach ($localRepo->getPackages() as $package) {
             // skip non-dev packages
             if (!$package->isDev()) {
                 continue;
             }
             // skip packages that will be updated/uninstalled
             foreach ($operations as $operation) {
                 if ('update' === $operation->getJobType() && $package === $operation->getInitialPackage() || 'uninstall' === $operation->getJobType() && $package === $operation->getPackage()) {
                     continue 2;
                 }
             }
             // force update
             $newPackage = $composer->getRepositoryManager()->findPackage($package->getName(), $package->getVersion());
             if ($newPackage && $newPackage->getSourceReference() !== $package->getSourceReference()) {
                 $operations[] = new UpdateOperation($package, $newPackage);
             }
         }
     }
     foreach ($operations as $operation) {
         if ($verbose) {
             $io->write((string) $operation);
         }
         if (!$dryRun) {
             $eventDispatcher->dispatchPackageEvent(constant('Composer\\Script\\ScriptEvents::PRE_PACKAGE_' . strtoupper($operation->getJobType())), $operation);
             // if installing from lock, restore dev packages' references to their locked state
             if ($installFromLock) {
                 $package = null;
                 if ('update' === $operation->getJobType()) {
                     $package = $operation->getTargetPackage();
                 } elseif ('install' === $operation->getJobType()) {
                     $package = $operation->getPackage();
                 }
                 if ($package && $package->isDev()) {
                     $lockData = $composer->getLocker()->getLockData();
                     foreach ($lockData['packages'] as $lockedPackage) {
                         if (!empty($lockedPackage['source-reference']) && strtolower($lockedPackage['package']) === $package->getName()) {
                             $package->setSourceReference($lockedPackage['source-reference']);
                             break;
                         }
                     }
                 }
             }
             $installationManager->execute($operation);
             $eventDispatcher->dispatchPackageEvent(constant('Composer\\Script\\ScriptEvents::POST_PACKAGE_' . strtoupper($operation->getJobType())), $operation);
         }
     }
     if (!$dryRun) {
         if ($update || !$composer->getLocker()->isLocked()) {
             $composer->getLocker()->lockPackages($localRepo->getPackages());
             $io->write('<info>Writing lock file</info>');
         }
         $localRepo->write();
         $io->write('<info>Generating autoload files</info>');
         $generator = new AutoloadGenerator();
         $generator->dump($localRepo, $composer->getPackage(), $installationManager, $installationManager->getVendorPath() . '/.composer');
         // dispatch post event
         $eventName = $update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD;
         $eventDispatcher->dispatchCommandEvent($eventName);
     }
 }