├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── index.php └── src └── ComposerHelper.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | .idea/ 3 | composer.lock 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Bob Mulder 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # composer-ui 2 | ComposerUI for Composer 3 | 4 | > Note: This is just a try for composer, and should be considered as experimental. 5 | 6 | ## Strategy 7 | Via [this issue at Composer](https://github.com/composer/composer/issues/4429), we started with the idea to build 8 | a general UI for composer. However, the UI couldn't exist without a `helper` to create and execute commands. 9 | 10 | At the moment we are working on the helper. The goal is that the helper can be used in future without the UI. The UI 11 | will be the second part. 12 | 13 | ## Installation 14 | You can install this package via... Yeah... Composer: 15 | 16 | composer require bobmulder/composer-ui:dev-master 17 | 18 | 19 | ## Usage 20 | The following commands are supported for now: 21 | - composer 22 | - install 23 | - archive 24 | - update 25 | - require 26 | - remove 27 | 28 | ### The ComposerHelper Class 29 | You can start using composer by creating an instance of the `ComposerUI/ComposerHelper`-class: 30 | 31 | $composer = new ComposerHelper(); 32 | 33 | You can configure the working path via: 34 | 35 | $composer = new ComposerHelper('/custom/path'); 36 | 37 | Now you are ready to go! 38 | 39 | ### Options 40 | On every command you can use every option that is available at composer. 41 | 42 | > Note: Read this to get a list of commands and options: https://getcomposer.org/doc/03-cli.md 43 | 44 | > Note: Need a specific command? Open up an issue or better a pull request! 45 | 46 | ### Composer 47 | Just initializes composer. Nothing special. 48 | 49 | $composer->composer(); 50 | 51 | ### Install 52 | The install command reads the `composer.json` file from the current directory, resolves the dependencies, and installs 53 | them into vendor. 54 | 55 | $composer->install(); 56 | 57 | ### Archive 58 | This command is used to generate a zip/tar archive for your entire project. 59 | 60 | $composer->archive(); 61 | 62 | > Note: Composer itself supports to archive specific packages, but this library doesn't support that yet... 63 | 64 | ### Update 65 | In order to get the latest versions of the dependencies and to update the `composer.lock` file, you should use the 66 | update command. 67 | 68 | $composer->update(); 69 | 70 | ### Require 71 | The require command adds new packages to the `composer.json` file from the current directory. If no file exists one will 72 | be created on the fly. 73 | 74 | $composer->requirePackages([ 75 | 'vendor/package' => '2.x', 76 | 'vendor/secondpackage' => 'dev-master', 77 | 'vendor/thirthpackage', 78 | ]); 79 | 80 | ### Remove 81 | The remove command removes packages from the `composer.json` file from the current directory. 82 | 83 | $composer->removePackages([ 84 | 'vendor/package' => '2.x', 85 | 'vendor/secondpackage' => 'dev-master', 86 | 'vendor/thirthpackage', 87 | ]); 88 | 89 | ## Next 90 | We would like to refer you to the composer docs itself: https://getcomposer.org/doc/03-cli.md 91 | 92 | If you need help, don't fear to get in touch via gitter: https://gitter.im/bobmulder/composer-ui 93 | 94 | [![Join the chat at https://gitter.im/bobmulder/composer-ui](https://badges.gitter.im/Join%20Chat.svg)] 95 | (https://gitter.im/bobmulder/composer-ui?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bobmulder/composer-ui", 3 | "description": "Composer tools and UI for Composer", 4 | "require": { 5 | "symfony/process": "~3.0@dev" 6 | }, 7 | "require-dev": { 8 | "phpunit/phpunit": "*" 9 | }, 10 | "autoload": { 11 | "psr-4": { 12 | "ComposerUI\\": "src" 13 | } 14 | }, 15 | "autoload-dev": { 16 | "psr-4": { 17 | } 18 | }, 19 | "minimum-stability": "dev" 20 | } 21 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | '; 9 | print_r($var); 10 | echo ''; 11 | } 12 | 13 | $composer = new ComposerHelper(); 14 | 15 | debug('welcome to ComposerTools. This stuff is needed before setting up a full working UI'); 16 | 17 | /** 18 | * Call composer 19 | * 20 | * You can call composer by calling `composer`. 21 | */ 22 | //$composer->composer(); 23 | 24 | 25 | 26 | /** 27 | * Install packages 28 | * 29 | * You can install composer packages by calling `install`. 30 | */ 31 | //$composer->install(); 32 | 33 | 34 | /** 35 | * Archive composer 36 | * 37 | * You can archive composer by calling `archive`. 38 | */ 39 | //$composer->archive(); 40 | 41 | 42 | /** 43 | * Installing packages 44 | * 45 | * You can installing a package by calling `requirePackages`. 46 | * Use the first parameter to define the package. 47 | * Use the second parameter to define the version. 48 | */ 49 | //$composer->requirePackages([ 50 | // 'symfony/stopwatch' => 'dev-master', 51 | //]); 52 | 53 | 54 | /** 55 | * Removing packages 56 | * 57 | * You can remove a package by calling `removePackages`. 58 | * Use the first parameter to define the package. 59 | */ 60 | //$composer->removePackages([ 61 | // 'symfony/stopwatch' => 'dev-master', 62 | //]); 63 | 64 | 65 | /** 66 | * Update packages 67 | * 68 | * You can update composer by calling `update`. 69 | */ 70 | //$composer->update(); -------------------------------------------------------------------------------- /src/ComposerHelper.php: -------------------------------------------------------------------------------- 1 | workingPath = $workingPath; 28 | } 29 | 30 | /** 31 | * Call composer command. 32 | * 33 | * @param array $options 34 | * @return string 35 | */ 36 | public function composer(array $options = []) 37 | { 38 | $process = $this->getProcess(); 39 | $process->setCommandLine($this->findComposer() . $this->normalizeOptions($options)); 40 | 41 | return $this->runProcess($process); 42 | } 43 | 44 | /** 45 | * Install composer packages. 46 | * 47 | * @param array $options 48 | * @return Process 49 | */ 50 | public function install(array $options = []) 51 | { 52 | $process = $this->getProcess(); 53 | $process->setCommandLine($this->findComposer() . 'install' . $this->normalizeOptions($options)); 54 | 55 | return $this->runProcess($process); 56 | } 57 | 58 | /** 59 | * Generates zip/tar 60 | * @param array $options 61 | * @return Process 62 | */ 63 | public function archive(array $options = []) 64 | { 65 | $process = $this->getProcess(); 66 | $process->setCommandLine($this->findComposer() . 'archive' . $this->normalizeOptions($options)); 67 | 68 | return $this->runProcess($process); 69 | } 70 | 71 | /** 72 | * Update composer packages. 73 | * 74 | * @param array $options 75 | * @return Process 76 | */ 77 | public function update(array $options = []) 78 | { 79 | $process = $this->getProcess(); 80 | $process->setCommandLine($this->findComposer() . 'update' . $this->normalizeOptions($options)); 81 | 82 | return $this->runProcess($process); 83 | } 84 | 85 | /** 86 | * Require one or multiple packages. 87 | * 88 | * @param array $packages Package name. 89 | * @param array $options 90 | * @return Process 91 | */ 92 | public function requirePackages(array $packages, array $options = []) 93 | { 94 | $packageString = $this->normalizePackages($packages); 95 | $optionsString = $this->normalizeOptions($options); 96 | 97 | $process = $this->getProcess(); 98 | $process->setCommandLine($this->findComposer() . 'require ' . $packageString . $optionsString); 99 | 100 | return $this->runProcess($process); 101 | } 102 | 103 | /** 104 | * Remove one or more packages. 105 | * 106 | * @param array $packages Package name. 107 | * @param array $options 108 | * @return Process 109 | */ 110 | public function removePackages(array $packages, array $options = []) 111 | { 112 | $packageString = $this->normalizePackages($packages, [ 113 | 'packageVersion' => false 114 | ]); 115 | $optionsString = $this->normalizeOptions($options); 116 | 117 | $process = $this->getProcess(); 118 | $process->setCommandLine($this->findComposer() . 'remove ' . $packageString . $optionsString); 119 | 120 | return $this->runProcess($process); 121 | } 122 | 123 | /** 124 | * Get the composer command for the environment. 125 | * 126 | * @return string 127 | */ 128 | protected function findComposer() 129 | { 130 | if (!file_exists($this->workingPath . '/composer.phar')) { 131 | return 'composer '; 132 | } 133 | 134 | $binary = ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false)); 135 | 136 | if (defined('HHVM_VERSION')) { 137 | $binary .= ' --php'; 138 | } 139 | 140 | return "{$binary} composer.phar "; 141 | } 142 | 143 | /** 144 | * Get a new Symfony process instance. 145 | * 146 | * @return \Symfony\Component\Process\Process 147 | */ 148 | protected function getProcess() 149 | { 150 | return (new Process('', $this->workingPath))->setTimeout(null); 151 | } 152 | 153 | /** 154 | * Runs the process and debugs result. 155 | * 156 | * @param Process $process 157 | * @return Process 158 | */ 159 | protected function runProcess(Process $process) 160 | { 161 | $process->mustRun(function ($type, $buffer) { 162 | if (Process::ERR === $type) { 163 | echo '
ERR > ' . $buffer . '
'; 164 | } else { 165 | echo '
OUT > ' . $buffer . '
'; 166 | } 167 | }); 168 | return $process; 169 | } 170 | 171 | /** 172 | * Returns a list of packages into a string to use in composer call. 173 | * 174 | * Example input: [ 175 | * 'symfony/yaml' => 'dev-master', 176 | * 'symfony/config' 177 | * ]; 178 | * 179 | * Example output: "symfony/yaml:dev-master" "symfony/config" 180 | * 181 | * ### Options 182 | * - `packageVersion` - Add package version into the string. If false, only the package name will be used. 183 | * 184 | * @param array $packages 185 | * @param array $options 186 | * @return string 187 | */ 188 | protected function normalizePackages(array $packages, array $options = []) 189 | { 190 | $_options = [ 191 | 'packageVersion' => true 192 | ]; 193 | $options = array_merge($_options, $options); 194 | 195 | $packageList = []; 196 | foreach ((array)$packages as $packageName => $packageVersion) { 197 | if (is_int($packageName)) { 198 | $packageName = $packageVersion; 199 | $packageVersion = false; 200 | } 201 | if ($options['packageVersion'] === false) { 202 | $packageVersion = false; 203 | } 204 | $packageList[] = escapeshellarg($packageName . (($packageVersion) ? ":" . $packageVersion : "")); 205 | } 206 | return implode(" ", $packageList); 207 | } 208 | 209 | /** 210 | * Returns a list of options into a string of options to use in composer call. 211 | * 212 | * @param array $options 213 | * @return string 214 | */ 215 | protected function normalizeOptions(array $options) 216 | { 217 | $optionsList = []; 218 | foreach ((array)$options as $option => $value) { 219 | if (is_int($option)) { 220 | $option = $value; 221 | $value = false; 222 | } 223 | $optionsList[] = $option . (($value) ? " " . escapeshellarg($value) : ""); 224 | } 225 | return " " . implode(" ", $optionsList); 226 | } 227 | 228 | /** 229 | * Set the working path used by the class. 230 | * 231 | * @param string $path 232 | * @return $this 233 | */ 234 | public function setWorkingPath($path) 235 | { 236 | $this->workingPath = realpath($path); 237 | 238 | return $this; 239 | } 240 | 241 | } --------------------------------------------------------------------------------