-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.ts
134 lines (117 loc) · 4.28 KB
/
config.ts
1
2
3
4
5
6
7
8
9
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
52
53
54
55
56
57
58
59
60
61
62
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
131
132
133
134
/* eslint-disable @typescript-eslint/camelcase */
import Git from "nodegit";
import { SpecifiableGitStackedRebaseOptions } from "./options";
import { getGitConfig__internal } from "./internal";
import { nativeConfigGet } from "./native-git/config";
export const configKeyPrefix = "stackedrebase" as const;
export type ConfigKeys = typeof configKeys;
export type ConfigKey = keyof ConfigKeys;
export const configKeys = {
gpgSign: "commit.gpgSign",
autoApplyIfNeeded: `${configKeyPrefix}.autoApplyIfNeeded`,
autoSquash: "rebase.autoSquash",
autoOpenPRUrlsInBrowser: `${configKeyPrefix}.autoOpenPRUrlsInBrowser`,
ignoredBranches: `${configKeyPrefix}.ignoredBranches`,
} as const;
export async function loadGitConfig(
repo: Git.Repository,
specifiedOptions: SpecifiableGitStackedRebaseOptions
): Promise<Git.Config> {
return getGitConfig__internal in specifiedOptions
? await specifiedOptions[getGitConfig__internal]!({ GitConfig: Git.Config, repo })
: await Git.Config.openDefault();
}
/**
* DON'T FORGET TO UPDATE `_BaseOptionsForGitStackedRebase_Optional` in options.ts
*/
export type ConfigValues = {
gpgSign: boolean | undefined;
autoApplyIfNeeded: boolean | undefined;
autoSquash: boolean | undefined;
autoOpenPRUrlsInBrowser: "always" | "ask" | "never";
/**
*
* @EXPERIMENTAL
* currently only matters for `getStackedBranchesReadyForStackedPRs`;
* in future should be expanded to work across all GSR operations.
*
* ---
*
* branches to ignore in the stack.
*
* should be specified before invoking git-stacked-rebase;
* specifying when in progress / in between commands can cause undefined behavior.
*
* matches substrings, e.g. if `night` is specified,
* `nightly` will match & will be ignored.
*/
ignoredBranches: string[];
};
export const defaultConfigValues: Pick<ConfigValues, "autoOpenPRUrlsInBrowser"> = {
autoOpenPRUrlsInBrowser: "ask",
}; // TODO TS satisfies ConfigValues
export async function resolveGitConfigValues(config: Git.Config): Promise<ConfigValues> {
/**
* beware:
* libgit's Git.Config is always taking from global, and ignoring local,
* which is obviously incorrect and not what we want...
*
* this (mostly) does not matter, until a user wants to configure per-project settings,
* which wasn't needed much, until `ignoredBranches` got implemented...
*/
const [
gpgSign, //
autoApplyIfNeeded,
autoSquash,
autoOpenPRUrlsInBrowser,
ignoredBranches,
] = await Promise.all([
resolveConfigBooleanValue(config.getBool(configKeys.gpgSign)),
resolveConfigBooleanValue(config.getBool(configKeys.autoApplyIfNeeded)),
resolveConfigBooleanValue(config.getBool(configKeys.autoSquash)),
resolveAutoOpenPRUrlsInBrowserValue(config.getStringBuf(configKeys.autoOpenPRUrlsInBrowser)),
resolveConfigArrayValue(nativeConfigGet(configKeys.ignoredBranches)),
]);
const configValues: ConfigValues = {
gpgSign,
autoApplyIfNeeded,
autoSquash,
autoOpenPRUrlsInBrowser,
ignoredBranches,
};
return configValues;
}
/**
* there's a difference between a value set to false (intentionally disabled),
* vs not set at all:
* can then look thru lower level options providers, and take their value.
*
* ```
* export const handleConfigBooleanValue = (x: Promise<number>) => x.then(Boolean).catch(() => undefined);
* ```
*
* but actually, it doesn't matter here, because when we're trying to resolve (here),
* our goal is to provide a final value that will be used by the program,
* thus no `undefined`.
*
*/
//
export const resolveConfigBooleanValue = (x: Promise<number>) => x.then(Boolean).catch(() => false);
export const resolveConfigArrayValue = (x: Promise<string>): Promise<string[]> =>
x.then((x) => x.split(",")).catch(() => []);
export const resolveAutoOpenPRUrlsInBrowserValue = (
pendingConfigValue: Promise<Git.Buf>
): Promise<ConfigValues["autoOpenPRUrlsInBrowser"]> => {
const parse = (x: Git.Buf) =>
autoOpenPRUrlsInBrowserAllowedValues.includes(x.ptr as ConfigValues["autoOpenPRUrlsInBrowser"])
? (x.ptr as ConfigValues["autoOpenPRUrlsInBrowser"])
: defaultConfigValues.autoOpenPRUrlsInBrowser;
return pendingConfigValue
.then(parse) //
.catch(() => defaultConfigValues.autoOpenPRUrlsInBrowser);
};
export const autoOpenPRUrlsInBrowserAllowedValues: ConfigValues["autoOpenPRUrlsInBrowser"][] = [
"always",
"ask",
"never",
];