diff --git a/doc/04-schema.md b/doc/04-schema.md
index 7c66813af..6e273c1a0 100644
--- a/doc/04-schema.md
+++ b/doc/04-schema.md
@@ -276,10 +276,11 @@ Example:
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
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.
Example:
diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php
index 329230e2e..56e994036 100644
--- a/src/Composer/Command/ConfigCommand.php
+++ b/src/Composer/Command/ConfigCommand.php
@@ -111,6 +111,14 @@ To disable packagist:
You can alter repositories in the global config.json file by passing in the
--global option.
+To add or edit suggested packages you can use:
+
+ %command.full_name% suggest.package reason for the suggestion
+
+To add or edit extra properties you can use:
+
+ %command.full_name% extra.property value
+
To edit the file in an external editor:
%command.full_name% --editor
@@ -478,6 +486,23 @@ EOT
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
$uniqueProps = array(
@@ -601,6 +626,26 @@ EOT
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
if (preg_match('/^platform\.(.+)/', $settingKey, $matches)) {
if ($input->getOption('unset')) {
@@ -613,6 +658,8 @@ EOT
return 0;
}
+
+ // handle unsetting platform
if ($settingKey === 'platform' && $input->getOption('unset')) {
$this->configSource->removeConfigSetting($settingKey);
diff --git a/src/Composer/Command/DiagnoseCommand.php b/src/Composer/Command/DiagnoseCommand.php
index d953809a7..b2b08e6f0 100644
--- a/src/Composer/Command/DiagnoseCommand.php
+++ b/src/Composer/Command/DiagnoseCommand.php
@@ -172,6 +172,8 @@ EOT
$io->write(sprintf('PHP binary path: %s', PHP_BINARY));
}
+ $io->write(sprintf('OpenSSL version: %s', OPENSSL_VERSION_TEXT));
+
return $this->exitCode;
}
diff --git a/src/Composer/Command/ExecCommand.php b/src/Composer/Command/ExecCommand.php
index c9184c707..d530def66 100644
--- a/src/Composer/Command/ExecCommand.php
+++ b/src/Composer/Command/ExecCommand.php
@@ -39,7 +39,7 @@ class ExecCommand extends BaseCommand
->setHelp(
<<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'));
}
}
diff --git a/src/Composer/Command/InitCommand.php b/src/Composer/Command/InitCommand.php
index 1c7704e83..92db88cfa 100644
--- a/src/Composer/Command/InitCommand.php
+++ b/src/Composer/Command/InitCommand.php
@@ -438,11 +438,34 @@ EOT
}
$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();
while (null !== $package = $io->ask('Search for a package: ')) {
$matches = $this->findPackages($package);
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;
$choices = array();
foreach ($matches as $position => $foundPackage) {
@@ -540,6 +563,7 @@ EOT
if (false !== $package) {
$requires[] = $package;
+ $existingPackages[] = substr($package, 0, strpos($package, ' '));
}
}
}
@@ -794,7 +818,13 @@ EOT
}
$similarPackages = array();
+ $installedRepo = $this->getComposer()->getRepositoryManager()->getLocalRepository();
+
foreach ($results as $result) {
+ if ($installedRepo->findPackage($result['name'], '*')) {
+ // Ignore installed package
+ continue;
+ }
$similarPackages[$result['name']] = levenshtein($package, $result['name']);
}
asort($similarPackages);
diff --git a/src/Composer/Command/ValidateCommand.php b/src/Composer/Command/ValidateCommand.php
index 5aba74adf..7ec15ccb9 100644
--- a/src/Composer/Command/ValidateCommand.php
+++ b/src/Composer/Command/ValidateCommand.php
@@ -93,7 +93,7 @@ EOT
$composer = Factory::create($io, $file, $input->hasParameterOption('--no-plugins'));
$locker = $composer->getLocker();
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 `.';
}
$this->outputResult($io, $file, $errors, $warnings, $checkPublish, $publishErrors, $checkLock, $lockErrors, true, $isStrict);
diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php
index d9e7a4a56..4182298d6 100644
--- a/src/Composer/Console/Application.php
+++ b/src/Composer/Console/Application.php
@@ -62,6 +62,11 @@ class Application extends BaseApplication
private $hasPluginCommands = false;
private $disablePluginsByDefault = false;
+ /**
+ * @var string Store the initial working directory at startup time
+ */
+ private $initialWorkingDirectory = '';
+
public function __construct()
{
static $shutdownRegistered = false;
@@ -91,6 +96,8 @@ class Application extends BaseApplication
$this->io = new NullIO();
+ $this->initialWorkingDirectory = getcwd();
+
parent::__construct('Composer', Composer::getVersion());
}
@@ -131,6 +138,7 @@ class Application extends BaseApplication
if ($newWorkDir = $this->getNewWorkingDir($input)) {
$oldWorkingDir = getcwd();
chdir($newWorkDir);
+ $this->initialWorkingDirectory = $newWorkDir;
$io->writeError('Changed CWD to ' . getcwd(), true, IOInterface::DEBUG);
}
@@ -497,4 +505,14 @@ class Application extends BaseApplication
return $commands;
}
+
+ /**
+ * Get the working directoy at startup time
+ *
+ * @return string
+ */
+ public function getInitialWorkingDirectory()
+ {
+ return $this->initialWorkingDirectory;
+ }
}
diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php
index 87412f7ea..646bb4fcf 100644
--- a/src/Composer/Installer.php
+++ b/src/Composer/Installer.php
@@ -586,7 +586,7 @@ class Installer
$request = $this->createRequest($this->fixedRootPackage, $platformRepo, $lockedRepository);
if (!$this->locker->isFresh()) {
- $this->io->writeError('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.', true, IOInterface::QUIET);
+ $this->io->writeError('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 `.', true, IOInterface::QUIET);
}
foreach ($lockedRepository->getPackages() as $package) {
diff --git a/src/Composer/Json/JsonManipulator.php b/src/Composer/Json/JsonManipulator.php
index e64a56f71..e1ee43485 100644
--- a/src/Composer/Json/JsonManipulator.php
+++ b/src/Composer/Json/JsonManipulator.php
@@ -167,6 +167,10 @@ class JsonManipulator
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.') {
return $this->addSubNode('extra', substr($name, 6), $value);
}
@@ -180,6 +184,10 @@ class JsonManipulator
public function removeProperty($name)
{
+ if (substr($name, 0, 8) === 'suggest.') {
+ return $this->removeSubNode('suggest', substr($name, 8));
+ }
+
if (substr($name, 0, 6) === 'extra.') {
return $this->removeSubNode('extra', substr($name, 6));
}
diff --git a/src/Composer/Package/Archiver/ZipArchiver.php b/src/Composer/Package/Archiver/ZipArchiver.php
index 65694cb88..b6cfaf73f 100644
--- a/src/Composer/Package/Archiver/ZipArchiver.php
+++ b/src/Composer/Package/Archiver/ZipArchiver.php
@@ -45,6 +45,18 @@ class ZipArchiver implements ArchiverInterface
} else {
$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()) {
return $target;
diff --git a/src/Composer/Package/Version/VersionGuesser.php b/src/Composer/Package/Version/VersionGuesser.php
index d655bc080..918e9706a 100644
--- a/src/Composer/Package/Version/VersionGuesser.php
+++ b/src/Composer/Package/Version/VersionGuesser.php
@@ -60,7 +60,7 @@ class VersionGuesser
* @param array $packageConfig
* @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)
{
@@ -89,10 +89,18 @@ class VersionGuesser
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'])) {
$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;
}
@@ -102,6 +110,8 @@ class VersionGuesser
$commit = null;
$version = null;
$prettyVersion = null;
+ $featureVersion = null;
+ $featurePrettyVersion = null;
$isDetached = false;
// try to fetch current version from git branch
@@ -136,6 +146,8 @@ class VersionGuesser
}
if ($isFeatureBranch) {
+ $featureVersion = $version;
+ $featurePrettyVersion = $prettyVersion;
// 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);
$version = $result['version'];
@@ -148,6 +160,8 @@ class VersionGuesser
if ($result) {
$version = $result['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);
}
@@ -200,6 +218,8 @@ class VersionGuesser
// 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['commit'] = '';
+ $result['feature_version'] = $version;
+ $result['feature_pretty_version'] = $version;
return $result;
}
diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php
index 02f2a05fe..8ff6da589 100644
--- a/src/Composer/Repository/ComposerRepository.php
+++ b/src/Composer/Repository/ComposerRepository.php
@@ -391,6 +391,14 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$this->loadProviderListings($this->loadRootServerFile());
}
+ if ($this->hasPartialPackages) {
+ if (null === $this->partialPackagesByName) {
+ $this->initializePartialPackages();
+ }
+
+ return array_keys($this->partialPackagesByName);
+ }
+
if ($this->lazyProvidersUrl) {
// Can not determine list of provided packages for lazy repositories
return array();
diff --git a/src/Composer/Repository/PathRepository.php b/src/Composer/Repository/PathRepository.php
index 2f26af2f7..4db774579 100644
--- a/src/Composer/Repository/PathRepository.php
+++ b/src/Composer/Repository/PathRepository.php
@@ -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'])) {
$versionData = $this->versionGuesser->guessVersion($package, $path);
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'];
} else {
$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);
$this->addPackage($package);
}
diff --git a/src/Composer/Repository/Vcs/GitHubDriver.php b/src/Composer/Repository/Vcs/GitHubDriver.php
index c9ed229b8..f99ad625f 100644
--- a/src/Composer/Repository/Vcs/GitHubDriver.php
+++ b/src/Composer/Repository/Vcs/GitHubDriver.php
@@ -35,6 +35,7 @@ class GitHubDriver extends VcsDriver
protected $hasIssues;
protected $infoCache = array();
protected $isPrivate = false;
+ private $isArchived = false;
/**
* Git Driver
@@ -163,6 +164,9 @@ class GitHubDriver extends VcsDriver
if (!isset($composer['support']['issues']) && $this->hasIssues) {
$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)) {
@@ -432,6 +436,7 @@ class GitHubDriver extends VcsDriver
$this->rootIdentifier = 'master';
}
$this->hasIssues = !empty($this->repoData['has_issues']);
+ $this->isArchived = !empty($this->repoData['archived']);
}
protected function attemptCloneFallback()
diff --git a/src/Composer/Repository/Vcs/GitLabDriver.php b/src/Composer/Repository/Vcs/GitLabDriver.php
index a1f810bfa..f1cd5f76c 100644
--- a/src/Composer/Repository/Vcs/GitLabDriver.php
+++ b/src/Composer/Repository/Vcs/GitLabDriver.php
@@ -120,6 +120,42 @@ class GitLabDriver extends VcsDriver
$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}
*/
diff --git a/tests/Composer/Test/Json/JsonManipulatorTest.php b/tests/Composer/Test/Json/JsonManipulatorTest.php
index 8bc7831af..063fcbc5e 100644
--- a/tests/Composer/Test/Json/JsonManipulatorTest.php
+++ b/tests/Composer/Test/Json/JsonManipulatorTest.php
@@ -1814,6 +1814,91 @@ class JsonManipulatorTest extends TestCase
', $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()
{
$manipulator = new JsonManipulator('{
diff --git a/tests/Composer/Test/Package/Version/VersionGuesserTest.php b/tests/Composer/Test/Package/Version/VersionGuesserTest.php
index fe229d679..6eeafd122 100644
--- a/tests/Composer/Test/Package/Version/VersionGuesserTest.php
+++ b/tests/Composer/Test/Package/Version/VersionGuesserTest.php
@@ -126,13 +126,15 @@ class VersionGuesserTest extends TestCase
$this->assertEquals("9999999-dev", $versionArray['version']);
$this->assertEquals("dev-master", $versionArray['pretty_version']);
+ $this->assertArrayNotHasKey('feature_version', $versionArray);
+ $this->assertArrayNotHasKey('feature_pretty_version', $versionArray);
$this->assertEquals($commitHash, $versionArray['commit']);
}
public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNaming()
{
$commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
- $anotherCommitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
+ $anotherCommitHash = '13a15d220da53c52eddd5f32ffca64a7b3801bea';
$executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor')
->setMethods(array('execute'))
@@ -172,12 +174,14 @@ class VersionGuesserTest extends TestCase
$this->assertEquals("dev-arbitrary", $versionArray['version']);
$this->assertEquals($anotherCommitHash, $versionArray['commit']);
+ $this->assertEquals("dev-current", $versionArray['feature_version']);
+ $this->assertEquals("dev-current", $versionArray['feature_pretty_version']);
}
public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNamingRegex()
{
$commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
- $anotherCommitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
+ $anotherCommitHash = '13a15d220da53c52eddd5f32ffca64a7b3801bea';
$executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor')
->setMethods(array('execute'))
@@ -217,12 +221,14 @@ class VersionGuesserTest extends TestCase
$this->assertEquals("dev-latest-testing", $versionArray['version']);
$this->assertEquals($anotherCommitHash, $versionArray['commit']);
+ $this->assertEquals("dev-current", $versionArray['feature_version']);
+ $this->assertEquals("dev-current", $versionArray['feature_pretty_version']);
}
public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNamingWhenOnNonFeatureBranch()
{
$commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
- $anotherCommitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
+ $anotherCommitHash = '13a15d220da53c52eddd5f32ffca64a7b3801bea';
$executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor')
->setMethods(array('execute'))
@@ -251,6 +257,8 @@ class VersionGuesserTest extends TestCase
$this->assertEquals("dev-latest-testing", $versionArray['version']);
$this->assertEquals($commitHash, $versionArray['commit']);
+ $this->assertArrayNotHasKey('feature_version', $versionArray);
+ $this->assertArrayNotHasKey('feature_pretty_version', $versionArray);
}
public function testDetachedHeadBecomesDevHash()
diff --git a/tests/Composer/Test/Repository/ComposerRepositoryTest.php b/tests/Composer/Test/Repository/ComposerRepositoryTest.php
index 22a58cf4f..313f8b7b6 100644
--- a/tests/Composer/Test/Repository/ComposerRepositoryTest.php
+++ b/tests/Composer/Test/Repository/ComposerRepositoryTest.php
@@ -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());
+ }
}
diff --git a/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php b/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php
index 977a4a7aa..4115b65da 100644
--- a/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php
+++ b/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php
@@ -216,7 +216,49 @@ class GitHubDriverTest extends TestCase
$this->assertEquals($repoUrl, $source['url']);
$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()
diff --git a/tests/Composer/Test/Util/ProcessExecutorTest.php b/tests/Composer/Test/Util/ProcessExecutorTest.php
index 29723b4a5..63ed0b7de 100644
--- a/tests/Composer/Test/Util/ProcessExecutorTest.php
+++ b/tests/Composer/Test/Util/ProcessExecutorTest.php
@@ -108,7 +108,7 @@ class ProcessExecutorTest extends TestCase
public function testConsoleIODoesNotFormatSymfonyConsoleStyle()
{
$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 \'foo\'');
$this->assertSame('foo'.PHP_EOL, $output->fetch());