Skip to content

Commit

Permalink
Update NPM Default and Fallback Versions to NPM 8 (#10757)
Browse files Browse the repository at this point in the history
* replace npm version detection as minimum npm 8 if `npm_fallback_version_above_v6` is enabled
* add log for detected version
  • Loading branch information
kbukum1 authored Oct 9, 2024
1 parent 0a80a72 commit 3b714de
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 18 deletions.
91 changes: 74 additions & 17 deletions npm_and_yarn/lib/dependabot/npm_and_yarn/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,82 @@ module Helpers
YARN_PATH_NOT_FOUND =
/^.*(?<error>The "yarn-path" option has been set \(in [^)]+\), but the specified location doesn't exist)/

# NPM Version Constants
NPM_V9 = 9
NPM_V8 = 8
NPM_V6 = 6
NPM_DEFAULT_VERSION = NPM_V8

# PNPM Version Constants
PNPM_V9 = 9
PNPM_V8 = 8
PNPM_V7 = 7
PNPM_V6 = 6
PNPM_DEFAULT_VERSION = PNPM_V9
PNPM_FALLBACK_VERSION = PNPM_V6

# YARN Version Constants
YARN_V3 = 3
YARN_V2 = 2
YARN_V1 = 1
YARN_DEFAULT_VERSION = YARN_V3
YARN_FALLBACK_VERSION = YARN_V1

# Determines the npm version depends to the feature flag
# If the feature flag is enabled, we are going to use the minimum version npm 8
# Otherwise, we are going to use old versionining npm 6
sig { params(lockfile: DependencyFile).returns(Integer) }
def self.npm_version_numeric(lockfile)
fallback_version_npm8 = Dependabot::Experiments.enabled?(:npm_fallback_version_above_v6)

return npm_version_numeric_npm8_or_higher(lockfile) if fallback_version_npm8

npm_version_numeric_npm6_or_higher(lockfile)
end

sig { params(lockfile: DependencyFile).returns(Integer) }
def self.npm_version_numeric_npm6_or_higher(lockfile)
lockfile_content = T.must(lockfile.content)
return 8 if JSON.parse(lockfile_content)["lockfileVersion"].to_i >= 2
return NPM_V8 if JSON.parse(lockfile_content)["lockfileVersion"].to_i >= 2

6
NPM_V6
rescue JSON::ParserError
6
NPM_V6
end

# Determines the npm version based on the lockfile version
# - NPM 7 uses lockfileVersion 2
# - NPM 8 uses lockfileVersion 2
# - NPM 9 uses lockfileVersion 3
sig { params(lockfile: DependencyFile).returns(Integer) }
def self.npm_version_numeric_npm8_or_higher(lockfile)
lockfile_content = lockfile.content

# Return default NPM version if there's no lockfile or it's empty
return NPM_DEFAULT_VERSION if lockfile_content.nil? || lockfile_content.strip.empty?

parsed_lockfile = JSON.parse(lockfile_content)

lockfile_version_str = parsed_lockfile["lockfileVersion"]

# Default to npm default version if lockfileVersion is missing or empty
return NPM_DEFAULT_VERSION if lockfile_version_str.nil? || lockfile_version_str.to_s.strip.empty?

lockfile_version = lockfile_version_str.to_i

return NPM_V9 if lockfile_version == 3

NPM_DEFAULT_VERSION
rescue JSON::ParserError
NPM_DEFAULT_VERSION # Fallback to default npm version if parsing fails
end

sig { params(yarn_lock: DependencyFile).returns(Integer) }
def self.yarn_version_numeric(yarn_lock)
if yarn_berry?(yarn_lock)
3
YARN_DEFAULT_VERSION
else
1
YARN_FALLBACK_VERSION
end
end

Expand All @@ -38,15 +98,12 @@ def self.yarn_version_numeric(yarn_lock)

sig { params(pnpm_lock: DependencyFile).returns(Integer) }
def self.pnpm_version_numeric(pnpm_lock)
if pnpm_lockfile_version(pnpm_lock).to_f >= 9.0
9
elsif pnpm_lockfile_version(pnpm_lock).to_f >= 6.0
8
elsif pnpm_lockfile_version(pnpm_lock).to_f >= 5.4
7
else
6
end
pnpm_lockfile_version = pnpm_lockfile_version(pnpm_lock).to_f
return PNPM_V9 if pnpm_lockfile_version >= 9.0
return PNPM_V8 if pnpm_lockfile_version >= 6.0
return PNPM_V7 if pnpm_lockfile_version >= 5.4

PNPM_FALLBACK_VERSION
end

def self.fetch_yarnrc_yml_value(key, default_value)
Expand All @@ -61,7 +118,7 @@ def self.fetch_yarnrc_yml_value(key, default_value)
def self.npm8?(package_lock)
return true unless package_lock

npm_version_numeric(package_lock) == 8
npm_version_numeric(package_lock) == NPM_V8
end

sig { params(yarn_lock: T.nilable(DependencyFile)).returns(T::Boolean) }
Expand Down Expand Up @@ -140,12 +197,12 @@ def self.yarn_berry_args

sig { returns(T::Boolean) }
def self.yarn_berry_skip_build?
yarn_major_version >= 3 && (yarn_zero_install? || yarn_offline_cache?)
yarn_major_version >= YARN_V3 && (yarn_zero_install? || yarn_offline_cache?)
end

sig { returns(T::Boolean) }
def self.yarn_berry_disable_scripts?
yarn_major_version == 2 || !yarn_zero_install?
yarn_major_version == YARN_V2 || !yarn_zero_install?
end

sig { returns(T::Boolean) }
Expand Down
6 changes: 5 additions & 1 deletion npm_and_yarn/lib/dependabot/npm_and_yarn/package_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,11 @@ def guessed_version(name)
lockfile = @lockfiles[name.to_sym]
return unless lockfile

Helpers.send(:"#{name}_version_numeric", lockfile)
version = Helpers.send(:"#{name}_version_numeric", lockfile)

Dependabot.logger.info("Guessed version info \"#{name}\" : \"#{version}\"")

version
end

sig { params(name: T.untyped).returns(T.nilable(String)) }
Expand Down

0 comments on commit 3b714de

Please sign in to comment.