@aaronshaf/ger 2.0.1 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -0
- package/docs/adr/0023-show-reviewer-list.md +42 -0
- package/docs/adr/README.md +1 -0
- package/docs/prd/commands.md +74 -1
- package/docs/prd/data-model.md +19 -8
- package/llms.txt +217 -0
- package/package.json +1 -1
- package/src/api/gerrit.ts +63 -60
- package/src/cli/commands/comment.ts +18 -0
- package/src/cli/commands/install-hook.ts +59 -0
- package/src/cli/commands/show.ts +123 -1
- package/src/cli/commands/topic.ts +108 -0
- package/src/cli/register-commands.ts +55 -33
- package/src/schemas/gerrit.ts +26 -8
- package/tests/show.test.ts +126 -0
- package/tests/submit.test.ts +28 -0
- package/tests/topic.test.ts +443 -0
- package/tests/unit/commands/install-hook.test.ts +258 -0
package/README.md
CHANGED
|
@@ -421,6 +421,22 @@ ger diff 12345 --file src/main.ts
|
|
|
421
421
|
|
|
422
422
|
### Change Management
|
|
423
423
|
|
|
424
|
+
#### Install Commit-Msg Hook
|
|
425
|
+
```bash
|
|
426
|
+
# Install the Gerrit commit-msg hook
|
|
427
|
+
ger install-hook
|
|
428
|
+
|
|
429
|
+
# Force reinstall (overwrite existing)
|
|
430
|
+
ger install-hook --force
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
**What it does:**
|
|
434
|
+
- Downloads the commit-msg hook from your configured Gerrit server
|
|
435
|
+
- Installs to `.git/hooks/commit-msg` with executable permissions
|
|
436
|
+
- Required for commits to have Change-Id footers
|
|
437
|
+
|
|
438
|
+
**Note:** The `push` command auto-installs the hook if missing, but you can use this command to manually install or update it.
|
|
439
|
+
|
|
424
440
|
#### Checkout Changes
|
|
425
441
|
```bash
|
|
426
442
|
# Checkout latest patchset
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# ADR 0023: Surface Reviewers and CCs in `ger show`
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
`ger` supports reviewer management (`add-reviewer`, `remove-reviewer`) but did not expose a reliable way to view current reviewers for a change in one command.
|
|
10
|
+
|
|
11
|
+
This created a workflow gap:
|
|
12
|
+
|
|
13
|
+
- Users could mutate reviewer state but not inspect it from the CLI.
|
|
14
|
+
- `show` already served as the canonical "single change detail" command and was the best place to surface reviewer assignments.
|
|
15
|
+
|
|
16
|
+
## Decision
|
|
17
|
+
|
|
18
|
+
Add reviewer visibility to `ger show` by:
|
|
19
|
+
|
|
20
|
+
1. Keeping `getChange` lightweight and using a `listChanges` fallback (with detailed account/label options) when reviewer state is not present in the base change response.
|
|
21
|
+
2. Extending `ChangeInfo` schema with Gerrit reviewer state maps (`REVIEWER`, `CC`, `REMOVED`).
|
|
22
|
+
3. Rendering reviewers and CCs in all `show` output formats (pretty, JSON, XML).
|
|
23
|
+
|
|
24
|
+
## Rationale
|
|
25
|
+
|
|
26
|
+
- **Single source of truth**: `show` remains the canonical command for full change context.
|
|
27
|
+
- **No new command surface**: avoids adding a narrowly scoped `list-reviewers` command.
|
|
28
|
+
- **Automation-friendly**: JSON/XML consumers can parse reviewer state without scraping text output.
|
|
29
|
+
- **Backward compatible**: reviewer fields are optional and do not break servers or older data shapes.
|
|
30
|
+
|
|
31
|
+
## Consequences
|
|
32
|
+
|
|
33
|
+
### Positive
|
|
34
|
+
|
|
35
|
+
- Users can verify reviewer assignment directly after add/remove operations.
|
|
36
|
+
- Better parity between mutation commands and read visibility.
|
|
37
|
+
- More complete machine-readable change payloads.
|
|
38
|
+
|
|
39
|
+
### Negative
|
|
40
|
+
|
|
41
|
+
- Extra `listChanges` request when reviewer data is absent from `getChange`.
|
|
42
|
+
- Additional schema/output maintenance for reviewer state rendering.
|
package/docs/adr/README.md
CHANGED
|
@@ -28,3 +28,4 @@ Records of significant architectural decisions with context and rationale. Each
|
|
|
28
28
|
| [0020](0020-code-coverage-enforcement.md) | 80% coverage threshold in pre-commit |
|
|
29
29
|
| [0021](0021-typescript-isolated-declarations.md) | Explicit return types on exports |
|
|
30
30
|
| [0022](0022-biome-oxlint-tooling.md) | Biome formatter + oxlint linter |
|
|
31
|
+
| [0023](0023-show-reviewer-list.md) | Surface reviewers and CCs in `ger show` |
|
package/docs/prd/commands.md
CHANGED
|
@@ -23,11 +23,13 @@ ger show # Auto-detect from HEAD
|
|
|
23
23
|
|
|
24
24
|
**Output includes:**
|
|
25
25
|
- Change metadata (number, project, branch, status)
|
|
26
|
-
- Owner and
|
|
26
|
+
- Owner, reviewers, and CC information
|
|
27
27
|
- Submit requirements
|
|
28
28
|
- Full diff
|
|
29
29
|
- All comments with context
|
|
30
30
|
|
|
31
|
+
Reviewer listing for a specific change is provided by `show` (there is no separate `list-reviewers` command).
|
|
32
|
+
|
|
31
33
|
### diff
|
|
32
34
|
|
|
33
35
|
Get change diff in various formats.
|
|
@@ -129,6 +131,55 @@ ger workspace
|
|
|
129
131
|
|
|
130
132
|
**Output:** Current branch and associated Gerrit change.
|
|
131
133
|
|
|
134
|
+
### topic
|
|
135
|
+
|
|
136
|
+
Get, set, or remove topic for a change.
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
ger topic [change-id] # View current topic (auto-detect from HEAD)
|
|
140
|
+
ger topic [change-id] <topic> # Set topic
|
|
141
|
+
ger topic [change-id] --delete # Remove topic
|
|
142
|
+
ger topic [change-id] --xml # XML output
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
| Option | Description |
|
|
146
|
+
|--------|-------------|
|
|
147
|
+
| `--delete` | Remove the topic from the change |
|
|
148
|
+
| `--xml` | Output as XML for LLM consumption |
|
|
149
|
+
|
|
150
|
+
**Output formats:**
|
|
151
|
+
|
|
152
|
+
Text (get):
|
|
153
|
+
```
|
|
154
|
+
my-feature
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Text (set):
|
|
158
|
+
```
|
|
159
|
+
✓ Set topic on change 12345: my-feature
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Text (delete):
|
|
163
|
+
```
|
|
164
|
+
✓ Removed topic from change 12345
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
XML:
|
|
168
|
+
```xml
|
|
169
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
170
|
+
<topic_result>
|
|
171
|
+
<status>success</status>
|
|
172
|
+
<action>get|set|deleted</action>
|
|
173
|
+
<change_id><![CDATA[12345]]></change_id>
|
|
174
|
+
<topic><![CDATA[my-feature]]></topic>
|
|
175
|
+
</topic_result>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Use cases:**
|
|
179
|
+
- Group related changes under a common topic
|
|
180
|
+
- Filter changes by topic in Gerrit UI
|
|
181
|
+
- Organize work for releases or features
|
|
182
|
+
|
|
132
183
|
## Code Review
|
|
133
184
|
|
|
134
185
|
### comment
|
|
@@ -370,6 +421,28 @@ ger init # Alias
|
|
|
370
421
|
|
|
371
422
|
**Creates:** `~/.ger/config.json` with secure permissions.
|
|
372
423
|
|
|
424
|
+
### install-hook
|
|
425
|
+
|
|
426
|
+
Install the Gerrit commit-msg hook for automatic Change-Id generation.
|
|
427
|
+
|
|
428
|
+
```bash
|
|
429
|
+
ger install-hook
|
|
430
|
+
ger install-hook --force # Overwrite existing hook
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
| Option | Description |
|
|
434
|
+
|--------|-------------|
|
|
435
|
+
| `--force` | Overwrite existing hook |
|
|
436
|
+
| `--xml` | Output as XML |
|
|
437
|
+
|
|
438
|
+
**Downloads:** Hook from configured Gerrit server.
|
|
439
|
+
**Installs to:** `.git/hooks/commit-msg` (executable).
|
|
440
|
+
|
|
441
|
+
**Use cases:**
|
|
442
|
+
- Set up a new clone before first push
|
|
443
|
+
- Repair corrupted hook
|
|
444
|
+
- Update hook after Gerrit upgrade
|
|
445
|
+
|
|
373
446
|
### open
|
|
374
447
|
|
|
375
448
|
Open change in browser.
|
package/docs/prd/data-model.md
CHANGED
|
@@ -14,25 +14,36 @@ const ChangeInfo = Schema.Struct({
|
|
|
14
14
|
_number: Schema.Number, // Numeric change ID
|
|
15
15
|
project: Schema.String, // Project name
|
|
16
16
|
branch: Schema.String, // Target branch
|
|
17
|
+
change_id: Schema.String, // Gerrit Change-Id
|
|
17
18
|
topic: Schema.optional(Schema.String),
|
|
18
19
|
subject: Schema.String, // First line of commit message
|
|
19
20
|
status: Schema.Literal('NEW', 'MERGED', 'ABANDONED', 'DRAFT'),
|
|
20
|
-
created: Schema.String,
|
|
21
|
-
updated: Schema.String,
|
|
22
|
-
|
|
23
|
-
submitter: Schema.optional(AccountInfo),
|
|
24
|
-
owner: AccountInfo,
|
|
21
|
+
created: Schema.optional(Schema.String),
|
|
22
|
+
updated: Schema.optional(Schema.String),
|
|
23
|
+
owner: Schema.optional(AccountInfo),
|
|
25
24
|
current_revision: Schema.optional(Schema.String),
|
|
26
25
|
revisions: Schema.optional(Schema.Record(Schema.String, RevisionInfo)),
|
|
27
26
|
labels: Schema.optional(Schema.Record(Schema.String, LabelInfo)),
|
|
28
|
-
reviewers: Schema.optional(
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
reviewers: Schema.optional(ReviewerStateMap),
|
|
28
|
+
submittable: Schema.optional(Schema.Boolean),
|
|
29
|
+
work_in_progress: Schema.optional(Schema.Boolean),
|
|
31
30
|
insertions: Schema.optional(Schema.Number),
|
|
32
31
|
deletions: Schema.optional(Schema.Number),
|
|
33
32
|
})
|
|
34
33
|
```
|
|
35
34
|
|
|
35
|
+
### ReviewerStateMap
|
|
36
|
+
|
|
37
|
+
Reviewer assignments grouped by Gerrit reviewer state.
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
const ReviewerStateMap = Schema.Struct({
|
|
41
|
+
REVIEWER: Schema.optional(Schema.Array(AccountInfo)),
|
|
42
|
+
CC: Schema.optional(Schema.Array(AccountInfo)),
|
|
43
|
+
REMOVED: Schema.optional(Schema.Array(AccountInfo)),
|
|
44
|
+
})
|
|
45
|
+
```
|
|
46
|
+
|
|
36
47
|
### AccountInfo
|
|
37
48
|
|
|
38
49
|
User account information.
|
package/llms.txt
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# ger
|
|
2
|
+
|
|
3
|
+
> CLI for Gerrit code review. Query changes, post comments, vote, manage reviewers, checkout/push code, check build status. Supports XML output for LLM pipelines.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun install -g @aaronshaf/ger
|
|
9
|
+
ger setup # Configure credentials interactively
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Change Identifiers
|
|
13
|
+
|
|
14
|
+
Commands accept change number (12345) or Change-ID (If5a3ae8...). Many commands auto-detect from HEAD commit when omitted.
|
|
15
|
+
|
|
16
|
+
## Commands
|
|
17
|
+
|
|
18
|
+
### View Changes
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
ger show [change-id] # Full change info: metadata, diff, comments
|
|
22
|
+
ger show --xml # XML output for LLM consumption
|
|
23
|
+
ger diff <change-id> # Get diff
|
|
24
|
+
ger diff <change-id> --files-only # List changed files only
|
|
25
|
+
ger comments <change-id> # View all comments with context
|
|
26
|
+
ger search "owner:self status:open" # Gerrit query syntax
|
|
27
|
+
ger search "project:foo" -n 10 # Limit results
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### List Changes
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
ger mine # Your open changes
|
|
34
|
+
ger incoming # Changes awaiting your review
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Post Comments
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
ger comment <change-id> -m "LGTM" # Overall comment
|
|
41
|
+
echo "Review text" | ger comment <change-id> # Piped input
|
|
42
|
+
ger comment <change-id> --file src/foo.ts --line 42 -m "Fix this" # Line comment
|
|
43
|
+
ger comment <change-id> --file src/foo.ts --line 42 -m "Bug" --unresolved
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Batch comments via JSON stdin:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
echo '[
|
|
50
|
+
{"file": "src/main.ts", "line": 10, "message": "Add type annotation"},
|
|
51
|
+
{"file": "src/api.ts", "line": 25, "message": "Handle error", "unresolved": true}
|
|
52
|
+
]' | ger comment <change-id> --batch
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
JSON schema: `{"file": string, "line": number, "message": string, "unresolved"?: boolean, "side"?: "PARENT"|"REVISION", "range"?: {start_line, end_line, start_character?, end_character?}}`
|
|
56
|
+
|
|
57
|
+
### Vote
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
ger vote <change-id> --code-review +2
|
|
61
|
+
ger vote <change-id> --code-review +2 --verified +1 -m "LGTM"
|
|
62
|
+
ger vote <change-id> --label "Custom-Label" +1
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Manage Reviewers
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
ger add-reviewer user@example.com -c <change-id>
|
|
69
|
+
ger add-reviewer user1 user2 -c <change-id>
|
|
70
|
+
ger add-reviewer --group team-name -c <change-id>
|
|
71
|
+
ger add-reviewer --cc user@example.com -c <change-id>
|
|
72
|
+
ger remove-reviewer user@example.com -c <change-id>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Topic Management
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
ger topic <change-id> # View current topic
|
|
79
|
+
ger topic <change-id> my-feature # Set topic
|
|
80
|
+
ger topic <change-id> --delete # Remove topic
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Git Operations
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
ger checkout <change-id> # Fetch and checkout change
|
|
87
|
+
ger checkout <change-id> --detach # Detached HEAD
|
|
88
|
+
ger push # Push for review
|
|
89
|
+
ger push -r alice@example.com -t my-topic --wip
|
|
90
|
+
ger push --dry-run # Preview push
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Change Lifecycle
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
ger rebase [change-id] # Rebase onto target branch
|
|
97
|
+
ger submit <change-id> # Submit for merge
|
|
98
|
+
ger abandon <change-id> -m "reason"
|
|
99
|
+
ger restore <change-id>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Build Status
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
ger build-status [change-id] # Check status: pending|running|success|failure
|
|
106
|
+
ger build-status --watch # Poll until completion
|
|
107
|
+
ger build-status --watch --exit-status && deploy.sh # Exit 1 on failure
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Extract URLs
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
ger extract-url "build-summary-report" | tail -1 # Latest Jenkins URL
|
|
114
|
+
ger extract-url "jenkins" --json | jq -r '.urls[-1]'
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### AI Review
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
ger review <change-id> # AI-powered review (requires claude/gemini/opencode CLI)
|
|
121
|
+
ger review <change-id> --tool claude
|
|
122
|
+
ger review <change-id> --comment --yes # Post review comments
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Groups
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
ger groups # List groups
|
|
129
|
+
ger groups --pattern "^team-.*" # Filter by regex
|
|
130
|
+
ger groups-show <group-id> # Group details
|
|
131
|
+
ger groups-members <group-id> # List members
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Utilities
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
ger status # Check connection
|
|
138
|
+
ger open <change-id> # Open in browser
|
|
139
|
+
ger install-hook # Install commit-msg hook
|
|
140
|
+
ger projects # List projects
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Output Formats
|
|
144
|
+
|
|
145
|
+
Most commands support `--xml` for structured LLM output:
|
|
146
|
+
|
|
147
|
+
```xml
|
|
148
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
149
|
+
<comment_result>
|
|
150
|
+
<status>success</status>
|
|
151
|
+
<change_id>12345</change_id>
|
|
152
|
+
</comment_result>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Some commands also support `--json`.
|
|
156
|
+
|
|
157
|
+
## Gerrit Query Syntax
|
|
158
|
+
|
|
159
|
+
Common operators for `ger search`:
|
|
160
|
+
|
|
161
|
+
- `owner:USER` - Changes owned by user (use 'self' for yourself)
|
|
162
|
+
- `status:STATE` - open, merged, abandoned
|
|
163
|
+
- `project:NAME` - Filter by project
|
|
164
|
+
- `branch:NAME` - Filter by branch
|
|
165
|
+
- `reviewer:USER` - Changes where user is reviewer
|
|
166
|
+
- `is:wip` - Work-in-progress
|
|
167
|
+
- `is:submittable` - Ready to submit
|
|
168
|
+
- `age:TIME` - Time since update (1d, 2w, 1mon)
|
|
169
|
+
- `label:Code-Review+2` - Filter by vote
|
|
170
|
+
|
|
171
|
+
## Common Workflows
|
|
172
|
+
|
|
173
|
+
### Review a change
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
ger show 12345 # View change
|
|
177
|
+
ger diff 12345 # See code changes
|
|
178
|
+
ger comment 12345 -m "LGTM" # Add comment
|
|
179
|
+
ger vote 12345 --code-review +2 # Approve
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Post AI review
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
ger review 12345 --comment --yes
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Check build and get failures
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
ger build-status --watch --exit-status
|
|
192
|
+
ger extract-url "build-summary-report" | tail -1 # Get Jenkins URL
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Push with reviewers
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
ger push -r alice@example.com -r bob@example.com -t feature-topic
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Exit Codes
|
|
202
|
+
|
|
203
|
+
- `0` - Success
|
|
204
|
+
- `1` - Error (or build failure with --exit-status)
|
|
205
|
+
- `2` - Timeout
|
|
206
|
+
- `3` - API/network error
|
|
207
|
+
|
|
208
|
+
## Configuration
|
|
209
|
+
|
|
210
|
+
Credentials stored in `~/.ger/config.json`. Run `ger setup` to configure:
|
|
211
|
+
- Gerrit host URL
|
|
212
|
+
- Username
|
|
213
|
+
- HTTP password (from Gerrit settings)
|
|
214
|
+
|
|
215
|
+
## Links
|
|
216
|
+
|
|
217
|
+
- [Gerrit Query Syntax](https://gerrit-review.googlesource.com/Documentation/user-search.html)
|