git-stack-cli 1.0.5 → 1.0.6
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 +1 -1
- package/dist/cjs/index.cjs +38 -14
- package/package.json +1 -1
- package/scripts/release-brew.ts +15 -13
- package/src/app/DependencyCheck.tsx +14 -18
- package/src/core/match_group.ts +8 -0
- package/src/github/gh.auth_status.test.ts +24 -0
- package/src/github/gh.ts +19 -0
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ Often pushing all your commits to a single pull request is the simplest and fast
|
|
|
44
44
|
This comes at a price, your teammates have to review larger, less related pieces of code and you will lose some of your atomic commit history if you "Squash and merge".
|
|
45
45
|
|
|
46
46
|
When you decide to break changes up into multiple diffs that depend on one another this process is commonly referred to as **[stacked diffs](https://graphite.dev/guides/stacked-diffs)** (pull requests that depend on other pull requests).
|
|
47
|
-
This
|
|
47
|
+
This approach is popular at many major companies such as Twitter, Facebook, etc.
|
|
48
48
|
Managing stacked diffs manually involves managing multiple local branches, jumping between them, rebasing, etc.
|
|
49
49
|
This process gets even more complicated when you start getting feedback in code review and have to update individual branches.
|
|
50
50
|
Managing even a few stacked diffs requires a relatively strong knowledge of `git`, even with tricks like [`--update-refs`](https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---update-refs).
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -26846,6 +26846,30 @@ function match_group(value, re, group) {
|
|
|
26846
26846
|
invariant(result, `match.groups must contain [${group}] ${debug}`);
|
|
26847
26847
|
return result;
|
|
26848
26848
|
}
|
|
26849
|
+
match_group.safe = (value, re, group) => {
|
|
26850
|
+
try {
|
|
26851
|
+
return match_group(value, re, group);
|
|
26852
|
+
}
|
|
26853
|
+
catch (err) {
|
|
26854
|
+
return null;
|
|
26855
|
+
}
|
|
26856
|
+
};
|
|
26857
|
+
|
|
26858
|
+
function auth_status(output) {
|
|
26859
|
+
let username;
|
|
26860
|
+
username = match_group.safe(output, RE$4.logged_in_as, "username");
|
|
26861
|
+
if (username)
|
|
26862
|
+
return username;
|
|
26863
|
+
username = match_group.safe(output, RE$4.logged_in_account, "username");
|
|
26864
|
+
if (username)
|
|
26865
|
+
return username;
|
|
26866
|
+
return null;
|
|
26867
|
+
}
|
|
26868
|
+
const RE$4 = {
|
|
26869
|
+
// Logged in to github.com as magus
|
|
26870
|
+
logged_in_as: /Logged in to github.com as (?<username>[^\s]+)/,
|
|
26871
|
+
logged_in_account: /Logged in to github.com account (?<username>[^\s]+)/,
|
|
26872
|
+
};
|
|
26849
26873
|
|
|
26850
26874
|
function DependencyCheck(props) {
|
|
26851
26875
|
const actions = Store.useActions();
|
|
@@ -26903,15 +26927,19 @@ function DependencyCheck(props) {
|
|
|
26903
26927
|
"Checking ",
|
|
26904
26928
|
reactExports.createElement(Command, null, "gh auth status"),
|
|
26905
26929
|
"...")), function: async () => {
|
|
26906
|
-
const
|
|
26907
|
-
|
|
26908
|
-
|
|
26909
|
-
|
|
26910
|
-
|
|
26911
|
-
|
|
26912
|
-
|
|
26913
|
-
|
|
26914
|
-
|
|
26930
|
+
const options = { ignoreExitCode: true };
|
|
26931
|
+
const auth_status$1 = await cli(`gh auth status`, options);
|
|
26932
|
+
if (auth_status$1.code === 0) {
|
|
26933
|
+
const username = auth_status(auth_status$1.stdout);
|
|
26934
|
+
if (username) {
|
|
26935
|
+
actions.set((state) => {
|
|
26936
|
+
state.username = username;
|
|
26937
|
+
});
|
|
26938
|
+
return;
|
|
26939
|
+
}
|
|
26940
|
+
}
|
|
26941
|
+
if (actions.isDebug()) {
|
|
26942
|
+
actions.error("gh auth status could not find username");
|
|
26915
26943
|
}
|
|
26916
26944
|
actions.output(reactExports.createElement(Text, { color: colors.yellow },
|
|
26917
26945
|
reactExports.createElement(Command, null, "gh"),
|
|
@@ -26920,10 +26948,6 @@ function DependencyCheck(props) {
|
|
|
26920
26948
|
actions.exit(4);
|
|
26921
26949
|
} }, props.children)))));
|
|
26922
26950
|
}
|
|
26923
|
-
const RE$4 = {
|
|
26924
|
-
// Logged in to github.com as magus
|
|
26925
|
-
auth_username: /Logged in to github.com as (?<username>[^\s]+)/,
|
|
26926
|
-
};
|
|
26927
26951
|
|
|
26928
26952
|
function GatherMetadata(props) {
|
|
26929
26953
|
const argv = Store.useState((state) => state.argv);
|
|
@@ -34080,7 +34104,7 @@ async function command() {
|
|
|
34080
34104
|
.wrap(null)
|
|
34081
34105
|
// disallow unknown options
|
|
34082
34106
|
.strict()
|
|
34083
|
-
.version("1.0.
|
|
34107
|
+
.version("1.0.6" )
|
|
34084
34108
|
.showHidden("show-hidden", "Show hidden options via `git stack help --show-hidden`")
|
|
34085
34109
|
.help("help", "Show usage via `git stack help`").argv);
|
|
34086
34110
|
}
|
package/package.json
CHANGED
package/scripts/release-brew.ts
CHANGED
|
@@ -50,7 +50,7 @@ previous_formula = previous_formula.replace(
|
|
|
50
50
|
);
|
|
51
51
|
|
|
52
52
|
await file.write_text(
|
|
53
|
-
path.join(HOMEBREW_DIR, "Formula", `git-stack@${previous_version}`),
|
|
53
|
+
path.join(HOMEBREW_DIR, "Formula", `git-stack@${previous_version}.rb`),
|
|
54
54
|
previous_formula
|
|
55
55
|
);
|
|
56
56
|
|
|
@@ -94,20 +94,22 @@ core = core.replace(re_token("linux_sha256"), linux_asset.sha256);
|
|
|
94
94
|
|
|
95
95
|
await file.write_text(path.join("Formula", "git-stack.core.rb"), core);
|
|
96
96
|
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
// finally upload the assets to the github release
|
|
98
|
+
process.chdir(STANDALONE_DIR);
|
|
99
|
+
await spawn.sync(`gh release upload ${version} ${linux_asset.filepath}`);
|
|
100
|
+
await spawn.sync(`gh release upload ${version} ${macos_asset.filepath}`);
|
|
101
|
+
await spawn.sync(`gh release upload ${version} ${win_asset.filepath}`);
|
|
100
102
|
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
// commit homebrew repo changes
|
|
104
|
+
process.chdir(HOMEBREW_DIR);
|
|
105
|
+
await spawn.sync(`git add .`);
|
|
106
|
+
await spawn.sync(`git commit -m ${version}`);
|
|
107
|
+
await spawn.sync(`git push`);
|
|
105
108
|
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
// await spawn.sync(`gh release upload ${version} ${win_asset.filepath}`);
|
|
109
|
+
// commmit changes to main repo
|
|
110
|
+
process.chdir(PROJECT_DIR);
|
|
111
|
+
await spawn.sync(`git commit -a -m "homebrew-git-stack ${version}"`);
|
|
112
|
+
await spawn.sync(`git push`);
|
|
111
113
|
|
|
112
114
|
console.debug();
|
|
113
115
|
console.debug("✅", "published", version);
|
|
@@ -10,8 +10,8 @@ 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 { match_group } from "~/core/match_group";
|
|
14
13
|
import { semver_compare } from "~/core/semver_compare";
|
|
14
|
+
import * as gh from "~/github/gh";
|
|
15
15
|
|
|
16
16
|
type Props = {
|
|
17
17
|
children: React.ReactNode;
|
|
@@ -112,22 +112,23 @@ export function DependencyCheck(props: Props) {
|
|
|
112
112
|
</Ink.Text>
|
|
113
113
|
}
|
|
114
114
|
function={async () => {
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
});
|
|
115
|
+
const options = { ignoreExitCode: true };
|
|
116
|
+
const auth_status = await cli(`gh auth status`, options);
|
|
118
117
|
|
|
119
118
|
if (auth_status.code === 0) {
|
|
120
|
-
const username =
|
|
121
|
-
auth_status.stdout,
|
|
122
|
-
RE.auth_username,
|
|
123
|
-
"username"
|
|
124
|
-
);
|
|
119
|
+
const username = gh.auth_status(auth_status.stdout);
|
|
125
120
|
|
|
126
|
-
|
|
127
|
-
state
|
|
128
|
-
|
|
121
|
+
if (username) {
|
|
122
|
+
actions.set((state) => {
|
|
123
|
+
state.username = username;
|
|
124
|
+
});
|
|
129
125
|
|
|
130
|
-
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (actions.isDebug()) {
|
|
131
|
+
actions.error("gh auth status could not find username");
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
actions.output(
|
|
@@ -148,8 +149,3 @@ export function DependencyCheck(props: Props) {
|
|
|
148
149
|
</Await>
|
|
149
150
|
);
|
|
150
151
|
}
|
|
151
|
-
|
|
152
|
-
const RE = {
|
|
153
|
-
// Logged in to github.com as magus
|
|
154
|
-
auth_username: /Logged in to github.com as (?<username>[^\s]+)/,
|
|
155
|
-
};
|
package/src/core/match_group.ts
CHANGED
|
@@ -8,3 +8,11 @@ export function match_group(value: string, re: RegExp, group: string) {
|
|
|
8
8
|
invariant(result, `match.groups must contain [${group}] ${debug}`);
|
|
9
9
|
return result;
|
|
10
10
|
}
|
|
11
|
+
|
|
12
|
+
match_group.safe = (value: string, re: RegExp, group: string) => {
|
|
13
|
+
try {
|
|
14
|
+
return match_group(value, re, group);
|
|
15
|
+
} catch (err) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { test, expect } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import * as gh from "./gh";
|
|
4
|
+
|
|
5
|
+
test("logged in as", () => {
|
|
6
|
+
const username = gh.auth_status(
|
|
7
|
+
" ✓ Logged in to github.com as magus (keyring)\n"
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
expect(username).toBe("magus");
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test("logged in without as", () => {
|
|
14
|
+
const username = gh.auth_status(
|
|
15
|
+
"✓ Logged in to github.com account xoxohorses (keyring)"
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
expect(username).toBe("xoxohorses");
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("returns null when no match is found", () => {
|
|
22
|
+
const username = gh.auth_status("this should not match anything");
|
|
23
|
+
expect(username).toBe(null);
|
|
24
|
+
});
|
package/src/github/gh.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { match_group } from "~/core/match_group";
|
|
2
|
+
|
|
3
|
+
export function auth_status(output: string) {
|
|
4
|
+
let username;
|
|
5
|
+
|
|
6
|
+
username = match_group.safe(output, RE.logged_in_as, "username");
|
|
7
|
+
if (username) return username;
|
|
8
|
+
|
|
9
|
+
username = match_group.safe(output, RE.logged_in_account, "username");
|
|
10
|
+
if (username) return username;
|
|
11
|
+
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const RE = {
|
|
16
|
+
// Logged in to github.com as magus
|
|
17
|
+
logged_in_as: /Logged in to github.com as (?<username>[^\s]+)/,
|
|
18
|
+
logged_in_account: /Logged in to github.com account (?<username>[^\s]+)/,
|
|
19
|
+
};
|