From e489d32c2725097488abe791bb895ee99732afba Mon Sep 17 00:00:00 2001 From: Walter Boring Date: Fri, 23 Jan 2026 12:10:49 -0500 Subject: [PATCH] added config export pattern --- aprsd_twitter_plugin/cli.py | 52 ++++++++++++++++++++++++ aprsd_twitter_plugin/conf/opts.py | 66 +++++++++++++++++++++++++++++++ pyproject.toml | 3 ++ 3 files changed, 121 insertions(+) create mode 100644 aprsd_twitter_plugin/cli.py diff --git a/aprsd_twitter_plugin/cli.py b/aprsd_twitter_plugin/cli.py new file mode 100644 index 0000000..569fbae --- /dev/null +++ b/aprsd_twitter_plugin/cli.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +""" +CLI tool for aprsd-twitter-plugin configuration export. +""" + +import json +import sys + + +def export_config_cmd(format="json"): + """Export plugin configuration options.""" + try: + from aprsd_twitter_plugin.conf.opts import export_config + + result = export_config(format=format) + + if format == "json": + print(result) + else: + print(json.dumps(result, indent=2)) + + return 0 + except ImportError as e: + print(f"Error: {e}", file=sys.stderr) + print("\nTo export config, install oslo.config:", file=sys.stderr) + print(" pip install oslo.config", file=sys.stderr) + return 1 + except Exception as e: + print(f"Error exporting config: {e}", file=sys.stderr) + return 1 + + +def main(): + """Main entry point for CLI.""" + import argparse + + parser = argparse.ArgumentParser( + description="Export aprsd-twitter-plugin configuration options", + ) + parser.add_argument( + "--format", + choices=["dict", "json"], + default="json", + help="Output format (default: json)", + ) + + args = parser.parse_args() + sys.exit(export_config_cmd(format=args.format)) + + +if __name__ == "__main__": + main() diff --git a/aprsd_twitter_plugin/conf/opts.py b/aprsd_twitter_plugin/conf/opts.py index 3822238..667f0f8 100644 --- a/aprsd_twitter_plugin/conf/opts.py +++ b/aprsd_twitter_plugin/conf/opts.py @@ -28,6 +28,7 @@ in this package. It is assumed that: import collections import importlib +import importlib.util import os import pkgutil @@ -78,3 +79,68 @@ def _append_config_options(imported_modules, config_options): configs = mod.list_opts() for key, val in configs.items(): config_options[key].extend(val) + + +def export_config(format="dict"): + """ + Export configuration options as a simple data structure. + + This function extracts configuration information from oslo_config + option objects and returns it in a simple dict or JSON format. + Works independently of aprsd installation. + + Args: + format: Output format - 'dict' (default) or 'json' + + Returns: + dict or JSON string containing all configuration options with: + - name: option name + - type: option type (StrOpt, BoolOpt, IntOpt, etc.) + - default: default value + - help: help text + - required: whether the option is required + - choices: list of valid choices (if applicable) + - secret: whether the option contains secret data (if applicable) + - min/max: min/max values for numeric types (if applicable) + + Raises: + ImportError: if oslo_config is not installed + """ + # Check if oslo_config is available + if importlib.util.find_spec("oslo_config") is None: + raise ImportError( + "oslo_config is required to export configuration. " + "Install it with: pip install oslo.config", + ) + + opts = list_opts() + result = {} + + for group_name, opt_list in opts: + result[group_name] = [] + for opt in opt_list: + opt_dict = { + "name": opt.name, + "type": type(opt).__name__, + "default": getattr(opt, "default", None), + "help": getattr(opt, "help", ""), + "required": not hasattr(opt, "default") or getattr(opt, "default", None) is None, + } + + # Add additional attributes if available + if hasattr(opt, "choices") and opt.choices: + opt_dict["choices"] = list(opt.choices) + if hasattr(opt, "secret") and opt.secret: + opt_dict["secret"] = True + if hasattr(opt, "min") and opt.min is not None: + opt_dict["min"] = opt.min + if hasattr(opt, "max") and opt.max is not None: + opt_dict["max"] = opt.max + + result[group_name].append(opt_dict) + + if format == "json": + import json + + return json.dumps(result, indent=2) + return result diff --git a/pyproject.toml b/pyproject.toml index 153fc7d..5219405 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,6 +55,9 @@ packages = ["aprsd_twitter_plugin"] [project.entry-points."oslo.config.opts.defaults"] "aprsd_twitter_plugin.conf" = "aprsd_twitter_plugin.conf.opts:defaults" # type: ignore +[project.scripts] + "aprsd-twitter-plugin-export-config" = "aprsd_twitter_plugin.cli:main" + [tool.pbr] # PBR configuration