git-stack-cli 0.8.7 → 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 +21 -7
- 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/Metadata.test.js +0 -34
- package/dist/core/StackSummaryTable.js +0 -86
- package/dist/core/StackSummaryTable.test.js +0 -134
- 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/app/MultiSelect.js
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import * as Ink from "ink";
|
|
3
|
-
import { clamp } from "../core/clamp.js";
|
|
4
|
-
import { colors } from "../core/colors.js";
|
|
5
|
-
import { is_finite_value } from "../core/is_finite_value.js";
|
|
6
|
-
import { wrap_index } from "../core/wrap_index.js";
|
|
7
|
-
export function MultiSelect(props) {
|
|
8
|
-
const [selected_set, select] = React.useReducer((state, value) => {
|
|
9
|
-
const next = new Set(state);
|
|
10
|
-
if (next.has(value)) {
|
|
11
|
-
next.delete(value);
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
next.add(value);
|
|
15
|
-
}
|
|
16
|
-
return next;
|
|
17
|
-
}, new Set(), (set) => {
|
|
18
|
-
props.items.forEach((item, i) => {
|
|
19
|
-
if (item.selected) {
|
|
20
|
-
set.add(i);
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
return set;
|
|
24
|
-
});
|
|
25
|
-
// clamp index to keep in item range
|
|
26
|
-
const [index, set_index] = React.useReducer((_, value) => {
|
|
27
|
-
return clamp(value, 0, props.items.length - 1);
|
|
28
|
-
}, 0, function find_initial_index() {
|
|
29
|
-
let last_enabled;
|
|
30
|
-
for (let i = props.items.length - 1; i >= 0; i--) {
|
|
31
|
-
const item = props.items[i];
|
|
32
|
-
if (!item.disabled) {
|
|
33
|
-
last_enabled = i;
|
|
34
|
-
}
|
|
35
|
-
if (!item.selected && !item.disabled) {
|
|
36
|
-
return i;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
if (is_finite_value(last_enabled)) {
|
|
40
|
-
return last_enabled;
|
|
41
|
-
}
|
|
42
|
-
return 0;
|
|
43
|
-
});
|
|
44
|
-
const selectRef = React.useRef(false);
|
|
45
|
-
React.useEffect(() => {
|
|
46
|
-
if (!selectRef.current) {
|
|
47
|
-
// console.debug("[MultiSelect]", "skip onSelect before selectRef");
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
const item = props.items[index].value;
|
|
51
|
-
const selected_list = Array.from(selected_set);
|
|
52
|
-
const selected = selected_set.has(index);
|
|
53
|
-
const state = selected_list.map((index) => props.items[index].value);
|
|
54
|
-
// console.debug({ item, selected, state });
|
|
55
|
-
props.onSelect({ item, selected, state });
|
|
56
|
-
}, [selected_set]);
|
|
57
|
-
Ink.useInput((input, key) => {
|
|
58
|
-
if (props.disabled) {
|
|
59
|
-
// console.debug("[MultiSelect] disabled, ignoring input");
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const space = input === " ";
|
|
63
|
-
if (key.return || space) {
|
|
64
|
-
selectRef.current = true;
|
|
65
|
-
const item = props.items[index];
|
|
66
|
-
if (!item.disabled) {
|
|
67
|
-
return select(index);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
if (key.upArrow) {
|
|
71
|
-
let check = index;
|
|
72
|
-
for (let i = 0; i < props.items.length; i++) {
|
|
73
|
-
check = wrap_index(check - 1, props.items);
|
|
74
|
-
// console.debug("up", { check, i, index });
|
|
75
|
-
const item = props.items[check];
|
|
76
|
-
if (!item.disabled) {
|
|
77
|
-
return set_index(check);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
if (key.downArrow) {
|
|
82
|
-
let check = index;
|
|
83
|
-
for (let i = 0; i < props.items.length; i++) {
|
|
84
|
-
check = wrap_index(check + 1, props.items);
|
|
85
|
-
// console.debug("down", { check, i, index });
|
|
86
|
-
const item = props.items[check];
|
|
87
|
-
if (!item.disabled) {
|
|
88
|
-
return set_index(check);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
return (React.createElement(Ink.Box, { flexDirection: "column" }, props.items.map((item, i) => {
|
|
94
|
-
const active = i === index;
|
|
95
|
-
const selected = selected_set.has(i);
|
|
96
|
-
const disabled = item.disabled || false;
|
|
97
|
-
return (React.createElement(ItemRow, { key: i, label: item.label, active: active, selected: selected, disabled: disabled, maxWidth: props.maxWidth }));
|
|
98
|
-
})));
|
|
99
|
-
}
|
|
100
|
-
function ItemRow(props) {
|
|
101
|
-
let color;
|
|
102
|
-
let bold;
|
|
103
|
-
let underline;
|
|
104
|
-
let dimColor;
|
|
105
|
-
if (props.active) {
|
|
106
|
-
color = colors.blue;
|
|
107
|
-
underline = true;
|
|
108
|
-
}
|
|
109
|
-
if (props.selected) {
|
|
110
|
-
// color = "";
|
|
111
|
-
bold = true;
|
|
112
|
-
}
|
|
113
|
-
if (props.disabled) {
|
|
114
|
-
color = "";
|
|
115
|
-
bold = false;
|
|
116
|
-
underline = false;
|
|
117
|
-
dimColor = true;
|
|
118
|
-
}
|
|
119
|
-
return (React.createElement(Ink.Box, { flexDirection: "row", gap: 1 },
|
|
120
|
-
React.createElement(Radio, { selected: props.selected, disabled: props.disabled }),
|
|
121
|
-
React.createElement(Ink.Box, { width: props.maxWidth },
|
|
122
|
-
React.createElement(Ink.Text, { bold: bold, underline: underline, color: color, dimColor: dimColor, wrap: "truncate-end" }, props.label))));
|
|
123
|
-
}
|
|
124
|
-
function Radio(props) {
|
|
125
|
-
let display;
|
|
126
|
-
let color;
|
|
127
|
-
let dimColor;
|
|
128
|
-
if (props.selected) {
|
|
129
|
-
// display = "✓";
|
|
130
|
-
display = "◉";
|
|
131
|
-
color = colors.green;
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
// display = " ";
|
|
135
|
-
display = "◯";
|
|
136
|
-
color = "";
|
|
137
|
-
}
|
|
138
|
-
if (props.disabled) {
|
|
139
|
-
color = colors.gray;
|
|
140
|
-
dimColor = true;
|
|
141
|
-
}
|
|
142
|
-
return (React.createElement(Ink.Text, { bold: props.selected, color: color, dimColor: dimColor }, display));
|
|
143
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import * as Ink from "ink";
|
|
4
|
-
export function AutoUpdate(props) {
|
|
5
|
-
const props_ref = React.useRef(props);
|
|
6
|
-
props_ref.current = props;
|
|
7
|
-
React.useEffect(() => {
|
|
8
|
-
async function auto_update() {
|
|
9
|
-
try {
|
|
10
|
-
const npm_res = await fetch(`https://registry.npmjs.org/${props.name}`);
|
|
11
|
-
const npm_json = await npm_res.json();
|
|
12
|
-
const latest = npm_json["dist-tags"].latest;
|
|
13
|
-
console.debug({ latest });
|
|
14
|
-
const script_path = process.argv[1];
|
|
15
|
-
const path_list = [process.argv[1]];
|
|
16
|
-
const real_path_list = path_list.map((p) => fs.realpathSync(p));
|
|
17
|
-
console.debug({ real_path_list, path_list });
|
|
18
|
-
// const winner = await Promise.race([
|
|
19
|
-
// sleep(Math.random() * 5000).then(() => "a"),
|
|
20
|
-
// sleep(Math.random() * 5000).then(() => "b"),
|
|
21
|
-
// ]);
|
|
22
|
-
// console.debug({ winner });
|
|
23
|
-
}
|
|
24
|
-
catch (err) {
|
|
25
|
-
console.debug({ err });
|
|
26
|
-
// handled by catch below
|
|
27
|
-
throw err;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
const onError = props_ref.current.onError || (() => { });
|
|
31
|
-
auto_update().catch(onError);
|
|
32
|
-
}, []);
|
|
33
|
-
return React.createElement(Ink.Text, { color: "yellow" }, "Checking for latest version...");
|
|
34
|
-
}
|
package/dist/app/Output.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import * as Ink from "ink";
|
|
3
|
-
import { Store } from "./Store.js";
|
|
4
|
-
export function Output() {
|
|
5
|
-
const output = Store.useState((state) => state.output);
|
|
6
|
-
const pending_output = Store.useState((state) => state.pending_output);
|
|
7
|
-
const pending_output_items = Object.values(pending_output);
|
|
8
|
-
return (React.createElement(React.Fragment, null,
|
|
9
|
-
React.createElement(Ink.Static, { items: output }, (node, i) => {
|
|
10
|
-
return React.createElement(Ink.Box, { key: i }, node);
|
|
11
|
-
}),
|
|
12
|
-
pending_output_items.map((node_list, i) => {
|
|
13
|
-
return (React.createElement(Ink.Box, { key: i },
|
|
14
|
-
React.createElement(Ink.Text, null, node_list.map((text, j) => {
|
|
15
|
-
return (React.createElement(React.Fragment, { key: j },
|
|
16
|
-
React.createElement(Ink.Text, null, text)));
|
|
17
|
-
}))));
|
|
18
|
-
})));
|
|
19
|
-
}
|
package/dist/app/Parens copy.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import * as Ink from "ink";
|
|
3
|
-
export function Parens(props) {
|
|
4
|
-
const color = "#38bdf8";
|
|
5
|
-
return (React.createElement(Ink.Text, null,
|
|
6
|
-
React.createElement(Ink.Text, { color: color }, "("),
|
|
7
|
-
props.children,
|
|
8
|
-
React.createElement(Ink.Text, { color: color }, ")")));
|
|
9
|
-
}
|
package/dist/app/Parens.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import * as Ink from "ink";
|
|
3
|
-
import { colors } from "../core/colors.js";
|
|
4
|
-
export function Parens(props) {
|
|
5
|
-
const color = colors.blue;
|
|
6
|
-
return (React.createElement(Ink.Text, null,
|
|
7
|
-
React.createElement(Ink.Text, { color: color }, "("),
|
|
8
|
-
props.children,
|
|
9
|
-
React.createElement(Ink.Text, { color: color }, ")")));
|
|
10
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import * as Ink from "ink";
|
|
3
|
-
import * as CommitMetadata from "../core/CommitMetadata.js";
|
|
4
|
-
import { invariant } from "../core/invariant.js";
|
|
5
|
-
import { Await } from "./Await.js";
|
|
6
|
-
import { StatusTable } from "./StatusTable.js";
|
|
7
|
-
import { Store } from "./Store.js";
|
|
8
|
-
export function PostRebaseStatus() {
|
|
9
|
-
const argv = Store.useState((state) => state.argv);
|
|
10
|
-
invariant(argv, "argv must exist");
|
|
11
|
-
return React.createElement(Await, { fallback: null, function: run });
|
|
12
|
-
}
|
|
13
|
-
async function run() {
|
|
14
|
-
const actions = Store.getState().actions;
|
|
15
|
-
// reset github pr cache before refreshing via commit range below
|
|
16
|
-
actions.reset_pr();
|
|
17
|
-
const commit_range = await CommitMetadata.range();
|
|
18
|
-
actions.set((state) => {
|
|
19
|
-
state.commit_range = commit_range;
|
|
20
|
-
});
|
|
21
|
-
actions.output(React.createElement(StatusTable, null));
|
|
22
|
-
actions.output(React.createElement(Ink.Text, null, "\u2705 Everything up to date."));
|
|
23
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import * as Ink from "ink";
|
|
3
|
-
import * as CommitMetadata from "../core/CommitMetadata.js";
|
|
4
|
-
import { invariant } from "../core/invariant.js";
|
|
5
|
-
import { Await } from "./Await.js";
|
|
6
|
-
import { StatusTable } from "./StatusTable.js";
|
|
7
|
-
import { Store } from "./Store.js";
|
|
8
|
-
export function PostRebaseStatus() {
|
|
9
|
-
const argv = Store.useState((state) => state.argv);
|
|
10
|
-
invariant(argv, "argv must exist");
|
|
11
|
-
return React.createElement(Await, { fallback: null, function: run });
|
|
12
|
-
}
|
|
13
|
-
async function run() {
|
|
14
|
-
const actions = Store.getState().actions;
|
|
15
|
-
// reset github pr cache before refreshing via commit range below
|
|
16
|
-
actions.reset_pr();
|
|
17
|
-
const commit_range = await CommitMetadata.range();
|
|
18
|
-
actions.set((state) => {
|
|
19
|
-
state.commit_range = commit_range;
|
|
20
|
-
});
|
|
21
|
-
actions.output(React.createElement(StatusTable, null));
|
|
22
|
-
actions.output(React.createElement(Ink.Text, null, "\u2705 Everything up to date."));
|
|
23
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { invariant } from "../core/invariant.js";
|
|
3
|
-
import { Store } from "./Store.js";
|
|
4
|
-
import { YesNoPrompt } from "./YesNoPrompt.js";
|
|
5
|
-
export function PreLocalMergeRebase() {
|
|
6
|
-
const actions = Store.useActions();
|
|
7
|
-
const argv = Store.useState((state) => state.argv);
|
|
8
|
-
invariant(argv, "argv must exist");
|
|
9
|
-
React.useEffect(() => {
|
|
10
|
-
if (argv.force) {
|
|
11
|
-
Store.setState((state) => {
|
|
12
|
-
state.step = "local-merge-rebase";
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
}, [argv]);
|
|
16
|
-
return (React.createElement(YesNoPrompt, { message: "Local branch needs to be rebased, would you like to rebase to update your local branch?", onYes: () => {
|
|
17
|
-
actions.set((state) => {
|
|
18
|
-
state.step = "local-merge-rebase";
|
|
19
|
-
});
|
|
20
|
-
}, onNo: () => actions.exit(0) }));
|
|
21
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { invariant } from "../core/invariant.js";
|
|
3
|
-
import { Store } from "./Store.js";
|
|
4
|
-
import { YesNoPrompt } from "./YesNoPrompt.js";
|
|
5
|
-
export function PreSelectCommitRanges() {
|
|
6
|
-
const actions = Store.useActions();
|
|
7
|
-
const argv = Store.useState((state) => state.argv);
|
|
8
|
-
invariant(argv, "argv must exist");
|
|
9
|
-
React.useEffect(() => {
|
|
10
|
-
if (argv.force) {
|
|
11
|
-
Store.setState((state) => {
|
|
12
|
-
state.step = "select-commit-ranges";
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
}, [argv]);
|
|
16
|
-
return (React.createElement(YesNoPrompt, { message: "Some commits are new or outdated, would you like to select new commit ranges?", onYes: () => {
|
|
17
|
-
actions.set((state) => {
|
|
18
|
-
state.step = "select-commit-ranges";
|
|
19
|
-
});
|
|
20
|
-
}, onNo: () => actions.exit(0) }));
|
|
21
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { invariant } from "../core/invariant.js";
|
|
3
|
-
import { Store } from "./Store.js";
|
|
4
|
-
import { YesNoPrompt } from "./YesNoPrompt.js";
|
|
5
|
-
export function PreSelectCommitRanges() {
|
|
6
|
-
const actions = Store.useActions();
|
|
7
|
-
const argv = Store.useState((state) => state.argv);
|
|
8
|
-
invariant(argv, "argv must exist");
|
|
9
|
-
React.useEffect(() => {
|
|
10
|
-
if (argv.force) {
|
|
11
|
-
Store.setState((state) => {
|
|
12
|
-
state.step = "select-commit-ranges";
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
}, [argv]);
|
|
16
|
-
return (React.createElement(YesNoPrompt, { message: "Some commits are new or outdated, would you like to select new commit ranges?", onYes: () => {
|
|
17
|
-
actions.set((state) => {
|
|
18
|
-
state.step = "select-commit-ranges";
|
|
19
|
-
});
|
|
20
|
-
}, onNo: () => actions.exit(0) }));
|
|
21
|
-
}
|
package/dist/app/Providers.js
DELETED
package/dist/app/RebaseCheck.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import * as Ink from "ink";
|
|
5
|
-
import { cli } from "../core/cli.js";
|
|
6
|
-
import { colors } from "../core/colors.js";
|
|
7
|
-
import { invariant } from "../core/invariant.js";
|
|
8
|
-
import { Await } from "./Await.js";
|
|
9
|
-
import { Store } from "./Store.js";
|
|
10
|
-
import { YesNoPrompt } from "./YesNoPrompt.js";
|
|
11
|
-
function reducer(state, patch) {
|
|
12
|
-
return { ...state, ...patch };
|
|
13
|
-
}
|
|
14
|
-
export function RebaseCheck(props) {
|
|
15
|
-
const actions = Store.useActions();
|
|
16
|
-
const argv = Store.useState((state) => state.argv);
|
|
17
|
-
invariant(argv, "argv must exist");
|
|
18
|
-
const [state, patch] = React.useReducer(reducer, {
|
|
19
|
-
status: "init",
|
|
20
|
-
});
|
|
21
|
-
switch (state.status) {
|
|
22
|
-
case "done":
|
|
23
|
-
return props.children;
|
|
24
|
-
case "prompt":
|
|
25
|
-
return (React.createElement(YesNoPrompt, { message: React.createElement(Ink.Text, { color: colors.yellow }, "Rebase detected, would you like to abort it?"), onYes: async () => {
|
|
26
|
-
await cli(`git rebase --abort`);
|
|
27
|
-
patch({ status: "done" });
|
|
28
|
-
}, onNo: async () => {
|
|
29
|
-
actions.exit(0);
|
|
30
|
-
} }));
|
|
31
|
-
default:
|
|
32
|
-
return (React.createElement(Await, { fallback: React.createElement(Ink.Text, { color: colors.yellow }, "Checking for rebase..."), function: rebase_check }));
|
|
33
|
-
}
|
|
34
|
-
async function rebase_check() {
|
|
35
|
-
const actions = Store.getState().actions;
|
|
36
|
-
const argv = Store.getState().argv;
|
|
37
|
-
invariant(argv, "argv must exist");
|
|
38
|
-
try {
|
|
39
|
-
const repo_root = (await cli(`git rev-parse --absolute-git-dir`)).stdout;
|
|
40
|
-
let is_rebase = false;
|
|
41
|
-
is_rebase ||= fs.existsSync(path.join(repo_root, "rebase-apply"));
|
|
42
|
-
is_rebase ||= fs.existsSync(path.join(repo_root, "rebase-merge"));
|
|
43
|
-
const status = is_rebase ? "prompt" : "done";
|
|
44
|
-
patch({ status });
|
|
45
|
-
}
|
|
46
|
-
catch (err) {
|
|
47
|
-
actions.error("Unable to check for rebase.");
|
|
48
|
-
if (err instanceof Error) {
|
|
49
|
-
if (actions.isDebug()) {
|
|
50
|
-
actions.error(err.message);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
actions.exit(9);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import * as Ink from "ink";
|
|
3
|
-
import { colors } from "../core/colors.js";
|
|
4
|
-
import { invariant } from "../core/invariant.js";
|
|
5
|
-
import { short_id } from "../core/short_id.js";
|
|
6
|
-
import { wrap_index } from "../core/wrap_index.js";
|
|
7
|
-
import { Brackets } from "./Brackets.js";
|
|
8
|
-
import { FormatText } from "./FormatText.js";
|
|
9
|
-
import { MultiSelect } from "./MultiSelect.js";
|
|
10
|
-
import { Parens } from "./Parens.js";
|
|
11
|
-
import { Store } from "./Store.js";
|
|
12
|
-
import { TextInput } from "./TextInput.js";
|
|
13
|
-
export function SelectCommitRanges() {
|
|
14
|
-
const commit_range = Store.useState((state) => state.commit_range);
|
|
15
|
-
invariant(commit_range, "commit_range must exist");
|
|
16
|
-
return React.createElement(SelectCommitRangesInternal, { commit_range: commit_range });
|
|
17
|
-
}
|
|
18
|
-
function SelectCommitRangesInternal(props) {
|
|
19
|
-
const actions = Store.useActions();
|
|
20
|
-
const [selected_group_id, set_selected_group_id] = React.useState(props.commit_range.UNASSIGNED);
|
|
21
|
-
const [group_input, set_group_input] = React.useState(false);
|
|
22
|
-
const [new_group_list, create_group] = React.useReducer((group_list, group) => {
|
|
23
|
-
return group_list.concat(group);
|
|
24
|
-
}, []);
|
|
25
|
-
const [commit_map, update_commit_map] = React.useReducer((map, args) => {
|
|
26
|
-
map.set(args.key, args.value);
|
|
27
|
-
// console.debug("update_commit_map", map, args);
|
|
28
|
-
return new Map(map);
|
|
29
|
-
}, new Map(), (map) => {
|
|
30
|
-
for (const commit of props.commit_range.commit_list) {
|
|
31
|
-
map.set(commit.sha, commit.branch_id);
|
|
32
|
-
}
|
|
33
|
-
return new Map(map);
|
|
34
|
-
});
|
|
35
|
-
const group_list = [];
|
|
36
|
-
// detect if there are unassigned commits
|
|
37
|
-
let unassigned_count = 0;
|
|
38
|
-
for (const [, group_id] of commit_map.entries()) {
|
|
39
|
-
if (group_id === null) {
|
|
40
|
-
// console.debug("unassigned commit detected", sha);
|
|
41
|
-
unassigned_count++;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
group_list.push(...new_group_list);
|
|
45
|
-
const total_group_count = new_group_list.length + props.commit_range.group_list.length;
|
|
46
|
-
for (const group of props.commit_range.group_list) {
|
|
47
|
-
if (group.pr?.state === "MERGED")
|
|
48
|
-
continue;
|
|
49
|
-
if (group.id === props.commit_range.UNASSIGNED) {
|
|
50
|
-
// only include unassigned group when there are no other groups
|
|
51
|
-
if (total_group_count === 1) {
|
|
52
|
-
group_list.push({
|
|
53
|
-
id: group.id,
|
|
54
|
-
title: "Unassigned",
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
group_list.push({
|
|
60
|
-
id: group.id,
|
|
61
|
-
title: group.pr?.title || group.id,
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
let current_index = group_list.findIndex((g) => g.id === selected_group_id);
|
|
65
|
-
if (current_index === -1) {
|
|
66
|
-
current_index = 0;
|
|
67
|
-
}
|
|
68
|
-
Ink.useInput((input, key) => {
|
|
69
|
-
const inputLower = input.toLowerCase();
|
|
70
|
-
const hasUnassignedCommits = unassigned_count > 0;
|
|
71
|
-
if (!hasUnassignedCommits && inputLower === "s") {
|
|
72
|
-
actions.set((state) => {
|
|
73
|
-
state.commit_map = {};
|
|
74
|
-
for (const [sha, id] of commit_map.entries()) {
|
|
75
|
-
if (id) {
|
|
76
|
-
const group = group_list.find((g) => g.id === id);
|
|
77
|
-
// console.debug({ sha, id, group });
|
|
78
|
-
if (group) {
|
|
79
|
-
state.commit_map[sha] = group;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
switch (inputLower) {
|
|
84
|
-
case "s":
|
|
85
|
-
state.step = "manual-rebase";
|
|
86
|
-
break;
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
// only allow create when on unassigned group
|
|
92
|
-
if (hasUnassignedCommits && inputLower === "c") {
|
|
93
|
-
set_group_input(true);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
if (key.leftArrow) {
|
|
97
|
-
const new_index = wrap_index(current_index - 1, group_list);
|
|
98
|
-
const next_group = group_list[new_index];
|
|
99
|
-
return set_selected_group_id(next_group.id);
|
|
100
|
-
}
|
|
101
|
-
if (key.rightArrow) {
|
|
102
|
-
const new_index = wrap_index(current_index + 1, group_list);
|
|
103
|
-
const next_group = group_list[new_index];
|
|
104
|
-
return set_selected_group_id(next_group.id);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
const group = group_list[current_index];
|
|
108
|
-
const items = props.commit_range.commit_list.map((commit) => {
|
|
109
|
-
const commit_metadata_id = commit_map.get(commit.sha);
|
|
110
|
-
const selected = commit_metadata_id !== null;
|
|
111
|
-
let disabled;
|
|
112
|
-
if (group.id === props.commit_range.UNASSIGNED) {
|
|
113
|
-
disabled = true;
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
disabled = Boolean(selected && commit_metadata_id !== group.id);
|
|
117
|
-
}
|
|
118
|
-
return {
|
|
119
|
-
label: commit.subject_line,
|
|
120
|
-
value: commit,
|
|
121
|
-
selected,
|
|
122
|
-
disabled,
|
|
123
|
-
};
|
|
124
|
-
});
|
|
125
|
-
items.reverse();
|
|
126
|
-
// <- (2/4) #742 Title A ->
|
|
127
|
-
const left_arrow = `${SYMBOL.left} `;
|
|
128
|
-
const right_arrow = ` ${SYMBOL.right}`;
|
|
129
|
-
const group_position = `(${current_index + 1}/${group_list.length}) `;
|
|
130
|
-
const max_group_label_width = 80;
|
|
131
|
-
let group_title_width = max_group_label_width;
|
|
132
|
-
group_title_width -= group_position.length;
|
|
133
|
-
group_title_width -= left_arrow.length + right_arrow.length;
|
|
134
|
-
group_title_width = Math.min(group.title.length, group_title_width);
|
|
135
|
-
let max_item_width = max_group_label_width;
|
|
136
|
-
max_item_width -= left_arrow.length + right_arrow.length;
|
|
137
|
-
return (React.createElement(Ink.Box, { flexDirection: "column" },
|
|
138
|
-
React.createElement(Ink.Box, { height: 1 }),
|
|
139
|
-
React.createElement(MultiSelect, { key: group.id, items: items, maxWidth: max_item_width, disabled: group_input, onSelect: (args) => {
|
|
140
|
-
// console.debug("onSelect", args);
|
|
141
|
-
const key = args.item.sha;
|
|
142
|
-
let value;
|
|
143
|
-
if (args.selected) {
|
|
144
|
-
value = group.id;
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
value = null;
|
|
148
|
-
}
|
|
149
|
-
update_commit_map({ key, value });
|
|
150
|
-
} }),
|
|
151
|
-
React.createElement(Ink.Box, { height: 1 }),
|
|
152
|
-
React.createElement(Ink.Box, { width: max_group_label_width, flexDirection: "row" },
|
|
153
|
-
React.createElement(Ink.Text, null, left_arrow),
|
|
154
|
-
React.createElement(Ink.Text, null, group_position),
|
|
155
|
-
React.createElement(Ink.Box, { width: group_title_width, justifyContent: "center" },
|
|
156
|
-
React.createElement(Ink.Text, { wrap: "truncate-end" }, group.title)),
|
|
157
|
-
React.createElement(Ink.Text, null, right_arrow)),
|
|
158
|
-
React.createElement(Ink.Box, { height: 1 }),
|
|
159
|
-
unassigned_count > 0 ? (React.createElement(FormatText, { wrapper: React.createElement(Ink.Text, { color: colors.gray }), message: "{count} unassigned commits, press {c} to {create} a new group", values: {
|
|
160
|
-
count: (React.createElement(Ink.Text, { color: colors.yellow, bold: true }, unassigned_count)),
|
|
161
|
-
c: (React.createElement(Ink.Text, { bold: true, color: colors.green }, "c")),
|
|
162
|
-
create: (React.createElement(Ink.Text, { bold: true, color: colors.green },
|
|
163
|
-
React.createElement(Parens, null, "c"),
|
|
164
|
-
"reate")),
|
|
165
|
-
} })) : (React.createElement(React.Fragment, null,
|
|
166
|
-
React.createElement(FormatText, { wrapper: React.createElement(Ink.Text, null), message: "\uD83C\uDF89 Done! Press {s} to {sync} the commits to Github", values: {
|
|
167
|
-
s: (React.createElement(Ink.Text, { bold: true, color: colors.green }, "s")),
|
|
168
|
-
sync: (React.createElement(Ink.Text, { bold: true, color: colors.green },
|
|
169
|
-
React.createElement(Parens, null, "s"),
|
|
170
|
-
"ync")),
|
|
171
|
-
} }))),
|
|
172
|
-
!group_input ? null : (React.createElement(React.Fragment, null,
|
|
173
|
-
React.createElement(Ink.Box, { height: 1 }),
|
|
174
|
-
React.createElement(FormatText, { wrapper: React.createElement(Ink.Text, { color: colors.gray }), message: "Enter a title for the PR {note}", values: {
|
|
175
|
-
note: (React.createElement(Parens, null,
|
|
176
|
-
React.createElement(FormatText, { message: "press {enter} to submit", values: {
|
|
177
|
-
enter: (React.createElement(Ink.Text, { bold: true, color: colors.green }, SYMBOL.enter)),
|
|
178
|
-
} }))),
|
|
179
|
-
} }),
|
|
180
|
-
React.createElement(TextInput, { onSubmit: submit_group_input }),
|
|
181
|
-
React.createElement(Ink.Box, { height: 1 }))),
|
|
182
|
-
React.createElement(Ink.Box, null,
|
|
183
|
-
React.createElement(FormatText, { wrapper: React.createElement(Ink.Text, { color: colors.gray }), message: "Press {left} and {right} to view PR groups", values: {
|
|
184
|
-
left: (React.createElement(Ink.Text, { bold: true, color: colors.green }, SYMBOL.left)),
|
|
185
|
-
right: (React.createElement(Ink.Text, { bold: true, color: colors.green }, SYMBOL.right)),
|
|
186
|
-
} })),
|
|
187
|
-
React.createElement(Ink.Box, null,
|
|
188
|
-
React.createElement(FormatText, { wrapper: React.createElement(Ink.Text, { color: colors.gray }), message: "Press {enter} to toggle commit selection", values: {
|
|
189
|
-
enter: (React.createElement(Ink.Text, { bold: true, color: colors.green }, SYMBOL.enter)),
|
|
190
|
-
} }))));
|
|
191
|
-
function submit_group_input(title) {
|
|
192
|
-
const id = short_id();
|
|
193
|
-
actions.output(React.createElement(FormatText, { wrapper: React.createElement(Ink.Text, { dimColor: true }), message: "Created new group {group} {note}", values: {
|
|
194
|
-
group: React.createElement(Brackets, null, title),
|
|
195
|
-
note: React.createElement(Parens, null, id),
|
|
196
|
-
} }));
|
|
197
|
-
// console.debug("submit_group_input", { title, id });
|
|
198
|
-
create_group({ id, title });
|
|
199
|
-
set_selected_group_id(id);
|
|
200
|
-
set_group_input(false);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
const SYMBOL = {
|
|
204
|
-
left: "←",
|
|
205
|
-
right: "→",
|
|
206
|
-
enter: "Enter",
|
|
207
|
-
};
|
package/dist/app/Status copy.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import * as Ink from "ink";
|
|
3
|
-
import { invariant } from "../core/invariant.js";
|
|
4
|
-
import { Await } from "./Await.js";
|
|
5
|
-
import { StatusTable } from "./StatusTable.js";
|
|
6
|
-
import { Store } from "./Store.js";
|
|
7
|
-
export function Status() {
|
|
8
|
-
const argv = Store.useState((state) => state.argv);
|
|
9
|
-
invariant(argv, "argv must exist");
|
|
10
|
-
return React.createElement(Await, { fallback: null, function: () => run({ argv }) });
|
|
11
|
-
}
|
|
12
|
-
async function run(args) {
|
|
13
|
-
const actions = Store.getState().actions;
|
|
14
|
-
const commit_range = Store.getState().commit_range;
|
|
15
|
-
invariant(commit_range, "commit_range must exist");
|
|
16
|
-
actions.output(React.createElement(StatusTable, null));
|
|
17
|
-
let needs_update = false;
|
|
18
|
-
for (const group of commit_range.group_list) {
|
|
19
|
-
if (group.dirty) {
|
|
20
|
-
needs_update = true;
|
|
21
|
-
break;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
if (args.argv.check) {
|
|
25
|
-
actions.exit(0);
|
|
26
|
-
}
|
|
27
|
-
else if (args.argv.force) {
|
|
28
|
-
Store.setState((state) => {
|
|
29
|
-
state.step = "select-commit-ranges";
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
else if (needs_update) {
|
|
33
|
-
Store.setState((state) => {
|
|
34
|
-
state.step = "pre-select-commit-ranges";
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
actions.newline();
|
|
39
|
-
actions.output(React.createElement(Ink.Text, null, "\u2705 Everything up to date."));
|
|
40
|
-
actions.output(React.createElement(Ink.Text, { color: "gray" },
|
|
41
|
-
React.createElement(Ink.Text, null, "Run with"),
|
|
42
|
-
React.createElement(Ink.Text, { bold: true, color: "yellow" }, ` --force `),
|
|
43
|
-
React.createElement(Ink.Text, null, "to force update all pull requests.")));
|
|
44
|
-
actions.exit(0);
|
|
45
|
-
}
|
|
46
|
-
}
|