2012-03-31 22:39:43 +00:00
< ? php
/*
* This file is part of Composer .
*
* ( c ) Nils Adermann < naderman @ naderman . de >
* Jordi Boggiano < j . boggiano @ seld . be >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Composer\Command ;
use Symfony\Component\Console\Input\InputInterface ;
use Symfony\Component\Console\Input\InputArgument ;
use Symfony\Component\Console\Input\InputOption ;
use Symfony\Component\Console\Output\OutputInterface ;
2012-05-26 12:45:19 +00:00
use Composer\Factory ;
2012-05-26 13:17:52 +00:00
use Composer\Installer ;
2012-03-31 22:39:43 +00:00
use Composer\Json\JsonFile ;
2012-05-26 12:45:19 +00:00
use Composer\Json\JsonManipulator ;
2012-03-31 22:39:43 +00:00
/**
* @ author Jérémy Romey < jeremy @ free - agent . fr >
2012-05-26 12:45:19 +00:00
* @ author Jordi Boggiano < j . boggiano @ seld . be >
2012-03-31 22:39:43 +00:00
*/
class RequireCommand extends InitCommand
{
protected function configure ()
{
$this
-> setName ( 'require' )
2012-05-26 13:17:52 +00:00
-> setDescription ( 'Adds required packages to your composer.json and installs them' )
2012-03-31 22:39:43 +00:00
-> setDefinition ( array (
2012-05-26 12:45:19 +00:00
new InputArgument ( 'packages' , InputArgument :: IS_ARRAY | InputArgument :: OPTIONAL , 'Required package with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"' ),
new InputOption ( 'dev' , null , InputOption :: VALUE_NONE , 'Add requirement to require-dev.' ),
2012-05-26 13:17:52 +00:00
new InputOption ( 'prefer-source' , null , InputOption :: VALUE_NONE , 'Forces installation from package sources when possible, including VCS information.' ),
2012-10-02 11:42:07 +00:00
new InputOption ( 'prefer-dist' , null , InputOption :: VALUE_NONE , 'Forces installation from package dist even for dev versions.' ),
2012-12-11 14:30:09 +00:00
new InputOption ( 'no-progress' , null , InputOption :: VALUE_NONE , 'Do not output download progress.' ),
2012-07-19 15:17:08 +00:00
new InputOption ( 'no-update' , null , InputOption :: VALUE_NONE , 'Disables the automatic update of the dependencies.' ),
2012-03-31 22:39:43 +00:00
))
-> setHelp ( <<< EOT
2012-05-26 13:17:52 +00:00
The require command adds required packages to your composer . json and installs them
2012-03-31 22:39:43 +00:00
2012-07-19 15:17:08 +00:00
If you do not want to install the new dependencies immediately you can call it with -- no - update
2012-03-31 22:39:43 +00:00
EOT
)
;
}
protected function execute ( InputInterface $input , OutputInterface $output )
{
2012-12-03 00:24:39 +00:00
$file = Factory :: getComposerFile ();
2012-03-31 22:39:43 +00:00
2013-01-13 14:57:03 +00:00
if ( ! file_exists ( $file ) && ! file_put_contents ( $file , " { } \n " )) {
$output -> writeln ( '<error>' . $file . ' could not be created.</error>' );
2012-05-28 14:38:52 +00:00
2012-03-31 22:39:43 +00:00
return 1 ;
}
if ( ! is_readable ( $file )) {
$output -> writeln ( '<error>' . $file . ' is not readable.</error>' );
2012-05-28 14:38:52 +00:00
2012-03-31 22:39:43 +00:00
return 1 ;
}
$dialog = $this -> getHelperSet () -> get ( 'dialog' );
2012-05-26 12:45:19 +00:00
$json = new JsonFile ( $file );
$composer = $json -> read ();
2012-03-31 22:39:43 +00:00
2012-05-26 12:45:19 +00:00
$requirements = $this -> determineRequirements ( $input , $output , $input -> getArgument ( 'packages' ));
2012-03-31 22:39:43 +00:00
2012-05-26 12:45:19 +00:00
$requireKey = $input -> getOption ( 'dev' ) ? 'require-dev' : 'require' ;
$baseRequirements = array_key_exists ( $requireKey , $composer ) ? $composer [ $requireKey ] : array ();
2012-05-27 21:21:10 +00:00
$requirements = $this -> formatRequirements ( $requirements );
2012-03-31 22:39:43 +00:00
2012-05-26 12:45:19 +00:00
if ( ! $this -> updateFileCleanly ( $json , $baseRequirements , $requirements , $requireKey )) {
foreach ( $requirements as $package => $version ) {
2012-03-31 22:39:43 +00:00
$baseRequirements [ $package ] = $version ;
}
2012-05-26 12:45:19 +00:00
$composer [ $requireKey ] = $baseRequirements ;
$json -> write ( $composer );
2012-03-31 22:39:43 +00:00
}
2012-05-26 12:45:19 +00:00
$output -> writeln ( '<info>' . $file . ' has been updated</info>' );
2012-05-26 13:17:52 +00:00
2012-07-19 15:17:08 +00:00
if ( $input -> getOption ( 'no-update' )) {
return 0 ;
}
2012-05-26 13:17:52 +00:00
// Update packages
$composer = $this -> getComposer ();
2012-12-11 14:30:09 +00:00
$composer -> getDownloadManager () -> setOutputProgress ( ! $input -> getOption ( 'no-progress' ));
2012-05-26 13:17:52 +00:00
$io = $this -> getIO ();
$install = Installer :: create ( $io , $composer );
$install
-> setVerbose ( $input -> getOption ( 'verbose' ))
-> setPreferSource ( $input -> getOption ( 'prefer-source' ))
2012-10-02 11:42:07 +00:00
-> setPreferDist ( $input -> getOption ( 'prefer-dist' ))
2012-05-26 13:17:52 +00:00
-> setDevMode ( $input -> getOption ( 'dev' ))
-> setUpdate ( true )
-> setUpdateWhitelist ( $requirements );
;
return $install -> run () ? 0 : 1 ;
2012-05-26 12:45:19 +00:00
}
private function updateFileCleanly ( $json , array $base , array $new , $requireKey )
{
$contents = file_get_contents ( $json -> getPath ());
2012-03-31 22:39:43 +00:00
2012-05-26 12:45:19 +00:00
$manipulator = new JsonManipulator ( $contents );
2012-03-31 22:39:43 +00:00
2012-05-26 12:45:19 +00:00
foreach ( $new as $package => $constraint ) {
if ( ! $manipulator -> addLink ( $requireKey , $package , $constraint )) {
return false ;
}
}
file_put_contents ( $json -> getPath (), $manipulator -> getContents ());
return true ;
2012-03-31 22:39:43 +00:00
}
protected function interact ( InputInterface $input , OutputInterface $output )
{
return ;
}
}