@forceuser/git-profile-switcher 0.1.4
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 +96 -0
- package/bin/gip.mjs +25 -0
- package/dist/runtime/app/index.js +677 -0
- package/dist/runtime/cli/completion.js +142 -0
- package/dist/runtime/cli/help.js +288 -0
- package/dist/runtime/cli/parse.js +41 -0
- package/dist/runtime/cli/prompts.js +389 -0
- package/dist/runtime/config/paths.js +39 -0
- package/dist/runtime/git/config.js +188 -0
- package/dist/runtime/profiles/repository.js +183 -0
- package/dist/runtime/profiles/transfer.js +111 -0
- package/dist/runtime/profiles/types.js +23 -0
- package/dist/runtime/prompt/status.js +103 -0
- package/dist/runtime/shell/integration.js +254 -0
- package/dist/runtime/tui/index.js +604 -0
- package/package.json +105 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { getHelpCommandFlags, getHelpCommandNames } from "#cli/help";
|
|
2
|
+
import { PROFILE_PROMPT_COLORS } from "#profiles/types";
|
|
3
|
+
const COMMANDS = getHelpCommandNames();
|
|
4
|
+
const GLOBAL_FLAGS = ["--help"];
|
|
5
|
+
const SHELLS = ["bash", "fish", "zsh"];
|
|
6
|
+
const PROMPT_FORMATS = ["auto", "identity", "profile"];
|
|
7
|
+
const PROMPT_COLOR_CLEAR_VALUES = ["no-color", "none", "default"];
|
|
8
|
+
const INSTALL_GROUPS = ["all", "completion", "prompt", "shell"];
|
|
9
|
+
export function generateCompletionScript(shell) {
|
|
10
|
+
if (shell === "bash") {
|
|
11
|
+
return `# git-profile-switcher bash completion
|
|
12
|
+
_gip_completion() {
|
|
13
|
+
local suggestions
|
|
14
|
+
suggestions="$(gip __complete --shell bash -- "\${COMP_WORDS[@]:1}")"
|
|
15
|
+
COMPREPLY=($(compgen -W "$suggestions" -- "\${COMP_WORDS[COMP_CWORD]}"))
|
|
16
|
+
}
|
|
17
|
+
complete -F _gip_completion gip git-profile-switcher
|
|
18
|
+
`;
|
|
19
|
+
}
|
|
20
|
+
if (shell === "fish") {
|
|
21
|
+
return `# git-profile-switcher fish completion
|
|
22
|
+
complete -c gip -f -a '(gip __complete --shell fish -- (commandline -opc)[2..-1])'
|
|
23
|
+
complete -c git-profile-switcher -f -a '(git-profile-switcher __complete --shell fish -- (commandline -opc)[2..-1])'
|
|
24
|
+
`;
|
|
25
|
+
}
|
|
26
|
+
return `#compdef gip git-profile-switcher
|
|
27
|
+
# git-profile-switcher zsh completion
|
|
28
|
+
_gip() {
|
|
29
|
+
local -a suggestions
|
|
30
|
+
suggestions=("\${(@f)$(gip __complete --shell zsh -- \${words[@]:1})}")
|
|
31
|
+
compadd -- "\${suggestions[@]}"
|
|
32
|
+
}
|
|
33
|
+
compdef _gip gip git-profile-switcher
|
|
34
|
+
`;
|
|
35
|
+
}
|
|
36
|
+
export async function buildCompletionSuggestions(runtime, words) {
|
|
37
|
+
const rawCommand = words[0];
|
|
38
|
+
const command = normalizeCompletionCommand(rawCommand);
|
|
39
|
+
if (!rawCommand || !isKnownCommand(command)) {
|
|
40
|
+
return uniqueSorted([...COMMANDS, ...GLOBAL_FLAGS]);
|
|
41
|
+
}
|
|
42
|
+
if (words.includes("--")) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
const valueFlag = findValueFlagNeedingCompletion(words);
|
|
46
|
+
if (valueFlag) {
|
|
47
|
+
return completeFlagValue(command, valueFlag);
|
|
48
|
+
}
|
|
49
|
+
const positionalWords = words.slice(1).filter((word) => !word.startsWith("-"));
|
|
50
|
+
const positionalSuggestions = await completePositionalValue(runtime, command, positionalWords);
|
|
51
|
+
if (positionalSuggestions.length > 0) {
|
|
52
|
+
return uniqueSorted(positionalSuggestions);
|
|
53
|
+
}
|
|
54
|
+
return uniqueSorted([...getHelpCommandFlags(command), ...GLOBAL_FLAGS]);
|
|
55
|
+
}
|
|
56
|
+
function normalizeCompletionCommand(command) {
|
|
57
|
+
return command;
|
|
58
|
+
}
|
|
59
|
+
async function completePositionalValue(runtime, command, positionalWords) {
|
|
60
|
+
if (!command) {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
if (command === "install") {
|
|
64
|
+
if (positionalWords.length <= 1) {
|
|
65
|
+
return [...INSTALL_GROUPS, ...SHELLS];
|
|
66
|
+
}
|
|
67
|
+
if (INSTALL_GROUPS.includes(positionalWords[0])) {
|
|
68
|
+
return positionalWords.length === 2 ? [...SHELLS] : [];
|
|
69
|
+
}
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
if (command === "completion" ||
|
|
73
|
+
command === "install:all" ||
|
|
74
|
+
command === "install:completion" ||
|
|
75
|
+
command === "install:prompt" ||
|
|
76
|
+
command === "install:shell" ||
|
|
77
|
+
command === "uninstall:all" ||
|
|
78
|
+
command === "uninstall:completion" ||
|
|
79
|
+
command === "uninstall:prompt" ||
|
|
80
|
+
command === "uninstall:shell" ||
|
|
81
|
+
command === "update") {
|
|
82
|
+
return positionalWords.length <= 1 ? [...SHELLS] : [];
|
|
83
|
+
}
|
|
84
|
+
if (command === "use" || command === "now" || command === "profile:remove") {
|
|
85
|
+
return positionalWords.length <= 1 ? completeProfiles(runtime) : [];
|
|
86
|
+
}
|
|
87
|
+
if (command === "profile:color") {
|
|
88
|
+
if (positionalWords.length <= 1) {
|
|
89
|
+
return completeProfiles(runtime);
|
|
90
|
+
}
|
|
91
|
+
if (positionalWords.length === 2) {
|
|
92
|
+
return [...PROMPT_COLOR_CLEAR_VALUES, ...PROFILE_PROMPT_COLORS];
|
|
93
|
+
}
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
if (command === "rule:add") {
|
|
97
|
+
return positionalWords.length <= 1 ? completeProfiles(runtime) : [];
|
|
98
|
+
}
|
|
99
|
+
if (command === "rule:remove") {
|
|
100
|
+
return positionalWords.length <= 1 ? completeRules(runtime) : [];
|
|
101
|
+
}
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
function completeFlagValue(command, flag) {
|
|
105
|
+
if (!command) {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
if (flag === "--format" &&
|
|
109
|
+
(command === "prompt" ||
|
|
110
|
+
command === "install" ||
|
|
111
|
+
command === "install:all" ||
|
|
112
|
+
command === "install:prompt" ||
|
|
113
|
+
command === "update")) {
|
|
114
|
+
return [...PROMPT_FORMATS];
|
|
115
|
+
}
|
|
116
|
+
if (flag === "--shell") {
|
|
117
|
+
return [...SHELLS];
|
|
118
|
+
}
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
async function completeProfiles(runtime) {
|
|
122
|
+
const data = await runtime.repository.read();
|
|
123
|
+
return data.profiles.map((profile) => profile.name);
|
|
124
|
+
}
|
|
125
|
+
async function completeRules(runtime) {
|
|
126
|
+
const data = await runtime.repository.read();
|
|
127
|
+
return data.rules.map((rule) => rule.id);
|
|
128
|
+
}
|
|
129
|
+
function findValueFlagNeedingCompletion(words) {
|
|
130
|
+
const previous = words.at(-2);
|
|
131
|
+
const current = words.at(-1);
|
|
132
|
+
if (previous?.startsWith("--") && !current?.startsWith("-")) {
|
|
133
|
+
return previous;
|
|
134
|
+
}
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
function isKnownCommand(command) {
|
|
138
|
+
return Boolean(command && (COMMANDS.includes(command) || command === "__complete"));
|
|
139
|
+
}
|
|
140
|
+
function uniqueSorted(values) {
|
|
141
|
+
return [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
142
|
+
}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
export const COMMANDS = [
|
|
2
|
+
{
|
|
3
|
+
name: "profile:add",
|
|
4
|
+
summary: "Create or update a Git identity profile.",
|
|
5
|
+
usage: "gip profile:add [profile] [--user-name <name>] [--user-email <email>]",
|
|
6
|
+
completionFlags: ["--user-name", "--user-email", "--help"],
|
|
7
|
+
examples: [
|
|
8
|
+
"gip profile:add",
|
|
9
|
+
'gip profile:add work --user-name "Work Name" --user-email work@example.com',
|
|
10
|
+
'gip profile:add personal --user-name "Personal Name" --user-email me@example.com',
|
|
11
|
+
],
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: "profile:list",
|
|
15
|
+
summary: "List saved Git identity profiles.",
|
|
16
|
+
usage: "gip profile:list [--json]",
|
|
17
|
+
completionFlags: ["--json", "--help"],
|
|
18
|
+
examples: ["gip profile:list", "gip profile:list --json"],
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "profile:remove",
|
|
22
|
+
summary: "Remove a profile and its directory rules.",
|
|
23
|
+
usage: "gip profile:remove <profile>",
|
|
24
|
+
completionFlags: ["--help"],
|
|
25
|
+
examples: ["gip profile:remove old-work"],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: "profile:color",
|
|
29
|
+
summary: "Set or clear the shell prompt color for a profile.",
|
|
30
|
+
usage: "gip profile:color [profile] [color|no-color]",
|
|
31
|
+
completionFlags: ["--help"],
|
|
32
|
+
examples: [
|
|
33
|
+
"gip profile:color",
|
|
34
|
+
"gip profile:color work cyan",
|
|
35
|
+
"gip profile:color work no-color",
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "rule:add",
|
|
40
|
+
summary: "Map a profile to a directory tree.",
|
|
41
|
+
usage: "gip rule:add [profile] [directory]",
|
|
42
|
+
completionFlags: ["--help"],
|
|
43
|
+
examples: [
|
|
44
|
+
"gip rule:add",
|
|
45
|
+
"gip rule:add ~/Developer/Work",
|
|
46
|
+
"gip rule:add work ~/Developer/Work",
|
|
47
|
+
"gip apply",
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: "rule:list",
|
|
52
|
+
summary: "List directory rules.",
|
|
53
|
+
usage: "gip rule:list [--json]",
|
|
54
|
+
completionFlags: ["--json", "--help"],
|
|
55
|
+
examples: ["gip rule:list"],
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: "rule:remove",
|
|
59
|
+
summary: "Remove a directory rule.",
|
|
60
|
+
usage: "gip rule:remove <rule-id>",
|
|
61
|
+
completionFlags: ["--help"],
|
|
62
|
+
examples: ["gip rule:remove rule_abc123"],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: "use",
|
|
66
|
+
summary: "Assign a profile to the current directory and apply Git config.",
|
|
67
|
+
usage: "gip use [profile] [directory] [--global|-g]",
|
|
68
|
+
completionFlags: ["--global", "-g", "--help"],
|
|
69
|
+
examples: [
|
|
70
|
+
"gip use",
|
|
71
|
+
"gip use work",
|
|
72
|
+
"gip use personal ~/Developer/personal-app",
|
|
73
|
+
"gip use work --global",
|
|
74
|
+
"gip use -g",
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: "now",
|
|
79
|
+
summary: "Use a profile only in the current shell session.",
|
|
80
|
+
usage: "gip now [profile] [--clear] [--exports] [--shell <zsh|bash|fish>]",
|
|
81
|
+
completionFlags: ["--clear", "--exports", "--shell", "--help"],
|
|
82
|
+
examples: [
|
|
83
|
+
"gip now work",
|
|
84
|
+
"gip now --clear",
|
|
85
|
+
'eval "$(gip now work --exports)"',
|
|
86
|
+
"gip now work --exports --shell fish",
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: "clear",
|
|
91
|
+
summary: "Clear a directory profile rule or the global Git identity.",
|
|
92
|
+
usage: "gip clear [directory] [--global|-g]",
|
|
93
|
+
completionFlags: ["--global", "-g", "--help"],
|
|
94
|
+
examples: ["gip clear", "gip clear ~/Developer/Work", "gip clear --global", "gip clear -g"],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "apply",
|
|
98
|
+
summary: "Write generated profile gitconfigs and the managed includeIf block.",
|
|
99
|
+
usage: "gip apply",
|
|
100
|
+
completionFlags: ["--help"],
|
|
101
|
+
examples: ["gip apply"],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: "export",
|
|
105
|
+
summary: "Export profiles and directory rules for migration.",
|
|
106
|
+
usage: "gip export [--output <path>] [--profiles-only]\n gip export <path>",
|
|
107
|
+
completionFlags: ["--output", "--profiles-only", "--help"],
|
|
108
|
+
examples: [
|
|
109
|
+
"gip export",
|
|
110
|
+
"gip export --profiles-only",
|
|
111
|
+
"gip export --output ./gip-profiles.backup.json",
|
|
112
|
+
"gip export ./gip.json",
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: "import",
|
|
117
|
+
summary: "Import profiles and directory rules from a migration file.",
|
|
118
|
+
usage: "gip import [--input <path>] [--replace] [--profiles-only] [--no-apply]\n gip import <path>",
|
|
119
|
+
completionFlags: ["--input", "--replace", "--profiles-only", "--no-apply", "--help"],
|
|
120
|
+
examples: [
|
|
121
|
+
"gip import",
|
|
122
|
+
"gip import --input ./gip-profiles.backup.json",
|
|
123
|
+
"gip import --profiles-only",
|
|
124
|
+
"gip import ./gip.json --replace",
|
|
125
|
+
"gip import ./gip.json --no-apply",
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: "doctor",
|
|
130
|
+
summary: "Explain the effective identity for a directory.",
|
|
131
|
+
usage: "gip doctor [cwd] [--json]",
|
|
132
|
+
completionFlags: ["--json", "--help"],
|
|
133
|
+
examples: ["gip doctor", "gip doctor ~/Developer/Work/app --json"],
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: "prompt",
|
|
137
|
+
summary: "Print the current Git identity for shell prompts.",
|
|
138
|
+
usage: "gip prompt [--json] [--format identity|profile|auto] [--profile]",
|
|
139
|
+
completionFlags: ["--json", "--format", "--profile", "--help"],
|
|
140
|
+
examples: [
|
|
141
|
+
"gip prompt",
|
|
142
|
+
"gip prompt --format identity",
|
|
143
|
+
"gip prompt --format profile",
|
|
144
|
+
"gip prompt --format auto",
|
|
145
|
+
"gip prompt --profile",
|
|
146
|
+
"gip prompt --json",
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: "install:prompt",
|
|
151
|
+
summary: "Install managed shell prompt integration.",
|
|
152
|
+
usage: "gip install:prompt [zsh|bash|fish] [--format identity|profile|auto] [--profile] [--config <path>]",
|
|
153
|
+
completionFlags: ["--format", "--profile", "--config", "--help"],
|
|
154
|
+
examples: [
|
|
155
|
+
"gip install:prompt zsh",
|
|
156
|
+
"gip install:prompt zsh --format identity",
|
|
157
|
+
"gip install:prompt zsh --format profile",
|
|
158
|
+
"gip install:prompt zsh --format auto",
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
name: "install:all",
|
|
163
|
+
summary: "Install all managed shell integrations.",
|
|
164
|
+
usage: "gip install:all [zsh|bash|fish] [--shell <zsh|bash|fish>] [--config <path>] [--format identity|profile|auto] [--profile]",
|
|
165
|
+
completionFlags: ["--shell", "--config", "--format", "--profile", "--help"],
|
|
166
|
+
examples: ["gip install:all zsh", "gip install all zsh", "gip install --shell zsh"],
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: "install",
|
|
170
|
+
summary: "Install the package globally and configure shell integrations.",
|
|
171
|
+
usage: "gip install [zsh|bash|fish] [--shell <zsh|bash|fish>] [--config <path>]\n gip install <all|completion|shell|prompt> [zsh|bash|fish] [--config <path>]",
|
|
172
|
+
completionFlags: ["--shell", "--config", "--path", "--format", "--profile", "--help"],
|
|
173
|
+
examples: [
|
|
174
|
+
"gip install",
|
|
175
|
+
"gip install zsh",
|
|
176
|
+
"gip install all zsh",
|
|
177
|
+
"gip install completion zsh",
|
|
178
|
+
"gip install shell zsh",
|
|
179
|
+
],
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
name: "update",
|
|
183
|
+
summary: "Update the global package and refresh shell integrations.",
|
|
184
|
+
usage: "gip update [zsh|bash|fish] [--shell <zsh|bash|fish>] [--config <path>] [--format identity|profile|auto] [--profile]",
|
|
185
|
+
completionFlags: ["--shell", "--config", "--path", "--format", "--profile", "--help"],
|
|
186
|
+
examples: ["gip update", "gip update zsh", "gip update --shell zsh"],
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: "uninstall:prompt",
|
|
190
|
+
summary: "Remove managed shell prompt integration.",
|
|
191
|
+
usage: "gip uninstall:prompt [zsh|bash|fish] [--config <path>]",
|
|
192
|
+
completionFlags: ["--config", "--help"],
|
|
193
|
+
examples: ["gip uninstall:prompt zsh"],
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: "completion",
|
|
197
|
+
summary: "Generate shell completion script.",
|
|
198
|
+
usage: "gip completion [zsh|bash|fish]",
|
|
199
|
+
completionFlags: ["--help"],
|
|
200
|
+
examples: [
|
|
201
|
+
"gip completion zsh",
|
|
202
|
+
"gip completion bash",
|
|
203
|
+
"gip completion fish",
|
|
204
|
+
"source <(gip completion zsh)",
|
|
205
|
+
],
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
name: "install:completion",
|
|
209
|
+
summary: "Install managed shell completion integration.",
|
|
210
|
+
usage: "gip install:completion [zsh|bash|fish] [--config <path>]",
|
|
211
|
+
completionFlags: ["--config", "--help"],
|
|
212
|
+
examples: ["gip install:completion zsh", "gip install:completion fish"],
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
name: "install:shell",
|
|
216
|
+
summary: "Install the managed shell wrapper for session commands.",
|
|
217
|
+
usage: "gip install:shell [zsh|bash|fish] [--config <path>]",
|
|
218
|
+
completionFlags: ["--config", "--help"],
|
|
219
|
+
examples: ["gip install:shell zsh", "gip install shell zsh"],
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
name: "uninstall:completion",
|
|
223
|
+
summary: "Remove managed shell completion integration.",
|
|
224
|
+
usage: "gip uninstall:completion [zsh|bash|fish] [--config <path>]",
|
|
225
|
+
completionFlags: ["--config", "--help"],
|
|
226
|
+
examples: ["gip uninstall:completion zsh"],
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
name: "uninstall:shell",
|
|
230
|
+
summary: "Remove the managed shell wrapper.",
|
|
231
|
+
usage: "gip uninstall:shell [zsh|bash|fish] [--config <path>]",
|
|
232
|
+
completionFlags: ["--config", "--help"],
|
|
233
|
+
examples: ["gip uninstall:shell zsh"],
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
name: "uninstall:all",
|
|
237
|
+
summary: "Remove all managed shell integrations.",
|
|
238
|
+
usage: "gip uninstall:all [zsh|bash|fish] [--shell <zsh|bash|fish>] [--config <path>]",
|
|
239
|
+
completionFlags: ["--shell", "--config", "--help"],
|
|
240
|
+
examples: ["gip uninstall:all zsh"],
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: "paths",
|
|
244
|
+
summary: "Print resolved storage and Git config paths.",
|
|
245
|
+
usage: "gip paths [--json]",
|
|
246
|
+
completionFlags: ["--json", "--help"],
|
|
247
|
+
examples: ["gip paths", "gip paths --json"],
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
name: "tui",
|
|
251
|
+
summary: "Open the terminal UI.",
|
|
252
|
+
usage: "gip tui",
|
|
253
|
+
completionFlags: ["--help"],
|
|
254
|
+
examples: ["gip tui"],
|
|
255
|
+
},
|
|
256
|
+
];
|
|
257
|
+
export function renderHelp(commandName) {
|
|
258
|
+
if (commandName) {
|
|
259
|
+
const command = COMMANDS.find((candidate) => candidate.name === commandName);
|
|
260
|
+
if (!command) {
|
|
261
|
+
return `Unknown command: ${commandName}\n\n${renderHelp()}`;
|
|
262
|
+
}
|
|
263
|
+
return [
|
|
264
|
+
`${command.name} - ${command.summary}`,
|
|
265
|
+
"",
|
|
266
|
+
`Usage: ${command.usage}`,
|
|
267
|
+
"",
|
|
268
|
+
"Examples:",
|
|
269
|
+
...command.examples.map((example) => ` ${example}`),
|
|
270
|
+
].join("\n");
|
|
271
|
+
}
|
|
272
|
+
return [
|
|
273
|
+
"gip - Git Profile Switcher",
|
|
274
|
+
"",
|
|
275
|
+
"Usage: gip <command> [options]",
|
|
276
|
+
"",
|
|
277
|
+
"Commands:",
|
|
278
|
+
...COMMANDS.map((command) => ` ${command.name.padEnd(18)} ${command.summary}`),
|
|
279
|
+
"",
|
|
280
|
+
"Run `gip help <command>` for command details.",
|
|
281
|
+
].join("\n");
|
|
282
|
+
}
|
|
283
|
+
export function getHelpCommandNames() {
|
|
284
|
+
return COMMANDS.map((command) => command.name);
|
|
285
|
+
}
|
|
286
|
+
export function getHelpCommandFlags(commandName) {
|
|
287
|
+
return COMMANDS.find((command) => command.name === commandName)?.completionFlags ?? [];
|
|
288
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export function parseArgs(args) {
|
|
2
|
+
const positionals = [];
|
|
3
|
+
const flags = new Map();
|
|
4
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
5
|
+
const arg = args[index];
|
|
6
|
+
if (arg === "-h") {
|
|
7
|
+
flags.set("help", true);
|
|
8
|
+
continue;
|
|
9
|
+
}
|
|
10
|
+
if (arg === "-g") {
|
|
11
|
+
flags.set("global", true);
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
if (!arg.startsWith("--")) {
|
|
15
|
+
positionals.push(arg);
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
const withoutPrefix = arg.slice(2);
|
|
19
|
+
const inlineEqualsIndex = withoutPrefix.indexOf("=");
|
|
20
|
+
if (inlineEqualsIndex >= 0) {
|
|
21
|
+
flags.set(withoutPrefix.slice(0, inlineEqualsIndex), withoutPrefix.slice(inlineEqualsIndex + 1));
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const next = args[index + 1];
|
|
25
|
+
if (next && !next.startsWith("--")) {
|
|
26
|
+
flags.set(withoutPrefix, next);
|
|
27
|
+
index += 1;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
flags.set(withoutPrefix, true);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return { positionals, flags };
|
|
34
|
+
}
|
|
35
|
+
export function getStringFlag(parsed, name) {
|
|
36
|
+
const value = parsed.flags.get(name);
|
|
37
|
+
return typeof value === "string" ? value : null;
|
|
38
|
+
}
|
|
39
|
+
export function hasFlag(parsed, name) {
|
|
40
|
+
return parsed.flags.get(name) === true;
|
|
41
|
+
}
|