mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
This switched `codegen` from the `autopep8` formatting to the `black` one, and applies it to `bulk_mad_generator.py` as well. We can enroll more python scripts to it in the future.
181 lines
6.1 KiB
Python
Executable File
181 lines
6.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Driver script to run all code generation"""
|
|
|
|
import argparse
|
|
import logging
|
|
import os
|
|
import sys
|
|
import pathlib
|
|
import typing
|
|
import shlex
|
|
|
|
if "BUILD_WORKSPACE_DIRECTORY" not in os.environ:
|
|
# we are not running with `bazel run`, set up module search path
|
|
_repo_root = pathlib.Path(__file__).resolve().parents[2]
|
|
sys.path.append(str(_repo_root))
|
|
|
|
from misc.codegen.lib import render, paths
|
|
from misc.codegen.generators import generate
|
|
|
|
|
|
def _parse_args() -> argparse.Namespace:
|
|
dirs = [pathlib.Path().resolve()]
|
|
dirs.extend(dirs[0].parents)
|
|
for dir in dirs:
|
|
conf = dir / "codegen.conf"
|
|
if conf.exists():
|
|
break
|
|
else:
|
|
conf = None
|
|
|
|
p = argparse.ArgumentParser(description="Code generation suite")
|
|
p.add_argument(
|
|
"--generate",
|
|
type=lambda x: x.split(","),
|
|
help="specify what targets to generate as a comma separated list, choosing among dbscheme, ql, "
|
|
"trap, cpp and rust",
|
|
)
|
|
p.add_argument(
|
|
"--verbose", "-v", action="store_true", help="print more information"
|
|
)
|
|
p.add_argument("--quiet", "-q", action="store_true", help="only print errors")
|
|
p.add_argument(
|
|
"--configuration-file",
|
|
"-c",
|
|
type=_abspath,
|
|
default=conf,
|
|
help="A configuration file to load options from. By default, the first codegen.conf file found by "
|
|
"going up directories from the current location. If present all paths provided in options are "
|
|
"considered relative to its directory",
|
|
)
|
|
p.add_argument(
|
|
"--root-dir",
|
|
type=_abspath,
|
|
help="the directory that should be regarded as the root of the language pack codebase. Used to "
|
|
"compute QL imports and in some comments and as root for relative paths provided as options. "
|
|
"If not provided it defaults to the directory of the configuration file, if any",
|
|
)
|
|
path_arguments = [
|
|
p.add_argument("--schema", help="input schema file (default schema.py)"),
|
|
p.add_argument(
|
|
"--dbscheme",
|
|
help="output file for dbscheme generation, input file for trap generation",
|
|
),
|
|
p.add_argument("--ql-output", help="output directory for generated QL files"),
|
|
p.add_argument(
|
|
"--ql-stub-output",
|
|
help="output directory for QL stub/customization files. Defines also the "
|
|
"generated qll file importing every class file",
|
|
),
|
|
p.add_argument(
|
|
"--ql-test-output",
|
|
help="output directory for QL generated extractor test files",
|
|
),
|
|
p.add_argument(
|
|
"--ql-cfg-output", help="output directory for QL CFG layer (optional)."
|
|
),
|
|
p.add_argument(
|
|
"--cpp-output",
|
|
help="output directory for generated C++ files, required if trap or cpp is provided to "
|
|
"--generate",
|
|
),
|
|
p.add_argument(
|
|
"--rust-output",
|
|
help="output directory for generated Rust files, required if rust is provided to "
|
|
"--generate",
|
|
),
|
|
p.add_argument(
|
|
"--generated-registry",
|
|
help="registry file containing information about checked-in generated code. A .gitattributes"
|
|
"file is generated besides it to mark those files with linguist-generated=true. Must"
|
|
"be in a directory containing all generated code.",
|
|
),
|
|
]
|
|
p.add_argument(
|
|
"--script-name",
|
|
help="script name to put in header comments of generated files. By default, the path of this "
|
|
"script relative to the root directory",
|
|
)
|
|
p.add_argument(
|
|
"--trap-library",
|
|
help="path to the trap library from an include directory, required if generating C++ trap bindings",
|
|
),
|
|
p.add_argument(
|
|
"--ql-format",
|
|
action="store_true",
|
|
default=True,
|
|
help="use codeql to autoformat QL files (which is the default)",
|
|
)
|
|
p.add_argument(
|
|
"--no-ql-format",
|
|
action="store_false",
|
|
dest="ql_format",
|
|
help="do not format QL files",
|
|
)
|
|
p.add_argument(
|
|
"--codeql-binary",
|
|
default="codeql",
|
|
help="command to use for QL formatting (default %(default)s)",
|
|
)
|
|
p.add_argument(
|
|
"--force",
|
|
"-f",
|
|
action="store_true",
|
|
help="generate all files without skipping unchanged files and overwriting modified ones",
|
|
)
|
|
p.add_argument(
|
|
"--use-current-directory",
|
|
action="store_true",
|
|
help="do not consider paths as relative to --root-dir or the configuration directory",
|
|
)
|
|
opts = p.parse_args()
|
|
if opts.configuration_file is not None:
|
|
with open(opts.configuration_file) as config:
|
|
defaults = p.parse_args(shlex.split(config.read(), comments=True))
|
|
for flag, value in opts._get_kwargs():
|
|
if value is None:
|
|
setattr(opts, flag, getattr(defaults, flag))
|
|
if opts.root_dir is None:
|
|
opts.root_dir = opts.configuration_file.parent
|
|
if opts.schema is None:
|
|
opts.schema = "schema.py"
|
|
if not opts.generate:
|
|
p.error("Nothing to do, specify --generate")
|
|
# absolutize all paths
|
|
for arg in path_arguments:
|
|
path = getattr(opts, arg.dest)
|
|
if path is not None:
|
|
setattr(
|
|
opts,
|
|
arg.dest,
|
|
(
|
|
_abspath(path)
|
|
if opts.use_current_directory
|
|
else (opts.root_dir / path)
|
|
),
|
|
)
|
|
if not opts.script_name:
|
|
opts.script_name = paths.exe_file.relative_to(opts.root_dir)
|
|
return opts
|
|
|
|
|
|
def _abspath(x: str) -> typing.Optional[pathlib.Path]:
|
|
return pathlib.Path(x).resolve() if x else None
|
|
|
|
|
|
def run():
|
|
opts = _parse_args()
|
|
if opts.verbose:
|
|
log_level = logging.DEBUG
|
|
elif opts.quiet:
|
|
log_level = logging.ERROR
|
|
else:
|
|
log_level = logging.INFO
|
|
logging.basicConfig(format="{levelname} {message}", style="{", level=log_level)
|
|
for target in opts.generate:
|
|
generate(target, opts, render.Renderer(opts.script_name))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run()
|