Skip to content

Commit df51194

Browse files
alexhulbertdaandemeyer
authored andcommitted
Support glob expansion for path list config options
1 parent 87c7e9a commit df51194

3 files changed

Lines changed: 102 additions & 23 deletions

File tree

mkosi/config.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import fnmatch
99
import functools
1010
import getpass
11+
import glob
1112
import graphlib
1213
import io
1314
import itertools
@@ -1204,6 +1205,7 @@ def config_make_list_parser(
12041205
unescape: bool = False,
12051206
reset: bool = True,
12061207
key: Optional[Callable[[T], Any]] = None,
1208+
expand_globs: bool = False,
12071209
) -> ConfigParseCallback[list[T]]:
12081210
def config_parse_list(value: Optional[str], old: Optional[list[T]]) -> Optional[list[T]]:
12091211
new = old.copy() if old else []
@@ -1228,6 +1230,9 @@ def config_parse_list(value: Optional[str], old: Optional[list[T]]) -> Optional[
12281230
if reset and len(values) == 1 and values[0] == "":
12291231
return None
12301232

1233+
if expand_globs:
1234+
values = flatten(sorted(glob.glob(v)) for v in values)
1235+
12311236
new += [parse(v) for v in values if v]
12321237

12331238
if key:
@@ -2694,7 +2699,7 @@ def parse_kernel_module_filter_regexp(p: str) -> str:
26942699
long="--configure-script",
26952700
metavar="PATH",
26962701
section="Config",
2697-
parse=config_make_list_parser(delimiter=",", parse=make_path_parser()),
2702+
parse=config_make_list_parser(delimiter=",", parse=make_path_parser(), expand_globs=True),
26982703
path_suffixes=("configure",),
26992704
help="Configure script to run before doing anything",
27002705
),
@@ -2968,7 +2973,7 @@ def parse_kernel_module_filter_regexp(p: str) -> str:
29682973
long="--clean-script",
29692974
metavar="PATH",
29702975
section="Output",
2971-
parse=config_make_list_parser(delimiter=",", parse=make_path_parser()),
2976+
parse=config_make_list_parser(delimiter=",", parse=make_path_parser(), expand_globs=True),
29722977
path_suffixes=("clean",),
29732978
recursive_path_suffixes=("clean.d/*",),
29742979
help="Clean script to run after cleanup",
@@ -3098,7 +3103,7 @@ def parse_kernel_module_filter_regexp(p: str) -> str:
30983103
long="--sync-script",
30993104
metavar="PATH",
31003105
section="Content",
3101-
parse=config_make_list_parser(delimiter=",", parse=make_path_parser()),
3106+
parse=config_make_list_parser(delimiter=",", parse=make_path_parser(), expand_globs=True),
31023107
path_suffixes=("sync",),
31033108
recursive_path_suffixes=("sync.d/*",),
31043109
help="Sync script to run before starting the build",
@@ -3109,7 +3114,7 @@ def parse_kernel_module_filter_regexp(p: str) -> str:
31093114
long="--prepare-script",
31103115
metavar="PATH",
31113116
section="Content",
3112-
parse=config_make_list_parser(delimiter=",", parse=make_path_parser()),
3117+
parse=config_make_list_parser(delimiter=",", parse=make_path_parser(), expand_globs=True),
31133118
path_suffixes=("prepare", "prepare.chroot"),
31143119
recursive_path_suffixes=("prepare.d/*",),
31153120
help="Prepare script to run inside the image before it is cached",
@@ -3121,7 +3126,7 @@ def parse_kernel_module_filter_regexp(p: str) -> str:
31213126
long="--build-script",
31223127
metavar="PATH",
31233128
section="Content",
3124-
parse=config_make_list_parser(delimiter=",", parse=make_path_parser()),
3129+
parse=config_make_list_parser(delimiter=",", parse=make_path_parser(), expand_globs=True),
31253130
path_suffixes=("build", "build.chroot"),
31263131
recursive_path_suffixes=("build.d/*",),
31273132
help="Build script to run inside image",
@@ -3133,7 +3138,7 @@ def parse_kernel_module_filter_regexp(p: str) -> str:
31333138
metavar="PATH",
31343139
name="PostInstallationScripts",
31353140
section="Content",
3136-
parse=config_make_list_parser(delimiter=",", parse=make_path_parser()),
3141+
parse=config_make_list_parser(delimiter=",", parse=make_path_parser(), expand_globs=True),
31373142
path_suffixes=("postinst", "postinst.chroot"),
31383143
recursive_path_suffixes=("postinst.d/*",),
31393144
help="Postinstall script to run inside image",
@@ -3144,7 +3149,7 @@ def parse_kernel_module_filter_regexp(p: str) -> str:
31443149
long="--finalize-script",
31453150
metavar="PATH",
31463151
section="Content",
3147-
parse=config_make_list_parser(delimiter=",", parse=make_path_parser()),
3152+
parse=config_make_list_parser(delimiter=",", parse=make_path_parser(), expand_globs=True),
31483153
path_suffixes=("finalize", "finalize.chroot"),
31493154
recursive_path_suffixes=("finalize.d/*",),
31503155
help="Postinstall script to run outside image",
@@ -3156,7 +3161,7 @@ def parse_kernel_module_filter_regexp(p: str) -> str:
31563161
metavar="PATH",
31573162
name="PostOutputScripts",
31583163
section="Content",
3159-
parse=config_make_list_parser(delimiter=",", parse=make_path_parser()),
3164+
parse=config_make_list_parser(delimiter=",", parse=make_path_parser(), expand_globs=True),
31603165
path_suffixes=("postoutput",),
31613166
recursive_path_suffixes=("postoutput.d/*",),
31623167
help="Output postprocessing script to run outside image",

mkosi/resources/man/mkosi.1.md

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -786,8 +786,9 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
786786

787787
`CleanScripts=`, `--clean-script=`
788788
: Takes a comma-separated list of paths to executables that are used as
789-
the clean scripts for this image. See the **SCRIPTS** section for
790-
more information.
789+
the clean scripts for this image. Glob patterns are supported and
790+
matching paths are sorted alphabetically. See the **SCRIPTS** section
791+
for more information.
791792

792793
### [Content] Section
793794

@@ -965,33 +966,39 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
965966

966967
`SyncScripts=`, `--sync-script=`
967968
: Takes a comma-separated list of paths to executables that are used as
968-
the sync scripts for this image. See the **SCRIPTS** section for
969-
more information.
969+
the sync scripts for this image. Glob patterns are supported and
970+
matching paths are sorted alphabetically. See the **SCRIPTS** section
971+
for more information.
970972

971973
`PrepareScripts=`, `--prepare-script=`
972974
: Takes a comma-separated list of paths to executables that are used as
973-
the prepare scripts for this image. See the **SCRIPTS** section for
974-
more information.
975+
the prepare scripts for this image. Glob patterns are supported and
976+
matching paths are sorted alphabetically. See the **SCRIPTS** section
977+
for more information.
975978

976979
`BuildScripts=`, `--build-script=`
977980
: Takes a comma-separated list of paths to executables that are used as
978-
the build scripts for this image. See the **SCRIPTS** section for more
979-
information.
981+
the build scripts for this image. Glob patterns are supported and
982+
matching paths are sorted alphabetically. See the **SCRIPTS** section
983+
for more information.
980984

981985
`PostInstallationScripts=`, `--postinst-script=`
982986
: Takes a comma-separated list of paths to executables that are used as
983-
the post-installation scripts for this image. See the **SCRIPTS** section
987+
the post-installation scripts for this image. Glob patterns are supported
988+
and matching paths are sorted alphabetically. See the **SCRIPTS** section
984989
for more information.
985990

986991
`FinalizeScripts=`, `--finalize-script=`
987992
: Takes a comma-separated list of paths to executables that are used as
988-
the finalize scripts for this image. See the **SCRIPTS** section for more
989-
information.
993+
the finalize scripts for this image. Glob patterns are supported and
994+
matching paths are sorted alphabetically. See the **SCRIPTS** section
995+
for more information.
990996

991997
`PostOutputScripts=`, `--postoutput-script=`
992998
: Takes a comma-separated list of paths to executables that are used as
993-
the post output scripts for this image. See the **SCRIPTS** section for more
994-
information.
999+
the post output scripts for this image. Glob patterns are supported and
1000+
matching paths are sorted alphabetically. See the **SCRIPTS** section
1001+
for more information.
9951002

9961003
`Bootable=`, `--bootable=`
9971004
: Takes a boolean or `auto`. Enables or disables generation of a
@@ -2278,8 +2285,9 @@ config file is read:
22782285

22792286
`ConfigureScripts=`, `--configure-script=`
22802287
: Takes a comma-separated list of paths to executables that are used as
2281-
the configure scripts for this image. See the **SCRIPTS** section for
2282-
more information.
2288+
the configure scripts for this image. Glob patterns are supported and
2289+
matching paths are sorted alphabetically. See the **SCRIPTS** section
2290+
for more information.
22832291

22842292
`PassEnvironment=`, `--pass-environment=`
22852293
: Takes a list of environment variable names separated by spaces. When

tests/test_config.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,72 @@ def test_paths_with_default_factory(tmp_path: Path) -> None:
11131113
]
11141114

11151115

1116+
def test_glob_expansion(tmp_path: Path) -> None:
1117+
d = tmp_path
1118+
1119+
(d / "script_a.sh").touch()
1120+
(d / "script_b.sh").touch()
1121+
(d / "script_c.sh").touch()
1122+
(d / "other.py").touch()
1123+
1124+
# Glob patterns should be expanded and results should be sorted.
1125+
(d / "mkosi.conf").write_text(
1126+
f"""\
1127+
[Content]
1128+
PrepareScripts={d}/script_*.sh
1129+
"""
1130+
)
1131+
1132+
with chdir(d):
1133+
_, _, [config] = parse_config()
1134+
1135+
assert config.prepare_scripts == [d / "script_a.sh", d / "script_b.sh", d / "script_c.sh"]
1136+
1137+
# Glob patterns that match nothing should result in an empty list.
1138+
(d / "mkosi.conf").write_text(
1139+
f"""\
1140+
[Content]
1141+
PrepareScripts={d}/nonexistent_*.sh
1142+
"""
1143+
)
1144+
1145+
with chdir(d):
1146+
_, _, [config] = parse_config()
1147+
1148+
assert config.prepare_scripts == []
1149+
1150+
# Non-glob paths should be ordered before glob results when listed first.
1151+
(d / "mkosi.conf").write_text(
1152+
f"""\
1153+
[Content]
1154+
PrepareScripts={d}/other.py,{d}/script_*.sh
1155+
"""
1156+
)
1157+
1158+
with chdir(d):
1159+
_, _, [config] = parse_config()
1160+
1161+
assert config.prepare_scripts == [
1162+
d / "other.py",
1163+
d / "script_a.sh",
1164+
d / "script_b.sh",
1165+
d / "script_c.sh",
1166+
]
1167+
1168+
# Glob expansion should work with other script options too.
1169+
(d / "mkosi.conf").write_text(
1170+
f"""\
1171+
[Content]
1172+
BuildScripts={d}/script_*.sh
1173+
"""
1174+
)
1175+
1176+
with chdir(d):
1177+
_, _, [config] = parse_config()
1178+
1179+
assert config.build_scripts == [d / "script_a.sh", d / "script_b.sh", d / "script_c.sh"]
1180+
1181+
11161182
@pytest.mark.parametrize(
11171183
"sections,args,warning_count",
11181184
[

0 commit comments

Comments
 (0)