diff --git a/npm_and_yarn/Dockerfile b/npm_and_yarn/Dockerfile index 25dca396ea..610a9b2393 100644 --- a/npm_and_yarn/Dockerfile +++ b/npm_and_yarn/Dockerfile @@ -9,6 +9,8 @@ ARG PNPM_VERSION=9.15.3 # Check for updates at https://github.com/yarnpkg/berry/releases ARG YARN_VERSION=4.5.3 +# Check for updates at https://github.com/oven-sh/bun/releases +ARG BUN_VERSION=1.1.39 # See https://github.com/nodesource/distributions#installation-instructions ARG NODEJS_VERSION=20 @@ -27,6 +29,7 @@ RUN mkdir -p /etc/apt/keyrings \ nodejs \ && rm -rf /var/lib/apt/lists/* \ && npm install -g corepack@$COREPACK_VERSION \ + && npm install -g corepack@$COREPACK_VERSION bun@$BUN_VERSION \ && rm -rf ~/.npm USER dependabot diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater.rb index bd3fb7cf9d..838c48eb56 100644 --- a/npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater.rb +++ b/npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater.rb @@ -18,6 +18,7 @@ class FileUpdater < Dependabot::FileUpdaters::Base require_relative "file_updater/npm_lockfile_updater" require_relative "file_updater/yarn_lockfile_updater" require_relative "file_updater/pnpm_lockfile_updater" + require_relative "file_updater/bun_lockfile_updater" class NoChangeError < StandardError extend T::Sig @@ -189,6 +190,15 @@ def pnpm_locks ) end + sig { returns(T::Array[Dependabot::DependencyFile]) } + def bun_locks + @bun_locks ||= T.let( + filtered_dependency_files + .select { |f| f.name.end_with?("bun.lock") }, + T.nilable(T::Array[Dependabot::DependencyFile]) + ) + end + sig { returns(T::Array[Dependabot::DependencyFile]) } def shrinkwraps @shrinkwraps ||= T.let( @@ -217,6 +227,11 @@ def pnpm_lock_changed?(pnpm_lock) pnpm_lock.content != updated_pnpm_lock_content(pnpm_lock) end + sig { params(bun_lock: Dependabot::DependencyFile).returns(T::Boolean) } + def bun_lock_changed?(bun_lock) + bun_lock.content != updated_bun_lock_content(bun_lock) + end + sig { params(package_lock: Dependabot::DependencyFile).returns(T::Boolean) } def package_lock_changed?(package_lock) package_lock.content != updated_lockfile_content(package_lock) @@ -237,6 +252,8 @@ def updated_manifest_files end end + # rubocop:disable Metrics/MethodLength + # rubocop:disable Metrics/PerceivedComplexity sig { returns(T::Array[Dependabot::DependencyFile]) } def updated_lockfiles updated_files = [] @@ -259,6 +276,15 @@ def updated_lockfiles ) end + bun_locks.each do |bun_lock| + next unless bun_lock_changed?(bun_lock) + + updated_files << updated_file( + file: bun_lock, + content: updated_bun_lock_content(bun_lock) + ) + end + package_locks.each do |package_lock| next unless package_lock_changed?(package_lock) @@ -279,6 +305,8 @@ def updated_lockfiles updated_files end + # rubocop:enable Metrics/MethodLength + # rubocop:enable Metrics/PerceivedComplexity sig { params(yarn_lock: Dependabot::DependencyFile).returns(String) } def updated_yarn_lock_content(yarn_lock) @@ -294,6 +322,13 @@ def updated_pnpm_lock_content(pnpm_lock) pnpm_lockfile_updater.updated_pnpm_lock_content(pnpm_lock) end + sig { params(bun_lock: Dependabot::DependencyFile).returns(String) } + def updated_bun_lock_content(bun_lock) + @updated_bun_lock_content ||= T.let({}, T.nilable(T::Hash[String, T.nilable(String)])) + @updated_bun_lock_content[bun_lock.name] ||= + bun_lockfile_updater.updated_bun_lock_content(bun_lock) + end + sig { returns(Dependabot::NpmAndYarn::FileUpdater::YarnLockfileUpdater) } def yarn_lockfile_updater @yarn_lockfile_updater ||= T.let( @@ -320,6 +355,19 @@ def pnpm_lockfile_updater ) end + sig { returns(Dependabot::NpmAndYarn::FileUpdater::BunLockfileUpdater) } + def bun_lockfile_updater + @bun_lockfile_updater ||= T.let( + BunLockfileUpdater.new( + dependencies: dependencies, + dependency_files: dependency_files, + repo_contents_path: repo_contents_path, + credentials: credentials + ), + T.nilable(Dependabot::NpmAndYarn::FileUpdater::BunLockfileUpdater) + ) + end + sig { params(file: Dependabot::DependencyFile).returns(T.nilable(String)) } def updated_lockfile_content(file) @updated_lockfile_content ||= T.let({}, T.nilable(T::Hash[String, T.nilable(String)])) diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/bun_lockfile_updater.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/bun_lockfile_updater.rb new file mode 100644 index 0000000000..b88fc689e9 --- /dev/null +++ b/npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/bun_lockfile_updater.rb @@ -0,0 +1,144 @@ +# typed: true +# frozen_string_literal: true + +require "dependabot/npm_and_yarn/helpers" +require "dependabot/npm_and_yarn/update_checker/registry_finder" +require "dependabot/npm_and_yarn/registry_parser" +require "dependabot/shared_helpers" + +module Dependabot + module NpmAndYarn + class FileUpdater < Dependabot::FileUpdaters::Base + class BunLockfileUpdater + require_relative "npmrc_builder" + require_relative "package_json_updater" + + def initialize(dependencies:, dependency_files:, repo_contents_path:, credentials:) + @dependencies = dependencies + @dependency_files = dependency_files + @repo_contents_path = repo_contents_path + @credentials = credentials + end + + def updated_bun_lock_content(bun_lock) + @updated_bun_lock_content ||= {} + return @updated_bun_lock_content[bun_lock.name] if @updated_bun_lock_content[bun_lock.name] + + new_content = run_bun_update(bun_lock: bun_lock) + @updated_bun_lock_content[bun_lock.name] = new_content + rescue SharedHelpers::HelperSubprocessFailed => e + handle_bun_lock_updater_error(e, bun_lock) + end + + private + + attr_reader :dependencies + attr_reader :dependency_files + attr_reader :repo_contents_path + attr_reader :credentials + + ERR_PATTERNS = { + /get .* 404/i => Dependabot::DependencyNotFound, + /installfailed cloning repository/i => Dependabot::DependencyNotFound, + /file:.* failed to resolve/i => Dependabot::DependencyNotFound, + /no version matching/i => Dependabot::DependencyFileNotResolvable, + /failed to resolve/i => Dependabot::DependencyFileNotResolvable + }.freeze + + def run_bun_update(bun_lock:) + SharedHelpers.in_a_temporary_repo_directory(base_dir, repo_contents_path) do + File.write(".npmrc", npmrc_content(bun_lock)) + + SharedHelpers.with_git_configured(credentials: credentials) do + run_bun_updater + + write_final_package_json_files + + run_bun_install + + File.read(bun_lock.name) + end + end + end + + def run_bun_updater + dependency_updates = dependencies.map do |d| + "#{d.name}@#{d.version}" + end.join(" ") + + Helpers.run_bun_command( + "install #{dependency_updates} --save-text-lockfile", + fingerprint: "install --save-text-lockfile" + ) + end + + def run_bun_install + Helpers.run_bun_command( + "install --save-text-lockfile" + ) + end + + def lockfile_dependencies(lockfile) + @lockfile_dependencies ||= {} + @lockfile_dependencies[lockfile.name] ||= + NpmAndYarn::FileParser.new( + dependency_files: [lockfile, *package_files], + source: nil, + credentials: credentials + ).parse + end + + def handle_bun_lock_updater_error(error, _bun_lock) + error_message = error.message + + ERR_PATTERNS.each do |pattern, error_class| + raise error_class, error_message if error_message.match?(pattern) + end + + raise error + end + + def write_final_package_json_files + package_files.each do |file| + path = file.name + FileUtils.mkdir_p(Pathname.new(path).dirname) + File.write(path, updated_package_json_content(file)) + end + end + + def npmrc_content(bun_lock) + NpmrcBuilder.new( + credentials: credentials, + dependency_files: dependency_files, + dependencies: lockfile_dependencies(bun_lock) + ).npmrc_content + end + + def updated_package_json_content(file) + @updated_package_json_content ||= {} + @updated_package_json_content[file.name] ||= + PackageJsonUpdater.new( + package_json: file, + dependencies: dependencies + ).updated_package_json.content + end + + def package_files + @package_files ||= dependency_files.select { |f| f.name.end_with?("package.json") } + end + + def base_dir + dependency_files.first.directory + end + + def npmrc_file + dependency_files.find { |f| f.name == ".npmrc" } + end + + def sanitize_message(message) + message.gsub(/"|\[|\]|\}|\{/, "") + end + end + end + end +end diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn/helpers.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn/helpers.rb index 0b6e45a3e8..1f028de1f8 100644 --- a/npm_and_yarn/lib/dependabot/npm_and_yarn/helpers.rb +++ b/npm_and_yarn/lib/dependabot/npm_and_yarn/helpers.rb @@ -361,6 +361,35 @@ def self.run_node_command(command, fingerprint: nil) raise end + sig { returns(T.nilable(String)) } + def self.bun_version + version = run_bun_command("--version", fingerprint: "--version").strip + if version.include?("+") + version.split("+").first # Remove build info, if present + end + rescue StandardError => e + Dependabot.logger.error("Error retrieving Bun version: #{e.message}") + nil + end + + sig { params(command: String, fingerprint: T.nilable(String)).returns(String) } + def self.run_bun_command(command, fingerprint: nil) + full_command = "bun #{command}" + + Dependabot.logger.info("Running bun command: #{full_command}") + + result = Dependabot::SharedHelpers.run_shell_command( + full_command, + fingerprint: "bun #{fingerprint || command}" + ) + + Dependabot.logger.info("Command executed successfully: #{full_command}") + result + rescue StandardError => e + Dependabot.logger.error("Error running bun command: #{full_command}, Error: #{e.message}") + raise + end + # Setup yarn and run a single yarn command returning stdout/stderr sig { params(command: String, fingerprint: T.nilable(String)).returns(String) } def self.run_yarn_command(command, fingerprint: nil) @@ -505,6 +534,8 @@ def self.package_manager_version(name) ).returns(String) end def self.package_manager_run_command(name, command, fingerprint: nil) + return run_bun_command(command, fingerprint: fingerprint) if name == BunPackageManager::NAME + full_command = "corepack #{name} #{command}" result = Dependabot::SharedHelpers.run_shell_command( diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/dependency_files_builder.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/dependency_files_builder.rb index 4bc4297966..fccf40ac23 100644 --- a/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/dependency_files_builder.rb +++ b/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/dependency_files_builder.rb @@ -49,6 +49,12 @@ def pnpm_locks .select { |f| f.name.end_with?("pnpm-lock.yaml") } end + def bun_locks + @bun_locks ||= + dependency_files + .select { |f| f.name.end_with?("bun.lock") } + end + def root_yarn_lock @root_yarn_lock ||= dependency_files @@ -61,6 +67,12 @@ def root_pnpm_lock .find { |f| f.name == "pnpm-lock.yaml" } end + def root_bun_lock + @root_bun_lock ||= + dependency_files + .find { |f| f.name == "bun.lock" } + end + def shrinkwraps @shrinkwraps ||= dependency_files @@ -68,7 +80,7 @@ def shrinkwraps end def lockfiles - [*package_locks, *shrinkwraps, *yarn_locks, *pnpm_locks] + [*package_locks, *shrinkwraps, *yarn_locks, *pnpm_locks, *bun_locks] end def package_files @@ -89,12 +101,7 @@ def write_lockfiles File.write(f.name, prepared_yarn_lockfile_content(f.content)) end - pnpm_locks.each do |f| - FileUtils.mkdir_p(Pathname.new(f.name).dirname) - File.write(f.name, f.content) - end - - [*package_locks, *shrinkwraps].each do |f| + [*package_locks, *shrinkwraps, *pnpm_locks, *bun_locks].each do |f| FileUtils.mkdir_p(Pathname.new(f.name).dirname) File.write(f.name, f.content) end diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb index 00d7e86931..9142bd3f8e 100644 --- a/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb +++ b/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb @@ -70,6 +70,8 @@ def update_subdependency_in_lockfile(lockfile) run_yarn_updater(path, lockfile_name) elsif lockfile.name.end_with?("pnpm-lock.yaml") run_pnpm_updater(path, lockfile_name) + elsif lockfile.name.end_with?("bun.lock") + run_bun_updater(path, lockfile_name) elsif !Helpers.npm8?(lockfile) run_npm6_updater(path, lockfile_name) else @@ -153,6 +155,18 @@ def run_npm_updater(path, lockfile_name) end end + def run_bun_updater(path, lockfile_name) + SharedHelpers.with_git_configured(credentials: credentials) do + Dir.chdir(path) do + Helpers.run_bun_command( + "update #{dependency.name} --save-text-lockfile", + fingerprint: "update --save-text-lockfile" + ) + { lockfile_name => File.read(lockfile_name) } + end + end + end + def run_npm6_updater(path, lockfile_name) SharedHelpers.with_git_configured(credentials: credentials) do Dir.chdir(path) do diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb index 0bc03a8d02..85ef72eb0a 100644 --- a/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb +++ b/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb @@ -413,6 +413,8 @@ def old_unmet_peer_dependencies end def error_details_from_captures(captures) + return {} unless captures.is_a?(Hash) + required_dep_captures = captures.fetch("required_dep") requiring_dep_captures = captures.fetch("requiring_dep") return {} unless required_dep_captures && requiring_dep_captures @@ -549,12 +551,18 @@ def run_checker(path:, version:) npm_lockfiles = lockfiles_for_path(lockfiles: dependency_files_builder.package_locks, path: path) return run_npm_checker(path: path, version: version) if npm_lockfiles.any? + bun_lockfiles = lockfiles_for_path(lockfiles: dependency_files_builder.bun_locks, path: path) + return run_bun_checker(path: path, version: version) if bun_lockfiles.any? + root_yarn_lock = dependency_files_builder.root_yarn_lock return run_yarn_checker(path: path, version: version, lockfile: root_yarn_lock) if root_yarn_lock root_pnpm_lock = dependency_files_builder.root_pnpm_lock return run_pnpm_checker(path: path, version: version) if root_pnpm_lock + root_bun_lock = dependency_files_builder.root_bun_lock + return run_bun_checker(path: path, version: version) if root_bun_lock + run_npm_checker(path: path, version: version) rescue SharedHelpers::HelperSubprocessFailed => e handle_peer_dependency_errors(e.message) @@ -583,6 +591,17 @@ def run_pnpm_checker(path:, version:) end end + def run_bun_checker(path:, version:) + SharedHelpers.with_git_configured(credentials: credentials) do + Dir.chdir(path) do + Helpers.run_bun_command( + "update #{dependency.name}@#{version} --save-text-lockfile", + fingerprint: "update @ --save-text-lockfile" + ) + end + end + end + def run_yarn_berry_checker(path:, version:) # This method mimics calling a native helper in order to comply with the caller's expectations # Specifically we add the dependency at the specified updated version diff --git a/npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater/bun_lockfile_updater_spec.rb b/npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater/bun_lockfile_updater_spec.rb new file mode 100644 index 0000000000..66604cd493 --- /dev/null +++ b/npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater/bun_lockfile_updater_spec.rb @@ -0,0 +1,167 @@ +# typed: false +# frozen_string_literal: true + +require "spec_helper" +require "dependabot/npm_and_yarn/file_updater/bun_lockfile_updater" + +RSpec.describe Dependabot::NpmAndYarn::FileUpdater::BunLockfileUpdater do + subject(:updated_bun_lock_content) { updater.updated_bun_lock_content(bun_lock) } + + let(:updater) do + described_class.new( + dependency_files: files, + dependencies: dependencies, + credentials: credentials, + repo_contents_path: repo_contents_path + ) + end + let(:dependencies) { [dependency] } + + let(:credentials) do + [Dependabot::Credential.new({ + "type" => "git_source", + "host" => "github.com" + })] + end + let(:dependency) do + Dependabot::Dependency.new( + name: dependency_name, + version: version, + previous_version: previous_version, + requirements: requirements, + previous_requirements: previous_requirements, + package_manager: "npm_and_yarn" + ) + end + let(:dependency_name) { "fetch-factory" } + let(:version) { "0.0.2" } + let(:previous_version) { "0.0.1" } + let(:requirements) do + [{ + file: "package.json", + requirement: "^0.0.2", + groups: ["dependencies"], + source: nil + }] + end + let(:previous_requirements) do + [{ + file: "package.json", + requirement: "^0.0.1", + groups: ["dependencies"], + source: nil + }] + end + + let(:files) { project_dependency_files(project_name) } + + let(:bun_lock) do + files.find { |f| f.name == "bun.lock" } + end + + let(:tmp_path) { Dependabot::Utils::BUMP_TMP_DIR_PATH } + + let(:repo_contents_path) { build_tmp_repo(project_name, path: "projects") } + + before do + FileUtils.mkdir_p(tmp_path) + allow(Dependabot::Experiments).to receive(:enabled?) + .with(:enable_shared_helpers_command_timeout).and_return(true) + end + + after do + Dependabot::Experiments.reset! + end + + describe "errors" do + context "without dependencies" do + let(:project_name) { "bun/empty" } + + it "raises a helpful error" do + expect { updated_bun_lock_content } + .to raise_error("Expected content to change!") + end + end + + context "with an invalid lockfile" do + let(:project_name) { "bun/invalid_lockfile" } + + it "raises a helpful error" do + expect { updated_bun_lock_content } + .to raise_error(Dependabot::DependencyFileNotParseable) + end + end + + context "with an invalid lockfile version" do + let(:project_name) { "bun/invalid_lockfile_version" } + + it "raises a helpful error" do + expect { updated_bun_lock_content } + .to raise_error(Dependabot::DependencyFileNotParseable) + end + end + + context "with a dependency that is missing" do + let(:project_name) { "bun/missing_dependency" } + + it "raises a helpful error" do + expect { updated_bun_lock_content } + .to raise_error(Dependabot::DependencyNotFound) + end + end + + context "with a dependency version that is missing" do + let(:project_name) { "bun/missing_dependency_version" } + + it "raises a helpful error" do + expect { updated_bun_lock_content } + .to raise_error(Dependabot::DependencyFileNotResolvable) + end + end + + context "with a git dependency that is missing" do + let(:project_name) { "bun/missing_git_dependency" } + + it "raises a helpful error" do + expect { updated_bun_lock_content } + .to raise_error(Dependabot::DependencyNotFound) + end + end + + context "with a github dependency that is missing" do + let(:project_name) { "bun/missing_github_dependency" } + + it "raises a helpful error" do + expect { updated_bun_lock_content } + .to raise_error(Dependabot::DependencyNotFound) + end + end + + context "with a tarball dependency that is missing" do + let(:project_name) { "bun/missing_tarball_dependency" } + + it "raises a helpful error" do + expect { updated_bun_lock_content } + .to raise_error(Dependabot::DependencyNotFound) + end + end + + context "with a npm dependency that is missing" do + let(:project_name) { "bun/missing_npm_dependency" } + + it "raises a helpful error" do + expect { updated_bun_lock_content } + .to raise_error(Dependabot::DependencyNotFound) + end + end + + context "with a file dependency that is missing" do + let(:project_name) { "bun/missing_file_dependency" } + + it "raises a helpful error" do + expect { updated_bun_lock_content } + .to raise_error(Dependabot::DependencyNotFound) + end + end + end +end diff --git a/npm_and_yarn/spec/fixtures/projects/bun/empty/bun.lock b/npm_and_yarn/spec/fixtures/projects/bun/empty/bun.lock new file mode 100644 index 0000000000..fcc66e12ce --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/empty/bun.lock @@ -0,0 +1,7 @@ +{ + "lockfileVersion": 0, + "workspaces": { + "": {}, + }, + "packages": {}, +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/empty/package.json b/npm_and_yarn/spec/fixtures/projects/bun/empty/package.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/empty/package.json @@ -0,0 +1 @@ +{} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/invalid_version/bun.lock b/npm_and_yarn/spec/fixtures/projects/bun/invalid_version/bun.lock new file mode 100644 index 0000000000..690cf8ed31 --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/invalid_version/bun.lock @@ -0,0 +1,36 @@ +{ + "lockfileVersion": 0, + "workspaces": { + "": { + "dependencies": { + "fetch-factory": "^0.0.1", + }, + "devDependencies": { + "etag": "^1.0.0", + }, + }, + }, + "packages": { + "encoding": ["encoding@0.1.13", "", { "dependencies": { "iconv-lite": "^0.6.2" } }, "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A=="], + + "es6-promise": ["es6-promise@3.3.1", "", {}, "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg=="], + + "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], + + "fetch-factory": ["fetch-factory@0.0.1", "", { "dependencies": { "es6-promise": "^3.0.2", "isomorphic-fetch": "^2.1.1", "lodash": "^3.10.1" } }, "sha512-gexRwqIhwzDJ2pJvL0UYfiZwW06/bdYWxAmswFFts7C87CF8i6liApihTk7TZFYMDcQjvvDIvyHv0q379z0aWA=="], + + "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + + "is-stream": ["is-stream@1.1.0", "", {}, "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ=="], + + "isomorphic-fetch": ["isomorphic-fetch@2.2.1", "", { "dependencies": { "node-fetch": "^1.0.1", "whatwg-fetch": ">=0.10.0" } }, "sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA=="], + + "lodash": ["lodash@3.10.1", "", {}, "sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R1HByV+yJfRWVJryQ=="], + + "node-fetch": ["node-fetch@1.7.3", "", { "dependencies": { "encoding": "^0.1.11", "is-stream": "^1.0.1" } }, "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ=="], + + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "whatwg-fetch": ["whatwg-fetch@3.6.20", "", {}, "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg=="], + } +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/invalid_version/package.json b/npm_and_yarn/spec/fixtures/projects/bun/invalid_version/package.json new file mode 100644 index 0000000000..13d8b3d2c7 --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/invalid_version/package.json @@ -0,0 +1,8 @@ +{ + "dependencies": { + "fetch-factory": "^0.0.1" + }, + "devDependencies": { + "etag" : "^.0.0" // previous: "^1.0.0" + } +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/missing_dependency/bun.lock b/npm_and_yarn/spec/fixtures/projects/bun/missing_dependency/bun.lock new file mode 100644 index 0000000000..fcc66e12ce --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/missing_dependency/bun.lock @@ -0,0 +1,7 @@ +{ + "lockfileVersion": 0, + "workspaces": { + "": {}, + }, + "packages": {}, +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/missing_dependency/package.json b/npm_and_yarn/spec/fixtures/projects/bun/missing_dependency/package.json new file mode 100644 index 0000000000..874c8de9ca --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/missing_dependency/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "this-does-not-exist-12jn1o2n98sqas": "^99999.0.0" + } +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/missing_dependency_version/bun.lock b/npm_and_yarn/spec/fixtures/projects/bun/missing_dependency_version/bun.lock new file mode 100644 index 0000000000..be8fb2962f --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/missing_dependency_version/bun.lock @@ -0,0 +1,39 @@ +{ + "lockfileVersion": 0, + "workspaces": { + "": { + "dependencies": { + "fetch-factory": "^0.0.1", + "lodash": "^4.17.21", + }, + "devDependencies": { + "etag": "^1.0.0", + }, + }, + }, + "packages": { + "encoding": ["encoding@0.1.13", "", { "dependencies": { "iconv-lite": "^0.6.2" } }, "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A=="], + + "es6-promise": ["es6-promise@3.3.1", "", {}, "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg=="], + + "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], + + "fetch-factory": ["fetch-factory@0.0.1", "", { "dependencies": { "es6-promise": "^3.0.2", "isomorphic-fetch": "^2.1.1", "lodash": "^3.10.1" } }, "sha512-gexRwqIhwzDJ2pJvL0UYfiZwW06/bdYWxAmswFFts7C87CF8i6liApihTk7TZFYMDcQjvvDIvyHv0q379z0aWA=="], + + "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + + "is-stream": ["is-stream@1.1.0", "", {}, "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ=="], + + "isomorphic-fetch": ["isomorphic-fetch@2.2.1", "", { "dependencies": { "node-fetch": "^1.0.1", "whatwg-fetch": ">=0.10.0" } }, "sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA=="], + + "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], + + "node-fetch": ["node-fetch@1.7.3", "", { "dependencies": { "encoding": "^0.1.11", "is-stream": "^1.0.1" } }, "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ=="], + + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "whatwg-fetch": ["whatwg-fetch@3.6.20", "", {}, "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg=="], + + "fetch-factory/lodash": ["lodash@3.10.1", "", {}, "sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R1HByV+yJfRWVJryQ=="], + } +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/missing_dependency_version/package.json b/npm_and_yarn/spec/fixtures/projects/bun/missing_dependency_version/package.json new file mode 100644 index 0000000000..15f2aa2038 --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/missing_dependency_version/package.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "fetch-factory": "^0.0.1", + "lodash": "^99999.0.0" // previous: "^4.17.21" + }, + "devDependencies": { + "etag": "^1.0.0" + } +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/missing_file_dependency/bun.lock b/npm_and_yarn/spec/fixtures/projects/bun/missing_file_dependency/bun.lock new file mode 100644 index 0000000000..fcc66e12ce --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/missing_file_dependency/bun.lock @@ -0,0 +1,7 @@ +{ + "lockfileVersion": 0, + "workspaces": { + "": {}, + }, + "packages": {}, +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/missing_file_dependency/package.json b/npm_and_yarn/spec/fixtures/projects/bun/missing_file_dependency/package.json new file mode 100644 index 0000000000..91c7a99c4e --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/missing_file_dependency/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "this-does-not-exist": "file:./this-does-not-exist" + } +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/missing_git_dependency/bun.lock b/npm_and_yarn/spec/fixtures/projects/bun/missing_git_dependency/bun.lock new file mode 100644 index 0000000000..fcc66e12ce --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/missing_git_dependency/bun.lock @@ -0,0 +1,7 @@ +{ + "lockfileVersion": 0, + "workspaces": { + "": {}, + }, + "packages": {}, +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/missing_git_dependency/package.json b/npm_and_yarn/spec/fixtures/projects/bun/missing_git_dependency/package.json new file mode 100644 index 0000000000..42bfadfd7f --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/missing_git_dependency/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "this-does-not-exist": "git@github.com:dependabot/this-does-not-exist.git" + } +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/missing_github_dependency/bun.lock b/npm_and_yarn/spec/fixtures/projects/bun/missing_github_dependency/bun.lock new file mode 100644 index 0000000000..fcc66e12ce --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/missing_github_dependency/bun.lock @@ -0,0 +1,7 @@ +{ + "lockfileVersion": 0, + "workspaces": { + "": {}, + }, + "packages": {}, +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/missing_github_dependency/package.json b/npm_and_yarn/spec/fixtures/projects/bun/missing_github_dependency/package.json new file mode 100644 index 0000000000..022dab1555 --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/missing_github_dependency/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "this-does-not-exist": "github:dependabot/this-does-not-exist" + } +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/missing_npm_dependency/bun.lock b/npm_and_yarn/spec/fixtures/projects/bun/missing_npm_dependency/bun.lock new file mode 100644 index 0000000000..fcc66e12ce --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/missing_npm_dependency/bun.lock @@ -0,0 +1,7 @@ +{ + "lockfileVersion": 0, + "workspaces": { + "": {}, + }, + "packages": {}, +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/missing_npm_dependency/package.json b/npm_and_yarn/spec/fixtures/projects/bun/missing_npm_dependency/package.json new file mode 100644 index 0000000000..b161bc4dfc --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/missing_npm_dependency/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "this-does-not-exist": "npm:this-does-not-exist-qubqwub1ubw@^99999.0.0" + } +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/missing_tarball_dependency/bun.lock b/npm_and_yarn/spec/fixtures/projects/bun/missing_tarball_dependency/bun.lock new file mode 100644 index 0000000000..fcc66e12ce --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/missing_tarball_dependency/bun.lock @@ -0,0 +1,7 @@ +{ + "lockfileVersion": 0, + "workspaces": { + "": {}, + }, + "packages": {}, +} diff --git a/npm_and_yarn/spec/fixtures/projects/bun/missing_tarball_dependency/package.json b/npm_and_yarn/spec/fixtures/projects/bun/missing_tarball_dependency/package.json new file mode 100644 index 0000000000..58cb4c9187 --- /dev/null +++ b/npm_and_yarn/spec/fixtures/projects/bun/missing_tarball_dependency/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "this-does-not-exist": "https://example.com/this-does-not-exist.tar.gz" + } +}