GitBucket と連携する Go 製 CLI ツールを作った

## 作ったもの

https://github.com/guitarinchen/gitbucket-cli

[GitBucket](https://github.com/gitbucket/gitbucket) とシームレスに連携する CLI ツールで、コマンドラインからの GitBucket の操作を可能にします。作成にあたっては [gh](https://github.com/cli/cli) を参考にしており、実行も gh と同様のコマンド・サブコマンドで行えるようにしています。

## モチベーション

私は仕事で [GitBucket](https://github.com/gitbucket/gitbucket) を利用しているのですが、GitBucket には GitHub の gh のようなコマンドラインから操作できるようなツールがありません。そのため、煩わしさを感じながらもほぼ全ての操作を GUI で行っていました。しかし、幸い GitBucket にも [API](https://github.com/gitbucket/gitbucket/wiki/API-WebHook) は用意されているので、それらを利用すれば GUI の操作から抜け出せるのではと思い本ツールの作成に至りました。

※GitBucket の GUI は非常にわかりやすいです。ここでの煩わしさとは私がウィンドウの切り替えやマウス操作を面倒くさがっていることに起因するものです。

## 使用技術

- [Go](https://go.dev/)
- [Cobra](https://github.com/spf13/cobra)

## インストール

現状では `go install` でのインストールにのみ対応しています。

`go install github.com/guitarinchen/gitbucket-cli@latest`

## 基本的な機能

### リポジトリ

<details><summary>作成</summary>

```sh
❯ gitbucket-cli repo create example
{
  "data": {
    "clone_url": "http://localhost:8080/git/root/example.git",
    "default_branch": "master",
    "description": "",
    "forks": 0,
    "forks_count": 0,
    "full_name": "root/example",
    "has_issues": true,
    "html_url": "http://localhost:8080/root/example",
    "id": 0,
    "name": "example",
    "owner": {
      "avatar_url": "http://localhost:8080/root/_avatar",
      "created_at": "2024-12-27T14:47:05Z",
      "email": "root@localhost",
      "html_url": "http://localhost:8080/root",
      "id": 0,
      "login": "root",
      "site_admin": true,
      "type": "User",
      "url": "http://localhost:8080/api/v3/users/root"
    },
    "private": false,
    "url": "http://localhost:8080/api/v3/repos/root/example",
    "watchers": 0,
    "watchers_count": 0
  }
}
```
</details>

<details><summary>取得</summary>

```sh
❯ gitbucket-cli repo list           
{
  "data": [
    {
      "clone_url": "http://localhost:8080/git/root/example2.git",
      "default_branch": "master",
      "description": "",
      "forks": 0,
      "forks_count": 0,
      "full_name": "root/example2",
      "has_issues": true,
      "html_url": "http://localhost:8080/root/example2",
      "id": 0,
      "name": "example2",
      "owner": {
        "avatar_url": "http://localhost:8080/root/_avatar",
        "created_at": "2024-12-27T14:47:05Z",
        "email": "root@localhost",
        "html_url": "http://localhost:8080/root",
        "id": 0,
        "login": "root",
        "site_admin": true,
        "type": "User",
        "url": "http://localhost:8080/api/v3/users/root"
      },
      "private": false,
      "url": "http://localhost:8080/api/v3/repos/root/example2",
      "watchers": 0,
      "watchers_count": 0
    },
    {
      "clone_url": "http://localhost:8080/git/root/example.git",
      "default_branch": "master",
      "description": "",
      "forks": 0,
      "forks_count": 0,
      "full_name": "root/example",
      "has_issues": true,
      "html_url": "http://localhost:8080/root/example",
      "id": 0,
      "name": "example",
      "owner": {
        "avatar_url": "http://localhost:8080/root/_avatar",
        "created_at": "2024-12-27T14:47:05Z",
        "email": "root@localhost",
        "html_url": "http://localhost:8080/root",
        "id": 0,
        "login": "root",
        "site_admin": true,
        "type": "User",
        "url": "http://localhost:8080/api/v3/users/root"
      },
      "private": false,
      "url": "http://localhost:8080/api/v3/repos/root/example",
      "watchers": 0,
      "watchers_count": 0
    }
  ]
}
```
</details>

### Issue

<details><summary>作成</summary>

```sh
❯ gitbucket-cli issue create --repo example --title 'Example Issue' --body 'This is an example issue.'
{
  "data": {
    "assignees": [],
    "body": "This is an example issue.",
    "comments_url": "http://localhost:8080/api/v3/repos/root/example/issues/1/comments",
    "created_at": "2024-12-27T14:56:07Z",
    "html_url": "http://localhost:8080/root/example/issues/1",
    "id": 0,
    "labels": [],
    "number": 1,
    "state": "open",
    "title": "Example Issue",
    "updated_at": "2024-12-27T14:56:07Z",
    "user": {
      "avatar_url": "http://localhost:8080/root/_avatar",
      "created_at": "2024-12-27T14:47:05Z",
      "email": "root@localhost",
      "html_url": "http://localhost:8080/root",
      "id": 0,
      "login": "root",
      "site_admin": true,
      "type": "User",
      "url": "http://localhost:8080/api/v3/users/root"
    }
  }
}
```
</details>

<details><summary>取得</summary>

```sh
❯ gitbucket-cli issue list example
{
  "data": [
    {
      "assignees": [],
      "body": "This is an example issue.",
      "comments_url": "http://localhost:8080/api/v3/repos/root/example/issues/1/comments",
      "created_at": "2024-12-27T14:56:07Z",
      "html_url": "http://localhost:8080/root/example/issues/1",
      "id": 0,
      "labels": [],
      "number": 1,
      "state": "open",
      "title": "Example Issue",
      "updated_at": "2024-12-27T14:56:07Z",
      "user": {
        "avatar_url": "http://localhost:8080/root/_avatar",
        "created_at": "2024-12-27T14:47:05Z",
        "email": "root@localhost",
        "html_url": "http://localhost:8080/root",
        "id": 0,
        "login": "root",
        "site_admin": true,
        "type": "User",
        "url": "http://localhost:8080/api/v3/users/root"
      }
    },
    {
      "assignees": [],
      "body": "This is an example issue2.",
      "comments_url": "http://localhost:8080/api/v3/repos/root/example/issues/2/comments",
      "created_at": "2024-12-27T14:56:48Z",
      "html_url": "http://localhost:8080/root/example/issues/2",
      "id": 0,
      "labels": [],
      "number": 2,
      "state": "open",
      "title": "Example Issue2",
      "updated_at": "2024-12-27T14:56:48Z",
      "user": {
        "avatar_url": "http://localhost:8080/root/_avatar",
        "created_at": "2024-12-27T14:47:05Z",
        "email": "root@localhost",
        "html_url": "http://localhost:8080/root",
        "id": 0,
        "login": "root",
        "site_admin": true,
        "type": "User",
        "url": "http://localhost:8080/api/v3/users/root"
      }
    }
  ]
}
```
</details>

### その他

ここでは省略していますが、以下のような操作も可能です。

- プライベートなリポジトリの作成
- リポジトリのクローン
- 状態 (open/closed) を指定した Issue の取得
- 組織 (Group) の作成・取得
- ラベルの作成・取得

## まとめ

今回は GitBucket と連携する自作の CLI ツールの紹介でした。こういった技術系の記事を投稿するのは初めてということもあり拙い文面だとは思いますが、ここまで読んでいただきありがとうございました。

今後も API で対応している操作については本ツールでも可能な限り対応していくつもりです。Feature request/Bug report はどうぞご気軽に [Issue](https://github.com/guitarinchen/gitbucket-cli/issues) に挙げてください。