Merge remote-tracking branch 'schmunk42/feature-create-project-events'
commit
4b22d7582a
|
@ -317,6 +317,9 @@ If the directory does not currently exist, it will be created during installatio
|
||||||
|
|
||||||
php composer.phar create-project doctrine/orm path 2.2.0
|
php composer.phar create-project doctrine/orm path 2.2.0
|
||||||
|
|
||||||
|
It is also possible to run the command without params in a directory with an
|
||||||
|
existing `composer.json` file to bootstrap a project.
|
||||||
|
|
||||||
By default the command checks for the packages on packagist.org.
|
By default the command checks for the packages on packagist.org.
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
|
@ -34,7 +34,10 @@ Composer fires the following named events during its execution process:
|
||||||
during `install`/`update`, or via the `dump-autoload` command.
|
during `install`/`update`, or via the `dump-autoload` command.
|
||||||
- **post-autoload-dump**: occurs after the autoloader is dumped, either
|
- **post-autoload-dump**: occurs after the autoloader is dumped, either
|
||||||
during `install`/`update`, or via the `dump-autoload` command.
|
during `install`/`update`, or via the `dump-autoload` command.
|
||||||
|
- **post-root-package-install**: occurs after the root package has been
|
||||||
|
installed, during the `create-project` command.
|
||||||
|
- **post-create-project-cmd**: occurs after the `create-project` command is
|
||||||
|
executed.
|
||||||
|
|
||||||
## Defining scripts
|
## Defining scripts
|
||||||
|
|
||||||
|
|
|
@ -290,6 +290,14 @@
|
||||||
"post-autoload-dump": {
|
"post-autoload-dump": {
|
||||||
"type": ["array", "string"],
|
"type": ["array", "string"],
|
||||||
"description": "Occurs after the autoloader is dumped, contains one or more Class::method callables or shell commands."
|
"description": "Occurs after the autoloader is dumped, contains one or more Class::method callables or shell commands."
|
||||||
|
},
|
||||||
|
"post-root-package-install": {
|
||||||
|
"type": ["array", "string"],
|
||||||
|
"description": "Occurs after the root-package is installed, contains one or more Class::method callables or shell commands."
|
||||||
|
},
|
||||||
|
"post-create-project-cmd": {
|
||||||
|
"type": ["array", "string"],
|
||||||
|
"description": "Occurs after the create-project command is executed, contains one or more Class::method callables or shell commands."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -26,6 +26,7 @@ use Composer\Repository\ComposerRepository;
|
||||||
use Composer\Repository\CompositeRepository;
|
use Composer\Repository\CompositeRepository;
|
||||||
use Composer\Repository\FilesystemRepository;
|
use Composer\Repository\FilesystemRepository;
|
||||||
use Composer\Repository\InstalledFilesystemRepository;
|
use Composer\Repository\InstalledFilesystemRepository;
|
||||||
|
use Composer\Script\ScriptEvents;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
@ -42,6 +43,7 @@ use Composer\Package\Version\VersionParser;
|
||||||
*
|
*
|
||||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
* @author Tobias Munk <schmunk@usrbin.de>
|
||||||
*/
|
*/
|
||||||
class CreateProjectCommand extends Command
|
class CreateProjectCommand extends Command
|
||||||
{
|
{
|
||||||
|
@ -51,7 +53,7 @@ class CreateProjectCommand extends Command
|
||||||
->setName('create-project')
|
->setName('create-project')
|
||||||
->setDescription('Create new project from a package into given directory.')
|
->setDescription('Create new project from a package into given directory.')
|
||||||
->setDefinition(array(
|
->setDefinition(array(
|
||||||
new InputArgument('package', InputArgument::REQUIRED, 'Package name to be installed'),
|
new InputArgument('package', InputArgument::OPTIONAL, 'Package name to be installed'),
|
||||||
new InputArgument('directory', InputArgument::OPTIONAL, 'Directory where the files should be created'),
|
new InputArgument('directory', InputArgument::OPTIONAL, 'Directory where the files should be created'),
|
||||||
new InputArgument('version', InputArgument::OPTIONAL, 'Version, will defaults to latest'),
|
new InputArgument('version', InputArgument::OPTIONAL, 'Version, will defaults to latest'),
|
||||||
new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum-stability allowed (unless a version is specified).', 'stable'),
|
new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum-stability allowed (unless a version is specified).', 'stable'),
|
||||||
|
@ -66,9 +68,11 @@ class CreateProjectCommand extends Command
|
||||||
))
|
))
|
||||||
->setHelp(<<<EOT
|
->setHelp(<<<EOT
|
||||||
The <info>create-project</info> command creates a new project from a given
|
The <info>create-project</info> command creates a new project from a given
|
||||||
package into a new directory. You can use this command to bootstrap new
|
package into a new directory. If executed without params and in a directory
|
||||||
projects or setup a clean version-controlled installation
|
with a composer.json file it installs the packages for the current project.
|
||||||
for developers of your project.
|
|
||||||
|
You can use this command to bootstrap new projects or setup a clean
|
||||||
|
version-controlled installation for developers of your project.
|
||||||
|
|
||||||
<info>php composer.phar create-project vendor/project target-directory [version]</info>
|
<info>php composer.phar create-project vendor/project target-directory [version]</info>
|
||||||
|
|
||||||
|
@ -133,6 +137,84 @@ EOT
|
||||||
|
|
||||||
public function installProject(IOInterface $io, $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositoryUrl = null, $disableCustomInstallers = false, $noScripts = false, $keepVcs = false, $noProgress = false)
|
public function installProject(IOInterface $io, $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositoryUrl = null, $disableCustomInstallers = false, $noScripts = false, $keepVcs = false, $noProgress = false)
|
||||||
{
|
{
|
||||||
|
if ($packageName !== null) {
|
||||||
|
$installedFromVcs = $this->installRootPackage($io, $config, $packageName, $directory, $packageVersion, $stability, $preferSource, $preferDist, $installDevPackages, $repositoryUrl, $disableCustomInstallers, $noScripts, $keepVcs, $noProgress);
|
||||||
|
} else {
|
||||||
|
$installedFromVcs = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($noScripts === false) {
|
||||||
|
// dispatch event
|
||||||
|
$this->getComposer()->getEventDispatcher()->dispatchCommandEvent(ScriptEvents::POST_ROOT_PACKAGE_INSTALL, $installDevPackages);
|
||||||
|
}
|
||||||
|
// install dependencies of the created project
|
||||||
|
$composer = Factory::create($io);
|
||||||
|
$installer = Installer::create($io, $composer);
|
||||||
|
|
||||||
|
$installer->setPreferSource($preferSource)
|
||||||
|
->setPreferDist($preferDist)
|
||||||
|
->setDevMode($installDevPackages)
|
||||||
|
->setRunScripts( ! $noScripts);
|
||||||
|
|
||||||
|
if ($disableCustomInstallers) {
|
||||||
|
$installer->disableCustomInstallers();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$installer->run()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($noScripts === false) {
|
||||||
|
// dispatch event
|
||||||
|
$this->getComposer()->getEventDispatcher()->dispatchCommandEvent(ScriptEvents::POST_CREATE_PROJECT_CMD, $installDevPackages);
|
||||||
|
}
|
||||||
|
|
||||||
|
$hasVcs = $installedFromVcs;
|
||||||
|
if (!$keepVcs && $installedFromVcs
|
||||||
|
&& (
|
||||||
|
!$io->isInteractive()
|
||||||
|
|| $io->askConfirmation('<info>Do you want to remove the existing VCS (.git, .svn..) history?</info> [<comment>Y,n</comment>]? ', true)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
$finder = new Finder();
|
||||||
|
$finder->depth(0)->directories()->in(getcwd())->ignoreVCS(false)->ignoreDotFiles(false);
|
||||||
|
foreach (array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg') as $vcsName) {
|
||||||
|
$finder->name($vcsName);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$fs = new Filesystem();
|
||||||
|
$dirs = iterator_to_array($finder);
|
||||||
|
unset($finder);
|
||||||
|
foreach ($dirs as $dir) {
|
||||||
|
if (!$fs->removeDirectory($dir)) {
|
||||||
|
throw new \RuntimeException('Could not remove '.$dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$io->write('<error>An error occurred while removing the VCS metadata: '.$e->getMessage().'</error>');
|
||||||
|
}
|
||||||
|
|
||||||
|
$hasVcs = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rewriting self.version dependencies with explicit version numbers if the package's vcs metadata is gone
|
||||||
|
if (!$hasVcs) {
|
||||||
|
$package = $composer->getPackage();
|
||||||
|
$configSource = new JsonConfigSource(new JsonFile('composer.json'));
|
||||||
|
foreach (BasePackage::$supportedLinkTypes as $type => $meta) {
|
||||||
|
foreach ($package->{'get'.$meta['method']}() as $link) {
|
||||||
|
if ($link->getPrettyConstraint() === 'self.version') {
|
||||||
|
$configSource->addLink($type, $link->getTarget(), $package->getPrettyVersion());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function installRootPackage(IOInterface $io, $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositoryUrl = null, $disableCustomInstallers = false, $noScripts = false, $keepVcs = false, $noProgress = false) {
|
||||||
$stability = strtolower($stability);
|
$stability = strtolower($stability);
|
||||||
if ($stability === 'rc') {
|
if ($stability === 'rc') {
|
||||||
$stability = 'RC';
|
$stability = 'RC';
|
||||||
|
@ -219,66 +301,7 @@ EOT
|
||||||
// clean up memory
|
// clean up memory
|
||||||
unset($dm, $im, $config, $projectInstaller, $sourceRepo, $package);
|
unset($dm, $im, $config, $projectInstaller, $sourceRepo, $package);
|
||||||
|
|
||||||
// install dependencies of the created project
|
return $installedFromVcs;
|
||||||
$composer = Factory::create($io);
|
|
||||||
$installer = Installer::create($io, $composer);
|
|
||||||
|
|
||||||
$installer->setPreferSource($preferSource)
|
|
||||||
->setPreferDist($preferDist)
|
|
||||||
->setDevMode($installDevPackages)
|
|
||||||
->setRunScripts( ! $noScripts);
|
|
||||||
|
|
||||||
if ($disableCustomInstallers) {
|
|
||||||
$installer->disableCustomInstallers();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$installer->run()) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$hasVcs = $installedFromVcs;
|
|
||||||
if (!$keepVcs && $installedFromVcs
|
|
||||||
&& (
|
|
||||||
!$io->isInteractive()
|
|
||||||
|| $io->askConfirmation('<info>Do you want to remove the existing VCS (.git, .svn..) history?</info> [<comment>Y,n</comment>]? ', true)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
$finder = new Finder();
|
|
||||||
$finder->depth(0)->directories()->in(getcwd())->ignoreVCS(false)->ignoreDotFiles(false);
|
|
||||||
foreach (array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg') as $vcsName) {
|
|
||||||
$finder->name($vcsName);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$fs = new Filesystem();
|
|
||||||
$dirs = iterator_to_array($finder);
|
|
||||||
unset($finder);
|
|
||||||
foreach ($dirs as $dir) {
|
|
||||||
if (!$fs->removeDirectory($dir)) {
|
|
||||||
throw new \RuntimeException('Could not remove '.$dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
$io->write('<error>An error occurred while removing the VCS metadata: '.$e->getMessage().'</error>');
|
|
||||||
}
|
|
||||||
|
|
||||||
$hasVcs = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rewriting self.version dependencies with explicit version numbers if the package's vcs metadata is gone
|
|
||||||
if (!$hasVcs) {
|
|
||||||
$package = $composer->getPackage();
|
|
||||||
$configSource = new JsonConfigSource(new JsonFile('composer.json'));
|
|
||||||
foreach (BasePackage::$supportedLinkTypes as $type => $meta) {
|
|
||||||
foreach ($package->{'get'.$meta['method']}() as $link) {
|
|
||||||
if ($link->getPrettyConstraint() === 'self.version') {
|
|
||||||
$configSource->addLink($type, $link->getTarget(), $package->getPrettyVersion());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createDownloadManager(IOInterface $io, Config $config)
|
protected function createDownloadManager(IOInterface $io, Config $config)
|
||||||
|
|
|
@ -127,4 +127,24 @@ class ScriptEvents
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
const POST_AUTOLOAD_DUMP = 'post-autoload-dump';
|
const POST_AUTOLOAD_DUMP = 'post-autoload-dump';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The POST_ROOT_PACKAGE_INSTALL event occurs after the root package has been installed.
|
||||||
|
*
|
||||||
|
* The event listener method receives a Composer\Script\PackageEvent instance.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const POST_ROOT_PACKAGE_INSTALL = 'post-root-package-install';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The POST_CREATE_PROJECT event occurs after the create-project command has been executed.
|
||||||
|
* Note: Event occurs after POST_INSTALL_CMD
|
||||||
|
*
|
||||||
|
* The event listener method receives a Composer\Script\PackageEvent instance.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const POST_CREATE_PROJECT_CMD = 'post-create-project-cmd';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue