rickub/clipublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/rickub/cli.git
git clone ssh://git@rickub.com/rickub/cli.git
README.md · 241 lines · 8.7 KBmarkdown Blame HistoryRaw
Initial import of the rickub CLI as a standalone public project 1a1d430 Olivier Girardot 8h ago1# rickub CLI
2
3`rickub` is the command-line interface to a [rickub](https://rickub.com) git host —
4*the smartest git in the universe, on the command line.* It is a thin, standalone
5HTTP client for the rickub JSON API (`/api/v1`), authenticated with a personal
6access token (PAT). It imports none of the server's code: a clean client boundary.
7
8- Repo: `ssh://git@rickub.com/rickub/cli.git`
9- Home: <https://rickub.com/rickub/cli>
10
11## Install
12
13**Download a release.** Binaries for linux (amd64, arm64) and macos (amd64,
14arm64) are attached to each release at <https://rickub.com/rickub/cli/releases>.
15Open that page, download the archive matching your OS and architecture, extract
16it, and put `rickub` on your `PATH`:
17
18```sh
19# after downloading the asset for your platform from the releases page:
20tar -xzf rickub_<version>_<os>_<arch>.tar.gz rickub
21sudo install rickub /usr/local/bin/rickub
22```
23
24> Note: rickub.com serves release assets from the release page itself — there is
25> no `/releases/latest/download/…` redirect, so pick the asset from the page (or
26> from the release's API entry) rather than guessing a URL.
27
28**Build from source** (Go 1.26+):
29
30```sh
31git clone ssh://git@rickub.com/rickub/cli.git
32cd cli
33go build -o rickub . # produces ./rickub at the repo root
34```
35
36To stamp a version into the binary:
37
38```sh
39go build -ldflags "-X rickub.com/rickub/cli/cmd.Version=$(git describe --tags)" -o rickub .
40```
41
42Verify:
43
44```sh
45./rickub version
46```
47
48## Authenticate
49
50```sh
51# browser (device) flow — the default. Prints a code, opens your browser,
52# waits for you to approve the sign-in while logged in to the website, and
53# stores the PAT the server mints. Nothing is copy-pasted.
54rickub auth login
55rickub auth login --host https://dev.rickub.com # any rickub host
56rickub auth login --scope read # a read-only token
57rickub auth login --no-browser # print the URL, don't open it
58```
59
60To use an existing PAT from *Settings → Tokens* instead, prefer one of the two
61forms that keep the secret out of your shell:
62
63```sh
64# 1. environment variable — nothing is written to disk
65export RICKUB_TOKEN=rickub_pat_xxx
66rickub repo list
67
68# 2. stdin, for `auth login` to verify and store it
69echo "$RICKUB_PAT" | rickub auth login --with-token --host https://rickub.com
70```
71
72There is also a `--token rickub_pat_xxx` flag on any command. Use it only when
73neither of the above fits: **arguments are visible to every process on the
74machine via `ps`, and land in your shell history and in CI logs.**
75
76The stored token lives in `~/.config/rickub/config.yaml` (mode `0600`). The
77browser flow mints a normal PAT named "CLI device login" — revoke it any time
78in Settings → Tokens.
79
80```sh
81rickub auth status # show the active host, where the token came from, and verify it
82rickub auth logout # remove the stored token for the active host
83```
84
85### Tokens are bound to their host
86
87A token stored by `auth login` is saved **under the host it was verified
88against** and is only ever sent back to that host. Pointing the CLI at a
89different server — `--host`, `RICKUB_HOST`, or a typo — will not hand your
90production credential to it; you get "no token stored for that host" instead.
91Log in per host as needed:
92
93```sh
94rickub auth login --host https://rickub.com # stored for rickub.com
95rickub auth login --host http://localhost:3000 # stored separately
96rickub auth logout --host http://localhost:3000 # removes only that one
97```
98
99A token you pass explicitly with `--token` or `RICKUB_TOKEN` is always honoured
100for whatever host is in effect — that is your call to make, not the config's.
101
102The CLI also prints a warning to stderr before sending a token to a host over
103plain `http://`, unless that host is loopback (`localhost`, `127.0.0.1`, `[::1]`),
104where the request never reaches the network.
105
106### Config & environment
107
108Effective host and token are resolved with this precedence (first wins):
109
110| Value | Precedence |
111|-------|-----------|
112| host | `--host` flag → `RICKUB_HOST` env → config file → `https://rickub.com` |
113| token | `--token` flag → `RICKUB_TOKEN` env → config file entry **for that host** |
114
115Point the CLI at a dev instance with `--host http://localhost:3000` (or set
116`RICKUB_HOST`). `XDG_CONFIG_HOME` is honoured for the config file location.
117
118The config file looks like this:
119
120```yaml
121host: https://rickub.com
122hosts:
123 https://rickub.com:
124 token: rickub_pat_…
125 http://localhost:3000:
126 token: rickub_pat_…
127```
128
129## Command reference
130
131Every command supports `--help`, and `--json` for raw JSON output instead of a table.
132
133```
134rickub auth login|status|logout
135
136rickub repo list [--user H | --org H] [--page N] [--per-page N]
137rickub repo create <name> [--org H] [--public|--private] [-d desc]
138rickub repo view <owner/repo>
139rickub repo edit <owner/repo> [--visibility public|private] [-d desc] [--default-branch B]
140rickub repo delete <owner/repo> [--yes]
141rickub repo clone <owner/repo> [dir] [-- git-args…]
142rickub repo files <owner/repo> [path] [--ref R]
143rickub repo cat <owner/repo> <path> [--ref R]
144rickub repo commits <owner/repo> [ref] [--page N] [--per-page N]
145rickub repo compare <owner/repo> <base...head>
146rickub repo collaborator list <owner/repo>
147rickub repo collaborator add <owner/repo> <user> [--permission read|write|admin]
148rickub repo collaborator remove <owner/repo> <user>
149
150rickub pr list [-R owner/repo] [--state open|closed|merged|all]
151rickub pr view <number> [-R owner/repo]
152rickub pr create [-R owner/repo] --base B --head H --title T [-b body] [--head-owner O --head-repo R]
153rickub pr merge <number> [-R owner/repo] [--method merge|squash|ff-only]
154rickub pr close <number> [-R owner/repo]
155rickub pr comment <number> [-R owner/repo] -b "text"
156
157rickub run list [-R owner/repo]
158rickub run view <number> [-R owner/repo]
159rickub run logs <number> [-R owner/repo]
160rickub run rerun <number> [-R owner/repo]
161rickub run cancel <number> [-R owner/repo]
162rickub run dispatch [-R owner/repo] [--ref B]
163rickub run watch <number> [-R owner/repo] [--interval 2s] [--timeout 30m] [--logs]
164 # follow until terminal; exit 0 on success, 1 otherwise
165
166rickub issue list [-R owner/repo] [--state open|closed|all] [--page N]
167rickub issue view <number> [-R owner/repo]
168rickub issue create [-R owner/repo] -t "title" [-b "body" | -b - < file]
169rickub issue close <number> [-R owner/repo]
170rickub issue reopen <number> [-R owner/repo]
171rickub issue comment <number> [-R owner/repo] -b "text"
172rickub issue label <number> [-R owner/repo] --labels "bug,help wanted" | --clear
173rickub issue milestone <number> [-R owner/repo] --milestone "v1.0" | --clear
174rickub issue assign <number> [-R owner/repo] --user H [--remove]
175rickub issue labels [-R owner/repo]
176
177rickub milestone list [-R owner/repo] [--state open|closed|all]
178rickub milestone create [-R owner/repo] -t "v1.0" [-d desc] [--due YYYY-MM-DD]
179rickub milestone close <id> [-R owner/repo]
180rickub milestone reopen <id> [-R owner/repo]
181rickub milestone delete <id> [-R owner/repo]
182
183rickub org view <handle>
184rickub org members <handle>
185rickub org teams <handle>
186
187rickub search repos <query> [--page N] [--per-page N]
188
189rickub api <METHOD> <path> [-f key=value] [-F key=value] # raw escape hatch
190rickub browse [owner/repo] [--print]
191rickub version
192```
193
194### Repo selector
195
196`pr`, `run`, `issue`, and `milestone` subcommands take `-R/--repo owner/repo`. When omitted, the repo is
197inferred from the current directory's git `origin` remote (any of `https://`,
198`ssh://`, or `git@host:owner/repo` forms).
199
200### `rickub api` — raw escape hatch
201
202Like `gh api`. `PATH` is relative to `/api/v1` (a leading `/api/v1` or `/` is
203optional). `--field/-f` values are type-inferred (`true`/`false`/`null`/numbers);
204`--raw-field/-F` forces a string. Fields become query parameters for `GET`/`HEAD`
205and a JSON body otherwise.
206
207```sh
208rickub api GET /user
209rickub api GET search/repos -f q=api
210rickub api POST /repos -f name=demo -f visibility=public
211```
212
213## Errors & exit codes
214
215API errors are surfaced from the `{error:{code,message}}` envelope, e.g.
216`rickub: repository not found (not_found)`, and the process exits non-zero.
217
218## Pointing at a dev host
219
220```sh
221# run a rickub instance on a spare port, then:
222echo "$DEV_PAT" | rickub auth login --with-token --host http://localhost:3000
223rickub repo list --user <you>
224```
225
226The dev token is stored separately from your rickub.com token; both stay put.
227
228## Development
229
230```sh
231go build ./... && go test ./... && go vet ./... && gofmt -l .
232```
233
234Layout:
235
236```
237main.go # entrypoint; maps API errors to exit codes
238cmd/ # Cobra command tree (auth, repo, pr, issue, milestone, run, org, search, api, browse)
239internal/api/ # typed HTTP client for the rickub JSON API
240internal/config/ # config load/save + host/token resolution and binding
241```