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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-stack-cli",
3
- "version": "2.5.0",
3
+ "version": "2.5.2",
4
4
  "description": "",
5
5
  "author": "magus",
6
6
  "license": "MIT",
package/src/app/App.tsx CHANGED
@@ -61,13 +61,11 @@ export function App() {
61
61
  }}
62
62
  >
63
63
  <VerboseDebugInfo>
64
- <DependencyCheck>
65
- <RebaseCheck>
66
- <CherryPickCheck>
67
- <MaybeMain />
68
- </CherryPickCheck>
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
- <GatherMetadata>
92
- <LocalCommitStatus>
93
- <Rebase />
94
- </LocalCommitStatus>
95
- </GatherMetadata>
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
- <GatherMetadata>
105
+ <DependencyCheck>
104
106
  <DirtyCheck>
105
- <LocalCommitStatus>
106
- <DetectInitialPR>
107
- <Main />
108
- </DetectInitialPR>
109
- </LocalCommitStatus>
107
+ <GatherMetadata>
108
+ <LocalCommitStatus>
109
+ <DetectInitialPR>
110
+ <Main />
111
+ </DetectInitialPR>
112
+ </LocalCommitStatus>
113
+ </GatherMetadata>
110
114
  </DirtyCheck>
111
- </GatherMetadata>
115
+ </DependencyCheck>
112
116
  </React.Fragment>
113
117
  );
114
118
  }
@@ -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 script_path = await fs.realpath(process.argv[1]);
90
- const script_dir = path.dirname(script_path);
94
+ const binary_path = process.argv[1];
91
95
 
92
- // dist/ts/index.js
93
- const package_json_path = path.join(script_dir, "..", "..", "package.json");
96
+ if (props_ref.current.verbose) {
97
+ handle_output(<Ink.Text dimColor>{JSON.stringify({ binary_path })}</Ink.Text>);
98
+ }
94
99
 
95
- type PackageJson = { version: string };
96
- const package_json = await read_json<PackageJson>(package_json_path);
100
+ is_brew_bun_standalone = binary_path.startsWith("/$bunfs");
97
101
 
98
- if (!package_json) {
99
- // unable to find read package.json, skip auto update
100
- throw new Error(`Unable to read package.json [${package_json_path}]`);
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.Text color={colors.yellow}>
169
- New version available, would you like to update?
170
- </Ink.Text>
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(`npm install -g ${props.name}@latest`);
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={
@@ -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
- // 2 push simultaneously to github
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];