Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bun package manager #11267

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions npm_and_yarn/lib/dependabot/npm_and_yarn/bun_package_manager.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# typed: strong
# frozen_string_literal: true

module Dependabot
module NpmAndYarn
class BunPackageManager < Ecosystem::VersionManager
extend T::Sig
NAME = "bun"
LOCKFILE_NAME = "bun.lock"

# In Bun 1.1.39, the lockfile format was changed from a binary bun.lockb to a text-based bun.lock.
# https://bun.sh/blog/bun-lock-text-lockfile
MIN_SUPPORTED_VERSION = Version.new("1.1.39")
SUPPORTED_VERSIONS = T.let([MIN_SUPPORTED_VERSION].freeze, T::Array[Dependabot::Version])
DEPRECATED_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])

sig do
params(
detected_version: T.nilable(String),
raw_version: T.nilable(String),
requirement: T.nilable(Dependabot::NpmAndYarn::Requirement)
).void
end
def initialize(detected_version: nil, raw_version: nil, requirement: nil)
super(
name: NAME,
detected_version: detected_version ? Version.new(detected_version) : nil,
version: raw_version ? Version.new(raw_version) : nil,
deprecated_versions: DEPRECATED_VERSIONS,
supported_versions: SUPPORTED_VERSIONS,
requirement: requirement
)
end

sig { override.returns(T::Boolean) }
def deprecated?
false
end

sig { override.returns(T::Boolean) }
def unsupported?
supported_versions.all? { |supported| supported > version }
end
end
end
end
45 changes: 45 additions & 0 deletions npm_and_yarn/lib/dependabot/npm_and_yarn/language.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# typed: strong
# frozen_string_literal: true

require "dependabot/npm_and_yarn/package_manager"

module Dependabot
module NpmAndYarn
class Language < Ecosystem::VersionManager
extend T::Sig
NAME = "node"

SUPPORTED_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])

DEPRECATED_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])

sig do
params(
detected_version: T.nilable(String),
raw_version: T.nilable(String),
requirement: T.nilable(Dependabot::NpmAndYarn::Requirement)
).void
end
def initialize(detected_version: nil, raw_version: nil, requirement: nil)
super(
name: NAME,
detected_version: detected_version ? Version.new(detected_version) : nil,
version: raw_version ? Version.new(raw_version) : nil,
deprecated_versions: DEPRECATED_VERSIONS,
supported_versions: SUPPORTED_VERSIONS,
requirement: requirement
)
end

sig { override.returns(T::Boolean) }
def deprecated?
false
end

sig { override.returns(T::Boolean) }
def unsupported?
false
end
end
end
end
70 changes: 70 additions & 0 deletions npm_and_yarn/lib/dependabot/npm_and_yarn/npm_package_manager.rb
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@markhallen ,

Is there a reason we recreated package manager for npm, pnpm and yarn? There in PackageManagerHelper normally?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I extracted these out as the package_manager.rb file was becoming very big. They have not changed and the specs still pass. They just live in new files.

Copy link
Contributor

@kbukum1 kbukum1 Jan 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see but as per our discussion I thought we are going to keep the bun completely seperated. The reason why npm, pnpm, yarn are together because they share the same flow. However for bun you shouldn't need that so, maybe it is not good to make changes for npm, pnpm, and yarn while working for bun. Later when we seperate ecosystems definitely it is going to be individual package manager files for each of them as it is for other ecosystems.

Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# typed: strong
# frozen_string_literal: true

require "dependabot/npm_and_yarn/package_manager"

module Dependabot
module NpmAndYarn
class NpmPackageManager < Ecosystem::VersionManager
extend T::Sig
NAME = "npm"
RC_FILENAME = ".npmrc"
LOCKFILE_NAME = "package-lock.json"
SHRINKWRAP_LOCKFILE_NAME = "npm-shrinkwrap.json"

NPM_V6 = "6"
NPM_V7 = "7"
NPM_V8 = "8"
NPM_V9 = "9"
NPM_V10 = "10"

# Keep versions in ascending order
SUPPORTED_VERSIONS = T.let([
Version.new(NPM_V7),
Version.new(NPM_V8),
Version.new(NPM_V9),
Version.new(NPM_V10)
].freeze, T::Array[Dependabot::Version])

DEPRECATED_VERSIONS = T.let([Version.new(NPM_V6)].freeze, T::Array[Dependabot::Version])

sig do
params(
detected_version: T.nilable(String),
raw_version: T.nilable(String),
requirement: T.nilable(Dependabot::NpmAndYarn::Requirement)
).void
end
def initialize(detected_version: nil, raw_version: nil, requirement: nil)
super(
name: NAME,
detected_version: detected_version ? Version.new(detected_version) : nil,
version: raw_version ? Version.new(raw_version) : nil,
deprecated_versions: DEPRECATED_VERSIONS,
supported_versions: SUPPORTED_VERSIONS,
requirement: requirement
)
end

sig { override.returns(T::Boolean) }
def deprecated?
return false unless detected_version

return false if unsupported?

return false unless Dependabot::Experiments.enabled?(:npm_v6_deprecation_warning)

deprecated_versions.include?(detected_version)
end

sig { override.returns(T::Boolean) }
def unsupported?
return false unless detected_version

return false unless Dependabot::Experiments.enabled?(:npm_v6_unsupported_error)

supported_versions.all? { |supported| supported > detected_version }
end
end
end
end
199 changes: 5 additions & 194 deletions npm_and_yarn/lib/dependabot/npm_and_yarn/package_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
require "dependabot/npm_and_yarn/requirement"
require "dependabot/npm_and_yarn/version_selector"
require "dependabot/npm_and_yarn/registry_helper"
require "dependabot/npm_and_yarn/npm_package_manager"
require "dependabot/npm_and_yarn/yarn_package_manager"
require "dependabot/npm_and_yarn/pnpm_package_manager"
require "dependabot/npm_and_yarn/bun_package_manager"
require "dependabot/npm_and_yarn/language"

module Dependabot
module NpmAndYarn
Expand Down Expand Up @@ -47,163 +52,6 @@ module NpmAndYarn
MANIFEST_PACKAGE_MANAGER_KEY = "packageManager"
MANIFEST_ENGINES_KEY = "engines"

class NpmPackageManager < Ecosystem::VersionManager
extend T::Sig
NAME = "npm"
RC_FILENAME = ".npmrc"
LOCKFILE_NAME = "package-lock.json"
SHRINKWRAP_LOCKFILE_NAME = "npm-shrinkwrap.json"

NPM_V6 = "6"
NPM_V7 = "7"
NPM_V8 = "8"
NPM_V9 = "9"
NPM_V10 = "10"

# Keep versions in ascending order
SUPPORTED_VERSIONS = T.let([
Version.new(NPM_V7),
Version.new(NPM_V8),
Version.new(NPM_V9),
Version.new(NPM_V10)
].freeze, T::Array[Dependabot::Version])

DEPRECATED_VERSIONS = T.let([Version.new(NPM_V6)].freeze, T::Array[Dependabot::Version])

sig do
params(
detected_version: T.nilable(String),
raw_version: T.nilable(String),
requirement: T.nilable(Dependabot::NpmAndYarn::Requirement)
).void
end
def initialize(detected_version: nil, raw_version: nil, requirement: nil)
super(
name: NAME,
detected_version: detected_version ? Version.new(detected_version) : nil,
version: raw_version ? Version.new(raw_version) : nil,
deprecated_versions: DEPRECATED_VERSIONS,
supported_versions: SUPPORTED_VERSIONS,
requirement: requirement
)
end

sig { override.returns(T::Boolean) }
def deprecated?
return false unless detected_version

return false if unsupported?

return false unless Dependabot::Experiments.enabled?(:npm_v6_deprecation_warning)

deprecated_versions.include?(detected_version)
end

sig { override.returns(T::Boolean) }
def unsupported?
return false unless detected_version

return false unless Dependabot::Experiments.enabled?(:npm_v6_unsupported_error)

supported_versions.all? { |supported| supported > detected_version }
end
end

class YarnPackageManager < Ecosystem::VersionManager
extend T::Sig
NAME = "yarn"
RC_FILENAME = ".yarnrc"
RC_YML_FILENAME = ".yarnrc.yml"
LOCKFILE_NAME = "yarn.lock"

YARN_V1 = "1"
YARN_V2 = "2"
YARN_V3 = "3"

SUPPORTED_VERSIONS = T.let([
Version.new(YARN_V1),
Version.new(YARN_V2),
Version.new(YARN_V3)
].freeze, T::Array[Dependabot::Version])

DEPRECATED_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])

sig do
params(
detected_version: T.nilable(String),
raw_version: T.nilable(String),
requirement: T.nilable(Dependabot::NpmAndYarn::Requirement)
).void
end
def initialize(detected_version: nil, raw_version: nil, requirement: nil)
super(
name: NAME,
detected_version: detected_version ? Version.new(detected_version) : nil,
version: raw_version ? Version.new(raw_version) : nil,
deprecated_versions: DEPRECATED_VERSIONS,
supported_versions: SUPPORTED_VERSIONS,
requirement: requirement
)
end

sig { override.returns(T::Boolean) }
def deprecated?
false
end

sig { override.returns(T::Boolean) }
def unsupported?
false
end
end

class PNPMPackageManager < Ecosystem::VersionManager
extend T::Sig
NAME = "pnpm"
LOCKFILE_NAME = "pnpm-lock.yaml"
PNPM_WS_YML_FILENAME = "pnpm-workspace.yaml"

PNPM_V7 = "7"
PNPM_V8 = "8"
PNPM_V9 = "9"

SUPPORTED_VERSIONS = T.let([
Version.new(PNPM_V7),
Version.new(PNPM_V8),
Version.new(PNPM_V9)
].freeze, T::Array[Dependabot::Version])

DEPRECATED_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])

sig do
params(
detected_version: T.nilable(String),
raw_version: T.nilable(String),
requirement: T.nilable(Dependabot::NpmAndYarn::Requirement)
).void
end
def initialize(detected_version: nil, raw_version: nil, requirement: nil)
super(
name: NAME,
detected_version: detected_version ? Version.new(detected_version) : nil,
version: raw_version ? Version.new(raw_version) : nil,
deprecated_versions: DEPRECATED_VERSIONS,
supported_versions: SUPPORTED_VERSIONS,
requirement: requirement
)
end

sig { override.returns(T::Boolean) }
def deprecated?
false
end

sig { override.returns(T::Boolean) }
def unsupported?
false
end
end

DEFAULT_PACKAGE_MANAGER = NpmPackageManager::NAME

# Define a type alias for the expected class interface
Expand Down Expand Up @@ -285,43 +133,6 @@ def name_from_engines
end
end

class Language < Ecosystem::VersionManager
extend T::Sig
NAME = "node"

SUPPORTED_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])

DEPRECATED_VERSIONS = T.let([].freeze, T::Array[Dependabot::Version])

sig do
params(
detected_version: T.nilable(String),
raw_version: T.nilable(String),
requirement: T.nilable(Dependabot::NpmAndYarn::Requirement)
).void
end
def initialize(detected_version: nil, raw_version: nil, requirement: nil)
super(
name: NAME,
detected_version: detected_version ? Version.new(detected_version) : nil,
version: raw_version ? Version.new(raw_version) : nil,
deprecated_versions: DEPRECATED_VERSIONS,
supported_versions: SUPPORTED_VERSIONS,
requirement: requirement
)
end

sig { override.returns(T::Boolean) }
def deprecated?
false
end

sig { override.returns(T::Boolean) }
def unsupported?
false
end
end

class PackageManagerHelper
extend T::Sig
extend T::Helpers
Expand Down
Loading
Loading