Merge remote-tracking branch 'donquixote/feature/psr4-complete'
commit
b23742e30c
|
@ -15,6 +15,7 @@ before_script:
|
|||
- sudo apt-get install parallel
|
||||
- rm -f ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini
|
||||
- composer install --dev --prefer-source
|
||||
- bin/composer install --dev --prefer-source
|
||||
- git config --global user.name travis-ci
|
||||
- git config --global user.email travis@example.com
|
||||
|
||||
|
|
|
@ -438,6 +438,10 @@ use an empty prefix like:
|
|||
}
|
||||
}
|
||||
|
||||
#### PSR-4
|
||||
|
||||
Stub: Similar to PSR-0.
|
||||
|
||||
#### Classmap
|
||||
|
||||
The `classmap` references are all combined, during install/update, into a single
|
||||
|
|
|
@ -207,6 +207,11 @@
|
|||
"description": "This is a hash of namespaces (keys) and the directories they can be found into (values, can be arrays of paths) by the autoloader.",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"psr-4": {
|
||||
"type": "object",
|
||||
"description": "This is a hash of namespaces (keys) and the PSR-4 directories they can be found into (values, can be arrays of paths) by the autoloader.",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"classmap": {
|
||||
"type": "array",
|
||||
"description": "This is an array of directories that contain classes to be included in the class-map generation process."
|
||||
|
|
|
@ -69,9 +69,23 @@ return array(
|
|||
|
||||
EOF;
|
||||
|
||||
$psr4File = <<<EOF
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
\$vendorDir = $vendorPathCode52;
|
||||
\$baseDir = $appBaseDirCode;
|
||||
|
||||
return array(
|
||||
|
||||
EOF;
|
||||
|
||||
// Collect information from all packages.
|
||||
$packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getCanonicalPackages());
|
||||
$autoloads = $this->parseAutoloads($packageMap, $mainPackage);
|
||||
|
||||
// Process the 'psr-0' base directories.
|
||||
foreach ($autoloads['psr-0'] as $namespace => $paths) {
|
||||
$exportedPaths = array();
|
||||
foreach ($paths as $path) {
|
||||
|
@ -83,6 +97,21 @@ EOF;
|
|||
}
|
||||
$namespacesFile .= ");\n";
|
||||
|
||||
// Process the 'psr-4' base directories.
|
||||
foreach ($autoloads['psr-4'] as $namespace => $paths) {
|
||||
if ('\\' !== $namespace[strlen($namespace) - 1]) {
|
||||
throw new \Exception("PSR-4 namespaces must end with a namespace separator. '$namespace' does not.");
|
||||
}
|
||||
$exportedPaths = array();
|
||||
foreach ($paths as $path) {
|
||||
$exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
|
||||
}
|
||||
$exportedPrefix = var_export($namespace, true);
|
||||
$psr4File .= " $exportedPrefix => ";
|
||||
$psr4File .= "array(".implode(', ', $exportedPaths)."),\n";
|
||||
}
|
||||
$psr4File .= ");\n";
|
||||
|
||||
$classmapFile = <<<EOF
|
||||
<?php
|
||||
|
||||
|
@ -131,6 +160,8 @@ EOF;
|
|||
// flatten array
|
||||
$classMap = array();
|
||||
if ($scanPsr0Packages) {
|
||||
// Scan the PSR-0 directories for class files, and add them to the
|
||||
// class map.
|
||||
foreach ($autoloads['psr-0'] as $namespace => $paths) {
|
||||
foreach ($paths as $dir) {
|
||||
$dir = $filesystem->normalizePath($filesystem->isAbsolutePath($dir) ? $dir : $basePath.'/'.$dir);
|
||||
|
@ -152,6 +183,29 @@ EOF;
|
|||
}
|
||||
}
|
||||
}
|
||||
// Scan the PSR-4 directories for class files, and add them to the
|
||||
// class map.
|
||||
foreach ($autoloads['psr-4'] as $namespace => $paths) {
|
||||
foreach ($paths as $dir) {
|
||||
$dir = $filesystem->normalizePath($filesystem->isAbsolutePath($dir) ? $dir : $basePath.'/'.$dir);
|
||||
if (!is_dir($dir)) {
|
||||
continue;
|
||||
}
|
||||
$whitelist = sprintf(
|
||||
'{%s/%s.+(?<!(?<!/)Test\.php)$}',
|
||||
preg_quote($dir),
|
||||
strpos($namespace, '_') === false ? preg_quote(strtr($namespace, '\\', '/')) : ''
|
||||
);
|
||||
foreach (ClassMapGenerator::createMap($dir, $whitelist) as $class => $path) {
|
||||
if ('' === $namespace || 0 === strpos($class, $namespace)) {
|
||||
if (!isset($classMap[$class])) {
|
||||
$path = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
|
||||
$classMap[$class] = $path.",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$autoloads['classmap'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['classmap']));
|
||||
|
@ -173,6 +227,7 @@ EOF;
|
|||
}
|
||||
|
||||
file_put_contents($targetDir.'/autoload_namespaces.php', $namespacesFile);
|
||||
file_put_contents($targetDir.'/autoload_psr4.php', $psr4File);
|
||||
file_put_contents($targetDir.'/autoload_classmap.php', $classmapFile);
|
||||
if ($includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) {
|
||||
file_put_contents($targetDir.'/include_paths.php', $includePathFile);
|
||||
|
@ -181,7 +236,7 @@ EOF;
|
|||
file_put_contents($targetDir.'/autoload_files.php', $includeFilesFile);
|
||||
}
|
||||
file_put_contents($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix));
|
||||
file_put_contents($targetDir.'/autoload_real.php', $this->getAutoloadRealFile(true, true, (bool) $includePathFile, $targetDirLoader, (bool) $includeFilesFile, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader));
|
||||
file_put_contents($targetDir.'/autoload_real.php', $this->getAutoloadRealFile(true, (bool) $includePathFile, $targetDirLoader, (bool) $includeFilesFile, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader));
|
||||
|
||||
// use stream_copy_to_stream instead of copy
|
||||
// to work around https://bugs.php.net/bug.php?id=64634
|
||||
|
@ -204,6 +259,7 @@ EOF;
|
|||
if ($package instanceof AliasPackage) {
|
||||
continue;
|
||||
}
|
||||
$this->validatePackage($package);
|
||||
|
||||
$packageMap[] = array(
|
||||
$package,
|
||||
|
@ -214,6 +270,21 @@ EOF;
|
|||
return $packageMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PackageInterface $package
|
||||
*
|
||||
* @throws \Exception
|
||||
* Throws an exception, if the package has illegal settings.
|
||||
*/
|
||||
protected function validatePackage(PackageInterface $package) {
|
||||
$autoload = $package->getAutoload();
|
||||
if (!empty($autoload['psr-4']) && null !== $package->getTargetDir()) {
|
||||
$name = $package->getName();
|
||||
$package->getTargetDir();
|
||||
throw new \Exception("The ['autoload']['psr-4'] setting is incompatible with the ['target-dir'] setting, in package '$name'.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles an ordered list of namespace => path mappings
|
||||
*
|
||||
|
@ -229,12 +300,14 @@ EOF;
|
|||
array_unshift($packageMap, $mainPackageMap);
|
||||
|
||||
$psr0 = $this->parseAutoloadsType($packageMap, 'psr-0', $mainPackage);
|
||||
$psr4 = $this->parseAutoloadsType($packageMap, 'psr-4', $mainPackage);
|
||||
$classmap = $this->parseAutoloadsType($sortedPackageMap, 'classmap', $mainPackage);
|
||||
$files = $this->parseAutoloadsType($sortedPackageMap, 'files', $mainPackage);
|
||||
|
||||
krsort($psr0);
|
||||
krsort($psr4);
|
||||
|
||||
return array('psr-0' => $psr0, 'classmap' => $classmap, 'files' => $files);
|
||||
return array('psr-0' => $psr0, 'psr-4' => $psr4, 'classmap' => $classmap, 'files' => $files);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -253,6 +326,12 @@ EOF;
|
|||
}
|
||||
}
|
||||
|
||||
if (isset($autoloads['psr-4'])) {
|
||||
foreach ($autoloads['psr-4'] as $namespace => $path) {
|
||||
$loader->addPsr4($namespace, $path);
|
||||
}
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
|
||||
|
@ -366,7 +445,7 @@ return ComposerAutoloaderInit$suffix::getLoader();
|
|||
AUTOLOAD;
|
||||
}
|
||||
|
||||
protected function getAutoloadRealFile($usePSR0, $useClassMap, $useIncludePath, $targetDirLoader, $useIncludeFiles, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader)
|
||||
protected function getAutoloadRealFile($useClassMap, $useIncludePath, $targetDirLoader, $useIncludeFiles, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader)
|
||||
{
|
||||
// TODO the class ComposerAutoloaderInit should be revert to a closure
|
||||
// when APC has been fixed:
|
||||
|
@ -417,8 +496,7 @@ HEADER;
|
|||
INCLUDE_PATH;
|
||||
}
|
||||
|
||||
if ($usePSR0) {
|
||||
$file .= <<<'PSR0'
|
||||
$file .= <<<'PSR0'
|
||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->set($namespace, $path);
|
||||
|
@ -426,8 +504,16 @@ INCLUDE_PATH;
|
|||
|
||||
|
||||
PSR0;
|
||||
|
||||
$file .= <<<'PSR4'
|
||||
$map = require __DIR__ . '/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->setPsr4($namespace, $path);
|
||||
}
|
||||
|
||||
|
||||
PSR4;
|
||||
|
||||
if ($useClassMap) {
|
||||
$file .= <<<'CLASSMAP'
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
|
|
|
@ -42,19 +42,36 @@ namespace Composer\Autoload;
|
|||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
private $prefixes = array();
|
||||
private $fallbackDirs = array();
|
||||
// PSR-4
|
||||
private $prefixLengthsPsr4 = array();
|
||||
private $prefixDirsPsr4 = array();
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
private $prefixesPsr0 = array();
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
private $useIncludePath = false;
|
||||
private $classMap = array();
|
||||
|
||||
public function getPrefixes()
|
||||
{
|
||||
return call_user_func_array('array_merge', $this->prefixes);
|
||||
return call_user_func_array('array_merge', $this->prefixesPsr0);
|
||||
}
|
||||
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirs;
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
public function getClassMap()
|
||||
|
@ -75,23 +92,24 @@ class ClassLoader
|
|||
}
|
||||
|
||||
/**
|
||||
* Registers a set of classes, merging with any others previously set.
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The classes prefix
|
||||
* @param array|string $paths The location(s) of the classes
|
||||
* @param bool $prepend Prepend the location(s)
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirs = array_merge(
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirs
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirs = array_merge(
|
||||
$this->fallbackDirs,
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
@ -100,38 +118,104 @@ class ClassLoader
|
|||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixes[$first][$prefix])) {
|
||||
$this->prefixes[$first][$prefix] = (array) $paths;
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixes[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixes[$first][$prefix]
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixes[$first][$prefix] = array_merge(
|
||||
$this->prefixes[$first][$prefix],
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of classes, replacing any others previously set.
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The classes prefix
|
||||
* @param array|string $paths The location(s) of the classes
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-0 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \Exception("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 base directories
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirs = (array) $paths;
|
||||
|
||||
return;
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
*/
|
||||
public function setPsr4($prefix, $paths) {
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \Exception("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
$this->prefixes[substr($prefix, 0, 1)][$prefix] = (array) $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -202,45 +286,71 @@ class ClassLoader
|
|||
$class = substr($class, 1);
|
||||
}
|
||||
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$classPath = strtr(substr($class, 0, $pos), '\\', DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
||||
$className = substr($class, $pos + 1);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$classPath = null;
|
||||
$className = $class;
|
||||
}
|
||||
|
||||
$classPath .= strtr($className, '_', DIRECTORY_SEPARATOR) . '.php';
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . '.php';
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixes[$first])) {
|
||||
foreach ($this->prefixes[$first] as $prefix => $dirs) {
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) {
|
||||
return $dir . DIRECTORY_SEPARATOR . $classPath;
|
||||
foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->fallbackDirs as $dir) {
|
||||
if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) {
|
||||
return $dir . DIRECTORY_SEPARATOR . $classPath;
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($classPath)) {
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0
|
||||
= substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR)
|
||||
;
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . '.php';
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
// Remember that this class does not exist.
|
||||
return $this->classMap[$class] = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -303,6 +303,10 @@ EOT
|
|||
foreach ($autoloads as $name => $path) {
|
||||
$output->writeln(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.')));
|
||||
}
|
||||
} elseif ($type === 'psr-4') {
|
||||
foreach ($autoloads as $name => $path) {
|
||||
$output->writeln(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.')));
|
||||
}
|
||||
} elseif ($type === 'classmap') {
|
||||
$output->writeln(implode(', ', $autoloads));
|
||||
}
|
||||
|
|
|
@ -103,6 +103,7 @@ class Compiler
|
|||
|
||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/autoload.php'));
|
||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_namespaces.php'));
|
||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_psr4.php'));
|
||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_classmap.php'));
|
||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_real.php'));
|
||||
if (file_exists(__DIR__.'/../../vendor/composer/include_paths.php')) {
|
||||
|
|
|
@ -180,7 +180,7 @@ class ValidatingArrayLoader implements LoaderInterface
|
|||
}
|
||||
|
||||
if ($this->validateArray('autoload') && !empty($this->config['autoload'])) {
|
||||
$types = array('psr-0', 'classmap', 'files');
|
||||
$types = array('psr-0', 'psr-4', 'classmap', 'files');
|
||||
foreach ($this->config['autoload'] as $type => $typeConfig) {
|
||||
if (!in_array($type, $types)) {
|
||||
$this->errors[] = 'autoload : invalid value ('.$type.'), must be one of '.implode(', ', $types);
|
||||
|
@ -189,6 +189,13 @@ class ValidatingArrayLoader implements LoaderInterface
|
|||
}
|
||||
}
|
||||
|
||||
if (!empty($this->config['autoload']['psr-4']) && !empty($this->config['target-dir'])) {
|
||||
$this->errors[] = "The ['autoload']['psr-4'] setting is incompatible with the ['target-dir'] setting.";
|
||||
// Unset the psr-4 setting, since unsetting target-dir might
|
||||
// interfere with other settings.
|
||||
unset($this->config['autoload']['psr-4']);
|
||||
}
|
||||
|
||||
// TODO validate dist
|
||||
// TODO validate source
|
||||
|
||||
|
|
|
@ -95,7 +95,14 @@ class AutoloadGeneratorTest extends TestCase
|
|||
{
|
||||
$package = new Package('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Main' => 'src/', 'Lala' => array('src/', 'lib/')),
|
||||
'psr-0' => array(
|
||||
'Main' => 'src/',
|
||||
'Lala' => array('src/', 'lib/'),
|
||||
),
|
||||
'psr-4' => array(
|
||||
'Acme\Fruit\\' => 'src-fruit/',
|
||||
'Acme\Cake\\' => array('src-cake/', 'lib-cake/'),
|
||||
),
|
||||
'classmap' => array('composersrc/'),
|
||||
));
|
||||
|
||||
|
@ -107,11 +114,22 @@ class AutoloadGeneratorTest extends TestCase
|
|||
$this->fs->ensureDirectoryExists($this->workingDir.'/src');
|
||||
$this->fs->ensureDirectoryExists($this->workingDir.'/lib');
|
||||
|
||||
$this->fs->ensureDirectoryExists($this->workingDir.'/src-fruit');
|
||||
$this->fs->ensureDirectoryExists($this->workingDir.'/src-cake');
|
||||
$this->fs->ensureDirectoryExists($this->workingDir.'/lib-cake');
|
||||
|
||||
$this->fs->ensureDirectoryExists($this->workingDir.'/composersrc');
|
||||
file_put_contents($this->workingDir.'/composersrc/foo.php', '<?php class ClassMapFoo {}');
|
||||
|
||||
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', false, '_1');
|
||||
|
||||
// Assert that autoload_namespaces.php was correctly generated.
|
||||
$this->assertAutoloadFiles('main', $this->vendorDir.'/composer');
|
||||
|
||||
// Assert that autoload_psr4.php was correctly generated.
|
||||
$this->assertAutoloadFiles('psr4', $this->vendorDir.'/composer', 'psr4');
|
||||
|
||||
// Assert that autoload_classmap.php was correctly generated.
|
||||
$this->assertAutoloadFiles('classmap', $this->vendorDir.'/composer', 'classmap');
|
||||
}
|
||||
|
||||
|
@ -122,6 +140,10 @@ class AutoloadGeneratorTest extends TestCase
|
|||
$package = new Package('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Main' => 'src/', 'Lala' => 'src/'),
|
||||
'psr-4' => array(
|
||||
'Acme\Fruit\\' => 'src-fruit/',
|
||||
'Acme\Cake\\' => array('src-cake/', 'lib-cake/'),
|
||||
),
|
||||
'classmap' => array('composersrc/'),
|
||||
));
|
||||
|
||||
|
@ -138,6 +160,7 @@ class AutoloadGeneratorTest extends TestCase
|
|||
|
||||
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', true, '_2');
|
||||
$this->assertAutoloadFiles('main3', $this->vendorDir.'/composer');
|
||||
$this->assertAutoloadFiles('psr4_3', $this->vendorDir.'/composer', 'psr4');
|
||||
$this->assertAutoloadFiles('classmap3', $this->vendorDir.'/composer', 'classmap');
|
||||
}
|
||||
|
||||
|
@ -146,6 +169,10 @@ class AutoloadGeneratorTest extends TestCase
|
|||
$package = new Package('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Main' => 'src/', 'Lala' => 'src/'),
|
||||
'psr-4' => array(
|
||||
'Acme\Fruit\\' => 'src-fruit/',
|
||||
'Acme\Cake\\' => array('src-cake/', 'lib-cake/'),
|
||||
),
|
||||
'classmap' => array('composersrc/'),
|
||||
));
|
||||
|
||||
|
@ -162,6 +189,7 @@ class AutoloadGeneratorTest extends TestCase
|
|||
file_put_contents($this->workingDir.'/composersrc/foo.php', '<?php class ClassMapFoo {}');
|
||||
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', false, '_3');
|
||||
$this->assertAutoloadFiles('main2', $this->vendorDir.'/composer');
|
||||
$this->assertAutoloadFiles('psr4_2', $this->vendorDir.'/composer', 'psr4');
|
||||
$this->assertAutoloadFiles('classmap2', $this->vendorDir.'/composer', 'classmap');
|
||||
}
|
||||
|
||||
|
@ -170,6 +198,10 @@ class AutoloadGeneratorTest extends TestCase
|
|||
$package = new Package('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Main\\Foo' => '', 'Main\\Bar' => ''),
|
||||
'psr-4' => array(
|
||||
'Acme\Fruit\\' => 'src-fruit/',
|
||||
'Acme\Cake\\' => array('src-cake/', 'lib-cake/'),
|
||||
),
|
||||
'classmap' => array('Main/Foo/src', 'lib'),
|
||||
'files' => array('foo.php', 'Main/Foo/bar.php'),
|
||||
));
|
||||
|
@ -486,6 +518,20 @@ return array(
|
|||
'A' => array(\$vendorDir . '/a/a/src'),
|
||||
);
|
||||
|
||||
EOF;
|
||||
|
||||
// autoload_psr4.php is expected to be empty in this example.
|
||||
$expectedPsr4 = <<<EOF
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
\$vendorDir = dirname(dirname(__FILE__));
|
||||
\$baseDir = dirname(\$vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
|
||||
EOF;
|
||||
|
||||
$expectedClassmap = <<<EOF
|
||||
|
@ -505,6 +551,7 @@ EOF;
|
|||
|
||||
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', true, '_9');
|
||||
$this->assertEquals($expectedNamespace, file_get_contents($this->vendorDir.'/composer/autoload_namespaces.php'));
|
||||
$this->assertEquals($expectedPsr4, file_get_contents($this->vendorDir.'/composer/autoload_psr4.php'));
|
||||
$this->assertEquals($expectedClassmap, file_get_contents($this->vendorDir.'/composer/autoload_classmap.php'));
|
||||
}
|
||||
|
||||
|
@ -678,6 +725,7 @@ EOF;
|
|||
$package = new Package('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Foo' => 'src'),
|
||||
'psr-4' => array('Acme\Foo\\' => 'src-psr4'),
|
||||
'classmap' => array('classmap'),
|
||||
'files' => array('test.php'),
|
||||
));
|
||||
|
@ -685,6 +733,7 @@ EOF;
|
|||
$vendorPackage = new Package('b/b', '1.0', '1.0');
|
||||
$vendorPackage->setAutoload(array(
|
||||
'psr-0' => array('Bar' => 'lib'),
|
||||
'psr-4' => array('Acme\Bar\\' => 'lib-psr4'),
|
||||
'classmap' => array('classmaps'),
|
||||
'files' => array('bootstrap.php'),
|
||||
));
|
||||
|
@ -734,6 +783,21 @@ return array(
|
|||
'Bar' => array($vendorDir . '/b/b/lib'),
|
||||
);
|
||||
|
||||
EOF;
|
||||
|
||||
$expectedPsr4 = <<<'EOF'
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir).'/working-dir';
|
||||
|
||||
return array(
|
||||
'Acme\\Foo\\' => array($baseDir . '/src-psr4'),
|
||||
'Acme\\Bar\\' => array($vendorDir . '/b/b/lib-psr4'),
|
||||
);
|
||||
|
||||
EOF;
|
||||
|
||||
$expectedClassmap = <<<'EOF'
|
||||
|
@ -754,6 +818,7 @@ return array(
|
|||
EOF;
|
||||
|
||||
$this->assertEquals($expectedNamespace, file_get_contents($vendorDir.'/composer/autoload_namespaces.php'));
|
||||
$this->assertEquals($expectedPsr4, file_get_contents($vendorDir.'/composer/autoload_psr4.php'));
|
||||
$this->assertEquals($expectedClassmap, file_get_contents($vendorDir.'/composer/autoload_classmap.php'));
|
||||
$this->assertContains("\n \$vendorDir . '/b/b/bootstrap.php',\n", file_get_contents($vendorDir.'/composer/autoload_files.php'));
|
||||
$this->assertContains("\n \$baseDir . '/test.php',\n", file_get_contents($vendorDir.'/composer/autoload_files.php'));
|
||||
|
@ -768,6 +833,7 @@ EOF;
|
|||
$package = new Package('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Foo' => '../path/../src'),
|
||||
'psr-4' => array('Acme\Foo\\' => '../path/../src-psr4'),
|
||||
'classmap' => array('../classmap'),
|
||||
'files' => array('../test.php'),
|
||||
));
|
||||
|
@ -798,7 +864,21 @@ return array(
|
|||
|
||||
EOF;
|
||||
|
||||
$expectedClassmap = <<<'EOF'
|
||||
$expectedPsr4 = <<<'EOF'
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir).'/working-dir';
|
||||
|
||||
return array(
|
||||
'Acme\\Foo\\' => array($baseDir . '/../src-psr4'),
|
||||
);
|
||||
|
||||
EOF;
|
||||
|
||||
$expectedClassmap = <<<'EOF'
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
@ -814,6 +894,7 @@ return array(
|
|||
EOF;
|
||||
|
||||
$this->assertEquals($expectedNamespace, file_get_contents($this->vendorDir.'/composer/autoload_namespaces.php'));
|
||||
$this->assertEquals($expectedPsr4, file_get_contents($this->vendorDir.'/composer/autoload_psr4.php'));
|
||||
$this->assertEquals($expectedClassmap, file_get_contents($this->vendorDir.'/composer/autoload_classmap.php'));
|
||||
$this->assertContains("\n \$baseDir . '/../test.php',\n", file_get_contents($this->vendorDir.'/composer/autoload_files.php'));
|
||||
}
|
||||
|
@ -823,6 +904,7 @@ EOF;
|
|||
$package = new Package('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Foo' => ''),
|
||||
'psr-4' => array('Acme\Foo\\' => ''),
|
||||
'classmap' => array(''),
|
||||
));
|
||||
|
||||
|
@ -850,7 +932,21 @@ return array(
|
|||
|
||||
EOF;
|
||||
|
||||
$expectedClassmap = <<<'EOF'
|
||||
$expectedPsr4 = <<<'EOF'
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Acme\\Foo\\' => array($baseDir . '/'),
|
||||
);
|
||||
|
||||
EOF;
|
||||
|
||||
$expectedClassmap = <<<'EOF'
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
@ -866,6 +962,7 @@ return array(
|
|||
EOF;
|
||||
|
||||
$this->assertEquals($expectedNamespace, file_get_contents($this->vendorDir.'/composer/autoload_namespaces.php'));
|
||||
$this->assertEquals($expectedPsr4, file_get_contents($this->vendorDir.'/composer/autoload_psr4.php'));
|
||||
$this->assertEquals($expectedClassmap, file_get_contents($this->vendorDir.'/composer/autoload_classmap.php'));
|
||||
}
|
||||
|
||||
|
@ -874,6 +971,7 @@ EOF;
|
|||
$package = new Package('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Foo' => 'composer-test-autoload-src/src'),
|
||||
'psr-4' => array('Acme\Foo\\' => 'composer-test-autoload-src/src-psr4'),
|
||||
));
|
||||
|
||||
$this->repository->expects($this->once())
|
||||
|
@ -894,10 +992,25 @@ return array(
|
|||
'Foo' => array($baseDir . '/composer-test-autoload-src/src'),
|
||||
);
|
||||
|
||||
EOF;
|
||||
|
||||
$expectedPsr4 = <<<'EOF'
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Acme\\Foo\\' => array($baseDir . '/composer-test-autoload-src/src-psr4'),
|
||||
);
|
||||
|
||||
EOF;
|
||||
|
||||
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', false, 'VendorSubstring');
|
||||
$this->assertEquals($expectedNamespace, file_get_contents($this->vendorDir.'/composer/autoload_namespaces.php'));
|
||||
$this->assertEquals($expectedPsr4, file_get_contents($this->vendorDir.'/composer/autoload_psr4.php'));
|
||||
}
|
||||
|
||||
private function assertAutoloadFiles($name, $dir, $type = 'namespaces')
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace Composer\Test\Autoload;
|
||||
|
||||
use Composer\Autoload\ClassLoader;
|
||||
|
||||
/**
|
||||
* Tests the Composer\Autoload\ClassLoader class.
|
||||
*/
|
||||
class ClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Tests regular PSR-0 and PSR-4 class loading.
|
||||
*
|
||||
* @dataProvider getLoadClassTests
|
||||
*
|
||||
* @param string $class
|
||||
* The fully-qualified class name to test,
|
||||
* without preceding namespace separator.
|
||||
* @param bool $prependSeparator
|
||||
* Whether to call ->loadClass() with a class name with preceding
|
||||
* namespace separator, as it happens in PHP 5.3.0 - 5.3.2.
|
||||
* See https://bugs.php.net/50731
|
||||
*/
|
||||
public function testLoadClass($class, $prependSeparator = FALSE)
|
||||
{
|
||||
$loader = new ClassLoader();
|
||||
$loader->add('Namespaced\\', __DIR__ . '/Fixtures');
|
||||
$loader->add('Pearlike_', __DIR__ . '/Fixtures');
|
||||
$loader->addPsr4('ShinyVendor\\ShinyPackage\\', __DIR__ . '/Fixtures');
|
||||
|
||||
if ($prependSeparator) {
|
||||
$prepend = '\\';
|
||||
$message = "->loadClass() loads '$class'.";
|
||||
}
|
||||
else {
|
||||
$prepend = '';
|
||||
$message = "->loadClass() loads '\\$class', as required in PHP 5.3.0 - 5.3.2.";
|
||||
}
|
||||
|
||||
$loader->loadClass($prepend . $class);
|
||||
$this->assertTrue(class_exists($class, false), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides arguments for ->testLoadClass().
|
||||
*
|
||||
* @return array
|
||||
* Array of parameter sets to test with.
|
||||
*/
|
||||
public function getLoadClassTests()
|
||||
{
|
||||
return array(
|
||||
array('Namespaced\\Foo'),
|
||||
array('Pearlike_Foo'),
|
||||
array('ShinyVendor\\ShinyPackage\\SubNamespace\\Foo'),
|
||||
// "Bar" would not work here, since it is defined in a ".inc" file,
|
||||
// instead of a ".php" file. So, use "Baz" instead.
|
||||
array('Namespaced\\Baz', '\\'),
|
||||
array('Pearlike_Bar', '\\'),
|
||||
array('ShinyVendor\\ShinyPackage\\SubNamespace\\Bar', '\\'),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace ShinyVendor\ShinyPackage\SubNamespace;
|
||||
|
||||
class Bar {}
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace ShinyVendor\ShinyPackage\SubNamespace;
|
||||
|
||||
class Foo {}
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Acme\\Fruit\\' => array($baseDir . '/src-fruit'),
|
||||
'Acme\\Cake\\' => array($baseDir . '/src-cake', $baseDir . '/lib-cake'),
|
||||
);
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname(dirname($vendorDir));
|
||||
|
||||
return array(
|
||||
'Acme\\Fruit\\' => array($baseDir . '/src-fruit'),
|
||||
'Acme\\Cake\\' => array($baseDir . '/src-cake', $baseDir . '/lib-cake'),
|
||||
);
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = $vendorDir;
|
||||
|
||||
return array(
|
||||
'Acme\\Fruit\\' => array($vendorDir . '/src-fruit'),
|
||||
'Acme\\Cake\\' => array($vendorDir . '/src-cake', $vendorDir . '/lib-cake'),
|
||||
);
|
|
@ -31,6 +31,11 @@ class ComposerAutoloaderInitFilesAutoloadOrder
|
|||
$loader->set($namespace, $path);
|
||||
}
|
||||
|
||||
$map = require __DIR__ . '/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->setPsr4($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
|
|
|
@ -31,6 +31,11 @@ class ComposerAutoloaderInitFilesAutoload
|
|||
$loader->set($namespace, $path);
|
||||
}
|
||||
|
||||
$map = require __DIR__ . '/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->setPsr4($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
|
|
|
@ -31,6 +31,11 @@ class ComposerAutoloaderInitIncludePath
|
|||
$loader->set($namespace, $path);
|
||||
}
|
||||
|
||||
$map = require __DIR__ . '/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->setPsr4($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
|
|
|
@ -31,6 +31,11 @@ class ComposerAutoloaderInitTargetDir
|
|||
$loader->set($namespace, $path);
|
||||
}
|
||||
|
||||
$map = require __DIR__ . '/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->setPsr4($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
|
|
|
@ -253,7 +253,7 @@ class ValidatingArrayLoaderTest extends \PHPUnit_Framework_TestCase
|
|||
),
|
||||
),
|
||||
array(
|
||||
'autoload : invalid value (psr0), must be one of psr-0, classmap, files'
|
||||
'autoload : invalid value (psr0), must be one of psr-0, psr-4, classmap, files'
|
||||
)
|
||||
),
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue