1
0
Fork 0

Merge branch 'master' into 2.0

pull/8528/head
Jordi Boggiano 2020-01-14 15:39:35 +01:00
commit a5b178084c
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
20 changed files with 384 additions and 15 deletions

View File

@ -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:

View File

@ -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);

View File

@ -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;
} }

View File

@ -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'));
} }
} }

View File

@ -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);

View File

@ -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);

View File

@ -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;
}
} }

View File

@ -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) {

View File

@ -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));
} }

View File

@ -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;

View File

@ -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;
} }

View File

@ -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();

View File

@ -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);
} }

View File

@ -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()

View File

@ -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}
*/ */

View File

@ -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('{

View File

@ -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()

View File

@ -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());
}
} }

View File

@ -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()

View File

@ -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());