@waron97/prbot 2.1.0 → 2.3.0
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/.claude/settings.local.json +9 -3
- package/.prettierrc.mjs +11 -0
- package/README.md +30 -30
- package/eslint.config.mjs +16 -0
- package/index.js +327 -344
- package/package.json +33 -32
- package/src/commands/autopr.js +238 -263
- package/src/commands/changelog.js +154 -150
- package/src/commands/commit.js +146 -0
- package/src/commands/export.js +7 -0
- package/src/commands/exportPb.js +156 -0
- package/src/commands/init.js +144 -136
- package/src/commands/pr.js +81 -107
- package/src/commands/ver.js +54 -64
- package/src/config.js +4 -4
- package/src/index.js +112 -78
- package/src/lib/addons.js +4 -4
- package/src/lib/auth.js +25 -0
- package/src/lib/git.js +6 -6
package/src/index.js
CHANGED
|
@@ -1,106 +1,140 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { readdirSync, readFileSync } from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { program } from 'commander';
|
|
5
|
+
import { configDotenv } from 'dotenv';
|
|
6
|
+
import omelette from 'omelette';
|
|
7
|
+
import { autopr } from './commands/autopr.js';
|
|
8
|
+
import { changelog } from './commands/changelog.js';
|
|
9
|
+
import { commit } from './commands/commit.js';
|
|
10
|
+
import { exportPb, exportRip } from './commands/export.js';
|
|
11
|
+
import { init } from './commands/init.js';
|
|
12
|
+
import { main as prMain } from './commands/pr.js';
|
|
13
|
+
import { verbot } from './commands/ver.js';
|
|
14
|
+
import { CONFIG_FILE } from './config.js';
|
|
2
15
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { program } from "commander";
|
|
7
|
-
import omelette from "omelette";
|
|
8
|
-
import { CONFIG_FILE, COMPLETION_SCRIPT } from "./config.js";
|
|
9
|
-
import { main as prMain } from "./commands/pr.js";
|
|
10
|
-
import { verbot } from "./commands/ver.js";
|
|
11
|
-
import { init } from "./commands/init.js";
|
|
12
|
-
import { changelog } from "./commands/changelog.js";
|
|
13
|
-
import { autopr } from "./commands/autopr.js";
|
|
14
|
-
|
|
15
|
-
const completion = omelette("prbot <command> <module>");
|
|
16
|
-
completion.on("command", ({ reply }) => {
|
|
17
|
-
reply(["pr", "ver", "init", "changelog", "autopr"]);
|
|
16
|
+
const completion = omelette('prbot <command> <module>');
|
|
17
|
+
completion.on('command', ({ reply }) => {
|
|
18
|
+
reply(['pr', 'ver', 'init', 'changelog', 'autopr', 'commit']);
|
|
18
19
|
});
|
|
19
20
|
|
|
20
|
-
completion.on(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
completion.on('module', ({ before, reply }) => {
|
|
22
|
+
if (['init', 'changelog', 'autopr'].includes(before)) {
|
|
23
|
+
reply([]);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const raw = readFileSync(CONFIG_FILE, 'utf-8');
|
|
28
|
+
const match = raw.match(/^ADDONS_PATH=(.+)$/m);
|
|
29
|
+
if (!match) {
|
|
30
|
+
reply([]);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const addonsPath = match[1].trim().replace(/^~/, process.env.HOME || '');
|
|
34
|
+
reply(readdirSync(path.join(addonsPath, 'config')));
|
|
35
|
+
} catch {
|
|
36
|
+
reply([]);
|
|
31
37
|
}
|
|
32
|
-
const addonsPath = match[1].trim().replace(/^~/, process.env.HOME || "");
|
|
33
|
-
reply(readdirSync(path.join(addonsPath, "config")));
|
|
34
|
-
} catch {
|
|
35
|
-
reply([]);
|
|
36
|
-
}
|
|
37
38
|
});
|
|
38
39
|
|
|
39
40
|
completion.init();
|
|
40
41
|
|
|
41
|
-
const isCompletionMode =
|
|
42
|
-
process.argv.includes("--compbash") || process.argv.includes("--compzsh");
|
|
42
|
+
const isCompletionMode = process.argv.includes('--compbash') || process.argv.includes('--compzsh');
|
|
43
43
|
|
|
44
44
|
if (!isCompletionMode) {
|
|
45
|
-
|
|
45
|
+
configDotenv({ path: CONFIG_FILE });
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
program
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
49
|
+
.command('pr <module>')
|
|
50
|
+
.option('-b, --bump <level>')
|
|
51
|
+
.action((module, opts) => {
|
|
52
|
+
prMain(module)
|
|
53
|
+
.then(() => {
|
|
54
|
+
if (opts.bump) {
|
|
55
|
+
return verbot(module, opts.bump);
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
.catch((err) => {
|
|
59
|
+
throw err;
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
62
|
|
|
63
63
|
program
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
64
|
+
.command('ver <module>')
|
|
65
|
+
.option('-b, --bump <level>')
|
|
66
|
+
.action((module, opts) => {
|
|
67
|
+
if (!opts.bump) {
|
|
68
|
+
throw new Error('No bump level specified');
|
|
69
|
+
}
|
|
70
|
+
verbot(module, opts.bump);
|
|
71
|
+
});
|
|
72
72
|
|
|
73
73
|
program
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
.command('init')
|
|
75
|
+
.description('Create config file and install shell completion')
|
|
76
|
+
.action(() => {
|
|
77
|
+
init(completion);
|
|
78
|
+
});
|
|
79
79
|
|
|
80
80
|
const collect = (val, prev) => [...(prev ?? []), val];
|
|
81
81
|
|
|
82
82
|
program
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
83
|
+
.command('changelog <pr>')
|
|
84
|
+
.option('-t, --trident <code>', 'Trident issue codes (repeatable)', collect)
|
|
85
|
+
.option('-j, --jira <code>', 'JIRA issue codes (repeatable)', collect)
|
|
86
|
+
.option('-m, --message <text>', 'Changelog entry message')
|
|
87
|
+
.action((prNumber, opts) => {
|
|
88
|
+
changelog(prNumber, opts).catch((err) => {
|
|
89
|
+
throw err;
|
|
90
|
+
});
|
|
90
91
|
});
|
|
91
|
-
});
|
|
92
92
|
|
|
93
93
|
program
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
94
|
+
.command('autopr')
|
|
95
|
+
.option('-t, --trident <id>', 'Trident task IDs (repeatable)', collect)
|
|
96
|
+
.option('-j, --jira <code>', 'JIRA issue codes (repeatable)', collect)
|
|
97
|
+
.option('-m, --message <text>', 'Changelog entry message')
|
|
98
|
+
.option('-b, --branch <name>', 'Branch name (default: autopr_<taskId>)')
|
|
99
|
+
.option('-n, --name <text>', 'PR title (default: task name from Odoo)')
|
|
100
|
+
.action((opts) => {
|
|
101
|
+
autopr(opts).catch((err) => {
|
|
102
|
+
throw err;
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
program.command('commit').action((opts) => {
|
|
107
|
+
commit(opts).catch((err) => {
|
|
108
|
+
throw err;
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const exportCmd = program.command('export');
|
|
113
|
+
|
|
114
|
+
exportCmd
|
|
115
|
+
.command('workflow <module>')
|
|
116
|
+
.option('-b, --bump <level>')
|
|
117
|
+
.action((module, opts) => {
|
|
118
|
+
prMain(module)
|
|
119
|
+
.then(() => {
|
|
120
|
+
if (opts.bump) {
|
|
121
|
+
return verbot(module, opts.bump);
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
.catch((err) => {
|
|
125
|
+
throw err;
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
exportCmd.command('rip').action(() => exportRip());
|
|
130
|
+
|
|
131
|
+
exportCmd
|
|
132
|
+
.command('pb')
|
|
133
|
+
.option('--no-commit')
|
|
134
|
+
.action((opts) => {
|
|
135
|
+
exportPb(opts).catch((err) => {
|
|
136
|
+
throw err;
|
|
137
|
+
});
|
|
103
138
|
});
|
|
104
|
-
});
|
|
105
139
|
|
|
106
140
|
program.parse();
|
package/src/lib/addons.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
function resolveAddonsPath(addonsPath) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
if (addonsPath.startsWith('~')) {
|
|
3
|
+
return addonsPath.replace('~', process.env.HOME);
|
|
4
|
+
}
|
|
5
|
+
return addonsPath;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export { resolveAddonsPath };
|
package/src/lib/auth.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import fetch from 'node-fetch';
|
|
2
|
+
|
|
3
|
+
async function getToken() {
|
|
4
|
+
const url = process.env.KC_URL;
|
|
5
|
+
const payload = new URLSearchParams();
|
|
6
|
+
|
|
7
|
+
payload.append('username', process.env.KC_USER);
|
|
8
|
+
payload.append('password', process.env.KC_PASSWORD);
|
|
9
|
+
payload.append('client_id', process.env.KC_ID);
|
|
10
|
+
payload.append('client_secret', process.env.KC_SECRET);
|
|
11
|
+
payload.append('grant_type', 'password');
|
|
12
|
+
|
|
13
|
+
const response = await fetch(url, {
|
|
14
|
+
method: 'POST',
|
|
15
|
+
headers: {
|
|
16
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
17
|
+
},
|
|
18
|
+
body: payload.toString(),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const json = await response.json();
|
|
22
|
+
return json.access_token;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { getToken };
|
package/src/lib/git.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { execFile } from
|
|
1
|
+
import { execFile } from 'child_process';
|
|
2
2
|
|
|
3
3
|
function execGit(args, cwd) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
execFile('git', args, { cwd }, (error, stdout) => {
|
|
6
|
+
if (error) reject(error);
|
|
7
|
+
else resolve(stdout);
|
|
8
|
+
});
|
|
8
9
|
});
|
|
9
|
-
});
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export { execGit };
|