git-stack-cli 1.0.6 → 1.1.0
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 +4 -7
- package/dist/cjs/index.cjs +355 -129
- package/package.json +4 -4
- package/{rollup.config.mjs → rollup.config.js} +11 -3
- package/scripts/git-sequence-editor.sh +35 -0
- package/scripts/release-brew.ts +7 -1
- package/src/app/DependencyCheck.tsx +150 -95
- package/src/app/LocalMergeRebase.tsx +1 -4
- package/src/app/ManualRebase.tsx +221 -87
- package/src/app/SelectCommitRanges.tsx +1 -0
- package/src/app/Store.tsx +14 -2
- package/src/command.ts +6 -0
- package/src/core/GitReviseTodo.test.ts +572 -0
- package/src/core/GitReviseTodo.ts +79 -0
- package/src/types/global.d.ts +2 -0
|
@@ -12,10 +12,16 @@ import replace from "@rollup/plugin-replace";
|
|
|
12
12
|
import typescript from "@rollup/plugin-typescript";
|
|
13
13
|
|
|
14
14
|
const SCRIPT_DIR = path.dirname(url.fileURLToPath(import.meta.url));
|
|
15
|
+
|
|
15
16
|
const PACKAGE_JSON_PATH = path.join(SCRIPT_DIR, "package.json");
|
|
17
|
+
const PACKAGE_JSON = JSON.parse(await fs.readFile(PACKAGE_JSON_PATH, "utf-8"));
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
+
// prettier-ignore
|
|
20
|
+
const GIT_SEQUENCE_EDITOR_SCRIPT_PATH = path.join(SCRIPT_DIR, "scripts", "git-sequence-editor.sh");
|
|
21
|
+
// prettier-ignore
|
|
22
|
+
const UNSAFE_GIT_SEQUENCE_EDITOR_SCRIPT = await fs.readFile(GIT_SEQUENCE_EDITOR_SCRIPT_PATH, "utf-8");
|
|
23
|
+
// prettier-ignore
|
|
24
|
+
const GIT_SEQUENCE_EDITOR_SCRIPT = UNSAFE_GIT_SEQUENCE_EDITOR_SCRIPT.replace(/`/g, "\\`");
|
|
19
25
|
|
|
20
26
|
export default {
|
|
21
27
|
input: "src/index.tsx",
|
|
@@ -39,7 +45,9 @@ export default {
|
|
|
39
45
|
preventAssignment: true,
|
|
40
46
|
values: {
|
|
41
47
|
"process.env.NODE_ENV": JSON.stringify("production"),
|
|
42
|
-
"process.env.CLI_VERSION": JSON.stringify(String(
|
|
48
|
+
"process.env.CLI_VERSION": JSON.stringify(String(PACKAGE_JSON.version)),
|
|
49
|
+
"process.env.GIT_STACK_STANDALONE": process.env.GIT_STACK_STANDALONE,
|
|
50
|
+
"process.env.GIT_SEQUENCE_EDITOR_SCRIPT": GIT_SEQUENCE_EDITOR_SCRIPT,
|
|
43
51
|
},
|
|
44
52
|
}),
|
|
45
53
|
],
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
# Example
|
|
4
|
+
#
|
|
5
|
+
# GIT_REVISE_TODO="abc" GIT_EDITOR="$(pwd)/scripts/git-sequence-editor.sh" git revise --edit -i head~4
|
|
6
|
+
#
|
|
7
|
+
# Note
|
|
8
|
+
# ----------------
|
|
9
|
+
# Use `GIT_EDITOR` above instead of `GIT_SEQUENCE_EDITOR` because `git revise` does not use
|
|
10
|
+
# `GIT_SEQUENCE_EDITOR` when passing the `--edit` flag, but does work without the `--edit` flag
|
|
11
|
+
#
|
|
12
|
+
#
|
|
13
|
+
|
|
14
|
+
# debug print env variables
|
|
15
|
+
echo "GIT_REVISE_TODO=$GIT_REVISE_TODO"
|
|
16
|
+
echo "CLI=$0 $*"
|
|
17
|
+
echo "PWD=$(pwd)"
|
|
18
|
+
|
|
19
|
+
# ensure `GIT_REVISE_TODO` is not empty
|
|
20
|
+
if [ -z "$GIT_REVISE_TODO" ]; then
|
|
21
|
+
echo "🚨 GIT_REVISE_TODO environment variable is empty" >&2
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# first argument into git sequence editor is git-revise-todo file
|
|
26
|
+
git_revise_todo_path="$1"
|
|
27
|
+
|
|
28
|
+
# debug print git-revise-todo file passed into command
|
|
29
|
+
echo "$git_revise_todo_path"
|
|
30
|
+
echo "----- START -----"
|
|
31
|
+
cat "$git_revise_todo_path"
|
|
32
|
+
echo "------ END ------"
|
|
33
|
+
|
|
34
|
+
# write content of `GIT_REVISE_TODO` env variable to `git_revise_todo_path`
|
|
35
|
+
echo "$GIT_REVISE_TODO" > "$git_revise_todo_path"
|
package/scripts/release-brew.ts
CHANGED
|
@@ -108,7 +108,13 @@ await spawn.sync(`git push`);
|
|
|
108
108
|
|
|
109
109
|
// commmit changes to main repo
|
|
110
110
|
process.chdir(PROJECT_DIR);
|
|
111
|
-
await spawn.sync(
|
|
111
|
+
await spawn.sync([
|
|
112
|
+
"git",
|
|
113
|
+
"commit",
|
|
114
|
+
"-a",
|
|
115
|
+
"-m",
|
|
116
|
+
`homebrew-git-stack ${version}`,
|
|
117
|
+
]);
|
|
112
118
|
await spawn.sync(`git push`);
|
|
113
119
|
|
|
114
120
|
console.debug();
|
|
@@ -10,7 +10,6 @@ import { Url } from "~/app/Url";
|
|
|
10
10
|
import { cli } from "~/core/cli";
|
|
11
11
|
import { colors } from "~/core/colors";
|
|
12
12
|
import { is_command_available } from "~/core/is_command_available";
|
|
13
|
-
import { semver_compare } from "~/core/semver_compare";
|
|
14
13
|
import * as gh from "~/github/gh";
|
|
15
14
|
|
|
16
15
|
type Props = {
|
|
@@ -18,6 +17,21 @@ type Props = {
|
|
|
18
17
|
};
|
|
19
18
|
|
|
20
19
|
export function DependencyCheck(props: Props) {
|
|
20
|
+
return (
|
|
21
|
+
<CheckGit>
|
|
22
|
+
<CheckGithubCli>
|
|
23
|
+
<CheckGithubCliAuth>
|
|
24
|
+
<CheckGitRevise>
|
|
25
|
+
{/* force line break */}
|
|
26
|
+
{props.children}
|
|
27
|
+
</CheckGitRevise>
|
|
28
|
+
</CheckGithubCliAuth>
|
|
29
|
+
</CheckGithubCli>
|
|
30
|
+
</CheckGit>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function CheckGit(props: Props) {
|
|
21
35
|
const actions = Store.useActions();
|
|
22
36
|
|
|
23
37
|
return (
|
|
@@ -46,106 +60,147 @@ export function DependencyCheck(props: Props) {
|
|
|
46
60
|
actions.exit(2);
|
|
47
61
|
}}
|
|
48
62
|
>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
63
|
+
{props.children}
|
|
64
|
+
</Await>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function CheckGithubCli(props: Props) {
|
|
69
|
+
const actions = Store.useActions();
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<Await
|
|
73
|
+
fallback={
|
|
74
|
+
<Ink.Text color={colors.yellow}>
|
|
75
|
+
<Ink.Text>
|
|
76
|
+
Checking <Command>gh</Command> install...
|
|
53
77
|
</Ink.Text>
|
|
78
|
+
</Ink.Text>
|
|
79
|
+
}
|
|
80
|
+
function={async () => {
|
|
81
|
+
if (is_command_available("gh")) {
|
|
82
|
+
return;
|
|
54
83
|
}
|
|
55
|
-
function={async () => {
|
|
56
|
-
const process_version = process.version.substring(1);
|
|
57
|
-
const semver_result = semver_compare(process_version, "14.0.0");
|
|
58
84
|
|
|
59
|
-
|
|
85
|
+
actions.output(
|
|
86
|
+
<Ink.Text color={colors.yellow}>
|
|
87
|
+
<Command>gh</Command> must be installed.
|
|
88
|
+
</Ink.Text>
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
actions.output(
|
|
92
|
+
<Ink.Text color={colors.yellow}>
|
|
93
|
+
<Ink.Text>{"Visit "}</Ink.Text>
|
|
94
|
+
<Url>https://cli.github.com</Url>
|
|
95
|
+
<Ink.Text>{" to install the github cli "}</Ink.Text>
|
|
96
|
+
|
|
97
|
+
<Parens>
|
|
98
|
+
<Command>gh</Command>
|
|
99
|
+
</Parens>
|
|
100
|
+
</Ink.Text>
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
actions.exit(3);
|
|
104
|
+
}}
|
|
105
|
+
>
|
|
106
|
+
{props.children}
|
|
107
|
+
</Await>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function CheckGithubCliAuth(props: Props) {
|
|
112
|
+
const actions = Store.useActions();
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<Await
|
|
116
|
+
fallback={
|
|
117
|
+
<Ink.Text color={colors.yellow}>
|
|
118
|
+
<Ink.Text>
|
|
119
|
+
Checking <Command>gh auth status</Command>...
|
|
120
|
+
</Ink.Text>
|
|
121
|
+
</Ink.Text>
|
|
122
|
+
}
|
|
123
|
+
function={async () => {
|
|
124
|
+
const options = { ignoreExitCode: true };
|
|
125
|
+
const auth_status = await cli(`gh auth status`, options);
|
|
126
|
+
|
|
127
|
+
if (auth_status.code === 0) {
|
|
128
|
+
const username = gh.auth_status(auth_status.stdout);
|
|
129
|
+
|
|
130
|
+
if (username) {
|
|
131
|
+
actions.set((state) => {
|
|
132
|
+
state.username = username;
|
|
133
|
+
});
|
|
134
|
+
|
|
60
135
|
return;
|
|
61
136
|
}
|
|
137
|
+
}
|
|
62
138
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (actions.isDebug()) {
|
|
131
|
-
actions.error("gh auth status could not find username");
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
actions.output(
|
|
135
|
-
<Ink.Text color={colors.yellow}>
|
|
136
|
-
<Command>gh</Command>
|
|
137
|
-
<Ink.Text>{" requires login, please run "}</Ink.Text>
|
|
138
|
-
<Command>gh auth login</Command>
|
|
139
|
-
</Ink.Text>
|
|
140
|
-
);
|
|
141
|
-
|
|
142
|
-
actions.exit(4);
|
|
143
|
-
}}
|
|
144
|
-
>
|
|
145
|
-
{props.children}
|
|
146
|
-
</Await>
|
|
147
|
-
</Await>
|
|
148
|
-
</Await>
|
|
139
|
+
if (actions.isDebug()) {
|
|
140
|
+
actions.error("gh auth status could not find username");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
actions.output(
|
|
144
|
+
<Ink.Text color={colors.yellow}>
|
|
145
|
+
<Command>gh</Command>
|
|
146
|
+
<Ink.Text>{" requires login, please run "}</Ink.Text>
|
|
147
|
+
<Command>gh auth login</Command>
|
|
148
|
+
</Ink.Text>
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
actions.exit(4);
|
|
152
|
+
}}
|
|
153
|
+
>
|
|
154
|
+
{props.children}
|
|
155
|
+
</Await>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function CheckGitRevise(props: Props) {
|
|
160
|
+
const actions = Store.useActions();
|
|
161
|
+
const argv = Store.useState((state) => state.argv);
|
|
162
|
+
|
|
163
|
+
// skip git revise check when `--git-revise` flag is not present
|
|
164
|
+
if (!argv?.["git-revise"]) {
|
|
165
|
+
return props.children;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return (
|
|
169
|
+
<Await
|
|
170
|
+
fallback={
|
|
171
|
+
<Ink.Text color={colors.yellow}>
|
|
172
|
+
<Ink.Text>
|
|
173
|
+
Checking <Command>git-revise</Command> install...
|
|
174
|
+
</Ink.Text>
|
|
175
|
+
</Ink.Text>
|
|
176
|
+
}
|
|
177
|
+
function={async () => {
|
|
178
|
+
if (is_command_available("git-revise")) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
actions.output(
|
|
183
|
+
<Ink.Text color={colors.yellow}>
|
|
184
|
+
<Command>git-revise</Command> must be installed.
|
|
185
|
+
</Ink.Text>
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
actions.output(
|
|
189
|
+
<Ink.Text color={colors.yellow}>
|
|
190
|
+
<Ink.Text>{"Visit "}</Ink.Text>
|
|
191
|
+
<Url>https://github.com/mystor/git-revise#install</Url>
|
|
192
|
+
<Ink.Text>{" to install the git revise cli "}</Ink.Text>
|
|
193
|
+
|
|
194
|
+
<Parens>
|
|
195
|
+
<Command>git-revise</Command>
|
|
196
|
+
</Parens>
|
|
197
|
+
</Ink.Text>
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
actions.exit(10);
|
|
201
|
+
}}
|
|
202
|
+
>
|
|
203
|
+
{props.children}
|
|
149
204
|
</Await>
|
|
150
205
|
);
|
|
151
206
|
}
|
|
@@ -112,10 +112,7 @@ async function run() {
|
|
|
112
112
|
|
|
113
113
|
let new_message;
|
|
114
114
|
if (commit.branch_id) {
|
|
115
|
-
new_message =
|
|
116
|
-
commit.full_message,
|
|
117
|
-
commit.branch_id
|
|
118
|
-
);
|
|
115
|
+
new_message = Metadata.write(commit.full_message, commit.branch_id);
|
|
119
116
|
} else {
|
|
120
117
|
new_message = commit.full_message;
|
|
121
118
|
}
|