├── .attach_pid25561 ├── ugh.jar ├── cover.jpeg ├── after_ugh_commit.png ├── before_ugh_commit.png ├── src ├── META-INF │ └── MANIFEST.MF └── com │ └── theah64 │ └── ugh │ ├── utils │ ├── StringUtils.kt │ ├── TerminalUtils.kt │ ├── InputUtils.kt │ └── CommitTypeUtils.kt │ ├── CommitType.kt │ ├── Main.kt │ └── Ugh.kt ├── after_ugh_commit_result.png ├── before_ugh_commit_result.png ├── .idea ├── encodings.xml ├── codeStyles │ ├── codeStyleConfig.xml │ └── Project.xml ├── vcs.xml ├── modules.xml ├── misc.xml ├── kotlinc.xml ├── libraries │ ├── com_squareup_moshi_moshi_1_8_0.xml │ ├── KotlinJavaRuntime.xml │ └── com_squareup_moshi_moshi_kotlin_1_8_0.xml ├── artifacts │ └── ugh_jar.xml └── workspace.xml ├── .gitignore ├── ugh.iml ├── README.md ├── dictionary.json └── LICENSE /.attach_pid25561: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ugh.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theapache64/ugh/HEAD/ugh.jar -------------------------------------------------------------------------------- /cover.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theapache64/ugh/HEAD/cover.jpeg -------------------------------------------------------------------------------- /after_ugh_commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theapache64/ugh/HEAD/after_ugh_commit.png -------------------------------------------------------------------------------- /before_ugh_commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theapache64/ugh/HEAD/before_ugh_commit.png -------------------------------------------------------------------------------- /src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: com.theah64.ugh.MainKt 3 | 4 | -------------------------------------------------------------------------------- /after_ugh_commit_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theapache64/ugh/HEAD/after_ugh_commit_result.png -------------------------------------------------------------------------------- /before_ugh_commit_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theapache64/ugh/HEAD/before_ugh_commit_result.png -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/com/theah64/ugh/utils/StringUtils.kt: -------------------------------------------------------------------------------- 1 | package com.theah64.ugh.utils 2 | 3 | object StringUtils { 4 | 5 | /** 6 | * Returns an array of commit command than can be executed with ProcessBuilder 7 | */ 8 | fun getCommitCommand(finalCommitMessage: String) = arrayOf("git", "commit", "-m", finalCommitMessage) 9 | } -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.war 15 | *.nar 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | 24 | out 25 | .DS_Store -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/libraries/com_squareup_moshi_moshi_1_8_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ugh.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/com/theah64/ugh/CommitType.kt: -------------------------------------------------------------------------------- 1 | package com.theah64.ugh 2 | 3 | import com.squareup.moshi.Json 4 | 5 | class CommitType( 6 | val type: String, 7 | val description: String, 8 | val emoji: String, 9 | val keywords: Array = arrayOf(), 10 | var points : Int = 0, 11 | @Transient 12 | var isMatchedWithKeyword : Boolean = false 13 | ) { 14 | companion object { 15 | const val TYPE_README = "readme" 16 | } 17 | 18 | override fun toString(): String { 19 | return "$emoji : $type : $description" 20 | } 21 | 22 | init { 23 | // making all keywords lowercase 24 | keywords.let { 25 | it.forEachIndexed { index, keyword -> 26 | keywords[index] = keyword.toLowerCase() 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/com/theah64/ugh/utils/TerminalUtils.kt: -------------------------------------------------------------------------------- 1 | package com.theah64.ugh.utils 2 | 3 | import java.io.BufferedReader 4 | import java.io.File 5 | import java.io.InputStreamReader 6 | 7 | object TerminalUtils { 8 | 9 | /** 10 | * Executes given command in given directory 11 | */ 12 | fun execute(command: Array, currentDir: String? = System.getProperty("user.dir")) { 13 | 14 | // log 15 | command.forEach { 16 | print("$it ") 17 | } 18 | 19 | var builder = ProcessBuilder(*command) 20 | builder = builder.directory(File(currentDir)) 21 | val p = builder.start() 22 | val reader = BufferedReader(InputStreamReader(p.inputStream)) 23 | var line = reader.readLine() 24 | println() 25 | while (line != null) { 26 | println(line) 27 | line = reader.readLine() 28 | } 29 | reader.close() 30 | } 31 | } -------------------------------------------------------------------------------- /.idea/libraries/KotlinJavaRuntime.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/libraries/com_squareup_moshi_moshi_kotlin_1_8_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/com/theah64/ugh/Main.kt: -------------------------------------------------------------------------------- 1 | package com.theah64.ugh 2 | 3 | 4 | /** 5 | * Inspired from https://github.com/kazupon/git-commit-message-convention 6 | * 7 | * MOTO 8 | * #### 9 | 10 | All Commit Message Format MUST meet this Text Format: 11 | 12 | [:: ][[()]: ] 13 | [] 14 | [] 15 | [] 16 | [] 17 | */ 18 | 19 | const val COMMIT_QUALITY_CLEAN = "clean" 20 | const val COMMIT_QUALITY_QUICK = "quick" 21 | const val COMMIT_QUALITY_QUICK_INTERACTIVE = "quick-i" 22 | 23 | fun main(args: Array) { 24 | 25 | require(args.isNotEmpty()) { "commit quality should be passed" } 26 | 27 | when (val commitQuality = args[0]) { 28 | 29 | COMMIT_QUALITY_CLEAN -> { 30 | Ugh.doCleanCommit() 31 | } 32 | 33 | 34 | COMMIT_QUALITY_QUICK -> { 35 | require(args.size > 1) { "commit message missing" } 36 | val message = args[1] 37 | Ugh.doQuickCommit(message) 38 | } 39 | 40 | COMMIT_QUALITY_QUICK_INTERACTIVE -> { 41 | require(args.size > 1) { "commit message missing" } 42 | val message = args[1] 43 | Ugh.doQuickInteractiveCommit(message) 44 | } 45 | 46 | else -> { 47 | println("ERROR : Undefined commit quality `$commitQuality`") 48 | } 49 | } 50 | 51 | 52 | } 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/com/theah64/ugh/utils/InputUtils.kt: -------------------------------------------------------------------------------- 1 | package com.theah64.ugh.utils 2 | 3 | import java.lang.NumberFormatException 4 | import java.util.* 5 | 6 | class InputUtils private constructor( 7 | private val scanner: Scanner 8 | ) { 9 | 10 | /** 11 | * Get a String with given prompt as prompt 12 | */ 13 | fun getString(prompt: String, isRequired: Boolean): String { 14 | print("$prompt: ") 15 | val value = scanner.nextLine() 16 | while (value.trim().isEmpty() && isRequired) { 17 | println("Invalid ${prompt.toLowerCase()} `$value`") 18 | return getString(prompt, isRequired) 19 | } 20 | return value 21 | } 22 | 23 | fun getInt(prompt: String, lowerBound: Int, upperBound: Int): Int { 24 | print("$prompt :") 25 | 26 | val sVal = scanner.nextLine() 27 | try { 28 | val value = sVal.toInt() 29 | if (value < lowerBound || value > upperBound) { 30 | println("Input must between $lowerBound and $upperBound") 31 | return getInt(prompt, lowerBound, upperBound) 32 | } 33 | return value 34 | } catch (e: NumberFormatException) { 35 | println("Invalid input `$sVal`") 36 | return getInt(prompt, lowerBound, upperBound) 37 | } 38 | } 39 | 40 | companion object { 41 | private var instance: InputUtils? = null 42 | fun getInstance(scanner: Scanner): InputUtils { 43 | if (instance == null) { 44 | instance = InputUtils(scanner) 45 | } 46 | return instance!! 47 | } 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /.idea/artifacts/ugh_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$ 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/com/theah64/ugh/Ugh.kt: -------------------------------------------------------------------------------- 1 | package com.theah64.ugh 2 | 3 | import com.theah64.ugh.utils.CommitTypeUtils 4 | import com.theah64.ugh.utils.InputUtils 5 | import com.theah64.ugh.utils.StringUtils 6 | import com.theah64.ugh.utils.TerminalUtils 7 | import java.util.* 8 | 9 | object Ugh { 10 | 11 | /** 12 | * Very interactive 13 | */ 14 | fun doCleanCommit() { 15 | 16 | val scanner = Scanner(System.`in`) 17 | 18 | val inputUtils = InputUtils.getInstance(scanner) 19 | val commitType = CommitTypeUtils.getCommitType(scanner) 20 | val scope = inputUtils.getString("Scope", true).toLowerCase() 21 | val subject = inputUtils.getString("Subject", true).capitalize() 22 | val messageBody = inputUtils.getString("Message Body", false).capitalize() 23 | val messageFooter = inputUtils.getString("Message Footer", false).capitalize() 24 | 25 | val finalCommitMessage = 26 | "${commitType.emoji} ${commitType.type}($scope) : $subject\n\n$messageBody\n\n$messageFooter\n".trim() 27 | 28 | val command = StringUtils.getCommitCommand(finalCommitMessage) 29 | 30 | TerminalUtils.execute(command) 31 | } 32 | 33 | /** 34 | * Non-interactive 35 | */ 36 | fun doQuickCommit(message: String) { 37 | val emoji = CommitTypeUtils.getCommitTypeFromMessage(message) 38 | doCommit(emoji, message) 39 | } 40 | 41 | private fun doCommit(emoji: CommitType, message: String) { 42 | println("Commit type identified : $emoji") 43 | val commitMessage = "${emoji.emoji} $message" 44 | val commitCommand = StringUtils.getCommitCommand(commitMessage) 45 | TerminalUtils.execute(commitCommand) 46 | emoji.points++ 47 | CommitTypeUtils.updateCommitTypes() 48 | } 49 | 50 | 51 | 52 | /** 53 | * Less interactive + quick 54 | */ 55 | fun doQuickInteractiveCommit(message: String) { 56 | 57 | val matchingCommitTypes = CommitTypeUtils.getCommitTypesFromMessage(message) 58 | 59 | val inputNum = if (matchingCommitTypes.size > 1) { 60 | println("Please confirm commit type") 61 | for (type in matchingCommitTypes.withIndex()) { 62 | val commitType = type.value 63 | val pointValue = if (commitType.points > 0) "(${commitType.points})" else "" 64 | if(commitType.isMatchedWithKeyword){ 65 | println("\u001B[32m${type.index + 1}) $commitType $pointValue \u001B[0m") 66 | }else{ 67 | println("${type.index + 1}) $commitType $pointValue") 68 | } 69 | } 70 | val scanner = Scanner(System.`in`) 71 | val inputUtils = InputUtils.getInstance(scanner) 72 | 73 | inputUtils.getInt("Enter number", 1, matchingCommitTypes.size) 74 | } else { 75 | println("Commit type identified via preset") 76 | // first 77 | 1 78 | } 79 | doCommit(matchingCommitTypes.elementAt(inputNum - 1), message) 80 | } 81 | 82 | } -------------------------------------------------------------------------------- /src/com/theah64/ugh/utils/CommitTypeUtils.kt: -------------------------------------------------------------------------------- 1 | package com.theah64.ugh.utils 2 | 3 | import com.squareup.moshi.Moshi 4 | import com.squareup.moshi.Types 5 | import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory 6 | import com.theah64.ugh.CommitType 7 | import com.theah64.ugh.Ugh 8 | import java.io.BufferedReader 9 | import java.io.File 10 | import java.io.FileReader 11 | import java.util.* 12 | 13 | object CommitTypeUtils { 14 | 15 | /** 16 | * Values should be in lowercase 17 | */ 18 | private val messageTypePreset = mapOf( 19 | "update readme" to CommitType.TYPE_README 20 | ) 21 | 22 | // jar path 23 | private val currentPath: String = File( 24 | Ugh::class.java!!.protectionDomain.codeSource.location 25 | .toURI() 26 | ).parentFile.path 27 | val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() 28 | val type = Types.newParameterizedType(List::class.java, CommitType::class.java) 29 | val adapter = moshi.adapter>(type) 30 | val dicFileName = "dictionary.json" 31 | var dicFile = File("$currentPath/$dicFileName") 32 | 33 | private val commitTypes: List by lazy { 34 | 35 | 36 | if (!dicFile.exists()) { 37 | // current path 38 | dicFile = File(dicFileName) 39 | } 40 | 41 | 42 | // Reading json file 43 | val reader = BufferedReader(FileReader(dicFile)) 44 | val jsonStringBuilder = StringBuffer() 45 | 46 | var line = reader.readLine() 47 | do { 48 | jsonStringBuilder.append(line) 49 | line = reader.readLine() 50 | } while (line != null) 51 | 52 | reader.close() 53 | 54 | 55 | // Converting to list 56 | adapter.fromJson(jsonStringBuilder.toString())!! 57 | } 58 | 59 | 60 | /** 61 | * Returns valid commit type 62 | */ 63 | fun getCommitType(scanner: Scanner): CommitType { 64 | 65 | 66 | print("Type: ") 67 | val inputType = scanner.nextLine() 68 | 69 | // Printing all type if it's a ? 70 | while (inputType == "?") { 71 | 72 | commitTypes.forEach { commitType -> 73 | println(commitType.toString()) 74 | } 75 | 76 | return getCommitType(scanner) 77 | } 78 | 79 | // Checking if it's a valid type 80 | val commitTypes = commitTypes.filter { 81 | inputType == it 82 | .type 83 | } 84 | 85 | while (commitTypes.isEmpty()) { 86 | println("Invalid commit type `$inputType`") 87 | return getCommitType(scanner) 88 | } 89 | 90 | val finalCommitType = commitTypes.first() 91 | 92 | println(finalCommitType.toString()) 93 | 94 | return finalCommitType 95 | } 96 | 97 | 98 | fun getCommitTypeFromMessage(message: String): CommitType { 99 | 100 | val msg = message.toLowerCase() 101 | val words = message.split(" ") 102 | val fWord = words[0].toLowerCase() 103 | 104 | // looping through all commit types 105 | for (commitType in commitTypes) { 106 | 107 | // looping through keywords 108 | commitType.keywords.let { keywords -> 109 | for (keyword in keywords) { 110 | if (msg.startsWith(keyword)) { 111 | return commitType 112 | } 113 | } 114 | } 115 | 116 | // couldn't get anything from keyword,now go for description 117 | if (commitType.description.toLowerCase().contains(fWord)) { 118 | return commitType 119 | } 120 | } 121 | 122 | return commitTypes[0] 123 | } 124 | 125 | 126 | fun getCommitTypesFromMessage(message: String): Set { 127 | 128 | // Preference for preset messages 129 | val message = message.toLowerCase().trim() 130 | if (messageTypePreset.containsKey(message)) { 131 | val commitType = messageTypePreset[message] 132 | return commitTypes.filter { it.type == commitType }.toSet() 133 | } else { 134 | val list = mutableSetOf() 135 | val words = message.split(" ") 136 | for (x in words) { 137 | val word = x.toLowerCase() 138 | for (commitType in commitTypes) { 139 | 140 | if (commitType.description.toLowerCase().contains(word) || word == commitType.type) { 141 | list.add(commitType) 142 | } else { 143 | // looping through keywords 144 | for (keyword in commitType.keywords) { 145 | if (keyword.contains(word) || word.contains(keyword)) { 146 | list.add(commitType) 147 | commitType.isMatchedWithKeyword = true 148 | } 149 | } 150 | } 151 | } 152 | } 153 | 154 | if (list.isEmpty()) { 155 | list.add(commitTypes.find { it.type == "backup" }!!) 156 | } 157 | 158 | return if (currentPath.contains("theapache64") && list.find { it.points > 0 } != null) { 159 | list.sortedByDescending { it.points } 160 | } else { 161 | list.sortedByDescending { it.isMatchedWithKeyword } 162 | }.toSet() 163 | } 164 | 165 | 166 | } 167 | 168 | fun updateCommitTypes() { 169 | val newJson = adapter.indent(" ").toJson(commitTypes) 170 | dicFile.writeText(newJson) 171 | } 172 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](cover.jpeg) 2 | 3 | # ugh 4 | Commit messages beautified 💖 5 | 6 | ### Installation 7 | 8 | Download [ugh.jar](ugh.jar) and [dictionary.json](dictionary.json) into one directory. Then, add this shortcut to your `.bashrc` file 9 | 10 | ``` 11 | # Build commit message interactively 12 | function commit-clean(){ 13 | git add -A && 14 | java -jar /path/to/ugh.jar clean 15 | } 16 | 17 | 18 | # Build commit message quickly 19 | function commit-quick(){ 20 | git add -A && 21 | java -jar /path/to/ugh.jar quick "$1" 22 | } 23 | 24 | # Build commit message quick + less interactive 25 | function commit-quick-i(){ 26 | git add -A && 27 | java -jar /path/to/ugh.jar quick-i 28 | } 29 | 30 | ``` 31 | 32 | and from your `git` directory, try those shortcuts. 33 | 34 | 35 | ### Example 36 | 37 | ##### Normal way 38 | 39 | `commit` 40 | 41 | ![](before_ugh_commit.png) 42 | 43 | 44 | `result` 45 | 46 | ![](before_ugh_commit_result.png) 47 | 48 | 49 | ##### Ugh Way 50 | 51 | `commit` 52 | 53 | ![](after_ugh_commit.png) 54 | 55 | 56 | `result` 57 | 58 | ![](after_ugh_commit_result.png) 59 | 60 | 61 | ### Commit Types 62 | 63 | | Emoji | Raw Emoji Code | Type | Description | 64 | |:--------------------------:|------------------------------|--------------------|-------------| 65 | | :star: | `:star:` | `feature` | add **new feature** | 66 | | :bug: | `:bug:` | `bug` | fix **bug** issue | 67 | | :ambulance: | `:ambulance:` | `critical-bug` | ciritial hotfix **bug** issue | 68 | | :lock: | `:lock:` | `security` | fix **security** issue | 69 | | :chart_with_upwards_trend: | `:chart_with_upwards_trend:` | `performance` | fix **performance** issue | 70 | | :zap: | `:zap:` | `improvement` | update **backwards-compatible** feature | 71 | | :boom: | `:boom:` | `breaking` | update **backwards-incompatible** feature | 72 | | :warning: | `:warning:` | `deprecated` | **deprecate** feature | 73 | | :globe_with_meridians: | `:globe_with_meridians:` | `i18n` | update or fix **internationalization** | 74 | | :wheelchair: | `:wheelchair:` | `a11y` | update or fix **accessibility** | 75 | | :lipstick: | `:lipstick:` | `ui-update` | update **UI/Cosmetic** | 76 | | :up: | `:up:` | `update` | update **other** | 77 | | :rotating_light: | `:rotating_light:` | `non-code-refactor` | remove **linter**/strict/deprecation warnings | 78 | | :shirt: | `:shirt:` | `code-refactor` | **refactoring** or code **layouting** | 79 | | :white_check_mark: | `:white_check_mark:` | `test-add` | add **tests** | 80 | | :green_heart: | `:green_heart:` | `test-fix` | fix **tests** failure or **CI** building | 81 | | :pencil: | `:pencil:` | `docs-update` | update **documentation** | 82 | | :copyright: | `:copyright:` | `licence` | decide or change **license** | 83 | | :lollipop: | `:lollipop:` | `example` | for **example** or **demo** codes | 84 | | :arrow_up: | `:arrow_up:` | `dependency-up` | upgrade **dependencies** | 85 | | :arrow_down: | `:arrow_down:` | `dependency-down` | downgrade **dependencies** | 86 | | :pushpin: | `:pushpin:` | `dependency-pin` | pin **dependencies** | 87 | | :wrench: | `:wrench:` | `config` | update **configuration** | 88 | | :package: | `:package:` | `build` | **packaging** or **bundling** or **building** | 89 | | :hatching_chick: | `:hatching_chick:` | `release-init` | **initial** commit | 90 | | :confetti_ball: | `:confetti_ball:` | `release-major` | release **major** version | 91 | | :tada: | `:tada:` | `release-minor` | release **minor** version | 92 | | :sparkles: | `:sparkles:` | `release-patch` | release **patch** version | 93 | | :rocket: | `:rocket:` | `release-deploy` | **deploy** to production enviroment | 94 | | :bookmark: | `:bookmark:` | `release-tagged` | **tagged** with version label | 95 | | :back: | `:back:` | `revert` | **revert** commiting | 96 | | :construction: | `:construction:` | `wip` | **WIP** commiting | 97 | | :truck: | `:truck:` | `move` | **move** or **rename** files, repository, ... | 98 | | :twisted_rightwards_arrows:| `:twisted_rightwards_arrows:`| `merge` | merge **conflict resolution** | 99 | | :heavy_plus_sign: | `:heavy_plus_sign:` | `add` | **add** files, dependencies, ... | 100 | | :heavy_minus_sign: | `:heavy_minus_sign:` | `remove` | **remove** files, dependencies, ... | 101 | | :on: | `:on:` | `enable` | **enable** feature and something ... | 102 | 103 | 104 | 105 | ### Author 106 | theapache64 - theapache64@gmail.com 107 | 108 | Inspired from [kazupon/git-commit-message-convention](https://github.com/kazupon/git-commit-message-convention) 109 | 110 | -------------------------------------------------------------------------------- /dictionary.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "update", 4 | "description": "Update other", 5 | "emoji": "🆙", 6 | "keywords": [ 7 | "update" 8 | ], 9 | "points": 1 10 | }, 11 | { 12 | "type": "init", 13 | "description": "Initialization of a module/screen/component", 14 | "emoji": "🌄", 15 | "keywords": [ 16 | "init", 17 | "initialize", 18 | "initialized" 19 | ], 20 | "points": 0 21 | }, 22 | { 23 | "type": "first-commit", 24 | "description": "First commit", 25 | "emoji": "🌛", 26 | "keywords": [ 27 | "first commit" 28 | ], 29 | "points": 0 30 | }, 31 | { 32 | "type": "backup", 33 | "description": "Backup source code", 34 | "emoji": "◀️", 35 | "keywords": [ 36 | "backup", 37 | "ing" 38 | ], 39 | "points": 1 40 | }, 41 | { 42 | "type": "new", 43 | "description": "Add new feature", 44 | "emoji": "🌟", 45 | "keywords": [ 46 | "add", 47 | "implement", 48 | "finish" 49 | ], 50 | "points": 1 51 | }, 52 | { 53 | "type": "bug", 54 | "description": "Fix bug issue", 55 | "emoji": "🐛", 56 | "keywords": [ 57 | "fixed", 58 | "bug", 59 | "bugs" 60 | ], 61 | "points": 0 62 | }, 63 | { 64 | "type": "critical-bug", 65 | "description": "Critical hotfix bug issue", 66 | "emoji": "🚑", 67 | "keywords": [ 68 | "bug", 69 | "critical bug" 70 | ], 71 | "points": 0 72 | }, 73 | { 74 | "type": "security", 75 | "description": "Fix security issue", 76 | "emoji": "🔒", 77 | "keywords": [], 78 | "points": 0 79 | }, 80 | { 81 | "type": "performance", 82 | "description": "Fix performance issue", 83 | "emoji": "📈", 84 | "keywords": [ 85 | "improve" 86 | ], 87 | "points": 0 88 | }, 89 | { 90 | "type": "improvement", 91 | "description": "Update backwards-compatible feature", 92 | "emoji": "⚡️", 93 | "keywords": [], 94 | "points": 0 95 | }, 96 | { 97 | "type": "breaking", 98 | "description": "Update backwards-incompatible feature", 99 | "emoji": "💥", 100 | "keywords": [], 101 | "points": 0 102 | }, 103 | { 104 | "type": "deprecated", 105 | "description": "Deprecate feature", 106 | "emoji": "⚠️", 107 | "keywords": [], 108 | "points": 0 109 | }, 110 | { 111 | "type": "i18n", 112 | "description": "Update or fix internationalization", 113 | "emoji": "🌐", 114 | "keywords": [], 115 | "points": 0 116 | }, 117 | { 118 | "type": "a11y", 119 | "description": "Update or fix accessibility", 120 | "emoji": "♿️", 121 | "keywords": [], 122 | "points": 0 123 | }, 124 | { 125 | "type": "ui-update", 126 | "description": "Update UI/Cosmetic", 127 | "emoji": "💄", 128 | "keywords": [ 129 | "ui" 130 | ], 131 | "points": 0 132 | }, 133 | { 134 | "type": "non-code-refactor", 135 | "description": "Remove linter/strict/deprecation warnings", 136 | "emoji": "🚨", 137 | "keywords": [], 138 | "points": 0 139 | }, 140 | { 141 | "type": "code-refactor", 142 | "description": "Refactoring or code layouting", 143 | "emoji": "👕", 144 | "keywords": [], 145 | "points": 0 146 | }, 147 | { 148 | "type": "test-add", 149 | "description": "Add tests", 150 | "emoji": "☑️", 151 | "keywords": [], 152 | "points": 0 153 | }, 154 | { 155 | "type": "test-fix", 156 | "description": "Fix tests failure or CI building", 157 | "emoji": "💚", 158 | "keywords": [], 159 | "points": 0 160 | }, 161 | { 162 | "type": "docs-update", 163 | "description": "Update documentation", 164 | "emoji": "📝", 165 | "keywords": [], 166 | "points": 0 167 | }, 168 | { 169 | "type": "licence", 170 | "description": "Decide or change license", 171 | "emoji": "©", 172 | "keywords": [], 173 | "points": 0 174 | }, 175 | { 176 | "type": "example", 177 | "description": "For example or demo codes", 178 | "emoji": "🍭", 179 | "keywords": [], 180 | "points": 0 181 | }, 182 | { 183 | "type": "dependency-up", 184 | "description": "Upgrade dependencies", 185 | "emoji": "⬆️", 186 | "keywords": [ 187 | "deps", 188 | "bump" 189 | ], 190 | "points": 0 191 | }, 192 | { 193 | "type": "dependency-down", 194 | "description": "Downgrade dependencies", 195 | "emoji": "⬇️", 196 | "keywords": [], 197 | "points": 0 198 | }, 199 | { 200 | "type": "dependency-pin", 201 | "description": "Pin dependencies", 202 | "emoji": "📌", 203 | "keywords": [], 204 | "points": 0 205 | }, 206 | { 207 | "type": "config", 208 | "description": "Update configuration", 209 | "emoji": "🔧", 210 | "keywords": [], 211 | "points": 0 212 | }, 213 | { 214 | "type": "build", 215 | "description": "Packaging or bundling or building", 216 | "emoji": "📦", 217 | "keywords": [], 218 | "points": 0 219 | }, 220 | { 221 | "type": "release-init", 222 | "description": "Initial commit", 223 | "emoji": "🐣", 224 | "keywords": [], 225 | "points": 0 226 | }, 227 | { 228 | "type": "release-major", 229 | "description": "Release major version", 230 | "emoji": "🎊", 231 | "keywords": [], 232 | "points": 0 233 | }, 234 | { 235 | "type": "release-minor", 236 | "description": "Release minor version", 237 | "emoji": "🎉", 238 | "keywords": [], 239 | "points": 0 240 | }, 241 | { 242 | "type": "release-patch", 243 | "description": "Release patch version", 244 | "emoji": "✨", 245 | "keywords": [], 246 | "points": 0 247 | }, 248 | { 249 | "type": "release-production", 250 | "description": "Deploy to production enviroment", 251 | "emoji": "🚀", 252 | "keywords": [], 253 | "points": 0 254 | }, 255 | { 256 | "type": "release-bookmark", 257 | "description": "Tagged with version label", 258 | "emoji": "🔖", 259 | "keywords": [], 260 | "points": 0 261 | }, 262 | { 263 | "type": "revert", 264 | "description": "Revert commiting", 265 | "emoji": "🔙", 266 | "keywords": [], 267 | "points": 0 268 | }, 269 | { 270 | "type": "wip", 271 | "description": "WIP commiting", 272 | "emoji": "🚧", 273 | "keywords": [], 274 | "points": 0 275 | }, 276 | { 277 | "type": "move", 278 | "description": "Move or rename files, repository, ...", 279 | "emoji": "🚚", 280 | "keywords": [], 281 | "points": 0 282 | }, 283 | { 284 | "type": "merge", 285 | "description": "Merge conflict resolution", 286 | "emoji": "🔀", 287 | "keywords": [ 288 | "conflicts" 289 | ], 290 | "points": 0 291 | }, 292 | { 293 | "type": "add", 294 | "description": "Add files, dependencies, ...", 295 | "emoji": "➕", 296 | "keywords": [ 297 | "added" 298 | ], 299 | "points": 0 300 | }, 301 | { 302 | "type": "remove", 303 | "description": "Remove files, dependencies, ...", 304 | "emoji": "➖", 305 | "keywords": [ 306 | "removed" 307 | ], 308 | "points": 0 309 | }, 310 | { 311 | "type": "enable", 312 | "description": "Enable feature and something ...", 313 | "emoji": "🔛", 314 | "keywords": [], 315 | "points": 0 316 | }, 317 | { 318 | "type": "readme", 319 | "description": "Update README", 320 | "emoji": "📖", 321 | "keywords": [ 322 | "updated readme" 323 | ], 324 | "points": 0 325 | } 326 | ] -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 43 | 44 | 49 | 50 | 51 | 52 | 53 | 54 | 56 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 1549617840252 92 | 111 | 112 | 113 | 114 | 116 | 117 | 118 | 119 | 120 | 121 | ugh:jar 122 | 123 | 129 | 130 | 131 | 132 | 133 | 134 | No facets are configured 135 | 136 | 141 | 142 | 143 | 144 | 145 | 146 | jmsm 147 | 148 | 153 | 154 | 155 | 156 | 157 | 158 | 1.8 159 | 160 | 165 | 166 | 167 | 168 | 169 | 170 | ugh 171 | 172 | 178 | 179 | 180 | 181 | 182 | 183 | com.squareup.moshi:moshi-kotlin:1.8.0 184 | 185 | 190 | 191 | 192 | 193 | 194 | 195 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------