diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php
index 2899e2bdb..00276f7e5 100644
--- a/src/Composer/Installer.php
+++ b/src/Composer/Installer.php
@@ -31,6 +31,7 @@ use Composer\Installer\NoopInstaller;
use Composer\IO\IOInterface;
use Composer\Json\JsonFile;
use Composer\Package\AliasPackage;
+use Composer\Package\CompletePackage;
use Composer\Package\Link;
use Composer\Package\LinkConstraint\VersionConstraint;
use Composer\Package\Locker;
@@ -239,6 +240,25 @@ class Installer
}
}
+ # Find abandoned packages and warn user
+ foreach ($localRepo->getPackages() as $package) {
+ if (!$package instanceof CompletePackage || !$package->isAbandoned()) {
+ continue;
+ }
+
+ $replacement = (is_string($package->getReplacementPackage()))
+ ? 'Use ' . $package->getReplacementPackage() . ' instead'
+ : 'No replacement was suggested';
+
+ $this->io->write(
+ sprintf(
+ "Package %s is abandoned, you should avoid using it. %s.",
+ $package->getPrettyName(),
+ $replacement
+ )
+ );
+ }
+
if (!$this->dryRun) {
// write lock
if ($this->update || !$this->locker->isLocked()) {
diff --git a/tests/Composer/Test/Fixtures/installer/abandoned-listed.test b/tests/Composer/Test/Fixtures/installer/abandoned-listed.test
new file mode 100644
index 000000000..18f47732e
--- /dev/null
+++ b/tests/Composer/Test/Fixtures/installer/abandoned-listed.test
@@ -0,0 +1,36 @@
+--TEST--
+Abandoned packages are flagged
+--COMPOSER--
+{
+ "repositories": [
+ {
+ "type": "package",
+ "package": [
+ { "name": "a/a", "version": "1.0.0", "abandoned": true }
+ ]
+ },
+ {
+ "type": "package",
+ "package": [
+ { "name": "c/c", "version": "1.0.0", "abandoned": "b/b" }
+ ]
+ }
+ ],
+ "require": {
+ "a/a": "1.0.0",
+ "c/c": "1.0.0"
+ }
+}
+--RUN--
+install
+--EXPECT-OUTPUT--
+Loading composer repositories with package information
+Installing dependencies (including require-dev)
+Package a/a is abandoned, you should avoid using it. No replacement was suggested.
+Package c/c is abandoned, you should avoid using it. Use b/b instead.
+Writing lock file
+Generating autoload files
+
+--EXPECT--
+Installing a/a (1.0.0)
+Installing c/c (1.0.0)
diff --git a/tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test b/tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test
index af4eed811..5495b60f3 100644
--- a/tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test
+++ b/tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test
@@ -38,7 +38,8 @@ install --prefer-dist
"reference": "459720ff3b74ee0c0d159277c6f2f5df89d8a4f6",
"shasum": null
},
- "type": "library"
+ "type": "library",
+ "abandoned": false
}
],
"packages-dev": [],
diff --git a/tests/Composer/Test/Fixtures/installer/partial-update-downgrades-non-whitelisted-unstable.test b/tests/Composer/Test/Fixtures/installer/partial-update-downgrades-non-whitelisted-unstable.test
index f9fd5058a..dd085c5ac 100644
--- a/tests/Composer/Test/Fixtures/installer/partial-update-downgrades-non-whitelisted-unstable.test
+++ b/tests/Composer/Test/Fixtures/installer/partial-update-downgrades-non-whitelisted-unstable.test
@@ -50,9 +50,9 @@ update c/uptodate
--EXPECT-LOCK--
{
"packages": [
- { "name": "a/old", "version": "1.0.0", "type": "library" },
- { "name": "b/unstable", "version": "1.0.0", "type": "library" },
- { "name": "c/uptodate", "version": "2.0.0", "type": "library" }
+ { "name": "a/old", "version": "1.0.0", "type": "library", "abandoned": false },
+ { "name": "b/unstable", "version": "1.0.0", "type": "library", "abandoned": false },
+ { "name": "c/uptodate", "version": "2.0.0", "type": "library", "abandoned": false }
],
"packages-dev": [],
"aliases": [],
diff --git a/tests/Composer/Test/Fixtures/installer/partial-update-from-lock.test b/tests/Composer/Test/Fixtures/installer/partial-update-from-lock.test
index 5b904f9b5..b63694a1e 100644
--- a/tests/Composer/Test/Fixtures/installer/partial-update-from-lock.test
+++ b/tests/Composer/Test/Fixtures/installer/partial-update-from-lock.test
@@ -50,9 +50,9 @@ update b/unstable
--EXPECT-LOCK--
{
"packages": [
- { "name": "a/old", "version": "1.0.0", "type": "library" },
- { "name": "b/unstable", "version": "1.0.0", "type": "library" },
- { "name": "c/uptodate", "version": "1.0.0", "type": "library" }
+ { "name": "a/old", "version": "1.0.0", "type": "library", "abandoned": false },
+ { "name": "b/unstable", "version": "1.0.0", "type": "library", "abandoned": false },
+ { "name": "c/uptodate", "version": "1.0.0", "type": "library", "abandoned": false }
],
"packages-dev": [],
"aliases": [],
diff --git a/tests/Composer/Test/Fixtures/installer/partial-update-without-lock.test b/tests/Composer/Test/Fixtures/installer/partial-update-without-lock.test
index 224e58f7d..9e4ff30e3 100644
--- a/tests/Composer/Test/Fixtures/installer/partial-update-without-lock.test
+++ b/tests/Composer/Test/Fixtures/installer/partial-update-without-lock.test
@@ -33,10 +33,10 @@ update b/unstable
--EXPECT-LOCK--
{
"packages": [
- { "name": "a/old", "version": "1.0.0", "type": "library" },
- { "name": "b/unstable", "version": "1.0.0", "type": "library" },
- { "name": "c/uptodate", "version": "1.0.0", "type": "library" },
- { "name": "d/removed", "version": "1.0.0", "type": "library" }
+ { "name": "a/old", "version": "1.0.0", "type": "library", "abandoned": false },
+ { "name": "b/unstable", "version": "1.0.0", "type": "library", "abandoned": false },
+ { "name": "c/uptodate", "version": "1.0.0", "type": "library", "abandoned": false },
+ { "name": "d/removed", "version": "1.0.0", "type": "library", "abandoned": false }
],
"packages-dev": [],
"aliases": [],
diff --git a/tests/Composer/Test/Fixtures/installer/update-alias-lock.test b/tests/Composer/Test/Fixtures/installer/update-alias-lock.test
index 0fc5fe301..256ce7e47 100644
--- a/tests/Composer/Test/Fixtures/installer/update-alias-lock.test
+++ b/tests/Composer/Test/Fixtures/installer/update-alias-lock.test
@@ -58,7 +58,8 @@ update
"name": "a/a", "version": "dev-master",
"extra": { "branch-alias": { "dev-master": "1.0.x-dev" } },
"source": { "reference": "master", "type": "git", "url": "" },
- "type": "library"
+ "type": "library",
+ "abandoned": false
}
],
"packages-dev": [],
@@ -70,4 +71,4 @@ update
"platform-dev": []
}
--EXPECT--
-Updating a/a (dev-master 1234) to a/a (dev-master master)
\ No newline at end of file
+Updating a/a (dev-master 1234) to a/a (dev-master master)
diff --git a/tests/Composer/Test/Fixtures/installer/updating-dev-updates-url-and-reference.test b/tests/Composer/Test/Fixtures/installer/updating-dev-updates-url-and-reference.test
index 849296850..aedc79fee 100644
--- a/tests/Composer/Test/Fixtures/installer/updating-dev-updates-url-and-reference.test
+++ b/tests/Composer/Test/Fixtures/installer/updating-dev-updates-url-and-reference.test
@@ -51,7 +51,8 @@ update
"name": "a/a", "version": "dev-master",
"type": "library",
"source": { "reference": "newref", "url": "newurl", "type": "git" },
- "dist": { "reference": "newref", "url": "newurl", "type": "zip", "shasum": "" }
+ "dist": { "reference": "newref", "url": "newurl", "type": "zip", "shasum": "" },
+ "abandoned": false
}
],
"packages-dev": [],
diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php
index a88ce7c21..5566e7c55 100644
--- a/tests/Composer/Test/InstallerTest.php
+++ b/tests/Composer/Test/InstallerTest.php
@@ -304,7 +304,7 @@ class InstallerTest extends TestCase
die(sprintf('Test "%s" is not valid, did not match the expected format.', str_replace($fixturesDir.'/', '', $file)));
}
- $tests[] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $composer, $lock, $installed, $run, $expectLock, $expectOutput, $expect, $expectExitCode);
+ $tests[basename($file)] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $composer, $lock, $installed, $run, $expectLock, $expectOutput, $expect, $expectExitCode);
}
return $tests;