diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn/file_parser/pnpm_lock.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn/file_parser/pnpm_lock.rb index 5bcee19a1f..2fac653f1c 100644 --- a/npm_and_yarn/lib/dependabot/npm_and_yarn/file_parser/pnpm_lock.rb +++ b/npm_and_yarn/lib/dependabot/npm_and_yarn/file_parser/pnpm_lock.rb @@ -26,6 +26,10 @@ def parsed end def dependencies + if Dependabot::Experiments.enabled?(:enable_fix_for_pnpm_no_change_error) + return dependencies_with_prioritization + end + dependency_set = Dependabot::FileParsers::Base::DependencySet.new parsed.each do |details| @@ -52,6 +56,49 @@ def dependencies dependency_set end + def dependencies_with_prioritization + dependency_set = Dependabot::FileParsers::Base::DependencySet.new + + # Separate dependencies into two categories: with specifiers and without specifiers. + dependencies_with_specifiers = [] # Main dependencies with specifiers. + dependencies_without_specifiers = [] # Subdependencies without specifiers. + + parsed.each do |details| + next if details["aliased"] + + name = details["name"] + version = details["version"] + + dependency_args = { + name: name, + version: version, + package_manager: "npm_and_yarn", + requirements: [] + } + + # Add metadata for subdependencies if marked as a dev dependency. + dependency_args[:subdependency_metadata] = [{ production: !details["dev"] }] if details["dev"] + + specifiers = details["specifiers"] + if specifiers&.any? + dependencies_with_specifiers << dependency_args + else + dependencies_without_specifiers << dependency_args + end + end + + # Add prioritized dependencies to the dependency set. + dependencies_with_specifiers.each do |dependency_args| + dependency_set << Dependency.new(**dependency_args) + end + + dependencies_without_specifiers.each do |dependency_args| + dependency_set << Dependency.new(**dependency_args) + end + + dependency_set + end + def details(dependency_name, requirement, _manifest_name) details_candidates = parsed.select { |info| info["name"] == dependency_name } diff --git a/npm_and_yarn/spec/dependabot/npm_and_yarn/file_parser_spec.rb b/npm_and_yarn/spec/dependabot/npm_and_yarn/file_parser_spec.rb index 64e5d249fd..186cb4f959 100644 --- a/npm_and_yarn/spec/dependabot/npm_and_yarn/file_parser_spec.rb +++ b/npm_and_yarn/spec/dependabot/npm_and_yarn/file_parser_spec.rb @@ -46,6 +46,8 @@ .with(:enable_shared_helpers_command_timeout).and_return(true) allow(Dependabot::Experiments).to receive(:enabled?) .with(:npm_v6_deprecation_warning).and_return(true) + allow(Dependabot::Experiments).to receive(:enabled?) + .with(:enable_fix_for_pnpm_no_change_error).and_return(true) end after do diff --git a/npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater/pnpm_lockfile_updater_spec.rb b/npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater/pnpm_lockfile_updater_spec.rb index cbed3e77ff..b465239d2c 100644 --- a/npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater/pnpm_lockfile_updater_spec.rb +++ b/npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater/pnpm_lockfile_updater_spec.rb @@ -72,6 +72,8 @@ .with(:enable_corepack_for_npm_and_yarn).and_return(enable_corepack_for_npm_and_yarn) allow(Dependabot::Experiments).to receive(:enabled?) .with(:enable_shared_helpers_command_timeout).and_return(true) + allow(Dependabot::Experiments).to receive(:enabled?) + .with(:enable_fix_for_pnpm_no_change_error).and_return(true) end after do diff --git a/npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater_spec.rb b/npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater_spec.rb index a96a61038f..4401883567 100644 --- a/npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater_spec.rb +++ b/npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater_spec.rb @@ -72,6 +72,8 @@ .with(:enable_shared_helpers_command_timeout).and_return(true) allow(Dependabot::Experiments).to receive(:enabled?) .with(:npm_v6_deprecation_warning).and_return(true) + allow(Dependabot::Experiments).to receive(:enabled?) + .with(:enable_fix_for_pnpm_no_change_error).and_return(true) end after do diff --git a/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver_spec.rb b/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver_spec.rb index 290a2e6b4d..5f01492305 100644 --- a/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver_spec.rb +++ b/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver_spec.rb @@ -45,6 +45,8 @@ .with(:enable_shared_helpers_command_timeout).and_return(true) allow(Dependabot::Experiments).to receive(:enabled?) .with(:npm_v6_deprecation_warning).and_return(true) + allow(Dependabot::Experiments).to receive(:enabled?) + .with(:enable_fix_for_pnpm_no_change_error).and_return(true) end after do diff --git a/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/version_resolver_spec.rb b/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/version_resolver_spec.rb index 778745eb63..aeb5f22a07 100644 --- a/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/version_resolver_spec.rb +++ b/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/version_resolver_spec.rb @@ -87,6 +87,8 @@ .with(:enable_shared_helpers_command_timeout).and_return(true) allow(Dependabot::Experiments).to receive(:enabled?) .with(:npm_v6_deprecation_warning).and_return(true) + allow(Dependabot::Experiments).to receive(:enabled?) + .with(:enable_fix_for_pnpm_no_change_error).and_return(true) end after do