diff options
Diffstat (limited to 'talerbuildconfig.py')
-rw-r--r-- | talerbuildconfig.py | 117 |
1 files changed, 83 insertions, 34 deletions
diff --git a/talerbuildconfig.py b/talerbuildconfig.py index 878beb3..642bcbc 100644 --- a/talerbuildconfig.py +++ b/talerbuildconfig.py @@ -40,7 +40,7 @@ from pathlib import Path """ This module aims to replicate a small GNU Coding Standards -configure script, taylored at projects in GNU Taler. We hope it +configure script, tailored at projects in GNU Taler. We hope it can be of use outside of GNU Taler, hence it is dedicated to the public domain ('0BSD'). It takes a couple of arguments on the commandline equivalent to @@ -48,7 +48,7 @@ configure by autotools, in addition some environment variables xan take precedence over the switches. In the absence of switches, /usr/local is assumed as the PREFIX. When all data from tests are gathered, it generates a config.mk -Makefile fragement, which is the processed by a Makefile (usually) in +Makefile fragment, which is the processed by a Makefile (usually) in GNU Make format. """ @@ -59,12 +59,15 @@ serialversion = 2 # TODO: We need a smallest version argument. class Tool(ABC): - def args(self): + def args(self, parser): ... def check(self, buildconfig): ... +class Plugin(ABC): + def args(self, parser): + ... class BuildConfig: def __init__(self): @@ -72,16 +75,26 @@ class BuildConfig: self.make_variables = [] self.tools = [] self.tool_results = {} + self.plugins = [] self.args = None self.prefix_enabled = False - self.variant_enabled = False self.configmk_enabled = False + self.configmk_dotfile = False def add_tool(self, tool): + """Deprecated. Prefer the 'use' method.""" if isinstance(tool, Tool): self.tools.append(tool) else: - raise Exception("Not a tool instance: " + repr(tool)) + raise Exception("Not a 'Tool' instance: " + repr(tool)) + + def use(self, plugin): + if isinstance(plugin, Plugin): + self.plugins.append(plugin) + elif isinstance(plugin, Tool): + self.tools.append(plugin) + else: + raise Exception("Not a 'Plugin' or 'Tool' instance: " + repr(plugin)) def _set_tool(self, name, value, version=None): self.tool_results[name] = (value, version) @@ -90,19 +103,16 @@ class BuildConfig: """If enabled, process the --prefix argument.""" self.prefix_enabled = True - def enable_variant(self): - """If enable, process the --variant argument.""" - self.variant_enabled = True - def _warn(self, msg): print("Warning", msg) def _error(self, msg): print("Error", msg) - def enable_configmk(self): + def enable_configmk(self, dotfile=False): """If enabled, output the config.mk makefile fragment.""" self.configmk_enabled = True + self.configmk_dotfile = dotfile def run(self): parser = argparse.ArgumentParser() @@ -113,17 +123,17 @@ class BuildConfig: default="/usr/local", help="Directory prefix for installation", ) - if self.variant_enabled: - parser.add_argument( - "--variant", - type=str, - default="", - help="Directory for installation", - ) for tool in self.tools: tool.args(parser) + + for plugin in self.plugins: + plugin.args(parser) + args = self.args = parser.parse_args() + for plugin in self.plugins: + res = plugin.run(self) + for tool in self.tools: res = tool.check(self) if not res: @@ -147,24 +157,58 @@ class BuildConfig: print(f"found {tool.name} as {path} (version {version})") if self.configmk_enabled: - d = Path(os.environ.get("TALERBUILDSYSTEMDIR", ".")) + if self.configmk_dotfile: + d = Path(".") + cf = d / ".config.mk" + else: + d = Path(os.environ.get("TALERBUILDSYSTEMDIR", ".")) + cf = d / "config.mk" d.mkdir(parents=True, exist_ok=True) - with open(d / "config.mk", "w") as f: - print("writing config.mk") + print(f"writing {cf}") + with open(cf, "w") as f: f.write("# this makefile fragment is autogenerated by configure.py\n") if self.prefix_enabled: f.write(f"prefix = {args.prefix}\n") - if self.variant_enabled: - f.write(f"variant = {args.variant}\n") for tool in self.tools: path, version = self.tool_results[tool.name] f.write(f"{tool.name} = {path}\n") + for plugin in self.plugins: + d = plugin.get_configmk(self) + for k, v in d.items(): + f.write(f"{k} = {v}\n") def existence(name): return find_executable(name) is not None +class Option(Plugin): + + def __init__(self, optname, help, required=True, default=None): + self.optname = optname + self.help = help + self.default = default + self.required = required + self._arg = None + + def args(self, parser): + parser.add_argument("--" + self.optname, action="store") + + def run(self, buildconfig): + arg = getattr(buildconfig.args, self.optname) + if arg is None: + if self.required: + print(f"required option '--{self.optname}' missing") + sys.exit(1) + else: + arg = self.default + self._arg = arg + + def get_configmk(self, buildconfig): + key = "opt_" + self.optname + return {"opt_" + self.optname: self._arg} + + class YarnTool(Tool): name = "yarn" description = "The yarn package manager for node" @@ -293,17 +337,17 @@ class YapfTool(Tool): "3.8": "yapf3.8", "3.9": "yapf3.9", "4.0": "yapf4.0", - "4.1": "yapf-3.0", - "4.2": "yapf-3.1", - "4.3": "yapf-3.2", - "4.4": "yapf-3.3", - "4.5": "yapf-3.4", - "4.6": "yapf-3.5", - "4.7": "yapf-3.6", - "4.8": "yapf-3.7", - "4.9": "yapf-3.8", - "5.0": "yapf-3.9", - "5.1": "yapf-4.0", + "4.1": "yapf4.1", + "4.2": "yapf4.2", + "4.3": "yapf4.3", + "4.4": "yapf4.4", + "4.5": "yapf4.5", + "4.6": "yapf4.6", + "4.7": "yapf4.7", + "4.8": "yapf4.8", + "4.9": "yapf4.9", + "5.0": "yapf5.0", + "5.1": "yapf5.1", } for key, value in version_dict.items(): if existence(value): @@ -394,6 +438,11 @@ class PythonTool(Tool): "3.7": "python3.7", "3.8": "python3.8", "3.9": "python3.9", + "3.10": "python3.10", + "3.11": "python3.11", + "3.12": "python3.12", + "3.13": "python3.13", + "3.14": "python3.14", } for key, value in version_dict.items(): if existence(value): @@ -444,7 +493,7 @@ class NodeJsTool(Tool): return False if ( subprocess.getstatusoutput( - "node -p 'process.exit(!(/v([0-9]+)/.exec(process.version)[1] >= 4))'" + "node -p 'process.exit((/v([0-9]+)/.exec(process.version)[1] >= 4) ? 0 : 5)'" )[1] != "" ): |