Skip to content

Commit 8f491df

Browse files
committed
setup: use setuptools-scm to generate the version
This commit changes the versioning scheme of non-release versions of mkosi to align with the standard Python version scheme [1]. Unfortunately this scheme is not fully compatible with the UAPI group version format specification. Concretely, this changes 26~devel to 25.3.post1.dev244+g0eac3718 The used format ensures that for prereleases the following inequalities still hold 25.3 < 25.3.post1.dev244+g0eac3718 < 25.4 < 26 Usage of this new format has the following benefits: 1. It is compatible with PyPI and allows publishing mkosi there in the future 2. Since it contains the number of commits since the last tag as well as part of the commit hash in the "local part" of the version, it becomes easier for bug reporters to show the version they are on no matter how mkosi has been installed. 3. The version no longer needs to be managed manually. The current implementation moves the version from mkosi/sandbox.py to a new file _version.py that obtains the version either via importlib metadata (in case mkosi has been installed) or by calling setuptools-scm directly, to support the bin/ shims. Since the version is no longer available in mkosi/sandbox.py, it passed as an environment variable for scripts. [1] https://packaging.python.org/en/latest/specifications/version-specifiers/
1 parent 45761bf commit 8f491df

File tree

9 files changed

+70
-14
lines changed

9 files changed

+70
-14
lines changed

mkosi/__init__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from pathlib import Path
2828
from typing import Any, Optional, Union, cast
2929

30+
from mkosi._version import __version__
3031
from mkosi.archive import can_extract_tar, extract_tar, make_cpio, make_tar
3132
from mkosi.bootloader import (
3233
efi_boot_binary,
@@ -127,7 +128,6 @@
127128
MOUNT_ATTR_RDONLY,
128129
MS_REC,
129130
MS_SLAVE,
130-
__version__,
131131
acquire_privileges,
132132
have_effective_cap,
133133
join_new_session_keyring,
@@ -598,6 +598,7 @@ def run_configure_scripts(config: Config) -> Config:
598598
SRCDIR="/work/src",
599599
MKOSI_UID=str(os.getuid()),
600600
MKOSI_GID=str(os.getgid()),
601+
MKOSI_VERSION=__version__,
601602
)
602603

603604
if config.profiles:
@@ -639,6 +640,7 @@ def run_sync_scripts(config: Config) -> None:
639640
MKOSI_UID=str(os.getuid()),
640641
MKOSI_GID=str(os.getgid()),
641642
MKOSI_CONFIG="/work/config.json",
643+
MKOSI_VERSION=__version__,
642644
CACHED=one_zero(have_cache(config)),
643645
)
644646

@@ -764,6 +766,7 @@ def run_prepare_scripts(context: Context, build: bool) -> None:
764766
MKOSI_UID=str(os.getuid()),
765767
MKOSI_GID=str(os.getgid()),
766768
MKOSI_CONFIG="/work/config.json",
769+
MKOSI_VERSION=__version__,
767770
WITH_DOCS=one_zero(context.config.with_docs),
768771
WITH_NETWORK=one_zero(context.config.with_network),
769772
WITH_TESTS=one_zero(context.config.with_tests),
@@ -833,6 +836,7 @@ def run_build_scripts(context: Context) -> None:
833836
MKOSI_UID=str(os.getuid()),
834837
MKOSI_GID=str(os.getgid()),
835838
MKOSI_CONFIG="/work/config.json",
839+
MKOSI_VERSION=__version__,
836840
WITH_DOCS=one_zero(context.config.with_docs),
837841
WITH_NETWORK=one_zero(context.config.with_network),
838842
WITH_TESTS=one_zero(context.config.with_tests),
@@ -907,6 +911,7 @@ def run_postinst_scripts(context: Context) -> None:
907911
MKOSI_UID=str(os.getuid()),
908912
MKOSI_GID=str(os.getgid()),
909913
MKOSI_CONFIG="/work/config.json",
914+
MKOSI_VERSION=__version__,
910915
WITH_NETWORK=one_zero(context.config.with_network),
911916
)
912917

@@ -975,6 +980,7 @@ def run_finalize_scripts(context: Context) -> None:
975980
MKOSI_UID=str(os.getuid()),
976981
MKOSI_GID=str(os.getgid()),
977982
MKOSI_CONFIG="/work/config.json",
983+
MKOSI_VERSION=__version__,
978984
WITH_NETWORK=one_zero(context.config.with_network),
979985
)
980986

@@ -1036,6 +1042,7 @@ def run_postoutput_scripts(context: Context) -> None:
10361042
MKOSI_UID=str(os.getuid()),
10371043
MKOSI_GID=str(os.getgid()),
10381044
MKOSI_CONFIG="/work/config.json",
1045+
MKOSI_VERSION=__version__,
10391046
)
10401047

10411048
if context.config.profiles:
@@ -4573,6 +4580,7 @@ def run_clean_scripts(config: Config) -> None:
45734580
MKOSI_UID=str(os.getuid()),
45744581
MKOSI_GID=str(os.getgid()),
45754582
MKOSI_CONFIG="/work/config.json",
4583+
MKOSI_VERSION=__version__,
45764584
)
45774585

45784586
if config.profiles:

mkosi/_version.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# SPDX-License-Identifier: LGPL-2.1-or-later
2+
3+
import datetime
4+
import os
5+
import subprocess
6+
from importlib.metadata import PackageNotFoundError, version
7+
from pathlib import Path
8+
9+
try:
10+
__version__ = version("package-name")
11+
except PackageNotFoundError:
12+
# This branch means, that mkosi was not installed as a package as Python is aware, this is most likely
13+
# the case if mkosi was run via the bin/mkosi shim in mkosi's repository. Though discouraged, we fall
14+
# back to importing setuptools_scm directly and having it try figure stuff out.
15+
try:
16+
p = subprocess.run(
17+
["git", "describe"],
18+
cwd=Path(__file__).parent.parent,
19+
check=True,
20+
text=True,
21+
capture_output=True,
22+
)
23+
version, *rest = p.stdout.strip().split("-")
24+
version = version.lstrip("v")
25+
if rest:
26+
numcommits, commit = rest
27+
__version__ = f"{version}.post1.dev{numcommits}+{commit}.d{datetime.datetime.now():%Y%m%d}"
28+
else:
29+
# we are exactly on a trag
30+
__version__ = version
31+
except (subprocess.CalledProcessError, NotADirectoryError):
32+
__version__ = os.getenv("MKOSI_VERSION", "0")

mkosi/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@
3030
from pathlib import Path
3131
from typing import Any, Callable, Generic, Optional, TypeVar, Union, cast
3232

33+
from mkosi._version import __version__
3334
from mkosi.distributions import Distribution, detect_distribution
3435
from mkosi.log import ARG_DEBUG, ARG_DEBUG_SANDBOX, ARG_DEBUG_SHELL, die
3536
from mkosi.pager import page
3637
from mkosi.run import SandboxProtocol, find_binary, nosandbox, run, sandbox_cmd, workdir
37-
from mkosi.sandbox import Style, __version__
38+
from mkosi.sandbox import Style
3839
from mkosi.user import INVOKING_USER
3940
from mkosi.util import (
4041
PathString,

mkosi/initrd.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
from typing import Optional, cast
1515

1616
import mkosi.resources
17+
from mkosi._version import __version__
1718
from mkosi.config import DocFormat, InitrdProfile, OutputFormat
1819
from mkosi.documentation import show_docs
1920
from mkosi.log import ARG_DEBUG, ARG_DEBUG_SHELL, log_notice, log_setup
2021
from mkosi.run import find_binary, run, uncaught_exception_handler
21-
from mkosi.sandbox import __version__, umask
22+
from mkosi.sandbox import umask
2223
from mkosi.tree import copy_tree, move_tree, rmtree
2324
from mkosi.util import PathString, mandatory_variable, resource_path
2425

mkosi/resources/man/mkosi.1.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2555,6 +2555,8 @@ Scripts executed by **mkosi** receive the following environment variables:
25552555
current image. This file can be parsed inside scripts to gain access to all
25562556
settings for the current image.
25572557

2558+
* `$MKOSI_VERSION` is the version string of mkosi.
2559+
25582560
* `$IMAGE_ID` contains the identifier from the `ImageId=` or `--image-id=` setting.
25592561

25602562
* `$IMAGE_VERSION` contains the version from the `ImageVersion=` or `--image-version=` setting.
@@ -2589,6 +2591,7 @@ Consult this table for which script receives which environment variables:
25892591
| `MKOSI_UID` |||||||||
25902592
| `MKOSI_GID` |||||||||
25912593
| `MKOSI_CONFIG` | ||||||||
2594+
| `MKOSI_VERSION` |||||||||
25922595
| `IMAGE_ID` |||||||||
25932596
| `IMAGE_VERSION` |||||||||
25942597

mkosi/sandbox.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
import sys
1414
import warnings # noqa: F401 (loaded lazily by os.execvp() which happens too late)
1515

16-
__version__ = "26~devel"
17-
1816
# The following constants are taken from the Linux kernel headers.
1917
AT_EMPTY_PATH = 0x1000
2018
AT_FDCWD = -100
@@ -894,8 +892,18 @@ def main() -> None:
894892
print(HELP, file=sys.stderr)
895893
sys.exit(0)
896894
elif arg == "--version":
897-
print(__version__, file=sys.stderr)
898-
sys.exit(0)
895+
try:
896+
from mkosi._version import __version__
897+
898+
print(__version__, file=sys.stderr)
899+
sys.exit(0)
900+
except ImportError:
901+
try:
902+
print(os.environ["MKOSI_VERSION"])
903+
sys.exit(0)
904+
except KeyError:
905+
print("Cannot determine version", file=sys.stderr)
906+
sys.exit(1)
899907
if arg == "--tmpfs":
900908
fsops.append(TmpfsOperation(argv.pop()))
901909
elif arg == "--dev":

pyproject.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
[build-system]
2-
requires = ["setuptools", "setuptools-scm"]
2+
requires = ["setuptools>=64", "setuptools-scm>=8"]
33
build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "mkosi"
77
authors = [
88
{name = "mkosi contributors", email = "[email protected]"},
99
]
10-
version = "25.3"
10+
dynamic = ["version"]
1111
description = "Build Bespoke OS Images"
1212
readme = "README.md"
1313
requires-python = ">=3.9"
@@ -49,6 +49,9 @@ packages = [
4949
"repart/**/*",
5050
]
5151

52+
[tool.setuptools_scm]
53+
version_scheme = "no-guess-dev"
54+
5255
[tool.isort]
5356
profile = "black"
5457
include_trailing_comma = true

tools/do-a-release.sh

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ if ! git diff-index --quiet HEAD; then
1313
exit 1
1414
fi
1515

16-
sed -r -i "s/^version = \".*\"$/version = \"$VERSION\"/" pyproject.toml
17-
sed -r -i "s/^__version__ = \".*\"$/__version__ = \"$VERSION\"/" mkosi/sandbox.py
18-
1916
git add -p pyproject.toml mkosi
2017

2118
git commit -m "Release $VERSION"
@@ -25,8 +22,6 @@ git tag -s "v$VERSION" -m "mkosi $VERSION"
2522
VERSION_MAJOR=${VERSION%%.*}
2623
VERSION="$((VERSION_MAJOR + 1))~devel"
2724

28-
sed -r -i "s/^__version__ = \".*\"$/__version__ = \"$VERSION\"/" mkosi/sandbox.py
29-
3025
git add -p mkosi
3126

3227
git commit -m "Bump version to $VERSION"

tools/generate-zipapp.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ mkdir -p builddir
1010

1111
cp -r mkosi "${BUILDDIR}/"
1212

13+
# HACK: importlib metadata doesn't seem to be there in a zipapp even if
14+
# properly installed via pip, so let's patch it in there manually.
15+
mkosiversion="$(python3 -m mkosi --version)"
16+
printf '__version__ = "%s"\n' "${mkosiversion#mkosi }" >>"${BUILDDIR}/mkosi/_version.py"
17+
1318
python3 -m zipapp \
1419
-p "/usr/bin/env python3" \
1520
-o builddir/mkosi \

0 commit comments

Comments
 (0)