36 |
37 |
38 | ## Preview
39 |
40 | Starting from an empty commit message, the extension created a recommended message and populated it inside the Git pane of VS Code:
41 |
42 |
43 |
46 |
47 |
48 |
49 |
50 |
51 | ## Getting started
52 |
53 | How to install and run the extension in VS Code.
54 |
55 |
60 |
61 |
62 | ## Features
63 |
64 | Just click the extension's one **button** in the Git pane.
65 |
66 | This is what the extension can do:
67 |
68 | - Look at any **staged** changes files, otherwise falls back to all unstaged changes.
69 | - Generate a commit message, which you can use or edit.
70 | - It can describe a variety of changes - when a file is added, removed, moved, renamed, etc.
71 | - Can handle multiple files at once.
72 | - Based on paths and extensions, infers a **Conventional Commit** prefix type e.g. `feat`, `chore`, `ci`, `build`, `build(deps)`, `docs`.
73 |
74 | See more info on the [Features](/docs/features.md) page in the docs.
75 |
76 |
77 | ## Comparison with other extensions
78 |
79 | Other extensions usually require some manual input, such as selecting prefix type from a droplist or writing a commit message by hand along with other form parameters.
80 |
81 | This extension takes _zero_ parameters. Just click a button.
82 |
83 | ## Why not generate a commit message with AI?
84 |
85 | This extension does not use AI. With the explosion of AI tools, you can find alternatives to this extension which use do AI - see notes here under [AI tools](/docs/other/ai-tools.md).
86 |
87 |
88 | ## Sample usage
89 |
90 | Here are some screenshots of what messages the extension generates based on changed files.
91 |
92 | If you created a new file and staged it:
93 |
94 |
95 |
96 |
97 |
98 | If you updated a build-related file:
99 |
100 |
101 |
102 |
103 |
104 | If updated a file in `docs/` or a `README.md` anywhere:
105 |
106 |
107 |
108 |
109 |
110 | If you renamed a file:
111 |
112 |
113 |
114 |
115 |
116 |
117 | ## Documentation
118 |
119 | Guides for installing and using the pre-built extension and for developers to build from source code.
120 |
121 |
126 |
127 |
128 | ## Contributing
129 |
130 | See the [Contributing](/CONTRIBUTING.md) guide.
131 |
132 |
133 | ## License
134 |
135 | Released under [MIT](/LICENSE) by [@MichaelCurrin](https://github.com/MichaelCurrin).
136 |
137 | See the [Credit](/docs/other/credit.md) doc for more info.
138 |
--------------------------------------------------------------------------------
/bin/reset_sandbox.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Set up the sandbox directory as a repo with some sample activity.
3 | set -e
4 |
5 | DIR='sandbox'
6 |
7 | if [[ -d "$DIR" ]]; then
8 | rm -rf "$DIR"
9 | fi
10 |
11 | git init "$DIR" --quiet
12 | cd "$DIR"
13 |
14 | # Create a commit, so that the extension can run diff-index, which requires an
15 | # initial commit.
16 | echo '# Sandbox' >'README.md'
17 | echo 'console.log("Hello, Foo!");' >foo.js
18 | echo 'console.log("Hello, Fizz!");' >fizz.js
19 | echo 'console.log("Hello, Buzz!");' >buzz.js
20 | echo 'console.log("Hello, Bazz!");' >bazz.js
21 | git add -A
22 | git commit -m "Initial commit in $DIR"
23 |
24 | # Modify.
25 | echo 'console.log("Hello, Foobar!");' >>foo.js
26 | # Add.
27 | echo 'console.log("Hello, Bar!");' >bar.js
28 | # Rename
29 | mv fizz.js fizzy.js
30 | # Move
31 | mkdir -p my_subdir
32 | mv bazz.js my_subdir
33 | # Delete.
34 | rm buzz.js
35 |
36 | # Special characters.
37 | echo '# Special characters' >'spëcial châracters.md'
38 |
39 | echo '---'
40 | git -c 'core.quotePath=false' status --short
41 | echo '---'
42 | git -c 'core.quotePath=false' diff-index --name-status --find-renames --find-copies --no-color HEAD
43 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Auto Commit Message documentation ⚙️ 🧙♂️ ✉️
2 |
3 | This project serves to prepare a smart commit message for you, to make your development flow smoother.
4 |
5 |
6 | ## Overview
7 |
8 | - [Quickstart](quickstart.md)
9 | - [About](about.md)
10 | - [Features](features.md)
11 | - What it can do, upcoming features, and how it works
12 | - [User manual](manual/)
13 | - How to install and use the installed extension.
14 | - [Development](development/)
15 | - Guide for developers to set up and run locally.
16 | - Useful for testing your changes before contributing a PR.
17 |
18 |
31 |
--------------------------------------------------------------------------------
/docs/_media/sample-build.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MichaelCurrin/auto-commit-msg/3b88dc49e80d07fa58784fe2f4196a4054eb2977/docs/_media/sample-build.png
--------------------------------------------------------------------------------
/docs/_media/sample-chore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MichaelCurrin/auto-commit-msg/3b88dc49e80d07fa58784fe2f4196a4054eb2977/docs/_media/sample-chore.png
--------------------------------------------------------------------------------
/docs/_media/sample-docs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MichaelCurrin/auto-commit-msg/3b88dc49e80d07fa58784fe2f4196a4054eb2977/docs/_media/sample-docs.png
--------------------------------------------------------------------------------
/docs/_media/sample-feat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MichaelCurrin/auto-commit-msg/3b88dc49e80d07fa58784fe2f4196a4054eb2977/docs/_media/sample-feat.png
--------------------------------------------------------------------------------
/docs/_media/sample-rename.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MichaelCurrin/auto-commit-msg/3b88dc49e80d07fa58784fe2f4196a4054eb2977/docs/_media/sample-rename.png
--------------------------------------------------------------------------------
/docs/about.md:
--------------------------------------------------------------------------------
1 | ## About
2 |
3 | A VS Code extension that gives you smart commit message suggestions. For the times where all your need is a simple message.
4 |
5 | It looks at the path of a file that changed and how it changed, then pushes the commit message to the Git pane in VS Code. You can edit or erase the message if you don't like it.
6 |
7 | It can make a message to **describe a change** for a single file to commit. Including "create", "update", "remove", "rename" and "move" - along with the filename. Or the path, like for a move. See the [message.test.ts](/src/test/generate/message.test.ts) test spec.
8 |
9 | In many cases, it can also provide an appropriate **Conventional Commit** type for you, as a commit message prefix.
10 |
11 |
12 | ## When auto-generated messages are good
13 |
14 | This is a time-saving tool. You get to spend more time writing code and solving problems. And less time on figuring out what to write for a commit message or typing the message.
15 |
16 | You can probably use this tool to generate messages for **80%** of your commits. Where the changes are rather mundane. And where the effort and time to write out a commit
17 |
18 | But remember to **manually** write explanatory messages for the other 20% of the time, where a commit message composed by a human is valuable. Or take the generated message and tweak it with more detail.
19 |
--------------------------------------------------------------------------------
/docs/development/README.md:
--------------------------------------------------------------------------------
1 | # Development
2 | > How to setup, run, and improve this extension in a local dev environment
3 |
4 | [](https://snyk.io/test/github/MichaelCurrin/auto-commit-msg?targetFile=package.json)
5 | [](https://nodejs.org "Go to Node.js homepage")
6 | [](https://www.npmjs.com/package/typescript "Go to TypeScript homepage")
7 |
8 | Requires VS Code version: [](https://code.visualstudio.com/ "Go to VS Code homepage")
9 |
10 | This guide is for anyone who wants to contribute to this repo or who just wants to explore this extension's code and how it works in VS Code.
11 |
12 |
13 | ## Overview
14 |
15 | - [Installation](installation.md) - Start with this doc to install dependencies.
16 | - [Export](export.md) - how to build the extension locally and install it in VS Code. Just a single command is needed.
17 | - [Deploy](deploy.md) - this doc covers the CI/CD pipeline and publishing releases.
18 |
19 |
20 | ## Install extension globally
21 |
22 | ### Roll your own
23 |
24 | See the [Export](export.md) doc to install a dev version of the package.
25 |
26 | ### Install pre-built extension
27 |
28 | See [Quickstart](/docs/quickstart.md) doc to download and install a _pre-built_ version of the extension from the Marketplace.
29 |
--------------------------------------------------------------------------------
/docs/development/advanced/debugging.md:
--------------------------------------------------------------------------------
1 | # Debugging
2 | > How to deal with errors in the extension
3 |
4 | ## Test shell commands
5 |
6 | This snippet of code can be used to for testing that a basic command works without error and output can be shown.
7 |
8 | ```typescript
9 | /**
10 | * Debug tool for checking that a basic command works.
11 | * Replace the `makeAndFillCommitMsg` call with `test` to use this.
12 | */
13 | async function _test(repository: Repository) {
14 | vscode.window.showInformationMessage("Testing")
15 |
16 | let cwd = repository.rootUri.fsPath;
17 |
18 | vscode.window.showInformationMessage(cwd)
19 |
20 | const resp = await _execute(cwd, 'git --version')
21 | vscode.window.showInformationMessage(`${resp.stdout} -- ${resp.stderr}`)
22 | }
23 | ```
24 |
25 | ### Background
26 |
27 | This was prompted by issue [#93](https://github.com/MichaelCurrin/auto-commit-msg/issues/93) on Windows.
28 |
29 | The output in the debug mode did not work because the shell command failed to spawn at all using `exec()` in Node.
30 |
31 | The `cwd` value was incorrect from the existing logs which I didn't notice initially but using the test above made it clear.
--------------------------------------------------------------------------------
/docs/development/advanced/file-changes.md:
--------------------------------------------------------------------------------
1 | # File changes
2 |
3 | Describe how files changed.
4 |
5 |
6 | ## Git CLI
7 |
8 | See `DESCRIPTION` enum in the [constants.ts][] module. This is a description of _how_ a file changed - it will sometimes be used in a generated description as the [Conventional Commits][] doc.
9 |
10 | This enum is a mapping of single-character keys and the verb, such as `M` for `modified`.
11 |
12 | When running either subcommand, you might get the short or long form of a change.
13 |
14 | The enum's _keys_ are from status when using the status `--short` output or standard `diff-index` output.
15 |
16 | e.g.
17 |
18 | ```console
19 | $ git status --short
20 | M abc.txt
21 | A def.txt
22 | $ g diff-index --name-status HEAD
23 | M abc.txt
24 | A def.txt
25 | ```
26 |
27 | The enum's _values_ are the human-readable values from the status long output (standard with no flag). The `diff-index` command has no long output for these verbs, as far as I can tell.
28 |
29 | e.g.
30 |
31 | ```console
32 | $ git status
33 | ...
34 | modified: abc.txt
35 | new file: def.txt
36 | ```
37 |
38 | ### Origin
39 |
40 | For more info, see the Git docs for either `git status` or `git diff-index`.
41 |
42 | From [git-diff-index][]:
43 |
44 | > Possible status letters are:
45 | >
46 | > - A: addition of a file
47 | > - C: copy of a file into a new one
48 | > - D: deletion of a file
49 | > - M: modification of the contents or mode of a file
50 | > - R: renaming of a file
51 | > - T: change in the type of the file
52 | > - U: file is unmerged (you must complete the merge before it can be committed)
53 | > - X: "unknown" change type (most probably a bug, please report it)
54 |
55 | Note this extension does not care about the last 3 kinds.
56 |
57 | ### Create note
58 |
59 | For the `A` key of the enum, `create` was used as a more natural form than `add` or `addition`.
60 |
61 | ### Copy note
62 |
63 | The 'copied' case is very _rare_. I've noted here how it works.
64 |
65 | I've only come across it once using this extension and it was like this:
66 |
67 | - One file `abc.txt` was updated (empty content replaced with text).
68 | - Another file `def.txt` was created (empty content).
69 |
70 | Both were staged and a message was generated. And then `diff-index` appears like to see `def.txt` as a copy of what `abc.txt` _was_ before it was modified.
71 |
72 | Result:
73 |
74 | ```json
75 | ["M abc.txt", "C100 abc.txt def.txt"]
76 | ```
77 |
78 |
79 | ## Actions list
80 |
81 | See `ACTION` in the [constants.ts][] module.
82 |
83 | These are based on Git syntax as in the `DESCRIPTION`. Except that values are in the _active_
84 | voice rather than the past tense, in order fit the Conventional Commit style. Plus, 'update' is
85 | used as a more natural word than 'modify'.
86 |
87 | Note that 'move' will be included in the 'rename' case and this project detects move versus rename with other longer.
88 |
89 |
90 | [constants.ts]: /src/lib/constants.ts
91 | [Conventional Commits]: /docs/manual/conventional-commits.md
92 | [git-diff-index]: https://git-scm.com/docs/git-diff-index
93 |
--------------------------------------------------------------------------------
/docs/development/advanced/maintenance.md:
--------------------------------------------------------------------------------
1 | # Maintenance
2 |
3 | ## Dependencies
4 |
5 | When upgrading `@types/vscode` in [package.json](/package.json), you must also upgrade the `engines.vscode` value manually.
6 |
7 | Or you'll get an error when packaging the extension, like:
8 |
9 | ```
10 | ERROR @types/vscode ^1.53.0 greater than engines.vscode ^1.52.0. Consider upgrade engines.vscode or use an older @types/vscode version
11 | ```
12 |
13 | Running the `test` command will not tell you about the error.
14 |
15 |
16 | ## Images
17 |
18 | The extension icon listed in `package.json` must not be an SVG because of security limitations by VS Code. A PNG works fine.
19 |
20 | SVGs are used for "commands" though, for the extension's button.
21 |
22 | See [images](/images/).
23 |
--------------------------------------------------------------------------------
/docs/development/advanced/npm-tasks.md:
--------------------------------------------------------------------------------
1 | # NPM tasks
2 |
3 |
4 | ## Clean
5 |
6 | This will clear the unversioned `out` directory - useful to get rid of files after renaming or deleting TS files. This will keep any hidden directories like `.vscode-test` which has a large binary for integration tests.
7 |
8 | ```sh
9 | $ npm run clean
10 | ```
11 |
12 | A few problems have been resolved by running the clean command, so this is now part of the `build` step so it runs every time when doing tests or running the extension. Note that the build/compile step happens as part of `watch` too, so it is covered there.
13 |
--------------------------------------------------------------------------------
/docs/development/advanced/resources.md:
--------------------------------------------------------------------------------
1 | # Resources
2 |
3 |
4 | See also the [License](/README.md#license) section for links to repos.
5 |
6 | NPM packages that parse git status output:
7 |
8 |
9 | ## git-status
10 |
11 | [NPM - git-status](https://www.npmjs.com/package/git-status)
12 |
13 | Published in 2020. This _has_ to use the git status command so is limiting. It wraps `parse-git-status` - see [index.js](https://github.com/IonicaBizau/git-status/blob/master/lib/index.js).
14 |
15 |
16 | ## parse-git-status
17 |
18 | [NPM - parse-git-status](https://www.npmjs.com/package/parse-git-status)
19 |
20 | Published in 2016 and no activity since.
21 |
22 | See [index.js](https://github.com/jamestalmage/parse-git-status/blob/master/index.js) - that is the core logic and a `DESCRIPTIONS` mapping. This package can be used against string output so does not require actually running git status. It doesn't have Types though and also from the tests it doesn't support renaming properly.
23 |
24 | The output looks like this:
25 |
26 | ```javascript
27 | parseGitStatus(output)
28 | {
29 | x: 'X DESCRIPTION',
30 | y: 'Y DESCRIPTION',
31 | to: 'TO PATH',
32 | from: 'FROM PATH OR NULL'
33 | }
34 | ```
35 |
--------------------------------------------------------------------------------
/docs/development/advanced/sandbox.md:
--------------------------------------------------------------------------------
1 | # Run extension in sandbox mode
2 |
3 | Start the extension for local development.
4 |
5 | This allows manual integration tests. Here we set up a separate sandboxed VS Code instance in an new window. That window has all extensions **disable** except the extension we are working on. And your original VS Code instance will not be affected.
6 |
7 | If you prefer not use this approach, you can just compile and install the extension globally. It will override the existing extension though.
8 |
9 |
10 | ## Start sandbox
11 |
12 | These are configured in the `.vscode/launch.json` config.
13 |
14 | Follow these steps:
15 |
16 | 1. Open VS Code at this repo if you haven't already.
17 | 1. Go to the _Debug_ tab.
18 | 1. Select one of two tasks:
19 | - _Run Extension_ task.
20 | - This will start in a default directory - such as your user's home directory.
21 | - You might want to use _File_ / _Open_ to change the sandbox window to a repo what has more content to play with. This will be _remembered_ on later runs. Unfortunately if you changed your VS Code settings to open in a new window on Open, then the extension setup will be undone.
22 | - _Start in Sandbox repo_ task.
23 | - For more reliable and consistent behavior.
24 | - This will run against the `sandbox` directory in the project, which is a separate Git repo where you can make files and commits as you like.
25 | - NB. You must run `npm run sb` command **first** to ensure this directory exists, then run the debug action. You can also this NPM command again whenever you want to clear the space and start over.
26 | 1. Click the run button.
27 |
28 | That will start a new sandboxed VS Code session which has the extension built using the local code and _enabled_, and all other extensions _disabled_. At a lower level, it runs `npm compile` and `npm watch`. If you want to keep extensions enabled, remove the `--disable-extensions` flag in the launch config.
29 |
30 | What is especially useful about this is that whenever an extension action is performed in the sandboxed VS Code window, if there are any logs for that then those will appear in the Debug Console of the _original_ VS Code window.
31 |
32 | The code for the extension is in [src](/src/).
33 |
34 |
35 | ## Reload
36 |
37 | The `watch` task is supposed to be running in the background but I haven't actually seen it actually pick up changes and affect what I see in the debugging window.
38 |
39 | So if you make a change to your source code, in the original repo you must use the green _Restart_ circle in the debugger to reload the extension in the sandbox window.
40 |
41 | If you don't see code changes appearing, you may need to stop and start the debugger afresh.
42 |
--------------------------------------------------------------------------------
/docs/development/advanced/status-vs-diff-index.md:
--------------------------------------------------------------------------------
1 | # status vs diff-index
2 |
3 | Git subcommands used by this extension to check which filepaths changed and how they changed.
4 |
5 | See [parseOutput.ts](/src/git/parseOutput.ts) module that handles output of two similar Git subcommands discussed below.
6 |
7 |
8 | ## History and motivation
9 |
10 | This project was initially built around [status](#status), as that was the subcommand use by another extension that this extension was based on. But, now the [diff-index](#diff-index) approach is used instead.
11 |
12 | Using `status` is friendly for everyday use as developer. The `diff-index` subcommand is not for everyday use - you can to add a path like `HEAD` and you need to add flags to get sensible output.
13 |
14 | Both `status` and `diff-index` can be used to see a list of paths and how they changed, using `from` and `to` as a pair of paths when moving or renaming a file.
15 |
16 | Why use `diff-index` and not `status`? Using the former makes things more **predictable** when parsing output. Since the `from` file is always first, from left to right. While `status` has it on the right, which is hard because it is not always there. There might be other reasons I can't remember, maybe because there is a percentage similarity that shows up in `diff-index` for renames/moves.
17 |
18 |
19 | ## status
20 |
21 | The well-known `git status` subcommand.
22 |
23 | ```sh
24 | $ git status [FLAGS] --short
25 | ```
26 |
27 | > git-status - Show the working tree status
28 |
29 | e.g.
30 |
31 | ```console
32 | $ git status
33 | modified: abc.txt
34 | $ git status --short
35 | M abc.txt
36 | ```
37 |
38 | Sample output of multiple lines. Note use of spaces not tabs.
39 |
40 | ```console
41 | $ git status --short
42 | R LICENSE -> LIC
43 | M docs/development/advanced/status-vs-diff-index.md
44 | M src/test/git/parseOutput.test.ts
45 | ```
46 |
47 |
48 | ## diff-index
49 |
50 | The lesser-known `git diff-index` subcommand. This is not so usable for day to to day use in the CLI but is great for scripts, or a project such as this one.
51 |
52 | ```sh
53 | $ git diff-index [FLAGS] PATH
54 | ```
55 |
56 | > Compare a tree to the working tree or index
57 |
58 | Notes:
59 |
60 | - Output has tab separator between columns.
61 | - Use `--cached` for _only_ staged changes. Note that the only way to pick up a new file or detect a move/rename pair properly with `diff-index` is to stage changes first and then use this flag.
62 | - Use `--name-status` to show names and status of changed files.
63 | - Use `-M` to detect renames (i.e. move or rename a file, stage both paths, then run the command with this flag to see it appear as `R100` or similar).
64 | - The path is required - `HEAD` works fine.
65 |
66 | e.g.
67 |
68 | ```console
69 | $ git diff-index HEAD
70 | :100644 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 M abc.txt
71 | ```
72 |
73 | ```console
74 | $ git diff-index --name-status HEAD
75 | M abc.txt
76 | ```
77 |
78 | Two files changed, with long paths:
79 |
80 | ```console
81 | $ git diff-index --name-status HEAD
82 | M docs/development/advanced/status-vs-diff-index.md
83 | M src/test/git/parseOutput.test.ts
84 | ```
85 |
86 | For a move or rename:
87 |
88 | ```console
89 | $ mv LICENSE LIC
90 | $ git add .
91 | $ git diff-index --name-status -M HEAD
92 | R100 LICENSE LIC
93 | ```
94 |
95 | Even though you might be able to select the output in the console as spaces, it is actually tabs. Check with a tool that can show hidden characters.
96 |
97 | ```console
98 | $ git diff-index --name-status HEAD -M | bat -A
99 | ───────┬─────────────────────────────────────────────────────────
100 | │ STDIN
101 | ───────┼─────────────────────────────────────────────────────────
102 | 1 │ R100├──┤LICENSE├──┤LIC␊
103 | 2 │ M├──┤docs/development/advanced/status-vs-diff-index.md␊
104 | 3 │ M├──┤src/test/git/parseOutput.test.ts␊
105 | ```
106 |
107 | ### Limitation of diff-index
108 |
109 | #### Summary
110 |
111 | New files and moved/renamed files _always_ need to be staged for `git diff-index` to see them. Just remember to do this yourself, because the extension won't see the `U` untracked files otherwise.
112 |
113 | I consider this is an acceptable limitation of functionality to keep the extension code simple.
114 |
115 | #### Details
116 |
117 | The `diff-index` subcommand **cannot** see new or moved/renamed files unless you **stage** them. This is okay. Because you just need to stage a file and then the extension can see it.
118 |
119 | And in the case of renaming/moving files, there's a limitation of git that can't be overcome - you need to **stage** the old and new paths anyway for `git` to see them as **one file**, regardless of using `status` or `diff-index`.
120 |
121 | The `git status` subcommand _can_ handle new _untracked_ files. But the effort to rewrite a chunk of the extension to use a different Git subcommand is not worth it, and won't solve the rename/move case anyway.
122 |
123 | So we just keep things simple to avoid bloating the codebase (adding the ability to use two similar subcommands and handle them both well is not sensible when one subcommand works great for most things).
124 |
125 | You can still do what you need to - just remember to stage files if you need the extension to recognize them.
126 |
127 |
128 | ## Find renames
129 |
130 | If you move/rename a file and stage that and you also change the contents, you can get `git diff-index` to recognise that as a rename with modification.
131 |
132 | This is possible using the `-M` or `--find-renames` flag, which uses the default 50% similarity.
133 |
134 | ```console
135 | $ git diff-index HEAD --name-status -M
136 | R099 package.json shell/package.json
137 | ```
138 |
139 | This flag also works for `git status`.
140 |
--------------------------------------------------------------------------------
/docs/development/advanced/structure.md:
--------------------------------------------------------------------------------
1 | # Structure
2 |
3 | The code from the Git Prefix was used to set up [src](/src) directory for a couple of TS files and the tests.
4 |
5 | The [generate](/src/generate/) module followed later as logic that will work standalone in the CLI for a hook.
6 |
--------------------------------------------------------------------------------
/docs/development/build-install.md:
--------------------------------------------------------------------------------
1 | # Build and install
2 |
3 | Build the extension using Node and then install it in your IDE, using the latest code in the repo. This is ideal for testing out local changes you've made in the extension, without creating a tag yet.
4 |
5 | Navigate to the repo root and then run this:
6 |
7 | ```sh
8 | $ make ext
9 | ```
10 |
11 | That will do the following:
12 |
13 | 1. Run **lint** checks.
14 | 1. **Build** the extension using the current codebase and output as an `.vsix` archive file to the `build` directory. Performs all necessary code quality checks.
15 | 1. **Install** the extension globally in VS Code.
16 |
17 | You should then **restart** VS Code.
18 |
19 | You can find the extension in the _Extension_ tab.
20 |
21 | ## Issues installing using WSL
22 |
23 | If using WSL, then after the build is complete you might get an error:
24 |
25 | ```
26 | ERROR: UtilConnectToInteropServer
27 | ```
28 |
29 | In that case, you'll need to install from the `.vsix` file yourself:
30 |
31 | 1. Open the VS Code _Command Palette_ under _View_.
32 | 1. Select the option _Extension: Install from VSIX..._.
33 | 1. Enter the path to the file e.g. `/home/my-user/repos/auto-commit-msg/build/auto-commit-msg-0.25.1.vsix`.
34 |
35 | ## Notes
36 |
37 | About the `ext` command in [package.json](/package.json):
38 |
39 | - We use the `--force` flag to allow **downgrade** to an older version, according to the CLI output help.
40 | - The command sorts by _time_ to find the latest version. Since sorting by name is _not_ reliable, such as when the version is `0.9.0` and `0.10.0` and the latter is meant to be higher but appears like a lower version)
41 |
--------------------------------------------------------------------------------
/docs/development/commands.md:
--------------------------------------------------------------------------------
1 | # Commands
2 | > Guide for running tasks in this project
3 |
4 |
5 | ## Overview
6 |
7 | There are just a _few_ important or frequent `npm` commands to know for this project. To make those easier to access and remember, some shortcut commands have been set up.
8 |
9 | This has been done with `make` as a task runner that wraps `npm run`. These tasks are covered in the [Makefile](/Makefile). They can be run with `make TARGET` for convenience. This is standard on macOS and Linux but you will need to install `make` on Windows.
10 |
11 | See [package.json](/package.json) for all the underlying NPM commands. Note that `.` is better than `src`, as then the configs like `tsconfig.json` can be found - otherwise you'll get an error.
12 |
13 |
14 | See also the [NPM tasks](advanced/npm-tasks.md) doc.
15 |
16 |
17 | ## Run tasks
18 |
19 | Run major tasks to check the project for issues.
20 |
21 | ```sh
22 | $ make all
23 | ```
24 |
25 | This will update hooks, install packages, run all checks, and attempt to build the app.
26 |
27 | This is useful for bootstrapping the project on a fresh clone, or before pushing commits. This task also runs as part of the `pre-push` hook after that has been set up.
28 |
29 |
30 | ## Run checks
31 |
32 | Note these lint and test steps happen in the CI/CD flow - see [Deploy](deploy.md).
33 |
34 | ### Format
35 |
36 | Apply Prettier formatting to scripts.
37 |
38 | ```sh
39 | $ make fmt
40 | ```
41 |
42 | ### Lint
43 |
44 | Run ESLint against TS files for a report and fixing problems where possible.
45 |
46 | ```sh
47 | $ make lint
48 | ```
49 |
50 | Note that linting will not pick up on TypeScript compilation errors, but that can be done using the `npm run compile` step. This runs as part of [Run tests](#run-tests) section.
51 |
52 | ### Run tests
53 |
54 | See the [Tests](tests.md) doc for more.
55 |
56 | Skip clean and style steps, for even faster results such and when editing test spec files. At the risk of inconsistencies sometimes, if a file is renamed or moved.
57 |
58 | ```sh
59 | $ make test-quick
60 | ```
61 |
62 | ### Run all checks
63 |
64 | Clean output, format code, and then run unit tests including code coverage.
65 |
66 | ```sh
67 | $ make test
68 | ```
69 |
--------------------------------------------------------------------------------
/docs/development/deploy.md:
--------------------------------------------------------------------------------
1 | # Deploy
2 | > Build and publish a release
3 |
4 |
5 | ## Checks
6 |
7 | A CI/CD flow is set up on GitHub Actions to compile the app and run checks against it, but not publish it. This is run on every push.
8 |
9 | See the [main.yml](/.github/workflows/main.yml) config file.
10 |
11 |
12 | ## Commands
13 |
14 | ### List
15 |
16 | Preview what will be included in the `.vsix` file.
17 |
18 | ```sh
19 | $ make ls
20 | ```
21 |
22 | ### Publish
23 |
24 | _This section is only relevant for the **maintainer** of this repo, as access to publishing to VS Code Marketplace requires authorization._
25 |
26 | See [Publish recipe][] for more detailed steps.
27 |
28 | Store a token for Azure DevOps - this only needs to be done once and grants access to publishing to VS Code Marketplace.
29 |
30 | ```sh
31 | $ make login
32 | ```
33 |
34 | Tag and push to GitHub and VS Code Marketplace. For major, minor, or bug/patch levels respectively.
35 |
36 | ```sh
37 | $ make publish-M
38 | $ make publish-m
39 | $ make publish-b
40 | ```
41 |
42 | [Publish recipe]: https://michaelcurrin.github.io/code-cookbook/recipes/other/vs-code-extensions/publish.html
43 |
--------------------------------------------------------------------------------
/docs/development/installation.md:
--------------------------------------------------------------------------------
1 | # Installation
2 | > Install dependencies
3 |
4 |
5 | ## Requirements
6 |
7 | - [Node](nodejs.org/)
8 | - [VS Code](https://code.visualstudio.com/)
9 |
10 |
11 | ## Install system dependencies
12 |
13 | Install Node.js - follow [instructions](https://gist.github.com/MichaelCurrin/aa1fc56419a355972b96bce23f3bccba) in gist.
14 |
15 |
16 | ## Clone
17 |
18 | ```sh
19 | $ git clone git@github.com:MichaelCurrin/auto-commit-msg.git
20 | $ cd auto-commit-msg
21 | ```
22 |
23 |
24 | ## Install project dependencies
25 |
26 | ```sh
27 | $ make install
28 | ```
29 |
30 | ## Upgrade project dependencies
31 |
32 | For project maintainers.
33 |
34 | ```sh
35 | $ make outdated
36 | ```
37 |
38 | ```sh
39 | $ make upgrade
40 | ```
41 |
--------------------------------------------------------------------------------
/docs/development/tests.md:
--------------------------------------------------------------------------------
1 | # Tests
2 |
3 |
4 | ## Unit tests
5 |
6 | This will clean the output directory, compile files and then run unit tests. No formatting or linting.
7 |
8 | ```sh
9 | $ npm test
10 | ```
11 |
12 | ## Integration tests
13 |
14 | There are no integration tests in this project.
15 |
16 | For the `git-prefix` project this project was partly based on, unfortunately the tests were poor there, so I didn't copy over the extension tests, but I could bring back some from tag `v0.6.0` so there are integration tests if I think I need them.
17 |
18 | Most of the logic is what happens internally so it is easy to test with unit tests. There is one frontend button and it just pushes a message, so there is not that much that can go wrong in the UI.
19 |
20 | What would be more useful is testing the integration with `git` - namely using actual output from `git` commands. For now, the unit tests are created using output copied from git command output, so that is covered. It is possible to add integration tests for this area, but it would end up duplicating the unit tests - unless the integration is just focus on git commands to expected strings which is testing git itself and not the extension.
21 |
22 | Notes:
23 |
24 | - This extension was built around Git Prefix, but unfortunately the integration tests of Git Prefix extension there are not useful, so I left out integration tests out of my project. I also noticed that downloading of VS Code as an NPM script is different but clear compared with _Git Semantic Commit_ approach. I don't know which is best practice - need to look at some more VS Code samples.
25 | - _Git Semantic Commit_ extension does in-depth integration tests and even creates a separate new repo in a subfolder to run activity in, so I could look at bringing this in to mine.
26 |
27 |
28 | ## Coverage
29 |
30 | Test with code coverage, as a text report.
31 |
32 | ```sh
33 | $ npm run cover
34 | ```
35 |
36 | Generate a visual multi-page HTML report.
37 |
38 | ```sh
39 | $ npm run cover:report
40 | ```
41 |
42 | See the main page generated as `coverage/lcov-report/index.html`.
43 |
44 | This can be viewed using a static site server.
45 |
46 | ```sh
47 | $ cd coverage/lcov-report
48 | $ python3 -m http.server
49 | ```
50 |
51 | Then open as:
52 |
53 | - http://localhost:8000
54 |
55 | Or set up VS Code's _Live Server_ to start on that `index.html` page. That will hot-reload the browser tab when the HTML files change - this is useful if you are updating your tests and want to see the browser reflect changes to coverage.
56 |
--------------------------------------------------------------------------------
/docs/features.md:
--------------------------------------------------------------------------------
1 | # Features
2 |
3 | ## What it does
4 |
5 | - Click the button in the Git pane to run the extension.
6 | - Reads from the status of your git repo, or staged changes.
7 | - Generates a commit message for you, then you can edit and commit as you like.
8 |
9 |
10 | ## Details
11 |
12 | A roadmap of features and whether done or not.
13 |
14 | - [x] Handle staged and unstaged files flexibly.
15 | - Handle **staged** files if there are any, so you can change a few files and then generate messages for those. But if there are zero staged changes, the extension will fall back to the working tree of unstaged changes.
16 | - Note that **new** files (including when doing a rename) should **always** be staged so that the extension can pick them up and so git can see that two paths for a renamed file are the same file.
17 | - [x] Generate a single-line commit message for a file to be committed, using action verbs (e.g. `Create`, `Update`, `Delete`)
18 | - [x] Handle changes from a single changed file.
19 | - [ ] Handle changes from two or more files.
20 | - [x] As a list of the same nature e.g. `update foo.txt and fizz/bar.txt`, `feat: create foo.txt, fizz/bar.txt and buzz.js` (including prefix) and `Various changes to foo.txt and fizz/bar.txt` (for one updated and one new file). See [#29](https://github.com/MichaelCurrin/auto-commit-msg/pull/29).
21 | - [x] As a count. e.g. `update 3 files`. See [#38](https://github.com/MichaelCurrin/auto-commit-msg/issues/38).
22 | - [ ] As different verb for each change `create foo.txt and delete bar.txt`. See [#37](https://github.com/MichaelCurrin/auto-commit-msg/issues/37) and See [#52](https://github.com/MichaelCurrin/auto-commit-msg/issues/52).
23 | - [ ] As a count in a directory. `update 3 files in foo`
24 | - [ ] As a count with a conventional commit message. See [#51](https://github.com/MichaelCurrin/auto-commit-msg/issues/51).
25 | - [ ] As a count with a label. e.g. `update 3 config files`. See [#13](https://github.com/MichaelCurrin/auto-commit-msg/issues/13).
26 | - [ ] As count that uses the old message. See [#55](https://github.com/MichaelCurrin/auto-commit-msg/issues/55)
27 | - [x] Support using multiple repos in one VS Code window.
28 | - [x] Keep user-entered value as a prefix e.g. Keep `docs:` (or ticket number) so message becomes `docs: Update README.md`
29 | - [x] Use conventional commits e.g. `chore: Update package.json`
30 | - [x] Support directories or filenames with spaces in them by adding quotes. e.g. `chore: rename foo.txt to 'foo bar.txt'`
31 |
32 | ## Topics areas
33 |
34 | It recognizes files from a variety of languages and tooling and then provides an appropriate conventional commit message.
35 |
36 | - [x] Python - package files and configs.
37 | - [x] JavaScript, TypeScript - package files and configs.
38 | - [x] Ruby - package files and configs.
39 | - [x] Go modules.
40 | - [x] Circle CI, GitHub Actions - `ci`.
41 | - [x] Makefile and package files for languages - `build`.
42 | - [x] Config files like YAML, JSON and TOML - `chore` or `build`.
43 |
44 | ### Capabilities
45 |
46 | This extension understands something about a single file and how it changed.
47 |
48 | #### Actions
49 |
50 | Here are supported action words that are used.
51 |
52 | - `Create`
53 | - `Update`
54 | - `Delete`
55 | - `Move`
56 | - `Rename`
57 | - `Move and rename`
58 |
59 | #### Prefixes
60 |
61 | Based on the action and the file (directory, name, and extension), a _conventional commit_ prefix will be derived. If none of the labels can be applied, they be will left out.
62 |
63 | Here are the prefixes it knows, with a summary of the rule used.
64 |
65 | | Prefix | Rule |
66 | | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
67 | | `feat` | For a new file. (The tool can't differentiate between content for a feature / refactor / bug fix, but it assumes a new file is probably going to be a new feature) |
68 | | `chore` | For config files and for deleting, renaming, or moving a file. |
69 | | `build` | For package management files and `Makefile` / `Rakefile`. |
70 | | `ci` | For configs around GH Actions, CircleCI and BuildKite. |
71 | | `test` | For directories and files related to tests, like `tests/` or `index.spec.js`. |
72 | | `docs` | For documentation changes, like `README.md`, `docs/` or `CONTRIBUTING.md`. |
73 |
74 | There are other prefixes available. These require looking at the content of the file, not just the path. These are not in the scope of this project, but you can always type them manually.
75 |
76 | - `style`
77 | - `fix`
78 | - `refactor`
79 | - `perf`
80 |
--------------------------------------------------------------------------------
/docs/manual/README.md:
--------------------------------------------------------------------------------
1 | # User manual
2 | > Guides for users to install and use the extension
3 |
4 | - [Installation](installation.md)
5 | - Install the extension.
6 | - [Usage](usage.md)
7 | - How to run the extension. It will generate a Conventional Commit type prefix where possible and a description of file changes.
8 | - [Conventional Commits](conventional-commits.md)
9 | - This page explains more about the commit standard used in this extension.
10 | - [Q&A][]
11 | - Ask questions on the Marketplace page about how to use the installed extension or clarification on the [features](/docs/features.md) available.
12 | - [Uninstall](uninstall.md)
13 | - Remove the extension.
14 |
15 | [Q&A]: https://marketplace.visualstudio.com/items?itemName=MichaelCurrin.auto-commit-msg&ssr=false#qna
16 |
--------------------------------------------------------------------------------
/docs/manual/conventional-commits.md:
--------------------------------------------------------------------------------
1 | # Conventional Commits
2 | > Info on how the Conventional Commits standard is applied for generating output in this project.
3 |
4 |
5 | ## Resources
6 |
7 | - The official [Conventional Commits](https://www.conventionalcommits.org) homepage
8 | - My [Conventional Commits cheatsheet](https://michaelcurrin.github.io/dev-cheatsheets/cheatsheets/other/conventional-commits.html) in my Dev Cheatsheets projects, covering parts of the standard most relevant to me and this extension project.
9 |
10 |
11 | ## The official standard
12 |
13 | Here is the full syntax for a commit message:
14 |
15 | ```
16 | [optional scope]:
17 |
18 | [optional body]
19 |
20 | [optional footer]
21 | ```
22 |
23 | The standard says that description is meant to start with a _lowercase letter_, so this is applied throughout this project.
24 |
25 |
26 | ## What this project uses
27 |
28 | The body and footer are ignored in this project, to keep things simple. Perhaps, one day, some details will be added to the body by this extension.
29 |
30 | So then the format of generated messages:
31 |
32 | - `TYPE: DESCRIPTION`
33 | - `TYPE(SCOPE): DESCRIPTION`
34 |
35 | Additionally, a custom message is allowed:
36 |
37 | - `CUSTOM_MESSAGE TYPE: DESCRIPTION`
38 |
39 | Here are some sample messages that this extension creates:
40 |
41 | - `feat: create foo.txt`
42 | - `build: update Makefile`
43 | - `build(deps): update package-lock.json`
44 | - `docs: update README.md`
45 | - `test: update foo.spec.js`
46 | - `chore: rename fizz.txt to buzz.txt`
47 |
48 | See [Sample usage](https://github.com/MichaelCurrin/auto-commit-msg#sample-usage) for screenshots.
49 |
--------------------------------------------------------------------------------
/docs/manual/installation.md:
--------------------------------------------------------------------------------
1 | # Installation
2 |
3 | ## Install from the Marketplace
4 |
5 | ### Marketplace website
6 |
7 | Go to the Marketplace link below then click the _Install_ button.
8 |
9 |
14 |
15 | ### Within VS Code
16 |
17 | 1. Go to VS Code's Extensions side panel.
18 | 1. Search for and install the extension by name - _Auto Commit Message_.
19 | 1. Click _Install_.
20 |
21 | Or enter the following in the VS Code command prompt:
22 |
23 | ```sh
24 | $ ext install MichaelCurrin.auto-commit-msg
25 | ```
26 |
27 | ---
28 |
29 | Continue to the [Usage](usage.md) doc.
30 |
31 |
32 | ## Manual install approaches
33 |
34 | ### Use the GUI
35 |
36 | 1. In the browser.
37 | 1. Go to the GitHub Releases page.
38 | - [](https://github.com/MichaelCurrin/auto-commit-msg/releases)
39 | 1. Find the latest release.
40 | 1. Expand the _Assets_ section.
41 | 1. Download a copy of the `.vsix` archive file by clicking on the filename.
42 | 1. In VS Code
43 | 1. Open the Command Palette (_View_ then _Command Palette_).
44 | 1. Type `extension`, wait for the auto-complete, then select _Extension: Install from VSIX..._.
45 | 1. Select the file downloaded earlier.f
46 | 1. Make sure to **restart** VS Code to get the extension loaded.
47 |
48 | ### Use the terminal
49 |
50 | Instructions for macOS / Linux.
51 |
52 | 1. Identify a release number on the GitHub Releases page.
53 | - [](https://github.com/MichaelCurrin/auto-commit-msg/releases)
54 | 1. Download the `.vsix` extension file using `curl`, using the appropriate target version.
55 | ```sh
56 | $ cd ~/Downloads
57 | $ TARGET='0.19.0'
58 | $ curl -L -O "https://github.com/MichaelCurrin/auto-commit-msg/releases/download/v$TARGET/auto-commit-msg-$TARGET.vsix"
59 | ```
60 | 1. Install the extension. Here we run VS Code in the CLI against a path to the downloaded file (no need to unzip it first).
61 | ```sh
62 | $ code --install-extension PATH
63 | ```
64 | e.g.
65 | ```sh
66 | $ code --install-extension ~/Downloads/auto-commit-msg-0.19.0.vsix
67 | ```
68 | ```
69 | Installing extensions...
70 | Extension 'auto-commit-msg-0.19.0.vsix' was successfully installed.
71 | ```
72 | 1. If you have VS Code running already, make sure to **restart** it to get the extension loaded.
73 |
--------------------------------------------------------------------------------
/docs/manual/uninstall.md:
--------------------------------------------------------------------------------
1 | # Uninstall
2 | > How to uninstall the extension if you don't want it anymore
3 |
4 |
5 | ## Extension pane
6 |
7 | 1. Open the _Extensions_ tab in VS Code.
8 | 1. Click the Auto Commit Message extension.
9 | 1. Click _uninstall_.
10 | 1. Restart VS Code.
11 |
12 | Or
13 |
14 | ## Command-prompt
15 |
16 | 1. Run this command.
17 | ```sh
18 | $ code --uninstall-extension MichaelCurrin.auto-commit-msg
19 | ```
20 | 2. Restart VS Code.
21 |
--------------------------------------------------------------------------------
/docs/manual/usage.md:
--------------------------------------------------------------------------------
1 | # Usage
2 | > How to use extension after it has been installed
3 |
4 |
5 |
6 | With the extension installed, open VS Code at the root of a git repo.
7 |
8 |
25 |
26 | 1. Open VS Code.
27 | 2. Go to the Source Control (Git Extension) tab. You'll see this extension added.
28 | 3. Make a change to a file and use the Source Control pane to stage a file.
29 | 4. Click the extension button.
30 | 5. You'll see a message added the commit message box. Edit it if you want.
31 | 6. Commit with the VS Code UI. e.g. Use CTRL+ENTER or press the tick button.
32 |
33 | To avoid having to use the extension with the mouse, you can use the command bar:
34 |
35 | 1. Press CTRL+SHIFT+P to open it up, select _Auto Commit Message_ and press enter or click it.
36 | 1. Your cursor will move to the commit message box, so now you can press commit with the keyboard. Use CTRL+ENTER.
37 |
--------------------------------------------------------------------------------
/docs/other/README.md:
--------------------------------------------------------------------------------
1 | # Other
2 |
--------------------------------------------------------------------------------
/docs/other/ai-tools.md:
--------------------------------------------------------------------------------
1 | # AI tools
2 | > Using AI to generate commit messages
3 |
4 | ## AI-based extensions
5 |
6 | Search for "gpt commit" in the extensions marketplace and you'll see plenty of extensions that use GPT to write your commit message.
7 |
8 | e.g. [GPT Commit](https://marketplace.visualstudio.com/items?itemName=DmytroBaida.gpt-commit)
9 |
10 | If done well, this could be even more flexible, thorough and natural than this Auto Commit Msg extension which has no AI (but at least handles basic messages for a variety of cases based on the paths of the files that changed rather than the contents).
11 |
12 | You can also try [Codeium](https://codeium.com/download) extension which has a lot of AI chat and completion features and includes a commit message generator (but it always gives me an error).
13 |
14 | ### Downsides
15 |
16 | - There's a time delay.
17 | - Requires network access.
18 | - Your code is shared across the internet with OpenAI etc., which can cause issues for private and company projects.
19 | - You need to a ChatGPT API key and to pay for a premium subscription.
20 | - Limited acccuracy - I don't know if GPT is powerful enough to figure out the context of what you are doing and intend to write based on a diff only, as some of the reasoning for a change won't be covered by code itself but by real world events and requirements. You can pass more unchanged files from you codebase in an extension to the AI but this costs more money and won't always help.
21 |
22 | ## Local LLMs
23 |
24 | To get around the limitations of the above, especially for private codebases, you could use a locally run LLM (like Ollama) instead of ChatGPT. Perhaps there are extensions which support this.
25 |
--------------------------------------------------------------------------------
/docs/other/commit-philosophy.md:
--------------------------------------------------------------------------------
1 | # Commit philosophy
2 |
3 | This repo is based on the practice of small, frequent, atomic commits such that it easy to rollback to a work state when developing (such as stashing uncommitted changes), or rolling back a deploy to an earlier commit (or using a revert commit).
4 |
5 | If there is too much friction in creating a commit message, then I find myself putting off a few changes and then I have 5 files changes for different reasons and sometimes multiple tangle changes within each file.
6 |
7 | So it makes sense for my approach to have a magical way to generate a commit message for a change in one or two files, commit and then keep going. Which is where this extension comes in.
8 |
9 | Yes sometimes you need to rename a variable across 10 files and then a manually-typed message makes sense. Or you add a function and use it at 3 levels, or you fix the same bug in multiple places. Then please go ahead and don't use the pre-filled message.
10 |
11 | But if your commit style is somewhat like mine, you'll find that 80% of he commit messages you write can be generated programmatically, especially for one file or one line changes. This keeps your commit flow smooth and keeps you in a state of writing code and solving problems, not feeling interrupted to write meaningful messages or type out precise file names.
12 |
13 | Also, the atomic approach doesn't have to be followed strictly. Sometimes I add tests and functions in one commit. Sometimes tests first and functions in a later commit to get the tests to pass.
14 |
15 | Tip: Even if you don't use the full message generated by this extension, you can still just keep the path at the end as part of your message.
16 |
--------------------------------------------------------------------------------
/docs/other/credit.md:
--------------------------------------------------------------------------------
1 | # Credit
2 | > Giving credit to projects which influenced this project
3 |
4 |
5 | The core of this project's VS Code extension logic is about creating a commit message and pushing it to the _Git Extension_ input box in the UI. That comes from the _Git Prefix_ extension. The use of _Git CLI_ in the extension comes from the _Semantic Git Commit_ extension.
6 |
7 | See more info below.
8 |
9 |
10 | ## Hello World sample
11 |
12 | - Source: [Hello World test sample](https://github.com/microsoft/vscode-extension-samples/tree/master/helloworld-test-sample) project
13 | - My project started off as an extension based on this VS Code test sample. It was just hello world and didn't help with my flow, so I got rid of the code in later tags.
14 |
15 |
16 | ## Git Semantic Commit
17 |
18 | Note that a "semantic commit" message is the same as a "conventional commit" message.
19 |
20 | - Repo: [nitayneeman/vscode-git-semantic-commit](https://github.com/nitayneeman/vscode-git-semantic-commit)
21 | - I liked how this extension does Git CLI commands, so I used the original [Git](https://github.com/nitayneeman/vscode-git-semantic-commit/blob/master/src/git.ts) class and `getWorkspaceFolder` function. That served as the base for my functionality in [gitCommands.ts](/src/gitCommands.ts), which allowed my `extension.ts` script to work as I wanted. I later split out the `Git` class into functions as that made more sense.
22 | - The rest of the extension was too advanced for what I needed to do, so I ended up not using the other parts.
23 | - I like the integration tests approach though so I might come back to use pieces of that.
24 |
25 |
26 | ## Git Prefix
27 |
28 | - Repos: [srmeyers/git-prefix](https://github.com/srmeyers/git-prefix) or the fork [d3skdev/git-prefix](https://github.com/d3skdev/git-prefix).
29 | - I found this in the marketplace - it adds a _branch prefix_ to the commit message UI box and gives the user a chance to read it and edit it. This is very close to the flow that I want and it is far less code than Git Semantic Commit, so my extension is based on this. See for example the use of `repository.inputBox.value` in [extension.ts](/src/extension.ts).
30 |
31 |
32 | ## Parse Git Status
33 |
34 | - Repo: [jamestalmage/parse-git-status](https://github.com/jamestalmage/parse-git-status)
35 | - I started out parsing git status output (not diff-index), intending to use this NPM package. Unfortunately, it does not come with types and I couldn't figure out how to add types, so I took the logic from it and rewrote it as my own so it is easier to manage and extend. See my [parse-git-output](/src/generate/parse-git-output) module - that based on `parse-git-status`.
36 | - My enhancements:
37 | - Compatible with git status `--porcelain` flag.
38 | - Replaced use of `-z` mode. As I do not like separating by either one _or_ two null characters and how the original package did this splitting. So I split columns by whitespace rather and had lines split by a newline character (for when more than one files changes or there is a trailing line).
39 | - Cleaner `for` loop logic
40 | - I found the original hard to work on because of how it uses an old-style `for` loop and `i` variable.
41 | - I found using `.split` with a regex pattern was much simpler.
42 | - Add TS types (essential for my project to run).
43 | - Add `git diff-index` support - see [status vs diff-index](/docs/development/status-vs-diff-index.md) doc.
44 |
--------------------------------------------------------------------------------
/docs/other/functionality.md:
--------------------------------------------------------------------------------
1 | # Functionality
2 |
3 | See the [gitCommands.ts](/src/gitCommands.ts) script for implementation details.
4 |
5 | UPDATE: Perhaps using untracked is a good idea - although not in the git CLI flow, in the VS Code git integration, new/untracked files would be added when adding _everything_ when nothing is staged. So updates might be needed below. Also, see the use of `git status -u` and similar for `diff-index`, but note that `diff-index` is still preferred because of the choice of staged or not while `status` does not have that ability.
6 |
7 | - The extension button must be able to run against **staged** changes only (if any). This will be the most common flow for the initial easy functionality of only committing one file at a time.
8 | - What is staged only. Not untracked.
9 | - Command
10 | - Use the output from `git diff-index --name-status --cached HEAD`. That is staged but not untracked. This was based on [index.js](https://github.com/mcwhittemore/staged-git-files/blob/master/index.js) of another extension.
11 | - Note `git diff` will not be appropriate here.
12 | - And fallback to **all** changes that would be committed. Nothing is staged then, this is everything, but excluding untracked. (There may be specific behavior here I've assumed because of my smart commit or other VS Code preferences.)
13 | - Want both staged and unstaged. But not untracked. The downside is that renames won't get picked unless they are staged (since the new file appears untracked).
14 | - Command
15 | - Use the output from `git status -s -uno --porcelain`.
16 | - Use the output from `git diff-index --name-status HEAD`.
17 |
18 | Also of interest, to get a summary of changes:
19 |
20 | ```sh
21 | $ git diff-index --shortstat HEAD
22 | 4 files changed, 131 insertions(+), 96 deletions(-)
23 | ```
24 |
25 | See more [here](https://github.com/MichaelCurrin/dev-cheatsheets/blob/master/cheatsheets/git/commands/diff-index.md).
26 |
--------------------------------------------------------------------------------
/docs/other/generate-message.md:
--------------------------------------------------------------------------------
1 | # Generate message
2 |
3 | This tool aims to prepare a smart commit message for you at the point you commit. Unfortunately, VS Code does not work with git hooks so this flow only works when committing on the command-line.
4 |
5 | This is to take the effort out of writing self-explanatory commits, where the machine can write a message I would write for a simple case. And where looking at the diff output is sufficient to see the _why_.
6 |
7 | This tool does not require you to always use the auto-generated message - it simply makes it available if you enable it. If there is something that needs to be captured like that a commit is a fix or the reason for a fix or a high-level description of the changes made (like a renamed variable), then write the message by hand.
8 |
--------------------------------------------------------------------------------
/docs/other/plan.md:
--------------------------------------------------------------------------------
1 | # Project plan
2 |
3 | This project is a work in progress. It is starting out as a specification of the desired behavior on the [Wiki](https://github.com/MichaelCurrin/auto-commit-msg/wiki), then will tests added and then only the functionality last.
4 |
5 | This will probably be in Python for easy scaling and tests. And it will probably use git commit hooks - whatever I find works well for command-line use and also VS Code messages if left blank but allowing manual overrides. And ideally showing the message just before its made so one can confirm. But this may be reaching too much especially for two entry methods. Maybe it can be generated when files are staged based on an event in VS Code.
6 |
7 |
8 | ## Tasks
9 |
10 | Roadmap of things to do to get this to v1 release.
11 |
12 | - [x] Works with `git` repos.
13 | - [x] Tests - Unit tests that are run with GitHub Actions CI
14 | - [x] Test coverage report.
15 | - [ ] Update logo.
16 | - [x] Available in VS Code marketplace.
17 | - [ ] CI to build the package archive on tag.
18 | - [ ] Clean up docs and Wiki.
19 |
20 | See [Issues](https://github.com/MichaelCurrin/auto-commit-msg/issues) on the repo.
21 |
--------------------------------------------------------------------------------
/docs/other/purpose-1.md:
--------------------------------------------------------------------------------
1 | # Purpose
2 |
3 |
4 | ## Why?
5 |
6 | Yes, before you ask, yes I _know_ that meaningful commit messages are meaningful to future me and other developers in understanding intent or the reason for a change.
7 |
8 | But I also find that the majority of commits I make have messages that could be generated programmatically. Based on the _pareto_ principle, probably 80% of them. The messages are easy to compute, or the change is so small (a few lines changed) that it does not have much meaning on its own until the "feature" or "fix" is complete through many commits (formalized with a Pull Request or tag). And sometimes I am working on a small personal project or writing docs (which are not code), so it matters to me more than I can commit frequently than every message is meaningful and handwritten.
9 |
10 | Additionally, there are some messages which are easy to figure out and write using an algorithm and not so nice to type precisely. e.g. `Update 5 files and created 2 files`. Or `Created 2 files in foo/bar`. This can be prefaced with a manual "fix: " or "feat: " to make the intent clear.
11 |
12 | I do a lot of frequent, small commits to store my working changes - they are "atomic", at least when I make sure the code is working at each commit. That means that a lot of my commits are small incremental changes around adding or fixing code or docs, or renaming or moving files. There is friction to thinking of and typing the message - so when I am stressed or tired I might end up taking unwanted shortcuts. Like committing less often (then it's harder to figure out what broke and what change to undo). Or I write shorter and simple messages. `Add heading to README.md` becomes `Add heading` or `Update README`.
13 |
14 | Occasionally there is a commit, which needs explaining because it is a significant change in how things work, or I want to elegant capture why a lot of files changed for the same or a similar reason. So I like to write a descriptive message then. And the idea with this tool is that you can go always override the auto-generated message with your own (much like Github's default commit message).
15 |
16 |
17 | ## Other auto commit tools
18 |
19 | ### Github
20 |
21 | This tool is inspired by Github's own default commit messages - the grey text which is used if you don't enter a commit message.
22 |
23 | e.g.
24 |
25 | ```
26 | Created foo.txt
27 | Renamed foo.txt to bar.txt
28 | Updated bar.txt
29 | ```
30 |
31 | But while Github only lets you change one file at a time and generate a message based on that, this tool is smart enough to generate a message based on all the files to be committed.
32 |
33 | Also note that wisdom I read online about commit messages says that a commit should be imperative and not past tense, which also makes more sense when reverting a commit.
34 |
35 | e.g.
36 |
37 | ```
38 | Create foo.txt
39 | ```
40 |
41 | ### StackEdit
42 |
43 | - [Stackedit.io](https://stackedit.io)
44 |
45 | This tool lets you edit markdown files with a preview sidebar. And it automatically saves your files every few minutes, reducing friction.
46 |
47 | It generates a message that includes StackEdit in the name. e.g.
48 |
49 | ```
50 | README.md updated from https://stackedit.io/
51 | ```
52 |
--------------------------------------------------------------------------------
/docs/other/purpose-2.md:
--------------------------------------------------------------------------------
1 | # Purpose
2 |
3 | This is a VS Code extension - when you run it, it will look at files changed and then generate a commit message for you and add it to the commit message box (using the Git Extension's UI).
4 |
5 | It will look at files that are staged. If there are none, then it will look at all changed unstaged files instead. The result will be a simple, descriptive message that fits on one line.
6 |
7 | Note: At the moment a message can be generated based on one changed file.
8 |
9 | The idea of this tool is to take the friction out of writing a commit message so that you commit more frequently (such as with more one-line changes rather than mixing multiple unrelated changes together) and to save having to type out details that can be automatic or a tedious (mentioning long or difficult-to-type paths or filenames). This tool is not meant to be perfect - it gives a best guess for common cases.
10 |
11 | It is also not meant to replace writing messages by hand. It is a tool for myself mainly - 80% of my commit messages could have been written by an algorithm.
12 |
13 | And for the other 20% when the change is important to describe in detail or hard to figure out programmatically (like class renames or bug fix descriptions), then I can still write my manual commit message.
14 |
15 | This tool was inspired partly by GitHub's UI - it suggests a message in grey like "Update README.md" when I edit that file and if I enter nothing it uses that.
16 |
17 | There are many tools out there that will _lint_ your commit message, or provide you a multi-line template, or will insert something in it like "feat:" or an emoji. But AutoCommitMsg writes you entire commit message for you in one line.
18 |
19 |
28 |
--------------------------------------------------------------------------------
/docs/other/reference.md:
--------------------------------------------------------------------------------
1 | # Reference
2 |
3 | See my [git hooks](https://github.com/MichaelCurrin/dev-cheatsheets/blob/master/cheatsheets/git/hooks.md) reference.
4 |
5 |
6 | ## Prepare a commit message
7 |
8 | In `prepare-commit-msg` hook, assuming it is a Bash script.
9 |
10 | You can use echo/print lines to print out - this would be printed
11 | on a successful or failed git commit.
12 | If you want to actually write over the message you need to use the path to the commit message temp file.
13 |
14 | e.g.
15 |
16 | ```sh
17 | COMMIT_MSG_FILE=$1
18 | echo -n "$CHG" >$COMMIT_MSG_FILE
19 | ```
20 |
21 | Note writing of multi-line output to the file is needed like above.
22 |
23 | The file path will be like:
24 |
25 | ```
26 | $HOME/path/to/repo/.git/COMMIT_EDITMSG
27 | ```
28 |
29 | ## git status
30 |
31 | This will ignore untracked files and have machine-readable output (without color).
32 |
33 | ```sh
34 | CHG=$(git status -s -uno --porcelain)
35 | ```
36 |
37 | See more in my dev cheatsheets.
38 |
39 |
40 | ### Warning
41 |
42 | Note a weakness - if you rename a file and then modify it, then you can have A and M for one file.
43 |
44 | ```sh
45 | $ git status -s
46 | D src/test/main.test.ts
47 | AM src/test/single-file.test.ts
48 | ```
49 |
50 | But when adding first using CLI or UI, then it will be simplified.
51 |
52 | If the percent change is very small, then it will be converted to a rename.
53 |
54 | In this case, the files are different enough to not be collapsed as a rename. Note that no code was changed - the add command changes from above.
55 |
56 | ```sh
57 | $ git add -A
58 | $ git status -s
59 | D src/test/main.test.ts
60 | A src/test/single-file.test.ts
61 | ```
62 |
63 | Fortunately, this status will always run _after_ staging because of the hook flow (or extension use).
64 |
--------------------------------------------------------------------------------
/docs/other/terminal-hook.md:
--------------------------------------------------------------------------------
1 | # Terminal hook
2 | > Setup and use a prepare-commit-msg hook for terminal commits
3 |
4 | **Note** Using this script outside of the extension is on the roadmap but not done yet.
5 |
6 | You can use the core logic of this project _without_ using the VS Code Git extension pane. You can use it in a standalone terminal or another IDE's integrated terminal.
7 |
8 |
9 | ## Warning
10 |
11 | While VS Code does in fact honor a `prepare-commit-msg` hook, unfortunately
12 |
13 | - The hook **cannot** read from the UI message box and
14 | - The message is _always_ written out without confirmation.
15 |
16 | So use an enable commit hook message hook inside VS Code with caution, but outside VS Code you are safe.
17 |
18 | ### Alias
19 |
20 | Another way around the issue in VS Code, is instead of using a commit hook, rather use an **alias** command like `git c` - see the [Shell README](/shell/README.md) for alias instructions. That could run the Auto Commit Msg script and pass the result to `git commit -m '...'`. Also, a hook only works when set up in a project, while an alias can work anywhere.
21 |
22 |
23 | ## Reference
24 |
25 | Here is the flow for using any `prepare-commit-msg` hook, not specific to this project:
26 |
27 | 1. Edit a file in your project.
28 | 1. Commit on command-line.
29 | 1. Prepare a commit message (this internally can look for the template as per the sample).
30 | 1. Override value with own message if desired.
31 | 1. Exit message editor view.
32 | 1. Commit is made.
33 | 1. Hook runs and the user sees a prepared message.
34 |
35 |
36 | ## Installation
37 |
38 | Note that, in the future, the installation steps here will change and be split into maybe a separate installation doc. One part is installing the hook in any repo using a file built with GH actions. Another is to build and use the file by hand, which is simpler to set up and will be become a development doc step once actions have been set up.
39 |
40 | ### Install system dependencies
41 |
42 | Install Node.js - see [instructions](https://gist.github.com/MichaelCurrin/aa1fc56419a355972b96bce23f3bccba).
43 |
44 | ### Clone
45 |
46 | ```sh
47 | $ git clone git@github.com:MichaelCurrin/auto-commit-msg.git
48 | $ cd auto-commit-msg
49 | ```
50 |
51 | ### Install hook
52 |
53 | Notes:
54 |
55 | - This flow covers how to add an executable script as a **git hook** in a project. This project was initially built around the Bash scripts in [shell](/shell/) as a proof of concept and you can continue to use one of those. Also, there was an idea to turn this TypeScript code from VS Code extension and re-purpose it as a standalone git hook for terminal use - but that doesn't work nicely in VS Code because a message hook ignores what you type in the message box and uses the hook's logic only.
56 | - This is very general for now - there is no Node or compile build step.
57 |
58 | For working on this project, set up a symlink from a hook in the repo to exist in `.git/hooks` directory. Adjust the first script name and path as needed but the last value must stay as is to be recognized by git.
59 |
60 | ```sh
61 | $ (cd .git/hooks && ln -s -f ../../prepare-commit-msg prepare-commit-msg)
62 | ```
63 |
64 | Use `-f` to overwrite the existing file.
65 |
66 | A `-r` relative flag would make this shorter but it is not standard across Linux and Bash.
67 |
68 | Check it:
69 |
70 | ```sh
71 | $ ls -l .git/hooks
72 | ```
73 |
74 | For other projects using this repo's hook - use `cp` or `curl` to add the hook to your repo. Or package and an installable Zip.
75 |
76 | Instructions to follow as this develops.
77 |
78 |
79 | ## Disable
80 |
81 | Remove the hook:
82 |
83 | ```sh
84 | $ rm .git/hooks/prepare-commit-msg
85 | ```
86 |
87 |
88 | ## Usage
89 |
90 | Perform a commit in the terminal. You'll see the prepared message appear.
91 |
92 | ```sh
93 | $ git commit
94 | $ git log
95 | ```
96 |
--------------------------------------------------------------------------------
/docs/other/unused.md:
--------------------------------------------------------------------------------
1 | # Unused
2 |
3 | Code that is no longer needed because approach changed, but kept in case it is needed again.
4 |
5 |
6 | ## Status
7 |
8 | These were for when the `git status` approach was used. Before the `git diff-index` approach was used.
9 |
10 | - `src/generate/action.ts`
11 | ```typescript
12 | /**
13 | * Extract single action from given X and Y actions.
14 | *
15 | * "Modified" must take preference over the others. Unfortunately, there is no way here to combine
16 | * update and move.
17 | */
18 | function _lookupStatusAction(x: string, y: string): string {
19 | if (ACTION[y as ActionKeys] === ACTION.M) {
20 | return ACTION.M;
21 | }
22 |
23 | return ACTION[x as ActionKeys];
24 | }
25 | ```
26 | - `src/git/cli.ts`
27 | ```typescript
28 | /**
29 | * Run `git status` with flags and return output.
30 | *
31 | * This will ignore untracked and remove color.
32 | */
33 | async function status(options: string[] = []) {
34 | return execute(getWorkspaceFolder(), "status", [
35 | "--short",
36 | "-uno",
37 | "--porcelain",
38 | ...options,
39 | ]);
40 | }
41 | ```
42 |
--------------------------------------------------------------------------------
/docs/quickstart.md:
--------------------------------------------------------------------------------
1 | # Quickstart
2 |
3 | How to install and run the extension in VS Code.
4 |
5 |
6 | ## Install
7 |
8 | Go to the Marketplace link below, then click the _Install_ button.
9 |
10 |