Gitlab Repo

Posted on May 9, 2020

gitlab 里面已经有十来个 group,几百个 project,虽然不一定会每个项目都参与, 但是为了快速同步代码,又捡起了 android 开发常用的 repo 命令来管理多项目代码。 这里使用了 gitlab graphql 接口来遍历项目生成分组的 manifest 文件

#!/usr/bin/env python

import argparse
import json
import os
import urllib2

GITLAB_HOST = "gitlab.mydomain.com"
GITLAB_SSH_URL = "ssh://git@" + GITLAB_HOST
GITLAB_GRAPHQL_URL = "https://" + GITLAB_HOST + "/api/graphql"
GITLAB_TOKEN = ""
GITLAB_GROUP = [""]
BLACK_LIST = ("",)

# 以上配置修改为自己的设定

template = """<?xml version="1.0" encoding="UTF-8"?>
<!-- autogen by gen.py, do not edit this file -->
<manifest>
  <remote  name="origin" fetch="{ssh_url}" />
  <default revision="master" remote="origin" sync-c="true" sync-j="4" />
{content}
</manifest>"""



def write_file(content, filename="default.xml"):
    _file = os.path.join(os.path.dirname(__file__), filename)
    with open(_file, "w") as f:
        f.write(template.format(content=content, ssh_url=GITLAB_SSH_URL))


def fetch_project_of_group(group, write=True):
    data = '{ group(fullPath: "%s") { projects { nodes { fullPath } } }}' % group
    req = urllib2.Request(
        GITLAB_GRAPHQL_URL,
        data=json.dumps(dict(query=data)),
        headers={
            "Authorization": "Bearer " + GITLAB_TOKEN,
            "Content-Type": "application/json",
        },
    )
    resp = json.load(urllib2.urlopen(req))
    content = "\n".join(
        [
            '<project path="{d}" name="{d}"/>'.format(d=p["fullPath"])
            for p in resp["data"]["group"]["projects"]["nodes"]
            if p["fullPath"] not in BLACK_LIST
        ]
    )

    if write:
        write_file(content, filename=group.replace("/", "-") + "-group.xml")
    else:
        return content


def main():
    parser = argparse.ArgumentParser(description="Process some projects.")
    parser.add_argument(
        "-G",
        "--group",
        help="for group/subgroup or all",
        type=str,
        choices=ns + ["all", "default"],
    )
    arg = parser.parse_args()

    if arg.group == "all":
        for x in GITLAB_GROUP:
            fetch_project_of_group(x)
        d = [fetch_project_of_group(x, write=False) for x in GITLAB_GROUP]
        write_file("\n".join(d))
    elif arg.group == "default":
        d = [fetch_project_of_group(x, write=False) for x in GITLAB_GROUP]
        write_file("\n".join(d))
    else:
        fetch_project_of_group(arg.group)


if __name__ == "__main__":
    main()

USAGE: 创建完 manifest 文件之后提交到仓库就可以愉快的玩耍啦

$ ./gen.py -G all
$ ./gen.py -G default
$ git commit -as # push and merge


# Install Repo <https://source.android.com/setup/build/downloading>
$ mkdir ~/bin
$ PATH=~/bin:$PATH

$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo


# 拉取全部项目
$ repo init -u git@gitlab.mydomain.com:groupname/manifest.git
$ repo sync

# 全部切换到 master 分支
$ repo start --all master
$ repo sync -d

# 拉取指定 manifest
$ rm -rf .repo
$ repo init -u git@gitlab.mydomain.com:groupname/manifest.git -m some-group.xml
$ repo sync