Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a26fac4b authored by Diogo Ferreira's avatar Diogo Ferreira Committed by Ricardo Cerqueira
Browse files

roomservice: Add lightweight dependencies to repositories

Roomservice can already fetch your cm_<device> without the need for a
manifest entry.

However, when working with common repositories, there is no way of
actually fetching them without adding to the manifest. This patch
introduces a lightweight dependency system. Each repository can have a
cm.dependencies in the following json format:

[
  {
    "repository": "repository_name_on_cm_organization"
    "target_path": "target/path"
  },
  ...
]

For instance, for cm_anzu I need android_device_semc_msm7x30-common and
android_device_semc_mogami-common. I would add both to cm.dependencies
as follows:

[
  {
    "repository": "android_device_semc_msm7x30-common",
    "target_path": "device/semc/msm7x30-common"
  },
  {
    "repository": "android_device_semc_mogami-common",
    "target_path": "device/semc/mogami-common"
  }
]

Roomservice would then fetch the anzu repository, parse the dependency
files and add/fetch/sync these additional repositories if they don't
exist already.

This also adds pretty printing to the output xml.

Change-Id: I9cc847adfc717a06439bc6094213ed6492343158
parent de5ad0e8
Loading
Loading
Loading
Loading
+80 −22
Original line number Diff line number Diff line
@@ -19,27 +19,47 @@ while True:
    repositories = repositories + result['repositories']
    page = page + 1

for repository in repositories:
    repo_name = repository['name']
    if repo_name.startswith("android_device_") and repo_name.endswith("_" + device):
        print "Found repository: %s" % repository['name']
        manufacturer = repo_name.replace("android_device_", "").replace("_" + device, "")
def exists_in_tree(lm, repository):
    for child in lm.getchildren():
        if child.attrib['name'].endswith(repository):
            return True
    return False

# in-place prettyprint formatter
def indent(elem, level=0):
    i = "\n" + level*"  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            indent(elem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i

def add_to_manifest(repositories):
    try:
        lm = ElementTree.parse(".repo/local_manifest.xml")
        lm = lm.getroot()
    except:
        lm = ElementTree.Element("manifest")

        for child in lm.getchildren():
            if child.attrib['name'].endswith("_" + device):
                print "Duplicate device '%s' found in local_manifest.xml." % child.attrib['name']
                sys.exit()
    for repository in repositories:
        (repo_name, repo_target) = repository
        if exists_in_tree(lm, repo_name):
            print 'CyanogenMod/%s already exists' % (repo_name)
            continue

        repo_path = "device/%s/%s" % (manufacturer, device)
        project = ElementTree.Element("project", attrib = { "path": repo_path, "remote": "github", "name": "CyanogenMod/%s" % repository['name'] })
        print 'Adding dependency: CyanogenMod/%s -> %s' % (repo_name, repo_target)
        project = ElementTree.Element("project", attrib = { "path": repo_target,
            "remote": "github", "name": "CyanogenMod/%s" % repo_name })
        lm.append(project)

    indent(lm, 0)
    raw_xml = ElementTree.tostring(lm)
    raw_xml = '<?xml version="1.0" encoding="UTF-8"?>\n' + raw_xml

@@ -47,9 +67,47 @@ for repository in repositories:
    f.write(raw_xml)
    f.close()

def fetch_dependencies(repo_path, repositories):
    print 'Looking for dependencies'
    dependencies_path = repo_path + '/cm.dependencies'
    syncable_repos = []

    if os.path.exists(dependencies_path):
        dependencies_file = open(dependencies_path, 'r')
        dependencies = json.loads(dependencies_file.read())
        fetch_list = []
        print dependencies

        for dependency in dependencies:
            fetch_list.append((dependency['repository'],dependency['target_path']))
            syncable_repos.append(dependency['target_path'])

        dependencies_file.close()

        print 'Adding dependencies to manifest'
        add_to_manifest(fetch_list)
    else:
        print 'Dependencies file not found, bailing out.'

    if len(syncable_repos) > 0:
        print 'Syncing dependencies'
        os.system('repo sync %s' % ' '.join(syncable_repos))

for repository in repositories:
    repo_name = repository['name']
    if repo_name.startswith("android_device_") and repo_name.endswith("_" + device):
        print "Found repository: %s" % repository['name']
        manufacturer = repo_name.replace("android_device_", "").replace("_" + device, "")

        repo_path = "device/%s/%s" % (manufacturer, device)
        add_to_manifest([(repo_name,repo_path)])

        print "Syncing repository to retrieve project."
        os.system('repo sync %s' % repo_path)
        print "Done!"
        print "Repository synced!"

        fetch_dependencies(repo_path, repositories)
        print "Done"
        sys.exit()

print "Repository for %s not found in the CyanogenMod Github repository list. If this is in error, you may need to manually add it to your local_manifest.xml." % device