Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added an autoload-dev section #1344

Merged
merged 1 commit into from Mar 1, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions composer.json
Expand Up @@ -39,6 +39,9 @@
"autoload": {
"psr-0": { "Composer": "src/" }
},
"autoload-dev": {
"psr-0": { "Composer\\Test": "tests/" }
},
"bin": ["bin/composer"],
"extra": {
"branch-alias": {
Expand Down
21 changes: 21 additions & 0 deletions doc/04-schema.md
Expand Up @@ -516,6 +516,27 @@ Example:
}
}

### autoload-dev <span>(root-only)</span>

This section allows to define autoload rules for development purpose.

If you're generating classmaps from your PSR-0 namespaces, you're probably concerned
about performance, if so, you'll also don't want your test classes to be mixed up
with your regular classes in those classmaps.

Therefore, it is a good idea to rely on a dedicated path for your unit tests.

Example:

{
"autoload": {
"psr-0": { "MyLibrary": "src/" }
},
"autoload-dev": {
"psr-0": { "MyLibrary\\Tests": "tests/" }
}
}

### include-path

> **DEPRECATED**: This is only present to support legacy projects, and all new code
Expand Down
24 changes: 24 additions & 0 deletions res/composer-schema.json
Expand Up @@ -226,6 +226,30 @@
}
}
},
"autoload-dev": {
"type": "object",
"description": "Description of additional autoload rules for development purpose (eg. a test suite).",
"properties": {
"psr-0": {
"type": "object",
"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 map to (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."
},
"files": {
"type": "array",
"description": "This is an array of files that are always required on every request."
}
}
},
"archive": {
"type": ["object"],
"description": "Options for creating package archives for distribution.",
Expand Down
10 changes: 10 additions & 0 deletions src/Composer/Autoload/AutoloadGenerator.php
Expand Up @@ -32,11 +32,18 @@ class AutoloadGenerator
*/
private $eventDispatcher;

private $devMode = false;

public function __construct(EventDispatcher $eventDispatcher)
{
$this->eventDispatcher = $eventDispatcher;
}

public function setDevMode($devMode = true)
{
$this->devMode = (boolean) $devMode;
}

public function dump(Config $config, InstalledRepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir, $scanPsr0Packages = false, $suffix = '')
{
$this->eventDispatcher->dispatchScript(ScriptEvents::PRE_AUTOLOAD_DUMP);
Expand Down Expand Up @@ -569,6 +576,9 @@ protected function parseAutoloadsType(array $packageMap, $type, PackageInterface
list($package, $installPath) = $item;

$autoload = $package->getAutoload();
if ($this->devMode && $package === $mainPackage) {
$autoload = array_merge_recursive($autoload, $package->getDevAutoload());
}

// skip misconfigured packages
if (!isset($autoload[$type]) || !is_array($autoload[$type])) {
Expand Down
5 changes: 4 additions & 1 deletion src/Composer/Command/DumpAutoloadCommand.php
Expand Up @@ -31,6 +31,7 @@ protected function configure()
->setDescription('Dumps the autoloader')
->setDefinition(array(
new InputOption('optimize', 'o', InputOption::VALUE_NONE, 'Optimizes PSR0 packages to be loaded with classmaps too, good for production.'),
new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables dev autoload.'),
))
->setHelp(<<<EOT
<info>php composer.phar dump-autoload</info>
Expand Down Expand Up @@ -59,6 +60,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
$output->writeln('<info>Generating autoload files</info>');
}

$composer->getAutoloadGenerator()->dump($config, $localRepo, $package, $installationManager, 'composer', $optimize);
$generator = $composer->getAutoloadGenerator();
$generator->setDevMode($input->getOption('dev'));
$generator->dump($config, $localRepo, $package, $installationManager, 'composer', $optimize);
}
}
1 change: 1 addition & 0 deletions src/Composer/Installer.php
Expand Up @@ -290,6 +290,7 @@ public function run()
$this->io->write('<info>Generating autoload files</info>');
}

$this->autoloadGenerator->setDevMode($this->devMode);
$this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader);

if ($this->runScripts) {
Expand Down
4 changes: 4 additions & 0 deletions src/Composer/Package/AliasPackage.php
Expand Up @@ -245,6 +245,10 @@ public function getAutoload()
{
return $this->aliasOf->getAutoload();
}
public function getDevAutoload()
{
return $this->aliasOf->getDevAutoload();
}
public function getIncludePaths()
{
return $this->aliasOf->getIncludePaths();
Expand Down
1 change: 1 addition & 0 deletions src/Composer/Package/Dumper/ArrayDumper.php
Expand Up @@ -31,6 +31,7 @@ public function dump(PackageInterface $package)
'extra',
'installationSource' => 'installation-source',
'autoload',
'devAutoload' => 'autoload-dev',
'notificationUrl' => 'notification-url',
'includePaths' => 'include-path',
);
Expand Down
4 changes: 4 additions & 0 deletions src/Composer/Package/Loader/ArrayLoader.php
Expand Up @@ -130,6 +130,10 @@ public function load(array $config, $class = 'Composer\Package\CompletePackage')
$package->setAutoload($config['autoload']);
}

if (isset($config['autoload-dev'])) {
$package->setDevAutoload($config['autoload-dev']);
}

if (isset($config['include-path'])) {
$package->setIncludePaths($config['include-path']);
}
Expand Down
19 changes: 19 additions & 0 deletions src/Composer/Package/Package.php
Expand Up @@ -47,6 +47,7 @@ class Package extends BasePackage
protected $devRequires = array();
protected $suggests = array();
protected $autoload = array();
protected $devAutoload = array();
protected $includePaths = array();
protected $archiveExcludes = array();

Expand Down Expand Up @@ -440,6 +441,24 @@ public function getAutoload()
return $this->autoload;
}

/**
* Set the dev autoload mapping
*
* @param array $autoload Mapping of dev autoloading rules
*/
public function setDevAutoload(array $devAutoload)
{
$this->devAutoload = $devAutoload;
}

/**
* {@inheritDoc}
*/
public function getDevAutoload()
{
return $this->devAutoload;
}

/**
* Sets the list of paths added to PHP's include path.
*
Expand Down
16 changes: 14 additions & 2 deletions src/Composer/Package/PackageInterface.php
Expand Up @@ -231,13 +231,25 @@ public function getSuggests();
*
* {"<type>": {"<namespace": "<directory>"}}
*
* Type is either "psr-0" or "pear". Namespaces are mapped to directories
* for autoloading using the type specified.
* Type is either "psr-4", "psr-0", "classmap" or "files". Namespaces are mapped to
* directories for autoloading using the type specified.
*
* @return array Mapping of autoloading rules
*/
public function getAutoload();

/**
* Returns an associative array of dev autoloading rules
*
* {"<type>": {"<namespace": "<directory>"}}
*
* Type is either "psr-4", "psr-0", "classmap" or "files". Namespaces are mapped to
* directories for autoloading using the type specified.
*
* @return array Mapping of dev autoloading rules
*/
public function getDevAutoload();

/**
* Returns a list of directories which should get added to PHP's
* include path.
Expand Down
68 changes: 68 additions & 0 deletions tests/Composer/Test/Autoload/AutoloadGeneratorTest.php
Expand Up @@ -170,7 +170,75 @@ public function testMainPackageAutoloading()
// Assert that autoload_classmap.php was correctly generated.
$this->assertAutoloadFiles('classmap', $this->vendorDir.'/composer', 'classmap');
}

public function testMainPackageDevAutoloading()
{
$package = new Package('a', '1.0', '1.0');
$package->setAutoload(array(
'psr-0' => array(
'Main' => 'src/',
),
));
$package->setDevAutoload(array(
'files' => array('devfiles/foo.php'),
));

$this->repository->expects($this->once())
->method('getCanonicalPackages')
->will($this->returnValue(array()));

$this->fs->ensureDirectoryExists($this->workingDir.'/composer');
$this->fs->ensureDirectoryExists($this->workingDir.'/src/Main');
file_put_contents($this->workingDir.'/src/Main/ClassMain.php', '<?php namespace Main; class ClassMain {}');

$this->fs->ensureDirectoryExists($this->workingDir.'/devfiles');
file_put_contents($this->workingDir.'/devfiles/foo.php', '<?php function foo() { echo "foo"; }');

// generate autoload files with the dev mode set to true
$this->generator->setDevMode(true);
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', true, '_1');

// check standard autoload
$this->assertAutoloadFiles('main4', $this->vendorDir.'/composer');
$this->assertAutoloadFiles('classmap7', $this->vendorDir.'/composer', 'classmap');

// make sure dev autoload is correctly dumped
$this->assertAutoloadFiles('files2', $this->vendorDir.'/composer', 'files');
}

public function testMainPackageDevAutoloadingDisabledByDefault()
{
$package = new Package('a', '1.0', '1.0');
$package->setAutoload(array(
'psr-0' => array(
'Main' => 'src/',
),
));
$package->setDevAutoload(array(
'files' => array('devfiles/foo.php'),
));

$this->repository->expects($this->once())
->method('getCanonicalPackages')
->will($this->returnValue(array()));

$this->fs->ensureDirectoryExists($this->workingDir.'/composer');
$this->fs->ensureDirectoryExists($this->workingDir.'/src/Main');
file_put_contents($this->workingDir.'/src/Main/ClassMain.php', '<?php namespace Main; class ClassMain {}');

$this->fs->ensureDirectoryExists($this->workingDir.'/devfiles');
file_put_contents($this->workingDir.'/devfiles/foo.php', '<?php function foo() { echo "foo"; }');

$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', true, '_1');

// check standard autoload
$this->assertAutoloadFiles('main4', $this->vendorDir.'/composer');
$this->assertAutoloadFiles('classmap7', $this->vendorDir.'/composer', 'classmap');

// make sure dev autoload is disabled when dev mode is set to false
$this->assertFalse(is_file($this->vendorDir.'/composer/autoload_files.php'));
}

public function testVendorDirSameAsWorkingDir()
{
$this->vendorDir = $this->workingDir;
Expand Down
10 changes: 10 additions & 0 deletions tests/Composer/Test/Autoload/Fixtures/autoload_classmap7.php
@@ -0,0 +1,10 @@
<?php

// autoload_classmap.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
'Main\\ClassMain' => $baseDir . '/src/Main/ClassMain.php',
);
10 changes: 10 additions & 0 deletions tests/Composer/Test/Autoload/Fixtures/autoload_files2.php
@@ -0,0 +1,10 @@
<?php

// autoload_files.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
$baseDir . '/devfiles/foo.php',
);
10 changes: 10 additions & 0 deletions tests/Composer/Test/Autoload/Fixtures/autoload_main4.php
@@ -0,0 +1,10 @@
<?php

// autoload_namespaces.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
'Main' => array($baseDir . '/src'),
);
2 changes: 2 additions & 0 deletions tests/bootstrap.php
Expand Up @@ -13,6 +13,8 @@
error_reporting(E_ALL);

$loader = require __DIR__.'/../src/bootstrap.php';

// to be removed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

$loader->add('Composer\Test', __DIR__);

require __DIR__.'/Composer/TestCase.php';