git-stack-cli 2.7.0 → 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/dist/js/index.js +222 -197
- package/package.json +1 -1
- package/src/app/AutoUpdate.tsx +204 -168
package/dist/js/index.js
CHANGED
|
@@ -31938,7 +31938,7 @@ var import_react21 = __toESM(require_react(), 1);
|
|
|
31938
31938
|
var React56 = __toESM(require_react(), 1);
|
|
31939
31939
|
|
|
31940
31940
|
// src/app/AutoUpdate.tsx
|
|
31941
|
-
var
|
|
31941
|
+
var React19 = __toESM(require_react(), 1);
|
|
31942
31942
|
|
|
31943
31943
|
// src/app/Brackets.tsx
|
|
31944
31944
|
var React10 = __toESM(require_react(), 1);
|
|
@@ -31993,24 +31993,34 @@ function FormatText(props) {
|
|
|
31993
31993
|
});
|
|
31994
31994
|
}
|
|
31995
31995
|
|
|
31996
|
+
// src/app/Url.tsx
|
|
31997
|
+
var React13 = __toESM(require_react(), 1);
|
|
31998
|
+
function Url(props) {
|
|
31999
|
+
return /* @__PURE__ */ React13.createElement(Text, {
|
|
32000
|
+
bold: true,
|
|
32001
|
+
color: colors.blue,
|
|
32002
|
+
...props
|
|
32003
|
+
}, props.children);
|
|
32004
|
+
}
|
|
32005
|
+
|
|
31996
32006
|
// src/app/YesNoPrompt.tsx
|
|
31997
|
-
var
|
|
32007
|
+
var React15 = __toESM(require_react(), 1);
|
|
31998
32008
|
|
|
31999
32009
|
// src/app/Parens.tsx
|
|
32000
|
-
var
|
|
32010
|
+
var React14 = __toESM(require_react(), 1);
|
|
32001
32011
|
function Parens(props) {
|
|
32002
32012
|
const color = colors.blue;
|
|
32003
|
-
return /* @__PURE__ */
|
|
32013
|
+
return /* @__PURE__ */ React14.createElement(Text, null, /* @__PURE__ */ React14.createElement(Text, {
|
|
32004
32014
|
color
|
|
32005
|
-
}, "("), props.children, /* @__PURE__ */
|
|
32015
|
+
}, "("), props.children, /* @__PURE__ */ React14.createElement(Text, {
|
|
32006
32016
|
color
|
|
32007
32017
|
}, ")"));
|
|
32008
32018
|
}
|
|
32009
32019
|
|
|
32010
32020
|
// src/app/YesNoPrompt.tsx
|
|
32011
32021
|
function YesNoPrompt(props) {
|
|
32012
|
-
const [answer, set_answer] =
|
|
32013
|
-
const answered_ref =
|
|
32022
|
+
const [answer, set_answer] = React15.useState("");
|
|
32023
|
+
const answered_ref = React15.useRef(false);
|
|
32014
32024
|
use_input_default((input) => {
|
|
32015
32025
|
if (answered_ref.current) {
|
|
32016
32026
|
return;
|
|
@@ -32032,11 +32042,11 @@ function YesNoPrompt(props) {
|
|
|
32032
32042
|
}
|
|
32033
32043
|
});
|
|
32034
32044
|
const choices = function get_choices() {
|
|
32035
|
-
const y3 = /* @__PURE__ */
|
|
32045
|
+
const y3 = /* @__PURE__ */ React15.createElement(Text, {
|
|
32036
32046
|
bold: true,
|
|
32037
32047
|
color: colors.green
|
|
32038
32048
|
}, "Y");
|
|
32039
|
-
const n3 = /* @__PURE__ */
|
|
32049
|
+
const n3 = /* @__PURE__ */ React15.createElement(Text, {
|
|
32040
32050
|
color: colors.red
|
|
32041
32051
|
}, "n");
|
|
32042
32052
|
switch (answer) {
|
|
@@ -32045,19 +32055,19 @@ function YesNoPrompt(props) {
|
|
|
32045
32055
|
case "n":
|
|
32046
32056
|
return n3;
|
|
32047
32057
|
default:
|
|
32048
|
-
return /* @__PURE__ */
|
|
32058
|
+
return /* @__PURE__ */ React15.createElement(FormatText, {
|
|
32049
32059
|
message: "{y}/{n}",
|
|
32050
32060
|
values: { y: y3, n: n3 }
|
|
32051
32061
|
});
|
|
32052
32062
|
}
|
|
32053
32063
|
}();
|
|
32054
|
-
return /* @__PURE__ */
|
|
32064
|
+
return /* @__PURE__ */ React15.createElement(Box_default, {
|
|
32055
32065
|
flexDirection: "column"
|
|
32056
|
-
}, /* @__PURE__ */
|
|
32066
|
+
}, /* @__PURE__ */ React15.createElement(Box_default, {
|
|
32057
32067
|
alignItems: "flex-end"
|
|
32058
|
-
}, typeof props.message === "object" ? props.message : /* @__PURE__ */
|
|
32068
|
+
}, typeof props.message === "object" ? props.message : /* @__PURE__ */ React15.createElement(Text, {
|
|
32059
32069
|
color: colors.yellow
|
|
32060
|
-
}, props.message), /* @__PURE__ */
|
|
32070
|
+
}, props.message), /* @__PURE__ */ React15.createElement(Text, null, " "), /* @__PURE__ */ React15.createElement(Parens, null, /* @__PURE__ */ React15.createElement(Text, {
|
|
32061
32071
|
color: colors.gray
|
|
32062
32072
|
}, choices))));
|
|
32063
32073
|
}
|
|
@@ -32071,7 +32081,7 @@ function assertNever(value) {
|
|
|
32071
32081
|
import * as child from "node:child_process";
|
|
32072
32082
|
|
|
32073
32083
|
// src/app/Store.tsx
|
|
32074
|
-
var
|
|
32084
|
+
var React18 = __toESM(require_react(), 1);
|
|
32075
32085
|
|
|
32076
32086
|
// node_modules/.pnpm/zustand@4.4.4_@types+react@18.2.33_immer@10.0.3_react@18.2.0/node_modules/zustand/esm/vanilla.mjs
|
|
32077
32087
|
var createStoreImpl = (createState) => {
|
|
@@ -32702,7 +32712,7 @@ var immerImpl = (initializer) => (set2, get, store) => {
|
|
|
32702
32712
|
var immer2 = immerImpl;
|
|
32703
32713
|
|
|
32704
32714
|
// src/app/Exit.tsx
|
|
32705
|
-
var
|
|
32715
|
+
var React16 = __toESM(require_react(), 1);
|
|
32706
32716
|
|
|
32707
32717
|
// src/core/sleep.ts
|
|
32708
32718
|
async function sleep(time) {
|
|
@@ -32711,7 +32721,7 @@ async function sleep(time) {
|
|
|
32711
32721
|
|
|
32712
32722
|
// src/app/Exit.tsx
|
|
32713
32723
|
function Exit(props) {
|
|
32714
|
-
|
|
32724
|
+
React16.useEffect(() => {
|
|
32715
32725
|
Exit.handle_exit(props).catch((err) => {
|
|
32716
32726
|
console.error(err);
|
|
32717
32727
|
});
|
|
@@ -32728,7 +32738,7 @@ Exit.handle_exit = async function handle_exit(props) {
|
|
|
32728
32738
|
}
|
|
32729
32739
|
if (state.is_dirty_check_stash) {
|
|
32730
32740
|
await cli("git stash pop");
|
|
32731
|
-
actions.output(/* @__PURE__ */
|
|
32741
|
+
actions.output(/* @__PURE__ */ React16.createElement(Text, {
|
|
32732
32742
|
color: colors.green
|
|
32733
32743
|
}, "✅ Changes restored from stash"));
|
|
32734
32744
|
}
|
|
@@ -32742,7 +32752,7 @@ Exit.handle_exit = async function handle_exit(props) {
|
|
|
32742
32752
|
};
|
|
32743
32753
|
|
|
32744
32754
|
// src/app/LogTimestamp.tsx
|
|
32745
|
-
var
|
|
32755
|
+
var React17 = __toESM(require_react(), 1);
|
|
32746
32756
|
|
|
32747
32757
|
// node_modules/.pnpm/luxon@3.4.4/node_modules/luxon/src/errors.js
|
|
32748
32758
|
class LuxonError extends Error {
|
|
@@ -37037,7 +37047,7 @@ function friendlyDateTime(dateTimeish) {
|
|
|
37037
37047
|
|
|
37038
37048
|
// src/app/LogTimestamp.tsx
|
|
37039
37049
|
function LogTimestamp() {
|
|
37040
|
-
return /* @__PURE__ */
|
|
37050
|
+
return /* @__PURE__ */ React17.createElement(Text, {
|
|
37041
37051
|
dimColor: true
|
|
37042
37052
|
}, DateTime.now().toFormat("[yyyy-MM-dd HH:mm:ss.SSS] "));
|
|
37043
37053
|
}
|
|
@@ -37081,7 +37091,7 @@ var BaseStore = createStore()(immer2((set2, get) => ({
|
|
|
37081
37091
|
state.exit_mode = "normal";
|
|
37082
37092
|
}
|
|
37083
37093
|
let clear = args?.clear ?? true;
|
|
37084
|
-
const node = /* @__PURE__ */
|
|
37094
|
+
const node = /* @__PURE__ */ React18.createElement(Exit, {
|
|
37085
37095
|
clear,
|
|
37086
37096
|
code
|
|
37087
37097
|
});
|
|
@@ -37109,17 +37119,17 @@ var BaseStore = createStore()(immer2((set2, get) => ({
|
|
|
37109
37119
|
error(error) {
|
|
37110
37120
|
let node;
|
|
37111
37121
|
if (typeof error === "string") {
|
|
37112
|
-
node = /* @__PURE__ */
|
|
37122
|
+
node = /* @__PURE__ */ React18.createElement(Text, {
|
|
37113
37123
|
color: colors.red
|
|
37114
37124
|
}, error);
|
|
37115
37125
|
} else if (error instanceof Error) {
|
|
37116
|
-
node = /* @__PURE__ */
|
|
37126
|
+
node = /* @__PURE__ */ React18.createElement(Box_default, {
|
|
37117
37127
|
flexDirection: "column"
|
|
37118
|
-
}, /* @__PURE__ */
|
|
37128
|
+
}, /* @__PURE__ */ React18.createElement(Text, {
|
|
37119
37129
|
color: colors.red
|
|
37120
37130
|
}, error.stack));
|
|
37121
37131
|
} else {
|
|
37122
|
-
node = /* @__PURE__ */
|
|
37132
|
+
node = /* @__PURE__ */ React18.createElement(Text, {
|
|
37123
37133
|
color: colors.red
|
|
37124
37134
|
}, `Unhandled error: ${JSON.stringify(error)}`);
|
|
37125
37135
|
}
|
|
@@ -37203,12 +37213,12 @@ function renderOutputArgs(args) {
|
|
|
37203
37213
|
case "boolean":
|
|
37204
37214
|
case "number":
|
|
37205
37215
|
case "string":
|
|
37206
|
-
output = /* @__PURE__ */
|
|
37216
|
+
output = /* @__PURE__ */ React18.createElement(Text, {
|
|
37207
37217
|
dimColor: args.debug
|
|
37208
37218
|
}, String(args.node));
|
|
37209
37219
|
}
|
|
37210
37220
|
if (args.debug) {
|
|
37211
|
-
return /* @__PURE__ */
|
|
37221
|
+
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, args.withoutTimestamp ? null : /* @__PURE__ */ React18.createElement(LogTimestamp, null), output);
|
|
37212
37222
|
}
|
|
37213
37223
|
return output;
|
|
37214
37224
|
}
|
|
@@ -37430,127 +37440,28 @@ function reducer(state, patch) {
|
|
|
37430
37440
|
return { ...state, ...patch };
|
|
37431
37441
|
}
|
|
37432
37442
|
function AutoUpdate(props) {
|
|
37433
|
-
const props_ref =
|
|
37443
|
+
const props_ref = React19.useRef(props);
|
|
37434
37444
|
props_ref.current = props;
|
|
37435
|
-
const [output, set_output] =
|
|
37436
|
-
const [state, patch] =
|
|
37437
|
-
|
|
37445
|
+
const [output, set_output] = React19.useState([]);
|
|
37446
|
+
const [state, patch] = React19.useReducer(reducer, {
|
|
37447
|
+
status: "init",
|
|
37438
37448
|
local_version: null,
|
|
37439
37449
|
latest_version: null,
|
|
37440
|
-
status: "init",
|
|
37441
37450
|
is_brew_bun_standalone: false
|
|
37442
37451
|
});
|
|
37443
|
-
|
|
37444
|
-
|
|
37445
|
-
|
|
37446
|
-
|
|
37447
|
-
|
|
37448
|
-
|
|
37449
|
-
});
|
|
37450
|
-
}
|
|
37451
|
-
}
|
|
37452
|
-
React18.useEffect(() => {
|
|
37452
|
+
React19.useEffect(handle_init_state, []);
|
|
37453
|
+
React19.useEffect(handle_status, [state.latest_version]);
|
|
37454
|
+
React19.useEffect(handle_on_done, [state.status]);
|
|
37455
|
+
const status = render_status();
|
|
37456
|
+
return /* @__PURE__ */ React19.createElement(React19.Fragment, null, output, status);
|
|
37457
|
+
function render_status() {
|
|
37453
37458
|
switch (state.status) {
|
|
37454
37459
|
case "init":
|
|
37455
|
-
|
|
37460
|
+
return null;
|
|
37456
37461
|
case "install":
|
|
37457
|
-
break;
|
|
37458
|
-
case "done": {
|
|
37459
|
-
props.onDone?.();
|
|
37460
|
-
break;
|
|
37461
|
-
}
|
|
37462
|
-
default:
|
|
37463
|
-
assertNever(state.status);
|
|
37464
|
-
}
|
|
37465
|
-
}, [state.status]);
|
|
37466
|
-
React18.useEffect(() => {
|
|
37467
|
-
let status2 = "init";
|
|
37468
|
-
let latest_version = null;
|
|
37469
|
-
let is_brew_bun_standalone = false;
|
|
37470
|
-
const local_version = "2.7.0";
|
|
37471
|
-
const is_output = props_ref.current.verbose || props_ref.current.force;
|
|
37472
|
-
async function auto_update() {
|
|
37473
|
-
if (!local_version) {
|
|
37474
|
-
throw new Error("Auto update requires process.env.CLI_VERSION to be set");
|
|
37475
|
-
}
|
|
37476
|
-
const timeout_ms = is_finite_value(props.timeoutMs) ? props.timeoutMs : 2 * 1000;
|
|
37477
|
-
const npm_json = await Promise.race([
|
|
37478
|
-
fetch_json(`https://registry.npmjs.org/${props.name}`),
|
|
37479
|
-
sleep(timeout_ms).then(() => {
|
|
37480
|
-
throw new Error("AutoUpdate timeout");
|
|
37481
|
-
})
|
|
37482
|
-
]);
|
|
37483
|
-
latest_version = npm_json?.["dist-tags"]?.latest;
|
|
37484
|
-
if (!latest_version) {
|
|
37485
|
-
throw new Error("Unable to retrieve latest version from npm");
|
|
37486
|
-
}
|
|
37487
|
-
const binary_path = process.argv[1];
|
|
37488
|
-
if (props_ref.current.verbose) {
|
|
37489
|
-
handle_output(/* @__PURE__ */ React18.createElement(Text, {
|
|
37490
|
-
dimColor: true
|
|
37491
|
-
}, JSON.stringify({ binary_path })));
|
|
37492
|
-
}
|
|
37493
|
-
is_brew_bun_standalone = binary_path.startsWith("/$bunfs");
|
|
37494
|
-
if (props_ref.current.verbose) {
|
|
37495
|
-
if (is_brew_bun_standalone) {
|
|
37496
|
-
handle_output(/* @__PURE__ */ React18.createElement(Text, {
|
|
37497
|
-
dimColor: true
|
|
37498
|
-
}, "brew install detected (compiled bun standalone)"));
|
|
37499
|
-
} else {
|
|
37500
|
-
handle_output(/* @__PURE__ */ React18.createElement(Text, {
|
|
37501
|
-
dimColor: true
|
|
37502
|
-
}, "npm install detected"));
|
|
37503
|
-
}
|
|
37504
|
-
}
|
|
37505
|
-
if (props_ref.current.verbose) {
|
|
37506
|
-
handle_output(/* @__PURE__ */ React18.createElement(FormatText, {
|
|
37507
|
-
key: "versions",
|
|
37508
|
-
wrapper: /* @__PURE__ */ React18.createElement(Text, null),
|
|
37509
|
-
message: "Auto update found latest version {latest_version} and current local version {local_version}",
|
|
37510
|
-
values: {
|
|
37511
|
-
latest_version: /* @__PURE__ */ React18.createElement(Brackets, null, latest_version),
|
|
37512
|
-
local_version: /* @__PURE__ */ React18.createElement(Brackets, null, local_version)
|
|
37513
|
-
}
|
|
37514
|
-
}));
|
|
37515
|
-
}
|
|
37516
|
-
const semver_result = semver_compare(latest_version, local_version);
|
|
37517
|
-
if (props_ref.current.verbose) {
|
|
37518
|
-
handle_output(/* @__PURE__ */ React18.createElement(Text, {
|
|
37519
|
-
dimColor: true
|
|
37520
|
-
}, JSON.stringify({ semver_result })));
|
|
37521
|
-
}
|
|
37522
|
-
if (semver_result === 0) {
|
|
37523
|
-
status2 = "done";
|
|
37524
|
-
if (is_output) {
|
|
37525
|
-
handle_output(/* @__PURE__ */ React18.createElement(Text, null, "✅ Everything up to date. ", /* @__PURE__ */ React18.createElement(Brackets, null, latest_version)));
|
|
37526
|
-
}
|
|
37527
|
-
return;
|
|
37528
|
-
}
|
|
37529
|
-
if (semver_result === 1) {
|
|
37530
|
-
status2 = "prompt";
|
|
37531
|
-
}
|
|
37532
|
-
throw new Error("AutoUpdate failed");
|
|
37533
|
-
}
|
|
37534
|
-
const onError = props_ref.current.onError || (() => {
|
|
37535
|
-
});
|
|
37536
|
-
auto_update().then(() => {
|
|
37537
|
-
patch({ status: status2, local_version, latest_version, is_brew_bun_standalone });
|
|
37538
|
-
}).catch((error) => {
|
|
37539
|
-
if (props_ref.current.verbose) {
|
|
37540
|
-
handle_output(/* @__PURE__ */ React18.createElement(Text, {
|
|
37541
|
-
key: "error",
|
|
37542
|
-
color: colors.red
|
|
37543
|
-
}, error?.message));
|
|
37544
|
-
}
|
|
37545
|
-
status2 = "done";
|
|
37546
|
-
patch({ status: status2, error, local_version, latest_version, is_brew_bun_standalone });
|
|
37547
|
-
onError(error);
|
|
37548
|
-
});
|
|
37549
|
-
}, []);
|
|
37550
|
-
const status = function render_status() {
|
|
37551
|
-
switch (state.status) {
|
|
37552
|
-
case "init":
|
|
37553
37462
|
return null;
|
|
37463
|
+
case "done":
|
|
37464
|
+
return props.children;
|
|
37554
37465
|
case "prompt": {
|
|
37555
37466
|
let install_command = "";
|
|
37556
37467
|
if (state.is_brew_bun_standalone) {
|
|
@@ -37558,27 +37469,21 @@ function AutoUpdate(props) {
|
|
|
37558
37469
|
} else {
|
|
37559
37470
|
install_command = `npm install -g ${props.name}@latest`;
|
|
37560
37471
|
}
|
|
37561
|
-
return /* @__PURE__ */
|
|
37562
|
-
message: /* @__PURE__ */
|
|
37563
|
-
flexDirection: "column"
|
|
37564
|
-
|
|
37565
|
-
|
|
37566
|
-
|
|
37567
|
-
color: colors.yellow
|
|
37568
|
-
}, /* @__PURE__ */ React18.createElement(FormatText, {
|
|
37569
|
-
wrapper: /* @__PURE__ */ React18.createElement(Text, null),
|
|
37570
|
-
message: "New version available {latest_version}",
|
|
37571
|
-
values: {
|
|
37572
|
-
latest_version: /* @__PURE__ */ React18.createElement(Brackets, null, state.latest_version)
|
|
37573
|
-
}
|
|
37574
|
-
}), ","), /* @__PURE__ */ React18.createElement(Text, null, " "), /* @__PURE__ */ React18.createElement(Command, null, install_command), /* @__PURE__ */ React18.createElement(Text, null, " ")), /* @__PURE__ */ React18.createElement(Box_default, null, /* @__PURE__ */ React18.createElement(FormatText, {
|
|
37575
|
-
wrapper: /* @__PURE__ */ React18.createElement(Text, {
|
|
37472
|
+
return /* @__PURE__ */ React19.createElement(YesNoPrompt, {
|
|
37473
|
+
message: /* @__PURE__ */ React19.createElement(Box_default, {
|
|
37474
|
+
flexDirection: "column",
|
|
37475
|
+
gap: 1
|
|
37476
|
+
}, /* @__PURE__ */ React19.createElement(Command, null, install_command), /* @__PURE__ */ React19.createElement(FormatText, {
|
|
37477
|
+
wrapper: /* @__PURE__ */ React19.createElement(Text, {
|
|
37576
37478
|
color: colors.yellow
|
|
37577
37479
|
}),
|
|
37578
37480
|
message: "Would you like to run the above command to update?"
|
|
37579
|
-
}))
|
|
37481
|
+
})),
|
|
37482
|
+
onNo: () => {
|
|
37483
|
+
patch({ status: "done" });
|
|
37484
|
+
},
|
|
37580
37485
|
onYes: async () => {
|
|
37581
|
-
|
|
37486
|
+
info(/* @__PURE__ */ React19.createElement(Command, null, install_command));
|
|
37582
37487
|
patch({ status: "install" });
|
|
37583
37488
|
await cli(install_command, {
|
|
37584
37489
|
env: {
|
|
@@ -37586,34 +37491,164 @@ function AutoUpdate(props) {
|
|
|
37586
37491
|
HOMEBREW_COLOR: "1"
|
|
37587
37492
|
},
|
|
37588
37493
|
onOutput: (data) => {
|
|
37589
|
-
|
|
37494
|
+
info(/* @__PURE__ */ React19.createElement(Text, null, data));
|
|
37590
37495
|
}
|
|
37591
37496
|
});
|
|
37592
|
-
|
|
37497
|
+
info(/* @__PURE__ */ React19.createElement(Text, {
|
|
37593
37498
|
key: "done"
|
|
37594
|
-
}, "✅ Installed ", /* @__PURE__ */
|
|
37595
|
-
patch({ status: "done" });
|
|
37596
|
-
},
|
|
37597
|
-
onNo: () => {
|
|
37499
|
+
}, "✅ Installed ", /* @__PURE__ */ React19.createElement(Brackets, null, state.latest_version)));
|
|
37598
37500
|
patch({ status: "done" });
|
|
37599
37501
|
}
|
|
37600
37502
|
});
|
|
37601
37503
|
}
|
|
37504
|
+
}
|
|
37505
|
+
}
|
|
37506
|
+
function handle_on_done() {
|
|
37507
|
+
switch (state.status) {
|
|
37508
|
+
case "init":
|
|
37509
|
+
case "prompt":
|
|
37602
37510
|
case "install":
|
|
37603
|
-
|
|
37604
|
-
case "done":
|
|
37605
|
-
|
|
37511
|
+
break;
|
|
37512
|
+
case "done": {
|
|
37513
|
+
props.onDone?.();
|
|
37514
|
+
break;
|
|
37515
|
+
}
|
|
37516
|
+
default:
|
|
37517
|
+
assertNever(state.status);
|
|
37606
37518
|
}
|
|
37607
|
-
}
|
|
37608
|
-
|
|
37519
|
+
}
|
|
37520
|
+
function handle_init_state() {
|
|
37521
|
+
init_state().catch(abort);
|
|
37522
|
+
async function init_state() {
|
|
37523
|
+
if (state.latest_version !== null)
|
|
37524
|
+
return;
|
|
37525
|
+
const local_version = "2.7.1";
|
|
37526
|
+
const latest_version = await get_latest_version();
|
|
37527
|
+
const is_brew_bun_standalone = get_is_brew_bun_standalone();
|
|
37528
|
+
patch({ local_version, latest_version, is_brew_bun_standalone });
|
|
37529
|
+
}
|
|
37530
|
+
async function get_latest_version() {
|
|
37531
|
+
const timeout_ms = is_finite_value(props.timeoutMs) ? props.timeoutMs : 2 * 1000;
|
|
37532
|
+
const npm_json = await Promise.race([
|
|
37533
|
+
fetch_json(`https://registry.npmjs.org/${props.name}`),
|
|
37534
|
+
sleep(timeout_ms).then(() => {
|
|
37535
|
+
abort(new Error("AutoUpdate timeout"));
|
|
37536
|
+
})
|
|
37537
|
+
]);
|
|
37538
|
+
const maybe_version = npm_json?.["dist-tags"]?.latest;
|
|
37539
|
+
if (typeof maybe_version === "string") {
|
|
37540
|
+
return maybe_version;
|
|
37541
|
+
}
|
|
37542
|
+
throw new Error("Unable to retrieve latest version from npm");
|
|
37543
|
+
}
|
|
37544
|
+
function get_is_brew_bun_standalone() {
|
|
37545
|
+
const binary_path = process.argv[1];
|
|
37546
|
+
debug(/* @__PURE__ */ React19.createElement(Text, {
|
|
37547
|
+
dimColor: true
|
|
37548
|
+
}, JSON.stringify({ binary_path })));
|
|
37549
|
+
const is_bunfs_path = binary_path.startsWith("/$bunfs");
|
|
37550
|
+
debug(/* @__PURE__ */ React19.createElement(Text, {
|
|
37551
|
+
dimColor: true
|
|
37552
|
+
}, is_bunfs_path ? "brew install detected (compiled bun standalone)" : "npm install detected"));
|
|
37553
|
+
return is_bunfs_path;
|
|
37554
|
+
}
|
|
37555
|
+
}
|
|
37556
|
+
function handle_status() {
|
|
37557
|
+
const latest_version = state.latest_version;
|
|
37558
|
+
if (latest_version === null) {
|
|
37559
|
+
return;
|
|
37560
|
+
}
|
|
37561
|
+
const local_version = state.local_version;
|
|
37562
|
+
if (!local_version) {
|
|
37563
|
+
throw new Error("Auto update requires process.env.CLI_VERSION to be set");
|
|
37564
|
+
}
|
|
37565
|
+
debug(/* @__PURE__ */ React19.createElement(FormatText, {
|
|
37566
|
+
key: "versions",
|
|
37567
|
+
wrapper: /* @__PURE__ */ React19.createElement(Text, {
|
|
37568
|
+
dimColor: true
|
|
37569
|
+
}),
|
|
37570
|
+
message: "Auto update found latest version {latest_version} and current local version {local_version}",
|
|
37571
|
+
values: {
|
|
37572
|
+
latest_version: /* @__PURE__ */ React19.createElement(Brackets, null, latest_version),
|
|
37573
|
+
local_version: /* @__PURE__ */ React19.createElement(Brackets, null, local_version)
|
|
37574
|
+
}
|
|
37575
|
+
}));
|
|
37576
|
+
const semver_result = semver_compare(latest_version, local_version);
|
|
37577
|
+
debug(/* @__PURE__ */ React19.createElement(Text, {
|
|
37578
|
+
dimColor: true
|
|
37579
|
+
}, JSON.stringify({ semver_result })));
|
|
37580
|
+
switch (semver_result) {
|
|
37581
|
+
case 0: {
|
|
37582
|
+
info(/* @__PURE__ */ React19.createElement(Text, null, "✅ Everything up to date. ", /* @__PURE__ */ React19.createElement(Brackets, null, latest_version)));
|
|
37583
|
+
return patch({ status: "done" });
|
|
37584
|
+
}
|
|
37585
|
+
case 1: {
|
|
37586
|
+
const old_tag = local_version;
|
|
37587
|
+
const new_tag = state.latest_version;
|
|
37588
|
+
const url = `https://github.com/magus/git-stack-cli/compare/${old_tag}...${new_tag}`;
|
|
37589
|
+
info(/* @__PURE__ */ React19.createElement(Box_default, {
|
|
37590
|
+
flexDirection: "column",
|
|
37591
|
+
gap: 1,
|
|
37592
|
+
paddingTop: 1,
|
|
37593
|
+
paddingBottom: 1
|
|
37594
|
+
}, /* @__PURE__ */ React19.createElement(Text, null, "\uD83C\uDD95 New version available! ", /* @__PURE__ */ React19.createElement(Brackets, null, latest_version)), /* @__PURE__ */ React19.createElement(Box_default, {
|
|
37595
|
+
flexDirection: "column"
|
|
37596
|
+
}, /* @__PURE__ */ React19.createElement(Text, {
|
|
37597
|
+
dimColor: true
|
|
37598
|
+
}, "Changelog"), /* @__PURE__ */ React19.createElement(Url, null, url))));
|
|
37599
|
+
return patch({ status: "prompt" });
|
|
37600
|
+
}
|
|
37601
|
+
case -1: {
|
|
37602
|
+
info(/* @__PURE__ */ React19.createElement(FormatText, {
|
|
37603
|
+
message: "⚠️ Local version {local_version} is newer than latest version {latest_version}",
|
|
37604
|
+
values: {
|
|
37605
|
+
local_version: /* @__PURE__ */ React19.createElement(Brackets, null, local_version),
|
|
37606
|
+
latest_version: /* @__PURE__ */ React19.createElement(Brackets, null, latest_version)
|
|
37607
|
+
}
|
|
37608
|
+
}));
|
|
37609
|
+
return patch({ status: "done" });
|
|
37610
|
+
}
|
|
37611
|
+
default: {
|
|
37612
|
+
assertNever(semver_result);
|
|
37613
|
+
abort(new Error("AutoUpdate failed"));
|
|
37614
|
+
}
|
|
37615
|
+
}
|
|
37616
|
+
}
|
|
37617
|
+
function info(node) {
|
|
37618
|
+
if (props_ref.current.verbose || props_ref.current.force) {
|
|
37619
|
+
handle_output(node);
|
|
37620
|
+
}
|
|
37621
|
+
}
|
|
37622
|
+
function debug(node) {
|
|
37623
|
+
if (props_ref.current.verbose) {
|
|
37624
|
+
handle_output(node);
|
|
37625
|
+
}
|
|
37626
|
+
}
|
|
37627
|
+
function abort(error) {
|
|
37628
|
+
info(/* @__PURE__ */ React19.createElement(Text, {
|
|
37629
|
+
key: "error",
|
|
37630
|
+
color: colors.red
|
|
37631
|
+
}, error.message));
|
|
37632
|
+
patch({ status: "done" });
|
|
37633
|
+
props_ref.current.onError?.(error);
|
|
37634
|
+
}
|
|
37635
|
+
function handle_output(node) {
|
|
37636
|
+
if (typeof props.onOutput === "function") {
|
|
37637
|
+
props.onOutput(node);
|
|
37638
|
+
} else {
|
|
37639
|
+
set_output((current2) => {
|
|
37640
|
+
return [...current2, node];
|
|
37641
|
+
});
|
|
37642
|
+
}
|
|
37643
|
+
}
|
|
37609
37644
|
}
|
|
37610
37645
|
|
|
37611
37646
|
// src/app/CherryPickCheck.tsx
|
|
37612
|
-
var
|
|
37647
|
+
var React21 = __toESM(require_react(), 1);
|
|
37613
37648
|
import path from "node:path";
|
|
37614
37649
|
|
|
37615
37650
|
// src/app/Await.tsx
|
|
37616
|
-
var
|
|
37651
|
+
var React20 = __toESM(require_react(), 1);
|
|
37617
37652
|
|
|
37618
37653
|
// src/core/cache.ts
|
|
37619
37654
|
function cache3(cacheable) {
|
|
@@ -37661,8 +37696,8 @@ function invariant(condition, message) {
|
|
|
37661
37696
|
|
|
37662
37697
|
// src/app/Await.tsx
|
|
37663
37698
|
function Await(props) {
|
|
37664
|
-
const [display_fallback, set_display_fallback] =
|
|
37665
|
-
const cacheRef =
|
|
37699
|
+
const [display_fallback, set_display_fallback] = React20.useState(false);
|
|
37700
|
+
const cacheRef = React20.useRef(null);
|
|
37666
37701
|
if (!cacheRef.current) {
|
|
37667
37702
|
cacheRef.current = cache3(props.function);
|
|
37668
37703
|
}
|
|
@@ -37672,7 +37707,7 @@ function Await(props) {
|
|
|
37672
37707
|
} else {
|
|
37673
37708
|
delayFallbackMs = 1000;
|
|
37674
37709
|
}
|
|
37675
|
-
|
|
37710
|
+
React20.useEffect(() => {
|
|
37676
37711
|
const cache4 = cacheRef.current;
|
|
37677
37712
|
if (!cache4) {
|
|
37678
37713
|
return;
|
|
@@ -37689,13 +37724,13 @@ function Await(props) {
|
|
|
37689
37724
|
}, [delayFallbackMs]);
|
|
37690
37725
|
invariant(cacheRef.current, "cache must exist");
|
|
37691
37726
|
if ("fallback" in props) {
|
|
37692
|
-
return /* @__PURE__ */
|
|
37727
|
+
return /* @__PURE__ */ React20.createElement(React20.Suspense, {
|
|
37693
37728
|
fallback: !display_fallback ? null : props.fallback
|
|
37694
|
-
}, /* @__PURE__ */
|
|
37729
|
+
}, /* @__PURE__ */ React20.createElement(ReadCache, {
|
|
37695
37730
|
cache: cacheRef.current
|
|
37696
37731
|
}, props.children));
|
|
37697
37732
|
}
|
|
37698
|
-
return /* @__PURE__ */
|
|
37733
|
+
return /* @__PURE__ */ React20.createElement(ReadCache, {
|
|
37699
37734
|
cache: cacheRef.current
|
|
37700
37735
|
});
|
|
37701
37736
|
}
|
|
@@ -37721,17 +37756,17 @@ function reducer2(state, patch) {
|
|
|
37721
37756
|
}
|
|
37722
37757
|
function CherryPickCheck(props) {
|
|
37723
37758
|
const actions = Store.useActions();
|
|
37724
|
-
const [state, patch] =
|
|
37759
|
+
const [state, patch] = React21.useReducer(reducer2, {
|
|
37725
37760
|
status: "init"
|
|
37726
37761
|
});
|
|
37727
37762
|
switch (state.status) {
|
|
37728
37763
|
case "done":
|
|
37729
37764
|
return props.children;
|
|
37730
37765
|
case "prompt":
|
|
37731
|
-
return /* @__PURE__ */
|
|
37732
|
-
message: /* @__PURE__ */
|
|
37766
|
+
return /* @__PURE__ */ React21.createElement(YesNoPrompt, {
|
|
37767
|
+
message: /* @__PURE__ */ React21.createElement(Text, {
|
|
37733
37768
|
color: colors.yellow
|
|
37734
|
-
}, /* @__PURE__ */
|
|
37769
|
+
}, /* @__PURE__ */ React21.createElement(Command, null, "git cherry-pick"), " detected, would you like to abort it?"),
|
|
37735
37770
|
onYes: async () => {
|
|
37736
37771
|
await cli(`git cherry-pick --abort`);
|
|
37737
37772
|
patch({ status: "done" });
|
|
@@ -37741,11 +37776,11 @@ function CherryPickCheck(props) {
|
|
|
37741
37776
|
}
|
|
37742
37777
|
});
|
|
37743
37778
|
default:
|
|
37744
|
-
return /* @__PURE__ */
|
|
37779
|
+
return /* @__PURE__ */ React21.createElement(Await, {
|
|
37745
37780
|
function: run,
|
|
37746
|
-
fallback: /* @__PURE__ */
|
|
37781
|
+
fallback: /* @__PURE__ */ React21.createElement(Text, {
|
|
37747
37782
|
color: colors.yellow
|
|
37748
|
-
}, "Checking for ", /* @__PURE__ */
|
|
37783
|
+
}, "Checking for ", /* @__PURE__ */ React21.createElement(Command, null, "git cherry-pick"), "…")
|
|
37749
37784
|
});
|
|
37750
37785
|
}
|
|
37751
37786
|
async function run() {
|
|
@@ -37771,7 +37806,7 @@ function CherryPickCheck(props) {
|
|
|
37771
37806
|
}
|
|
37772
37807
|
|
|
37773
37808
|
// src/app/Debug.tsx
|
|
37774
|
-
var
|
|
37809
|
+
var React22 = __toESM(require_react(), 1);
|
|
37775
37810
|
import fs4 from "node:fs/promises";
|
|
37776
37811
|
import path2 from "node:path";
|
|
37777
37812
|
|
|
@@ -37824,14 +37859,14 @@ function Debug() {
|
|
|
37824
37859
|
const state = Store.useState((state2) => state2);
|
|
37825
37860
|
const argv = Store.useState((state2) => state2.argv);
|
|
37826
37861
|
const debug = Store.useState((state2) => state2.select.debug(state2));
|
|
37827
|
-
|
|
37862
|
+
React22.useEffect(function debugMessageOnce() {
|
|
37828
37863
|
if (debug) {
|
|
37829
|
-
actions.output(/* @__PURE__ */
|
|
37864
|
+
actions.output(/* @__PURE__ */ React22.createElement(Text, {
|
|
37830
37865
|
color: colors.yellow
|
|
37831
37866
|
}, "Debug mode enabled"));
|
|
37832
37867
|
}
|
|
37833
37868
|
}, [argv]);
|
|
37834
|
-
|
|
37869
|
+
React22.useEffect(function sync_state_json() {
|
|
37835
37870
|
if (!argv?.["write-state-json"]) {
|
|
37836
37871
|
return;
|
|
37837
37872
|
}
|
|
@@ -37850,16 +37885,6 @@ function Debug() {
|
|
|
37850
37885
|
// src/app/DependencyCheck.tsx
|
|
37851
37886
|
var React23 = __toESM(require_react(), 1);
|
|
37852
37887
|
|
|
37853
|
-
// src/app/Url.tsx
|
|
37854
|
-
var React22 = __toESM(require_react(), 1);
|
|
37855
|
-
function Url(props) {
|
|
37856
|
-
return /* @__PURE__ */ React22.createElement(Text, {
|
|
37857
|
-
bold: true,
|
|
37858
|
-
color: colors.blue,
|
|
37859
|
-
...props
|
|
37860
|
-
}, props.children);
|
|
37861
|
-
}
|
|
37862
|
-
|
|
37863
37888
|
// src/core/is_command_available.ts
|
|
37864
37889
|
import fs5 from "node:fs";
|
|
37865
37890
|
import path3 from "node:path";
|
|
@@ -45537,7 +45562,7 @@ async function command2(argv, options = {}) {
|
|
|
45537
45562
|
if (options.env_config) {
|
|
45538
45563
|
builder = builder.config(options.env_config);
|
|
45539
45564
|
}
|
|
45540
|
-
const parsed = await builder.scriptName("git stack").usage("Usage: git stack [command] [options]").command("$0", "Sync commit ranges to Github", (yargs) => yargs.options(DefaultOptions)).command("fixup [commit]", "Amend staged changes to a specific commit in history", (yargs) => yargs.positional("commit", FixupOptions.commit)).command("log [args...]", "Print an abbreviated log with numbered commits, useful for git stack fixup", (yargs) => yargs.strict(false)).command("rebase", "Update local branch via rebase with latest changes from origin master branch", (yargs) => yargs).command(["update", "upgrade"], "Check and install the latest version of git stack", (yargs) => yargs).command("config", "Generate a one-time configuration json based on the passed arguments", (yargs) => yargs.options(DefaultOptions)).option("verbose", GlobalOptions.verbose).wrap(123).strict().version("2.7.
|
|
45565
|
+
const parsed = await builder.scriptName("git stack").usage("Usage: git stack [command] [options]").command("$0", "Sync commit ranges to Github", (yargs) => yargs.options(DefaultOptions)).command("fixup [commit]", "Amend staged changes to a specific commit in history", (yargs) => yargs.positional("commit", FixupOptions.commit)).command("log [args...]", "Print an abbreviated log with numbered commits, useful for git stack fixup", (yargs) => yargs.strict(false)).command("rebase", "Update local branch via rebase with latest changes from origin master branch", (yargs) => yargs).command(["update", "upgrade"], "Check and install the latest version of git stack", (yargs) => yargs).command("config", "Generate a one-time configuration json based on the passed arguments", (yargs) => yargs.options(DefaultOptions)).option("verbose", GlobalOptions.verbose).wrap(123).strict().version("2.7.1").showHidden("show-hidden", "Show hidden options via `git stack help --show-hidden`").help("help", "Show usage via `git stack help`");
|
|
45541
45566
|
const result = parsed.argv;
|
|
45542
45567
|
return result;
|
|
45543
45568
|
}
|
package/package.json
CHANGED
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
|
}
|