https://github.com/mroth/semverdesc
:dart: git describe with semantic version compatible names
https://github.com/mroth/semverdesc
cli devtools git semantic-versioning semver
Last synced: 12 months ago
JSON representation
:dart: git describe with semantic version compatible names
- Host: GitHub
- URL: https://github.com/mroth/semverdesc
- Owner: mroth
- License: lgpl-3.0
- Created: 2019-05-10T21:10:22.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2021-12-12T02:02:10.000Z (over 4 years ago)
- Last Synced: 2024-11-12T13:29:57.983Z (over 1 year ago)
- Topics: cli, devtools, git, semantic-versioning, semver
- Language: Go
- Homepage:
- Size: 62.5 KB
- Stars: 4
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# git semver-describe :dart:

[](https://goreportcard.com/report/github.com/mroth/semverdesc)
[](https://godoc.org/github.com/mroth/semverdesc)
Extends `git describe` to return [Semantic Versioning v2.0](https://semver.org)
compatible names by default:
```
$ git describe --tags
v0.2.1-15-gd71dd50
$ git semver-describe --tags
v0.2.1+15.gd71dd50
$ git semver-describe --tags --legacy
v0.2.1-15-gd71dd50
```
## Usage
For the most part, this is a drop-in replacement for `git describe`, with nearly
identical option syntax.
The official git-describe has [tons of
options](https://git-scm.com/docs/git-describe), a few of which are not
supported here, but I believe we have covered the entire subset of options that
are potentially useful when using git tags for semantic versioning:
```
$ git semver-describe --help
usage: git semver-describe [] []
or: git semver-describe [] --dirty
--all use any ref
--tags use any tag, even unannotated
--long always use long format
--first-parent only follow first parent
--abbrev use digits to display SHA-1s (default 7)
--exact-match only output exact matches
--candidates consider most recent tags (default 10)
--match only consider tags matching
--exclude do not consider tags matching
--dirty [="-dirty"] append on dirty working tree
--path describe repository at (default $PWD)
--trim trim from results
--legacy format results like normal git describe
```
The last three flags: `--path`, `--trim` and `--legacy` are some handy extra
features unique to semver-describe.
## Installation
Download from the [Releases] page and put somewhere in your `$PATH`.
Homebrew users can `brew install mroth/tap/git-semver-describe`.
[Releases]: https://github.com/mroth/semverdesc/releases
## API
There is also a Go library encapsulating a lot of this functionality, for more
information see the [GoDocs](https://godoc.org/github.com/mroth/semverdesc).
## Detailed Discussion
_:warning: Warning: this is likely only interesting to you if really care about
semantic versioning..._
Firstly familiarize yourself with actual semver specification, this discussion
likely won't make much sense otherwise.
**git semver-describe** essentially takes the following philosophy: only tagged
refs are part of semver version precedence (including for pre-release versions),
everything else goes in the build metadata field.
How do these strings differ?
Here are some of the current issues in integrating `git describe` with semantic
versioning git tags:
- Git describe output would increment the pre-release patch version. But
"prelease" versions come before a specific release. During early development,
you don't necessarily know if the next release will be a major/minor/patch
release.
- The output of git describe looks close to valid semver to the naked eye, but
does not actually adhere to the specification.
- Once you tag an actual pre-release version (e.g. ), git describe's output
drifts even further off from the specification. See the example below.
Consider the following sequence in both git describe and semver-describe:
| `git semver-describe` | `git describe` | comments |
|-------------------------|--------------------------|---------------------------------|
| `v0.8.3` | `v0.8.3` | TAG: currently released version |
| `v0.8.3+1.g1a2b3c4` | `v0.8.3-1-g1a2b3c4`¹ | one commit later |
| `v0.8.3+2.g2b3c4d5` | `v0.8.3-2-g2b3c4d5` | two commits later |
| `v0.9.0-rc1` | `v0.9.0-rc1` | TAG: pre-minor-release |
| `v0.9.0-rc1+1.gd3adb33` | `v0.9.0-rc1-1-gd3adb33`² | one commit later |
| `v0.9.0` | `v0.9.0` | TAG: minor-release made |
1. This "describe" version is now something that comes _before_ the previous
release in semver ordering.
2. This doesn't parse in SemVer v2.0 at all, but if it did, a typical
interpretation would be something that also came before the previous
`v0.9.0` release.
If you were to re-order those commits by semantic versioning precedence, rather
than commit order, you would get:
```
| git semver-describe | git describe |
|-------------------------|--------------------------|
| v0.8.3 | v0.8.3-1-g1a2b3c4* |
| v0.8.3+1.g1a2b3c4 | v0.8.3-2-g2b3c4d5* |
| v0.8.3+2.g2b3c4d5 | v0.8.3* |
| v0.9.0-rc1 | v0.9.0-rc1-1-gd3adb33* |
| v0.9.0-rc1+1.gd3adb33 | v0.9.0-rc1* |
| v0.9.0 | v0.9.0 |
*: Out-of-order: SemVer ordering differs from commit history.
```
There are some other benefits:
- As a happy coincidence, the `+` character that precedes build metadata in
SemVer v2.0 better expresses the situational context possible during a git
describe: something that comes *after* a point in history, rather than
*before* something to come.
## Integration with various build tools
### Go
Configure a placeholder variable in your main package.
```go
package main
var (
version = "unknown"
)
```
You will then override this variable value in your build command:
```shell
$ VERSION=$(git-semver-describe --tags) go build -ldflags="-X main.version=$VERSION"
```
Or for another example, using a Makefile:
```makefile
VERSION := $(shell git-semver-describe --tags --trim=v)
build:
go build -ldflags="-X main.version=${VERSION}"
```
For a more involved example, see this project itself.
## Related Work
- A similar versioning schematic was implemented as a NodeJS library, which
looks to function by parsing and wrapping the output from shell commands sent
to git: https://www.npmjs.com/package/git-describe.
- Some relevant discussion on the semver spec itself: semver/semver#106, semver/semver#106, semver/semver#106