#!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import print_function import argparse import json import os import re import sys import kobo.conf import pungi.checks import pungi.util def load_file(source, conf): try: with open(source) as f: conf.load_from_dict(json.load(f)) except ValueError: conf.load_from_file(source) def load_source(source, conf): if os.path.isfile(source): load_file(source, conf) else: load_file(os.path.join(source, "logs/global/config-dump.global.log"), conf) def validate_definition(value): """Check that the variable name is a valid Python variable name, and that there is an equals sign. The value can by anything non-empty. """ if not re.match(r"^[a-z_]\w*=.+$", value): raise argparse.ArgumentTypeError( "definition should be in var=value format: %r" % value ) return value def main(): parser = argparse.ArgumentParser() parser.add_argument( "sources", metavar="SOURCE", nargs="+", help=( "Source for the configuration; either a compose " "or arbitrary number of config files." ), ) parser.add_argument( "--freeze-event", metavar="ID", type=pungi.util.parse_koji_event, help=( "Include this koji event in the created config; " "takes either event ID or path to a compose" ), ) parser.add_argument( "-e", "--define", action="append", default=[], metavar="VAR=VALUE", type=validate_definition, help=( "Define a variable on command line and inject it into the config file. " "Can be used multiple times." ), ) group = parser.add_mutually_exclusive_group() group.add_argument( "--just-dump", action="store_true", help=( "Do not transform the config in any way. Default values are not " "added, git references are not resolved." ), ) group.add_argument( "--offline", action="store_true", help="Do not resolve git references." ) args = parser.parse_args() defines = dict(var.split("=", 1) for var in args.define) conf = kobo.conf.PyConfigParser() conf.load_from_dict(defines) for source in args.sources: load_source(source, conf) if not args.just_dump: errors, _ = pungi.checks.validate(conf, offline=args.offline) if errors: for error in errors: print(error, file=sys.stderr) return False if args.freeze_event: conf["koji_event"] = args.freeze_event # Clean up defines from the final final config. We don't want to keep them # as they would cause warnings during validation. for key in defines: del conf[key] json.dump(conf, sys.stdout, sort_keys=True, indent=4) return True if __name__ == "__main__": if not main(): sys.exit(1)