-
Notifications
You must be signed in to change notification settings - Fork 81
Expand file tree
/
Copy pathcli.py
More file actions
136 lines (109 loc) · 4.79 KB
/
cli.py
File metadata and controls
136 lines (109 loc) · 4.79 KB
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import argparse
import logging
from pathlib import Path
from typing import Literal, cast
from .build_matrix import build_matrix
from .dockerfiles import render_dockerfile_with_context
from .readme import update_dynamic_readme
from .settings import DISTROS
from .versions import (
decide_version_combinations,
find_new_or_updated,
load_build_contexts,
load_versions,
persist_versions,
supported_versions,
)
logger = logging.getLogger("dpn")
class CLIArgs(argparse.Namespace):
dry_run: bool
distros: list[str]
verbose: bool
command: Literal["dockerfile", "build-matrix", "release"]
force: bool # build-matrix and release command arg
context: str # dockerfile command arg
event: str # build-matrix command arg
builds_dir: Path # release command arg
def run_dockerfile(args: CLIArgs) -> None:
render_dockerfile_with_context(args.context, args.dry_run)
def run_build_matrix(args: CLIArgs) -> None:
supported_python_versions, supported_nodejs_versions = supported_versions()
versions = decide_version_combinations(args.distros, supported_python_versions, supported_nodejs_versions)
current_versions = load_versions()
new_or_updated = find_new_or_updated(versions, current_versions, args.force)
build_matrix(new_or_updated, args.event)
def run_release(args: CLIArgs) -> None:
"""Release new/updated version by updating versions.json and README.md.
Note: We fetch supported and available versions again here and update with the actual built digests"""
supported_python_versions, supported_nodejs_versions = supported_versions()
versions = decide_version_combinations(args.distros, supported_python_versions, supported_nodejs_versions)
# Update versions with build digests to allow pinning
built_versions = load_build_contexts(args.builds_dir)
current_versions = load_versions()
for version in versions:
if version.key in built_versions:
version.digest = built_versions[version.key].digest
elif version.key in current_versions:
version.digest = current_versions[version.key].digest
new_or_updated = find_new_or_updated(versions, current_versions, args.force)
supported_python_versions, supported_nodejs_versions = supported_versions()
if not new_or_updated:
logger.info("No new or updated versions")
return
persist_versions(versions, args.dry_run)
update_dynamic_readme(versions, supported_python_versions, supported_nodejs_versions, args.dry_run)
def main(args: CLIArgs) -> None:
if args.dry_run:
logger.debug("Dry run, outputting only.")
if args.command == "dockerfile":
run_dockerfile(args)
elif args.command == "build-matrix":
run_build_matrix(args)
elif args.command == "release":
run_release(args)
def parse_args() -> CLIArgs:
parser = argparse.ArgumentParser(usage="🐳 Build Python with Node.js docker images")
parser.add_argument(
"-d",
"--distros",
dest="distros",
nargs="*",
choices=DISTROS,
help="Specify which distros to build",
default=DISTROS,
)
parser.add_argument(
"--dry-run",
action="store_true",
dest="dry_run",
help="Skip persisting, README update, and pushing of builds",
)
parser.add_argument("--force", action="store_true", help="Force build all versions (even old)")
parser.add_argument("--verbose", action="store_true", help="Enable debug logging")
subparsers = parser.add_subparsers(dest="command", help="Sub-commands")
# Dockerfile command
parser_dockerfile = subparsers.add_parser("dockerfile", help="Render a dockerfile based on version config")
parser_dockerfile.add_argument("--context", default="", help="Dockerfile version config")
# Build matrix command
parser_build_matrix = subparsers.add_parser("build-matrix", help="Generate CI build matrix")
parser_build_matrix.add_argument(
"--event",
default="webhook",
# https://docs.github.com/en/actions/learn-github-actions/contexts#github-context
help="GitHub Action event name (github.event_name)",
)
# Release command
parser_release = subparsers.add_parser("release", help="Persist versions and make a release")
parser_release.add_argument(
"--builds-dir",
type=Path,
required=True,
help="Builds directory with build context JSON files",
)
cli_args = cast("CLIArgs", parser.parse_args())
if cli_args.command == "release":
if not cli_args.builds_dir.exists():
parser.error(f"Builds directory {cli_args.builds_dir.as_posix()} does not exist")
if not cli_args.builds_dir.is_dir():
parser.error(f"Builds directory {cli_args.builds_dir.as_posix()} is not a directory")
return cli_args