├── .gitignore ├── sample └── composer.json ├── bin └── embedded-composer ├── composer.json ├── README.md ├── composer.lock └── src └── dflydev └── embedded └── composer └── console ├── command ├── ComposerInstallCommand.php └── ComposerUpdateCommand.php └── Application.php /.gitignore: -------------------------------------------------------------------------------- 1 | composer.phar 2 | sample/vendor 3 | sample/composer.lock 4 | vendor 5 | -------------------------------------------------------------------------------- /sample/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dflydev/embedded-composer-application-broken", 3 | "require": { 4 | "php": ">=5.3.2", 5 | "symfony/finder": "dev-master", 6 | "dflydev/embedded-composer-application": "dev-master", 7 | "dflydev/markdown": "dev-master" 8 | }, 9 | "repositories": [ 10 | { 11 | "type": "vcs", 12 | "url": "git://github.com/dflydev/dflydev-embedded-composer-application.git" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /bin/embedded-composer: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | run(); 24 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dflydev/embedded-composer-application", 3 | "type": "application", 4 | "description": "Embedded Composer Application", 5 | "homepage": "http://github.com/dflydev/dflydev-embedded-composer-application", 6 | "keywords": ["sample", "embedded", "composer", "application"], 7 | "license": "New BSD License", 8 | "authors": [ 9 | { 10 | "name": "Dragonfly Development Inc.", 11 | "email": "info@dflydev.com", 12 | "homepage": "http://dflydev.com" 13 | }, 14 | { 15 | "name": "Beau Simensen", 16 | "email": "beau@dflydev.com", 17 | "homepage": "http://beausimensen.com" 18 | } 19 | ], 20 | "require": { 21 | "php": ">=5.3.2", 22 | "composer/composer": "dev-master" 23 | }, 24 | "autoload": { 25 | "psr-0": { 26 | "dflydev\\embedded\\composer": "src" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Embedded Composer 2 | ================= 3 | 4 | Sample console application embedding [Composer](http://github.com/composer/composer) 5 | to manage its runtime dependencies. 6 | 7 | 8 | Usage 9 | ----- 10 | 11 | git clone git://github.com/dflydev/dflydev-embedded-composer-application.git 12 | cd dflydev-embedded-composer-application/ 13 | wget -nc http://getcomposer.org/composer.phar 14 | php composer.phar install 15 | cd sample 16 | ../bin/embedded-composer install 17 | 18 | This showcases the ability to have an embedded Composer install dependencies in 19 | a directory against the dependencies of the calling application. This would be 20 | useful in cases where a PHP application may be distrubted as a `.phar` but still 21 | need to be extended by plugins. 22 | 23 | 24 | License 25 | ------- 26 | 27 | This library is licensed under the New BSD License - see the LICENSE file for details. 28 | 29 | 30 | Community 31 | --------- 32 | 33 | If you have questions or want to help out, join us in the 34 | [#dflydev](irc://irc.freenode.net/#dflydev) channel on irc.freenode.net. 35 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "hash": "428bb91f5cf46c95efbf28dd72faf827", 3 | "packages": [ 4 | { 5 | "package": "composer/composer", 6 | "version": "dev-master", 7 | "source-reference": "48ae8bf3ec2dc282efab14cd2827bd6117de6afc" 8 | }, 9 | { 10 | "package": "justinrainbow/json-schema", 11 | "version": "1.1.0" 12 | }, 13 | { 14 | "package": "seld/jsonlint", 15 | "version": "1.0.0" 16 | }, 17 | { 18 | "package": "symfony/console", 19 | "version": "dev-master", 20 | "source-reference": "8e3c42aa976f18a9bfcb0694553e5f99def3309c", 21 | "alias": "2.1.9999999.9999999-dev" 22 | }, 23 | { 24 | "package": "symfony/finder", 25 | "version": "dev-master", 26 | "source-reference": "57ec7198a70e6c40e450ba66cc2f8ecab98746c8", 27 | "alias": "2.1.9999999.9999999-dev" 28 | }, 29 | { 30 | "package": "symfony/process", 31 | "version": "dev-master", 32 | "source-reference": "2e4da8c8076744bafed97451bb1574c96cda0e68", 33 | "alias": "2.1.9999999.9999999-dev" 34 | } 35 | ], 36 | "aliases": [] 37 | } 38 | -------------------------------------------------------------------------------- /src/dflydev/embedded/composer/console/command/ComposerInstallCommand.php: -------------------------------------------------------------------------------- 1 | getApplication()->getHelperSet()); 29 | $composer = Factory::create($io); 30 | $eventDispatcher = new EventDispatcher($composer, $io); 31 | if ($this->getApplication()->internallyInstalledRepositoryEnabled()) { 32 | $internalRepositoryFile = $this->getApplication()->internalVendorRoot().'/.composer/installed.json'; 33 | $filesystemRepository = new FilesystemRepository(new JsonFile($internalRepositoryFile)); 34 | $io->write('Including '.$internalRepositoryFile.' in installed repository, contains:'); 35 | foreach ($filesystemRepository->getPackages() as $package) { 36 | $io->write(' * '.$package->getName() . ':' . $package->getPrettyVersion()); 37 | } 38 | } else { 39 | $filesystemRepository = null; 40 | } 41 | 42 | $install = Installer::create($io, $composer); 43 | 44 | $install 45 | ->setDryRun($input->getOption('dry-run')) 46 | ->setVerbose($input->getOption('verbose')) 47 | ->setPreferSource($input->getOption('prefer-source')) 48 | ->setInstallRecommends(!$input->getOption('no-install-recommends')) 49 | ->setInstallSuggests($input->getOption('install-suggests')) 50 | ->setAdditionalInstalledRepository($filesystemRepository) 51 | ; 52 | 53 | return $install->run() ? 0 : 1; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/dflydev/embedded/composer/console/command/ComposerUpdateCommand.php: -------------------------------------------------------------------------------- 1 | getApplication()->find('install'); 29 | $io = new ConsoleIO($input, $output, $this->getApplication()->getHelperSet()); 30 | $composer = Factory::create($io); 31 | $eventDispatcher = new EventDispatcher($composer, $io); 32 | if ($this->getApplication()->internallyInstalledRepositoryEnabled()) { 33 | $internalRepositoryFile = $this->getApplication()->internalVendorRoot().'/.composer/installed.json'; 34 | $filesystemRepository = new FilesystemRepository(new JsonFile($internalRepositoryFile)); 35 | $io->write('Including '.$internalRepositoryFile.' in installed repository, contains:'); 36 | foreach ($filesystemRepository->getPackages() as $package) { 37 | $io->write(' * '.$package->getName() . ':' . $package->getPrettyVersion()); 38 | } 39 | } else { 40 | $filesystemRepository = null; 41 | } 42 | 43 | $install = Installer::create($io, $composer); 44 | 45 | $install 46 | ->setDryRun($input->getOption('dry-run')) 47 | ->setVerbose($input->getOption('verbose')) 48 | ->setPreferSource($input->getOption('prefer-source')) 49 | ->setInstallRecommends(!$input->getOption('no-install-recommends')) 50 | ->setInstallSuggests($input->getOption('install-suggests')) 51 | ->setAdditionalInstalledRepository($filesystemRepository) 52 | ->setUpdate(true) 53 | ; 54 | 55 | return $install->run() ? 0 : 1; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/dflydev/embedded/composer/console/Application.php: -------------------------------------------------------------------------------- 1 | getDefinition()->addOption(new InputOption('project-root', null, InputOption::VALUE_REQUIRED, 'Project root.', self::DEFAULT_PROJECT_ROOT)); 51 | $this->classLoader = $classLoader; 52 | $obj = new \ReflectionClass($this->classLoader); 53 | $this->internalVendorRoot = dirname(dirname($obj->getFileName())); 54 | } 55 | 56 | /** 57 | * {@inheritDoc} 58 | */ 59 | public function doRun(InputInterface $input, OutputInterface $output) 60 | { 61 | $projectRoot = realpath($input->getParameterOption('--project-root') ?: self::DEFAULT_PROJECT_ROOT); 62 | if ($autoloadNamespacesFile = realpath($projectRoot.'/vendor/.composer/autoload_namespaces.php')) { 63 | if ($this->internalVendorRoot != dirname(dirname($autoloadNamespacesFile))) { 64 | // We have an autoload file that is *not* the same as the 65 | // autoload that bootstrapped this application. 66 | $map = require $autoloadNamespacesFile; 67 | foreach ($map as $namespace => $path) { 68 | $this->classLoader->add($namespace, $path); 69 | } 70 | } 71 | } 72 | if (strpos($this->internalVendorRoot, $projectRoot)===false) { 73 | // If our vendor root does not contain our project root then we 74 | // can assume that we should enable the internally installed 75 | // repository. 76 | $this->internallyInstalledRepositoryEnabled = true; 77 | } 78 | $this->add(new command\ComposerInstallCommand()); 79 | $this->add(new command\ComposerUpdateCommand()); 80 | return parent::doRun($input, $output); 81 | } 82 | 83 | /** 84 | * Class loader 85 | * @return \Composer\Autoload\ClassLoader 86 | */ 87 | public function classLoader() 88 | { 89 | return $this->classLoader; 90 | } 91 | 92 | /** 93 | * Internal vendor root 94 | * 95 | * This is the vendor root for the class loader used to bootstrap 96 | * the application. In some cases this may be embedded in a phar, 97 | * in a development directory, or the vendor for the package using 98 | * Embedded Composer. 99 | * @return string 100 | */ 101 | public function internalVendorRoot() 102 | { 103 | return $this->internalVendorRoot; 104 | } 105 | 106 | /** 107 | * Whether or not Composer should use the internally installed repsoitory 108 | * 109 | * This is done when the Embedded Composer instance running is located in 110 | * another directory or is embedded in a phar. It instructs Composer to 111 | * include the installed repository from the internal vendor root. 112 | */ 113 | public function internallyInstalledRepositoryEnabled() 114 | { 115 | return $this->internallyInstalledRepositoryEnabled; 116 | } 117 | } 118 | --------------------------------------------------------------------------------