Merge branch 'master' into 2.0
commit
a5b178084c
|
@ -276,10 +276,11 @@ Example:
|
||||||
|
|
||||||
All links are optional fields.
|
All links are optional fields.
|
||||||
|
|
||||||
`require` and `require-dev` additionally support stability flags ([root-only](04-schema.md#root-package)).
|
`require` and `require-dev` additionally support _stability flags_ ([root-only](04-schema.md#root-package)).
|
||||||
|
They take the form "_constraint_@_stability flag_".
|
||||||
These allow you to further restrict or expand the stability of a package beyond
|
These allow you to further restrict or expand the stability of a package beyond
|
||||||
the scope of the [minimum-stability](#minimum-stability) setting. You can apply
|
the scope of the [minimum-stability](#minimum-stability) setting. You can apply
|
||||||
them to a constraint, or apply them to an empty constraint if you want to
|
them to a constraint, or apply them to an empty _constraint_ if you want to
|
||||||
allow unstable packages of a dependency for example.
|
allow unstable packages of a dependency for example.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
|
@ -111,6 +111,14 @@ To disable packagist:
|
||||||
You can alter repositories in the global config.json file by passing in the
|
You can alter repositories in the global config.json file by passing in the
|
||||||
<info>--global</info> option.
|
<info>--global</info> option.
|
||||||
|
|
||||||
|
To add or edit suggested packages you can use:
|
||||||
|
|
||||||
|
<comment>%command.full_name% suggest.package reason for the suggestion</comment>
|
||||||
|
|
||||||
|
To add or edit extra properties you can use:
|
||||||
|
|
||||||
|
<comment>%command.full_name% extra.property value</comment>
|
||||||
|
|
||||||
To edit the file in an external editor:
|
To edit the file in an external editor:
|
||||||
|
|
||||||
<comment>%command.full_name% --editor</comment>
|
<comment>%command.full_name% --editor</comment>
|
||||||
|
@ -478,6 +486,23 @@ EOT
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
// handle preferred-install per-package config
|
||||||
|
if (preg_match('/^preferred-install\.(.+)/', $settingKey, $matches)) {
|
||||||
|
if ($input->getOption('unset')) {
|
||||||
|
$this->configSource->removeConfigSetting($settingKey);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
list($validator) = $uniqueConfigValues['preferred-install'];
|
||||||
|
if (!$validator($values[0])) {
|
||||||
|
throw new \RuntimeException('Invalid value for '.$settingKey.'. Should be one of: auto, source, or dist');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->configSource->addConfigSetting($settingKey, $values[0]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// handle properties
|
// handle properties
|
||||||
$uniqueProps = array(
|
$uniqueProps = array(
|
||||||
|
@ -601,6 +626,26 @@ EOT
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle suggest
|
||||||
|
if (preg_match('/^suggest\.(.+)/', $settingKey, $matches)) {
|
||||||
|
if ($input->getOption('unset')) {
|
||||||
|
$this->configSource->removeProperty($settingKey);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->configSource->addProperty($settingKey, implode(' ', $values));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle unsetting extra/suggest
|
||||||
|
if (in_array($settingKey, array('suggest', 'extra'), true) && $input->getOption('unset')) {
|
||||||
|
$this->configSource->removeProperty($settingKey);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// handle platform
|
// handle platform
|
||||||
if (preg_match('/^platform\.(.+)/', $settingKey, $matches)) {
|
if (preg_match('/^platform\.(.+)/', $settingKey, $matches)) {
|
||||||
if ($input->getOption('unset')) {
|
if ($input->getOption('unset')) {
|
||||||
|
@ -613,6 +658,8 @@ EOT
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle unsetting platform
|
||||||
if ($settingKey === 'platform' && $input->getOption('unset')) {
|
if ($settingKey === 'platform' && $input->getOption('unset')) {
|
||||||
$this->configSource->removeConfigSetting($settingKey);
|
$this->configSource->removeConfigSetting($settingKey);
|
||||||
|
|
||||||
|
|
|
@ -172,6 +172,8 @@ EOT
|
||||||
$io->write(sprintf('PHP binary path: <comment>%s</comment>', PHP_BINARY));
|
$io->write(sprintf('PHP binary path: <comment>%s</comment>', PHP_BINARY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$io->write(sprintf('OpenSSL version: <comment>%s</comment>', OPENSSL_VERSION_TEXT));
|
||||||
|
|
||||||
return $this->exitCode;
|
return $this->exitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,17 @@ EOT
|
||||||
$output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
|
$output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the CWD was modified, we restore it to what it was initially, as it was
|
||||||
|
// most likely modified by the global command, and we want exec to run in the local working directory
|
||||||
|
// not the global one
|
||||||
|
if (getcwd() !== $this->getApplication()->getInitialWorkingDirectory()) {
|
||||||
|
try {
|
||||||
|
chdir($this->getApplication()->getInitialWorkingDirectory());
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new \RuntimeException('Could not switch back to working directory "'.$this->getApplication()->getWorkingDirectory().'"', 0, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $dispatcher->dispatchScript('__exec_command', true, $input->getArgument('args'));
|
return $dispatcher->dispatchScript('__exec_command', true, $input->getArgument('args'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -438,11 +438,34 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
$versionParser = new VersionParser();
|
$versionParser = new VersionParser();
|
||||||
|
|
||||||
|
// Collect existing packages
|
||||||
|
$composer = $this->getComposer(false);
|
||||||
|
$installedRepo = $composer ? $composer->getRepositoryManager()->getLocalRepository() : null;
|
||||||
|
$existingPackages = [];
|
||||||
|
if ($installedRepo) {
|
||||||
|
foreach ($installedRepo->getPackages() as $package) {
|
||||||
|
$existingPackages[] = $package->getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($requires as $requiredPackage) {
|
||||||
|
$existingPackages[] = substr($requiredPackage, 0, strpos($requiredPackage, ' '));
|
||||||
|
}
|
||||||
|
unset($composer, $installedRepo, $requiredPackage);
|
||||||
|
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
while (null !== $package = $io->ask('Search for a package: ')) {
|
while (null !== $package = $io->ask('Search for a package: ')) {
|
||||||
$matches = $this->findPackages($package);
|
$matches = $this->findPackages($package);
|
||||||
|
|
||||||
if (count($matches)) {
|
if (count($matches)) {
|
||||||
|
// Remove existing packages from search results.
|
||||||
|
foreach ($matches as $position => $foundPackage) {
|
||||||
|
if (in_array($foundPackage['name'], $existingPackages, true)) {
|
||||||
|
unset($matches[$position]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$matches = array_values($matches);
|
||||||
|
|
||||||
$exactMatch = null;
|
$exactMatch = null;
|
||||||
$choices = array();
|
$choices = array();
|
||||||
foreach ($matches as $position => $foundPackage) {
|
foreach ($matches as $position => $foundPackage) {
|
||||||
|
@ -540,6 +563,7 @@ EOT
|
||||||
|
|
||||||
if (false !== $package) {
|
if (false !== $package) {
|
||||||
$requires[] = $package;
|
$requires[] = $package;
|
||||||
|
$existingPackages[] = substr($package, 0, strpos($package, ' '));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -794,7 +818,13 @@ EOT
|
||||||
}
|
}
|
||||||
$similarPackages = array();
|
$similarPackages = array();
|
||||||
|
|
||||||
|
$installedRepo = $this->getComposer()->getRepositoryManager()->getLocalRepository();
|
||||||
|
|
||||||
foreach ($results as $result) {
|
foreach ($results as $result) {
|
||||||
|
if ($installedRepo->findPackage($result['name'], '*')) {
|
||||||
|
// Ignore installed package
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$similarPackages[$result['name']] = levenshtein($package, $result['name']);
|
$similarPackages[$result['name']] = levenshtein($package, $result['name']);
|
||||||
}
|
}
|
||||||
asort($similarPackages);
|
asort($similarPackages);
|
||||||
|
|
|
@ -93,7 +93,7 @@ EOT
|
||||||
$composer = Factory::create($io, $file, $input->hasParameterOption('--no-plugins'));
|
$composer = Factory::create($io, $file, $input->hasParameterOption('--no-plugins'));
|
||||||
$locker = $composer->getLocker();
|
$locker = $composer->getLocker();
|
||||||
if ($locker->isLocked() && !$locker->isFresh()) {
|
if ($locker->isLocked() && !$locker->isFresh()) {
|
||||||
$lockErrors[] = 'The lock file is not up to date with the latest changes in composer.json, it is recommended that you run `composer update`.';
|
$lockErrors[] = 'The lock file is not up to date with the latest changes in composer.json, it is recommended that you run `composer update` or `composer update <package name>`.';
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->outputResult($io, $file, $errors, $warnings, $checkPublish, $publishErrors, $checkLock, $lockErrors, true, $isStrict);
|
$this->outputResult($io, $file, $errors, $warnings, $checkPublish, $publishErrors, $checkLock, $lockErrors, true, $isStrict);
|
||||||
|
|
|
@ -62,6 +62,11 @@ class Application extends BaseApplication
|
||||||
private $hasPluginCommands = false;
|
private $hasPluginCommands = false;
|
||||||
private $disablePluginsByDefault = false;
|
private $disablePluginsByDefault = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Store the initial working directory at startup time
|
||||||
|
*/
|
||||||
|
private $initialWorkingDirectory = '';
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
static $shutdownRegistered = false;
|
static $shutdownRegistered = false;
|
||||||
|
@ -91,6 +96,8 @@ class Application extends BaseApplication
|
||||||
|
|
||||||
$this->io = new NullIO();
|
$this->io = new NullIO();
|
||||||
|
|
||||||
|
$this->initialWorkingDirectory = getcwd();
|
||||||
|
|
||||||
parent::__construct('Composer', Composer::getVersion());
|
parent::__construct('Composer', Composer::getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +138,7 @@ class Application extends BaseApplication
|
||||||
if ($newWorkDir = $this->getNewWorkingDir($input)) {
|
if ($newWorkDir = $this->getNewWorkingDir($input)) {
|
||||||
$oldWorkingDir = getcwd();
|
$oldWorkingDir = getcwd();
|
||||||
chdir($newWorkDir);
|
chdir($newWorkDir);
|
||||||
|
$this->initialWorkingDirectory = $newWorkDir;
|
||||||
$io->writeError('Changed CWD to ' . getcwd(), true, IOInterface::DEBUG);
|
$io->writeError('Changed CWD to ' . getcwd(), true, IOInterface::DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,4 +505,14 @@ class Application extends BaseApplication
|
||||||
|
|
||||||
return $commands;
|
return $commands;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the working directoy at startup time
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getInitialWorkingDirectory()
|
||||||
|
{
|
||||||
|
return $this->initialWorkingDirectory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -586,7 +586,7 @@ class Installer
|
||||||
$request = $this->createRequest($this->fixedRootPackage, $platformRepo, $lockedRepository);
|
$request = $this->createRequest($this->fixedRootPackage, $platformRepo, $lockedRepository);
|
||||||
|
|
||||||
if (!$this->locker->isFresh()) {
|
if (!$this->locker->isFresh()) {
|
||||||
$this->io->writeError('<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>', true, IOInterface::QUIET);
|
$this->io->writeError('<warning>Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. It is recommended that you run `composer update` or `composer update <package name>`.</warning>', true, IOInterface::QUIET);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($lockedRepository->getPackages() as $package) {
|
foreach ($lockedRepository->getPackages() as $package) {
|
||||||
|
|
|
@ -167,6 +167,10 @@ class JsonManipulator
|
||||||
|
|
||||||
public function addProperty($name, $value)
|
public function addProperty($name, $value)
|
||||||
{
|
{
|
||||||
|
if (substr($name, 0, 8) === 'suggest.') {
|
||||||
|
return $this->addSubNode('suggest', substr($name, 8), $value);
|
||||||
|
}
|
||||||
|
|
||||||
if (substr($name, 0, 6) === 'extra.') {
|
if (substr($name, 0, 6) === 'extra.') {
|
||||||
return $this->addSubNode('extra', substr($name, 6), $value);
|
return $this->addSubNode('extra', substr($name, 6), $value);
|
||||||
}
|
}
|
||||||
|
@ -180,6 +184,10 @@ class JsonManipulator
|
||||||
|
|
||||||
public function removeProperty($name)
|
public function removeProperty($name)
|
||||||
{
|
{
|
||||||
|
if (substr($name, 0, 8) === 'suggest.') {
|
||||||
|
return $this->removeSubNode('suggest', substr($name, 8));
|
||||||
|
}
|
||||||
|
|
||||||
if (substr($name, 0, 6) === 'extra.') {
|
if (substr($name, 0, 6) === 'extra.') {
|
||||||
return $this->removeSubNode('extra', substr($name, 6));
|
return $this->removeSubNode('extra', substr($name, 6));
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,18 @@ class ZipArchiver implements ArchiverInterface
|
||||||
} else {
|
} else {
|
||||||
$zip->addFile($filepath, $localname);
|
$zip->addFile($filepath, $localname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ZipArchive::setExternalAttributesName is available from >= PHP 5.6
|
||||||
|
*/
|
||||||
|
if (PHP_VERSION_ID >= 50600) {
|
||||||
|
$perms = fileperms($filepath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure to preserve the permission umasks for the filepath in the archive.
|
||||||
|
*/
|
||||||
|
$zip->setExternalAttributesName($localname, ZipArchive::OPSYS_UNIX, $perms << 16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ($zip->close()) {
|
if ($zip->close()) {
|
||||||
return $target;
|
return $target;
|
||||||
|
|
|
@ -60,7 +60,7 @@ class VersionGuesser
|
||||||
* @param array $packageConfig
|
* @param array $packageConfig
|
||||||
* @param string $path Path to guess into
|
* @param string $path Path to guess into
|
||||||
*
|
*
|
||||||
* @return null|array versionData, 'version', 'pretty_version' and 'commit' keys
|
* @return null|array versionData, 'version', 'pretty_version' and 'commit' keys, if the version is a feature branch, 'feature_version' and 'feature_pretty_version' keys may also be returned
|
||||||
*/
|
*/
|
||||||
public function guessVersion(array $packageConfig, $path)
|
public function guessVersion(array $packageConfig, $path)
|
||||||
{
|
{
|
||||||
|
@ -89,10 +89,18 @@ class VersionGuesser
|
||||||
|
|
||||||
private function postprocess(array $versionData)
|
private function postprocess(array $versionData)
|
||||||
{
|
{
|
||||||
|
if (!empty($versionData['feature_version']) && $versionData['feature_version'] === $versionData['version'] && $versionData['feature_pretty_version'] === $versionData['feature_pretty_version']) {
|
||||||
|
unset($versionData['feature_version'], $versionData['feature_pretty_version']);
|
||||||
|
}
|
||||||
|
|
||||||
if ('-dev' === substr($versionData['version'], -4) && preg_match('{\.9{7}}', $versionData['version'])) {
|
if ('-dev' === substr($versionData['version'], -4) && preg_match('{\.9{7}}', $versionData['version'])) {
|
||||||
$versionData['pretty_version'] = preg_replace('{(\.9{7})+}', '.x', $versionData['version']);
|
$versionData['pretty_version'] = preg_replace('{(\.9{7})+}', '.x', $versionData['version']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!empty($versionData['feature_version']) && '-dev' === substr($versionData['feature_version'], -4) && preg_match('{\.9{7}}', $versionData['feature_version'])) {
|
||||||
|
$versionData['feature_pretty_version'] = preg_replace('{(\.9{7})+}', '.x', $versionData['feature_version']);
|
||||||
|
}
|
||||||
|
|
||||||
return $versionData;
|
return $versionData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +110,8 @@ class VersionGuesser
|
||||||
$commit = null;
|
$commit = null;
|
||||||
$version = null;
|
$version = null;
|
||||||
$prettyVersion = null;
|
$prettyVersion = null;
|
||||||
|
$featureVersion = null;
|
||||||
|
$featurePrettyVersion = null;
|
||||||
$isDetached = false;
|
$isDetached = false;
|
||||||
|
|
||||||
// try to fetch current version from git branch
|
// try to fetch current version from git branch
|
||||||
|
@ -136,6 +146,8 @@ class VersionGuesser
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($isFeatureBranch) {
|
if ($isFeatureBranch) {
|
||||||
|
$featureVersion = $version;
|
||||||
|
$featurePrettyVersion = $prettyVersion;
|
||||||
// try to find the best (nearest) version branch to assume this feature's version
|
// try to find the best (nearest) version branch to assume this feature's version
|
||||||
$result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'git rev-list %candidate%..%branch%', $path);
|
$result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'git rev-list %candidate%..%branch%', $path);
|
||||||
$version = $result['version'];
|
$version = $result['version'];
|
||||||
|
@ -148,6 +160,8 @@ class VersionGuesser
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$version = $result['version'];
|
$version = $result['version'];
|
||||||
$prettyVersion = $result['pretty_version'];
|
$prettyVersion = $result['pretty_version'];
|
||||||
|
$featureVersion = null;
|
||||||
|
$featurePrettyVersion = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +172,10 @@ class VersionGuesser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($featureVersion) {
|
||||||
|
return array('version' => $version, 'commit' => $commit, 'pretty_version' => $prettyVersion, 'feature_version' => $featureVersion, 'feature_pretty_version' => $featurePrettyVersion);
|
||||||
|
}
|
||||||
|
|
||||||
return array('version' => $version, 'commit' => $commit, 'pretty_version' => $prettyVersion);
|
return array('version' => $version, 'commit' => $commit, 'pretty_version' => $prettyVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,6 +218,8 @@ class VersionGuesser
|
||||||
// try to find the best (nearest) version branch to assume this feature's version
|
// try to find the best (nearest) version branch to assume this feature's version
|
||||||
$result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'hg log -r "not ancestors(\'%candidate%\') and ancestors(\'%branch%\')" --template "{node}\\n"', $path);
|
$result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'hg log -r "not ancestors(\'%candidate%\') and ancestors(\'%branch%\')" --template "{node}\\n"', $path);
|
||||||
$result['commit'] = '';
|
$result['commit'] = '';
|
||||||
|
$result['feature_version'] = $version;
|
||||||
|
$result['feature_pretty_version'] = $version;
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -391,6 +391,14 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
||||||
$this->loadProviderListings($this->loadRootServerFile());
|
$this->loadProviderListings($this->loadRootServerFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->hasPartialPackages) {
|
||||||
|
if (null === $this->partialPackagesByName) {
|
||||||
|
$this->initializePartialPackages();
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_keys($this->partialPackagesByName);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->lazyProvidersUrl) {
|
if ($this->lazyProvidersUrl) {
|
||||||
// Can not determine list of provided packages for lazy repositories
|
// Can not determine list of provided packages for lazy repositories
|
||||||
return array();
|
return array();
|
||||||
|
|
|
@ -159,19 +159,26 @@ class PathRepository extends ArrayRepository implements ConfigurableRepositoryIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$output = '';
|
||||||
|
if (is_dir($path . DIRECTORY_SEPARATOR . '.git') && 0 === $this->process->execute('git log -n1 --pretty=%H', $output, $path)) {
|
||||||
|
$package['dist']['reference'] = trim($output);
|
||||||
|
}
|
||||||
|
|
||||||
if (!isset($package['version'])) {
|
if (!isset($package['version'])) {
|
||||||
$versionData = $this->versionGuesser->guessVersion($package, $path);
|
$versionData = $this->versionGuesser->guessVersion($package, $path);
|
||||||
if (is_array($versionData) && $versionData['pretty_version']) {
|
if (is_array($versionData) && $versionData['pretty_version']) {
|
||||||
|
// if there is a feature branch detected, we add a second packages with the feature branch version
|
||||||
|
if (!empty($versionData['feature_pretty_version'])) {
|
||||||
|
$package['version'] = $versionData['feature_pretty_version'];
|
||||||
|
$this->addPackage($this->loader->load($package));
|
||||||
|
}
|
||||||
|
|
||||||
$package['version'] = $versionData['pretty_version'];
|
$package['version'] = $versionData['pretty_version'];
|
||||||
} else {
|
} else {
|
||||||
$package['version'] = 'dev-master';
|
$package['version'] = 'dev-master';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$output = '';
|
|
||||||
if (is_dir($path . DIRECTORY_SEPARATOR . '.git') && 0 === $this->process->execute('git log -n1 --pretty=%H', $output, $path)) {
|
|
||||||
$package['dist']['reference'] = trim($output);
|
|
||||||
}
|
|
||||||
$package = $this->loader->load($package);
|
$package = $this->loader->load($package);
|
||||||
$this->addPackage($package);
|
$this->addPackage($package);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ class GitHubDriver extends VcsDriver
|
||||||
protected $hasIssues;
|
protected $hasIssues;
|
||||||
protected $infoCache = array();
|
protected $infoCache = array();
|
||||||
protected $isPrivate = false;
|
protected $isPrivate = false;
|
||||||
|
private $isArchived = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Git Driver
|
* Git Driver
|
||||||
|
@ -163,6 +164,9 @@ class GitHubDriver extends VcsDriver
|
||||||
if (!isset($composer['support']['issues']) && $this->hasIssues) {
|
if (!isset($composer['support']['issues']) && $this->hasIssues) {
|
||||||
$composer['support']['issues'] = sprintf('https://%s/%s/%s/issues', $this->originUrl, $this->owner, $this->repository);
|
$composer['support']['issues'] = sprintf('https://%s/%s/%s/issues', $this->originUrl, $this->owner, $this->repository);
|
||||||
}
|
}
|
||||||
|
if (!isset($composer['abandoned']) && $this->isArchived) {
|
||||||
|
$composer['abandoned'] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->shouldCache($identifier)) {
|
if ($this->shouldCache($identifier)) {
|
||||||
|
@ -432,6 +436,7 @@ class GitHubDriver extends VcsDriver
|
||||||
$this->rootIdentifier = 'master';
|
$this->rootIdentifier = 'master';
|
||||||
}
|
}
|
||||||
$this->hasIssues = !empty($this->repoData['has_issues']);
|
$this->hasIssues = !empty($this->repoData['has_issues']);
|
||||||
|
$this->isArchived = !empty($this->repoData['archived']);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function attemptCloneFallback()
|
protected function attemptCloneFallback()
|
||||||
|
|
|
@ -120,6 +120,42 @@ class GitLabDriver extends VcsDriver
|
||||||
$this->httpDownloader = $httpDownloader;
|
$this->httpDownloader = $httpDownloader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function getComposerInformation($identifier)
|
||||||
|
{
|
||||||
|
if ($this->gitDriver) {
|
||||||
|
return $this->gitDriver->getComposerInformation($identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($this->infoCache[$identifier])) {
|
||||||
|
if ($this->shouldCache($identifier) && $res = $this->cache->read($identifier)) {
|
||||||
|
return $this->infoCache[$identifier] = JsonFile::parseJson($res);
|
||||||
|
}
|
||||||
|
|
||||||
|
$composer = $this->getBaseComposerInformation($identifier);
|
||||||
|
|
||||||
|
if ($composer) {
|
||||||
|
// specials for gitlab (this data is only available if authentication is provided)
|
||||||
|
if (!isset($composer['support']['issues']) && isset($this->project['_links']['issues'])) {
|
||||||
|
$composer['support']['issues'] = $this->project['_links']['issues'];
|
||||||
|
}
|
||||||
|
if (!isset($composer['abandoned']) && !empty($this->project['archived'])) {
|
||||||
|
$composer['abandoned'] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->shouldCache($identifier)) {
|
||||||
|
$this->cache->write($identifier, json_encode($composer));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->infoCache[$identifier] = $composer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->infoCache[$identifier];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1814,6 +1814,91 @@ class JsonManipulatorTest extends TestCase
|
||||||
', $manipulator->getContents());
|
', $manipulator->getContents());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testAddConfigWithPackage() {
|
||||||
|
$manipulator = new JsonManipulator('{
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "package",
|
||||||
|
"package": {
|
||||||
|
"authors": [],
|
||||||
|
"extra": {
|
||||||
|
"package-xml": "package.xml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"config": {
|
||||||
|
"platform": {
|
||||||
|
"php": "5.3.9"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}');
|
||||||
|
|
||||||
|
$this->assertTrue($manipulator->addConfigSetting('preferred-install.my-organization/stable-package', 'dist'));
|
||||||
|
$this->assertEquals('{
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "package",
|
||||||
|
"package": {
|
||||||
|
"authors": [],
|
||||||
|
"extra": {
|
||||||
|
"package-xml": "package.xml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"config": {
|
||||||
|
"platform": {
|
||||||
|
"php": "5.3.9"
|
||||||
|
},
|
||||||
|
"preferred-install": {
|
||||||
|
"my-organization/stable-package": "dist"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
', $manipulator->getContents());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddSuggestWithPackage()
|
||||||
|
{
|
||||||
|
$manipulator = new JsonManipulator('{
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "package",
|
||||||
|
"package": {
|
||||||
|
"authors": [],
|
||||||
|
"extra": {
|
||||||
|
"package-xml": "package.xml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"suggest": {
|
||||||
|
"package": "Description"
|
||||||
|
}
|
||||||
|
}');
|
||||||
|
|
||||||
|
$this->assertTrue($manipulator->addProperty('suggest.new-package', 'new-description'));
|
||||||
|
$this->assertEquals('{
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "package",
|
||||||
|
"package": {
|
||||||
|
"authors": [],
|
||||||
|
"extra": {
|
||||||
|
"package-xml": "package.xml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"suggest": {
|
||||||
|
"package": "Description",
|
||||||
|
"new-package": "new-description"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
', $manipulator->getContents());
|
||||||
|
}
|
||||||
|
|
||||||
public function testAddRepositoryCanInitializeEmptyRepositories()
|
public function testAddRepositoryCanInitializeEmptyRepositories()
|
||||||
{
|
{
|
||||||
$manipulator = new JsonManipulator('{
|
$manipulator = new JsonManipulator('{
|
||||||
|
|
|
@ -126,13 +126,15 @@ class VersionGuesserTest extends TestCase
|
||||||
|
|
||||||
$this->assertEquals("9999999-dev", $versionArray['version']);
|
$this->assertEquals("9999999-dev", $versionArray['version']);
|
||||||
$this->assertEquals("dev-master", $versionArray['pretty_version']);
|
$this->assertEquals("dev-master", $versionArray['pretty_version']);
|
||||||
|
$this->assertArrayNotHasKey('feature_version', $versionArray);
|
||||||
|
$this->assertArrayNotHasKey('feature_pretty_version', $versionArray);
|
||||||
$this->assertEquals($commitHash, $versionArray['commit']);
|
$this->assertEquals($commitHash, $versionArray['commit']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNaming()
|
public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNaming()
|
||||||
{
|
{
|
||||||
$commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
|
$commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
|
||||||
$anotherCommitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
|
$anotherCommitHash = '13a15d220da53c52eddd5f32ffca64a7b3801bea';
|
||||||
|
|
||||||
$executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor')
|
$executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor')
|
||||||
->setMethods(array('execute'))
|
->setMethods(array('execute'))
|
||||||
|
@ -172,12 +174,14 @@ class VersionGuesserTest extends TestCase
|
||||||
|
|
||||||
$this->assertEquals("dev-arbitrary", $versionArray['version']);
|
$this->assertEquals("dev-arbitrary", $versionArray['version']);
|
||||||
$this->assertEquals($anotherCommitHash, $versionArray['commit']);
|
$this->assertEquals($anotherCommitHash, $versionArray['commit']);
|
||||||
|
$this->assertEquals("dev-current", $versionArray['feature_version']);
|
||||||
|
$this->assertEquals("dev-current", $versionArray['feature_pretty_version']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNamingRegex()
|
public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNamingRegex()
|
||||||
{
|
{
|
||||||
$commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
|
$commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
|
||||||
$anotherCommitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
|
$anotherCommitHash = '13a15d220da53c52eddd5f32ffca64a7b3801bea';
|
||||||
|
|
||||||
$executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor')
|
$executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor')
|
||||||
->setMethods(array('execute'))
|
->setMethods(array('execute'))
|
||||||
|
@ -217,12 +221,14 @@ class VersionGuesserTest extends TestCase
|
||||||
|
|
||||||
$this->assertEquals("dev-latest-testing", $versionArray['version']);
|
$this->assertEquals("dev-latest-testing", $versionArray['version']);
|
||||||
$this->assertEquals($anotherCommitHash, $versionArray['commit']);
|
$this->assertEquals($anotherCommitHash, $versionArray['commit']);
|
||||||
|
$this->assertEquals("dev-current", $versionArray['feature_version']);
|
||||||
|
$this->assertEquals("dev-current", $versionArray['feature_pretty_version']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNamingWhenOnNonFeatureBranch()
|
public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNamingWhenOnNonFeatureBranch()
|
||||||
{
|
{
|
||||||
$commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
|
$commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
|
||||||
$anotherCommitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
|
$anotherCommitHash = '13a15d220da53c52eddd5f32ffca64a7b3801bea';
|
||||||
|
|
||||||
$executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor')
|
$executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor')
|
||||||
->setMethods(array('execute'))
|
->setMethods(array('execute'))
|
||||||
|
@ -251,6 +257,8 @@ class VersionGuesserTest extends TestCase
|
||||||
|
|
||||||
$this->assertEquals("dev-latest-testing", $versionArray['version']);
|
$this->assertEquals("dev-latest-testing", $versionArray['version']);
|
||||||
$this->assertEquals($commitHash, $versionArray['commit']);
|
$this->assertEquals($commitHash, $versionArray['commit']);
|
||||||
|
$this->assertArrayNotHasKey('feature_version', $versionArray);
|
||||||
|
$this->assertArrayNotHasKey('feature_pretty_version', $versionArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDetachedHeadBecomesDevHash()
|
public function testDetachedHeadBecomesDevHash()
|
||||||
|
|
|
@ -283,4 +283,33 @@ class ComposerRepositoryTest extends TestCase
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetProviderNamesWillReturnPartialPackageNames()
|
||||||
|
{
|
||||||
|
$rfs = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$rfs->expects($this->at(0))
|
||||||
|
->method('getContents')
|
||||||
|
->with('example.org', 'http://example.org/packages.json', false)
|
||||||
|
->willReturn(json_encode(array(
|
||||||
|
'providers-lazy-url' => '/foo/p/%package%.json',
|
||||||
|
'packages' => array('foo/bar' => array(
|
||||||
|
'dev-branch' => array(),
|
||||||
|
'v1.0.0' => array(),
|
||||||
|
))
|
||||||
|
)));
|
||||||
|
|
||||||
|
$repository = new ComposerRepository(
|
||||||
|
array('url' => 'http://example.org/packages.json'),
|
||||||
|
new NullIO(),
|
||||||
|
FactoryMock::createConfig(),
|
||||||
|
null,
|
||||||
|
$rfs
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertTrue($repository->hasProviders());
|
||||||
|
$this->assertEquals(array('foo/bar'), $repository->getProviderNames());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,7 +216,49 @@ class GitHubDriverTest extends TestCase
|
||||||
$this->assertEquals($repoUrl, $source['url']);
|
$this->assertEquals($repoUrl, $source['url']);
|
||||||
$this->assertEquals($sha, $source['reference']);
|
$this->assertEquals($sha, $source['reference']);
|
||||||
|
|
||||||
$gitHubDriver->getComposerInformation($identifier);
|
$data = $gitHubDriver->getComposerInformation($identifier);
|
||||||
|
|
||||||
|
$this->assertArrayNotHasKey('abandoned', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPublicRepositoryArchived()
|
||||||
|
{
|
||||||
|
$repoUrl = 'http://github.com/composer/packagist';
|
||||||
|
$repoApiUrl = 'https://api.github.com/repos/composer/packagist';
|
||||||
|
$identifier = 'v0.0.0';
|
||||||
|
$sha = 'SOMESHA';
|
||||||
|
$composerJsonUrl = 'https://api.github.com/repos/composer/packagist/contents/composer.json?ref=' . $sha;
|
||||||
|
|
||||||
|
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||||
|
$io->expects($this->any())
|
||||||
|
->method('isInteractive')
|
||||||
|
->will($this->returnValue(true));
|
||||||
|
|
||||||
|
$remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
|
||||||
|
->setConstructorArgs(array($io))
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$remoteFilesystem->expects($this->at(0))
|
||||||
|
->method('getContents')
|
||||||
|
->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false))
|
||||||
|
->will($this->returnValue('{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist", "archived": true}'));
|
||||||
|
|
||||||
|
$remoteFilesystem->expects($this->at(1))
|
||||||
|
->method('getContents')
|
||||||
|
->with($this->equalTo('github.com'), $this->equalTo($composerJsonUrl), $this->equalTo(false))
|
||||||
|
->will($this->returnValue('{"encoding": "base64", "content": "' . base64_encode('{"name": "composer/packagist"}') . '"}'));
|
||||||
|
|
||||||
|
$repoConfig = array(
|
||||||
|
'url' => $repoUrl,
|
||||||
|
);
|
||||||
|
|
||||||
|
$gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $remoteFilesystem);
|
||||||
|
$gitHubDriver->initialize();
|
||||||
|
$this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha));
|
||||||
|
|
||||||
|
$data = $gitHubDriver->getComposerInformation($sha);
|
||||||
|
|
||||||
|
$this->assertTrue($data['abandoned']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPrivateRepositoryNoInteraction()
|
public function testPrivateRepositoryNoInteraction()
|
||||||
|
|
|
@ -108,7 +108,7 @@ class ProcessExecutorTest extends TestCase
|
||||||
public function testConsoleIODoesNotFormatSymfonyConsoleStyle()
|
public function testConsoleIODoesNotFormatSymfonyConsoleStyle()
|
||||||
{
|
{
|
||||||
$output = new BufferedOutput(OutputInterface::VERBOSITY_NORMAL, true);
|
$output = new BufferedOutput(OutputInterface::VERBOSITY_NORMAL, true);
|
||||||
$process = new ProcessExecutor(new ConsoleIO(new ArrayInput([]), $output, new HelperSet([])));
|
$process = new ProcessExecutor(new ConsoleIO(new ArrayInput(array()), $output, new HelperSet(array())));
|
||||||
|
|
||||||
$process->execute('echo \'<error>foo</error>\'');
|
$process->execute('echo \'<error>foo</error>\'');
|
||||||
$this->assertSame('<error>foo</error>'.PHP_EOL, $output->fetch());
|
$this->assertSame('<error>foo</error>'.PHP_EOL, $output->fetch());
|
||||||
|
|
Loading…
Reference in New Issue