From bab6a3c77bc68d1b40030c54368ca7bd953991d9 Mon Sep 17 00:00:00 2001 From: Felix Moessbauer Date: Wed, 11 Dec 2024 12:58:37 +0100 Subject: [PATCH] dump: only sort keys if explicitly requested The yaml and json formatter differed w.r.t sorting the keys during serialization (json kept the order, yaml sorted). As pointed out in #118 the users expect to maintain the order of the keys. By that, we make this the new default and add an CLI option "--sort" to sort the output. Closes: #118 Signed-off-by: Felix Moessbauer --- kas/plugins/dump.py | 16 +++++++++++++--- kas/plugins/lock.py | 3 ++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/kas/plugins/dump.py b/kas/plugins/dump.py index d7ad36be..f8e4b9a4 100644 --- a/kas/plugins/dump.py +++ b/kas/plugins/dump.py @@ -49,6 +49,9 @@ - the dumped config is semantically identical but not bit-by-bit identical - all referenced repositories are checked out to resolve cross-repo configs - all branches are resolved before patches are applied + - the ordering of the keys is kept unless ``--sort`` is used. If you intend + to store the flattened configs for comparison, it is recommended to sort + the keys. For example, to get a single config representing the final build config of ``kas-project.yml:target-override.yml`` you could run:: @@ -152,6 +155,10 @@ def setup_parser_format_args(parser): type=int, default=4, help='Line indent (# of spaces, default: 4)') + parser.add_argument('--sort', + action='store_true', + default=False, + help='Alphanumerically sort keys in output') @classmethod def setup_parser(cls, parser): @@ -179,18 +186,20 @@ def setup_parser(cls, parser): help=argparse.SUPPRESS) @staticmethod - def dump_config(config: dict, target: IoTarget, format: str, indent: int): + def dump_config(config: dict, target: IoTarget, format: str, indent: int, + sorted: bool): """ Dump the configuration to the target in the specified format. """ with IoTargetMonitor(target) as f: if format == 'json': - json.dump(config, f, indent=indent) + json.dump(config, f, indent=indent, sort_keys=sorted) f.write('\n') elif format == 'yaml': yaml.dump( config, f, indent=indent, + sort_keys=sorted, Dumper=Dump.KasYamlDumper) else: raise OutputFormatError(format) @@ -264,7 +273,8 @@ def _filter_local(repos): if args.resolve_env and 'env' in config_expanded: config_expanded['env'] = ctx.config.get_environment() - self.dump_config(config_expanded, output, args.format, args.indent) + self.dump_config(config_expanded, output, args.format, args.indent, + args.sort) __KAS_PLUGINS__ = [Dump] diff --git a/kas/plugins/lock.py b/kas/plugins/lock.py index 905a821c..1979a619 100644 --- a/kas/plugins/lock.py +++ b/kas/plugins/lock.py @@ -104,7 +104,8 @@ def _update_lockfile(self, lockfile, repos_to_lock, args): os.path.relpath(lockfile.filename, os.getcwd())) output = IoTarget(target=lockfile.filename, managed=True) format = "json" if lockfile.filename.suffix == '.json' else "yaml" - Dump.dump_config(lockfile_config, output, format, args.indent) + Dump.dump_config(lockfile_config, output, format, args.indent, + args.sort) return repos_to_lock def run(self, args):