jgrodziski / metav

Release and Versioning of Clojure projects using tools.deps
Eclipse Public License 1.0
68 stars 12 forks source link

Bumping edge case when bumping a dirty version. #7

Closed JeremS closed 5 years ago

JeremS commented 5 years ago

Hi,

I came across an uncaught exception while playing with metav. Here is how it works.

Let's say I have a repo setup this way:

Let's say everything is committed in project1 while some stuff remains uncommitted in project2, every project is version 0.1.0. If I release a patch from root/project1, metav will allow the bump from 0.1.0-XXXX-DIRTY to 0.1.1-DIRTY creating a tag like project1-0.1.1-DIRTY.

Now if I wanna bump again, when metav creates its invocation-context, it parses the previous tag and will end up trying to do something like:

(let [[_ major minor patch] (re-matches #"(\d+)\.(\d+)\.(\d+)" "0.1.1-DIRTY")] ;=> [nil nil nil nil]
  (mapv #(Integer/parseInt %) [major minor patch])) ; => throws Integer/parse exception

I propose in this PR to change the use of re-matches for re-find. This way the regex would return the numbers we want. However I am not sure fixing the parsing is the good answer because I am not sure if the possibility of releasing a "DIRTY" version is intended behaviour.

Cheers,

Jeremy.

jgrodziski commented 5 years ago

Hi Jeremy,

I would say it should not be possible to release the repo while in a dirty state (even if the uncommited files are in another project of the monorepo as the build process could go up and use a file from another repo, say a common project where the released project may have dependencies with).

However, the bump in the semver namespace should work seamlessly on a dirty version and should not throw an exception, so I accept the PR. The correct behavior of metav should be to throw a proper exception stating that the repo is dirty and stopping the release process as determinism is broken. I should have a testing example to be sure of that behavior.

Jérémie,

jgrodziski commented 5 years ago

version 1.5.4 with that PR as patch was published on clojars

jgrodziski commented 5 years ago

Thanks for your contribution Jeremy, I greatly appreciate

JeremS commented 5 years ago

From what I gathered this behaviour of being able to release one clean module with other dirty modules in the monorepo comes from 2 things. If we keep with my example, project1 is clean, project2isn't.

To get the current version, metav will use something like:

git -C root-repo/project1 describe --long --match repo2-*.* --abbrev=4 --dirty=-DIRTY --always

Here I the -C root-repo/project1 doesn't matter, the "DIRTY" suffix will be used since git describe will care for the whole repo from /root-repo and root-repo/project2 is dirty. Thus in this state we get a dirty version.

However when we get to metav.git/assert-committed?, this check is based on the following git command:

git -C root-repo/project1 status --short root-repo/project1

And if there are any lines of text in the results, it will mean there are uncommitted things.

The problem is: since root-repo/project1 is clean, the targeted git status returns nothing, metav.git/assert-committed? doesn't find any committed files, everything is good to go.

And so we get a release with a dirty version. In some ways it looks like intended behaviour.