Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4b22d75

Browse files
committed
Merge remote-tracking branch 'schmunk42/feature-create-project-events'
2 parents 93d3783 + dac2f03 commit 4b22d75

5 files changed

Lines changed: 122 additions & 65 deletions

File tree

doc/03-cli.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,9 @@ If the directory does not currently exist, it will be created during installatio
317317

318318
php composer.phar create-project doctrine/orm path 2.2.0
319319

320+
It is also possible to run the command without params in a directory with an
321+
existing `composer.json` file to bootstrap a project.
322+
320323
By default the command checks for the packages on packagist.org.
321324

322325
### Options

doc/articles/scripts.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ Composer fires the following named events during its execution process:
3434
during `install`/`update`, or via the `dump-autoload` command.
3535
- **post-autoload-dump**: occurs after the autoloader is dumped, either
3636
during `install`/`update`, or via the `dump-autoload` command.
37-
37+
- **post-root-package-install**: occurs after the root package has been
38+
installed, during the `create-project` command.
39+
- **post-create-project-cmd**: occurs after the `create-project` command is
40+
executed.
3841

3942
## Defining scripts
4043

res/composer-schema.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,14 @@
290290
"post-autoload-dump": {
291291
"type": ["array", "string"],
292292
"description": "Occurs after the autoloader is dumped, contains one or more Class::method callables or shell commands."
293+
},
294+
"post-root-package-install": {
295+
"type": ["array", "string"],
296+
"description": "Occurs after the root-package is installed, contains one or more Class::method callables or shell commands."
297+
},
298+
"post-create-project-cmd": {
299+
"type": ["array", "string"],
300+
"description": "Occurs after the create-project command is executed, contains one or more Class::method callables or shell commands."
293301
}
294302
}
295303
},

src/Composer/Command/CreateProjectCommand.php

Lines changed: 87 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use Composer\Repository\CompositeRepository;
2727
use Composer\Repository\FilesystemRepository;
2828
use Composer\Repository\InstalledFilesystemRepository;
29+
use Composer\Script\ScriptEvents;
2930
use Symfony\Component\Console\Input\InputArgument;
3031
use Symfony\Component\Console\Input\InputInterface;
3132
use Symfony\Component\Console\Input\InputOption;
@@ -42,6 +43,7 @@
4243
*
4344
* @author Benjamin Eberlei <[email protected]>
4445
* @author Jordi Boggiano <[email protected]>
46+
* @author Tobias Munk <[email protected]>
4547
*/
4648
class CreateProjectCommand extends Command
4749
{
@@ -51,7 +53,7 @@ protected function configure()
5153
->setName('create-project')
5254
->setDescription('Create new project from a package into given directory.')
5355
->setDefinition(array(
54-
new InputArgument('package', InputArgument::REQUIRED, 'Package name to be installed'),
56+
new InputArgument('package', InputArgument::OPTIONAL, 'Package name to be installed'),
5557
new InputArgument('directory', InputArgument::OPTIONAL, 'Directory where the files should be created'),
5658
new InputArgument('version', InputArgument::OPTIONAL, 'Version, will defaults to latest'),
5759
new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum-stability allowed (unless a version is specified).', 'stable'),
@@ -66,9 +68,11 @@ protected function configure()
6668
))
6769
->setHelp(<<<EOT
6870
The <info>create-project</info> command creates a new project from a given
69-
package into a new directory. You can use this command to bootstrap new
70-
projects or setup a clean version-controlled installation
71-
for developers of your project.
71+
package into a new directory. If executed without params and in a directory
72+
with a composer.json file it installs the packages for the current project.
73+
74+
You can use this command to bootstrap new projects or setup a clean
75+
version-controlled installation for developers of your project.
7276
7377
<info>php composer.phar create-project vendor/project target-directory [version]</info>
7478
@@ -133,6 +137,84 @@ protected function execute(InputInterface $input, OutputInterface $output)
133137

134138
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)
135139
{
140+
if ($packageName !== null) {
141+
$installedFromVcs = $this->installRootPackage($io, $config, $packageName, $directory, $packageVersion, $stability, $preferSource, $preferDist, $installDevPackages, $repositoryUrl, $disableCustomInstallers, $noScripts, $keepVcs, $noProgress);
142+
} else {
143+
$installedFromVcs = false;
144+
}
145+
146+
if ($noScripts === false) {
147+
// dispatch event
148+
$this->getComposer()->getEventDispatcher()->dispatchCommandEvent(ScriptEvents::POST_ROOT_PACKAGE_INSTALL, $installDevPackages);
149+
}
150+
// install dependencies of the created project
151+
$composer = Factory::create($io);
152+
$installer = Installer::create($io, $composer);
153+
154+
$installer->setPreferSource($preferSource)
155+
->setPreferDist($preferDist)
156+
->setDevMode($installDevPackages)
157+
->setRunScripts( ! $noScripts);
158+
159+
if ($disableCustomInstallers) {
160+
$installer->disableCustomInstallers();
161+
}
162+
163+
if (!$installer->run()) {
164+
return 1;
165+
}
166+
167+
if ($noScripts === false) {
168+
// dispatch event
169+
$this->getComposer()->getEventDispatcher()->dispatchCommandEvent(ScriptEvents::POST_CREATE_PROJECT_CMD, $installDevPackages);
170+
}
171+
172+
$hasVcs = $installedFromVcs;
173+
if (!$keepVcs && $installedFromVcs
174+
&& (
175+
!$io->isInteractive()
176+
|| $io->askConfirmation('<info>Do you want to remove the existing VCS (.git, .svn..) history?</info> [<comment>Y,n</comment>]? ', true)
177+
)
178+
) {
179+
$finder = new Finder();
180+
$finder->depth(0)->directories()->in(getcwd())->ignoreVCS(false)->ignoreDotFiles(false);
181+
foreach (array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg') as $vcsName) {
182+
$finder->name($vcsName);
183+
}
184+
185+
try {
186+
$fs = new Filesystem();
187+
$dirs = iterator_to_array($finder);
188+
unset($finder);
189+
foreach ($dirs as $dir) {
190+
if (!$fs->removeDirectory($dir)) {
191+
throw new \RuntimeException('Could not remove '.$dir);
192+
}
193+
}
194+
} catch (\Exception $e) {
195+
$io->write('<error>An error occurred while removing the VCS metadata: '.$e->getMessage().'</error>');
196+
}
197+
198+
$hasVcs = false;
199+
}
200+
201+
// rewriting self.version dependencies with explicit version numbers if the package's vcs metadata is gone
202+
if (!$hasVcs) {
203+
$package = $composer->getPackage();
204+
$configSource = new JsonConfigSource(new JsonFile('composer.json'));
205+
foreach (BasePackage::$supportedLinkTypes as $type => $meta) {
206+
foreach ($package->{'get'.$meta['method']}() as $link) {
207+
if ($link->getPrettyConstraint() === 'self.version') {
208+
$configSource->addLink($type, $link->getTarget(), $package->getPrettyVersion());
209+
}
210+
}
211+
}
212+
}
213+
214+
return 0;
215+
}
216+
217+
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) {
136218
$stability = strtolower($stability);
137219
if ($stability === 'rc') {
138220
$stability = 'RC';
@@ -219,66 +301,7 @@ public function installProject(IOInterface $io, $config, $packageName, $director
219301
// clean up memory
220302
unset($dm, $im, $config, $projectInstaller, $sourceRepo, $package);
221303

222-
// install dependencies of the created project
223-
$composer = Factory::create($io);
224-
$installer = Installer::create($io, $composer);
225-
226-
$installer->setPreferSource($preferSource)
227-
->setPreferDist($preferDist)
228-
->setDevMode($installDevPackages)
229-
->setRunScripts( ! $noScripts);
230-
231-
if ($disableCustomInstallers) {
232-
$installer->disableCustomInstallers();
233-
}
234-
235-
if (!$installer->run()) {
236-
return 1;
237-
}
238-
239-
$hasVcs = $installedFromVcs;
240-
if (!$keepVcs && $installedFromVcs
241-
&& (
242-
!$io->isInteractive()
243-
|| $io->askConfirmation('<info>Do you want to remove the existing VCS (.git, .svn..) history?</info> [<comment>Y,n</comment>]? ', true)
244-
)
245-
) {
246-
$finder = new Finder();
247-
$finder->depth(0)->directories()->in(getcwd())->ignoreVCS(false)->ignoreDotFiles(false);
248-
foreach (array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg') as $vcsName) {
249-
$finder->name($vcsName);
250-
}
251-
252-
try {
253-
$fs = new Filesystem();
254-
$dirs = iterator_to_array($finder);
255-
unset($finder);
256-
foreach ($dirs as $dir) {
257-
if (!$fs->removeDirectory($dir)) {
258-
throw new \RuntimeException('Could not remove '.$dir);
259-
}
260-
}
261-
} catch (\Exception $e) {
262-
$io->write('<error>An error occurred while removing the VCS metadata: '.$e->getMessage().'</error>');
263-
}
264-
265-
$hasVcs = false;
266-
}
267-
268-
// rewriting self.version dependencies with explicit version numbers if the package's vcs metadata is gone
269-
if (!$hasVcs) {
270-
$package = $composer->getPackage();
271-
$configSource = new JsonConfigSource(new JsonFile('composer.json'));
272-
foreach (BasePackage::$supportedLinkTypes as $type => $meta) {
273-
foreach ($package->{'get'.$meta['method']}() as $link) {
274-
if ($link->getPrettyConstraint() === 'self.version') {
275-
$configSource->addLink($type, $link->getTarget(), $package->getPrettyVersion());
276-
}
277-
}
278-
}
279-
}
280-
281-
return 0;
304+
return $installedFromVcs;
282305
}
283306

284307
protected function createDownloadManager(IOInterface $io, Config $config)

src/Composer/Script/ScriptEvents.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,24 @@ class ScriptEvents
127127
* @var string
128128
*/
129129
const POST_AUTOLOAD_DUMP = 'post-autoload-dump';
130+
131+
/**
132+
* The POST_ROOT_PACKAGE_INSTALL event occurs after the root package has been installed.
133+
*
134+
* The event listener method receives a Composer\Script\PackageEvent instance.
135+
*
136+
* @var string
137+
*/
138+
const POST_ROOT_PACKAGE_INSTALL = 'post-root-package-install';
139+
140+
/**
141+
* The POST_CREATE_PROJECT event occurs after the create-project command has been executed.
142+
* Note: Event occurs after POST_INSTALL_CMD
143+
*
144+
* The event listener method receives a Composer\Script\PackageEvent instance.
145+
*
146+
* @var string
147+
*/
148+
const POST_CREATE_PROJECT_CMD = 'post-create-project-cmd';
149+
130150
}

0 commit comments

Comments
 (0)