| #!/usr/bin/env python3 |
| |
| # Copyright 2019-2020 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", |
| "vendor/dozuki/apps/iFixit", |
| "vendor/fairphone/fp2-gms", |
| "vendor/fairphone/fp2-open", |
| "vendor/google/partner_gms", |
| "vendor/google/unbundled_apps", |
| "vendor/google-extra/apps/GoogleCamera", |
| "vendor/orange", |
| "vendor/orange/appsorange", |
| "fp2/vendor/google-gms-7.1-201803", |
| "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() |