Skip to content

Commit

Permalink
Add bun file fetcher
Browse files Browse the repository at this point in the history
  • Loading branch information
markhallen committed Jan 13, 2025
1 parent 64e8c6e commit dd5ca72
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def package_required_lockfile?(lockfile)

sig { params(lockfile: DependencyFile).returns(T::Boolean) }
def workspaces_lockfile?(lockfile)
return false unless ["yarn.lock", "package-lock.json", "pnpm-lock.yaml"].include?(lockfile.name)
return false unless ["yarn.lock", "package-lock.json", "pnpm-lock.yaml", "bun.lock"].include?(lockfile.name)

return false unless parsed_root_package_json["workspaces"] || dependency_files.any? do |file|
file.name.end_with?("pnpm-workspace.yaml") && File.dirname(file.name) == File.dirname(lockfile.name)
Expand Down Expand Up @@ -148,6 +148,7 @@ def lockfile?(file)
"package-lock.json",
"yarn.lock",
"pnpm-lock.yaml",
"bun.lock",
"npm-shrinkwrap.json"
)
end
Expand Down
83 changes: 50 additions & 33 deletions npm_and_yarn/lib/dependabot/npm_and_yarn/file_fetcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def ecosystem_versions
package_managers["npm"] = npm_version if npm_version
package_managers["yarn"] = yarn_version if yarn_version
package_managers["pnpm"] = pnpm_version if pnpm_version
package_managers["bun"] = bun_version if bun_version
package_managers["unknown"] = 1 if package_managers.empty?

{
Expand All @@ -83,6 +84,7 @@ def fetch_files
fetched_files += npm_files if npm_version
fetched_files += yarn_files if yarn_version
fetched_files += pnpm_files if pnpm_version
fetched_files += bun_files if bun_version
fetched_files += lerna_files
fetched_files += workspace_package_jsons
fetched_files += path_dependencies(fetched_files)
Expand Down Expand Up @@ -120,6 +122,13 @@ def pnpm_files
fetched_pnpm_files
end

sig { returns(T::Array[DependencyFile]) }
def bun_files
fetched_bun_files = []
fetched_bun_files << bun_lock if bun_lock
fetched_bun_files
end

sig { returns(T::Array[DependencyFile]) }
def lerna_files
fetched_lerna_files = []
Expand Down Expand Up @@ -202,6 +211,16 @@ def pnpm_version
)
end

sig { returns(T.nilable(T.any(Integer, String))) }
def bun_version
return @bun_version = nil unless Experiments.enabled?(:bun_updates)

@bun_version ||= T.let(
package_manager_helper.setup(BunPackageManager::NAME),
T.nilable(T.any(Integer, String))
)
end

sig { returns(PackageManagerHelper) }
def package_manager_helper
@package_manager_helper ||= T.let(
Expand All @@ -219,7 +238,8 @@ def lockfiles
{
npm: package_lock || shrinkwrap,
yarn: yarn_lock,
pnpm: pnpm_lock
pnpm: pnpm_lock,
bun: bun_lock
}
end

Expand Down Expand Up @@ -261,17 +281,18 @@ def pnpm_lock

return @pnpm_lock if @pnpm_lock || directory == "/"

# Loop through parent directories looking for a pnpm-lock
(1..directory.split("/").count).each do |i|
@pnpm_lock = fetch_file_from_host(("../" * i) + PNPMPackageManager::LOCKFILE_NAME)
.tap { |f| f.support_file = true }
break if @pnpm_lock
rescue Dependabot::DependencyFileNotFound
# Ignore errors (pnpm_lock.yaml may not be present)
nil
end
@pnpm_lock = fetch_file_from_parent_directories(PNPMPackageManager::LOCKFILE_NAME)
end

sig { returns(T.nilable(DependencyFile)) }
def bun_lock
return @bun_lock if defined?(@bun_lock)

@bun_lock ||= T.let(fetch_file_if_present(BunPackageManager::LOCKFILE_NAME), T.nilable(DependencyFile))

@pnpm_lock
return @bun_lock if @bun_lock || directory == "/"

@bun_lock = fetch_file_from_parent_directories(BunPackageManager::LOCKFILE_NAME)
end

sig { returns(T.nilable(DependencyFile)) }
Expand All @@ -294,17 +315,7 @@ def npmrc

return @npmrc if @npmrc || directory == "/"

# Loop through parent directories looking for an npmrc
(1..directory.split("/").count).each do |i|
@npmrc = fetch_file_from_host(("../" * i) + NpmPackageManager::RC_FILENAME)
.tap { |f| f.support_file = true }
break if @npmrc
rescue Dependabot::DependencyFileNotFound
# Ignore errors (.npmrc may not be present)
nil
end

@npmrc
@npmrc = fetch_file_from_parent_directories(NpmPackageManager::RC_FILENAME)
end

sig { returns(T.nilable(DependencyFile)) }
Expand All @@ -315,17 +326,7 @@ def yarnrc

return @yarnrc if @yarnrc || directory == "/"

# Loop through parent directories looking for an yarnrc
(1..directory.split("/").count).each do |i|
@yarnrc = fetch_file_from_host(("../" * i) + YarnPackageManager::RC_FILENAME)
.tap { |f| f.support_file = true }
break if @yarnrc
rescue Dependabot::DependencyFileNotFound
# Ignore errors (.yarnrc may not be present)
nil
end

@yarnrc
@yarnrc = fetch_file_from_parent_directories(YarnPackageManager::RC_FILENAME)
end

sig { returns(T.nilable(DependencyFile)) }
Expand Down Expand Up @@ -699,6 +700,22 @@ def create_yarn_cache
Dependabot.logger.info("Repository contents path does not exist")
end
end

sig { params(filename: String).returns(T.nilable(DependencyFile)) }
def fetch_file_with_support(filename)
fetch_file_from_host(filename).tap { |f| f.support_file = true }
rescue Dependabot::DependencyFileNotFound
nil
end

sig { params(filename: String).returns(T.nilable(DependencyFile)) }
def fetch_file_from_parent_directories(filename)
(1..directory.split("/").count).each do |i|
file = fetch_file_with_support(("../" * i) + filename)
return file if file
end
nil
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def lockfile?(file)
"package-lock.json",
"yarn.lock",
"npm-shrinkwrap.json",
"bun.lock",
"pnpm-lock.yaml"
)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,17 @@ def project_dependency_file(file_name)
end
end

context "when using bun.lock" do
let(:project_name) { "bun/simple_v0" }

it do
expect(files_requiring_update).to contain_exactly(
project_dependency_file("package.json"),
project_dependency_file("bun.lock")
)
end
end

context "with multiple dependencies" do
let(:project_name) { "npm6_and_yarn/nested_dependency_update" }
let(:updated_dependencies) { [dependency, other_dependency] }
Expand Down
59 changes: 59 additions & 0 deletions npm_and_yarn/spec/dependabot/npm_and_yarn/file_fetcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,20 @@
body: nil,
headers: json_header
)
stub_request(:get, File.join(url, "bun.lock?ref=sha"))
.with(headers: { "Authorization" => "token token" })
.to_return(
status: 404,
body: nil,
headers: json_header
)
stub_request(:get, File.join(url, "packages/bun.lock?ref=sha"))
.with(headers: { "Authorization" => "token token" })
.to_return(
status: 404,
body: nil,
headers: json_header
)
# FileFetcher will iterate trying to find `pnpm-lock.yaml` upwards in the folder tree
stub_request(:get, File.join(url, "packages/pnpm-lock.yaml?ref=sha"))
.with(headers: { "Authorization" => "token token" })
Expand Down Expand Up @@ -488,6 +502,39 @@
end
end

context "with a bun.lock but no package-lock.json file" do
before do
stub_request(:get, url + "?ref=sha")
.with(headers: { "Authorization" => "token token" })
.to_return(
status: 200,
body: fixture("github", "contents_js_bun.json"),
headers: json_header
)
stub_request(:get, File.join(url, "package-lock.json?ref=sha"))
.with(headers: { "Authorization" => "token token" })
.to_return(status: 404)
stub_request(:get, File.join(url, "bun.lock?ref=sha"))
.with(headers: { "Authorization" => "token token" })
.to_return(
status: 200,
body: fixture("github", "bun_lock_content.json"),
headers: json_header
)
end

it "fetches the package.json and bun.lock" do
expect(file_fetcher_instance.files.map(&:name))
.to match_array(%w(package.json bun.lock))
end

it "parses the bun.lock" do
expect(file_fetcher_instance.ecosystem_versions).to match(
{ package_managers: { "bun" => an_instance_of(Integer) } }
)
end
end

context "with an npm-shrinkwrap.json but no package-lock.json file" do
before do
stub_request(:get, url + "?ref=sha")
Expand Down Expand Up @@ -1271,6 +1318,12 @@
"pnpm-lock.yaml?ref=sha"
).with(headers: { "Authorization" => "token token" })
.to_return(status: 404)
stub_request(
:get,
"https://api.github.com/repos/gocardless/bump/contents/" \
"bun.lock?ref=sha"
).with(headers: { "Authorization" => "token token" })
.to_return(status: 404)
end

it "fetches package.json from the workspace dependencies" do
Expand Down Expand Up @@ -1840,6 +1893,12 @@
"pnpm-lock.yaml?ref=sha"
).with(headers: { "Authorization" => "token token" })
.to_return(status: 404)
stub_request(
:get,
"https://api.github.com/repos/gocardless/bump/contents/" \
"bun.lock?ref=sha"
).with(headers: { "Authorization" => "token token" })
.to_return(status: 404)
end

it "fetches package.json from the workspace dependencies" do
Expand Down

0 comments on commit dd5ca72

Please sign in to comment.