git-stack-cli 2.6.1 → 2.7.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 +25 -6
- package/dist/js/index.js +612 -497
- package/package.json +1 -1
- package/src/app/App.tsx +3 -0
- package/src/app/AutoUpdate.tsx +204 -168
- package/src/app/SelectCommitRanges.tsx +4 -12
- package/src/command.ts +68 -50
- package/src/commands/Config.tsx +106 -0
- package/src/index.tsx +2 -2
- package/src/types/global.d.ts +1 -1
- package/src/core/gs_short_id.ts +0 -5
package/package.json
CHANGED
package/src/app/App.tsx
CHANGED
|
@@ -17,6 +17,7 @@ import { RebaseCheck } from "~/app/RebaseCheck";
|
|
|
17
17
|
import { RequireBranch } from "~/app/RequireBranch";
|
|
18
18
|
import { Store } from "~/app/Store";
|
|
19
19
|
import { VerboseDebugInfo } from "~/app/VerboseDebugInfo";
|
|
20
|
+
import { Config } from "~/commands/Config";
|
|
20
21
|
import { Fixup } from "~/commands/Fixup";
|
|
21
22
|
import { Log } from "~/commands/Log";
|
|
22
23
|
import { Rebase } from "~/commands/Rebase";
|
|
@@ -92,6 +93,8 @@ function MaybeMain() {
|
|
|
92
93
|
return <Log />;
|
|
93
94
|
} else if (positional_list.has("update")) {
|
|
94
95
|
return <Update />;
|
|
96
|
+
} else if (positional_list.has("config")) {
|
|
97
|
+
return <Config />;
|
|
95
98
|
} else if (positional_list.has("rebase")) {
|
|
96
99
|
return (
|
|
97
100
|
<DependencyCheck>
|
package/src/app/AutoUpdate.tsx
CHANGED
|
@@ -5,6 +5,7 @@ import * as Ink from "ink-cjs";
|
|
|
5
5
|
import { Brackets } from "~/app/Brackets";
|
|
6
6
|
import { Command } from "~/app/Command";
|
|
7
7
|
import { FormatText } from "~/app/FormatText";
|
|
8
|
+
import { Url } from "~/app/Url";
|
|
8
9
|
import { YesNoPrompt } from "~/app/YesNoPrompt";
|
|
9
10
|
import { assertNever } from "~/core/assertNever";
|
|
10
11
|
import { cli } from "~/core/cli";
|
|
@@ -26,10 +27,9 @@ type Props = {
|
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
type State = {
|
|
29
|
-
|
|
30
|
+
status: "init" | "prompt" | "install" | "done";
|
|
30
31
|
local_version: null | string;
|
|
31
32
|
latest_version: null | string;
|
|
32
|
-
status: "init" | "prompt" | "install" | "done";
|
|
33
33
|
is_brew_bun_standalone: boolean;
|
|
34
34
|
};
|
|
35
35
|
|
|
@@ -44,24 +44,94 @@ export function AutoUpdate(props: Props) {
|
|
|
44
44
|
const [output, set_output] = React.useState<Array<React.ReactNode>>([]);
|
|
45
45
|
|
|
46
46
|
const [state, patch] = React.useReducer(reducer, {
|
|
47
|
-
|
|
47
|
+
status: "init",
|
|
48
48
|
local_version: null,
|
|
49
49
|
latest_version: null,
|
|
50
|
-
status: "init",
|
|
51
50
|
is_brew_bun_standalone: false,
|
|
51
|
+
|
|
52
|
+
// // debugging
|
|
53
|
+
// status: "prompt",
|
|
54
|
+
// local_version: "2.5.3",
|
|
55
|
+
// latest_version: "2.7.0",
|
|
56
|
+
// is_brew_bun_standalone: true,
|
|
52
57
|
});
|
|
53
58
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
React.useEffect(handle_init_state, []);
|
|
60
|
+
React.useEffect(handle_status, [state.latest_version]);
|
|
61
|
+
React.useEffect(handle_on_done, [state.status]);
|
|
62
|
+
|
|
63
|
+
const status = render_status();
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<React.Fragment>
|
|
67
|
+
{output}
|
|
68
|
+
{status}
|
|
69
|
+
</React.Fragment>
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
function render_status() {
|
|
73
|
+
switch (state.status) {
|
|
74
|
+
case "init":
|
|
75
|
+
return null;
|
|
76
|
+
|
|
77
|
+
case "install":
|
|
78
|
+
return null;
|
|
79
|
+
|
|
80
|
+
case "done":
|
|
81
|
+
return props.children;
|
|
82
|
+
|
|
83
|
+
case "prompt": {
|
|
84
|
+
let install_command = "";
|
|
85
|
+
if (state.is_brew_bun_standalone) {
|
|
86
|
+
install_command = "brew install magus/git-stack/git-stack";
|
|
87
|
+
} else {
|
|
88
|
+
install_command = `npm install -g ${props.name}@latest`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<YesNoPrompt
|
|
93
|
+
message={
|
|
94
|
+
<Ink.Box flexDirection="column" gap={1}>
|
|
95
|
+
<Command>{install_command}</Command>
|
|
96
|
+
<FormatText
|
|
97
|
+
wrapper={<Ink.Text color={colors.yellow} />}
|
|
98
|
+
message="Would you like to run the above command to update?"
|
|
99
|
+
/>
|
|
100
|
+
</Ink.Box>
|
|
101
|
+
}
|
|
102
|
+
onNo={() => {
|
|
103
|
+
patch({ status: "done" });
|
|
104
|
+
}}
|
|
105
|
+
onYes={async () => {
|
|
106
|
+
info(<Command>{install_command}</Command>);
|
|
107
|
+
|
|
108
|
+
patch({ status: "install" });
|
|
109
|
+
|
|
110
|
+
await cli(install_command, {
|
|
111
|
+
env: {
|
|
112
|
+
...process.env,
|
|
113
|
+
HOMEBREW_COLOR: "1",
|
|
114
|
+
},
|
|
115
|
+
onOutput: (data: string) => {
|
|
116
|
+
info(<Ink.Text>{data}</Ink.Text>);
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
info(
|
|
121
|
+
<Ink.Text key="done">
|
|
122
|
+
✅ Installed <Brackets>{state.latest_version}</Brackets>
|
|
123
|
+
</Ink.Text>,
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
patch({ status: "done" });
|
|
127
|
+
}}
|
|
128
|
+
/>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
61
131
|
}
|
|
62
132
|
}
|
|
63
133
|
|
|
64
|
-
|
|
134
|
+
function handle_on_done() {
|
|
65
135
|
switch (state.status) {
|
|
66
136
|
case "init":
|
|
67
137
|
case "prompt":
|
|
@@ -76,199 +146,165 @@ export function AutoUpdate(props: Props) {
|
|
|
76
146
|
default:
|
|
77
147
|
assertNever(state.status);
|
|
78
148
|
}
|
|
79
|
-
}
|
|
149
|
+
}
|
|
80
150
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
let latest_version: string | null = null;
|
|
84
|
-
let is_brew_bun_standalone = false;
|
|
151
|
+
function handle_init_state() {
|
|
152
|
+
init_state().catch(abort);
|
|
85
153
|
|
|
86
|
-
|
|
87
|
-
|
|
154
|
+
async function init_state() {
|
|
155
|
+
if (state.latest_version !== null) return;
|
|
88
156
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
157
|
+
const local_version = process.env.CLI_VERSION;
|
|
158
|
+
const latest_version = await get_latest_version();
|
|
159
|
+
const is_brew_bun_standalone = get_is_brew_bun_standalone();
|
|
160
|
+
patch({ local_version, latest_version, is_brew_bun_standalone });
|
|
161
|
+
}
|
|
93
162
|
|
|
163
|
+
async function get_latest_version() {
|
|
94
164
|
const timeout_ms = is_finite_value(props.timeoutMs) ? props.timeoutMs : 2 * 1000;
|
|
95
165
|
|
|
96
166
|
const npm_json = await Promise.race([
|
|
97
167
|
fetch_json(`https://registry.npmjs.org/${props.name}`),
|
|
98
168
|
|
|
99
169
|
sleep(timeout_ms).then(() => {
|
|
100
|
-
|
|
170
|
+
abort(new Error("AutoUpdate timeout"));
|
|
101
171
|
}),
|
|
102
172
|
]);
|
|
103
173
|
|
|
104
|
-
|
|
174
|
+
const maybe_version = npm_json?.["dist-tags"]?.latest;
|
|
105
175
|
|
|
106
|
-
if (
|
|
107
|
-
|
|
176
|
+
if (typeof maybe_version === "string") {
|
|
177
|
+
return maybe_version;
|
|
108
178
|
}
|
|
109
179
|
|
|
180
|
+
throw new Error("Unable to retrieve latest version from npm");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function get_is_brew_bun_standalone() {
|
|
110
184
|
const binary_path = process.argv[1];
|
|
185
|
+
debug(<Ink.Text dimColor>{JSON.stringify({ binary_path })}</Ink.Text>);
|
|
186
|
+
|
|
187
|
+
const is_bunfs_path = binary_path.startsWith("/$bunfs");
|
|
188
|
+
debug(
|
|
189
|
+
<Ink.Text dimColor>
|
|
190
|
+
{is_bunfs_path
|
|
191
|
+
? "brew install detected (compiled bun standalone)"
|
|
192
|
+
: "npm install detected"}
|
|
193
|
+
</Ink.Text>,
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
return is_bunfs_path;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function handle_status() {
|
|
201
|
+
const latest_version = state.latest_version;
|
|
202
|
+
|
|
203
|
+
if (latest_version === null) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const local_version = state.local_version;
|
|
208
|
+
|
|
209
|
+
if (!local_version) {
|
|
210
|
+
throw new Error("Auto update requires process.env.CLI_VERSION to be set");
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
debug(
|
|
214
|
+
<FormatText
|
|
215
|
+
key="versions"
|
|
216
|
+
wrapper={<Ink.Text dimColor />}
|
|
217
|
+
message="Auto update found latest version {latest_version} and current local version {local_version}"
|
|
218
|
+
values={{
|
|
219
|
+
latest_version: <Brackets>{latest_version}</Brackets>,
|
|
220
|
+
local_version: <Brackets>{local_version}</Brackets>,
|
|
221
|
+
}}
|
|
222
|
+
/>,
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
const semver_result = semver_compare(latest_version, local_version);
|
|
226
|
+
debug(<Ink.Text dimColor>{JSON.stringify({ semver_result })}</Ink.Text>);
|
|
227
|
+
|
|
228
|
+
switch (semver_result) {
|
|
229
|
+
case 0: {
|
|
230
|
+
info(
|
|
231
|
+
<Ink.Text>
|
|
232
|
+
✅ Everything up to date. <Brackets>{latest_version}</Brackets>
|
|
233
|
+
</Ink.Text>,
|
|
234
|
+
);
|
|
111
235
|
|
|
112
|
-
|
|
113
|
-
handle_output(<Ink.Text dimColor>{JSON.stringify({ binary_path })}</Ink.Text>);
|
|
236
|
+
return patch({ status: "done" });
|
|
114
237
|
}
|
|
115
238
|
|
|
116
|
-
|
|
239
|
+
case 1: {
|
|
240
|
+
const old_tag = local_version;
|
|
241
|
+
const new_tag = state.latest_version;
|
|
242
|
+
const url = `https://github.com/magus/git-stack-cli/compare/${old_tag}...${new_tag}`;
|
|
117
243
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
244
|
+
info(
|
|
245
|
+
<Ink.Box flexDirection="column" gap={1} paddingTop={1} paddingBottom={1}>
|
|
246
|
+
<Ink.Text>
|
|
247
|
+
🆕 New version available! <Brackets>{latest_version}</Brackets>
|
|
248
|
+
</Ink.Text>
|
|
249
|
+
<Ink.Box flexDirection="column">
|
|
250
|
+
<Ink.Text dimColor>Changelog</Ink.Text>
|
|
251
|
+
<Url>{url}</Url>
|
|
252
|
+
</Ink.Box>
|
|
253
|
+
</Ink.Box>,
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
return patch({ status: "prompt" });
|
|
126
257
|
}
|
|
127
258
|
|
|
128
|
-
|
|
129
|
-
|
|
259
|
+
case -1: {
|
|
260
|
+
info(
|
|
130
261
|
<FormatText
|
|
131
|
-
|
|
132
|
-
wrapper={<Ink.Text />}
|
|
133
|
-
message="Auto update found latest version {latest_version} and current local version {local_version}"
|
|
262
|
+
message="⚠️ Local version {local_version} is newer than latest version {latest_version}"
|
|
134
263
|
values={{
|
|
135
|
-
latest_version: <Brackets>{latest_version}</Brackets>,
|
|
136
264
|
local_version: <Brackets>{local_version}</Brackets>,
|
|
265
|
+
latest_version: <Brackets>{latest_version}</Brackets>,
|
|
137
266
|
}}
|
|
138
267
|
/>,
|
|
139
268
|
);
|
|
140
|
-
}
|
|
141
269
|
|
|
142
|
-
|
|
143
|
-
if (props_ref.current.verbose) {
|
|
144
|
-
handle_output(<Ink.Text dimColor>{JSON.stringify({ semver_result })}</Ink.Text>);
|
|
270
|
+
return patch({ status: "done" });
|
|
145
271
|
}
|
|
146
272
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
if (is_output) {
|
|
151
|
-
handle_output(
|
|
152
|
-
<Ink.Text>
|
|
153
|
-
✅ Everything up to date. <Brackets>{latest_version}</Brackets>
|
|
154
|
-
</Ink.Text>,
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (semver_result === 1) {
|
|
161
|
-
// trigger yes no prompt
|
|
162
|
-
status = "prompt";
|
|
273
|
+
default: {
|
|
274
|
+
assertNever(semver_result);
|
|
275
|
+
abort(new Error("AutoUpdate failed"));
|
|
163
276
|
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
164
279
|
|
|
165
|
-
|
|
280
|
+
function info(node: React.ReactNode) {
|
|
281
|
+
if (props_ref.current.verbose || props_ref.current.force) {
|
|
282
|
+
handle_output(node);
|
|
166
283
|
}
|
|
284
|
+
}
|
|
167
285
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
286
|
+
function debug(node: React.ReactNode) {
|
|
287
|
+
if (props_ref.current.verbose) {
|
|
288
|
+
handle_output(node);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
function abort(error: Error) {
|
|
292
|
+
info(
|
|
293
|
+
<Ink.Text key="error" color={colors.red}>
|
|
294
|
+
{error.message}
|
|
295
|
+
</Ink.Text>,
|
|
296
|
+
);
|
|
297
|
+
patch({ status: "done" });
|
|
298
|
+
props_ref.current.onError?.(error);
|
|
299
|
+
}
|
|
182
300
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
301
|
+
function handle_output(node: React.ReactNode) {
|
|
302
|
+
if (typeof props.onOutput === "function") {
|
|
303
|
+
props.onOutput(node);
|
|
304
|
+
} else {
|
|
305
|
+
set_output((current) => {
|
|
306
|
+
return [...current, node];
|
|
187
307
|
});
|
|
188
|
-
}, []);
|
|
189
|
-
|
|
190
|
-
const status = (function render_status() {
|
|
191
|
-
switch (state.status) {
|
|
192
|
-
case "init":
|
|
193
|
-
return null;
|
|
194
|
-
|
|
195
|
-
case "prompt": {
|
|
196
|
-
let install_command = "";
|
|
197
|
-
if (state.is_brew_bun_standalone) {
|
|
198
|
-
install_command = "brew install magus/git-stack/git-stack";
|
|
199
|
-
} else {
|
|
200
|
-
install_command = `npm install -g ${props.name}@latest`;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
return (
|
|
204
|
-
<YesNoPrompt
|
|
205
|
-
message={
|
|
206
|
-
<Ink.Box flexDirection="column">
|
|
207
|
-
<Ink.Box flexDirection="column">
|
|
208
|
-
<Ink.Text color={colors.yellow}>
|
|
209
|
-
<FormatText
|
|
210
|
-
wrapper={<Ink.Text />}
|
|
211
|
-
message="New version available {latest_version}"
|
|
212
|
-
values={{
|
|
213
|
-
latest_version: <Brackets>{state.latest_version}</Brackets>,
|
|
214
|
-
}}
|
|
215
|
-
/>
|
|
216
|
-
,
|
|
217
|
-
</Ink.Text>
|
|
218
|
-
<Ink.Text> </Ink.Text>
|
|
219
|
-
<Command>{install_command}</Command>
|
|
220
|
-
<Ink.Text> </Ink.Text>
|
|
221
|
-
</Ink.Box>
|
|
222
|
-
<Ink.Box>
|
|
223
|
-
<FormatText
|
|
224
|
-
wrapper={<Ink.Text color={colors.yellow} />}
|
|
225
|
-
message="Would you like to run the above command to update?"
|
|
226
|
-
/>
|
|
227
|
-
</Ink.Box>
|
|
228
|
-
</Ink.Box>
|
|
229
|
-
}
|
|
230
|
-
onYes={async () => {
|
|
231
|
-
handle_output(<Command>{install_command}</Command>);
|
|
232
|
-
|
|
233
|
-
patch({ status: "install" });
|
|
234
|
-
|
|
235
|
-
await cli(install_command, {
|
|
236
|
-
env: {
|
|
237
|
-
...process.env,
|
|
238
|
-
HOMEBREW_COLOR: "1",
|
|
239
|
-
},
|
|
240
|
-
onOutput: (data: string) => {
|
|
241
|
-
handle_output(<Ink.Text>{data}</Ink.Text>);
|
|
242
|
-
},
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
handle_output(
|
|
246
|
-
<Ink.Text key="done">
|
|
247
|
-
✅ Installed <Brackets>{state.latest_version}</Brackets>
|
|
248
|
-
</Ink.Text>,
|
|
249
|
-
);
|
|
250
|
-
|
|
251
|
-
patch({ status: "done" });
|
|
252
|
-
}}
|
|
253
|
-
onNo={() => {
|
|
254
|
-
patch({ status: "done" });
|
|
255
|
-
}}
|
|
256
|
-
/>
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
case "install":
|
|
261
|
-
return null;
|
|
262
|
-
|
|
263
|
-
case "done":
|
|
264
|
-
return props.children;
|
|
265
308
|
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
return (
|
|
269
|
-
<React.Fragment>
|
|
270
|
-
{output}
|
|
271
|
-
{status}
|
|
272
|
-
</React.Fragment>
|
|
273
|
-
);
|
|
309
|
+
}
|
|
274
310
|
}
|
|
@@ -10,8 +10,8 @@ import { Parens } from "~/app/Parens";
|
|
|
10
10
|
import { Store } from "~/app/Store";
|
|
11
11
|
import { TextInput } from "~/app/TextInput";
|
|
12
12
|
import { colors } from "~/core/colors";
|
|
13
|
-
import { gs_short_id } from "~/core/gs_short_id";
|
|
14
13
|
import { invariant } from "~/core/invariant";
|
|
14
|
+
import { short_id } from "~/core/short_id";
|
|
15
15
|
import { wrap_index } from "~/core/wrap_index";
|
|
16
16
|
|
|
17
17
|
import type { State } from "~/app/Store";
|
|
@@ -35,6 +35,8 @@ function SelectCommitRangesInternal(props: Props) {
|
|
|
35
35
|
const actions = Store.useActions();
|
|
36
36
|
|
|
37
37
|
const argv = Store.useState((state) => state.argv);
|
|
38
|
+
const branch_name = Store.useState((state) => state.branch_name);
|
|
39
|
+
invariant(branch_name, "branch_name must exist");
|
|
38
40
|
|
|
39
41
|
const [selected_group_id, set_selected_group_id] = React.useState(() => {
|
|
40
42
|
const first_group = props.commit_range.group_list.find(
|
|
@@ -444,17 +446,7 @@ function SelectCommitRangesInternal(props: Props) {
|
|
|
444
446
|
);
|
|
445
447
|
|
|
446
448
|
function get_group_id() {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
// branch prefix via cli flag or env var
|
|
450
|
-
// cli flag takes precedence since it is more explicit
|
|
451
|
-
if (argv["branch-prefix"]) {
|
|
452
|
-
branch_prefix = argv["branch-prefix"];
|
|
453
|
-
} else if (process.env.GIT_STACK_BRANCH_PREFIX) {
|
|
454
|
-
branch_prefix = process.env.GIT_STACK_BRANCH_PREFIX;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
return `${branch_prefix}${gs_short_id()}`;
|
|
449
|
+
return `${branch_name}-${short_id()}`;
|
|
458
450
|
}
|
|
459
451
|
|
|
460
452
|
function submit_group_input(title: string) {
|
package/src/command.ts
CHANGED
|
@@ -1,54 +1,78 @@
|
|
|
1
1
|
import yargs from "yargs";
|
|
2
2
|
import { hideBin } from "yargs/helpers";
|
|
3
3
|
|
|
4
|
-
import type { Options, InferredOptionTypes, Arguments } from "yargs";
|
|
4
|
+
import type { Options, InferredOptionTypes, Arguments, ParserConfigurationOptions } from "yargs";
|
|
5
5
|
|
|
6
6
|
export type Argv = Arguments & TGlobalOptions & TFixupOptions & TDefaultOptions;
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
type CommandOptions = {
|
|
9
|
+
env_config?: Partial<Argv>;
|
|
10
|
+
parserConfiguration?: Partial<ParserConfigurationOptions>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export async function command(argv: string[], options: CommandOptions = {}) {
|
|
9
14
|
// https://yargs.js.org/docs/#api-reference-optionkey-opt
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
15
|
+
let builder = yargs(hideBin(argv));
|
|
16
|
+
|
|
17
|
+
if (options.parserConfiguration) {
|
|
18
|
+
builder = builder.parserConfiguration(options.parserConfiguration);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// apply overrides from config
|
|
22
|
+
// higher precedence than defaults, but lower precendence than cli flags
|
|
23
|
+
// perfect since that's what we want, prefer config only if not explicitly set on cli
|
|
24
|
+
if (options.env_config) {
|
|
25
|
+
builder = builder.config(options.env_config);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const parsed = await builder
|
|
29
|
+
.scriptName("git stack")
|
|
30
|
+
.usage("Usage: git stack [command] [options]")
|
|
31
|
+
|
|
32
|
+
.command("$0", "Sync commit ranges to Github", (yargs) => yargs.options(DefaultOptions))
|
|
33
|
+
|
|
34
|
+
.command("fixup [commit]", "Amend staged changes to a specific commit in history", (yargs) =>
|
|
35
|
+
yargs.positional("commit", FixupOptions.commit),
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
.command(
|
|
39
|
+
"log [args...]",
|
|
40
|
+
"Print an abbreviated log with numbered commits, useful for git stack fixup",
|
|
41
|
+
(yargs) => yargs.strict(false),
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
.command(
|
|
45
|
+
"rebase",
|
|
46
|
+
"Update local branch via rebase with latest changes from origin master branch",
|
|
47
|
+
(yargs) => yargs,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
.command(
|
|
51
|
+
["update", "upgrade"],
|
|
52
|
+
"Check and install the latest version of git stack",
|
|
53
|
+
(yargs) => yargs,
|
|
54
|
+
)
|
|
55
|
+
.command(
|
|
56
|
+
"config",
|
|
57
|
+
"Generate a one-time configuration json based on the passed arguments",
|
|
58
|
+
(yargs) => yargs.options(DefaultOptions),
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
.option("verbose", GlobalOptions.verbose)
|
|
62
|
+
|
|
63
|
+
// yargs default wraps to 80 columns
|
|
64
|
+
// passing null will wrap to terminal width
|
|
65
|
+
// value below if what seems to look decent
|
|
66
|
+
.wrap(123)
|
|
67
|
+
|
|
68
|
+
// disallow unknown options
|
|
69
|
+
.strict()
|
|
70
|
+
.version(process.env.CLI_VERSION || "unknown")
|
|
71
|
+
.showHidden("show-hidden", "Show hidden options via `git stack help --show-hidden`")
|
|
72
|
+
.help("help", "Show usage via `git stack help`");
|
|
73
|
+
|
|
74
|
+
const result = parsed.argv as unknown as Argv;
|
|
75
|
+
return result;
|
|
52
76
|
}
|
|
53
77
|
|
|
54
78
|
const GlobalOptions = {
|
|
@@ -109,12 +133,6 @@ const DefaultOptions = {
|
|
|
109
133
|
description: "Open all PRs as drafts",
|
|
110
134
|
},
|
|
111
135
|
|
|
112
|
-
"branch-prefix": {
|
|
113
|
-
type: "string",
|
|
114
|
-
default: "",
|
|
115
|
-
description: "Prefix for generated branch names, e.g. dev/magus/",
|
|
116
|
-
},
|
|
117
|
-
|
|
118
136
|
"revise-sign": {
|
|
119
137
|
type: "boolean",
|
|
120
138
|
default: true,
|