1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
"""
Generate a Dockerfile from in.Dockerfile and a version JSON file, and write version info.
If the argument --error-modified is passed, the script will not write any output
and will exit with status code 1 if the output files were modified.
"""
import difflib
import sys
from pathlib import Path
from textwrap import dedent
try:
from scripts.python_version import ALL_VERSIONS, MAIN_VERSION
except ModuleNotFoundError:
sys.path.insert(0, Path(__file__).parent.parent.absolute().as_posix())
from scripts.python_version import ALL_VERSIONS, MAIN_VERSION
DOCKERFILE_TEMPLATE = Path("scripts/in.Dockerfile").read_text("utf-8")
DOCKERFILE = Path("Dockerfile")
ERROR_MODIFIED = "--error-modified" in sys.argv
# Download and copy multiple python images into one layer
python_build = ""
previous_layer = "first"
for version in ALL_VERSIONS:
if version.is_main:
# Main is handled separately later
continue
# Add the current version to the Dockerfile
layer_name = version.version_name.replace(".", "-") # Dots aren't valid in layer names
python_build += dedent(
f"""
FROM python:{version.image_tag} as base-{layer_name}
COPY --from=base-{previous_layer} / /
"""
)
previous_layer = layer_name
# Main version is installed twice, once at the very beginning to make sure
# its files aren't overwritten, and once at the end which actually makes use of the version
python_build = f"FROM python:{MAIN_VERSION.image_tag} as base-first\n" + python_build
# Write new dockerfile
# fmt: off
# Black makes the following block much less readable
dockerfile_out = (
"# THIS FILE IS AUTOGENERATED, DO NOT MODIFY! #\n"
+ DOCKERFILE_TEMPLATE
.replace("{python_install_commands}", python_build)
.replace("{final_base}", previous_layer).replace("{main_version_tag}", MAIN_VERSION.image_tag)
)
# fmt: on
if ERROR_MODIFIED:
if (original := DOCKERFILE.read_text("utf-8")) != dockerfile_out:
print("Dockerfile modified:")
print("\n".join(difflib.unified_diff(dockerfile_out.splitlines(), original.splitlines())))
raise SystemExit(1)
else:
exit(0)
else:
DOCKERFILE.write_text(dockerfile_out, "utf-8")
print("Finished!")
|