Skip to content

Commit

Permalink
Fail on conflicting package manager metadata in package.json
Browse files Browse the repository at this point in the history
Along with lockfile detection, we also detect what intended package manager (and version) should be used based on metadata found in package.json. When multiple package managers are  declared we should fail the build early and ask the user to correct any conflicts found.

Related to #1313
  • Loading branch information
colincasey committed Sep 4, 2024
1 parent 15350cd commit 99a2b5f
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 0 deletions.
1 change: 1 addition & 0 deletions bin/compile
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ fail_dot_heroku "$BUILD_DIR"
fail_dot_heroku_node "$BUILD_DIR"
fail_invalid_package_json "$BUILD_DIR"
fail_multiple_lockfiles "$BUILD_DIR"
fail_conflicting_package_manager_metadata "$BUILD_DIR"
fail_iojs_unsupported "$BUILD_DIR"
warn_prebuilt_modules "$BUILD_DIR"
warn_missing_package_json "$BUILD_DIR"
Expand Down
49 changes: 49 additions & 0 deletions lib/failure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1007,3 +1007,52 @@ warn_about_node_version_22_5_0() {
" "https://github.com/nodejs/node/pull/53934"
mcount 'warnings.node.22-5-0'
}

fail_conflicting_package_manager_metadata() {
# track the package managers we see in an associative array
declare -A package_managers
declare -a fields_detected

npm_engine=$(read_json "$BUILD_DIR/package.json" ".engines.npm")
yarn_engine=$(read_json "$BUILD_DIR/package.json" ".engines.yarn")
pnpm_engine=$(read_json "$BUILD_DIR/package.json" ".engines.pnpm")
package_manager=$(read_json "$BUILD_DIR/package.json" ".packageManager")

if [ -n "$npm_engine" ]; then
package_managers["npm"]=0
fields_detected+=("- npm version detected in engines.npm ($npm_engine)")
fi

if [ -n "$yarn_engine" ]; then
package_managers["yarn"]=0
fields_detected+=("- yarn version declared in engines.yarn ($yarn_engine)")
fi

if [ -n "$pnpm_engine" ]; then
package_managers["pnpm"]=0
fields_detected+=("- pnpm version declared in engines.pnpm ($pnpm_engine)")
fi

if [[ "$package_manager" == yarn* ]]; then
package_managers["yarn"]=0
fields_detected+=("- yarn version declared in packageManager ($package_manager)")
elif [[ "$package_manager" == pnpm* ]]; then
package_managers["pnpm"]=0
fields_detected+=("- pnpm version declared in packageManager ($package_manager)")
fi

# was there more than one package manager found?
if (( "${#package_managers[@]}" > 1 )); then
mcount "failures.multiple-package-managers"
meta_set "failure" "multiple-package-managers"
header "Build failed"
warn "Multiple package managers declared in package.json
Installing dependencies using the wrong package manager can result in missing packages or subtle bugs
in production. Only one of the following fields should be used, all others should be removed:
$(for item in "${fields_detected[@]}"; do echo " $item"; done)
"
fail
fi
}
11 changes: 11 additions & 0 deletions test/fixtures/conflicting-package-manager-metadata/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "conflicting-package-manager-metadata",
"version": "1.0.0",
"license": "ISC",
"packageManager": "[email protected]",
"engines": {
"npm": "10.x",
"yarn": "4.x",
"pnpm": "9.x"
}
}
10 changes: 10 additions & 0 deletions test/run
Original file line number Diff line number Diff line change
Expand Up @@ -2018,6 +2018,16 @@ testWarningNode_22_5_0() {
assertCapturedSuccess
}

testConflictingPackageManagerMetadata() {
compile "conflicting-package-manager-metadata"
assertCaptured "Multiple package managers declared in package.json"
assertCaptured "- npm version detected in engines.npm (10.x)"
assertCaptured "- yarn version declared in engines.yarn (4.x)"
assertCaptured "- pnpm version declared in engines.pnpm (9.x)"
assertCaptured "- pnpm version declared in packageManager ([email protected])"
assertCapturedError
}

# Utils

pushd "$(dirname 0)" >/dev/null
Expand Down

0 comments on commit 99a2b5f

Please sign in to comment.