Skip to content

Commit f08ab8d

Browse files
committed
fix: Fix path and aliases imports
1 parent b700393 commit f08ab8d

4 files changed

Lines changed: 60 additions & 8 deletions

File tree

src/resources/asdf/asdf.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export class AsdfResource extends Resource<AsdfConfig> {
2727
schema,
2828
parameterSettings: {
2929
plugins: { type: 'stateful', definition: new AsdfPluginsParameter() },
30-
}
30+
},
3131
}
3232
}
3333

src/resources/shell/aliases/aliases-resource.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export class AliasesResource extends Resource<AliasesConfig> {
5454
current.filter((c) => desired.some((d) => d.alias === c.alias)),
5555
canModify: true,
5656
},
57-
declarationsOnly: { default: false, setting: true },
57+
declarationsOnly: { default: true, setting: true },
5858
},
5959
importAndDestroy: {
6060
refreshMapper(input) {

src/resources/shell/path/path-resource.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,20 @@ export PATH=/Users/kevinwang/.nvm/.bin/3:$PATH;
9494

9595
})
9696

97+
it('Can match path declarations with ${VAR:-default} syntax', () => {
98+
const pathResource = new PathResource();
99+
100+
const result = pathResource.findAllPathDeclarations(
101+
`
102+
export PATH="\${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"
103+
`);
104+
105+
expect(result).toMatchObject([
106+
{
107+
declaration: 'export PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"',
108+
path: '${ASDF_DATA_DIR:-$HOME/.asdf}/shims'
109+
}
110+
])
111+
})
112+
97113
})

src/resources/shell/path/path-resource.ts

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export interface PathConfig extends StringIndexedObject {
2727

2828
export class PathResource extends Resource<PathConfig> {
2929
private readonly PATH_DECLARATION_REGEX = /((export PATH=)|(path+=\()|(path=\())(.+?)[\n;]/g;
30-
private readonly PATH_REGEX = /(?<=[="':(])([^"'\n\r]+?)(?=["':)\n;])/g
3130
private readonly filePaths = Utils.getShellRcFiles()
3231

3332
getSettings(): ResourceSettings<PathConfig> {
@@ -237,24 +236,61 @@ export class PathResource extends Resource<PathConfig> {
237236

238237
for (const declaration of pathDeclarations) {
239238
const trimmedDeclaration = declaration[0];
240-
const paths = trimmedDeclaration.matchAll(this.PATH_REGEX);
239+
// Extract the value portion after the = or ( and strip surrounding quotes/parens
240+
const valueMatch = trimmedDeclaration.match(/(?:export PATH=|path\+=\(|path=\()(["']?)(.+?)\1[\n;)]/s);
241+
if (!valueMatch) {
242+
continue;
243+
}
244+
const value = valueMatch[2];
245+
const paths = this.splitPathValue(value);
241246

242-
for (const path of paths) {
243-
const trimmedPath = path[0];
244-
if (trimmedPath === '$PATH') {
247+
for (const p of paths) {
248+
if (!p || p.trim() === '' || p === '$PATH') {
245249
continue;
246250
}
247251

248252
results.push({
249253
declaration: trimmedDeclaration.trim(),
250-
path: trimmedPath,
254+
path: p,
251255
});
252256
}
253257
}
254258

255259
return results;
256260
}
257261

262+
// Split a PATH value by ':' but treat ':' inside ${...} as literal
263+
private splitPathValue(value: string): string[] {
264+
const segments: string[] = [];
265+
let current = '';
266+
let depth = 0;
267+
268+
for (let i = 0; i < value.length; i++) {
269+
const ch = value[i];
270+
if (ch === '$' && value[i + 1] === '{') {
271+
// Skip the '$', let the '{' handler increment depth
272+
current += ch;
273+
} else if (ch === '{') {
274+
depth++;
275+
current += ch;
276+
} else if (ch === '}' && depth > 0) {
277+
depth--;
278+
current += ch;
279+
} else if (ch === ':' && depth === 0) {
280+
segments.push(current);
281+
current = '';
282+
} else {
283+
current += ch;
284+
}
285+
}
286+
287+
if (current) {
288+
segments.push(current);
289+
}
290+
291+
return segments;
292+
}
293+
258294
private async resolvePathWithVariables(pathWithVariables: string): Promise<string> {
259295
const $ = getPty();
260296
const { data } = await $.spawnSafe(`echo ${pathWithVariables}`);

0 commit comments

Comments
 (0)