Skip to content

Commit 98af49e

Browse files
zkochanclaude
andauthored
feat: add proxyVarSubDir option to path extenders (#26)
* feat: add proxyVarSubDir option to path extenders Allow specifying a subdirectory of the proxy variable to add to PATH, e.g. PNPM_HOME/bin instead of PNPM_HOME. Supports posix (bash, fish, nushell) and windows shells. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ci: retrigger CI * ci: update Node.js versions to 22 and 24 Drop support for Node.js 16, 18, 20, and 21. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: remove pnpm.builder/policy component The pnpm.builder scope has been removed from Bit. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: add @teambit/builder to workspace dependencies Previously resolved transitively through the removed policy component. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address review feedback for proxyVarSubDir - Validate proxyVarSubDir to reject dangerous values (leading slashes, .., shell metacharacters) in both posix and windows path extenders - Quote pathRef in Fish shell string match when using proxyVarSubDir - Add Fish and Nushell tests for proxyVarSubDir Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: move proxyVarSubDir validation to shared path-extender Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: add Windows test for proxyVarSubDir Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5a7eefc commit 98af49e

15 files changed

Lines changed: 751 additions & 412 deletions

File tree

.bitmap

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,7 @@
8686
"mainFile": "index.ts",
8787
"rootDir": "config/nerf-dart"
8888
},
89-
"policy": {
90-
"name": "policy",
91-
"scope": "pnpm.builder",
92-
"version": "3.0.2",
93-
"mainFile": "index.ts",
94-
"rootDir": "builder/policy"
95-
},
96-
"proxy-agent": {
89+
"proxy-agent": {
9790
"name": "proxy-agent",
9891
"scope": "pnpm.network",
9992
"version": "2.0.3",

.github/workflows/ci.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@ jobs:
1515
fail-fast: false
1616
matrix:
1717
node:
18-
- '16.14'
19-
- '18'
20-
- '20'
21-
- '21'
18+
- '22'
19+
- '24'
2220
platform:
2321
- ubuntu-latest
2422
- windows-latest

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
public
22
node_modules
3+
.claude

builder/policy/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

builder/policy/onlyBuild.json

Lines changed: 0 additions & 4 deletions
This file was deleted.

builder/policy/policy.docs.mdx

Lines changed: 0 additions & 10 deletions
This file was deleted.

builder/policy/policy.spec.ts

Lines changed: 0 additions & 54 deletions
This file was deleted.

builder/policy/policy.ts

Lines changed: 0 additions & 23 deletions
This file was deleted.

os/env/path-extender-posix/path-extender-posix.spec.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,36 @@ case ":$PATH:" in
8383
*) export PATH="${pnpmHomeDir}:$PATH" ;;
8484
esac
8585
# pnpm end
86+
`)
87+
})
88+
it('should append to shell script with proxyVarSubDir', async () => {
89+
fs.writeFileSync(configFile, '', 'utf8')
90+
const report = await addDirToPosixEnvPath(pnpmHomeDir, {
91+
proxyVarName: 'PNPM_HOME',
92+
proxyVarSubDir: 'bin',
93+
configSectionName: 'pnpm',
94+
})
95+
expect(report).toStrictEqual({
96+
configFile: {
97+
path: configFile,
98+
changeType: 'appended',
99+
},
100+
oldSettings: '',
101+
newSettings: `export PNPM_HOME="${pnpmHomeDir}"
102+
case ":$PATH:" in
103+
*":$PNPM_HOME/bin:"*) ;;
104+
*) export PATH="$PNPM_HOME/bin:$PATH" ;;
105+
esac`,
106+
})
107+
const configContent = fs.readFileSync(configFile, 'utf8')
108+
expect(configContent).toEqual(`
109+
# pnpm
110+
export PNPM_HOME="${pnpmHomeDir}"
111+
case ":$PATH:" in
112+
*":$PNPM_HOME/bin:"*) ;;
113+
*) export PATH="$PNPM_HOME/bin:$PATH" ;;
114+
esac
115+
# pnpm end
86116
`)
87117
})
88118
it('should put the new directory to the end of the PATH', async () => {
@@ -978,6 +1008,35 @@ if not string match -q -- $PNPM_HOME $PATH
9781008
set -gx PATH "$PNPM_HOME" $PATH
9791009
end
9801010
# pnpm end
1011+
`)
1012+
})
1013+
it('should append to shell script with proxyVarSubDir', async () => {
1014+
fs.mkdirSync('.config/fish', { recursive: true })
1015+
fs.writeFileSync(configFile, '', 'utf8')
1016+
const report = await addDirToPosixEnvPath(pnpmHomeDir, {
1017+
proxyVarName: 'PNPM_HOME',
1018+
proxyVarSubDir: 'bin',
1019+
configSectionName: 'pnpm',
1020+
})
1021+
expect(report).toStrictEqual({
1022+
configFile: {
1023+
path: configFile,
1024+
changeType: 'appended',
1025+
},
1026+
oldSettings: ``,
1027+
newSettings: `set -gx PNPM_HOME "${pnpmHomeDir}"
1028+
if not string match -q -- "$PNPM_HOME/bin" $PATH
1029+
set -gx PATH "$PNPM_HOME/bin" $PATH
1030+
end`,
1031+
})
1032+
const configContent = fs.readFileSync(configFile, 'utf8')
1033+
expect(configContent).toEqual(`
1034+
# pnpm
1035+
set -gx PNPM_HOME "${pnpmHomeDir}"
1036+
if not string match -q -- "$PNPM_HOME/bin" $PATH
1037+
set -gx PATH "$PNPM_HOME/bin" $PATH
1038+
end
1039+
# pnpm end
9811040
`)
9821041
})
9831042
it('should append to empty shell script without using a proxy varialbe', async () => {
@@ -1178,6 +1237,31 @@ $env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )`,
11781237
$env.PNPM_HOME = "${pnpmHomeDir}"
11791238
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )
11801239
# pnpm end
1240+
`)
1241+
})
1242+
it('should append to shell script with proxyVarSubDir', async () => {
1243+
fs.mkdirSync('.config/nushell', { recursive: true })
1244+
fs.writeFileSync(configFile, '', 'utf8')
1245+
const report = await addDirToPosixEnvPath(pnpmHomeDir, {
1246+
proxyVarName: 'PNPM_HOME',
1247+
proxyVarSubDir: 'bin',
1248+
configSectionName: 'pnpm',
1249+
})
1250+
expect(report).toStrictEqual({
1251+
configFile: {
1252+
path: configFile,
1253+
changeType: 'appended',
1254+
},
1255+
oldSettings: ``,
1256+
newSettings: `$env.PNPM_HOME = "${pnpmHomeDir}"
1257+
$env.PATH = ($env.PATH | split row (char esep) | prepend ($env.PNPM_HOME | path join "bin") )`,
1258+
})
1259+
const configContent = fs.readFileSync(configFile, 'utf8')
1260+
expect(configContent).toEqual(`
1261+
# pnpm
1262+
$env.PNPM_HOME = "${pnpmHomeDir}"
1263+
$env.PATH = ($env.PATH | split row (char esep) | prepend ($env.PNPM_HOME | path join "bin") )
1264+
# pnpm end
11811265
`)
11821266
})
11831267
it('should append to empty shell script without using a proxy varialbe', async () => {

os/env/path-extender-posix/path-extender-posix.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export type AddingPosition = 'start' | 'end'
1717

1818
export interface AddDirToPosixEnvPathOpts {
1919
proxyVarName?: string
20+
proxyVarSubDir?: string
2021
overwrite?: boolean
2122
position?: AddingPosition
2223
configSectionName: string
@@ -93,10 +94,11 @@ async function setupShell (
9394
let newSettings!: string
9495
const _createPathValue = createPathValue.bind(null, opts.position ?? 'start')
9596
if (opts.proxyVarName) {
97+
const pathRef = opts.proxyVarSubDir ? `$${opts.proxyVarName}/${opts.proxyVarSubDir}` : `$${opts.proxyVarName}`
9698
newSettings = `export ${opts.proxyVarName}="${dir}"
9799
case ":$PATH:" in
98-
*":$${opts.proxyVarName}:"*) ;;
99-
*) export PATH="${_createPathValue(`$${opts.proxyVarName}`)}" ;;
100+
*":${pathRef}:"*) ;;
101+
*) export PATH="${_createPathValue(pathRef)}" ;;
100102
esac`
101103
} else {
102104
newSettings = `case ":$PATH:" in
@@ -141,9 +143,11 @@ async function setupFishShell (dir: string, opts: AddDirToPosixEnvPathOpts): Pro
141143
let newSettings!: string
142144
const _createPathValue = createFishPathValue.bind(null, opts.position ?? 'start')
143145
if (opts.proxyVarName) {
146+
const pathRef = opts.proxyVarSubDir ? `$${opts.proxyVarName}/${opts.proxyVarSubDir}` : `$${opts.proxyVarName}`
147+
const matchPattern = opts.proxyVarSubDir ? `"${pathRef}"` : pathRef
144148
newSettings = `set -gx ${opts.proxyVarName} "${dir}"
145-
if not string match -q -- $${opts.proxyVarName} $PATH
146-
set -gx PATH ${_createPathValue(`$${opts.proxyVarName}`)}
149+
if not string match -q -- ${matchPattern} $PATH
150+
set -gx PATH ${_createPathValue(pathRef)}
147151
end`
148152
} else {
149153
newSettings = `if not string match -q -- "${dir}" $PATH
@@ -167,8 +171,11 @@ async function setupNuShell (dir: string, opts: AddDirToPosixEnvPathOpts): Promi
167171
let newSettings!: string
168172
const addingCommand = (opts.position ?? "start") === "start" ? "prepend" : "append"
169173
if (opts.proxyVarName) {
174+
const pathRef = opts.proxyVarSubDir
175+
? `($env.${opts.proxyVarName} | path join "${opts.proxyVarSubDir}")`
176+
: `$env.${opts.proxyVarName}`
170177
newSettings = `$env.${opts.proxyVarName} = "${dir}"
171-
$env.PATH = ($env.PATH | split row (char esep) | ${addingCommand} $env.${opts.proxyVarName} )`
178+
$env.PATH = ($env.PATH | split row (char esep) | ${addingCommand} ${pathRef} )`
172179
} else {
173180
newSettings = `$env.PATH = ($env.PATH | split row (char esep) | ${addingCommand} ${dir} )`
174181
}

0 commit comments

Comments
 (0)