Skip to content

Commit 2dcb2f0

Browse files
committed
Add git version info to frozen modules.
1 parent e44fbca commit 2dcb2f0

File tree

5 files changed

+77
-4
lines changed

5 files changed

+77
-4
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,6 @@
2929
[submodule "frozen/Adafruit_CircuitPython_BusDevice"]
3030
path = frozen/Adafruit_CircuitPython_BusDevice
3131
url = https://github.com/adafruit/Adafruit_CircuitPython_BusDevice.git
32+
[submodule "tools/python-semver"]
33+
path = tools/python-semver
34+
url = https://github.com/k-bx/python-semver.git

py/mkenv.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ endif
7070
MAKE_FROZEN = $(TOP)/tools/make-frozen.py
7171
MPY_CROSS = $(TOP)/mpy-cross/mpy-cross
7272
MPY_TOOL = $(TOP)/tools/mpy-tool.py
73+
PREPROCESS_FROZEN_MODULES = PYTHONPATH=$(TOP)/tools/python-semver $(TOP)/tools/preprocess_frozen_modules.py
7374

7475
all:
7576
.PHONY: all

py/mkrules.mk

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,13 @@ $(MPY_CROSS): $(TOP)/py/*.[ch] $(TOP)/mpy-cross/*.[ch] $(TOP)/windows/fmode.c
114114
$(Q)$(MAKE) -C $(TOP)/mpy-cross
115115

116116
# Copy all the modules and single python files to freeze to a common area, omitting top-level dirs (the repo names).
117-
# Remove any conf.py (sphinx config) and setup.py (module install info) files, which are not meant to be frozen.
118-
# Also remove the library examples directory, so it won't be included.
117+
# Do any preprocessing necessary: currently, this adds version information, removes examples, and
118+
# non-library .py files in the modules (setup.py and conf.py)
119119
# Then compile .mpy files from all the .py files, placing them in the same directories as the .py files.
120120
$(BUILD)/frozen_mpy: $(FROZEN_MPY_DIRS)
121121
$(ECHO) FREEZE $(FROZEN_MPY_DIRS)
122122
$(Q)$(MKDIR) -p $@
123-
$(Q)$(RSYNC) -rL --include="*/" --include='*.py' --exclude="*" $(addsuffix /*,$(FROZEN_MPY_DIRS)) $@
124-
$(Q)$(RM) -rf $@/conf.py $@/setup.py $@/examples
123+
$(Q)$(PREPROCESS_FROZEN_MODULES) -o $@ $(FROZEN_MPY_DIRS)
125124
$(Q)$(CD) $@ && \
126125
$(FIND) -L . -type f -name '*.py' | sed 's=^\./==' | \
127126
xargs -n1 $(abspath $(MPY_CROSS)) $(MPY_CROSS_FLAGS)

tools/preprocess_frozen_modules.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env python3
2+
import argparse
3+
import os
4+
import os.path
5+
from pathlib import Path
6+
import semver
7+
import subprocess
8+
9+
def version_string(path=None, *, valid_semver=False):
10+
version = None
11+
tag = subprocess.run('git describe --tags --exact-match', shell=True,
12+
stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=path)
13+
if tag.returncode == 0:
14+
version = tag.stdout.strip().decode("utf-8", "strict")
15+
else:
16+
describe = subprocess.run("git describe --tags", shell=True, stdout=subprocess.PIPE, cwd=path)
17+
tag, additional_commits, commitish = describe.stdout.strip().decode("utf-8", "strict").rsplit("-", maxsplit=2)
18+
commitish = commitish[1:]
19+
if valid_semver:
20+
version_info = semver.parse_version_info(tag)
21+
if not version_info.prerelease:
22+
version = semver.bump_patch(tag) + "-alpha.0.plus." + additional_commits + "+" + commitish
23+
else:
24+
version = tag + ".plus." + additional_commits + "+" + commitish
25+
else:
26+
version = commitish
27+
return version
28+
29+
# Visit all the .py files in topdir. Replace any __version__ = "0.0.0-auto.0" type of info
30+
# with actual version info derived from git.
31+
def copy_and_process(in_dir, out_dir):
32+
for root, subdirs, files in os.walk(in_dir):
33+
34+
# Skip library examples directories.
35+
if Path(root).name == 'examples':
36+
continue
37+
38+
for file in files:
39+
# Skip top-level setup.py (module install info) and conf.py (sphinx config),
40+
# which are not part of the library
41+
if (root == in_dir) and file in ('conf.py', 'setup.py'):
42+
continue
43+
44+
input_file_path = Path(root, file)
45+
output_file_path = Path(out_dir, input_file_path.relative_to(in_dir))
46+
47+
if file.endswith(".py"):
48+
output_file_path.parent.mkdir(parents=True, exist_ok=True)
49+
with input_file_path.open("r") as input, output_file_path.open("w") as output:
50+
for line in input:
51+
if line.startswith("__version__"):
52+
module_version = version_string(root, valid_semver=True)
53+
line = line.replace("0.0.0-auto.0", module_version)
54+
output.write(line)
55+
56+
if __name__ == '__main__':
57+
argparser = argparse.ArgumentParser(description="""\
58+
Copy and pre-process .py files into output directory, before freezing.
59+
1. Remove top-level repo directory.
60+
2. Update __version__ info.
61+
3. Remove examples.
62+
4. Remove non-library setup.py and conf.py""")
63+
argparser.add_argument("in_dirs", metavar="input-dir", nargs="+",
64+
help="top-level code dirs (may be git repo dirs)")
65+
argparser.add_argument("-o", "--out_dir", help="output directory")
66+
args = argparser.parse_args()
67+
68+
for in_dir in args.in_dirs:
69+
copy_and_process(in_dir, args.out_dir)

tools/python-semver

Submodule python-semver added at 2001c62

0 commit comments

Comments
 (0)