1# Copyright 2022 The Bazel Authors. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#    http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Tool to merge the <dist /> element from a feature manifest into the main manifest."""
16
17import xml.etree.ElementTree as ET
18
19from absl import app
20from absl import flags
21
22_MAIN_MANIFEST = flags.DEFINE_string("main_manifest", None,
23                                     "Input main manifestl")
24_FEATURE_MANIFEST = flags.DEFINE_string("feature_manifest", None,
25                                        "Output feature manifest")
26_TITLE = flags.DEFINE_string("feature_title", None, "Feature title")
27_OUT = flags.DEFINE_string("out", None, "Output manifest")
28
29
30def _register_namespace(f):
31  """Registers namespaces in ET global state and returns dict of namspaces."""
32  ns = {}
33  with open(f) as xml:
34    ns_parser = ET.XMLPullParser(events=["start-ns"])
35    ns_parser.feed(xml.read())
36    ns_parser.close()
37    for _, ns_tuple in ns_parser.read_events():
38      try:
39        ET.register_namespace(ns_tuple[0], ns_tuple[1])
40        ns[ns_tuple[0]] = ns_tuple[1]
41      except ValueError:
42        pass
43  return ns
44
45
46def main(argv):
47  if len(argv) > 1:
48    raise app.UsageError("Too many command-line arguments.")
49
50  # Parse namespaces first to keep the prefix.
51  ns = {}
52  ns.update(_register_namespace(_MAIN_MANIFEST.value))
53  ns.update(_register_namespace(_FEATURE_MANIFEST.value))
54
55  main_manifest = ET.parse(_MAIN_MANIFEST.value)
56  feature_manifest = ET.parse(_FEATURE_MANIFEST.value)
57
58  dist = feature_manifest.find("dist:module", ns)
59  dist.set("{%s}title" % ns["dist"], _TITLE.value)
60  main_manifest.getroot().append(dist)
61
62  main_manifest.write(_OUT.value, encoding="utf-8", xml_declaration=True)
63
64
65if __name__ == "__main__":
66  app.run(main)
67