| #!/usr/bin/env python |
| # |
| # Copyright (C) 2022-2024 LeafOS Project |
| # |
| # 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. |
| # |
| |
| from __future__ import print_function |
| import argparse |
| import glob |
| import os |
| import yaml |
| import xml.etree.ElementTree as ET |
| |
| def parse_args(): |
| parser = argparse.ArgumentParser() |
| parser.add_argument("target_device", nargs="?", help="Target device") |
| parser.add_argument("-l", "--list", help="List all supported devices", action="store_true") |
| parser.add_argument("-t", "--topdir", help="Set the path to the source code directory") |
| return parser.parse_args() |
| |
| def load_devices(leaf_devices): |
| with open(leaf_devices) as f: |
| return yaml.safe_load(f) |
| |
| def get_device_info(devices, args): |
| repositories = [] |
| family = None |
| |
| if args.list: |
| for item in devices: |
| if 'device' in item: |
| for device in item["device"]: |
| print(device) |
| return None, None |
| |
| for item in devices: |
| if "device" in item and "repositories" in item and args.target_device in item["device"]: |
| family = item.get("family") |
| for repo_list in item["repositories"]: |
| if isinstance(repo_list, list): |
| repositories.extend(repo_list) |
| else: |
| repositories.append(repo_list) |
| |
| if family is None: |
| print(f"Device {args.target_device} not found") |
| |
| return repositories, family |
| |
| def repo_is_in_manifest(local_manifests, repo_path): |
| for path in glob.glob(f"{local_manifests}/*.xml"): |
| tree = ET.parse(path).getroot() |
| |
| if any(localpath.get("path") == repo_path for localpath in tree.findall("project")): |
| return True |
| |
| def update_local_manifest(local_manifest, repositories): |
| local_manifests = os.path.dirname(local_manifest) |
| os.makedirs(local_manifests, exist_ok=True) |
| |
| try: |
| tree = ET.parse(local_manifest).getroot() |
| except: |
| tree = ET.Element("manifest") |
| |
| for repo in repositories: |
| repo_name = repo["name"] |
| repo_path = repo["path"] |
| if repo_is_in_manifest(local_manifests, repo_path): |
| continue |
| project = ET.Element("project", attrib={"path": repo_path, "name": repo_name}) |
| if "revision" in repo: |
| project.set("revision", repo["revision"]) |
| if "remote" in repo: |
| project.set("remote", repo["remote"]) |
| tree.append(project) |
| |
| ET.indent(tree, space=" ", level=0) |
| |
| with open(local_manifest, "w", encoding="utf-8") as f: |
| f.write(ET.tostring(tree, encoding="unicode")) |
| |
| def sync_repositories(topdir, repositories): |
| for repo in repositories: |
| repo_path = repo["path"] |
| print(f"Syncing {repo_path}") |
| os.system(f"repo sync --force-sync {topdir}/{repo_path}") |
| print("\n") |
| |
| def main(): |
| args = parse_args() |
| topdir = args.topdir or os.getcwd() |
| leaf_devices = f"{topdir}/leaf/devices/devices.yaml" |
| |
| devices = load_devices(leaf_devices) |
| repositories, family = get_device_info(devices, args) |
| |
| if repositories: |
| local_manifests = f"{topdir}/.repo/local_manifests" |
| local_manifest = f"{local_manifests}/{family}.xml" |
| update_local_manifest(local_manifest, repositories) |
| sync_repositories(topdir, repositories) |
| |
| if __name__ == "__main__": |
| main() |