-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgithub-cli-alias.ts
More file actions
141 lines (125 loc) · 4.47 KB
/
Copy pathgithub-cli-alias.ts
File metadata and controls
141 lines (125 loc) · 4.47 KB
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
135
136
137
138
139
140
141
import {
CreatePlan,
DestroyPlan,
ModifyPlan,
ParameterChange,
Resource,
ResourceSettings,
SpawnStatus,
getPty,
z,
} from '@codifycli/plugin-core';
import { OS } from '@codifycli/schemas';
import { exampleGithubCliAliasBasic, exampleGithubCliAliasShell } from './examples.js';
export const schema = z
.object({
alias: z
.string()
.describe('The alias name used to invoke the expansion'),
expansion: z
.string()
.describe('The gh command or shell command this alias expands to'),
shell: z
.boolean()
.optional()
.describe(
'When true, the expansion is treated as a shell command and passed through sh. Allows pipes, redirects, and other shell features'
),
})
.meta({ $comment: 'https://cli.github.com/manual/gh_alias_set' })
.describe('GitHub CLI alias — create short-hand names for gh commands');
export type GithubCliAliasConfig = z.infer<typeof schema>;
const defaultConfig: Partial<GithubCliAliasConfig> = {
shell: false,
};
export class GithubCliAliasResource extends Resource<GithubCliAliasConfig> {
getSettings(): ResourceSettings<GithubCliAliasConfig> {
return {
id: 'github-cli-alias',
defaultConfig,
exampleConfigs: {
example1: exampleGithubCliAliasBasic,
example2: exampleGithubCliAliasShell,
},
operatingSystems: [OS.Darwin, OS.Linux],
schema,
dependencies: ['github-cli'],
parameterSettings: {
alias: {},
expansion: { canModify: true },
shell: { canModify: true },
},
allowMultiple: {
identifyingParameters: ['alias'],
findAllParameters: async () => {
const $ = getPty();
const { data, status } = await $.spawnSafe('gh alias list');
if (status === SpawnStatus.ERROR || !data.trim()) return [];
return data
.split('\n')
.filter(Boolean)
.map((line) => {
// gh alias list outputs "alias: expansion" (colon-space separated)
const colonIdx = line.indexOf(':');
const alias = (colonIdx !== -1 ? line.slice(0, colonIdx) : line).trim();
return { alias };
})
.filter((a) => Boolean(a.alias));
},
},
};
}
async refresh(params: Partial<GithubCliAliasConfig>): Promise<Partial<GithubCliAliasConfig> | null> {
const $ = getPty();
const { data, status } = await $.spawnSafe('gh alias list');
if (status === SpawnStatus.ERROR || !data.trim()) return null;
const found = this.parseAliasList(data).find((a) => a.alias === params.alias);
if (!found) return null;
return {
alias: found.alias,
expansion: found.expansion,
shell: found.shell,
};
}
async create(plan: CreatePlan<GithubCliAliasConfig>): Promise<void> {
const $ = getPty();
const { alias, expansion, shell } = plan.desiredConfig;
const shellFlag = shell ? ' --shell' : '';
await $.spawn(`gh alias set ${alias} '${expansion.replace(/'/g, "'\\''")}'${shellFlag}`);
}
async modify(pc: ParameterChange<GithubCliAliasConfig>, plan: ModifyPlan<GithubCliAliasConfig>): Promise<void> {
if (pc.name === 'expansion' || pc.name === 'shell') {
const $ = getPty();
const { alias, expansion, shell } = plan.desiredConfig;
const shellFlag = shell ? ' --shell' : '';
await $.spawn(
`gh alias set --clobber ${alias} '${expansion.replace(/'/g, "'\\''")}'${shellFlag}`
);
}
}
async destroy(plan: DestroyPlan<GithubCliAliasConfig>): Promise<void> {
const $ = getPty();
const { status } = await $.spawnSafe('which gh');
if (status === SpawnStatus.ERROR) return;
await $.spawn(`gh alias delete ${plan.currentConfig.alias}`);
}
private parseAliasList(output: string): Array<{ alias: string; expansion: string; shell: boolean }> {
return output
.split('\n')
.filter(Boolean)
.map((line) => {
// gh alias list outputs "alias: expansion" (colon-space separated)
const colonIdx = line.indexOf(':');
if (colonIdx === -1) return null;
const alias = line.slice(0, colonIdx).trim();
const rawExpansion = line.slice(colonIdx + 1).trim();
const isShell = rawExpansion.startsWith('!');
return {
alias,
expansion: isShell ? rawExpansion.slice(1) : rawExpansion,
shell: isShell,
};
})
.filter((x): x is { alias: string; expansion: string; shell: boolean } => x !== null);
}
}