Skip to content

Commit aca18f5

Browse files
committed
Swift: make codegen use a config file
1 parent e4627cb commit aca18f5

File tree

4 files changed

+56
-22
lines changed

4 files changed

+56
-22
lines changed

swift/BUILD.bazel

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ load("//misc/bazel:pkg_runfiles.bzl", "pkg_runfiles")
55

66
filegroup(
77
name = "schema",
8-
srcs = ["schema.py"],
8+
srcs = ["schema.py"] + glob(["*.dbscheme"]),
99
visibility = ["//swift:__subpackages__"],
1010
)
1111

1212
filegroup(
13-
name = "schema_includes",
14-
srcs = glob(["*.dbscheme"]),
13+
name = "codegen_conf",
14+
srcs = ["codegen.conf"],
1515
visibility = ["//swift:__subpackages__"],
1616
)
1717

swift/codegen.conf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# configuration file for Swift code generation default options
2+
--generate=dbscheme,ql
3+
--dbscheme=ql/lib/swift.dbscheme
4+
--ql-output=ql/lib/codeql/swift/generated
5+
--ql-stub-output=ql/lib/codeql/swift/elements
6+
--ql-test-output=ql/test/extractor-tests/generated
7+
--generated-registry=ql/.generated.list

swift/codegen/BUILD.bazel

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ py_binary(
55
srcs = ["codegen.py"],
66
data = [
77
"//swift:schema",
8-
"//swift:schema_includes",
8+
"//swift:codegen_conf",
99
"//swift/codegen/templates:cpp",
1010
"//swift/codegen/templates:trap",
1111
],
12+
args = [
13+
"--configuration-file=$(location //swift:codegen_conf)",
14+
],
1215
visibility = ["//swift:__subpackages__"],
1316
deps = [
1417
"//swift/codegen/generators",

swift/codegen/codegen.py

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import sys
88
import pathlib
99
import typing
10+
import shlex
1011

1112
if 'BUILD_WORKSPACE_DIRECTORY' not in os.environ:
1213
# we are not running with `bazel run`, set up module search path
@@ -18,35 +19,45 @@
1819

1920

2021
def _parse_args() -> argparse.Namespace:
22+
dirs = [pathlib.Path().resolve()]
23+
dirs.extend(dirs[0].parents)
24+
for dir in dirs:
25+
conf = dir / "codegen.conf"
26+
if conf.exists():
27+
break
28+
else:
29+
conf = None
30+
2131
p = argparse.ArgumentParser(description="Code generation suite")
22-
p.add_argument("--generate", type=lambda x: x.split(","), default=["dbscheme", "ql"],
32+
p.add_argument("--generate", type=lambda x: x.split(","),
2333
help="specify what targets to generate as a comma separated list, choosing among dbscheme, ql, trap "
2434
"and cpp")
2535
p.add_argument("--verbose", "-v", action="store_true", help="print more information")
2636
p.add_argument("--quiet", "-q", action="store_true", help="only print errors")
27-
p.add_argument("--root-dir", type=_abspath, default=paths.root_dir,
28-
help="the directory that should be regarded as the root of the language pack codebase. Used to"
29-
"compute QL imports and in some comments and as root for relative paths provided as options "
30-
"(default %(default)s)")
31-
p.add_argument("--language", default=paths.root_dir.name,
32-
help="string that should replace {language} in other provided options")
37+
p.add_argument("--configuration-file", "-c", type=_abspath, default=conf,
38+
help="A configuration file to load options from. By default, the first codegen.conf file found by "
39+
"going up directories from the current location. If present all paths provided in options are "
40+
"considered relative to its directory")
41+
p.add_argument("--root-dir", type=_abspath,
42+
help="the directory that should be regarded as the root of the language pack codebase. Used to "
43+
"compute QL imports and in some comments and as root for relative paths provided as options. "
44+
"If not provided it defaults to the directory of the configuration file, if any")
3345
path_arguments = [
3446
p.add_argument("--schema", default="schema.py",
3547
help="input schema file (default %(default)s)"),
36-
p.add_argument("--dbscheme", default="ql/lib/{language}.dbscheme",
37-
help="output file for dbscheme generation, input file for trap generation (default "
38-
"%(default)s)"),
39-
p.add_argument("--ql-output", default="ql/lib/codeql/{language}/generated",
40-
help="output directory for generated QL files (default %(default)s)"),
41-
p.add_argument("--ql-stub-output", default="ql/lib/codeql/{language}/elements",
42-
help="output directory for QL stub/customization files (default %(default)s). Defines also the "
48+
p.add_argument("--dbscheme",
49+
help="output file for dbscheme generation, input file for trap generation"),
50+
p.add_argument("--ql-output",
51+
help="output directory for generated QL files"),
52+
p.add_argument("--ql-stub-output",
53+
help="output directory for QL stub/customization files. Defines also the "
4354
"generated qll file importing every class file"),
44-
p.add_argument("--ql-test-output", default="ql/test/extractor-tests/generated",
45-
help="output directory for QL generated extractor test files (default %(default)s)"),
55+
p.add_argument("--ql-test-output",
56+
help="output directory for QL generated extractor test files"),
4657
p.add_argument("--cpp-output",
4758
help="output directory for generated C++ files, required if trap or cpp is provided to "
4859
"--generate"),
49-
p.add_argument("--generated-registry", default="ql/.generated.list",
60+
p.add_argument("--generated-registry",
5061
help="registry file containing information about checked-in generated code"),
5162
]
5263
p.add_argument("--ql-format", action="store_true", default=True,
@@ -56,11 +67,24 @@ def _parse_args() -> argparse.Namespace:
5667
p.add_argument("--force", "-f", action="store_true",
5768
help="generate all files without skipping unchanged files and overwriting modified ones"),
5869
opts = p.parse_args()
70+
if opts.configuration_file is not None:
71+
with open(opts.configuration_file) as config:
72+
defaults = p.parse_args(shlex.split(config.read(), comments=True))
73+
for flag, value in opts._get_kwargs():
74+
if value is None:
75+
setattr(opts, flag, getattr(defaults, flag))
76+
if opts.root_dir is None:
77+
opts.root_dir = opts.configuration_file.parent
78+
if opts.root_dir is None:
79+
p.error("Either --configuration-file or --root-dir must be provided, or a codegen.conf file must be in a "
80+
"containing directory")
81+
if not opts.generate:
82+
p.error("Nothing to do, specify --generate")
5983
# absolutize all paths relative to --root-dir
6084
for arg in path_arguments:
6185
path = getattr(opts, arg.dest)
6286
if path is not None:
63-
setattr(opts, arg.dest, opts.root_dir / path.format(language=opts.language))
87+
setattr(opts, arg.dest, opts.root_dir / path)
6488
return opts
6589

6690

0 commit comments

Comments
 (0)