Warn on invalid package name or require/provide/.., fixes #7874
parent
98a15bc93c
commit
acea4a4d4d
|
@ -347,7 +347,7 @@ class Factory
|
||||||
// load package
|
// load package
|
||||||
$parser = new VersionParser;
|
$parser = new VersionParser;
|
||||||
$guesser = new VersionGuesser($config, new ProcessExecutor($io), $parser);
|
$guesser = new VersionGuesser($config, new ProcessExecutor($io), $parser);
|
||||||
$loader = new Package\Loader\RootPackageLoader($rm, $config, $parser, $guesser);
|
$loader = new Package\Loader\RootPackageLoader($rm, $config, $parser, $guesser, $io);
|
||||||
$package = $loader->load($localConfig, 'Composer\Package\RootPackage', $cwd);
|
$package = $loader->load($localConfig, 'Composer\Package\RootPackage', $cwd);
|
||||||
$composer->setPackage($package);
|
$composer->setPackage($package);
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace Composer\Package\Loader;
|
||||||
use Composer\Package\BasePackage;
|
use Composer\Package\BasePackage;
|
||||||
use Composer\Package\AliasPackage;
|
use Composer\Package\AliasPackage;
|
||||||
use Composer\Config;
|
use Composer\Config;
|
||||||
|
use Composer\IO\IOInterface;
|
||||||
use Composer\Package\RootPackageInterface;
|
use Composer\Package\RootPackageInterface;
|
||||||
use Composer\Repository\RepositoryFactory;
|
use Composer\Repository\RepositoryFactory;
|
||||||
use Composer\Package\Version\VersionGuesser;
|
use Composer\Package\Version\VersionGuesser;
|
||||||
|
@ -46,13 +47,19 @@ class RootPackageLoader extends ArrayLoader
|
||||||
*/
|
*/
|
||||||
private $versionGuesser;
|
private $versionGuesser;
|
||||||
|
|
||||||
public function __construct(RepositoryManager $manager, Config $config, VersionParser $parser = null, VersionGuesser $versionGuesser = null)
|
/**
|
||||||
|
* @var IOInterface
|
||||||
|
*/
|
||||||
|
private $io;
|
||||||
|
|
||||||
|
public function __construct(RepositoryManager $manager, Config $config, VersionParser $parser = null, VersionGuesser $versionGuesser = null, IOInterface $io = null)
|
||||||
{
|
{
|
||||||
parent::__construct($parser);
|
parent::__construct($parser);
|
||||||
|
|
||||||
$this->manager = $manager;
|
$this->manager = $manager;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->versionGuesser = $versionGuesser ?: new VersionGuesser($config, new ProcessExecutor(), $this->versionParser);
|
$this->versionGuesser = $versionGuesser ?: new VersionGuesser($config, new ProcessExecutor(), $this->versionParser);
|
||||||
|
$this->io = $io;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,6 +72,10 @@ class RootPackageLoader extends ArrayLoader
|
||||||
{
|
{
|
||||||
if (!isset($config['name'])) {
|
if (!isset($config['name'])) {
|
||||||
$config['name'] = '__root__';
|
$config['name'] = '__root__';
|
||||||
|
} elseif ($this->io) {
|
||||||
|
if ($err = ValidatingArrayLoader::hasPackageNamingError($config['name'])) {
|
||||||
|
$this->io->writeError('<warning>Deprecation warning: Your package name '.$err.' Make sure you fix this as Composer 2.0 will error.</warning>');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$autoVersioned = false;
|
$autoVersioned = false;
|
||||||
if (!isset($config['version'])) {
|
if (!isset($config['version'])) {
|
||||||
|
@ -131,6 +142,18 @@ class RootPackageLoader extends ArrayLoader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->io) {
|
||||||
|
foreach (array_keys(BasePackage::$supportedLinkTypes) as $linkType) {
|
||||||
|
if (isset($config[$linkType])) {
|
||||||
|
foreach ($config[$linkType] as $linkName => $constraint) {
|
||||||
|
if ($err = ValidatingArrayLoader::hasPackageNamingError($linkName, true)) {
|
||||||
|
$this->io->writeError('<warning>Deprecation warning: '.$linkType.'.'.$err.' Make sure you fix this as Composer 2.0 will error.</warning>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($links[$config['name']])) {
|
if (isset($links[$config['name']])) {
|
||||||
throw new \InvalidArgumentException(sprintf('Root package \'%s\' cannot require itself in its composer.json' . PHP_EOL .
|
throw new \InvalidArgumentException(sprintf('Root package \'%s\' cannot require itself in its composer.json' . PHP_EOL .
|
||||||
'Did you accidentally name your root package after an external package?', $config['name']));
|
'Did you accidentally name your root package after an external package?', $config['name']));
|
||||||
|
|
|
@ -336,6 +336,38 @@ class ValidatingArrayLoader implements LoaderInterface
|
||||||
return $this->errors;
|
return $this->errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function hasPackageNamingError($name, $isLink = false)
|
||||||
|
{
|
||||||
|
if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preg_match('{^[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9]([_.-]?[a-z0-9]+)*$}iD', $name)) {
|
||||||
|
return $name.' is invalid, it should have a vendor name, a forward slash, and a package name. The vendor and package name can be words separated by -, . or _. The complete name should match "[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9]([_.-]?[a-z0-9]+)*".';
|
||||||
|
}
|
||||||
|
|
||||||
|
$reservedNames = array('nul', 'con', 'prn', 'aux', 'com1', 'com2', 'com3', 'com4', 'com5', 'com6', 'com7', 'com8', 'com9', 'lpt1', 'lpt2', 'lpt3', 'lpt4', 'lpt5', 'lpt6', 'lpt7', 'lpt8', 'lpt9');
|
||||||
|
$bits = explode('/', strtolower($name));
|
||||||
|
if (in_array($bits[0], $reservedNames, true) || in_array($bits[1], $reservedNames, true)) {
|
||||||
|
return $name.' is reserved, package and vendor names can not match any of: '.implode(', ', $reservedNames).'.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('{\.json$}', $name)) {
|
||||||
|
return $name.' is invalid, package names can not end in .json, consider renaming it or perhaps using a -json suffix instead.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('{[A-Z]}', $name)) {
|
||||||
|
if ($isLink) {
|
||||||
|
return $name.' is invalid, it should not contain uppercase characters. Please use '.strtolower($name).' instead.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$suggestName = preg_replace('{(?:([a-z])([A-Z])|([A-Z])([A-Z][a-z]))}', '\\1\\3-\\2\\4', $name);
|
||||||
|
$suggestName = strtolower($suggestName);
|
||||||
|
|
||||||
|
return $name.' is invalid, it should not contain uppercase characters. We suggest using '.$suggestName.' instead.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function validateRegex($property, $regex, $mandatory = false)
|
private function validateRegex($property, $regex, $mandatory = false)
|
||||||
{
|
{
|
||||||
if (!$this->validateString($property, $mandatory)) {
|
if (!$this->validateString($property, $mandatory)) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ use Composer\XdebugHandler\XdebugHandler;
|
||||||
*/
|
*/
|
||||||
class PlatformRepository extends ArrayRepository
|
class PlatformRepository extends ArrayRepository
|
||||||
{
|
{
|
||||||
const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[^/ ]+)$}i';
|
const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[a-z0-9](?:-?[a-z0-9]+)*)$}iD';
|
||||||
|
|
||||||
private $versionParser;
|
private $versionParser;
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,12 @@ Present a clear error message when config.platform.php version results in a conf
|
||||||
{
|
{
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"package": [
|
"package": [
|
||||||
{ "name": "a", "version": "1.0.0", "require": { "php": "5.5" } }
|
{ "name": "a/a", "version": "1.0.0", "require": { "php": "5.5" } }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"a": "~1.0"
|
"a/a": "~1.0"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"platform": {
|
"platform": {
|
||||||
|
@ -36,8 +36,8 @@ Updating dependencies (including require-dev)
|
||||||
Your requirements could not be resolved to an installable set of packages.
|
Your requirements could not be resolved to an installable set of packages.
|
||||||
|
|
||||||
Problem 1
|
Problem 1
|
||||||
- Installation request for a ~1.0 -> satisfiable by a[1.0.0].
|
- Installation request for a/a ~1.0 -> satisfiable by a/a[1.0.0].
|
||||||
- a 1.0.0 requires php 5.5 -> your PHP version (%s) overridden by "config.platform.php" version (5.3) does not satisfy that requirement.
|
- a/a 1.0.0 requires php 5.5 -> your PHP version (%s) overridden by "config.platform.php" version (5.3) does not satisfy that requirement.
|
||||||
|
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
|
|
||||||
|
|
|
@ -11,27 +11,27 @@ that are also a root package, when that root package is also explicitly whitelis
|
||||||
{
|
{
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"package": [
|
"package": [
|
||||||
{ "name": "a", "version": "1.0.0" },
|
{ "name": "a/a", "version": "1.0.0" },
|
||||||
{ "name": "a", "version": "1.1.0" },
|
{ "name": "a/a", "version": "1.1.0" },
|
||||||
{ "name": "b", "version": "1.0.0", "require": { "a": "~1.0" } },
|
{ "name": "b/b", "version": "1.0.0", "require": { "a/a": "~1.0" } },
|
||||||
{ "name": "b", "version": "1.1.0", "require": { "a": "~1.1" } }
|
{ "name": "b/b", "version": "1.1.0", "require": { "a/a": "~1.1" } }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"a": "~1.0",
|
"a/a": "~1.0",
|
||||||
"b": "~1.0"
|
"b/b": "~1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
--INSTALLED--
|
--INSTALLED--
|
||||||
[
|
[
|
||||||
{ "name": "a", "version": "1.0.0" },
|
{ "name": "a/a", "version": "1.0.0" },
|
||||||
{ "name": "b", "version": "1.0.0", "require": { "a": "~1.0" } }
|
{ "name": "b/b", "version": "1.0.0", "require": { "a/a": "~1.0" } }
|
||||||
]
|
]
|
||||||
|
|
||||||
--RUN--
|
--RUN--
|
||||||
update a b --with-dependencies
|
update a/a b/b --with-dependencies
|
||||||
|
|
||||||
--EXPECT-OUTPUT--
|
--EXPECT-OUTPUT--
|
||||||
Loading composer repositories with package information
|
Loading composer repositories with package information
|
||||||
|
@ -41,5 +41,5 @@ Writing lock file
|
||||||
Generating autoload files
|
Generating autoload files
|
||||||
|
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
Updating a (1.0.0) to a (1.1.0)
|
Updating a/a (1.0.0) to a/a (1.1.0)
|
||||||
Updating b (1.0.0) to b (1.1.0)
|
Updating b/b (1.0.0) to b/b (1.1.0)
|
||||||
|
|
|
@ -11,30 +11,30 @@ dependency of one the requirements that is whitelisted for update.
|
||||||
{
|
{
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"package": [
|
"package": [
|
||||||
{ "name": "a", "version": "1.0.0" },
|
{ "name": "a/a", "version": "1.0.0" },
|
||||||
{ "name": "a", "version": "1.1.0" },
|
{ "name": "a/a", "version": "1.1.0" },
|
||||||
{ "name": "b", "version": "1.0.0", "require": { "a": "~1.0" } },
|
{ "name": "b/b", "version": "1.0.0", "require": { "a/a": "~1.0" } },
|
||||||
{ "name": "b", "version": "1.1.0", "require": { "a": "~1.1" } }
|
{ "name": "b/b", "version": "1.1.0", "require": { "a/b": "~1.1" } }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"a": "~1.0",
|
"a/a": "~1.0",
|
||||||
"b": "~1.0"
|
"b/b": "~1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
--INSTALLED--
|
--INSTALLED--
|
||||||
[
|
[
|
||||||
{ "name": "a", "version": "1.0.0" },
|
{ "name": "a/a", "version": "1.0.0" },
|
||||||
{ "name": "b", "version": "1.0.0", "require": { "a": "~1.0" } }
|
{ "name": "b/b", "version": "1.0.0", "require": { "a/a": "~1.0" } }
|
||||||
]
|
]
|
||||||
|
|
||||||
--RUN--
|
--RUN--
|
||||||
update b --with-dependencies
|
update b/b --with-dependencies
|
||||||
|
|
||||||
--EXPECT-OUTPUT--
|
--EXPECT-OUTPUT--
|
||||||
<warning>Dependency "a" is also a root requirement, but is not explicitly whitelisted. Ignoring.</warning>
|
<warning>Dependency "a/a" is also a root requirement, but is not explicitly whitelisted. Ignoring.</warning>
|
||||||
Loading composer repositories with package information
|
Loading composer repositories with package information
|
||||||
Updating dependencies (including require-dev)
|
Updating dependencies (including require-dev)
|
||||||
Nothing to install or update
|
Nothing to install or update
|
||||||
|
|
|
@ -8,30 +8,30 @@ Test the error output of solver problems.
|
||||||
"package": [
|
"package": [
|
||||||
{ "name": "unstable/package", "version": "2.0.0-alpha" },
|
{ "name": "unstable/package", "version": "2.0.0-alpha" },
|
||||||
{ "name": "unstable/package", "version": "1.0.0" },
|
{ "name": "unstable/package", "version": "1.0.0" },
|
||||||
{ "name": "requirer", "version": "1.0.0", "require": {"dependency": "1.0.0" } },
|
{ "name": "requirer/pkg", "version": "1.0.0", "require": {"dependency/pkg": "1.0.0" } },
|
||||||
{ "name": "dependency", "version": "2.0.0" },
|
{ "name": "dependency/pkg", "version": "2.0.0" },
|
||||||
{ "name": "dependency", "version": "1.0.0" },
|
{ "name": "dependency/pkg", "version": "1.0.0" },
|
||||||
{ "name": "stable-requiree-excluded", "version": "1.0.1" },
|
{ "name": "stable-requiree-excluded/pkg", "version": "1.0.1" },
|
||||||
{ "name": "stable-requiree-excluded", "version": "1.0.0" }
|
{ "name": "stable-requiree-excluded/pkg", "version": "1.0.0" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"unstable/package": "2.*",
|
"unstable/package": "2.*",
|
||||||
"bogus": "1.*",
|
"bogus/pkg": "1.*",
|
||||||
"requirer": "1.*",
|
"requirer/pkg": "1.*",
|
||||||
"dependency": "2.*",
|
"dependency/pkg": "2.*",
|
||||||
"stable-requiree-excluded": "1.0.1"
|
"stable-requiree-excluded/pkg": "1.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
--INSTALLED--
|
--INSTALLED--
|
||||||
[
|
[
|
||||||
{ "name": "stable-requiree-excluded", "version": "1.0.0" }
|
{ "name": "stable-requiree-excluded/pkg", "version": "1.0.0" }
|
||||||
]
|
]
|
||||||
|
|
||||||
--RUN--
|
--RUN--
|
||||||
update unstable/package requirer dependency
|
update unstable/package requirer/pkg dependency/pkg
|
||||||
|
|
||||||
--EXPECT-EXIT-CODE--
|
--EXPECT-EXIT-CODE--
|
||||||
2
|
2
|
||||||
|
@ -44,12 +44,12 @@ Your requirements could not be resolved to an installable set of packages.
|
||||||
Problem 1
|
Problem 1
|
||||||
- The requested package unstable/package 2.* exists as unstable/package[1.0.0] but these are rejected by your constraint.
|
- The requested package unstable/package 2.* exists as unstable/package[1.0.0] but these are rejected by your constraint.
|
||||||
Problem 2
|
Problem 2
|
||||||
- The requested package bogus could not be found in any version, there may be a typo in the package name.
|
- The requested package bogus/pkg could not be found in any version, there may be a typo in the package name.
|
||||||
Problem 3
|
Problem 3
|
||||||
- The requested package stable-requiree-excluded (installed at 1.0.0, required as 1.0.1) is satisfiable by stable-requiree-excluded[1.0.0] but these conflict with your requirements or minimum-stability.
|
- The requested package stable-requiree-excluded/pkg (installed at 1.0.0, required as 1.0.1) is satisfiable by stable-requiree-excluded/pkg[1.0.0] but these conflict with your requirements or minimum-stability.
|
||||||
Problem 4
|
Problem 4
|
||||||
- Installation request for requirer 1.* -> satisfiable by requirer[1.0.0].
|
- Installation request for requirer/pkg 1.* -> satisfiable by requirer/pkg[1.0.0].
|
||||||
- requirer 1.0.0 requires dependency 1.0.0 -> satisfiable by dependency[1.0.0] but these conflict with your requirements or minimum-stability.
|
- requirer/pkg 1.0.0 requires dependency/pkg 1.0.0 -> satisfiable by dependency/pkg[1.0.0] but these conflict with your requirements or minimum-stability.
|
||||||
|
|
||||||
Potential causes:
|
Potential causes:
|
||||||
- A typo in the package name
|
- A typo in the package name
|
||||||
|
|
|
@ -10,27 +10,27 @@ When `--with-all-dependencies` is used, Composer\Installer::whitelistUpdateDepen
|
||||||
{
|
{
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"package": [
|
"package": [
|
||||||
{ "name": "a", "version": "1.0.0" },
|
{ "name": "a/a", "version": "1.0.0" },
|
||||||
{ "name": "a", "version": "1.1.0" },
|
{ "name": "a/a", "version": "1.1.0" },
|
||||||
{ "name": "b", "version": "1.0.0", "require": { "a": "~1.0" } },
|
{ "name": "b/b", "version": "1.0.0", "require": { "a/a": "~1.0" } },
|
||||||
{ "name": "b", "version": "1.1.0", "require": { "a": "~1.1" } }
|
{ "name": "b/b", "version": "1.1.0", "require": { "a/a": "~1.1" } }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"a": "~1.0",
|
"a/a": "~1.0",
|
||||||
"b": "~1.0"
|
"b/b": "~1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
--INSTALLED--
|
--INSTALLED--
|
||||||
[
|
[
|
||||||
{ "name": "a", "version": "1.0.0" },
|
{ "name": "a/a", "version": "1.0.0" },
|
||||||
{ "name": "b", "version": "1.0.0", "require": { "a": "~1.0" } }
|
{ "name": "b/b", "version": "1.0.0", "require": { "a/a": "~1.0" } }
|
||||||
]
|
]
|
||||||
|
|
||||||
--RUN--
|
--RUN--
|
||||||
update b --with-all-dependencies
|
update b/b --with-all-dependencies
|
||||||
|
|
||||||
--EXPECT-OUTPUT--
|
--EXPECT-OUTPUT--
|
||||||
Loading composer repositories with package information
|
Loading composer repositories with package information
|
||||||
|
@ -40,5 +40,5 @@ Writing lock file
|
||||||
Generating autoload files
|
Generating autoload files
|
||||||
|
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
Updating a (1.0.0) to a (1.1.0)
|
Updating a/a (1.0.0) to a/a (1.1.0)
|
||||||
Updating b (1.0.0) to b (1.1.0)
|
Updating b/b (1.0.0) to b/b (1.1.0)
|
||||||
|
|
Loading…
Reference in New Issue