diff --git a/README.md b/README.md index d06efdb..7b1efd1 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,10 @@ **lab2hub** syncs from gitlab to github like described in [this GitHub article](https://help.github.com/articles/duplicating-a-repository/#mirroring-a-repository). ## Install - pyvenv venv - . venv/bin/activate - pip install -r requirements.txt - -## Usage - -* Create a `config.py` with GitHub and GitLab url and key. -* Use `config-example.py` as a template. -* run with `python lab2hub.py`. - + pipenv install + cp config-example.py config.py # Change GitHub and GitLab url and key + pipenv shell + python lab2hub.py ## TODO diff --git a/lab2hub.py b/lab2hub.py index b096c29..87c5c7f 100644 --- a/lab2hub.py +++ b/lab2hub.py @@ -22,90 +22,93 @@ except ImportError: pass -def get_gitlab_repo_data(gl_api, group_id): - projects = gl_api.groups.get(group_id).projects.list(visibility='public', all=True) - repos = OrderedDict() - for project in projects: - name = project.http_url_to_repo.split('/')[-1].split('.')[0] - repos[name] = { - 'description': project.name, - 'clone_url': project.http_url_to_repo, - 'name': name, - } - return repos +class Lab2Hub: + def __init__(self): + self.gl_api = Gitlab(config.GITLAB_URL, config.GITLAB_TOKEN) + self.gitlab_group_id = config.GITLAB_GROUP_ID + self.gh_api = login(token=config.GITHUB_TOKEN) + self.gh_org = self.gh_api.organization(config.GITHUB_ORG_NAME) -def get_github_repo_data(org): - gh_repos = list(org.repositories()) - repos = OrderedDict() + def get_gitlab_repo_data(self): + projects = self.gl_api.groups.get(self.gitlab_group_id).projects.list(visibility='public', all=True) + repos = OrderedDict() + for project in projects: + name = project.http_url_to_repo.split('/')[-1].split('.')[0] + repos[name] = { + 'description': project.name, + 'clone_url': project.http_url_to_repo, + 'name': name, + } + return repos - for r in gh_repos: - name = r.name.lower() + def get_github_repo_data(self): + gh_repos = list(self.gh_org.repositories()) + repos = OrderedDict() - repos[name] = { - 'ssh_url': r.ssh_url, + for r in gh_repos: + name = r.name.lower() + + repos[name] = { + 'ssh_url': r.ssh_url, + 'name': name + } + return repos + + def git_clone(self, git_url, dir_name): + local_path = os.path.join(REPO_DIR, dir_name) + if not os.path.exists(local_path): + logger.debug('Cloning %s into bare repo %s', git_url, local_path) + git.Repo.clone_from(git_url, local_path, mirror=True) + else: + logger.debug('Fetch from %s (origin) into %s', git_url, local_path) + r = git.Repo(local_path) + r.remotes.origin.fetch(prune=True) + + def git_push(self, dir_name, hub_url): + remote_branch_name = 'github' + local_path = os.path.join(REPO_DIR, dir_name) + r = git.Repo(local_path) + + try: + remote = r.remote(remote_branch_name) + except ValueError: + logger.debug('Created remote %s', remote_branch_name) + remote = r.create_remote(remote_branch_name, hub_url) + + logger.debug('Pushing %s (%s) to %s', local_path, remote_branch_name, hub_url) + remote.push(mirror=True) + + def create_github_repository(self, name): + repo = self.gh_org.create_repository(name) + return { + 'ssh_url': repo.ssh_url, 'name': name } - return repos + def lab2hub(self, gl_repo, gh_repo): + self.git_clone(gl_repo['clone_url'], gl_repo['name']) + self.git_push(gl_repo['name'], gh_repo['ssh_url']) -def git_clone(git_url, dir_name): - local_path = os.path.join(REPO_DIR, dir_name) - if not os.path.exists(local_path): - logger.debug('Cloning %s into bare repo %s', git_url, local_path) - git.Repo.clone_from(git_url, local_path, mirror=True) - else: - logger.debug('Fetch from %s (origin) into %s', git_url, local_path) - r = git.Repo(local_path) - r.remotes.origin.fetch(prune=True) + def sync(self): + gl_repo_data = self.get_gitlab_repo_data() + logger.info('Found {} GitLab ({}) projects'.format(len(gl_repo_data), config.GITLAB_URL)) + gh_repo_data = self.get_github_repo_data() + logger.info('Found {} GitHub repos'.format(len(gh_repo_data))) -def git_push(dir_name, hub_url): - remote_branch_name = 'github' - local_path = os.path.join(REPO_DIR, dir_name) - r = git.Repo(local_path) + # Check if repos exist and sync + for name, gl_repo in gl_repo_data.items(): + if name not in gh_repo_data: + logger.info('[NEW]: {}'.format(name)) + gh_repo = self.create_github_repository(name) + else: + gh_repo = gh_repo_data[name] - try: - remote = r.remote(remote_branch_name) - except ValueError: - logger.debug('Created remote %s', remote_branch_name) - remote = r.create_remote(remote_branch_name, hub_url) + self.lab2hub(gl_repo, gh_repo) + logger.info('[OK]: {}'.format(name)) - logger.debug('Pushing %s (%s) to %s', local_path, remote_branch_name, hub_url) - remote.push(mirror=True) - - -def create_github_repository(gh_org, name): - repo = gh_org.create_repository(name) - return { - 'ssh_url': repo.ssh_url, - 'name': name - } - - -def lab2hub(gl_repo, gh_repo): - git_clone(gl_repo['clone_url'], gl_repo['name']) - git_push(gl_repo['name'], gh_repo['ssh_url']) if __name__ == '__main__': - # Gitlab - gl = Gitlab(config.GITLAB_URL, config.GITLAB_TOKEN) - gl_repo_data = get_gitlab_repo_data(gl, config.GITLAB_GROUP_ID) - logger.info('Found {} GitLab ({}) projects'.format(len(gl_repo_data), config.GITLAB_URL)) - - # Github - gh = login(token=config.GITHUB_TOKEN) - gh_org = gh.organization(config.GITHUB_ORG_NAME) - gh_repo_data = get_github_repo_data(gh_org) - logger.info('Found {} GitHub repos'.format(len(gh_repo_data))) - - # Check if repos exist and sync - for name, gl_repo in gl_repo_data.items(): - if name not in gh_repo_data: - logger.info('[NEW]: {}'.format(name)) - gh_repo = create_github_repository(gh_org, name) - else: - gh_repo = gh_repo_data[name] - - lab2hub(gl_repo, gh_repo) - logger.info('[OK]: {}'.format(name)) + l2h = Lab2Hub() + l2h.sync()