Skip to content

Commit ea99eb2

Browse files
committed
fix(cli,icongenie,create-quasar): pnpm >= 11 aborted installs over unapproved build scripts
Same defect just fixed in app-vite: pnpm 11 turned "Ignored build scripts" into a fatal error (pnpm 10 only warned), so a dependency with an unapproved build script anywhere in the tree made "pnpm add"/"pnpm install" exit 1 even though the packages did install. That left "quasar upgrade" with the package.json versions bumped and nothing installed to match, had icongenie report "Failed to install @capacitor/splash-screen" for a package that is in fact there, and made create-quasar declare a fresh project's install a failure (dropping its lint and dev-command steps with it). Their pnpm install/add params now carry --config.strict-dep-builds=false (accepted by pnpm 9/10/11), which only drops the fatal exit: same resolution, byte-identical lockfile, build scripts still not run, notice still printed. The user resolves the ignored builds with "pnpm approve-builds" on their own time and their own installs keep enforcing whatever they configured.
1 parent d34677b commit ea99eb2

4 files changed

Lines changed: 57 additions & 6 deletions

File tree

cli/lib/node-packager.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,16 +275,32 @@ class Yarn extends PackageManager {
275275
}
276276
}
277277

278+
// pnpm >= 11 exits with an error when any dependency in the tree has a build
279+
// script that was not approved (pnpm 10 only warned about it), even though the
280+
// packages did get installed. "quasar upgrade" must not abort over that, with
281+
// the package.json versions already bumped but nothing installed to match —
282+
// the user resolves it with "pnpm approve-builds" on their own time, and their
283+
// own installs keep enforcing whatever they configured.
284+
// Unknown "--config.<key>" params are accepted by any pnpm version.
285+
const pnpmIgnoredBuildsParam = '--config.strict-dep-builds=false'
286+
278287
class Pnpm extends PackageManager {
279288
name = 'pnpm'
280289
lockFiles = ['pnpm-lock.yaml']
281290

282291
getInstallParams(env) {
283-
return env === 'development' ? ['install'] : ['install', '--prod']
292+
return env === 'development'
293+
? ['install', pnpmIgnoredBuildsParam]
294+
: ['install', '--prod', pnpmIgnoredBuildsParam]
284295
}
285296

286297
getInstallPackageParams(names, isDevDependency) {
287-
return ['add', isDevDependency ? '--save-dev' : '', ...names]
298+
return [
299+
'add',
300+
pnpmIgnoredBuildsParam,
301+
isDevDependency ? '--save-dev' : '',
302+
...names
303+
]
288304
}
289305

290306
getUninstallPackageParams(names) {

cli/lib/node-packager.test.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,33 @@ describe('[node-packager.js]', () => {
5959
makeProjectDir('npm-params', 'package-lock.json')
6060
)
6161

62+
// pnpm >= 11 fails the command over unapproved build scripts anywhere in
63+
// the tree, so every pnpm install params list opts out of that
64+
const noStrictBuilds = '--config.strict-dep-builds=false'
65+
6266
test('build the package manager specific install arguments', () => {
63-
expect(pnpm.getInstallParams('development')).toEqual(['install'])
64-
expect(pnpm.getInstallParams('production')).toEqual(['install', '--prod'])
67+
expect(pnpm.getInstallParams('development')).toEqual([
68+
'install',
69+
noStrictBuilds
70+
])
71+
expect(pnpm.getInstallParams('production')).toEqual([
72+
'install',
73+
'--prod',
74+
noStrictBuilds
75+
])
6576
expect(npm.getInstallParams('development')).toEqual(['install'])
6677
})
6778

6879
test('build the add/remove package arguments', () => {
6980
expect(pnpm.getInstallPackageParams(['quasar'], false)).toEqual([
7081
'add',
82+
noStrictBuilds,
7183
'',
7284
'quasar'
7385
])
7486
expect(pnpm.getInstallPackageParams(['quasar'], true)).toEqual([
7587
'add',
88+
noStrictBuilds,
7689
'--save-dev',
7790
'quasar'
7891
])

create-quasar/lib/utils.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,16 @@ async function runCommand({
258258
async function installDeps(scope) {
259259
const hadError = await runCommand({
260260
cmd: scope.install,
261-
args: ['install'],
261+
args:
262+
scope.install === 'pnpm'
263+
? // pnpm >= 11 exits with an error when any dependency in the tree has
264+
// a build script that was not approved (pnpm 10 only warned about
265+
// it), even though the packages did get installed — we would then
266+
// wrongly declare the fresh project's install a failure. The user
267+
// resolves those with "pnpm approve-builds" on their own time, and
268+
// their own installs from here on keep enforcing it.
269+
['install', '--config.strict-dep-builds=false']
270+
: ['install'],
262271
cwd: scope.projectFolder,
263272
message: `Installing dependencies using ${scope.install.toUpperCase()}...`,
264273
successMessage: 'Dependencies installed successfully!',

icongenie/lib/utils/package-manager.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,17 +155,30 @@ class Yarn extends PackageManager {
155155
}
156156
}
157157

158+
// pnpm >= 11 exits with an error when any dependency in the tree has a build
159+
// script that was not approved (pnpm 10 only warned about it), even though the
160+
// packages did get installed — which would have us report "Failed to install"
161+
// for a package that is in fact there. The user resolves the ignored builds
162+
// with "pnpm approve-builds" on their own time; their own installs keep
163+
// enforcing whatever they configured. It is a no-op next to
164+
// "--dangerously-allow-all-builds" (nothing is ignored then), and unknown
165+
// "--config.<key>" params are accepted by any pnpm version.
166+
const pnpmIgnoredBuildsParam = '--config.strict-dep-builds=false'
167+
158168
class Pnpm extends PackageManager {
159169
name = 'pnpm'
160170
lockFiles = ['pnpm-lock.yaml']
161171

162172
getInstallParams(env) {
163-
return env === 'development' ? ['install'] : ['install', '--prod']
173+
return env === 'development'
174+
? ['install', pnpmIgnoredBuildsParam]
175+
: ['install', '--prod', pnpmIgnoredBuildsParam]
164176
}
165177

166178
getInstallPackageParams(names, isDevDependency, allowBuilds) {
167179
return [
168180
'add',
181+
pnpmIgnoredBuildsParam,
169182
isDevDependency ? '--save-dev' : '',
170183
allowBuilds ? '--dangerously-allow-all-builds' : '',
171184
...names

0 commit comments

Comments
 (0)