GithubHelp home page GithubHelp logo

mainrs / git-cm Goto Github PK

View Code? Open in Web Editor NEW
92.0 1.0 7.0 281 KB

Easily create conventional-commits friendly commit messages.

License: Apache License 2.0

Rust 100.00%
cli git git-subcommand conventional-commits

git-cm's Introduction

git-cm

A git subcommand for creating conventional-friendly commit messages.

Installation

Either compile from source or install via crates.io:

$ cargo install git-cm --locked

For macOS, you can install git-cm via homebrew:

$ brew install sirwindfield/tap/git-cm

Usage

Instead of using git commit to commit changes, simply run git cm. This will start the questioning process and commit the message once you're done.

You also have to specifiy which types of commits your project supports. Just add the following to your Cargo.toml:

[package.metadata.commits]
defaults = true

# This is optional
[[package.metadata.commits.type]]
name = "xyz"
desc = "A custom command"

Example run

Example run GIF

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

git-cm's People

Contributors

dbofmmbt avatar dependabot[bot] avatar mainrs avatar maksyms avatar nobles5e avatar tbarusseau avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

git-cm's Issues

Allow to only include a sub-part of the default commit types

Currently, default types are either all-in or none. It would be nice to have an option that would allow someone to only use certain parts of it:

[package.metadata.commits]
include = ["feat", "fix", "refactor"] # maybe `use` as a key fits better here...

Panic when no branch is available

This most certainly happens when performing the first commit inside a repository. For a workaround, create an empty first commit:

git commit --allow-empty -m "root commit"

Reduce compilation time

The tool is certainly not big and some dependencies take long to compile (serde, console). Maybe smaller alternatives are available.

Possibilities:

  • remove git2 dependency and call git methods through std::command::Command.
  • remove serde and manually use the toml crate.

Suggestions welcome ^.^

Validate command line arguments at startup

When running git cm with a misspelled/completely wrong argument on the command line, it only fails at the very end:

$ git cm woops!
✔ Select the type of change that you're committing: · perf: A code change that improves performance
✔ Denote the scope of this change (compiler, runtime, stdlib, etc.): · 
✔ Write a short, imperative tense description of the change: · 
✔ Provide a longer description of the change: · 
✔ Are there any breaking changes? · no
✔ Does this change affect any open issues? · no
thread 'main' panicked at 'Failed to open git repository: Error { code: -3, klass: 2, message: "failed to resolve path \'woops!\': No such file or directory" }', /home/tbarusseau/.cargo/registry/src/github.com-1ecc6299db9ec823/git-cm-0.1.1/src/git.rs:79:16
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

It should fail at the very beginning.

Add editor mode

A CLI flag that, instead of running the dialog, opens up an editor with a basic template that people can edit.

Fix CI lint checks

The error occurs because no toolchain has been specified. The default one (1.41.0) should be used however.

Could we have a better line editor?

While I was using git-cm, I noticed that the line editor which gets our information in each question is very limited. Could we try to find another one which has more features?

Some Limitations

  • We can't use the arrow keys to go back in the text position and delete a typo in the middle or something like that. (#61 should solve it)
  • We can't use CTRL + left/right arrow to navigate around the words.
  • ...

[Feature Request] Support config through a unified file

As of now, commit types can be specified in Cargo.toml, which works fine for Rust projects. However, this isn't suitable in non-Rust projects.

I'd like to suggest using a unified config file everywhere, say git-cm.toml or (whatever file type is preferable for parsing) for easy use of git-cm regardless of the project.

"git cm" fails if invoked from a directory other than git repository root

I have a project checked out into /home/maksym/Work/project. I'm trying to run git cm from /home/maksym/Work/project/rust/src/ directory. The command fails with the following error:

thread 'main' panicked at 'Failed to open git repository:
Error { code: -3, klass: 6, message: "could not find repository from \'.\'" }', 
/home/maksym/.cargo/registry/src/github.com-1ecc6299db9ec823/git-cm-0.1.2/src/git.rs:106:57
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

When the same command is run from /home/maksym/Work/project, it works flawlessly.

Configurable editor mode templates

Different templates that people can use when they run the CLI in editor mode. Maybe the selection of the type is still showing but after that we switch to the standard editor of the user.

auto-update binary

Since the tool should be something that is seemless for most users, I'd like to add an auto-updater to the binary. There are crates out there that work over GitHub releases (self_update).

An opt-in flag should be added to the configuration.

Add a flag that allows for compact output

As of now, all commit messages seem to be spaced out:

    ci(CircleCI)!: Renamed main build job
    
    Renamed main build job from `build-base` to `base`
    
    BREAKING CHANGE: The `build-base` is now named `base`
    
    123

Allowing the user to generate a more compact message with -c/--compact would be neat:

    ci(CircleCI)!: Renamed main build job
    Renamed main build job from `build-base` to `base`
    BREAKING CHANGE: The `build-base` is now named `base`
    123

Lines should be wrapped around a specific number of words

I suggest a 72/80 format or 50/80, where the first number denotes the length of the first line, e.g. the type, scope and short message of the commit. The second one is the character constraint for all other lines.

50/80 is the "classic" format that the Linux kernel tries to stick to. 72/80 is the one that goes well with GitHub, as GitHub truncates the first line using three dots (...) if it is longer than 72.

Nice to have: Configurable

Add a human-readable tag to the issue references in the commit

Inserting issue references in a git cm prompt results in the references being written without any additional information in the commit message, like so:

    ci(CircleCI)!: Renamed main build job
    
    Renamed main build job from `build-base` to `base`
    
    BREAKING CHANGE: The `build-base` job is now named `base`
    
    123

In this case, I think it would make more sense to add a Referenced issues: before the lone 123.

Allow custom questions to be specified

This would allow people to implement their own questions. A list of possible additions (these are all footers to be compatible with the specification):

  • Signed-by
  • Approved-by
  • Closes/Fixes
  • PR
  • Reverts

This goes probably alongside of #12, allowing a total customization.

Add support for keyboard shortcuts on multi-selection menus

Currently, running git cm offers a quite lengthy menu:

$ git cm
? Select the type of change that you're committing: ›
❯ feat: A new feature
  test: Adding missing tests or correcting existing tests
  ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, GitHub Actions)
  build: Changes that affect the build system or external dependencies (example scopes: cargo, bazel, make)
  style: Changes that do not affect the meaning of the code (white-space, formatting, etc)
  chore: Other changes that don't modify src or test files
  perf: A code change that improves performance
  fix: A bug fix
  revert: Reverts a previous commit
  docs: Documentation only changes
  refactor: A code change that neither fixes a bug nor adds a feature

Being able to instantly select one with a key-press would make it really faster to use.

I'm thinking about some letter hints, which are indicated by a line below the relevant character.

Repository with no staged changes does still produce a commit hash

Running git-cm on a repository with no staged changes does still go through the dialog and prints out the commit hash, but nothing gets added to the repository.
This should be fixed by adding a check that the repository contains staged files and if not, print an error message on stderr and terminate the process.

Build failing

I tried to install with cargo install git-cm but the build is failing.

Any ideas why this is happening, or is the release just broken?

Log
ole@ole-desktop:~$ cargo install git-cm
    Updating crates.io index
  Installing git-cm v0.2.3
   Compiling libc v0.2.112
   Compiling cfg-if v1.0.0
   Compiling autocfg v1.0.1
   Compiling proc-macro2 v1.0.36
   Compiling unicode-xid v0.2.2
   Compiling pkg-config v0.3.24
   Compiling syn v1.0.85
   Compiling ppv-lite86 v0.2.16
   Compiling serde_derive v1.0.133
   Compiling tinyvec_macros v0.1.0
   Compiling matches v0.1.9
   Compiling serde v1.0.133
   Compiling memchr v2.4.1
   Compiling bitflags v1.3.2
   Compiling log v0.4.14
   Compiling percent-encoding v2.1.0
   Compiling remove_dir_all v0.5.3
   Compiling regex-syntax v0.6.25
   Compiling unicode-bidi v0.3.7
   Compiling lazy_static v1.4.0
   Compiling unicode-width v0.1.9
   Compiling either v1.6.1
   Compiling hashbrown v0.11.2
   Compiling anyhow v1.0.52
   Compiling strsim v0.10.0
   Compiling zeroize v1.4.3
   Compiling termcolor v1.1.2
   Compiling textwrap v0.14.2
   Compiling once_cell v1.9.0
   Compiling tinyvec v1.5.1
   Compiling form_urlencoded v1.0.1
   Compiling memoffset v0.6.5
   Compiling indexmap v1.7.0
   Compiling os_str_bytes v6.0.0
   Compiling regex v1.5.4
   Compiling quote v1.0.14
   Compiling unicode-normalization v0.1.19
   Compiling getrandom v0.2.3
   Compiling terminal_size v0.1.17
   Compiling nix v0.23.1
   Compiling which v4.2.2
   Compiling atty v0.2.14
   Compiling jobserver v0.1.24
   Compiling idna v0.2.3
   Compiling rand_core v0.6.3
   Compiling console v0.14.1
   Compiling clap v3.0.5
   Compiling cc v1.0.72
   Compiling rand_chacha v0.3.1
   Compiling url v2.2.2
   Compiling rand v0.8.4
   Compiling libz-sys v1.1.3
   Compiling libgit2-sys v0.12.26+1.3.0
   Compiling tempfile v3.2.0
   Compiling edit v0.1.3
   Compiling dialoguer v0.8.0
   Compiling ctrlc v3.2.1
   Compiling toml v0.5.8
   Compiling cargo_toml v0.9.2
   Compiling git2 v0.13.25
   Compiling git-cm v0.2.3
error[E0432]: unresolved import `clap::Clap`
  --> /home/ole/.cargo/registry/src/github.com-1ecc6299db9ec823/git-cm-0.2.3/src/main.rs:10:5
   |
10 | use clap::Clap;
   |     ^^^^^^^^^^ no `Clap` in the root

error[E0432]: unresolved import `clap::Clap`
 --> /home/ole/.cargo/registry/src/github.com-1ecc6299db9ec823/git-cm-0.2.3/src/args.rs:1:5
  |
1 | use clap::Clap;
  |     ^^^^^^^^^^ no `Clap` in the root

error: cannot determine resolution for the derive macro `Clap`
 --> /home/ole/.cargo/registry/src/github.com-1ecc6299db9ec823/git-cm-0.2.3/src/args.rs:4:10
  |
4 | #[derive(Clap, Debug)]
  |          ^^^^
  |
  = note: import resolution is stuck, try simplifying macro imports

error: cannot find attribute `clap` in this scope
 --> /home/ole/.cargo/registry/src/github.com-1ecc6299db9ec823/git-cm-0.2.3/src/args.rs:5:3
  |
5 | #[clap(author, version)]
  |   ^^^^
  |
  = note: `clap` is in scope, but it is a crate, not an attribute

error: cannot find attribute `clap` in this scope
 --> /home/ole/.cargo/registry/src/github.com-1ecc6299db9ec823/git-cm-0.2.3/src/args.rs:8:7
  |
8 |     #[clap(long, short = 'e')]
  |       ^^^^
  |
  = note: `clap` is in scope, but it is a crate, not an attribute

error: cannot find attribute `clap` in this scope
  --> /home/ole/.cargo/registry/src/github.com-1ecc6299db9ec823/git-cm-0.2.3/src/args.rs:11:7
   |
11 |     #[clap(name = "REPO", default_value = ".", parse(from_os_str))]
   |       ^^^^
   |
   = note: `clap` is in scope, but it is a crate, not an attribute

error[E0599]: no function or associated item named `parse` found for struct `args::App` in the current scope
  --> /home/ole/.cargo/registry/src/github.com-1ecc6299db9ec823/git-cm-0.2.3/src/main.rs:71:25
   |
71 |     let app: App = App::parse();
   |                         ^^^^^ function or associated item not found in `args::App`
   |
  ::: /home/ole/.cargo/registry/src/github.com-1ecc6299db9ec823/git-cm-0.2.3/src/args.rs:6:1
   |
6  | pub struct App {
   | -------------- function or associated item `parse` not found for this
   |
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `parse`, perhaps you need to implement it:
           candidate #1: `Parser`

Some errors have detailed explanations: E0432, E0599.
For more information about an error, try `rustc --explain E0432`.
error: failed to compile `git-cm v0.2.3`, intermediate artifacts can be found at `/tmp/cargo-install6MsLu5`

Caused by:
  could not compile `git-cm` due to 7 previous errors
ole@ole-desktop:~$ 


Move to @conventional-commits-rs

Hey!

Quick update on the future of this crate. I am in the process of building the conventional commits ecosystem over at @conventional-commits-rs for Rust based on already existing crates by forking them if unmaintained or complete new re-writes if that improves ergonomics and code quality.

Currently on the plan are:

  • commitlint, a simple commit linting tool. Can be used to verify that your commit matches organization-specific settings.
  • cargo-semantic, a cargo plugin used to create semantic releases. It automatically detects the changes and runs checks, tests, pushes the new tag and publishes to crates.io
  • Some kind of changelog generator.

Almost done are some generic utility crates for parsing and type definitions.

This repository will move in the near future over to the organization once I have implemented the linting tool. This puts all related crates into one place, allow for easier collaboration and (hopefully!) keep the fully automated release toolbox dream alive!

Cheers!

Allow per-repo installation

It would be nice if I could check in git-cm along with my other dev dependencies instead of relying on a global install, kind of like how Commitizen allows. That way I could use this alongside rusty-hook to automate creating conventional commits in my repo without telling users to globally install git-cm. I'm not sure if this is something that's possible (installing per-project binaries), but it would be nice to have.

The binary executable depends on source code to run

For example if I install git-cm with cargo install git-cm, and then remove the git-cm source code from ~/.cargo/registry/src. Running git-cm will give the following error

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: No such file or directory (os error 2)

Caused by:
    No such file or directory (os error 2)', <home>/.cargo/registry/src/github.com-1ecc6299db9ec823/git-cm-0.2.2/src/main.rs:19:37
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

User-specified template file instead of interactive dialog

I am writing regarding the reddit conversation we had and will shortly recap the idea to reduce user-time on filling the commit message. Sorry for the long post, but I wanted to make sure what I do mean. This feature would include writing a hopefully very simple grammar to check the templates for conventional commits conformance.
The template then can be checked locally and by the CI against commit messages. Please let me know what you think of the idea and what your practical experience is with conventional commits.

The idea

Have a template to create the commit "popup as fulltext" in .conv_commit. The idea is to use parse prefix and postfix to check conformance to the content of the commit message with the following lines (as block).
The overall structure is (pseudocode later to be replaced by grammar file):

template-identifier template-name
template-version-identifier template-version
commit-identifier hashrange (first hash or dots - last hash or dots)
block-identifier expression; text for user; (amount lines)
optional definitions for expression
default-user space
...
block-identifier expression; text for user; (amount of lines)
(default-user space)
(default-user space)
(default-user space)

template-version here defines the version of git-scm the template was created with. Incompatibilities/CVEs etc then can be checked at startup.
One instance of such template, we call it bug.convcom, could look like

template bugs
version 0.0.1
commits [initialhash - ..]
fix(scope): #issuenr;; (1 lines)

freetext; long description, additional informations, etc; ([0-x] lines)

key: #value; fixed and closed issues; ([1-x] lines)
key isof {Fixes, Closes, PR-Close}

Comma-separated values and line-separated keys are implicit knowledge, so not part of the template. Annoyingly hard would be the parsing of expressions key isof {Fixes, Closes, PR-Close}, so saving these as part of the program could be easier for maintenance.

The user would see the following, (I do assume we can somehow make sure the commit is rebased against master, so the according script-template will be executed or an error message returned)

#fix(scope): #issuenr;; (1 lines)

#      freetext; long description, additional informations, etc; ([0-x] lines)

#key: #value; fixed and closed issues; ([1-x] lines)
#key isof {Fixes, Closes, PR-Close}

The empty space is to indicate, that freetext is no keyword. Aside of that the user should only care about the template, when issues occur.

Use templates for custom commit message formats

I do think that this would be a great addition to the CLI. We could provide a template that reflects the conventional commits specification but allow people to customize the template if they want to.

The template engine would need the following features:

  • variable substitutions to insert the user's answers.
  • conditional branches to allow for basic logic. This allows to not apply certain elements if no text has been entered.

A list of possible engines can be found here: https://lib.rs/keywords/template

Add option to open a text editor for the commit's description

It feels nice to write short stuff like the scope and the header of the commit right from the CLI, but when it comes to a potentially larger text such as the description of the commit, I'd rather write it on a text editor.

Currently, we have the -e flag, but this option makes the whole process occur in the text editor, which isn't as convenient as having the CLI questioning you about the smaller fields.

Add support for signed commits

Edit: I did a prototype using gpgme, but that only works for Unix systems. I couldn't find an alternative way to sign commits on Windows. For that we'd have to:

  1. Create the commit buffer instead of committing directly (create_commit_buffer).
  2. Use OpenPGP to sign the contents of the commit_buffer.
  3. Call commit_signed on the repository instance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.