├── .gitignore ├── LICENSE ├── bin └── commit ├── composer.json ├── docs └── example.gif ├── readme.md └── src ├── EmojiList.php └── EmojiUsage.php /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | .emoji_usage 4 | composer.lock 5 | vendor -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Jake A. Smith 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /bin/commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | input('Use the commit builder? (y/n) [y]:'); 14 | $input->accept(['y', 'n']); 15 | $input->defaultTo('y'); 16 | 17 | $response = $input->prompt(); 18 | if ($response === 'n') { 19 | passthru('"${EDITOR:-${VISUAL:-vim}}" ' . $argv[1]); 20 | echo PHP_EOL; 21 | exit; 22 | } 23 | 24 | // Capture Emoji first -------------------------------------------------------- 25 | $climate->flank('Lets make a commit message', '-', 20); 26 | $climate->green('Which emoji will we need?'); 27 | 28 | $emojiList = new EmojiList(); 29 | $emojiUsage = new EmojiUsage(realpath(__DIR__ . '/..')); 30 | 31 | $options = $emojiUsage->sortByUsage($emojiList->get()); 32 | $input = $climate->checkboxes('Check all that apply:', $options); 33 | $emojiSelected = $input->prompt(); 34 | $emojiUsage->useEmojii($emojiSelected); 35 | $emojiSpacing = str_repeat('# ', count($emojiSelected)); 36 | $emojiSelected = implode(' ', $emojiSelected); 37 | 38 | // Create the rest of the subject line ------------------------------------------- 39 | $climate->green('Complete the subject line below:'); 40 | 41 | $climate->yellow('Use the Present Tense ("Add feature" not "Added feature").'); 42 | $climate->yellow('Use the Imperative Mood ("Move cursor to..." not "Moves cursor to...").'); 43 | $climate->yellow('Make it shorter than the yellow line.'); 44 | $climate->yellow('--------------------------------------------------------------------------------'); 45 | $subjectLine = $climate->input($emojiSpacing)->prompt(); 46 | $subjectLine = $emojiSelected . ' ' . $subjectLine; 47 | 48 | // Create the message body ---------------------------------------------------- 49 | $climate->green('Now for the message body. You can use MarkDown here.'); 50 | $messageBody = $climate->input('Commit body:')->prompt(); 51 | 52 | // Get any issue task links --------------------------------------------------- 53 | $climate->green('Include any GitHub Issue/Phabricator/Jira Task ID References.'); 54 | $climate->green('Ex. Issue #27, Ref T27 or Ref T27, T56 or Fixes T8.'); 55 | $taskLinks = $climate->input('Task links:')->prompt(); 56 | 57 | // Display the subject line 58 | $message = "{$subjectLine}"; 59 | if (!empty($messageBody)) { 60 | $message .= PHP_EOL . PHP_EOL . $messageBody; 61 | } 62 | if (!empty($taskLinks)) { 63 | $message .= PHP_EOL . PHP_EOL . $taskLinks; 64 | } 65 | 66 | file_put_contents($argv[1], $message); 67 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "smacme/commit", 3 | "require": { 4 | "league/climate": "^3.2" 5 | }, 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Jake A. Smith", 10 | "email": "theman@jakeasmith.com" 11 | } 12 | ], 13 | "autoload": { 14 | "psr-4": { 15 | "Smacme\\Commit\\": "src" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /docs/example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakeasmith/commit/dab3e5de1d2938da2ab2fb37ccf463a7c470fc4d/docs/example.gif -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Standardized Commit Messages 2 | 3 | A tool to aid in standardizing commit messages. Based on this wonderful emoji based [standard Git Commit Message format by @slashsBin](https://github.com/slashsBin/styleguide-git-commit-message). 4 | 5 | ![Example output](docs/example.gif) 6 | 7 | ## Setup 8 | 9 | - Clone the repo 10 | - Run `composer install` 11 | - Set Git's file editor to use the included `bin/commit` with something like `export GIT_EDITOR=/your/path/to/commit-repo/bin/commit` 12 | 13 | ## Known issues 14 | - Git uses the `#` character to signify comment lines that should be ignored causing ticket numbers to be ignored when not prefixed with any other characters. As of Git 1.8.2 [a config value](https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt#L98) is available to customize the comment character. 15 | 16 | ## Feature requests and bugs 17 | Find a bug? Have an idea to make this better? Go to the [Issues tab in GitHub](https://github.com/jakeasmith/commit/issues) and open up a ticket! Just have a comment? My twitter handle is [@jakeasmith](https://twitter.com/jakeasmith). 18 | 19 | ## Contributing 20 | All PRs are welcome but you might want to open up an issue to discuss any major changes before putting a lot of time into them. 21 | 22 | ## Copyright 23 | The smacme/commit library is copyright © Jake A. Smith and licensed for use under the MIT License (MIT). Please see LICENSE for more information. 24 | -------------------------------------------------------------------------------- /src/EmojiList.php: -------------------------------------------------------------------------------- 1 | 'Improving the format/structure of the code', 10 | '🐎' => 'Improving performance', 11 | '📚' => 'Writing docs', 12 | '🐛' => 'Reporting a bug', 13 | '🚑' => 'Fixing a bug', 14 | '🐧' => 'Fixing something on Linux', 15 | '🍎' => 'Fixing something on Mac OS', 16 | '🏁' => 'Fixing something on Windows', 17 | '📼' => 'Deprecating code', 18 | '🔥' => 'Removing code or files', 19 | '✅' => 'Adding tests', 20 | '💚' => 'Fixing the CI build', 21 | '🔒' => 'Dealing with security', 22 | '⬆️' => 'Upgrading dependencies', 23 | '⬇️' => 'Downgrading dependencies', 24 | '👕' => 'Removing linter/strict/deprecation warnings', 25 | '💄' => 'Improving UI/Cosmetic', 26 | '🚧' => 'WIP(Work In Progress) Commits', 27 | '💎' => 'New Release', 28 | '🔖' => 'Version Tags', 29 | '🎉' => 'Initial Commit', 30 | '🔈' => 'Adding Logging', 31 | '🔇' => 'Reducing Logging', 32 | '✨' => 'Introducing New Features', 33 | '⚡️' => 'Introducing Backward-InCompatible Features', 34 | '💡' => 'New Idea', 35 | '❄️' => 'Changing Configuration', 36 | '🎀' => 'Customer requested application Customization', 37 | '🚀' => 'Anything related to Deployments/DevOps', 38 | '🐬' => 'MySQL Database scripts/schema', 39 | ]; 40 | 41 | public function get() 42 | { 43 | return $this->options; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/EmojiUsage.php: -------------------------------------------------------------------------------- 1 | workingDir = realpath($workingDir); 15 | } 16 | 17 | public function sortByUsage($emojii) 18 | { 19 | uksort($emojii, function ($a, $b) use ($emojii) { 20 | $aCount = $this->getCount($a); 21 | $bCount = $this->getCount($b); 22 | 23 | if ($aCount == $bCount) { 24 | return $emojii[$a] > $emojii[$b]; 25 | } 26 | 27 | return $aCount > $bCount ? -1 : 1; 28 | }); 29 | 30 | return $emojii; 31 | } 32 | 33 | public function useEmojii($emojii) 34 | { 35 | $usage = $this->get(); 36 | foreach ($emojii as $emoji) { 37 | if (!array_key_exists($emoji, $usage)) { 38 | $usage[$emoji] = 0; 39 | } 40 | 41 | $usage[$emoji]++; 42 | } 43 | 44 | $this->save($usage); 45 | } 46 | 47 | private function getCount($emoji) 48 | { 49 | $usage = $this->get(); 50 | return array_key_exists($emoji, $usage) 51 | ? $usage[$emoji] 52 | : 0; 53 | } 54 | 55 | private function get() 56 | { 57 | $filename = $this->getFilename(); 58 | if (!file_exists($filename)) { 59 | file_put_contents($filename, json_encode([])); 60 | } 61 | 62 | return json_decode(file_get_contents($filename), true); 63 | } 64 | 65 | private function save($usage) 66 | { 67 | file_put_contents($this->getFilename(), json_encode($usage, JSON_PRETTY_PRINT)); 68 | } 69 | 70 | private function getFilename() 71 | { 72 | return $this->workingDir . DIRECTORY_SEPARATOR . $this->usageFilename; 73 | } 74 | } --------------------------------------------------------------------------------