Skip to content

Commit de319e8

Browse files
committed
fix: allow overriding path to npm bin in workspaces
1 parent cad156a commit de319e8

File tree

3 files changed

+54
-23
lines changed

3 files changed

+54
-23
lines changed

lib/config.js

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,36 @@ const deglob = (v) => makePosix(v).replace(/[/*]+$/, '')
2222
const posixDir = (v) => `${v === '.' ? '' : deglob(v).replace(/\/$/, '')}${posix.sep}`
2323
const posixGlob = (str) => `${posixDir(str)}**`
2424

25-
const getCmdPath = (key, { rootConfig, defaultConfig, isRoot, pkg, rootPkg }) => {
26-
// Make a path relative from a workspace to the root if we are in a workspace
27-
const wsToRoot = (p) => isRoot ? p : makePosix(join(relative(pkg.path, rootPkg.path), p))
25+
const getCmdPath = (key, { pkgConfig, rootConfig, isRoot, pkg, rootPkg }) => {
26+
const result = (local, isRelative) => {
27+
let root = local
28+
const isLocal = local.startsWith('.') || local.startsWith('/')
29+
30+
if (isLocal) {
31+
if (isRelative) {
32+
// Make a path relative from a workspace to the root if we are in a workspace
33+
local = makePosix(join(relative(pkg.path, rootPkg.path), local))
34+
}
35+
local = `node ${local}`
36+
root = `node ${root}`
37+
}
2838

29-
const rootPath = rootConfig[key]
30-
const defaultPath = defaultConfig[key]
31-
const isLocal = rootPath && rootPath !== defaultPath
39+
return {
40+
isLocal,
41+
local,
42+
root,
43+
}
44+
}
3245

33-
return {
34-
isLocal,
35-
root: !isLocal ? defaultPath : `node ${rootPath}`,
36-
local: !isLocal ? defaultPath : `node ${wsToRoot(rootPath)}`,
46+
if (pkgConfig[key]) {
47+
return result(pkgConfig[key])
3748
}
49+
50+
if (rootConfig[key]) {
51+
return result(rootConfig[key], !isRoot)
52+
}
53+
54+
return result(key)
3855
}
3956

4057
const mergeConfigs = (...configs) => {
@@ -138,9 +155,8 @@ const getFullConfig = async ({
138155
] : [],
139156
]
140157

141-
// root only configs
142-
const npmPath = getCmdPath('npm', { rootConfig, defaultConfig, isRoot, pkg, rootPkg })
143-
const npxPath = getCmdPath('npx', { rootConfig, defaultConfig, isRoot, pkg, rootPkg })
158+
const npmPath = getCmdPath('npm', { pkgConfig, rootConfig, isRoot, pkg, rootPkg })
159+
const npxPath = getCmdPath('npx', { pkgConfig, rootConfig, isRoot, pkg, rootPkg })
144160

145161
// these are written to ci yml files so it needs to always use posix
146162
const pkgPath = makePosix(relative(rootPkg.path, pkg.path)) || '.'

lib/content/index.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,6 @@ module.exports = {
163163
codeowner: '@npm/cli-team',
164164
eslint: true,
165165
publish: false,
166-
npm: 'npm',
167-
npx: 'npx',
168166
updateNpm: true,
169167
dependabot: 'increase-if-necessary',
170168
unwantedPackages: [

test/apply/npm-bin.js

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,33 @@ t.test('relative npm bin with workspaces', async (t) => {
2121
ok: true,
2222
package: {
2323
templateOSS: {
24-
npm: 'cli.js',
24+
content: 'rootContent',
2525
},
2626
},
27-
workspaces: { a: '@name/aaaa', b: 'bbb' },
27+
workspaces: {
28+
a: 'a',
29+
b: { name: 'b', templateOSS: { npm: './local-workspace-cli.js' } },
30+
c: { name: 'c', templateOSS: { npm: 'npm' } },
31+
d: { name: 'd', templateOSS: { content: '../../wsContent' } },
32+
e: { name: 'e', templateOSS: { content: '../../wsContent', npm: 'npm' } },
33+
},
34+
testdir: {
35+
rootContent: { 'index.js': 'module.exports={ npm: "./cli.js" }' },
36+
wsContent: { 'index.js': 'module.exports={ npm: "../../cli.js" }' },
37+
},
2838
})
2939
await s.apply()
30-
const { scripts } = await s.readJson('package.json')
31-
const { scripts: scriptsA } = await s.readJson(join(s.workspaces.a, 'package.json'))
32-
const { scripts: scriptsB } = await s.readJson(join(s.workspaces.b, 'package.json'))
33-
t.equal(scripts.posttest, 'node cli.js run lint')
34-
t.equal(scriptsA.posttest, 'node ../../cli.js run lint')
35-
t.equal(scriptsB.posttest, 'node ../../cli.js run lint')
40+
41+
const readScripts = (p) => s.readJson(join(p, 'package.json')).then(r => r.scripts)
42+
43+
const ws = s.workspaces
44+
const pkgs = ['', ws.a, ws.b, ws.c, ws.d, ws.e]
45+
const [root, a, b, c, d, e] = await Promise.all(pkgs.map(readScripts))
46+
47+
t.equal(root.posttest, 'node ./cli.js run lint')
48+
t.equal(a.posttest, 'node ../../cli.js run lint')
49+
t.equal(b.posttest, 'node ./local-workspace-cli.js run lint')
50+
t.equal(c.posttest, 'npm run lint')
51+
t.equal(d.posttest, 'node ../../cli.js run lint')
52+
t.equal(e.posttest, 'npm run lint')
3653
})

0 commit comments

Comments
 (0)