git-stack-cli 0.8.6 → 1.0.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/README.md +32 -3
- package/dist/cjs/index.cjs +34770 -0
- package/package.json +23 -9
- package/dist/__fixtures__/metadata.js +0 -666
- package/dist/__fixtures__/metadata.json +0 -186
- package/dist/app/App copy.js +0 -30
- package/dist/app/App.js +0 -42
- package/dist/app/ArgCheck.js +0 -21
- package/dist/app/AutoUpdate.js +0 -128
- package/dist/app/Await.js +0 -45
- package/dist/app/Brackets copy.js +0 -10
- package/dist/app/Brackets.js +0 -11
- package/dist/app/Command.js +0 -7
- package/dist/app/Counter.js +0 -19
- package/dist/app/Debug.js +0 -33
- package/dist/app/DependencyCheck.js +0 -89
- package/dist/app/Exit.js +0 -14
- package/dist/app/FormatText.js +0 -9
- package/dist/app/GatherMetadata copy.js +0 -91
- package/dist/app/GatherMetadata.js +0 -100
- package/dist/app/GithubApiError.js +0 -50
- package/dist/app/InitMetadata.js +0 -14
- package/dist/app/Input.js +0 -15
- package/dist/app/KeepAlive.js +0 -11
- package/dist/app/LocalCommitStatus.js +0 -43
- package/dist/app/LocalMergeRebase.js +0 -157
- package/dist/app/Main copy.js +0 -200
- package/dist/app/ManualRebase copy.js +0 -127
- package/dist/app/ManualRebase.js +0 -220
- package/dist/app/MultiSelect copy.js +0 -76
- package/dist/app/MultiSelect.js +0 -143
- package/dist/app/NPMAutoUpdate.js +0 -34
- package/dist/app/Output.js +0 -19
- package/dist/app/Parens copy.js +0 -9
- package/dist/app/Parens.js +0 -10
- package/dist/app/PostRebaseStatus copy.js +0 -23
- package/dist/app/PostRebaseStatus.js +0 -23
- package/dist/app/PreLocalMergeRebase.js +0 -21
- package/dist/app/PreSelectCommitRanges copy.js +0 -21
- package/dist/app/PreSelectCommitRanges.js +0 -21
- package/dist/app/Providers.js +0 -5
- package/dist/app/RebaseCheck.js +0 -56
- package/dist/app/SelectCommitRange.js +0 -1
- package/dist/app/SelectCommitRanges.js +0 -207
- package/dist/app/Status copy.js +0 -46
- package/dist/app/Status.js +0 -61
- package/dist/app/StatusTable.js +0 -115
- package/dist/app/Store.js +0 -136
- package/dist/app/Table.js +0 -65
- package/dist/app/TextInput.js +0 -51
- package/dist/app/Url copy.js +0 -6
- package/dist/app/Url.js +0 -6
- package/dist/app/Waterfall.js +0 -20
- package/dist/app/YesNoPrompt copy.js +0 -24
- package/dist/app/YesNoPrompt.js +0 -40
- package/dist/app/main.js +0 -39
- package/dist/cli.js +0 -9
- package/dist/command.js +0 -60
- package/dist/core/CommitMetadata.js +0 -159
- package/dist/core/Metadata copy.js +0 -37
- package/dist/core/Metadata.js +0 -36
- package/dist/core/StackSummaryTable.js +0 -87
- package/dist/core/StackSummaryTable.test.js +0 -98
- package/dist/core/StackTable.js +0 -38
- package/dist/core/SummaryTable.js +0 -38
- package/dist/core/ZustandStore.js +0 -23
- package/dist/core/assertNever.js +0 -4
- package/dist/core/cache.js +0 -39
- package/dist/core/capitalize.js +0 -5
- package/dist/core/chalk.js +0 -83
- package/dist/core/clamp.js +0 -6
- package/dist/core/cli copy.js +0 -44
- package/dist/core/cli.js +0 -86
- package/dist/core/color.js +0 -83
- package/dist/core/colors.js +0 -15
- package/dist/core/date.js +0 -18
- package/dist/core/dependency_check.js +0 -27
- package/dist/core/env.js +0 -4
- package/dist/core/exit.js +0 -4
- package/dist/core/fetch_json.js +0 -24
- package/dist/core/get_commit_metadata.js +0 -61
- package/dist/core/github.js +0 -118
- package/dist/core/id.js +0 -61
- package/dist/core/invariant copy.js +0 -5
- package/dist/core/invariant.js +0 -5
- package/dist/core/isFiniteValue.js +0 -3
- package/dist/core/is_command_available.js +0 -15
- package/dist/core/is_dev.js +0 -1
- package/dist/core/is_finite_value.js +0 -3
- package/dist/core/json.js +0 -35
- package/dist/core/match_group.js +0 -9
- package/dist/core/readJson.js +0 -3
- package/dist/core/read_json.js +0 -12
- package/dist/core/safe_quote.js +0 -9
- package/dist/core/semver_compare.js +0 -26
- package/dist/core/serialize_json.js +0 -17
- package/dist/core/short_id.js +0 -60
- package/dist/core/sleep copy.js +0 -3
- package/dist/core/sleep.js +0 -3
- package/dist/core/wrap_index.js +0 -10
- package/dist/index.js +0 -13
- package/dist/main copy.js +0 -266
- package/dist/main.backup.js +0 -266
- package/dist/main.js +0 -265
package/dist/core/cli copy.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import * as child from "node:child_process";
|
|
2
|
-
export async function cli(command, unsafe_options) {
|
|
3
|
-
const options = Object.assign({}, unsafe_options);
|
|
4
|
-
return new Promise((resolve, reject) => {
|
|
5
|
-
const childProcess = child.spawn("sh", ["-c", command], options);
|
|
6
|
-
let stdout = "";
|
|
7
|
-
let stderr = "";
|
|
8
|
-
let output = "";
|
|
9
|
-
childProcess.stdout?.on("data", (data) => {
|
|
10
|
-
stdout += data.toString();
|
|
11
|
-
output += data.toString();
|
|
12
|
-
});
|
|
13
|
-
childProcess.stderr?.on("data", (data) => {
|
|
14
|
-
stderr += data.toString();
|
|
15
|
-
output += data.toString();
|
|
16
|
-
});
|
|
17
|
-
childProcess.on("close", (code) => {
|
|
18
|
-
if (!options.ignoreExitCode && code !== 0) {
|
|
19
|
-
reject(new Error(`[${command}] (${code})`));
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
const result = {
|
|
23
|
-
code: code || 0,
|
|
24
|
-
stdout: stdout.trimEnd(),
|
|
25
|
-
stderr: stderr.trimEnd(),
|
|
26
|
-
output: output.trimEnd(),
|
|
27
|
-
};
|
|
28
|
-
resolve(result);
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
childProcess.on("error", (err) => {
|
|
32
|
-
reject(err);
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
cli.sync = function cli_sync(command, unsafe_options) {
|
|
37
|
-
const options = Object.assign({}, unsafe_options);
|
|
38
|
-
const spawn_return = child.spawnSync("sh", ["-c", command], options);
|
|
39
|
-
const stdout = String(spawn_return.stdout);
|
|
40
|
-
const stderr = String(spawn_return.stderr);
|
|
41
|
-
const output = String(spawn_return.output);
|
|
42
|
-
const code = spawn_return.status || 0;
|
|
43
|
-
return { code, stdout, stderr, output };
|
|
44
|
-
};
|
package/dist/core/cli.js
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import * as child from "node:child_process";
|
|
2
|
-
import { Store } from "../app/Store.js";
|
|
3
|
-
let i = 0;
|
|
4
|
-
export async function cli(unsafe_command, unsafe_options) {
|
|
5
|
-
const options = Object.assign({}, unsafe_options);
|
|
6
|
-
const state = Store.getState();
|
|
7
|
-
let command;
|
|
8
|
-
if (Array.isArray(unsafe_command)) {
|
|
9
|
-
command = unsafe_command.join(" ");
|
|
10
|
-
}
|
|
11
|
-
else {
|
|
12
|
-
command = unsafe_command;
|
|
13
|
-
}
|
|
14
|
-
return new Promise((resolve, reject) => {
|
|
15
|
-
const childProcess = child.spawn("sh", ["-c", command], options);
|
|
16
|
-
let stdout = "";
|
|
17
|
-
let stderr = "";
|
|
18
|
-
let output = "";
|
|
19
|
-
const id = `${++i}-${command}`;
|
|
20
|
-
state.actions.debug(`[start] ${command}`);
|
|
21
|
-
state.actions.debug(`[⏳] ${command}\n`, id);
|
|
22
|
-
function write_output(value) {
|
|
23
|
-
output += value;
|
|
24
|
-
state.actions.debug(value, id);
|
|
25
|
-
}
|
|
26
|
-
childProcess.stdout?.on("data", (data) => {
|
|
27
|
-
const value = String(data);
|
|
28
|
-
stdout += value;
|
|
29
|
-
write_output(value);
|
|
30
|
-
});
|
|
31
|
-
childProcess.stderr?.on("data", (data) => {
|
|
32
|
-
const value = String(data);
|
|
33
|
-
stderr += value;
|
|
34
|
-
write_output(value);
|
|
35
|
-
});
|
|
36
|
-
childProcess.on("close", (unsafe_code) => {
|
|
37
|
-
const result = {
|
|
38
|
-
command,
|
|
39
|
-
code: unsafe_code || 0,
|
|
40
|
-
stdout: stdout.trimEnd(),
|
|
41
|
-
stderr: stderr.trimEnd(),
|
|
42
|
-
output: output.trimEnd(),
|
|
43
|
-
};
|
|
44
|
-
state.actions.set((state) => state.mutate.end_pending_output(state, id));
|
|
45
|
-
state.actions.debug(`[end] ${command} (${result.code})`);
|
|
46
|
-
state.actions.debug(result.output);
|
|
47
|
-
if (!options.ignoreExitCode && result.code !== 0) {
|
|
48
|
-
reject(new Error(`[${command}] (${result.code})`));
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
resolve(result);
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
childProcess.on("error", (err) => {
|
|
55
|
-
reject(err);
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
cli.sync = function cli_sync(unsafe_command, unsafe_options) {
|
|
60
|
-
const options = Object.assign({}, unsafe_options);
|
|
61
|
-
const state = Store.getState();
|
|
62
|
-
let command;
|
|
63
|
-
if (Array.isArray(unsafe_command)) {
|
|
64
|
-
command = unsafe_command.join(" ");
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
command = unsafe_command;
|
|
68
|
-
}
|
|
69
|
-
state.actions.debug(`[start] ${command}`);
|
|
70
|
-
const spawn_return = child.spawnSync("sh", ["-c", command], options);
|
|
71
|
-
const stdout = String(spawn_return.stdout);
|
|
72
|
-
const stderr = String(spawn_return.stderr);
|
|
73
|
-
const result = {
|
|
74
|
-
command,
|
|
75
|
-
code: spawn_return.status || 0,
|
|
76
|
-
stdout,
|
|
77
|
-
stderr,
|
|
78
|
-
output: [stdout, stderr].join(""),
|
|
79
|
-
};
|
|
80
|
-
state.actions.debug(`[end] ${command} (${result.code})`);
|
|
81
|
-
state.actions.debug(result.output);
|
|
82
|
-
if (!options.ignoreExitCode && result.code !== 0) {
|
|
83
|
-
throw new Error(`[${command}] (${result.code})`);
|
|
84
|
-
}
|
|
85
|
-
return result;
|
|
86
|
-
};
|
package/dist/core/color.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
function create_color_proxy(base) {
|
|
3
|
-
return new Proxy(base, {
|
|
4
|
-
get(target, prop) {
|
|
5
|
-
switch (prop) {
|
|
6
|
-
case "test":
|
|
7
|
-
return test;
|
|
8
|
-
case "bracket":
|
|
9
|
-
return (str) => [
|
|
10
|
-
target.bold.whiteBright("["),
|
|
11
|
-
str,
|
|
12
|
-
target.bold.whiteBright("]"),
|
|
13
|
-
].join("");
|
|
14
|
-
case "url":
|
|
15
|
-
return target.bold.underline.blueBright;
|
|
16
|
-
case "cmd":
|
|
17
|
-
return target.bold.yellow;
|
|
18
|
-
case "branch":
|
|
19
|
-
return target.bold.green;
|
|
20
|
-
}
|
|
21
|
-
const target_prop = target[prop];
|
|
22
|
-
return target_prop;
|
|
23
|
-
},
|
|
24
|
-
apply(target, _this_arg, arguments_list) {
|
|
25
|
-
return target(...arguments_list);
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
export const color = create_color_proxy(chalk);
|
|
30
|
-
function test() {
|
|
31
|
-
const PROP_LIST = [
|
|
32
|
-
"reset",
|
|
33
|
-
"bold",
|
|
34
|
-
"dim",
|
|
35
|
-
"italic",
|
|
36
|
-
"underline",
|
|
37
|
-
"overline",
|
|
38
|
-
"inverse",
|
|
39
|
-
"hidden",
|
|
40
|
-
"strikethrough",
|
|
41
|
-
"visible",
|
|
42
|
-
"black",
|
|
43
|
-
"red",
|
|
44
|
-
"green",
|
|
45
|
-
"yellow",
|
|
46
|
-
"blue",
|
|
47
|
-
"magenta",
|
|
48
|
-
"cyan",
|
|
49
|
-
"white",
|
|
50
|
-
"blackBright",
|
|
51
|
-
"gray",
|
|
52
|
-
"grey",
|
|
53
|
-
"redBright",
|
|
54
|
-
"greenBright",
|
|
55
|
-
"yellowBright",
|
|
56
|
-
"blueBright",
|
|
57
|
-
"magentaBright",
|
|
58
|
-
"cyanBright",
|
|
59
|
-
"whiteBright",
|
|
60
|
-
"bgBlack",
|
|
61
|
-
"bgRed",
|
|
62
|
-
"bgGreen",
|
|
63
|
-
"bgYellow",
|
|
64
|
-
"bgBlue",
|
|
65
|
-
"bgMagenta",
|
|
66
|
-
"bgCyan",
|
|
67
|
-
"bgWhite",
|
|
68
|
-
"bgBlackBright",
|
|
69
|
-
"bgGray",
|
|
70
|
-
"bgGrey",
|
|
71
|
-
"bgRedBright",
|
|
72
|
-
"bgGreenBright",
|
|
73
|
-
"bgYellowBright",
|
|
74
|
-
"bgBlueBright",
|
|
75
|
-
"bgMagentaBright",
|
|
76
|
-
"bgCyanBright",
|
|
77
|
-
"bgWhiteBright",
|
|
78
|
-
];
|
|
79
|
-
for (const prop of PROP_LIST) {
|
|
80
|
-
// eslint-disable-next-line no-console
|
|
81
|
-
console.debug(chalk[prop](prop));
|
|
82
|
-
}
|
|
83
|
-
}
|
package/dist/core/colors.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// ink uses chalk internally
|
|
2
|
-
// https://github.com/vadimdemedes/ink#color
|
|
3
|
-
export const colors = {
|
|
4
|
-
red: "rgb(248, 81, 73)",
|
|
5
|
-
// red-emphasis rgb(218, 54, 51)
|
|
6
|
-
green: "rgb(63, 185, 80)",
|
|
7
|
-
// green-emphasis rgb(35, 134, 54)
|
|
8
|
-
purple: "rgb(163, 113, 247)",
|
|
9
|
-
// purple-emphasis rgb(137, 87, 229)
|
|
10
|
-
blue: "rgb(47, 129, 247)",
|
|
11
|
-
orange: "rgb(255, 166, 87)",
|
|
12
|
-
yellow: "rgb(234, 179, 8)",
|
|
13
|
-
gray: "rgb(110, 118, 129)",
|
|
14
|
-
lightGray: "rgb(125, 133, 144)",
|
|
15
|
-
};
|
package/dist/core/date.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export function format(date) {
|
|
2
|
-
const year = intl_format(date, { year: "numeric" });
|
|
3
|
-
const month = intl_format(date, { month: "2-digit" });
|
|
4
|
-
const day = intl_format(date, { day: "2-digit" });
|
|
5
|
-
const time = format_time(date);
|
|
6
|
-
return `${year}-${month}-${day} ${time}`;
|
|
7
|
-
}
|
|
8
|
-
export function intl_format(date, options) {
|
|
9
|
-
return new Intl.DateTimeFormat("en-US", options).format(date);
|
|
10
|
-
}
|
|
11
|
-
export function format_time(date) {
|
|
12
|
-
const time = intl_format(date, {
|
|
13
|
-
hour: "numeric",
|
|
14
|
-
minute: "2-digit",
|
|
15
|
-
hour12: true,
|
|
16
|
-
});
|
|
17
|
-
return time;
|
|
18
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { cli } from "./cli.js";
|
|
2
|
-
import { color } from "./color.js";
|
|
3
|
-
import { is_command_available } from "./is_command_available.js";
|
|
4
|
-
export async function dependency_check() {
|
|
5
|
-
if (!is_command_available("git")) {
|
|
6
|
-
console.error(`${color.cmd("git")} must be installed.`);
|
|
7
|
-
process.exitCode = 2;
|
|
8
|
-
return false;
|
|
9
|
-
}
|
|
10
|
-
if (!is_command_available("gh")) {
|
|
11
|
-
console.error(`${color.cmd("gh")} must be installed.`);
|
|
12
|
-
// prettier-ignore
|
|
13
|
-
console.error(`Visit ${color.url("https://cli.github.com/")} to install the github cli (${color.cmd("gh")})`);
|
|
14
|
-
process.exitCode = 3;
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
const gh_auth_status_cli = await cli(`gh auth status`, {
|
|
18
|
-
ignoreExitCode: true,
|
|
19
|
-
});
|
|
20
|
-
if (gh_auth_status_cli.code !== 0) {
|
|
21
|
-
// prettier-ignore
|
|
22
|
-
console.error(`${color.cmd('gh')} requires login, please run \`${color.cmd('gh auth login')}\`.`);
|
|
23
|
-
process.exitCode = 4;
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
return true;
|
|
27
|
-
}
|
package/dist/core/env.js
DELETED
package/dist/core/exit.js
DELETED
package/dist/core/fetch_json.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import https from "node:https";
|
|
2
|
-
export async function fetch_json(url) {
|
|
3
|
-
return new Promise((resolve, reject) => {
|
|
4
|
-
https
|
|
5
|
-
.get(url, (res) => {
|
|
6
|
-
let data = "";
|
|
7
|
-
res.on("data", (chunk) => {
|
|
8
|
-
data += chunk;
|
|
9
|
-
});
|
|
10
|
-
res.on("end", () => {
|
|
11
|
-
try {
|
|
12
|
-
const json = JSON.parse(data);
|
|
13
|
-
resolve(json);
|
|
14
|
-
}
|
|
15
|
-
catch (error) {
|
|
16
|
-
reject(error);
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
})
|
|
20
|
-
.on("error", (error) => {
|
|
21
|
-
reject(error);
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import * as github from "../core/github.js";
|
|
2
|
-
import * as Metadata from "./Metadata.js";
|
|
3
|
-
import { cli } from "./cli.js";
|
|
4
|
-
async function all() {
|
|
5
|
-
const log_result = await cli(`git log master..HEAD --oneline --format=%H --color=never`);
|
|
6
|
-
const sha_list = lines(log_result.stdout).reverse();
|
|
7
|
-
const commit_metadata_list = [];
|
|
8
|
-
for (let i = 0; i < sha_list.length; i++) {
|
|
9
|
-
const sha = sha_list[i];
|
|
10
|
-
let base;
|
|
11
|
-
if (i === 0) {
|
|
12
|
-
base = "master";
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
base = commit_metadata_list[i - 1].metadata.id;
|
|
16
|
-
}
|
|
17
|
-
const commit_metadata = await commit(sha, base);
|
|
18
|
-
commit_metadata_list.push(commit_metadata);
|
|
19
|
-
}
|
|
20
|
-
return commit_metadata_list;
|
|
21
|
-
}
|
|
22
|
-
export async function commit(sha, base) {
|
|
23
|
-
const raw_message = (await cli(`git show -s --format=%B ${sha}`)).stdout;
|
|
24
|
-
const metadata = await Metadata.read(raw_message);
|
|
25
|
-
const message = display_message(raw_message);
|
|
26
|
-
let pr = null;
|
|
27
|
-
let pr_exists = false;
|
|
28
|
-
let pr_dirty = false;
|
|
29
|
-
if (metadata.id) {
|
|
30
|
-
const pr_branch = metadata.id;
|
|
31
|
-
pr = await github.pr_status(pr_branch);
|
|
32
|
-
if (pr && pr.state === "OPEN") {
|
|
33
|
-
pr_exists = true;
|
|
34
|
-
const last_commit = pr.commits[pr.commits.length - 1];
|
|
35
|
-
pr_dirty = last_commit.oid !== sha;
|
|
36
|
-
if (pr.baseRefName !== base) {
|
|
37
|
-
// requires base update
|
|
38
|
-
pr_dirty = true;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return {
|
|
43
|
-
sha,
|
|
44
|
-
base,
|
|
45
|
-
message,
|
|
46
|
-
pr,
|
|
47
|
-
pr_exists,
|
|
48
|
-
pr_dirty,
|
|
49
|
-
metadata,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
function display_message(message) {
|
|
53
|
-
// remove metadata
|
|
54
|
-
let result = message;
|
|
55
|
-
result = result.replace(Metadata.id_regex(), "");
|
|
56
|
-
result = result.trimEnd();
|
|
57
|
-
return result;
|
|
58
|
-
}
|
|
59
|
-
function lines(value) {
|
|
60
|
-
return value.split("\n");
|
|
61
|
-
}
|
package/dist/core/github.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import * as Ink from "ink";
|
|
6
|
-
import { Brackets } from "../app/Brackets.js";
|
|
7
|
-
import { Store } from "../app/Store.js";
|
|
8
|
-
import { colors } from "../core/colors.js";
|
|
9
|
-
import { cli } from "./cli.js";
|
|
10
|
-
import { invariant } from "./invariant.js";
|
|
11
|
-
import { safe_quote } from "./safe_quote.js";
|
|
12
|
-
// prettier-ignore
|
|
13
|
-
const JSON_FIELDS = "--json number,state,baseRefName,headRefName,commits,title,body,url";
|
|
14
|
-
export async function pr_list() {
|
|
15
|
-
const state = Store.getState();
|
|
16
|
-
const actions = state.actions;
|
|
17
|
-
const username = state.username;
|
|
18
|
-
const repo_path = state.repo_path;
|
|
19
|
-
invariant(username, "username must exist");
|
|
20
|
-
invariant(repo_path, "repo_path must exist");
|
|
21
|
-
const cli_result = await cli(`gh pr list --repo ${repo_path} --author ${username} --state open ${JSON_FIELDS}`, {
|
|
22
|
-
ignoreExitCode: true,
|
|
23
|
-
});
|
|
24
|
-
if (cli_result.code !== 0) {
|
|
25
|
-
handle_error(cli_result.output);
|
|
26
|
-
}
|
|
27
|
-
const result_pr_list = JSON.parse(cli_result.stdout);
|
|
28
|
-
if (actions.isDebug()) {
|
|
29
|
-
actions.output(React.createElement(Ink.Text, { dimColor: true },
|
|
30
|
-
React.createElement(Ink.Text, null, "Github cache "),
|
|
31
|
-
React.createElement(Ink.Text, { bold: true, color: colors.yellow }, result_pr_list.length),
|
|
32
|
-
React.createElement(Ink.Text, null, " open PRs from "),
|
|
33
|
-
React.createElement(Brackets, null, repo_path),
|
|
34
|
-
React.createElement(Ink.Text, null, " authored by "),
|
|
35
|
-
React.createElement(Brackets, null, username)));
|
|
36
|
-
}
|
|
37
|
-
actions.set((state) => {
|
|
38
|
-
for (const pr of result_pr_list) {
|
|
39
|
-
state.pr[pr.headRefName] = pr;
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
return result_pr_list;
|
|
43
|
-
}
|
|
44
|
-
export async function pr_status(branch) {
|
|
45
|
-
const state = Store.getState();
|
|
46
|
-
const actions = state.actions;
|
|
47
|
-
const username = state.username;
|
|
48
|
-
const repo_path = state.repo_path;
|
|
49
|
-
invariant(username, "username must exist");
|
|
50
|
-
invariant(repo_path, "repo_path must exist");
|
|
51
|
-
const cache = state.pr[branch];
|
|
52
|
-
if (cache) {
|
|
53
|
-
if (actions.isDebug()) {
|
|
54
|
-
actions.output(React.createElement(Ink.Text, null,
|
|
55
|
-
React.createElement(Ink.Text, { dimColor: true }, "Github pr_status cache"),
|
|
56
|
-
React.createElement(Ink.Text, null, " "),
|
|
57
|
-
React.createElement(Ink.Text, { bold: true, color: colors.green }, "HIT "),
|
|
58
|
-
React.createElement(Ink.Text, null, " "),
|
|
59
|
-
React.createElement(Ink.Text, { dimColor: true }, branch)));
|
|
60
|
-
}
|
|
61
|
-
return cache;
|
|
62
|
-
}
|
|
63
|
-
if (actions.isDebug()) {
|
|
64
|
-
actions.output(React.createElement(Ink.Text, null,
|
|
65
|
-
React.createElement(Ink.Text, { dimColor: true }, "Github pr_status cache"),
|
|
66
|
-
React.createElement(Ink.Text, null, " "),
|
|
67
|
-
React.createElement(Ink.Text, { bold: true, color: colors.red }, "MISS"),
|
|
68
|
-
React.createElement(Ink.Text, null, " "),
|
|
69
|
-
React.createElement(Ink.Text, { dimColor: true }, branch)));
|
|
70
|
-
}
|
|
71
|
-
const cli_result = await cli(`gh pr view ${branch} --repo ${repo_path} ${JSON_FIELDS}`, {
|
|
72
|
-
ignoreExitCode: true,
|
|
73
|
-
});
|
|
74
|
-
if (cli_result.code !== 0) {
|
|
75
|
-
// handle_error(cli_result.output);
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
const pr = JSON.parse(cli_result.stdout);
|
|
79
|
-
actions.set((state) => {
|
|
80
|
-
state.pr[pr.headRefName] = pr;
|
|
81
|
-
});
|
|
82
|
-
return pr;
|
|
83
|
-
}
|
|
84
|
-
export async function pr_create(args) {
|
|
85
|
-
const title = safe_quote(args.title);
|
|
86
|
-
const cli_result = await cli(`gh pr create --fill --head ${args.branch} --base ${args.base} --title="${title}" --body="${args.body}"`);
|
|
87
|
-
if (cli_result.code !== 0) {
|
|
88
|
-
handle_error(cli_result.output);
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
return cli_result.stdout;
|
|
92
|
-
}
|
|
93
|
-
export async function pr_edit(args) {
|
|
94
|
-
const cli_result = await cli(
|
|
95
|
-
// prettier-ignore
|
|
96
|
-
`gh pr edit ${args.branch} --base ${args.base} --body-file="${body_file(args.body)}"`);
|
|
97
|
-
if (cli_result.code !== 0) {
|
|
98
|
-
handle_error(cli_result.output);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
function handle_error(output) {
|
|
102
|
-
const state = Store.getState();
|
|
103
|
-
const actions = state.actions;
|
|
104
|
-
actions.set((state) => {
|
|
105
|
-
state.step = "github-api-error";
|
|
106
|
-
});
|
|
107
|
-
throw new Error(output);
|
|
108
|
-
}
|
|
109
|
-
// convert a string to a file for use via github cli `--body-file`
|
|
110
|
-
function body_file(body) {
|
|
111
|
-
const temp_dir = os.tmpdir();
|
|
112
|
-
const temp_path = path.join(temp_dir, "git-stack-body");
|
|
113
|
-
if (fs.existsSync(temp_path)) {
|
|
114
|
-
fs.rmSync(temp_path);
|
|
115
|
-
}
|
|
116
|
-
fs.writeFileSync(temp_path, body);
|
|
117
|
-
return temp_path;
|
|
118
|
-
}
|
package/dist/core/id.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
|
-
// console.log(id());
|
|
3
|
-
export function id() {
|
|
4
|
-
const timestamp = Date.now();
|
|
5
|
-
// 9 223 372 036 854 775 808
|
|
6
|
-
// 9 trillion possible values
|
|
7
|
-
// (2^53) * (2^10) = 2^63 = 9,223,372,036,854,775,808
|
|
8
|
-
const js_max_bits = 53;
|
|
9
|
-
const timestamp_bits = Math.floor(Math.log2(timestamp)) + 1;
|
|
10
|
-
// padding needed to reach 53 bits
|
|
11
|
-
const padding_bits = js_max_bits - timestamp_bits;
|
|
12
|
-
// random between 0 and 2^padding_bits - 1
|
|
13
|
-
const random = crypto.randomInt(0, Math.pow(2, padding_bits));
|
|
14
|
-
// combine timestamp and random value
|
|
15
|
-
const combined = interleave_bits(timestamp, random);
|
|
16
|
-
// console.debug({ combined, timestamp, random, padding_bits, timestamp_bits });
|
|
17
|
-
return encode(combined);
|
|
18
|
-
}
|
|
19
|
-
function binary(value) {
|
|
20
|
-
return BigInt(value).toString(2);
|
|
21
|
-
}
|
|
22
|
-
function rand_index(list) {
|
|
23
|
-
return Math.floor(Math.random() * list.length);
|
|
24
|
-
}
|
|
25
|
-
function interleave_bits(a, b) {
|
|
26
|
-
const a_binary = binary(a).split("");
|
|
27
|
-
const b_binary = binary(b).split("");
|
|
28
|
-
while (b_binary.length) {
|
|
29
|
-
// pull random bit out of b_binary
|
|
30
|
-
const b_index = rand_index(b_binary);
|
|
31
|
-
const [selected] = b_binary.splice(b_index, 1);
|
|
32
|
-
// insert random bit into a_binary
|
|
33
|
-
const a_index = rand_index(a_binary);
|
|
34
|
-
a_binary.splice(a_index, 0, selected);
|
|
35
|
-
}
|
|
36
|
-
// convert binary list back to integer
|
|
37
|
-
const a_value = parseInt(a_binary.join(""), 2);
|
|
38
|
-
return a_value;
|
|
39
|
-
}
|
|
40
|
-
function encode(value) {
|
|
41
|
-
// base64 encode (64 characters)
|
|
42
|
-
// max character necessary to encode is equal to maximum number
|
|
43
|
-
// of bits in value divided by bits per character in encoding
|
|
44
|
-
//
|
|
45
|
-
// Example
|
|
46
|
-
// in base64 each characters can represent 6 bits (2^6 = 64)
|
|
47
|
-
// 53 bits / 6 bits = 8.833333333333334 characters (9 characters)
|
|
48
|
-
//
|
|
49
|
-
// prettier-ignore
|
|
50
|
-
const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-+";
|
|
51
|
-
const bits_per_char = Math.log2(chars.length);
|
|
52
|
-
const max_value_bits = 53;
|
|
53
|
-
const max_char_size = Math.ceil(max_value_bits / bits_per_char);
|
|
54
|
-
let result = "";
|
|
55
|
-
while (value > 0) {
|
|
56
|
-
result = chars[value % chars.length] + result;
|
|
57
|
-
value = Math.floor(value / chars.length);
|
|
58
|
-
}
|
|
59
|
-
// pad the result to necessary characters
|
|
60
|
-
return result.padStart(max_char_size, "=");
|
|
61
|
-
}
|
package/dist/core/invariant.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { invariant } from "./invariant.js";
|
|
4
|
-
export function is_command_available(command) {
|
|
5
|
-
const PATH = process.env["PATH"];
|
|
6
|
-
invariant(PATH, "PATH env must exist");
|
|
7
|
-
const path_list = PATH.split(path.delimiter);
|
|
8
|
-
for (const dir of path_list) {
|
|
9
|
-
const full_path = path.join(dir, command);
|
|
10
|
-
if (fs.existsSync(full_path)) {
|
|
11
|
-
return true;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
return false;
|
|
15
|
-
}
|
package/dist/core/is_dev.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/core/json.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
export function serialize(obj) {
|
|
2
|
-
if (obj instanceof Map) {
|
|
3
|
-
return {
|
|
4
|
-
_type: "Map",
|
|
5
|
-
_value: Array.from(obj.entries()).map(([k, v]) => [k, serialize(v)]),
|
|
6
|
-
};
|
|
7
|
-
}
|
|
8
|
-
else if (Array.isArray(obj)) {
|
|
9
|
-
return obj.map(serialize);
|
|
10
|
-
}
|
|
11
|
-
else if (obj !== null && typeof obj === "object") {
|
|
12
|
-
const serializedObj = {};
|
|
13
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
14
|
-
serializedObj[key] = serialize(value);
|
|
15
|
-
}
|
|
16
|
-
return serializedObj;
|
|
17
|
-
}
|
|
18
|
-
return obj;
|
|
19
|
-
}
|
|
20
|
-
export function deserialize(obj) {
|
|
21
|
-
if (obj && obj._type === "Map") {
|
|
22
|
-
return new Map(obj._value.map(([k, v]) => [k, deserialize(v)]));
|
|
23
|
-
}
|
|
24
|
-
else if (Array.isArray(obj)) {
|
|
25
|
-
return obj.map(deserialize);
|
|
26
|
-
}
|
|
27
|
-
else if (obj !== null && typeof obj === "object") {
|
|
28
|
-
const deserializedObj = {};
|
|
29
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
30
|
-
deserializedObj[key] = deserialize(value);
|
|
31
|
-
}
|
|
32
|
-
return deserializedObj;
|
|
33
|
-
}
|
|
34
|
-
return obj;
|
|
35
|
-
}
|
package/dist/core/match_group.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { invariant } from "./invariant.js";
|
|
2
|
-
export function match_group(value, re, group) {
|
|
3
|
-
const match = value.match(re);
|
|
4
|
-
const debug = `[${value}.match(${re})]`;
|
|
5
|
-
invariant(match?.groups, `match.groups must exist ${debug}`);
|
|
6
|
-
const result = match?.groups[group];
|
|
7
|
-
invariant(result, `match.groups must contain [${group}] ${debug}`);
|
|
8
|
-
return result;
|
|
9
|
-
}
|
package/dist/core/readJson.js
DELETED
package/dist/core/read_json.js
DELETED