Skip to content

Commit 19bd04c

Browse files
authored
feat: add support for Nushell (#21)
* feat: add support for Nushell * test: add tests for Nushell
1 parent c2c8afd commit 19bd04c

File tree

2 files changed

+199
-2
lines changed

2 files changed

+199
-2
lines changed

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

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,3 +1147,175 @@ end
11471147
# pnpm end`)
11481148
})
11491149
})
1150+
1151+
describe('Nushell', () => {
1152+
let configFile!: string
1153+
beforeAll(() => {
1154+
process.env.NU_VERSION = '0.92.2'
1155+
})
1156+
beforeEach(() => {
1157+
configFile = path.join(homeDir, '.config/nushell/env.nu')
1158+
})
1159+
it('should append to empty shell script', async () => {
1160+
fs.mkdirSync('.config/nushell', { recursive: true })
1161+
fs.writeFileSync(configFile, '', 'utf8')
1162+
const report = await addDirToPosixEnvPath(pnpmHomeDir, {
1163+
proxyVarName: 'PNPM_HOME',
1164+
configSectionName: 'pnpm',
1165+
})
1166+
expect(report).toStrictEqual({
1167+
configFile: {
1168+
path: configFile,
1169+
changeType: 'appended',
1170+
},
1171+
oldSettings: ``,
1172+
newSettings: `$env.PNPM_HOME = "${pnpmHomeDir}"
1173+
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )`,
1174+
})
1175+
const configContent = fs.readFileSync(configFile, 'utf8')
1176+
expect(configContent).toEqual(`
1177+
# pnpm
1178+
$env.PNPM_HOME = "${pnpmHomeDir}"
1179+
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )
1180+
# pnpm end
1181+
`)
1182+
})
1183+
it('should append to empty shell script without using a proxy varialbe', async () => {
1184+
fs.mkdirSync('.config/nushell', { recursive: true })
1185+
fs.writeFileSync(configFile, '', 'utf8')
1186+
const report = await addDirToPosixEnvPath(pnpmHomeDir, {
1187+
configSectionName: 'pnpm',
1188+
})
1189+
expect(report).toStrictEqual({
1190+
configFile: {
1191+
path: configFile,
1192+
changeType: 'appended',
1193+
},
1194+
oldSettings: ``,
1195+
newSettings: `$env.PATH = ($env.PATH | split row (char esep) | prepend ${pnpmHomeDir} )`,
1196+
})
1197+
const configContent = fs.readFileSync(configFile, 'utf8')
1198+
expect(configContent).toEqual(`
1199+
# pnpm
1200+
$env.PATH = ($env.PATH | split row (char esep) | prepend ${pnpmHomeDir} )
1201+
# pnpm end
1202+
`)
1203+
})
1204+
it('should add the new dir to the end of PATH', async () => {
1205+
fs.mkdirSync('.config/nushell', { recursive: true })
1206+
fs.writeFileSync(configFile, '', 'utf8')
1207+
const report = await addDirToPosixEnvPath(pnpmHomeDir, {
1208+
proxyVarName: 'PNPM_HOME',
1209+
configSectionName: 'pnpm',
1210+
position: 'end',
1211+
})
1212+
expect(report).toStrictEqual({
1213+
configFile: {
1214+
path: configFile,
1215+
changeType: 'appended',
1216+
},
1217+
oldSettings: ``,
1218+
newSettings: `$env.PNPM_HOME = "${pnpmHomeDir}"
1219+
$env.PATH = ($env.PATH | split row (char esep) | append $env.PNPM_HOME )`,
1220+
})
1221+
const configContent = fs.readFileSync(configFile, 'utf8')
1222+
expect(configContent).toEqual(`
1223+
# pnpm
1224+
$env.PNPM_HOME = "${pnpmHomeDir}"
1225+
$env.PATH = ($env.PATH | split row (char esep) | append $env.PNPM_HOME )
1226+
# pnpm end
1227+
`)
1228+
})
1229+
it('should create a shell script', async () => {
1230+
const report = await addDirToPosixEnvPath(pnpmHomeDir, {
1231+
proxyVarName: 'PNPM_HOME',
1232+
configSectionName: 'pnpm',
1233+
})
1234+
expect(report).toStrictEqual({
1235+
configFile: {
1236+
path: configFile,
1237+
changeType: 'created',
1238+
},
1239+
oldSettings: ``,
1240+
newSettings: `$env.PNPM_HOME = "${pnpmHomeDir}"
1241+
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )`
1242+
})
1243+
const configContent = fs.readFileSync(configFile, 'utf8')
1244+
expect(configContent).toEqual(`# pnpm
1245+
$env.PNPM_HOME = "${pnpmHomeDir}"
1246+
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )
1247+
# pnpm end
1248+
`)
1249+
})
1250+
it('should make no changes to a shell script that already has the necessary configurations', async () => {
1251+
fs.mkdirSync('.config/nushell', { recursive: true })
1252+
fs.writeFileSync(configFile, `
1253+
# pnpm
1254+
$env.PNPM_HOME = "${pnpmHomeDir}"
1255+
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )
1256+
# pnpm end`, 'utf8')
1257+
const report = await addDirToPosixEnvPath(pnpmHomeDir, {
1258+
proxyVarName: 'PNPM_HOME',
1259+
configSectionName: 'pnpm',
1260+
})
1261+
expect(report).toStrictEqual({
1262+
configFile: {
1263+
path: configFile,
1264+
changeType: 'skipped',
1265+
},
1266+
oldSettings: `$env.PNPM_HOME = "${pnpmHomeDir}"
1267+
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )`,
1268+
newSettings: `$env.PNPM_HOME = "${pnpmHomeDir}"
1269+
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )`
1270+
})
1271+
const configContent = fs.readFileSync(configFile, 'utf8')
1272+
expect(configContent).toEqual(`
1273+
# pnpm
1274+
$env.PNPM_HOME = "${pnpmHomeDir}"
1275+
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )
1276+
# pnpm end`)
1277+
})
1278+
it('should fail if the shell already has PNPM_HOME set to a different directory', async () => {
1279+
fs.mkdirSync('.config/nushell', { recursive: true })
1280+
fs.writeFileSync(configFile, `
1281+
# pnpm
1282+
$env.PNPM_HOME = "pnpm_home"
1283+
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )
1284+
# pnpm end`, 'utf8')
1285+
await expect(
1286+
addDirToPosixEnvPath(pnpmHomeDir, {
1287+
proxyVarName: 'PNPM_HOME',
1288+
configSectionName: 'pnpm',
1289+
})
1290+
).rejects.toThrowError(/The config file at/)
1291+
})
1292+
it('should not fail if setup is forced', async () => {
1293+
fs.mkdirSync('.config/nushell', { recursive: true })
1294+
fs.writeFileSync(configFile, `
1295+
# pnpm
1296+
$env.PNPM_HOME = "pnpm_home"
1297+
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )
1298+
# pnpm end`, 'utf8')
1299+
const report = await addDirToPosixEnvPath(pnpmHomeDir, {
1300+
proxyVarName: 'PNPM_HOME',
1301+
overwrite: true,
1302+
configSectionName: 'pnpm',
1303+
})
1304+
expect(report).toStrictEqual({
1305+
configFile: {
1306+
path: configFile,
1307+
changeType: 'modified',
1308+
},
1309+
oldSettings: `$env.PNPM_HOME = "pnpm_home"
1310+
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )`,
1311+
newSettings: `$env.PNPM_HOME = "${pnpmHomeDir}"
1312+
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )`
1313+
})
1314+
const configContent = fs.readFileSync(configFile, 'utf8')
1315+
expect(configContent).toEqual(`
1316+
# pnpm
1317+
$env.PNPM_HOME = "${pnpmHomeDir}"
1318+
$env.PATH = ($env.PATH | split row (char esep) | prepend $env.PNPM_HOME )
1319+
# pnpm end`)
1320+
})
1321+
})

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export interface AddDirToPosixEnvPathOpts {
2222
configSectionName: string
2323
}
2424

25-
export type ShellType = 'zsh' | 'bash' | 'fish' | 'ksh' | 'dash' | 'sh'
25+
export type ShellType = 'zsh' | 'bash' | 'fish' | 'ksh' | 'dash' | 'sh' | 'nu'
2626

2727
export type ConfigFileChangeType = 'skipped' | 'appended' | 'modified' | 'created'
2828

@@ -50,6 +50,7 @@ function detectCurrentShell () {
5050
if (process.env.ZSH_VERSION) return 'zsh'
5151
if (process.env.BASH_VERSION) return 'bash'
5252
if (process.env.FISH_VERSION) return 'fish'
53+
if (process.env.NU_VERSION) return 'nu'
5354
return typeof process.env.SHELL === 'string' ? path.basename(process.env.SHELL) : null
5455
}
5556

@@ -69,8 +70,11 @@ async function updateShell (
6970
case 'fish': {
7071
return setupFishShell(pnpmHomeDir, opts)
7172
}
73+
case 'nu': {
74+
return setupNuShell(pnpmHomeDir, opts)
7275
}
73-
const supportedShellsMsg = 'Supported shell languages are bash, zsh, fish, ksh, dash, and sh.'
76+
}
77+
const supportedShellsMsg = 'Supported shell languages are bash, zsh, fish, ksh, dash, sh, and nushell.'
7478
if (!currentShell) throw new PnpmError('UNKNOWN_SHELL', 'Could not infer shell type.', {
7579
hint: `Set the SHELL environment variable to your active shell.
7680
${supportedShellsMsg}`
@@ -158,6 +162,27 @@ end`
158162
}
159163
}
160164

165+
async function setupNuShell (dir: string, opts: AddDirToPosixEnvPathOpts): Promise<PathExtenderPosixReport> {
166+
const configFile = path.join(os.homedir(), '.config/nushell/env.nu')
167+
let newSettings!: string
168+
const addingCommand = (opts.position ?? "start") === "start" ? "prepend" : "append"
169+
if (opts.proxyVarName) {
170+
newSettings = `$env.${opts.proxyVarName} = "${dir}"
171+
$env.PATH = ($env.PATH | split row (char esep) | ${addingCommand} $env.${opts.proxyVarName} )`
172+
} else {
173+
newSettings = `$env.PATH = ($env.PATH | split row (char esep) | ${addingCommand} ${dir} )`
174+
}
175+
const content = wrapSettings(opts.configSectionName, newSettings)
176+
const { changeType, oldSettings } = await updateShellConfig(configFile, content, opts)
177+
return {
178+
configFile: {
179+
path: configFile,
180+
changeType,
181+
},
182+
oldSettings,
183+
newSettings,
184+
}
185+
}
161186
function wrapSettings (sectionName: string, settings: string): string {
162187
return `# ${sectionName}
163188
${settings}

0 commit comments

Comments
 (0)