Write merge_flat_configs utility to simplify merging FlatConfigLists
BUG=chromium:1073073
TEST=manual
Change-Id: I7ebb5d9b7303688cd6098f6202aa991f14658e46
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/config/+/2465573
Commit-Queue: Sean McAllister <smcallis@google.com>
Auto-Submit: Sean McAllister <smcallis@google.com>
Reviewed-by: Andrew Lamb <andrewlamb@chromium.org>
diff --git a/payload_utils/checker/io_utils.py b/payload_utils/checker/io_utils.py
index ee43989..e8b6585 100644
--- a/payload_utils/checker/io_utils.py
+++ b/payload_utils/checker/io_utils.py
@@ -12,7 +12,7 @@
from google.protobuf.message import Message
from chromiumos.config.payload import config_bundle_pb2
-
+from chromiumos.config.payload import flat_config_pb2
def write_message_json(message: Message, path: pathlib.Path, \
@@ -32,11 +32,10 @@
def read_config(path: str) -> config_bundle_pb2.ConfigBundle:
- """Reads a ConfigBundle mesage from a jsonpb file.
+ """Reads a ConfigBundle message from a jsonpb file.
Args:
- path: Path to the json proto. See note above about deprecated repo
- root behavior.
+ path: Path to the json proto.
Returns:
ConfigBundle parsed from file.
@@ -47,6 +46,21 @@
return project_config
+def read_flat_config(path: str) -> flat_config_pb2.FlatConfigList:
+ """Reads a FlatConfigList message from a jsonpb file.
+
+ Args:
+ path: Path to the json proto.
+
+ Returns:
+ FlatConfigList parsed from file.
+ """
+ flat_config = flat_config_pb2.FlatConfigList()
+ with open(path, 'r') as f:
+ json_format.Parse(f.read(), flat_config)
+ return flat_config
+
+
def read_model_sku_json(factory_dir: pathlib.Path) -> Dict[str, Any]:
"""Reads and parses the model_sku.json file.
diff --git a/payload_utils/checker/io_utils_test.py b/payload_utils/checker/io_utils_test.py
index e2bed4c..d2da36f 100644
--- a/payload_utils/checker/io_utils_test.py
+++ b/payload_utils/checker/io_utils_test.py
@@ -12,6 +12,7 @@
from google.protobuf import json_format
from checker import io_utils
+from common import config_bundle_utils
from chromiumos.config.payload.config_bundle_pb2 import ConfigBundle
from chromiumos.config.api.program_pb2 import Program
@@ -22,6 +23,7 @@
def setUp(self):
self.config = ConfigBundle(program_list=[Program(name='TestProgram1')])
+ self.flat_config = config_bundle_utils.flatten_config(self.config)
repo_path = tempfile.mkdtemp()
os.mkdir(os.path.join(repo_path, 'generated'))
@@ -32,6 +34,13 @@
with open(self.config_path, 'w') as f:
print(json_output, file=f)
+ self.flat_config_path = os.path.join(repo_path, 'generated',
+ 'flattened.jsonproto')
+ json_output = json_format.MessageToJson(
+ self.flat_config, sort_keys=True, use_integers_for_enums=True)
+ with open(self.flat_config_path, 'w') as f:
+ print(json_output, file=f)
+
self.factory_path = os.path.join(repo_path, 'factory')
os.makedirs(os.path.join(self.factory_path, 'generated'))
self.model_sku = {"model": {"a": 1}}
@@ -44,6 +53,11 @@
"""Tests the json proto can be read."""
self.assertEqual(io_utils.read_config(self.config_path), self.config)
+ def test_read_flat_config(self):
+ """Tests the json proto can be read."""
+ self.assertEqual(
+ io_utils.read_flat_config(self.flat_config_path), self.flat_config)
+
def test_read_model_sku_json(self):
"""Tests model_sku.json can be read."""
self.assertDictEqual(
diff --git a/payload_utils/merge_flat_configs.py b/payload_utils/merge_flat_configs.py
new file mode 100755
index 0000000..4bcb8b6
--- /dev/null
+++ b/payload_utils/merge_flat_configs.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# Copyright 2020 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""Merge two FlatConfigList messages into a single FlatConfigList.
+
+The second FlatConfigList is optional, in which case the first input is
+copied to the output."""
+
+import argparse
+
+from checker import io_utils
+
+from chromiumos.config.payload import flat_config_pb2
+
+
+def merge(files, outfile):
+ """Merge multiple FlatConfigList .jsonproto files.
+
+ Merge the given files into a single FlatConfigList and write to the output.
+
+ Args:
+ files ([str]): .jsonproto files containing FlatConfigList
+ outfile (str): filename to which to write merged config
+ """
+
+ config = flat_config_pb2.FlatConfigList()
+ for file in files:
+ config.values.MergeFrom(io_utils.read_flat_config(file).values)
+ io_utils.write_message_json(config, outfile)
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ "input",
+ type=str,
+ nargs='+',
+ help="FlatConfigList to merge in jsonpb format.")
+ parser.add_argument(
+ '-o',
+ '--output',
+ type=str,
+ required=True,
+ help='output file to write FlatConfigList jsonproto to')
+
+ options = parser.parse_args()
+ merge(options.input, options.output)