blob: 1c31db33fac3a36c029385346af4d89a0d67389d [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2019-2022 Fairphone B.V.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Generate public Android manifests for FP2."""
import argparse
import logging
from lxml import etree
__log__ = logging.getLogger(__name__)
PUBLIC_MANIFEST_REMOTE = {"name": "origin", "fetch": ".."}
PROJECT_FOR_INTERNAL_ONLY = [
"device/fairphone/fp2-gms",
"device/fairphone/fp2-open",
"device/fairphone/fp2-proprietary",
"device/fairphone/fp3-gms",
"device/fairphone/fp3-proprietary",
"vendor/dozuki/apps/iFixit",
"vendor/fairphone/firmware",
"vendor/fairphone/fp2-gms",
"vendor/fairphone/fp2-open",
"vendor/fairphone/fp3-gms",
"vendor/fairphone/proprietary-apps",
"vendor/google/partner_gms",
"vendor/google/unbundled_apps",
"vendor/google-extra/apps/GoogleCamera",
"vendor/orange",
"vendor/orange/appsorange",
"vendor/tuxera",
"fp2/vendor/google-gms-7.1-201803",
"platform/vendor/partner_modules",
"platform/vendor/widevine",
]
def generate_public_manifest(args: argparse.Namespace):
"""Generate a public manifest based on an internal one."""
# Clean the output while parsing (remove whitespace etc.)
parser = etree.XMLParser(remove_comments=True, remove_blank_text=True)
tree = etree.parse(args.reference_manifest, parser=parser)
# Replace remote definition by the one needed for public
remote_element = tree.find("remote")
remote_element.clear()
for key, value in PUBLIC_MANIFEST_REMOTE.items():
remote_element.set(key, value)
# Remove potential other remotes
for remote in tree.findall("remote"):
if remote != remote_element:
remote.getparent().remove(remote)
# Remove projects we don't publish
for project in tree.findall("project"):
project_name = project.get("name")
if project_name in PROJECT_FOR_INTERNAL_ONLY:
project.getparent().remove(project)
PROJECT_FOR_INTERNAL_ONLY.remove(project_name)
if PROJECT_FOR_INTERNAL_ONLY:
__log__.warning(
"Internal projects not found in this manifest: %s",
", ".join(PROJECT_FOR_INTERNAL_ONLY),
)
# Print while indenting, putting elements on separate lines etc.
# Have a uppercase "UTF-8" statement as in the AOSP manifest.
manifest_string = etree.tostring(
tree, xml_declaration=True, pretty_print=True, encoding="UTF-8"
).decode("utf-8")
# Adjust formatting to conform with AOSP style:
# ... fix quotes in the XML declaration.
manifest_string = manifest_string.replace("'", '"')
# ... add whitespace at the end of tags.
manifest_string = manifest_string.replace('">', '" >')
manifest_string = manifest_string.replace('"/>', '" />')
print(manifest_string, end="")
def build_cmdline_arguments() -> argparse.ArgumentParser:
"""Parse the command line arguments.
Returns:
argparse Namespace containing the parsed command line arguments of this
script.
"""
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument("reference_manifest", type=str, help="")
sub_parsers = parser.add_subparsers(title="subcommands")
gen_public_parser = sub_parsers.add_parser(
"gen_public", help="Generate a public manifest from an internal one."
)
gen_public_parser.set_defaults(func=generate_public_manifest)
return parser
def main():
"""Entry point into the public-manifest command line tool."""
parser = build_cmdline_arguments()
args = parser.parse_args()
if "func" in args:
args.func(args=args)
else:
parser.error("Select the subcommand to execute.")
if __name__ == "__main__":
main()