ya-git-jira 2.0.0 → 2.1.1
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/.dockerignore +8 -0
- package/.opencode/skills/git-confluence/SKILL.md +18 -18
- package/.opencode/skills/git-jira/SKILL.md +18 -18
- package/.opencode/skills/git-lab/SKILL.md +30 -30
- package/Dockerfile +58 -0
- package/README.md +31 -12
- package/bin/git-api.ts +2 -4
- package/bin/git-bump.ts +2 -4
- package/bin/git-confluence-page-search.ts +4 -6
- package/bin/git-confluence-page-show.ts +3 -5
- package/bin/git-confluence-page-update.ts +3 -5
- package/bin/git-confluence-page.ts +2 -4
- package/bin/git-confluence-space-list.ts +3 -5
- package/bin/git-confluence-space.ts +2 -4
- package/bin/git-confluence-whoami.ts +3 -5
- package/bin/git-confluence.ts +11 -4
- package/bin/git-jira-issue-list.ts +2 -4
- package/bin/git-jira-issue-show.ts +3 -5
- package/bin/git-jira-issue.ts +2 -4
- package/bin/git-jira-start.ts +2 -4
- package/bin/git-jira-whoami.ts +3 -5
- package/bin/git-jira.ts +11 -4
- package/bin/git-lab-group-list.ts +4 -6
- package/bin/git-lab-group.ts +2 -4
- package/bin/git-lab-merge-active.ts +4 -6
- package/bin/git-lab-merge-todo.ts +4 -6
- package/bin/git-lab-merge-train-list.ts +3 -5
- package/bin/git-lab-merge-train.ts +2 -4
- package/bin/git-lab-merge.ts +2 -4
- package/bin/git-lab-namespace-list.ts +3 -5
- package/bin/git-lab-namespace.ts +2 -4
- package/bin/git-lab-project-list.ts +4 -6
- package/bin/git-lab-project-mr-list.ts +4 -6
- package/bin/git-lab-project-mr.ts +2 -4
- package/bin/git-lab-project-pipeline-jobs.ts +2 -4
- package/bin/git-lab-project-pipeline-latest.ts +2 -4
- package/bin/git-lab-project-pipeline-list.ts +4 -6
- package/bin/git-lab-project-pipeline-log.ts +2 -4
- package/bin/git-lab-project-pipeline.ts +2 -4
- package/bin/git-lab-project-whereami.ts +3 -5
- package/bin/git-lab-project.ts +2 -4
- package/bin/git-lab-whoami.ts +3 -5
- package/bin/git-lab.ts +11 -4
- package/bin/gitj-install-skills.ts +15 -12
- package/bin/gitj.ts +6 -1
- package/dist/bin/git-api.js +33 -5
- package/dist/bin/git-bump.js +32 -24
- package/dist/bin/git-confluence-page-search.js +46 -26
- package/dist/bin/git-confluence-page-show.js +24 -4
- package/dist/bin/git-confluence-page-update.js +24 -4
- package/dist/bin/git-confluence-page.js +30 -16
- package/dist/bin/git-confluence-space-list.js +45 -25
- package/dist/bin/git-confluence-space.js +46 -28
- package/dist/bin/git-confluence-whoami.js +45 -25
- package/dist/bin/git-confluence.js +45 -31
- package/dist/bin/git-jira-issue-list.js +36 -24
- package/dist/bin/git-jira-issue-show.js +16 -4
- package/dist/bin/git-jira-issue.js +18 -10
- package/dist/bin/git-jira-start.js +16 -4
- package/dist/bin/git-jira-whoami.js +37 -25
- package/dist/bin/git-jira.js +32 -22
- package/dist/bin/git-lab-group-list.js +18 -6
- package/dist/bin/git-lab-group.js +19 -9
- package/dist/bin/git-lab-merge-active.js +18 -6
- package/dist/bin/git-lab-merge-todo.js +18 -6
- package/dist/bin/git-lab-merge-train-list.js +17 -5
- package/dist/bin/git-lab-merge-train.js +18 -8
- package/dist/bin/git-lab-merge.js +25 -21
- package/dist/bin/git-lab-namespace-list.js +38 -26
- package/dist/bin/git-lab-namespace.js +39 -29
- package/dist/bin/git-lab-project-list.js +18 -6
- package/dist/bin/git-lab-project-mr-list.js +18 -6
- package/dist/bin/git-lab-project-mr.js +19 -9
- package/dist/bin/git-lab-project-pipeline-jobs.js +16 -4
- package/dist/bin/git-lab-project-pipeline-latest.js +16 -4
- package/dist/bin/git-lab-project-pipeline-list.js +18 -6
- package/dist/bin/git-lab-project-pipeline-log.js +16 -4
- package/dist/bin/git-lab-project-pipeline.js +22 -18
- package/dist/bin/git-lab-project-whereami.js +17 -5
- package/dist/bin/git-lab-project.js +32 -38
- package/dist/bin/git-lab-whoami.js +17 -5
- package/dist/bin/git-lab.js +61 -81
- package/dist/bin/gitj-install-skills.js +21 -11
- package/dist/bin/gitj.js +154 -153
- package/dist/index.js +32 -1
- package/install-docker-gitj.sh +77 -0
- package/lib/api.ts +19 -1
- package/lib/confluence/api.ts +12 -0
- package/lib/confluence/config.ts +3 -3
- package/lib/gitlab/api.ts +4 -0
- package/lib/gitlab/config.ts +2 -2
- package/lib/is_main.ts +11 -0
- package/lib/jira.ts +7 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -717,6 +717,10 @@ async function confluenceApi(endpoint) {
|
|
|
717
717
|
};
|
|
718
718
|
let request = new Request(uri, options);
|
|
719
719
|
const response = await fetch(request);
|
|
720
|
+
if (!response.ok) {
|
|
721
|
+
const text = await response.text();
|
|
722
|
+
throw new Error(`Confluence API ${endpoint} failed (${response.status}): ${text}`);
|
|
723
|
+
}
|
|
720
724
|
let link = getNextLink(response.headers.get("Link"));
|
|
721
725
|
const body = await response.json();
|
|
722
726
|
if (!body.results) {
|
|
@@ -777,6 +781,10 @@ async function confluenceSearch(cql) {
|
|
|
777
781
|
while (uri) {
|
|
778
782
|
const request = new Request(uri, options);
|
|
779
783
|
const response = await fetch(request);
|
|
784
|
+
if (!response.ok) {
|
|
785
|
+
const text = await response.text();
|
|
786
|
+
throw new Error(`Confluence search failed (${response.status}): ${text}`);
|
|
787
|
+
}
|
|
780
788
|
const body = await response.json();
|
|
781
789
|
if (body.results) {
|
|
782
790
|
allResults = allResults.concat(body.results);
|
|
@@ -805,6 +813,10 @@ async function confluenceApiV1(endpoint) {
|
|
|
805
813
|
};
|
|
806
814
|
const request = new Request(uri, options);
|
|
807
815
|
const response = await fetch(request);
|
|
816
|
+
if (!response.ok) {
|
|
817
|
+
const text = await response.text();
|
|
818
|
+
throw new Error(`Confluence API v1 ${endpoint} failed (${response.status}): ${text}`);
|
|
819
|
+
}
|
|
808
820
|
const result = await response.json();
|
|
809
821
|
return result;
|
|
810
822
|
}
|
|
@@ -817,7 +829,7 @@ async function getGitlabConfig() {
|
|
|
817
829
|
const host = await hostP || "gitlab.com";
|
|
818
830
|
const user = await gitEmailP2 || await gitlabEmailP;
|
|
819
831
|
if (!user)
|
|
820
|
-
throw new Error("Neither user.email nor gitlab.
|
|
832
|
+
throw new Error("Neither user.email nor gitlab.user in git config");
|
|
821
833
|
const token = await tokenP;
|
|
822
834
|
if (!token)
|
|
823
835
|
throw new Error("gitlab.token not in git config");
|
|
@@ -854,6 +866,10 @@ async function gitlabApi(endpoint) {
|
|
|
854
866
|
};
|
|
855
867
|
let request = new Request(uri, options);
|
|
856
868
|
const response = await fetch(request);
|
|
869
|
+
if (!response.ok) {
|
|
870
|
+
const text = await response.text();
|
|
871
|
+
throw new Error(`GitLab API ${endpoint} failed (${response.status}): ${text}`);
|
|
872
|
+
}
|
|
857
873
|
let link = getNextLink2(response.headers.get("Link"));
|
|
858
874
|
let partial = await response.json();
|
|
859
875
|
let result = partial;
|
|
@@ -1016,6 +1032,16 @@ function isMain(self) {
|
|
|
1016
1032
|
const result = argv1Base === selfBase;
|
|
1017
1033
|
return result;
|
|
1018
1034
|
}
|
|
1035
|
+
async function runMain(self, create) {
|
|
1036
|
+
if (!isMain(self))
|
|
1037
|
+
return;
|
|
1038
|
+
try {
|
|
1039
|
+
await create().parseAsync(Bun.argv);
|
|
1040
|
+
} catch (err) {
|
|
1041
|
+
console.error(`error: ${err instanceof Error ? err.message : String(err)}`);
|
|
1042
|
+
process.exit(1);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1019
1045
|
// lib/jira.ts
|
|
1020
1046
|
var gitEmailP3 = getConfig("user.email");
|
|
1021
1047
|
var jiraEmailP2 = getConfig("jira.user");
|
|
@@ -1052,6 +1078,10 @@ async function jiraApi(endpoint) {
|
|
|
1052
1078
|
};
|
|
1053
1079
|
const request = new Request(uri, options);
|
|
1054
1080
|
const response = await fetch(request);
|
|
1081
|
+
if (!response.ok) {
|
|
1082
|
+
const text = await response.text();
|
|
1083
|
+
throw new Error(`Jira API ${endpoint} failed (${response.status}): ${text}`);
|
|
1084
|
+
}
|
|
1055
1085
|
const result = await response.json();
|
|
1056
1086
|
return result;
|
|
1057
1087
|
}
|
|
@@ -1072,6 +1102,7 @@ async function myUnresolvedIssues() {
|
|
|
1072
1102
|
export {
|
|
1073
1103
|
whoami,
|
|
1074
1104
|
spawn,
|
|
1105
|
+
runMain,
|
|
1075
1106
|
projectScopedGetText,
|
|
1076
1107
|
projectScopedGet,
|
|
1077
1108
|
myUnresolvedIssues,
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
IMAGE_NAME="gitj"
|
|
5
|
+
WRAPPER_NAME="gitj"
|
|
6
|
+
|
|
7
|
+
# --- Find a writable bin directory on PATH under $HOME ---
|
|
8
|
+
|
|
9
|
+
find_bin_dir() {
|
|
10
|
+
# Prefer ~/.local/bin if it exists and is on PATH
|
|
11
|
+
if [ -d "$HOME/.local/bin" ]; then
|
|
12
|
+
case ":$PATH:" in
|
|
13
|
+
*":$HOME/.local/bin:"*) echo "$HOME/.local/bin"; return 0 ;;
|
|
14
|
+
esac
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Search PATH for any directory under $HOME
|
|
18
|
+
IFS=: read -ra path_dirs <<< "$PATH"
|
|
19
|
+
for dir in "${path_dirs[@]}"; do
|
|
20
|
+
case "$dir" in
|
|
21
|
+
"$HOME"/*)
|
|
22
|
+
if [ -d "$dir" ] && [ -w "$dir" ]; then
|
|
23
|
+
echo "$dir"
|
|
24
|
+
return 0
|
|
25
|
+
fi
|
|
26
|
+
;;
|
|
27
|
+
esac
|
|
28
|
+
done
|
|
29
|
+
|
|
30
|
+
# Fall back to creating ~/.local/bin
|
|
31
|
+
echo ""
|
|
32
|
+
return 1
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# --- Main ---
|
|
36
|
+
|
|
37
|
+
echo "Building Docker image '$IMAGE_NAME'..."
|
|
38
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
39
|
+
docker build -t "$IMAGE_NAME" "$SCRIPT_DIR"
|
|
40
|
+
echo ""
|
|
41
|
+
|
|
42
|
+
BIN_DIR=$(find_bin_dir) || true
|
|
43
|
+
|
|
44
|
+
if [ -z "$BIN_DIR" ]; then
|
|
45
|
+
BIN_DIR="$HOME/.local/bin"
|
|
46
|
+
echo "No bin directory found under \$HOME on your PATH."
|
|
47
|
+
echo "Creating $BIN_DIR ..."
|
|
48
|
+
mkdir -p "$BIN_DIR"
|
|
49
|
+
echo ""
|
|
50
|
+
echo "WARNING: $BIN_DIR is not on your PATH."
|
|
51
|
+
echo "Add this to your shell profile (~/.bashrc, ~/.zshrc, etc.):"
|
|
52
|
+
echo ""
|
|
53
|
+
echo " export PATH=\"\$HOME/.local/bin:\$PATH\""
|
|
54
|
+
echo ""
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
WRAPPER="$BIN_DIR/$WRAPPER_NAME"
|
|
58
|
+
|
|
59
|
+
cat > "$WRAPPER" << 'SCRIPT'
|
|
60
|
+
#!/usr/bin/env bash
|
|
61
|
+
exec docker run --rm \
|
|
62
|
+
--user "$(id -u):$(id -g)" \
|
|
63
|
+
-e HOME="$HOME" \
|
|
64
|
+
-v "$HOME:$HOME" \
|
|
65
|
+
-v "$(pwd):$(pwd)" -w "$(pwd)" \
|
|
66
|
+
gitj "$@"
|
|
67
|
+
SCRIPT
|
|
68
|
+
|
|
69
|
+
chmod +x "$WRAPPER"
|
|
70
|
+
|
|
71
|
+
echo "Installed $WRAPPER"
|
|
72
|
+
echo ""
|
|
73
|
+
echo "Usage:"
|
|
74
|
+
echo " gitj --version"
|
|
75
|
+
echo " gitj jira start BUG-42"
|
|
76
|
+
echo " gitj lab merge active"
|
|
77
|
+
echo " gitj --help-all"
|
package/lib/api.ts
CHANGED
|
@@ -82,6 +82,18 @@ export async function apiRequest(
|
|
|
82
82
|
|
|
83
83
|
const request = new Request(url, fetchOptions)
|
|
84
84
|
const response = await fetch(request)
|
|
85
|
+
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
const text = await response.text()
|
|
88
|
+
let body: JSONValue
|
|
89
|
+
try {
|
|
90
|
+
body = JSON.parse(text) as JSONValue
|
|
91
|
+
} catch {
|
|
92
|
+
throw new Error(`${serviceName} API ${method} ${endpoint} failed (${response.status}): ${text}`)
|
|
93
|
+
}
|
|
94
|
+
return { status: response.status, headers: response.headers, body }
|
|
95
|
+
}
|
|
96
|
+
|
|
85
97
|
const body = await response.json() as JSONValue
|
|
86
98
|
|
|
87
99
|
return {
|
|
@@ -138,7 +150,13 @@ export async function apiPaginate(
|
|
|
138
150
|
lastHeaders = response.headers
|
|
139
151
|
|
|
140
152
|
if (!response.ok) {
|
|
141
|
-
const
|
|
153
|
+
const text = await response.text()
|
|
154
|
+
let body: JSONValue
|
|
155
|
+
try {
|
|
156
|
+
body = JSON.parse(text) as JSONValue
|
|
157
|
+
} catch {
|
|
158
|
+
throw new Error(`${serviceName} API paginate ${endpoint} failed (${response.status}): ${text}`)
|
|
159
|
+
}
|
|
142
160
|
return { status: response.status, headers: response.headers, body }
|
|
143
161
|
}
|
|
144
162
|
|
package/lib/confluence/api.ts
CHANGED
|
@@ -30,6 +30,10 @@ export async function confluenceApi(endpoint: string): Promise<JSONValue> {
|
|
|
30
30
|
}
|
|
31
31
|
let request = new Request(uri, options)
|
|
32
32
|
const response = await fetch(request)
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
const text = await response.text()
|
|
35
|
+
throw new Error(`Confluence API ${endpoint} failed (${response.status}): ${text}`)
|
|
36
|
+
}
|
|
33
37
|
let link = getNextLink(response.headers.get('Link'))
|
|
34
38
|
const body = await response.json() as JSONValue & { results?: Array<JSONValue> }
|
|
35
39
|
if (!body.results) {
|
|
@@ -94,6 +98,10 @@ export async function confluenceSearch(cql: string): Promise<JSONValue> {
|
|
|
94
98
|
while (uri) {
|
|
95
99
|
const request = new Request(uri, options)
|
|
96
100
|
const response = await fetch(request)
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
const text = await response.text()
|
|
103
|
+
throw new Error(`Confluence search failed (${response.status}): ${text}`)
|
|
104
|
+
}
|
|
97
105
|
const body = await response.json() as JSONValue & {
|
|
98
106
|
results?: Array<JSONValue>
|
|
99
107
|
_links?: { next?: string }
|
|
@@ -127,6 +135,10 @@ export async function confluenceApiV1(endpoint: string): Promise<JSONValue> {
|
|
|
127
135
|
}
|
|
128
136
|
const request = new Request(uri, options)
|
|
129
137
|
const response = await fetch(request)
|
|
138
|
+
if (!response.ok) {
|
|
139
|
+
const text = await response.text()
|
|
140
|
+
throw new Error(`Confluence API v1 ${endpoint} failed (${response.status}): ${text}`)
|
|
141
|
+
}
|
|
130
142
|
const result = await response.json()
|
|
131
143
|
return result
|
|
132
144
|
}
|
package/lib/confluence/config.ts
CHANGED
|
@@ -15,11 +15,11 @@ const confluenceTokenP = getConfig('confluence.token', { expectQuiet: true })
|
|
|
15
15
|
|
|
16
16
|
export async function getConfluenceConfig(): Promise<ConfluenceConfig> {
|
|
17
17
|
const host = await confluenceHostP || await jiraHostP
|
|
18
|
-
if (!host) throw new Error('confluence.host or jira.host not in git config')
|
|
18
|
+
if (!host) throw new Error('confluence.host or jira.host not in git config (see: gitj confluence --help)')
|
|
19
19
|
const user = await confluenceEmailP || await jiraEmailP || await gitEmailP
|
|
20
|
-
if (!user) throw new Error('confluence.user, jira.user, or user.email not in git config')
|
|
20
|
+
if (!user) throw new Error('confluence.user, jira.user, or user.email not in git config (see: gitj confluence --help)')
|
|
21
21
|
const pat = await confluenceTokenP || await jiraTokenP
|
|
22
|
-
if (!pat) throw new Error('confluence.token or jira.token not in git config')
|
|
22
|
+
if (!pat) throw new Error('confluence.token or jira.token not in git config (see: gitj confluence --help)')
|
|
23
23
|
const token = Buffer.from(`${user}:${pat}`).toString('base64')
|
|
24
24
|
return { host, token }
|
|
25
25
|
}
|
package/lib/gitlab/api.ts
CHANGED
|
@@ -31,6 +31,10 @@ export async function gitlabApi(endpoint: string): Promise<JSONValue> {
|
|
|
31
31
|
}
|
|
32
32
|
let request = new Request(uri, options)
|
|
33
33
|
const response = await fetch(request)
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
const text = await response.text()
|
|
36
|
+
throw new Error(`GitLab API ${endpoint} failed (${response.status}): ${text}`)
|
|
37
|
+
}
|
|
34
38
|
let link = getNextLink(response.headers.get('Link'))
|
|
35
39
|
let partial = (await response.json()) as Array<JSONValue>
|
|
36
40
|
let result: Array<JSONValue> = partial
|
package/lib/gitlab/config.ts
CHANGED
|
@@ -14,8 +14,8 @@ const tokenP = getConfig("gitlab.token")
|
|
|
14
14
|
export async function getGitlabConfig(): Promise<GitlabConfig> {
|
|
15
15
|
const host = await hostP || 'gitlab.com'
|
|
16
16
|
const user = await gitEmailP || await gitlabEmailP
|
|
17
|
-
if (!user) throw new Error("Neither user.email nor gitlab.
|
|
17
|
+
if (!user) throw new Error("Neither user.email nor gitlab.user in git config (see: gitj lab --help)")
|
|
18
18
|
const token = await tokenP
|
|
19
|
-
if (!token) throw new Error("gitlab.token not in git config")
|
|
19
|
+
if (!token) throw new Error("gitlab.token not in git config (see: gitj lab --help)")
|
|
20
20
|
return { host, user, token }
|
|
21
21
|
}
|
package/lib/is_main.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
+
import type { Command } from 'commander'
|
|
2
3
|
|
|
3
4
|
function justBase(filename: string): string {
|
|
4
5
|
const ext = path.extname(filename)
|
|
@@ -22,3 +23,13 @@ export function isMain(self: string): boolean {
|
|
|
22
23
|
// }
|
|
23
24
|
return result
|
|
24
25
|
}
|
|
26
|
+
|
|
27
|
+
export async function runMain(self: string, create: () => Command): Promise<void> {
|
|
28
|
+
if (!isMain(self)) return
|
|
29
|
+
try {
|
|
30
|
+
await create().parseAsync(Bun.argv)
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.error(`error: ${err instanceof Error ? err.message : String(err)}`)
|
|
33
|
+
process.exit(1)
|
|
34
|
+
}
|
|
35
|
+
}
|
package/lib/jira.ts
CHANGED
|
@@ -21,11 +21,11 @@ const tokenP = getConfig("jira.token")
|
|
|
21
21
|
|
|
22
22
|
export async function getJiraConfig(): Promise<JiraConfig> {
|
|
23
23
|
const host = await hostP
|
|
24
|
-
if (!host) throw new Error("jira.host not in git config")
|
|
24
|
+
if (!host) throw new Error("jira.host not in git config (see: gitj jira --help)")
|
|
25
25
|
const user = await jiraEmailP || await gitEmailP
|
|
26
|
-
if (!user) throw new Error("jira.user or user.email not in git config")
|
|
26
|
+
if (!user) throw new Error("jira.user or user.email not in git config (see: gitj jira --help)")
|
|
27
27
|
const pat = await tokenP
|
|
28
|
-
if (!pat) throw new Error("jira.token not in git config")
|
|
28
|
+
if (!pat) throw new Error("jira.token not in git config (see: gitj jira --help)")
|
|
29
29
|
const token = Buffer.from(`${user}:${pat}`).toString('base64')
|
|
30
30
|
return { host, token }
|
|
31
31
|
}
|
|
@@ -48,6 +48,10 @@ export async function jiraApi(endpoint: string): Promise<JSONValue> {
|
|
|
48
48
|
}
|
|
49
49
|
const request = new Request(uri, options)
|
|
50
50
|
const response = await fetch(request)
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
const text = await response.text()
|
|
53
|
+
throw new Error(`Jira API ${endpoint} failed (${response.status}): ${text}`)
|
|
54
|
+
}
|
|
51
55
|
const result = await response.json()
|
|
52
56
|
return result;
|
|
53
57
|
}
|