gitlabのリポジトリ取得用スクリプト

gitlab.com の自分のプライベートリポジトリを含めて、
一覧取得して、git clone 出来るShellScriptを作ってみたので共有します。

gitlabリポジトリ取得スクリプト

完成品はこんな感じで、
gitlab.com の自分のリポジトリから、一覧を取得して
インタラクティブにリポジトリをクローンする事ができる。

git-clone-gitlab.sh

今回使うコマンド

curl

最初から入ってるはず、gitlabのAPIリクエストに使用する。

openssl

最初から入ってるはず、アクセストークンの暗号化保存に使う。
平文保存でいいなら、別に必要ない。

git

gitは開発者なら入れてるよね?

jq

json よく使うなら入れておいて損なし!

brew install jq

Gitlab.com アクセストークンの発行

アクセストークンは、Settings > Access Tokens から、発行することが出来る。

プライベートリポジトリも含めた、リポジトリ一覧を取得するには、
Scopesは、apiを選択。
read_registry でいけるかと思ったけど、無理だった。
read_registryって一体何に使うんだろう…。

Expires at は空欄しておけば、期限なしのアクセストークンを作成する事ができる。

作成したアクセストークンは、一度しか表示されないので、ちゃんとメモしておこう。
まぁ、忘れてももっかい新しいのを発行すればいいんだけどね。

リポジトリ一覧取得

curl --header "Private-Token: XXXXXXX" https://gitlab.com/api/v3/projects

このように、curlコマンドで、アクセストークンをつけて、
リクエストすると自分のリポジトリ一覧がjsonで取得出来る。

レスポンスの内容

gitlabのAPIレスポンスで取得できるJSONの構造はこんな感じ、
今回使いたいのは、ssh_url_to_repo あたりがあれば良いかな。

[
  {
    "id": xxxxxx,
    "description": "",
    "default_branch": "master",
    "tag_list": [],
    "public": true,
    "archived": false,
    "visibility_level": 20,
    "ssh_url_to_repo": "git@gitlab.com:tyabuta/learning-reactjs.git",
    "http_url_to_repo": "https://gitlab.com/tyabuta/learning-reactjs.git",
    "web_url": "https://gitlab.com/tyabuta/learning-reactjs",
    "owner": {
      "id": xxxxxxxx,
      "name": "tyabuta",
      "username": "tyabuta",
      "state": "active",
      "avatar_url": "https://secure.gravatar.com/avatar/xxxxxxxxxxxxxxxx?s=xx&d=identicon",
      "web_url": "https://gitlab.com/tyabuta"
    },
    "name": "learning-reactjs",
    "name_with_namespace": "tyabuta / learning-reactjs",
    "path": "learning-reactjs",
    "path_with_namespace": "tyabuta/learning-reactjs",
    "resolve_outdated_diff_discussions": null,
    "container_registry_enabled": true,
    "issues_enabled": true,
    "merge_requests_enabled": true,
    "wiki_enabled": true,
    "builds_enabled": true,
    "snippets_enabled": true,
    "created_at": "2017-07-12T14:52:25.143Z",
    "last_activity_at": "2017-07-16T12:00:23.961Z",
    "shared_runners_enabled": true,
    "lfs_enabled": true,
    "creator_id": xxxxxxxxx,
    "namespace": {
      "id": xxxxxxxxx,
      "name": "tyabuta",
      "path": "tyabuta",
      "kind": "user",
      "full_path": "tyabuta",
      "parent_id": null,
      "plan": "early_adopter"
    },
    "avatar_url": null,
    "star_count": 0,
    "forks_count": 0,
    "open_issues_count": 0,
    "public_builds": true,
    "shared_with_groups": [],
    "only_allow_merge_if_build_succeeds": false,
    "request_access_enabled": false,
    "only_allow_merge_if_all_discussions_are_resolved": false,
    "approvals_before_merge": 0,
    "permissions": {
      "project_access": {
        "access_level": 40,
        "notification_level": 3
      },
      "group_access": null
    }
  },
  ~ 省略 ~
]

jq コマンドでリスト化

jqコマンドで、取得したjsonから、扱いやすいようにリスト化します。

curl --header "Private-Token: XXXXXXXXX" https://gitlab.com/api/v3/projects | \
    jq -r ".[].ssh_url_to_repo"  | \
    sort

出力結果はこんなこんな感じになる。

git@gitlab.com:tyabuta/go-msearch.git
git@gitlab.com:tyabuta/go-termbox-test.git
git@gitlab.com:tyabuta/go-util.git
git@gitlab.com:tyabuta/learning-reactjs.git
git@gitlab.com:tyabuta/learning-rxjava.git
git@gitlab.com:tyabuta/minecraft.docker.git
git@gitlab.com:tyabuta/redmine.docker.git
git@gitlab.com:tyabuta/report-draft-3.git
git@gitlab.com:tyabuta/template-go.git
git@gitlab.com:tyabuta/template-groovy.git

git-clone-gitlab.sh の全体像

最終的にこんなスクリプトになりました。

#!/usr/bin/env bash

set -u

tokenDir=~/.config/gitlab-token
tokenFile=token.enc

if [ ! -f "$tokenDir/$tokenFile" ]; then
    echo "Enter PrivateToken"
    read inputToken

    mkdir -p $tokenDir
    echo "$inputToken" | openssl aes-256-cbc -e -base64 -out $tokenDir/$tokenFile
    echo "Private-Token saved."
fi

# token取得
token=$(cat $tokenDir/$tokenFile | openssl aes-256-cbc -d -base64)
if [ 0 -ne $? ]; then
    echo "Invalid password."
    exit 1
fi

# リポジトリ一覧取得
repos=$(curl --header "Private-Token: $token" https://gitlab.com/api/v3/projects | \
    jq -r ".[].ssh_url_to_repo"  | \
    sort)
if [ -z "$repos" ]; then
    echo "取得出来るリポジトリがみつかりません"
    exit 1
fi

# 取得するリポジトリを選択
echo "取得するリポジトリを選んでください"
PS3='>>> '
select repository in $repos; do
    [ -z "$repository" ] && exit 0
    break
done

# git clone
git clone --recursive $repository

先日の暗号化して保存する処理を、使ってアクセストークンはローカルに保存するようにしています。
アクセストークンは暗号化して保存しよう (openssl)

これで使うときはパスフレーズだけ入力して使えますね!
リポジトリの数が多い人は、fzfとか、pecoを挟んで選択させる方が便利かと思います。

[余談] github.comよりgitlab.comを使う

最近、会社でもgitlabを使っているし、
github.comより、無料でプライベートリポジトリも作成できるgitlab.comを使うようにしている。
非公開リポジトリと公開リポジトリ、どちらも一元管理できる方がいいですよね。

git insteadOfについて

go get した時に
gitlabホストだと、正常にクローン出来なかったというのがあったが、
git の insteadOfを設定しておく事で問題なく動作します。
(githubのプライベートリポジトリでも同じかもしれないけど、試した事ないから分かんないです…)

git config --global url."git@gitlab.com:tyabuta".insteadOf "https://gitlab.com/tyabuta"

httpsでアクセスしようとすると、ssh-keyが使われない為、
プライベートリポジトリのアクセスに失敗するという事だろう。
代わりに、git@を使って、ssh-key接続でクローンさせる。

コメントを残す