adamtabrams / change

A simple tool that automates generating and updating a changelog
GNU General Public License v3.0
75 stars 8 forks source link

Pre-commit hook #12

Closed pylang closed 2 years ago

pylang commented 3 years ago

Topic Adding a pre-commit hook

Explaination I'd like to automate generation of changelog + bump versions during release.

Example (using git flow):

> git flow release start 0.2.0
# Auto-generate changelog on release branch creation
> git status
changelog.md
version.tst
> git add .
> git commit -m "Bump 0.2.0"

Questions Would you consider adding a hook?

Links

adamtabrams commented 3 years ago

@pylang I haven't used pre-commit hooks before. I'll look into them and let you know what I think.

adamtabrams commented 3 years ago

@pylang Pre-commit looks like a pretty helpful tool. From my understanding, I would just need to create a valid .pre-commit-hooks.yaml file for this repo and make sure the tool is interfacing properly with pre-commit. Is that your understanding as well?

Additionally, I'm trying to understand the example you included in the issue description. I haven't used the git flow tool myself, so it's a little difficult to know for sure what git commands are implicit within git flow release start 0.2.0. It seems like your suggesting that change init would be run in this case? If that's so, I'm hesitant to implement that. change init only needs to be run once for a given repo, and it's really good to have users double checking this step because plenty can go wrong. Seems like automating something that only happens once doesn't have much payoff, but maybe I'm misunderstanding what you meant.

Next, I'm wondering which change commands you think would be most helpful. It looks like I can easily offer multiple versions of the command that users can choose from. I can think of 4 useful options: change, change tag, and change post as individual options, as well as change all as another option?

Lastly, when you say "+ bump versions during release" are you just referring to the git version (which change tag is currently capable of) or are you also referring to updating the version elsewhere in the repo?

pylang commented 3 years ago
Clarifications

Yes, you have the right understanding on implementing hooks. See also the resources below on examples implementing the config file.

In the end, which ever commands achieved the "update changelog + bump files and tags" on releases, that would be great. This idea models standard-version - an npm implementation of the mentioned behavior from conventional changelog. I haven't found a python equivalent, but this repo, as a hook, seems to have potential.

As to triggering change init, I hadn't thought about that in particular.

Regarding commands, I'm not sure which commands to recommend yet. I'd have to play with change some more.

Details `git flow release` is a command that creates a new branch dedicated to bumping and releasing. All you do in that branch is: - bump versions in files - close the branch - update the tag during the merge commit That's all it does. I mentioned `git flow` since it is a concrete example I use, but you would likely want something more general. Example, the concept of a "release branch" isn't generic. More commonly, a release is a particular merge commit associated with an updated git tag. So then you might want a hook to trigger `change ...` on [pre-/post-merge commits][2]. Following the merge commit, at minimum, you'd have an **updated changelog**. This presumes you have some kind of changelog already. However, as mentioned you might have files that have version info too e.g. `_versions.py`, `setup.[py|cfg]`, `pyproject.toml`. The version in these files might influence the latest tag, which then affects the latest changelog. The question here is - what is a general way to automate bumping version info in various files? That might be a separate objective, but I suspect the user could add a script that can be run to update versions in certain files when this hook is triggered (similar to [`standard-version`'s lifecycle scripts][5]). So maybe developing the hook might look like this: - hook v1: bump tag + update changelog (requires empty or existing changelog) - hook v2: allow custom user scripts to bump versions in other files
Resources
adamtabrams commented 3 years ago

@pylang So I added the --bump flag which allows change to interact with a user-created script to version bump a project. I also added a first attempt at the pre-commit-hook file. After reading the documentation, it looks like users can still pass arguments to the hook. So this one hook should let users implement any of the change commands and features. I'm hoping that we can figure out if there's any further modifications needed.

pylang commented 3 years ago

Many thanks. I'm excited to look into this. It might take me some time to look through the CLI.

I had some trouble installing the hook.

InvalidManifestError
# .pre-commit-config.yaml
-   id: isort
-   repo: https://github.com/adamtabrams/change.git
    rev: 0.14.1
    hooks:
    -    id: change

Seems this configuration complains of a missing .pre-commit-hooks.yaml file.

> git add .
> git commit
An error has occurred: InvalidManifestError: 
...

I don't see it included the zip. That might be why it's complaining.

I then tried grabbing from the commit:

# .pre-commit-config.yaml
-   id: isort
-   repo: https://github.com/adamtabrams/change.git
    rev: 4fcbcd7ac529fa2cd5813f596d649f69b587fb22
    hooks:
    -    id: change

and got this error:

An error has occurred: InvalidManifestError: 
==> At Hook(id='change')
==> At key: stages
=====> Expected array but got 'str'
pylang commented 3 years ago

In running change, I'm getting some errors

> git tag 0.1.0
> change init
grep: Invalid range end
grep: Invalid range end
grep: Invalid range end
grep: Invalid range end
created CHANGELOG.md
...

I've tried adding more commits, and update via change, but the changelog only includes tags, not commits.

## [Unreleased]

## [0.3.0] - 2021-05-08
## [0.2.0] - 2021-05-08
## [0.1.0] - 2021-05-08
...

I'll look closer at the docs to see if I'm missing something.


UPDATE: I get it to work on Window GitBash, but doesn't work on Debian so far.

I can reproduce the error using the commandline in this container (click JupyterLab, then File -> New -> Terminal ).

I tried these lines.

# Error
>   grep -e "^[A-z]*: " -e "^[A-z]*(.*): " \
        -e "^[*-] *[A-z]*: " -e "^[*-] *[A-z]*(.*): " \
    "foo"
grep: Invalid range end
grep: Invalid range end
grep: Invalid range end
grep: Invalid range end

Seems to work if I escape some range characters:

# Works
>   grep -e "^[A\-z]*: " -e "^[A\-z]*(.*): " \
        -e "^[*-] *[A\-z]*: " -e "^[*-] *[A\-z]*(.*): " \
    "foo"
adamtabrams commented 3 years ago

@pylang What OS and setup are you using when you get these errors?

Also, using the setup that gives you errors, would you clone the change repo and run ./run-test

pylang commented 3 years ago

I'm running a flavor of Debian. On my system I got 37 failures. The output shows similar grep errors.

I also got failures running tests on a fresh install of Ubuntu focal LTS.


Ran it on docker Ubuntu focal. It passed.

adamtabrams commented 3 years ago

@pylang Is the version of grep in the dockerized Ubuntu different that the versions used when the tests were failing for you?

pylang commented 3 years ago

I have an earlier version of grep (3.3) on my original VM, but the grep versions are newer and the same on both Ubuntu focal LTS (VM) and Ubuntu focal (docker). They are also both using bash.

Passing - again I run the following to launch docker.

sudo docker run --rm -it ubuntu:focal

Inside

apt update -y && apt install git git config --global user.name foo git config --global user.email @.*** git clone https://github.com/adamtabrams/change.git cd change ./run-tests

Failing - all other attempts I get errors.

pylang commented 3 years ago

I've created another issue to isolate the grep bug from the main topic. The last pertinent issue was related to installing the hook.

I see it's been edited. I'll take another look.

adamtabrams commented 3 years ago

@pylang I want to check in on this issue. Do you have any updates on the status of this?

adamtabrams commented 2 years ago

Closing base on non-responsiveness