git-stack-cli 2.5.0 → 2.5.2
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/dist/js/index.js +220 -257
- package/package.json +1 -1
- package/src/app/App.tsx +23 -19
- package/src/app/AutoUpdate.tsx +49 -23
- package/src/app/DependencyCheck.tsx +18 -3
- package/src/app/SyncGithub.tsx +1 -60
package/package.json
CHANGED
package/src/app/App.tsx
CHANGED
|
@@ -61,13 +61,11 @@ export function App() {
|
|
|
61
61
|
}}
|
|
62
62
|
>
|
|
63
63
|
<VerboseDebugInfo>
|
|
64
|
-
<
|
|
65
|
-
<
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
</RebaseCheck>
|
|
70
|
-
</DependencyCheck>
|
|
64
|
+
<RebaseCheck>
|
|
65
|
+
<CherryPickCheck>
|
|
66
|
+
<MaybeMain />
|
|
67
|
+
</CherryPickCheck>
|
|
68
|
+
</RebaseCheck>
|
|
71
69
|
</VerboseDebugInfo>
|
|
72
70
|
</AutoUpdate>
|
|
73
71
|
|
|
@@ -88,11 +86,15 @@ function MaybeMain() {
|
|
|
88
86
|
return <Log />;
|
|
89
87
|
} else if (positional_list.has("rebase")) {
|
|
90
88
|
return (
|
|
91
|
-
<
|
|
92
|
-
<
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
<DependencyCheck>
|
|
90
|
+
<DirtyCheck>
|
|
91
|
+
<GatherMetadata>
|
|
92
|
+
<LocalCommitStatus>
|
|
93
|
+
<Rebase />
|
|
94
|
+
</LocalCommitStatus>
|
|
95
|
+
</GatherMetadata>
|
|
96
|
+
</DirtyCheck>
|
|
97
|
+
</DependencyCheck>
|
|
96
98
|
);
|
|
97
99
|
}
|
|
98
100
|
|
|
@@ -100,15 +102,17 @@ function MaybeMain() {
|
|
|
100
102
|
<React.Fragment>
|
|
101
103
|
{!argv.verbose ? null : <GithubApiError />}
|
|
102
104
|
|
|
103
|
-
<
|
|
105
|
+
<DependencyCheck>
|
|
104
106
|
<DirtyCheck>
|
|
105
|
-
<
|
|
106
|
-
<
|
|
107
|
-
<
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
<GatherMetadata>
|
|
108
|
+
<LocalCommitStatus>
|
|
109
|
+
<DetectInitialPR>
|
|
110
|
+
<Main />
|
|
111
|
+
</DetectInitialPR>
|
|
112
|
+
</LocalCommitStatus>
|
|
113
|
+
</GatherMetadata>
|
|
110
114
|
</DirtyCheck>
|
|
111
|
-
</
|
|
115
|
+
</DependencyCheck>
|
|
112
116
|
</React.Fragment>
|
|
113
117
|
);
|
|
114
118
|
}
|
package/src/app/AutoUpdate.tsx
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
|
|
3
|
-
import fs from "node:fs/promises";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
|
|
6
3
|
import * as Ink from "ink-cjs";
|
|
7
4
|
|
|
8
5
|
import { Brackets } from "~/app/Brackets";
|
|
6
|
+
import { Command } from "~/app/Command";
|
|
9
7
|
import { FormatText } from "~/app/FormatText";
|
|
10
8
|
import { YesNoPrompt } from "~/app/YesNoPrompt";
|
|
11
9
|
import { cli } from "~/core/cli";
|
|
12
10
|
import { colors } from "~/core/colors";
|
|
13
11
|
import { fetch_json } from "~/core/fetch_json";
|
|
14
12
|
import { is_finite_value } from "~/core/is_finite_value";
|
|
15
|
-
import { read_json } from "~/core/read_json";
|
|
16
13
|
import { semver_compare } from "~/core/semver_compare";
|
|
17
14
|
import { sleep } from "~/core/sleep";
|
|
18
15
|
|
|
@@ -31,6 +28,7 @@ type State = {
|
|
|
31
28
|
local_version: null | string;
|
|
32
29
|
latest_version: null | string;
|
|
33
30
|
status: "init" | "prompt" | "install" | "done" | "exit";
|
|
31
|
+
is_brew_bun_standalone: boolean;
|
|
34
32
|
};
|
|
35
33
|
|
|
36
34
|
function reducer(state: State, patch: Partial<State>) {
|
|
@@ -48,6 +46,7 @@ export function AutoUpdate(props: Props) {
|
|
|
48
46
|
local_version: null,
|
|
49
47
|
latest_version: null,
|
|
50
48
|
status: "init",
|
|
49
|
+
is_brew_bun_standalone: false,
|
|
51
50
|
});
|
|
52
51
|
|
|
53
52
|
function handle_output(node: React.ReactNode) {
|
|
@@ -62,10 +61,16 @@ export function AutoUpdate(props: Props) {
|
|
|
62
61
|
|
|
63
62
|
React.useEffect(() => {
|
|
64
63
|
let status: State["status"] = "done";
|
|
65
|
-
let local_version: string | null = null;
|
|
66
64
|
let latest_version: string | null = null;
|
|
65
|
+
let is_brew_bun_standalone = false;
|
|
66
|
+
|
|
67
|
+
const local_version = process.env.CLI_VERSION;
|
|
67
68
|
|
|
68
69
|
async function auto_update() {
|
|
70
|
+
if (!local_version) {
|
|
71
|
+
throw new Error("Auto update requires process.env.CLI_VERSION to be set");
|
|
72
|
+
}
|
|
73
|
+
|
|
69
74
|
if (props_ref.current.verbose) {
|
|
70
75
|
handle_output(<Ink.Text key="init">Checking for latest version...</Ink.Text>);
|
|
71
76
|
}
|
|
@@ -86,22 +91,24 @@ export function AutoUpdate(props: Props) {
|
|
|
86
91
|
throw new Error("Unable to retrieve latest version from npm");
|
|
87
92
|
}
|
|
88
93
|
|
|
89
|
-
const
|
|
90
|
-
const script_dir = path.dirname(script_path);
|
|
94
|
+
const binary_path = process.argv[1];
|
|
91
95
|
|
|
92
|
-
|
|
93
|
-
|
|
96
|
+
if (props_ref.current.verbose) {
|
|
97
|
+
handle_output(<Ink.Text dimColor>{JSON.stringify({ binary_path })}</Ink.Text>);
|
|
98
|
+
}
|
|
94
99
|
|
|
95
|
-
|
|
96
|
-
const package_json = await read_json<PackageJson>(package_json_path);
|
|
100
|
+
is_brew_bun_standalone = binary_path.startsWith("/$bunfs");
|
|
97
101
|
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
if (props_ref.current.verbose) {
|
|
103
|
+
if (is_brew_bun_standalone) {
|
|
104
|
+
handle_output(
|
|
105
|
+
<Ink.Text dimColor>brew install detected (compiled bun standalone)</Ink.Text>,
|
|
106
|
+
);
|
|
107
|
+
} else {
|
|
108
|
+
handle_output(<Ink.Text dimColor>npm install detected</Ink.Text>);
|
|
109
|
+
}
|
|
101
110
|
}
|
|
102
111
|
|
|
103
|
-
local_version = package_json.version;
|
|
104
|
-
|
|
105
112
|
if (props_ref.current.verbose) {
|
|
106
113
|
handle_output(
|
|
107
114
|
<FormatText
|
|
@@ -118,6 +125,8 @@ export function AutoUpdate(props: Props) {
|
|
|
118
125
|
|
|
119
126
|
const semver_result = semver_compare(latest_version, local_version);
|
|
120
127
|
|
|
128
|
+
status = "prompt";
|
|
129
|
+
|
|
121
130
|
if (semver_result === 0) {
|
|
122
131
|
return;
|
|
123
132
|
}
|
|
@@ -137,10 +146,10 @@ export function AutoUpdate(props: Props) {
|
|
|
137
146
|
|
|
138
147
|
auto_update()
|
|
139
148
|
.then(() => {
|
|
140
|
-
patch({ status, local_version, latest_version });
|
|
149
|
+
patch({ status, local_version, latest_version, is_brew_bun_standalone });
|
|
141
150
|
})
|
|
142
151
|
.catch((error) => {
|
|
143
|
-
patch({ status, error, local_version, latest_version });
|
|
152
|
+
patch({ status, error, local_version, latest_version, is_brew_bun_standalone });
|
|
144
153
|
onError(error);
|
|
145
154
|
|
|
146
155
|
if (props_ref.current.verbose) {
|
|
@@ -161,13 +170,29 @@ export function AutoUpdate(props: Props) {
|
|
|
161
170
|
case "init":
|
|
162
171
|
return null;
|
|
163
172
|
|
|
164
|
-
case "prompt":
|
|
173
|
+
case "prompt": {
|
|
174
|
+
let install_command = "";
|
|
175
|
+
if (state.is_brew_bun_standalone) {
|
|
176
|
+
install_command = `npm install -g ${props.name}@latest`;
|
|
177
|
+
} else {
|
|
178
|
+
install_command = `HOMEBREW_NO_AUTO_UPDATE=1 brew upgrade magus/git-stack/git-stack`;
|
|
179
|
+
}
|
|
180
|
+
|
|
165
181
|
return (
|
|
166
182
|
<YesNoPrompt
|
|
167
183
|
message={
|
|
168
|
-
<Ink.
|
|
169
|
-
|
|
170
|
-
|
|
184
|
+
<Ink.Box flexDirection="column">
|
|
185
|
+
<Ink.Text color={colors.yellow}>
|
|
186
|
+
New version available, would you like to update?
|
|
187
|
+
</Ink.Text>
|
|
188
|
+
<Ink.Text> </Ink.Text>
|
|
189
|
+
<Command>{install_command}</Command>
|
|
190
|
+
<Ink.Text> </Ink.Text>
|
|
191
|
+
<FormatText
|
|
192
|
+
wrapper={<Ink.Text color={colors.yellow} />}
|
|
193
|
+
message="Would you like to run the above command to update?"
|
|
194
|
+
/>
|
|
195
|
+
</Ink.Box>
|
|
171
196
|
}
|
|
172
197
|
onYes={async () => {
|
|
173
198
|
handle_output(
|
|
@@ -184,7 +209,7 @@ export function AutoUpdate(props: Props) {
|
|
|
184
209
|
|
|
185
210
|
patch({ status: "install" });
|
|
186
211
|
|
|
187
|
-
await cli(
|
|
212
|
+
await cli(install_command);
|
|
188
213
|
|
|
189
214
|
patch({ status: "exit" });
|
|
190
215
|
|
|
@@ -195,6 +220,7 @@ export function AutoUpdate(props: Props) {
|
|
|
195
220
|
}}
|
|
196
221
|
/>
|
|
197
222
|
);
|
|
223
|
+
}
|
|
198
224
|
|
|
199
225
|
case "install":
|
|
200
226
|
return null;
|
|
@@ -15,14 +15,17 @@ import * as gh from "~/github/gh";
|
|
|
15
15
|
|
|
16
16
|
type Props = {
|
|
17
17
|
children: React.ReactNode;
|
|
18
|
+
disableGithubCli?: boolean;
|
|
19
|
+
disableGithubCliAuth?: boolean;
|
|
20
|
+
disableGitRevise?: boolean;
|
|
18
21
|
};
|
|
19
22
|
|
|
20
23
|
export function DependencyCheck(props: Props) {
|
|
21
24
|
return (
|
|
22
25
|
<CheckGit>
|
|
23
|
-
<CheckGithubCli>
|
|
24
|
-
<CheckGithubCliAuth>
|
|
25
|
-
<CheckGitRevise>
|
|
26
|
+
<CheckGithubCli {...props}>
|
|
27
|
+
<CheckGithubCliAuth {...props}>
|
|
28
|
+
<CheckGitRevise {...props}>
|
|
26
29
|
{/* force line break */}
|
|
27
30
|
{props.children}
|
|
28
31
|
</CheckGitRevise>
|
|
@@ -69,6 +72,10 @@ function CheckGit(props: Props) {
|
|
|
69
72
|
function CheckGithubCli(props: Props) {
|
|
70
73
|
const actions = Store.useActions();
|
|
71
74
|
|
|
75
|
+
if (props.disableGithubCli) {
|
|
76
|
+
return <>{props.children}</>;
|
|
77
|
+
}
|
|
78
|
+
|
|
72
79
|
return (
|
|
73
80
|
<Await
|
|
74
81
|
fallback={
|
|
@@ -112,6 +119,10 @@ function CheckGithubCli(props: Props) {
|
|
|
112
119
|
function CheckGithubCliAuth(props: Props) {
|
|
113
120
|
const actions = Store.useActions();
|
|
114
121
|
|
|
122
|
+
if (props.disableGithubCliAuth) {
|
|
123
|
+
return <>{props.children}</>;
|
|
124
|
+
}
|
|
125
|
+
|
|
115
126
|
return (
|
|
116
127
|
<Await
|
|
117
128
|
fallback={
|
|
@@ -164,6 +175,10 @@ function CheckGithubCliAuth(props: Props) {
|
|
|
164
175
|
function CheckGitRevise(props: Props) {
|
|
165
176
|
const actions = Store.useActions();
|
|
166
177
|
|
|
178
|
+
if (props.disableGitRevise) {
|
|
179
|
+
return <>{props.children}</>;
|
|
180
|
+
}
|
|
181
|
+
|
|
167
182
|
return (
|
|
168
183
|
<Await
|
|
169
184
|
fallback={
|
package/src/app/SyncGithub.tsx
CHANGED
|
@@ -35,13 +35,6 @@ async function run() {
|
|
|
35
35
|
const commit_range = sync_github.commit_range;
|
|
36
36
|
const rebase_group_index = sync_github.rebase_group_index;
|
|
37
37
|
|
|
38
|
-
// immediately register abort_handler in case of ctrl+c exit
|
|
39
|
-
actions.register_abort_handler(async function abort_sync_github() {
|
|
40
|
-
actions.output(<Ink.Text color={colors.red}>🚨 Abort</Ink.Text>);
|
|
41
|
-
handle_exit();
|
|
42
|
-
return 17;
|
|
43
|
-
});
|
|
44
|
-
|
|
45
38
|
let DEFAULT_PR_BODY = "";
|
|
46
39
|
if (state.pr_template_body) {
|
|
47
40
|
DEFAULT_PR_BODY = state.pr_template_body;
|
|
@@ -52,13 +45,10 @@ async function run() {
|
|
|
52
45
|
// for all push targets in push_group_list
|
|
53
46
|
// things that can be done in parallel are grouped by numbers
|
|
54
47
|
//
|
|
55
|
-
// -----------------------------------
|
|
56
|
-
// 1 (before_push) temp mark draft
|
|
57
48
|
// --------------------------------------
|
|
58
|
-
//
|
|
49
|
+
// 1 push simultaneously to github
|
|
59
50
|
// --------------------------------------
|
|
60
51
|
// 2 create PR / edit PR
|
|
61
|
-
// 2 (after_push) undo temp mark draft
|
|
62
52
|
// --------------------------------------
|
|
63
53
|
|
|
64
54
|
try {
|
|
@@ -170,25 +160,10 @@ async function run() {
|
|
|
170
160
|
|
|
171
161
|
invariant(group.base, "group.base must exist");
|
|
172
162
|
|
|
173
|
-
// we may temporarily mark PR as a draft before editing it
|
|
174
|
-
// if it is not already a draft PR, to avoid notification spam
|
|
175
|
-
let is_temp_draft = !group.pr?.isDraft;
|
|
176
|
-
|
|
177
163
|
// before pushing reset base to master temporarily
|
|
178
164
|
// avoid accidentally pointing to orphaned parent commit
|
|
179
165
|
// should hopefully fix issues where a PR includes a bunch of commits after pushing
|
|
180
166
|
if (group.pr) {
|
|
181
|
-
if (!group.pr.isDraft) {
|
|
182
|
-
is_temp_draft = true;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (is_temp_draft) {
|
|
186
|
-
await github.pr_draft({
|
|
187
|
-
branch: group.id,
|
|
188
|
-
draft: true,
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
|
|
192
167
|
await github.pr_edit({
|
|
193
168
|
branch: group.id,
|
|
194
169
|
base: master_branch,
|
|
@@ -214,18 +189,6 @@ async function run() {
|
|
|
214
189
|
selected_url,
|
|
215
190
|
}),
|
|
216
191
|
});
|
|
217
|
-
|
|
218
|
-
// we may temporarily mark PR as a draft before editing it
|
|
219
|
-
// if it is not already a draft PR, to avoid notification spam
|
|
220
|
-
let is_temp_draft = !group.pr?.isDraft;
|
|
221
|
-
|
|
222
|
-
if (is_temp_draft) {
|
|
223
|
-
// mark pr as ready for review again
|
|
224
|
-
await github.pr_draft({
|
|
225
|
-
branch: group.id,
|
|
226
|
-
draft: false,
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
192
|
} else {
|
|
230
193
|
// create pr in github
|
|
231
194
|
const pr_url = await github.pr_create({
|
|
@@ -279,28 +242,6 @@ async function run() {
|
|
|
279
242
|
});
|
|
280
243
|
}
|
|
281
244
|
}
|
|
282
|
-
|
|
283
|
-
function handle_exit() {
|
|
284
|
-
actions.output(<Ink.Text color={colors.yellow}>Restoring PR state…</Ink.Text>);
|
|
285
|
-
|
|
286
|
-
for (const group of push_group_list) {
|
|
287
|
-
// we may temporarily mark PR as a draft before editing it
|
|
288
|
-
// if it is not already a draft PR, to avoid notification spam
|
|
289
|
-
let is_temp_draft = !group.pr?.isDraft;
|
|
290
|
-
|
|
291
|
-
// restore PR to non-draft state
|
|
292
|
-
if (is_temp_draft) {
|
|
293
|
-
github
|
|
294
|
-
.pr_draft({
|
|
295
|
-
branch: group.id,
|
|
296
|
-
draft: false,
|
|
297
|
-
})
|
|
298
|
-
.catch(actions.error);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
actions.output(<Ink.Text color={colors.yellow}>Restored PR state.</Ink.Text>);
|
|
303
|
-
}
|
|
304
245
|
}
|
|
305
246
|
|
|
306
247
|
type CommitMetadataGroup = CommitMetadata.CommitRange["group_list"][number];
|