├── .all-contributorsrc
├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ └── ci.yml
├── .gitignore
├── .gitmojirc
├── .huskyrc
├── .lintstagedrc
├── .node-version
├── .npmrc
├── .nycrc
├── .prettierignore
├── .prettierrc
├── .vscode
└── settings.json
├── LICENSE
├── README-jp.md
├── README.md
├── ava.config.js
├── gifs
├── commit.gif
├── init.gif
├── list.gif
├── remove.gif
└── search.gif
├── package.json
├── renovate.json
├── src
├── commands
│ ├── commit
│ │ ├── index.ts
│ │ ├── withClient.ts
│ │ └── withHook.ts
│ ├── hook
│ │ ├── create
│ │ │ └── index.ts
│ │ ├── hook.ts
│ │ ├── index.ts
│ │ └── remove
│ │ │ └── index.ts
│ ├── index.ts
│ └── list
│ │ └── index.ts
└── index.ts
├── tsconfig.json
└── yarn.lock
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "customizable-gitmoji-cli",
3 | "projectOwner": "SnO2WMaN",
4 | "repoType": "github",
5 | "repoHost": "https://github.com",
6 | "files": ["README.md", "README-jp.md"],
7 | "imageSize": 100,
8 | "commit": true,
9 | "commitConvention": "gitmoji",
10 | "contributors": [
11 | {
12 | "login": "SnO2WMaN",
13 | "name": "SnO₂WMaN",
14 | "avatar_url": "https://avatars3.githubusercontent.com/u/15155608?v=4",
15 | "profile": "https://sno2wman.dev/",
16 | "contributions": ["code", "maintenance"]
17 | },
18 | {
19 | "login": "renovate-bot",
20 | "name": "Renovate Bot",
21 | "avatar_url": "https://avatars0.githubusercontent.com/u/25180681?v=4",
22 | "profile": "https://renovatebot.com",
23 | "contributions": ["infra"]
24 | },
25 | {
26 | "login": "carloscuesta",
27 | "name": "Carlos Cuesta",
28 | "avatar_url": "https://avatars1.githubusercontent.com/u/7629661?v=4",
29 | "profile": "https://carloscuesta.me",
30 | "contributions": ["ideas"]
31 | },
32 | {
33 | "login": "0918nobita",
34 | "name": "0918nobita",
35 | "avatar_url": "https://avatars1.githubusercontent.com/u/8453302?v=4",
36 | "profile": "https://twitter.com/0918nobita",
37 | "contributions": ["bug", "security"]
38 | }
39 | ],
40 | "contributorsPerLine": 7
41 | }
42 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | [*]
3 | indent_style = space
4 | indent_size = 2
5 | end_of_line = lf
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 |
10 | [*.yml]
11 | indent_style = space
12 |
13 | [.node-version]
14 | insert_final_newline = false
15 |
16 | [*.md]
17 | trim_trailing_whitespace = false
18 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
3 | dist/
4 | lib/
5 |
6 | coverage/
7 | snapshots/
8 |
9 | .nyc_output/
10 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "extends": [
4 | "@sno2wman/eslint-config-typescript",
5 | "@sno2wman/eslint-config/+ava"
6 | ],
7 | "parserOptions": {
8 | "project": "./tsconfig.json"
9 | },
10 | "settings": {
11 | "import/resolver": {
12 | "typescript": {
13 | "alwaysTryTypes": true
14 | }
15 | }
16 | },
17 | "rules": {
18 | "import/extensions": 0,
19 | "unicorn/filename-case": [
20 | 2,
21 | { "cases": { "pascalCase": true, "camelCase": true } }
22 | ],
23 | "unicorn/no-process-exit": 0,
24 | "@typescript-eslint/restrict-template-expressions": [
25 | 2,
26 | { "allowNumber": true }
27 | ]
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: SnO2WMaN
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: SnO2WMaN
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Hello @SnO2WMaN!
2 |
3 | ### Issue
4 |
5 | ### Env
6 |
7 | - **OS**:
8 | - **gitmoji-cli -v**:
9 | - **node -v**:
10 |
11 | ### .gitmojirc
12 |
13 | ```json
14 |
15 | ```
16 |
17 | ### Error message
18 |
19 | ```
20 |
21 | ```
22 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Description
2 |
3 | Issue: #
4 |
5 | ## Tests
6 |
7 | - [ ] All tests passed.
8 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Node CI
2 |
3 | on: [push]
4 |
5 | jobs:
6 | default:
7 | runs-on: ubuntu-latest
8 | env:
9 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
10 | steps:
11 | - uses: actions/checkout@v1
12 | - name: Get Node.js version
13 | id: node-version
14 | run: echo "::set-output name=version::$(cat .node-version)"
15 | - name: Setup Node.js
16 | uses: actions/setup-node@v1
17 | with:
18 | node-version: ${{ steps.node-version.version }}
19 | - name: Setup yarn
20 | run: |
21 | curl -o- -L https://yarnpkg.com/install.sh | bash
22 | export PATH="$HOME/.yarn/bin:$PATH"
23 | - name: Get yarn cache dir
24 | id: yarn-cache
25 | run: echo "::set-output name=dir::$(yarn cache dir)"
26 | - name: Cache
27 | uses: actions/cache@v1
28 | with:
29 | path: ${{ steps.yarn-cache.outputs.dir }}
30 | key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
31 | restore-keys: |
32 | ${{ runner.os }}-yarn-
33 | - name: Install dependencies
34 | run: yarn --frozen-lockfile
35 | - name: Lint
36 | run: npm run lint
37 | env:
38 | CI: true
39 | - name: Build
40 | run: npm run build
41 | env:
42 | CI: true
43 | - name: Codecov
44 | run: npx codecov
45 | env:
46 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
47 | - name: Publish
48 | run: npm publish
49 | if: contains(github.ref, 'tags/v')
50 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
3 | dist/
4 | lib/
5 |
6 | coverage/
7 |
8 | .env
9 | .envrc
10 |
11 | *.log
12 | *.cache
13 |
14 | .nyc_output/
15 |
--------------------------------------------------------------------------------
/.gitmojirc:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "gitmojis": [
4 | {
5 | "emoji": "✨",
6 | "description": "Introduce new features.",
7 | "name": "sparkles",
8 | "tags": [
9 | "feat"
10 | ]
11 | },
12 | {
13 | "emoji": "👍",
14 | "description": "Improve features.",
15 | "name": "thumbsup",
16 | "tags": [
17 | "improve",
18 | "update"
19 | ]
20 | },
21 | {
22 | "emoji": "⚡️",
23 | "description": "Update about performance.",
24 | "name": "zap",
25 | "tags": [
26 | "performance"
27 | ]
28 | },
29 | {
30 | "emoji": "🐛",
31 | "description": "Fix bugs.",
32 | "name": "bug",
33 | "tags": [
34 | "bug",
35 | "fix"
36 | ]
37 | },
38 | {
39 | "emoji": "🚑",
40 | "description": "Create a hotfix.",
41 | "name": "ambulance",
42 | "tags": [
43 | "bug",
44 | "fix",
45 | "hotfix"
46 | ]
47 | },
48 | {
49 | "emoji": "♻️",
50 | "description": "Refactor codes.",
51 | "name": "recycle",
52 | "tags": [
53 | "refactor"
54 | ]
55 | },
56 | {
57 | "emoji": "🔧",
58 | "description": "Update configurations.",
59 | "name": "wrench",
60 | "tags": [
61 | "config",
62 | "setting"
63 | ],
64 | "scopes": [
65 | "eslint",
66 | "stylelint",
67 | "prettier",
68 | "lint-staged",
69 | "husky",
70 | "gitmoji",
71 | "typescript"
72 | ]
73 | },
74 | {
75 | "emoji": "🎨",
76 | "description": "Update UI/UX.",
77 | "name": "art",
78 | "tags": [
79 | "ui",
80 | "ux"
81 | ]
82 | },
83 | {
84 | "emoji": "🔥",
85 | "description": "Remove codes.",
86 | "name": "fire",
87 | "tags": [
88 | "remove"
89 | ]
90 | },
91 | {
92 | "emoji": "🚨",
93 | "description": "Add/Update tests.",
94 | "name": "warning",
95 | "tags": [
96 | "test"
97 | ]
98 | },
99 | {
100 | "emoji": "🏗",
101 | "description": "Update structures.",
102 | "name": "building_construction",
103 | "tags": [
104 | "structure"
105 | ]
106 | },
107 | {
108 | "emoji": "🔒",
109 | "description": "Update security.",
110 | "name": "lock",
111 | "tags": [
112 | "security"
113 | ]
114 | },
115 | {
116 | "emoji": "🚥",
117 | "description": "Resolve Linter warning.",
118 | "name": "traffic_light",
119 | "tags": [
120 | "lint"
121 | ]
122 | },
123 | {
124 | "emoji": "🚧",
125 | "description": "Work in progress.",
126 | "name": "construction",
127 | "tags": [
128 | "wip"
129 | ]
130 | },
131 | {
132 | "emoji": "⚓️",
133 | "description": "Salvage old features.",
134 | "name": "anchor",
135 | "tags": [
136 | "salvage"
137 | ]
138 | },
139 | {
140 | "emoji": "💥",
141 | "description": "make a breaking change.",
142 | "name": "boom",
143 | "tags": [
144 | "breaking"
145 | ]
146 | },
147 | {
148 | "emoji": "🧪",
149 | "description": "Add experimental features.",
150 | "name": "test_tube",
151 | "tags": [
152 | "beta",
153 | "experimental"
154 | ]
155 | },
156 | {
157 | "emoji": "👷",
158 | "description": "Maintain infrastructure.",
159 | "name": "construction_worker",
160 | "tags": [
161 | "infra",
162 | "ci"
163 | ],
164 | "scopes": [
165 | "circle ci",
166 | "renovate",
167 | "github actions"
168 | ]
169 | },
170 | {
171 | "emoji": "🌐",
172 | "description": "Translate.",
173 | "name": "globe_with_meridians",
174 | "tags": [
175 | "translate",
176 | "i18n",
177 | "l10n"
178 | ],
179 | "scopes": [
180 | {
181 | "name": "ja",
182 | "description": "Japanese"
183 | },
184 | {
185 | "name": "en",
186 | "description": "English"
187 | }
188 | ]
189 | },
190 | {
191 | "emoji": "📖",
192 | "description": "Write docs.",
193 | "name": "open_book",
194 | "tags": [
195 | "docs",
196 | "readme"
197 | ]
198 | },
199 | {
200 | "emoji": "💬",
201 | "description": "Update literal or text.",
202 | "name": "speech_balloon",
203 | "tags": [
204 | "text",
205 | "literal"
206 | ]
207 | },
208 | {
209 | "emoji": "🚚",
210 | "description": "Transfer files.",
211 | "name": "truck",
212 | "tags": [
213 | "move"
214 | ]
215 | },
216 | {
217 | "emoji": "🍱",
218 | "description": "Add assets.",
219 | "name": "bento",
220 | "tags": [
221 | "assets",
222 | "images"
223 | ]
224 | },
225 | {
226 | "emoji": "📷",
227 | "description": "Update snapshots.",
228 | "name": "camera",
229 | "tags": [
230 | "snapshots",
231 | "test"
232 | ]
233 | },
234 | {
235 | "emoji": "🧹",
236 | "description": "Format codes.",
237 | "name": "bloom",
238 | "tags": [
239 | "format",
240 | "prettier"
241 | ]
242 | },
243 | {
244 | "emoji": "⬆️",
245 | "description": "Updgrade dependencies.",
246 | "name": "arrow_up",
247 | "tags": [
248 | "dependencies",
249 | "upgrade"
250 | ]
251 | },
252 | {
253 | "emoji": "⬇️",
254 | "description": "Downgrade dependencies.",
255 | "name": "arrow_down",
256 | "tags": [
257 | "dependencies",
258 | "downgrade"
259 | ]
260 | },
261 | {
262 | "emoji": "➕",
263 | "description": "Add dependencies.",
264 | "name": "heavy_plus_sign",
265 | "tags": [
266 | "dependencies",
267 | "add"
268 | ]
269 | },
270 | {
271 | "emoji": "➖",
272 | "description": "Remove dependencies.",
273 | "name": "heavy_minus_sign",
274 | "tags": [
275 | "dependencies",
276 | "remove"
277 | ]
278 | },
279 | {
280 | "emoji": "📌",
281 | "description": "Pin dependencies to specific versions.",
282 | "name": "pushpin",
283 | "tags": [
284 | "dependencies",
285 | "pin"
286 | ]
287 | },
288 | {
289 | "emoji": "🆗",
290 | "description": "OK for the review.",
291 | "name": "ok",
292 | "tags": [
293 | "review"
294 | ]
295 | },
296 | {
297 | "emoji": "⏪",
298 | "description": "Revert changes.",
299 | "name": "rewind",
300 | "tags": [
301 | "rewind"
302 | ]
303 | },
304 | {
305 | "emoji": "🔀",
306 | "description": "Merge branches.",
307 | "name": "twisted_rightwards_arrows",
308 | "tags": [
309 | "merge"
310 | ]
311 | },
312 | {
313 | "emoji": "📄",
314 | "description": "Attach a license.",
315 | "name": "page_facing_up",
316 | "tags": [
317 | "license"
318 | ]
319 | },
320 | {
321 | "emoji": "🔖",
322 | "description": "Release.",
323 | "name": "bookmark",
324 | "tags": [
325 | "version"
326 | ]
327 | },
328 | {
329 | "emoji": "🚀",
330 | "description": "Deploy.",
331 | "name": "rocket",
332 | "tags": [
333 | "deploy"
334 | ]
335 | },
336 | {
337 | "emoji": "🙈",
338 | "description": "Ignore things.",
339 | "name": "see_no_evil",
340 | "tags": [
341 | "ignore"
342 | ]
343 | },
344 | {
345 | "emoji": "👥",
346 | "description": "Add a contributor.",
347 | "name": "busts_in_silhouette",
348 | "tags": [
349 | "contributor"
350 | ]
351 | },
352 | {
353 | "emoji": "💵",
354 | "description": "Add financial things.",
355 | "name": "dollar",
356 | "tags": [
357 | "funding"
358 | ]
359 | },
360 | {
361 | "emoji": "🔺",
362 | "description": "Use as a commit separator.",
363 | "name": "small_red_triangle"
364 | },
365 | {
366 | "emoji": "🎉",
367 | "description": "Init.",
368 | "name": "tada",
369 | "tags": [
370 | "init"
371 | ]
372 | }
373 | ]
374 | }
375 |
--------------------------------------------------------------------------------
/.huskyrc:
--------------------------------------------------------------------------------
1 | {
2 | "hooks": {
3 | "pre-commit": "lint-staged"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/.lintstagedrc:
--------------------------------------------------------------------------------
1 | {
2 | "*.md": [
3 | "prettier --write",
4 | "git add"
5 | ],
6 | "*.{js,ts}": [
7 | "eslint --fix",
8 | "prettier --write",
9 | "git add"
10 | ],
11 | "*.yml": [
12 | "prettier --write",
13 | "git add"
14 | ],
15 | "*.json": [
16 | "prettier --write",
17 | "git add"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/.node-version:
--------------------------------------------------------------------------------
1 | 12.14.0
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | message="🔖 %s"
2 | //registry.npmjs.org/:_authToken=${NPM_TOKEN}
3 |
--------------------------------------------------------------------------------
/.nycrc:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["src/**/*.ts"],
3 | "extension": [".ts"],
4 | "require": ["ts-node/register"],
5 | "reporter": ["text", "text-summary", "html"],
6 | "sourceMap": true
7 | }
8 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
3 | dist/
4 | lib/
5 |
6 | coverage/
7 | snapshots/
8 |
9 | .nyc_output/
10 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | "@sno2wman/prettier-config"
2 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "node_modules/typescript/lib"
3 | }
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 SnO₂WMaN
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 |
--------------------------------------------------------------------------------
/README-jp.md:
--------------------------------------------------------------------------------
1 |
customizable-gitmoji-cli
2 |
3 | カスタマイズ可能なgitmoji-cli!
4 |
5 | ---
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | [](https://github.com/SnO2WMaN/customizable-gitmoji-cli/actions)
14 | [](https://codecov.io/gh/SnO2WMaN/customizable-gitmoji-cli)
15 | [](https://codeclimate.com/github/SnO2WMaN/customizable-gitmoji-cli/maintainability)
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | [](https://www.npmjs.com/package/@conten2/eslint-config)
24 | [](https://renovatebot.com/)
25 | [](https://gitmoji.carloscuesta.me)
26 | [](https://github.com/prettier/prettier)
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | [](#contributors-)
37 |
38 |
39 |
40 |
41 |
42 |
43 | ---
44 |
45 |
46 |
47 |
48 |
49 | [日本語](https://github.com/SnO2WMaN/customizable-gitmoji-cli/blob/master/README-jp.md) / [English](https://github.com/SnO2WMaN/customizable-gitmoji-cli#readme)
50 |
51 | **この`README-jp.md`を「正しい」英語に訳してくれる人間を探しています。**
52 |
53 |
54 |
55 |
56 |
57 | ---
58 |
59 | ## インストール 📥
60 |
61 | ```bash
62 | npm i -g customizable-gitmoji-cli
63 |
64 | yarn global add customizable-gitmoji-cli
65 | ```
66 |
67 | 挙動について保証出来ないので、オリジナルの gitmoji-cli はアンインストールしてください。
68 |
69 | ```bash
70 | npm uninstall -g gitmoji-cli
71 |
72 | yarn global remove gitmoji-cli
73 | ```
74 |
75 | ## 使用方法 🧰
76 |
77 | 任意の git プロジェクトで以下のコマンドを叩いてください。
78 |
79 | ```bash
80 | gitmoji init
81 | ```
82 |
83 | 
84 |
85 | コミット時に自動で gitmoji-cli が起動します。
86 |
87 | 
88 |
89 | ## コマンド ⌨️
90 |
91 | ```
92 | gitmoji v1.0.0
93 |
94 | Usage:
95 | $ gitmoji [options]
96 |
97 | Commands:
98 | init Initialize gitmoji as a commit hook
99 | remove Remove a previously initialized commit hook
100 | commit Interactively commit using the prompts
101 | list List all the available gitmojis
102 | search [query] Search gitmojis
103 |
104 | For more info, run any command with the `--help` flag:
105 | $ gitmoji init --help
106 | $ gitmoji remove --help
107 | $ gitmoji commit --help
108 | $ gitmoji list --help
109 | $ gitmoji search --help
110 |
111 | Options:
112 | -v, --version Display version number
113 | -h, --help Display this message
114 | ```
115 |
116 | ### init
117 |
118 | コミット時に gitmoji プロンプトを起動するようにフックを掛けます。
119 |
120 | ### remove
121 |
122 | コミット時に起動する gitmoji プロンプトを解除します。
123 |
124 | ### commit
125 |
126 | gitmoji プロンプトをマニュアルで実行します。
127 |
128 | 特に理由がなければ `gitmoji init`でフックを掛けてください。
129 |
130 | ### list
131 |
132 | `.gitmojirc`から利用可能な全ての gitmoji を列挙します。
133 |
134 | 
135 |
136 | ### search
137 |
138 | 条件に合致する gitmoji を探します。
139 |
140 | 
141 |
142 | ## コンフィグファイル 🔧
143 |
144 | [cosmiconfig](https://github.com/davidtheclark/cosmiconfig)に基づいて、`.gitmojirc`などの設定ファイルを読み込みます。
145 |
146 | ### 例
147 |
148 | ```json
149 | {
150 | "emojiFormat": "code",
151 | "autoAdd": false,
152 | "signedCommit": false,
153 | "titleMaxLength": 48,
154 | "presets": "base"
155 | "rules": [
156 | {
157 | "emoji": "🤡",
158 | "description": "Everything must go!!",
159 | "name": "clown_face"
160 | }
161 | ],
162 | "order": [
163 | "ok_hand"
164 | ],
165 | "scopes": ["frontend", "backend"]
166 | }
167 | ```
168 |
169 | ### `emojiFormat`
170 |
171 | コミット時に添付される絵文字のフォーマットを選択できます。
172 |
173 | - emoji
174 | - 👌, 🐶, 🔪
175 | - code
176 | - `:ok_hand:`, `:dog:`, `:knife:`
177 |
178 | のどちらかを使用できます。
179 |
180 | **デフォルト**: `code`
181 |
182 | ### `autoAdd`
183 |
184 | コミット時に自動で`git add .`を実行します。
185 |
186 | **デフォルト**: `false`
187 |
188 | ### `signedCommit`
189 |
190 | 署名付きコミットを行います。
191 |
192 | **デフォルト**: `false`
193 |
194 | ### `titleMaxLength`
195 |
196 | コミットメッセージの長さを設定します。72 文字以下で設定してください。
197 |
198 | **デフォルト**: `48`
199 |
200 | ### `presets`
201 |
202 | 読み込む`gitmoji-presets`を列挙します。
203 |
204 | **デフォルト**: `base`
205 |
206 | **TODO:詳細は今後記載します。**
207 |
208 | ### `rules`
209 |
210 | gitmoji を定義します。以下のように記載してください。
211 |
212 | [ikatyang/emoji-cheat-sheet](https://github.com/ikatyang/emoji-cheat-sheet)は役に立つでしょう。
213 |
214 | ```json
215 | {
216 | "emoji": "🦍",
217 | "description": "Feel good.",
218 | "name": "gorilla"
219 | }
220 | ```
221 |
222 | ### `order`
223 |
224 | 順序を指定します。指定された gitmoji はより優先されます。
225 |
226 | ### `scopes`
227 |
228 | 選択できるスコープを列挙します。スコープを指定した場合、以下のようなコミットメッセージになります。
229 |
230 | ```
231 | 📷(scope) commit message.
232 |
233 | :camera:(scope) commit message.
234 | ```
235 |
236 | ## Contributors 👥
237 |
238 | 以下の方々には感謝しかありません ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
239 |
240 |
241 |
242 |
243 |
251 |
252 |
253 |
254 |
255 |
256 |
257 | このプロジェクトは [all-contributors](https://github.com/all-contributors/all-contributors) に準拠しています。どのような貢献もお待ちしています!
258 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | customizable-gitmoji-cli
2 |
3 | Customizable gitmoji-cli.
4 |
5 | ---
6 |
7 |
8 |
9 |
10 |
11 | [](https://www.npmjs.com/package/customizable-gitmoji-cli)
12 |
13 |
14 |
15 |
16 | [](https://github.com/SnO2WMaN/customizable-gitmoji-cli/actions)
17 | [](https://codecov.io/gh/SnO2WMaN/customizable-gitmoji-cli)
18 |
19 |
20 |
21 |
22 | [](https://github.com/SnO2WMaN/customizable-gitmoji-cli/blob/master/LICENSE)
23 | [](https://renovatebot.com/)
24 | [](https://gitmoji.carloscuesta.me)
25 | [](https://github.com/prettier/prettier)
26 |
27 |
28 |
29 |
30 |
31 |
32 | [](#contributors-)
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | ---
41 |
42 | ## Contributors ✨
43 |
44 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
45 |
46 |
47 |
48 |
49 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
64 |
--------------------------------------------------------------------------------
/ava.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | compileEnhancements: false,
3 | extensions: ['ts'],
4 | require: ['ts-node/register', 'tsconfig-paths/register']
5 | }
6 |
--------------------------------------------------------------------------------
/gifs/commit.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SnO2WMaN/customizable-gitmoji-cli/5b05f0ab1d28534df783b9aa538bd42fcd41489a/gifs/commit.gif
--------------------------------------------------------------------------------
/gifs/init.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SnO2WMaN/customizable-gitmoji-cli/5b05f0ab1d28534df783b9aa538bd42fcd41489a/gifs/init.gif
--------------------------------------------------------------------------------
/gifs/list.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SnO2WMaN/customizable-gitmoji-cli/5b05f0ab1d28534df783b9aa538bd42fcd41489a/gifs/list.gif
--------------------------------------------------------------------------------
/gifs/remove.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SnO2WMaN/customizable-gitmoji-cli/5b05f0ab1d28534df783b9aa538bd42fcd41489a/gifs/remove.gif
--------------------------------------------------------------------------------
/gifs/search.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SnO2WMaN/customizable-gitmoji-cli/5b05f0ab1d28534df783b9aa538bd42fcd41489a/gifs/search.gif
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "customizable-gitmoji-cli",
3 | "description": "Customizable gitmoji cli",
4 | "license": "MIT",
5 | "author": "SnO2WMaN (https://sno2wman.dev)",
6 | "homepage": "https://github.com/SnO2WMaN/customizable-gitmoji-cli#readme",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/SnO2WMaN/customizable-gitmoji-cli.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/SnO2WMaN/customizable-gitmoji-cli/issues"
13 | },
14 | "version": "2.0.0-3",
15 | "bin": {
16 | "cz-gitmoji": "lib/index.js"
17 | },
18 | "files": [
19 | "lib"
20 | ],
21 | "dependencies": {
22 | "cac": "^6.5.3",
23 | "chalk": "^3.0.0",
24 | "cosmiconfig": "^6.0.0",
25 | "customizable-gitmoji-config-parser": "^0.0.1",
26 | "execa": "^4.0.0",
27 | "fs-extra": "^8.1.0",
28 | "inquirer": "6.5.2",
29 | "inquirer-autocomplete-prompt": "^1.0.1",
30 | "ora": "^4.0.3",
31 | "update-notifier": "^4.0.0"
32 | },
33 | "devDependencies": {
34 | "@sno2wman/eslint-config": "^1.0.3",
35 | "@sno2wman/eslint-config-typescript": "^1.0.3",
36 | "@sno2wman/gitmoji-preset": "^1.0.1",
37 | "@sno2wman/prettier-config": "^1.0.2",
38 | "@sno2wman/prettier-package-json": "^2.0.2",
39 | "@types/cosmiconfig": "^5.0.3",
40 | "@types/fs-extra": "^8.0.1",
41 | "@types/inquirer": "^6.5.0",
42 | "@types/update-notifier": "^2.5.0",
43 | "all-contributors-cli": "^6.9.3",
44 | "ava": "^2.4.0",
45 | "codecov": "^3.6.1",
46 | "cpx": "^1.5.0",
47 | "eslint": "^6.5.1",
48 | "husky": "^3.0.8",
49 | "lint-staged": "^9.4.1",
50 | "nyc": "^14.1.1",
51 | "prettier": "^1.18.2",
52 | "rimraf": "^3.0.0",
53 | "ts-node": "^8.5.4",
54 | "tsconfig-paths": "^3.9.0",
55 | "typescript": "^3.7.3"
56 | },
57 | "keywords": [
58 | "commit",
59 | "emoji",
60 | "gitmoji"
61 | ],
62 | "engines": {
63 | "node": ">=10"
64 | },
65 | "scripts": {
66 | "prebuild": "rimraf lib",
67 | "build": "tsc",
68 | "postbuild": "cpx 'lib/src/**' lib && rimraf lib/{src,test} lib/package.json",
69 | "fmt": "prettier **/*.{js,json,yml,md} --write",
70 | "lint": "eslint src . --ext .js,.ts --fix",
71 | "test": "nyc ava",
72 | "contributors:add": "all-contributors add",
73 | "contributors:generate": "all-contributors generate",
74 | "postversion": "git push origin --tags"
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "github>sno2wman/renovate-config",
4 | ":timezone(Asia/Tokyo)",
5 | "schedule:weekly"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/src/commands/commit/index.ts:
--------------------------------------------------------------------------------
1 | import chalk from 'chalk'
2 | import inquirer from 'inquirer'
3 | import { GitmojiConfig } from 'customizable-gitmoji-config-parser'
4 |
5 | import withClient from './withClient'
6 | import withHook from './withHook'
7 |
8 | // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
9 | inquirer.registerPrompt('autocomplete', require('inquirer-autocomplete-prompt'))
10 |
11 | export default async (config: GitmojiConfig, hook: boolean) => {
12 | const longestDescription = config
13 | .list()
14 | .reduce((c, { description }) => Math.max(c, description.length), 0)
15 | const gitmojiAnswer = (
16 | await inquirer.prompt([
17 | {
18 | name: 'gitmoji',
19 | message: 'Choose a gitmoji:',
20 | type: 'autocomplete',
21 | source: (_: any, input?: string) =>
22 | Promise.resolve(
23 | (input && input !== '' ? config.search(input) : config.list()).map(
24 | ({ emoji, name, description, tags }) => ({
25 | name: [
26 | emoji,
27 | ' '.repeat(2),
28 | ' │ ',
29 | description,
30 | ' '.repeat(longestDescription - description.length),
31 | ' │ ',
32 | tags.length === 0
33 | ? chalk.italic.grey('None')
34 | : tags.map(tag => chalk.italic.blue(`${tag}`)).join(', ')
35 | ].join(''),
36 | value: name
37 | })
38 | )
39 | )
40 | }
41 | ])
42 | ).gitmoji as string
43 | const details = config.getByName(gitmojiAnswer)
44 | const longestScope = details.scopes.reduce(
45 | (c, { name }) => Math.max(c, name.length),
46 | 0
47 | )
48 | let scopeAnswer = (
49 | await inquirer.prompt([
50 | {
51 | name: 'scope',
52 | message: 'Choose a scope:',
53 | type: 'list',
54 | choices: [
55 | ...details.scopes.map(({ name, description }) => ({
56 | name: [
57 | name,
58 | ' '.repeat(longestScope - name.length),
59 | ' │ ',
60 | description === ''
61 | ? chalk.gray('No description')
62 | : chalk.blue(description)
63 | ].join(''),
64 | value: name
65 | })),
66 | new inquirer.Separator(),
67 | { name: 'Custom.', value: '_custom' },
68 | { name: 'None.', value: null }
69 | ]
70 | }
71 | ])
72 | ).scope as string | null
73 | if (scopeAnswer === '_custom') {
74 | scopeAnswer = (
75 | await inquirer.prompt([
76 | {
77 | name: 'scope',
78 | message: 'Input custom scope:',
79 | type: 'input',
80 | validate: (scope: string) =>
81 | !scope ? chalk.red('Enter a valid scope') : true
82 | }
83 | ])
84 | ).scope
85 | }
86 | const maxTitleLength =
87 | 72 -
88 | (config.emojiFormat === 'code' ? gitmojiAnswer.length : 1) - // emoji
89 | (scopeAnswer ? scopeAnswer.length + 2 : 0) - // scope
90 | 1 // space
91 | const titleAnswer = (
92 | await inquirer.prompt([
93 | {
94 | name: 'title',
95 | message: 'Enter the commit title',
96 | validate: (title: string) =>
97 | !title ? chalk.red('Enter a valid commit title') : true,
98 | transformer: (input: string) => {
99 | return `[${input.length}/${maxTitleLength}]: ${input}`
100 | }
101 | }
102 | ])
103 | ).title as string
104 | const commitTitle = [
105 | config.emojiFormat === 'code' ? details.name : details.emoji,
106 | scopeAnswer ? `(${scopeAnswer})` : '',
107 | ' ',
108 | titleAnswer
109 | ]
110 | .join('')
111 | .trim()
112 |
113 | if (hook) withHook(commitTitle)
114 | else await withClient(config, commitTitle)
115 | }
116 |
--------------------------------------------------------------------------------
/src/commands/commit/withClient.ts:
--------------------------------------------------------------------------------
1 | import execa from 'execa'
2 | import { GitmojiConfig } from 'customizable-gitmoji-config-parser'
3 |
4 | export default async (config: GitmojiConfig, title: string) => {
5 | try {
6 | if (config.autoAdd) await execa('git', ['add', '.'])
7 | const { stdout } = await execa('git', [
8 | 'commit',
9 | ...(config.signedCommit ? ['-S'] : []),
10 | '-m',
11 | `${title}`
12 | ])
13 | console.log(stdout)
14 | } catch (error) {
15 | console.error(error)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/commands/commit/withHook.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs-extra'
2 |
3 | export default (title: string) => {
4 | try {
5 | fs.writeFileSync(process.argv[3], `${title}`)
6 | } catch (error) {
7 | console.error(error)
8 | process.exit(1)
9 | } finally {
10 | process.exit(0)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/commands/hook/create/index.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs-extra'
2 | import execa from 'execa'
3 | import ora from 'ora'
4 |
5 | import hook from '../hook'
6 |
7 | export default async () => {
8 | const spinner = ora('Creating the gitmoji commit hook').start()
9 |
10 | try {
11 | const { stdout } = await execa('git', ['rev-parse', '--absolute-git-dir'])
12 | await fs.writeFile(stdout + hook.path, hook.contents, {
13 | mode: hook.permissions
14 | })
15 | spinner.succeed('Gitmoji commit hook created successfully')
16 | } catch (error) {
17 | spinner.fail(`Error: ${String(error)}`)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/commands/hook/hook.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | permissions: 0o775,
3 | path: '/hooks/prepare-commit-msg',
4 | contents:
5 | '#!/bin/sh\n# gitmoji as a commit hook\nexec < /dev/tty\ncz-gitmoji commit --hook $1\n'
6 | }
7 |
--------------------------------------------------------------------------------
/src/commands/hook/index.ts:
--------------------------------------------------------------------------------
1 | import create from './create'
2 | import remove from './remove'
3 |
4 | export default { create, remove }
5 |
--------------------------------------------------------------------------------
/src/commands/hook/remove/index.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs-extra'
2 | import execa from 'execa'
3 | import ora from 'ora'
4 |
5 | import hook from '../hook'
6 |
7 | export default async () => {
8 | const spinner = ora('Creating the gitmoji commit hook').start()
9 |
10 | try {
11 | const { stdout } = await execa('git', ['rev-parse', '--absolute-git-dir'])
12 | await fs.unlink(stdout + hook.path)
13 | spinner.succeed('Gitmoji commit hook removed successfully')
14 | } catch (error) {
15 | spinner.fail(`Error: ${String(error)}`)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/commands/index.ts:
--------------------------------------------------------------------------------
1 | import list from './list'
2 | import hook from './hook'
3 | import commit from './commit'
4 |
5 | export default {
6 | list,
7 | init: hook.create,
8 | remove: hook.remove,
9 | commit
10 | }
11 |
--------------------------------------------------------------------------------
/src/commands/list/index.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | import chalk from 'chalk'
3 |
4 | import { GitmojiConfig } from 'customizable-gitmoji-config-parser'
5 |
6 | export default async function(config: GitmojiConfig) {
7 | const list = config.list()
8 | const longestName = list.reduce((c, { name }) => Math.max(c, name.length), 0)
9 | const longestDescription = list.reduce(
10 | (c, { description }) => Math.max(c, description.length),
11 | 0
12 | )
13 | const separator = ` ${chalk.grey('│')} `
14 | list.forEach(({ emoji, name, description, tags, scopes }) => {
15 | console.log(
16 | [
17 | emoji,
18 | ' '.repeat(2),
19 | chalk.bold.cyan(`:${name}:`),
20 | ' '.repeat(longestName - name.length),
21 | separator,
22 | description,
23 | ' '.repeat(longestDescription - description.length),
24 | separator,
25 | tags.length === 0
26 | ? chalk.italic.grey('None')
27 | : tags.map(tag => chalk.italic.blue(`${tag}`)).join(', ')
28 | ].join('')
29 | )
30 | const longestScope = scopes.reduce(
31 | (c, { name: scopeName }) => Math.max(c, scopeName.length),
32 | 0
33 | )
34 | scopes.forEach(({ name: scopeName, description: scopeDescription }, i) => {
35 | console.log(
36 | [
37 | i === scopes.length - 1 ? '└' : '├',
38 | '─ ',
39 | chalk.blue(`(${scopeName})`),
40 | ' '.repeat(longestScope - scopeName.length),
41 | separator,
42 | scopeDescription === ''
43 | ? chalk.grey('No description')
44 | : chalk.white(scopeDescription)
45 | ].join('')
46 | )
47 | })
48 | })
49 | }
50 | /* eslint-enable no-console */
51 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | import cac from 'cac'
4 | import updateNotifier from 'update-notifier'
5 | import { cosmiconfig } from 'cosmiconfig'
6 | import parser from 'customizable-gitmoji-config-parser'
7 |
8 | import package_ from '../package.json'
9 |
10 | import commands from './commands'
11 |
12 | updateNotifier({ pkg: package_ }).notify()
13 |
14 | const cli = cac('cz-gitmoji')
15 |
16 | async function getConfig() {
17 | const result = await cosmiconfig('gitmoji', { cache: false }).search()
18 | return parser(result?.config ?? {})
19 | }
20 |
21 | cli.command('list', 'List all the available gitmojis').action(async () => {
22 | await commands.list(await getConfig())
23 | })
24 |
25 | cli.command('init', 'Initialize gitmoji as a commit hook').action(async () => {
26 | await commands.init()
27 | })
28 |
29 | cli
30 | .command('remove', 'Remove a previously initialized commit hook')
31 | .action(async () => {
32 | await commands.remove()
33 | })
34 |
35 | cli
36 | .command('commit', 'Interactively commit using the prompts')
37 | .option('--hook', 'DO NOT USE')
38 | .action(async ({ hook }) => {
39 | await commands.commit(await getConfig(), hook ?? false)
40 | })
41 |
42 | cli.version(package_.version)
43 | cli.help()
44 | cli.parse()
45 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES6",
4 | "module": "commonjs",
5 | "lib": ["ESNext"],
6 | "strict": true,
7 | "sourceMap": true,
8 | "esModuleInterop": true,
9 | "resolveJsonModule": true,
10 | "baseUrl": ".",
11 | "sourceRoot": "src",
12 | "outDir": "lib",
13 | "paths": {
14 | "~/*": ["src/*"]
15 | }
16 | },
17 | "exclude": ["lib"]
18 | }
19 |
--------------------------------------------------------------------------------