mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-23 23:29:17 -05:00
feat: config set local should save settings in pnpm-workspace.yaml (#9316)
This commit is contained in:
7
.changeset/breezy-mice-sell.md
Normal file
7
.changeset/breezy-mice-sell.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-config": minor
|
||||
"@pnpm/config": minor
|
||||
"pnpm": minor
|
||||
---
|
||||
|
||||
`pnpm config get` and `list` also show settings set in `pnpm-workspace.yaml` files [#9316](https://github.com/pnpm/pnpm/pull/9316).
|
||||
7
.changeset/mean-chicken-leave.md
Normal file
7
.changeset/mean-chicken-leave.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-config": minor
|
||||
"@pnpm/config": minor
|
||||
"pnpm": minor
|
||||
---
|
||||
|
||||
`pnpm config set --location=project` saves the setting to a `pnpm-workspace.yaml` file if no `.npmrc` file is present in the directory [#9316](https://github.com/pnpm/pnpm/pull/9316).
|
||||
@@ -51,6 +51,7 @@
|
||||
"can-write-to-dir": "catalog:",
|
||||
"is-subdir": "catalog:",
|
||||
"is-windows": "catalog:",
|
||||
"lodash.kebabcase": "catalog:",
|
||||
"normalize-registry-url": "catalog:",
|
||||
"path-absolute": "catalog:",
|
||||
"path-name": "catalog:",
|
||||
@@ -67,6 +68,7 @@
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@pnpm/test-fixtures": "workspace:*",
|
||||
"@types/is-windows": "catalog:",
|
||||
"@types/lodash.kebabcase": "catalog:",
|
||||
"@types/ramda": "catalog:",
|
||||
"@types/which": "catalog:",
|
||||
"symlink-dir": "catalog:"
|
||||
|
||||
@@ -12,6 +12,7 @@ import { createMatcher } from '@pnpm/matcher'
|
||||
import betterPathResolve from 'better-path-resolve'
|
||||
import camelcase from 'camelcase'
|
||||
import isWindows from 'is-windows'
|
||||
import kebabCase from 'lodash.kebabcase'
|
||||
import normalizeRegistryUrl from 'normalize-registry-url'
|
||||
import realpathMissing from 'realpath-missing'
|
||||
import pathAbsolute from 'path-absolute'
|
||||
@@ -489,7 +490,12 @@ export async function getConfig (opts: {
|
||||
|
||||
pnpmConfig.workspacePackagePatterns = cliOptions['workspace-packages'] as string[] ?? workspaceManifest?.packages ?? ['.']
|
||||
if (workspaceManifest) {
|
||||
Object.assign(pnpmConfig, getOptionsFromPnpmSettings(pnpmConfig.workspaceDir, workspaceManifest, pnpmConfig.rootProjectManifest), configFromCliOpts)
|
||||
const newSettings = Object.assign(getOptionsFromPnpmSettings(pnpmConfig.workspaceDir, workspaceManifest, pnpmConfig.rootProjectManifest), configFromCliOpts)
|
||||
for (const [key, value] of Object.entries(newSettings)) {
|
||||
// @ts-expect-error
|
||||
pnpmConfig[key] = value
|
||||
pnpmConfig.rawConfig[kebabCase(key)] = value
|
||||
}
|
||||
pnpmConfig.catalogs = getCatalogsFromWorkspaceManifest(workspaceManifest)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1039,4 +1039,5 @@ test('settings from pnpm-workspace.yaml are read', async () => {
|
||||
})
|
||||
|
||||
expect(config.onlyBuiltDependencies).toStrictEqual(['foo'])
|
||||
expect(config.rawConfig['only-built-dependencies']).toStrictEqual(['foo'])
|
||||
})
|
||||
|
||||
@@ -36,7 +36,10 @@
|
||||
"@pnpm/error": "workspace:*",
|
||||
"@pnpm/object.key-sorting": "workspace:*",
|
||||
"@pnpm/run-npm": "workspace:*",
|
||||
"@pnpm/workspace.manifest-writer": "workspace:*",
|
||||
"camelcase": "catalog:",
|
||||
"ini": "catalog:",
|
||||
"lodash.kebabcase": "catalog:",
|
||||
"read-ini-file": "catalog:",
|
||||
"render-help": "catalog:",
|
||||
"write-ini-file": "catalog:"
|
||||
@@ -45,7 +48,9 @@
|
||||
"@pnpm/logger": "workspace:*",
|
||||
"@pnpm/plugin-commands-config": "workspace:*",
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@types/ini": "catalog:"
|
||||
"@types/ini": "catalog:",
|
||||
"@types/lodash.kebabcase": "catalog:",
|
||||
"read-yaml-file": "catalog:"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.12"
|
||||
|
||||
@@ -7,6 +7,7 @@ export type ConfigCommandOptions = Pick<Config,
|
||||
| 'global'
|
||||
| 'npmPath'
|
||||
| 'rawConfig'
|
||||
| 'workspaceDir'
|
||||
> & {
|
||||
json?: boolean
|
||||
location?: 'global' | 'project'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import kebabCase from 'lodash.kebabcase'
|
||||
import { type ConfigCommandOptions } from './ConfigCommandOptions'
|
||||
|
||||
export function configGet (opts: ConfigCommandOptions, key: string): string {
|
||||
const config = opts.rawConfig[key]
|
||||
const config = opts.rawConfig[kebabCase(key)]
|
||||
return Array.isArray(config) ? config.join(',') : String(config)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import util from 'util'
|
||||
import { runNpm } from '@pnpm/run-npm'
|
||||
import { updateWorkspaceManifest } from '@pnpm/workspace.manifest-writer'
|
||||
import camelCase from 'camelcase'
|
||||
import kebabCase from 'lodash.kebabcase'
|
||||
import { readIniFile } from 'read-ini-file'
|
||||
import { writeIniFile } from 'write-ini-file'
|
||||
import { type ConfigCommandOptions } from './ConfigCommandOptions'
|
||||
|
||||
export async function configSet (opts: ConfigCommandOptions, key: string, value: string | null): Promise<void> {
|
||||
const configPath = opts.global ? path.join(opts.configDir, 'rc') : path.join(opts.dir, '.npmrc')
|
||||
if (opts.global && settingShouldFallBackToNpm(key)) {
|
||||
const _runNpm = runNpm.bind(null, opts.npmPath)
|
||||
if (value == null) {
|
||||
@@ -16,14 +19,23 @@ export async function configSet (opts: ConfigCommandOptions, key: string, value:
|
||||
}
|
||||
return
|
||||
}
|
||||
const settings = await safeReadIniFile(configPath)
|
||||
if (value == null) {
|
||||
if (settings[key] == null) return
|
||||
delete settings[key]
|
||||
} else {
|
||||
settings[key] = value
|
||||
if (opts.global === true || fs.existsSync(path.join(opts.dir, '.npmrc'))) {
|
||||
const configPath = opts.global ? path.join(opts.configDir, 'rc') : path.join(opts.dir, '.npmrc')
|
||||
const settings = await safeReadIniFile(configPath)
|
||||
key = kebabCase(key)
|
||||
if (value == null) {
|
||||
if (settings[key] == null) return
|
||||
delete settings[key]
|
||||
} else {
|
||||
settings[key] = value
|
||||
}
|
||||
await writeIniFile(configPath, settings)
|
||||
return
|
||||
}
|
||||
await writeIniFile(configPath, settings)
|
||||
key = camelCase(key)
|
||||
await updateWorkspaceManifest(opts.workspaceDir ?? opts.dir, {
|
||||
[key]: value,
|
||||
})
|
||||
}
|
||||
|
||||
function settingShouldFallBackToNpm (key: string): boolean {
|
||||
|
||||
@@ -14,6 +14,20 @@ test('config get', async () => {
|
||||
expect(configKey).toEqual('~/store')
|
||||
})
|
||||
|
||||
test('config get works with camelCase', async () => {
|
||||
const configKey = await config.handler({
|
||||
dir: process.cwd(),
|
||||
cliOptions: {},
|
||||
configDir: process.cwd(),
|
||||
global: true,
|
||||
rawConfig: {
|
||||
'store-dir': '~/store',
|
||||
},
|
||||
}, ['get', 'storeDir'])
|
||||
|
||||
expect(configKey).toEqual('~/store')
|
||||
})
|
||||
|
||||
test('config get a boolean should return string format', async () => {
|
||||
const configKey = await config.handler({
|
||||
dir: process.cwd(),
|
||||
|
||||
@@ -4,6 +4,7 @@ import { PnpmError } from '@pnpm/error'
|
||||
import { tempDir } from '@pnpm/prepare'
|
||||
import { config } from '@pnpm/plugin-commands-config'
|
||||
import { readIniFileSync } from 'read-ini-file'
|
||||
import { sync as readYamlFile } from 'read-yaml-file'
|
||||
|
||||
test('config set using the global option', async () => {
|
||||
const tmp = tempDir()
|
||||
@@ -37,7 +38,7 @@ test('config set using the location=global option', async () => {
|
||||
configDir,
|
||||
location: 'global',
|
||||
rawConfig: {},
|
||||
}, ['set', 'fetch-retries', '1'])
|
||||
}, ['set', 'fetchRetries', '1'])
|
||||
|
||||
expect(readIniFileSync(path.join(configDir, 'rc'))).toEqual({
|
||||
'store-dir': '~/store',
|
||||
@@ -45,6 +46,24 @@ test('config set using the location=global option', async () => {
|
||||
})
|
||||
})
|
||||
|
||||
test('config set using the location=project option. The setting is written to pnpm-workspace.yaml, when .npmrc is not present', async () => {
|
||||
const tmp = tempDir()
|
||||
const configDir = path.join(tmp, 'global-config')
|
||||
fs.mkdirSync(configDir, { recursive: true })
|
||||
|
||||
await config.handler({
|
||||
dir: process.cwd(),
|
||||
cliOptions: {},
|
||||
configDir,
|
||||
location: 'project',
|
||||
rawConfig: {},
|
||||
}, ['set', 'virtual-store-dir', '.pnpm'])
|
||||
|
||||
expect(readYamlFile(path.join(tmp, 'pnpm-workspace.yaml'))).toEqual({
|
||||
virtualStoreDir: '.pnpm',
|
||||
})
|
||||
})
|
||||
|
||||
test('config set using the location=project option', async () => {
|
||||
const tmp = tempDir()
|
||||
const configDir = path.join(tmp, 'global-config')
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
{
|
||||
"path": "../../packages/logger"
|
||||
},
|
||||
{
|
||||
"path": "../../workspace/manifest-writer"
|
||||
},
|
||||
{
|
||||
"path": "../config"
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
"jega",
|
||||
"jhcg",
|
||||
"jnbpamcxayl",
|
||||
"kebabcase",
|
||||
"kevva",
|
||||
"keyfile",
|
||||
"killcb",
|
||||
|
||||
34
pnpm-lock.yaml
generated
34
pnpm-lock.yaml
generated
@@ -102,6 +102,9 @@ catalogs:
|
||||
'@types/js-yaml':
|
||||
specifier: ^4.0.9
|
||||
version: 4.0.9
|
||||
'@types/lodash.kebabcase':
|
||||
specifier: 4.1.9
|
||||
version: 4.1.9
|
||||
'@types/lodash.throttle':
|
||||
specifier: 4.1.7
|
||||
version: 4.1.7
|
||||
@@ -387,6 +390,9 @@ catalogs:
|
||||
load-json-file:
|
||||
specifier: ^6.2.0
|
||||
version: 6.2.0
|
||||
lodash.kebabcase:
|
||||
specifier: ^4.1.1
|
||||
version: 4.1.1
|
||||
lodash.throttle:
|
||||
specifier: 4.1.1
|
||||
version: 4.1.1
|
||||
@@ -1499,6 +1505,9 @@ importers:
|
||||
is-windows:
|
||||
specifier: 'catalog:'
|
||||
version: 1.0.2
|
||||
lodash.kebabcase:
|
||||
specifier: 'catalog:'
|
||||
version: 4.1.1
|
||||
normalize-registry-url:
|
||||
specifier: 'catalog:'
|
||||
version: 2.0.0
|
||||
@@ -1533,6 +1542,9 @@ importers:
|
||||
'@types/is-windows':
|
||||
specifier: 'catalog:'
|
||||
version: 1.0.2
|
||||
'@types/lodash.kebabcase':
|
||||
specifier: 'catalog:'
|
||||
version: 4.1.9
|
||||
'@types/ramda':
|
||||
specifier: 'catalog:'
|
||||
version: 0.29.12
|
||||
@@ -1680,9 +1692,18 @@ importers:
|
||||
'@pnpm/run-npm':
|
||||
specifier: workspace:*
|
||||
version: link:../../exec/run-npm
|
||||
'@pnpm/workspace.manifest-writer':
|
||||
specifier: workspace:*
|
||||
version: link:../../workspace/manifest-writer
|
||||
camelcase:
|
||||
specifier: 'catalog:'
|
||||
version: 6.3.0
|
||||
ini:
|
||||
specifier: 'catalog:'
|
||||
version: 4.1.1
|
||||
lodash.kebabcase:
|
||||
specifier: 'catalog:'
|
||||
version: 4.1.1
|
||||
read-ini-file:
|
||||
specifier: 'catalog:'
|
||||
version: 4.0.0
|
||||
@@ -1705,6 +1726,12 @@ importers:
|
||||
'@types/ini':
|
||||
specifier: 'catalog:'
|
||||
version: 1.3.31
|
||||
'@types/lodash.kebabcase':
|
||||
specifier: 'catalog:'
|
||||
version: 4.1.9
|
||||
read-yaml-file:
|
||||
specifier: 'catalog:'
|
||||
version: 2.1.0
|
||||
|
||||
crypto/hash:
|
||||
dependencies:
|
||||
@@ -9676,6 +9703,9 @@ packages:
|
||||
'@types/keyv@3.1.4':
|
||||
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
|
||||
|
||||
'@types/lodash.kebabcase@4.1.9':
|
||||
resolution: {integrity: sha512-kPrrmcVOhSsjAVRovN0lRfrbuidfg0wYsrQa5IYuoQO1fpHHGSme66oyiYA/5eQPVl8Z95OA3HG0+d2SvYC85w==}
|
||||
|
||||
'@types/lodash.throttle@4.1.7':
|
||||
resolution: {integrity: sha512-znwGDpjCHQ4FpLLx19w4OXDqq8+OvREa05H89obtSyXyOFKL3dDjCslsmfBz0T2FU8dmf5Wx1QvogbINiGIu9g==}
|
||||
|
||||
@@ -16704,6 +16734,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/node': 22.13.10
|
||||
|
||||
'@types/lodash.kebabcase@4.1.9':
|
||||
dependencies:
|
||||
'@types/lodash': 4.17.16
|
||||
|
||||
'@types/lodash.throttle@4.1.7':
|
||||
dependencies:
|
||||
'@types/lodash': 4.17.16
|
||||
|
||||
@@ -89,6 +89,7 @@ catalog:
|
||||
"@types/is-gzip": 2.0.0
|
||||
"@types/is-windows": ^1.0.2
|
||||
"@types/js-yaml": ^4.0.9
|
||||
"@types/lodash.kebabcase": 4.1.9
|
||||
"@types/lodash.throttle": 4.1.7
|
||||
"@types/micromatch": ^4.0.9
|
||||
"@types/node": ^18.19.34
|
||||
@@ -184,6 +185,7 @@ catalog:
|
||||
jest-diff: ^29.7.0
|
||||
json5: ^2.2.3
|
||||
load-json-file: ^6.2.0
|
||||
lodash.kebabcase: ^4.1.1
|
||||
lodash.throttle: 4.1.1
|
||||
loud-rejection: ^2.2.0
|
||||
lru-cache: ^10.4.3
|
||||
|
||||
Reference in New Issue
Block a user