Pythonでbitbucketのレポジトリ一覧を取得する


はじめに

git pythonを利用してbitbucketのプライベートレポジトリの一覧を取得します。
参考: シェルスクリプトでの取得方法

用途

こちらのエントリ開発チームの生産性・健全性を客観的に知るためにリポジトリ履歴から機械的に可視化するツールを作ったを読んで会社の中でもこの可視化ツールを使ってレポジトリも横並びで評価したいなと考えています。この時にbitbucketのプライベートレポジトリの一覧をpython経由で取得できると便利だったので、紹介します。

作成したスクリプト

main.py

import os
from os.path import join, dirname
from dotenv import load_dotenv
import requests
import json
from git import Repo, NoSuchPathError
import logging

load_dotenv(verbose=True)

class GitConnector:

    LOGGER = logging.getLogger('GitActivity')

    def __init__(self):
        self._dotenv_path = join(dirname(__file__), '.env')
        load_dotenv(self._dotenv_path)
        self._user_name = os.environ.get("BITBUCKET_USER_NAME")
        self._password = os.environ.get("BITBUCKET_PRIVATE_ACCESS_TOKEN")
        self._remote_workspace = os.environ.get("REMOTE_WORK_SPACE")
        self._work_dir = os.environ.get("WORK_DIR")
        self.git_repo = None

    def get_repositories(self):
        url = 'https://api.bitbucket.org/2.0/repositories/%s' % self._remote_workspace
        params = {'pagelen': 100, 'page': 1, 'sort': 'name'}
        auth = (self._user_name, self._password)
        response = requests.get(url=url, params=params, auth=auth)
        text = json.loads(response.text)
        repositories = [value['name'] for value in text['values']]
        return repositories

    def clone(self, repo):

        try:
            self.git_repo = Repo(join(self._work_dir, repo))
            self.LOGGER.warning("%s exists, skip cloning.", repo)

        except NoSuchPathError:
            self.LOGGER.info("%s doesn't exist, cloning... it will take a while... ", repo)
            self.git_repo = Repo.clone_from(url='https://' + self._user_name + ':' + self._password + '@bitbucket.org/'
                                                + join(self._remote_workspace, repo),
                                            to_path=join(self._work_dir, repo))
        return self.git_repo, self._work_dir + repo


def main():
    git_activity = GitConnector()
    repositories = git_activity.get_repositories()
    for repo in repositories:
        git_repo, path = git_activity.clone(repo)

if __name__ == '__main__':
    main()

手順解説

bitbucketのユーザ名、パスワードの設定

まず、git_activity = GitConnector()で環境変数の取得・初期化を行います。今回は、環境変数を別途.envとして用意してパスワードなどの設定値を読み込みます。

.env
BITBUCKET_USER_NAME=username
BITBUCKET_PRIVATE_ACCESS_TOKEN=password
WORK_DIR=/dir/for/clone
REMOTE_WORK_SPACE=your_work_space_name
  • BITBUCKET_USER_NAME
    • bitbucketのユーザ名です。ログイン時のユーザ名を使用してください
  • BITBUCKET_PRIVATE_ACCESS_TOKEN
  • WORK_DIR
    • クローンしたいフォルダを設定します
  • REMOTE_WORK_SPACE
    • ワークスペース名(https://bitbucket.org/hogehoge/hogehoge部分)

レポジトリ名一覧の取得

bitbucketのワークスペースの情報のリクエスト結果をjson形式でロードしてレポジトリ名のみ抜き出してリストへ保存します。レスポンスの内容はAPI referenceを参照ください。

    def get_repositories(self):
        url = 'https://api.bitbucket.org/2.0/repositories/%s' % self._remote_workspace
        params = {'pagelen': 100, 'page': 1, 'sort': 'name'}
        auth = (self._user_name, self._password)
        response = requests.get(url=url, params=params, auth=auth)
        text = json.loads(response.text)
        repositories = [value['name'] for value in text['values']]
        return repositories

レポジトリをクローン

レポジトリをgitpythonでクローンします。レポジトリが既に存在する場合はクローンをスキップしています。

    def clone(self, repo):
        try:
            self.repo = Repo(join(self._work_dir, repo))
            self.LOGGER.warning("%s exists, skip cloning.", repo)
        except NoSuchPathError as err:
            self.LOGGER.info("%s doesn't exist, cloning... it will take a while... ", repo)
            self.repo = Repo.clone_from(url='https://' + self._user_name + ':' + self._password + '@bitbucket.org/'
                                            + join(self._remote_workspace, repo),
                                        to_path=join(self._work_dir, repo))
        return self.repo, self._work_dir + repo

実行結果

bitbucket内にあるレポジトリが全てローカルの指定したフォルダへとクローンされます。

最後に

今後はクローンしたレポジトリを冒頭で説明したパッケージで可視化して、プロダクトごとの生産性を定量的に測れるようにしたいなぁ。