├── composer.json ├── GDM └── SSAutoGitIgnore │ ├── UpdateScript.php │ ├── SSPackageInfo.php │ └── GitIgnoreEditor.php ├── license.md └── readme.md /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gdmedia/ss-auto-git-ignore", 3 | "description": "A Composer post-update-cmd script to automatically add Composer managed SilverStripe modules and themes to .gitignore", 4 | "authors": [ 5 | { 6 | "name": "Corey Sewell", 7 | "email": "corey@gurudigal.nz" 8 | } 9 | ], 10 | "autoload": { 11 | "psr-0": { 12 | "GDM\\": "./" 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /GDM/SSAutoGitIgnore/UpdateScript.php: -------------------------------------------------------------------------------- 1 | getIO()->writeError('Generating .gitignore: ', false); 11 | $gi = new GitIgnoreEditor(getcwd() . '/.gitignore'); 12 | $packageInfo = new SSPackageInfo($event->getComposer()); 13 | $ignores = array(); 14 | foreach ($packageInfo->GetSSModules() as $value) { 15 | $ignores[] = "/" . $value["path"] ;//. "/"; 16 | } 17 | $ignores = array_unique($ignores); 18 | sort($ignores); 19 | 20 | $gi->setLines($ignores); 21 | $gi->save(); 22 | $event->getIO()->writeError('Done - Set to ignore '.count($ignores).' packages'); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Guru Digital Media 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # SilverStripe Auto Git Ignore 2 | A Composer post-update-cmd script to automatically add Composer managed SilverStripe modules and themes to .gitignore 3 | 4 | ## Installation 5 | ### Add it to your project with: 6 | ```shell 7 | composer require gdmedia/ss-auto-git-ignore 8 | ``` 9 | ### Add the following to your composer.json 10 | ```json 11 | "scripts": { 12 | "post-update-cmd": "GDM\\SSAutoGitIgnore\\UpdateScript::Go" 13 | } 14 | ``` 15 | 16 | ## License 17 | 3-clause BSD license 18 | See [License](license.md) 19 | 20 | ## Bugtracker 21 | Bugs are tracked in the issues section of this repository. Before submitting an issue please read over existing issues to ensure yours is unique. 22 | 23 | If the issue does look like a new bug: 24 | 25 | - [Create a new issue](../../issues/new) 26 | - Describe the steps required to reproduce your issue, and the expected outcome. Unit tests, screenshots and screencasts can help here. 27 | - Describe your environment as detailed as possible: Browser, Operating System, etc. 28 | 29 | ## Development and contribution 30 | Feature requests can also be made by [creating a new issue](../../issues/new). 31 | If you would like to make contributions to this module, feel free to [create a fork](../../fork) and submit a pull request 32 | 33 | ## Versioning 34 | This project follows [Semantic Versioning](http://semver.org) paradigm. That is: 35 | 36 | > Given a version number MAJOR.MINOR.PATCH, increment the: 37 | > 1. MAJOR version when you make incompatible API changes, 38 | > 2. MINOR version when you add functionality in a backwards-compatible manner, and 39 | > 3. PATCH version when you make backwards-compatible bug fixes. 40 | > 4. Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format. 41 | -------------------------------------------------------------------------------- /GDM/SSAutoGitIgnore/SSPackageInfo.php: -------------------------------------------------------------------------------- 1 | composer = $composer; 40 | $this->repoManager = $this->composer->getRepositoryManager(); 41 | $this->installManager = $composer->getInstallationManager(); 42 | $this->baseDir = $this->NormalizePath(getcwd()); 43 | } 44 | 45 | public function GetSSModules() { 46 | $packages = array(); 47 | 48 | foreach ($this->repoManager->getLocalRepository()->getPackages() as $package) { 49 | /* @var $package \Composer\Package\Package */ 50 | if (!isset($packages[$package->getName()]) || !is_object($packages[$package->getName()]) || version_compare($packages[$package->getName()]->getVersion(), $package->getVersion(), '<') 51 | ) { 52 | if (in_array($package->getType(), $this->requiredTpes)) { 53 | $packgePath = $this->NormalizePath($this->installManager->getInstallPath($package)); 54 | $packages[$package->getName()]["info"] = $package; 55 | $packages[$package->getName()]["path"] = $packgePath; 56 | } 57 | } 58 | } 59 | return $packages; 60 | } 61 | 62 | protected function NormalizePath($path) { 63 | $search = array('\\', '\\\\', '//', $this->baseDir); 64 | $replace = array('/', '/', '/', ''); 65 | return trim(str_replace($search, $replace, $path), '/'); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /GDM/SSAutoGitIgnore/GitIgnoreEditor.php: -------------------------------------------------------------------------------- 1 | filePath = $ignoreFilePath; 79 | $this->CheckGitIgnore(); 80 | $this->parse(); 81 | } 82 | 83 | /** 84 | * Loads the current .gitignore and parses it. 85 | * Overwites/resets any unsaved changes 86 | * 87 | * @throws AutoGitIgnoreParseException 88 | * @return self 89 | */ 90 | public function parse() { 91 | $this->readLines = file($this->filePath, FILE_IGNORE_NEW_LINES); 92 | if (in_array($this->startMarker, $this->readLines) && !in_array($this->endMarker, $this->readLines)) { 93 | throw new AutoGitIgnoreParseException("Found start marker on line " . ($this->findStartIndex() + 1) . " without an end marker. Please manually edit " . $this->filePath); 94 | } else if (in_array($this->endMarker, $this->readLines) && !in_array($this->startMarker, $this->readLines)) { 95 | throw new AutoGitIgnoreParseException("Found end marker on line " . ( $this->findEndIndex() + 1) . " without a start marker. Please manually edit " . $this->filePath); 96 | } 97 | $this->startIndex = $this->findStartIndex(); 98 | $this->endIndex = $this->findEndIndex(); 99 | if ($this->endIndex < $this->startIndex) { 100 | throw new AutoGitIgnoreParseException("End marker found on line " . ($this->endIndex + 1) . " before start maker on line " . ($this->startIndex + 1) . ". Please manually edit " . $this->filePath); 101 | } 102 | 103 | $this->numLines = count($this->readLines); 104 | 105 | if ($this->startIndex === false) { 106 | $this->startIndex = $this->numLines + 1; 107 | } 108 | if ($this->startIndex != 0) { 109 | $this->beforeLines = array_slice($this->readLines, 0, $this->startIndex); 110 | } 111 | if ($this->endIndex === false) { 112 | $this->endIndex = $this->numLines - 1; 113 | } 114 | 115 | if ($this->endIndex !== $this->numLines - 1) { 116 | $this->afterLines = array_slice($this->readLines, $this->endIndex + 1, $this->numLines); 117 | } 118 | 119 | $this->autoLines = array_slice($this->readLines, $this->startIndex, $this->endIndex); 120 | 121 | // If autoLines is empty, this is the first time we are auto adding to this gitinore. 122 | // So just add the markers 123 | if (empty($this->autoLines)) { 124 | // Add an empy line above the marker, unless its on the first line or already had one 125 | if ($this->startIndex !== 0 && !empty($this->readLines[$this->endIndex])) { 126 | $this->autoLines[] = PHP_EOL; 127 | } 128 | $this->autoLines[] = $this->startMarker; 129 | $this->autoLines[] = $this->endMarker; 130 | } 131 | return $this; 132 | } 133 | 134 | /** 135 | * Set the lines to appear between the makers 136 | * 137 | * @param type $lines 138 | * @throws AutoGitIgnoreInvalidParameterException 139 | * @return self 140 | */ 141 | public function setLines($lines) { 142 | if (!is_array($lines)) { 143 | throw new AutoGitIgnoreInvalidParameterException("$lines must be an array. Each value is one line"); 144 | } 145 | if (current($lines) !== $this->startMarker) { 146 | array_unshift($lines, $this->startMarker); 147 | } 148 | if (end($lines) !== $this->endMarker) { 149 | $lines[] = $this->endMarker; 150 | } 151 | $this->autoLines = $lines; 152 | return $this; 153 | } 154 | 155 | /** 156 | * Save chanes to the .gitinore file 157 | * 158 | * @throws AutoGitIgnoreSaveFailedException 159 | * @return self 160 | */ 161 | public function save() { 162 | $this->CheckGitIgnore(); 163 | if (!empty($this->beforeLines) && trim(end($this->beforeLines))) { 164 | array_push($this->beforeLines, ''); 165 | } 166 | if (empty($this->afterLines) || trim(reset($this->afterLines))) { 167 | array_unshift($this->afterLines, ''); 168 | } 169 | $this->readLines = array_merge($this->beforeLines, $this->autoLines, $this->afterLines); 170 | if (count($this->readLines)) { 171 | if (!file_put_contents($this->filePath, implode(PHP_EOL, $this->readLines))) { 172 | throw new AutoGitIgnoreSaveFailedException("Saving to " . $this->filePath . " failed"); 173 | } 174 | } 175 | return $this; 176 | } 177 | 178 | /** 179 | * Find the index in the readLines array containg the value of $line 180 | * 181 | * @param string $line the line to search for 182 | * @return int 183 | */ 184 | public function findLine($line) { 185 | return array_search($line, $this->readLines); 186 | } 187 | 188 | /** 189 | * Find the index in the readLines array containg the start marker 190 | * 191 | * @return int 192 | */ 193 | public function findStartIndex() { 194 | return $this->findLine($this->startMarker); 195 | } 196 | 197 | /** 198 | * Find the index in the readLines array containg the end marker 199 | * 200 | * @return int 201 | */ 202 | public function findEndIndex() { 203 | return $this->findLine($this->endMarker); 204 | } 205 | 206 | /** 207 | * Prints debug info 208 | * @return self 209 | */ 210 | public function debug() { 211 | echo "filePath = " . $this->filePath . PHP_EOL; 212 | echo "startMarker = " . $this->startMarker . PHP_EOL; 213 | echo "endMarker = " . $this->endMarker . PHP_EOL; 214 | echo "startIndex = " . $this->startIndex . PHP_EOL; 215 | echo "endIndex = " . $this->endIndex . PHP_EOL; 216 | echo "numLines = " . $this->numLines . PHP_EOL; 217 | echo "Start = " . print_r($this->beforeLines, true); 218 | echo "Auto = " . print_r($this->autoLines, true); 219 | echo "End = " . print_r($this->afterLines, true); 220 | return $this; 221 | } 222 | 223 | /** 224 | * 225 | * @throws AutoGitIgnorePermissionException 226 | * @return self 227 | */ 228 | protected function CheckGitIgnore() { 229 | if (!file_exists($this->filePath)) { 230 | if (!is_writable(dirname($this->filePath))) { 231 | throw new AutoGitIgnorePermissionException("Do not have permission to create " . $this->filePath . ". .gitignore does not exist, and unable to create it"); 232 | } 233 | touch($this->filePath); 234 | } elseif (!is_writable($this->filePath)) { 235 | throw new AutoGitIgnorePermissionException("Do not have permission to edit " . $this->filePath . "."); 236 | } 237 | return $this; 238 | } 239 | 240 | } 241 | 242 | class AutoGitIgnorePermissionException extends \Exception { 243 | 244 | } 245 | 246 | class AutoGitIgnoreParseException extends \Exception { 247 | 248 | } 249 | 250 | class AutoGitIgnoreInvalidParameterException extends \Exception { 251 | 252 | } 253 | 254 | class AutoGitIgnoreSaveFailedException extends \Exception { 255 | 256 | } 257 | --------------------------------------------------------------------------------