YoavKlein
YoavKlein

Reputation: 2703

How to use setuptools_scm?

I didn't quite understand how to use setuptools-scm.

From what I understand, this tool should derive a version number according to the SCM (git in my case) history. It basically uses the distance from the latest tag in order to derive this information.

Now, say I have a project in which we work as such: we have a main and develop branches. We work with SemVer, so we have a x.y.z version schema. Now, whenever we commit to develop, we'd like to have a latest package in our package registry. So if the latest version on the main branch is 1.2.3 for example, we'd like to get 1.2.3.dev1, 1.2.3.dev2, etc.

What I actually see happening is, that if I have 1.2.3 as my latest tag, setuptools-scm defines the next version as 1.2.4, plus, it adds a +g532hj.. to the version, which a registry such as PyPI Test for example doesn't accept.

Could someone explain exactly how is it used?

Upvotes: 20

Views: 10381

Answers (2)

Jakub Narębski
Jakub Narębski

Reputation: 323464

There is setuptools_scm_git_semver SemVer-compatible hook/plugin for setuptools_scm.

[build-system]
requires = [
    "setuptools",
    "setuptools_scm",
    "setuptools_scm_git_semver",
]
build-backend = 'setuptools.build_meta'

[tool.setuptools_scm]
version_scheme = "guess-next-rc"
local_scheme = "time-dot-node"
normalize = false
write_to = "VERSION.txt"

There is also alternative to setuptools_scm, namely setuptools-git-versioning, that uses git repo data (latest tag, current commit hash, time of version file modification, etc.) for building a version number.

[build-system]
requires = [ 
    "setuptools>=41",
    "wheel",
    "setuptools-git-versioning>=2.0,<3",
]
build-backend = "setuptools.build_meta"

[project]
dynamic = ["version"]

[tool.setuptools-git-versioning]
enabled = true
version_file = "VERSION.txt"
count_commits_from_version_file = true  # <--- enable commits tracking
dev_template = "{tag}.dev{ccount}"  # suffix for versions will be .dev
dirty_template = "{tag}.dev{ccount}"  # same thing here

Upvotes: 1

Terseus
Terseus

Reputation: 2212

Yeah, that behavior from setuptools-scm it's surprising and hard to understand, while the doc doesn't give it (in my opinion) proper emphasis, it's documented right there.

The thing is, setuptools-scm get the current version if you're in a tagged commit, when you're not (most of the time) it tries very hard to "guess" the next version dividing it in two parts, the "version" and the "local" part, with the format {version}+{local}, both of them can be configured.

The {version} part is controlled by the version_scheme directive, which by default:

Automatically guesses the next development version (default). Guesses the upcoming release by incrementing the pre-release segment if present, otherwise by incrementing the micro segment. Then appends .devN. In case the tag ends with .dev0 the version is not bumped and custom .devN versions will trigger a error.

The {local} part is controlled by the local_scheme directive, which by default:

adds the node on dev versions and the date on dirty workdir (default)

Unfortunately there isn't a value of version_scheme which does exactly what you want (add a plain .devX) but you can get away with one of these:

  • post-release

generates post release versions (adds .postN)

  • no-guess-dev

Does no next version guessing, just adds .post1.devN

About the {local} part you can disable it completely using in local_scheme the value no-local-version.

omits local version, useful e.g. because pypi does not support it

Hope this helps.

Edit: Sorry, my first post was quite incomplete since I completely missed the local_scheme part at first.

Upvotes: 17

Related Questions