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

Types for FileFetchers::Base #8327

Merged
merged 12 commits into from
Nov 13, 2023
9 changes: 7 additions & 2 deletions bundler/lib/dependabot/bundler/file_fetcher.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# typed: false
# frozen_string_literal: true

require "sorbet-runtime"
require "dependabot/file_fetchers"
require "dependabot/file_fetchers/base"
require "dependabot/bundler/file_updater/lockfile_updater"
Expand All @@ -9,6 +10,9 @@
module Dependabot
module Bundler
class FileFetcher < Dependabot::FileFetchers::Base
extend T::Sig
extend T::Helpers

require "dependabot/bundler/file_fetcher/gemspec_finder"
require "dependabot/bundler/file_fetcher/path_gemspec_finder"
require "dependabot/bundler/file_fetcher/child_gemfile_finder"
Expand All @@ -32,8 +36,7 @@ def ecosystem_versions
}
end

private

sig { override.returns(T::Array[DependencyFile]) }
def fetch_files
fetched_files = []
fetched_files << gemfile if gemfile
Expand All @@ -55,6 +58,8 @@ def fetch_files
fetched_files
end

private

def uniq_files(fetched_files)
uniq_files = fetched_files.reject(&:support_file?).uniq
uniq_files += fetched_files
Expand Down
9 changes: 7 additions & 2 deletions cargo/lib/dependabot/cargo/file_fetcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# frozen_string_literal: true

require "pathname"
require "sorbet-runtime"
require "toml-rb"

require "dependabot/file_fetchers"
Expand All @@ -13,6 +14,9 @@
module Dependabot
module Cargo
class FileFetcher < Dependabot::FileFetchers::Base
extend T::Sig
extend T::Helpers

def self.required_files_in?(filenames)
filenames.include?("Cargo.toml")
end
Expand Down Expand Up @@ -40,8 +44,7 @@ def ecosystem_versions
)
end

private

sig { override.returns(T::Array[DependencyFile]) }
def fetch_files
fetched_files = []
fetched_files << cargo_toml
Expand All @@ -51,6 +54,8 @@ def fetch_files
fetched_files.uniq
end

private

def fetch_path_dependency_and_workspace_files(files = nil)
fetched_files = files || [cargo_toml]

Expand Down
88 changes: 75 additions & 13 deletions common/lib/dependabot/dependency_file.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,42 @@
# typed: true
# typed: strict
# frozen_string_literal: true

require "pathname"
require "sorbet-runtime"

module Dependabot
class DependencyFile
attr_accessor :name, :content, :directory, :type, :support_file,
:vendored_file, :symlink_target, :content_encoding,
:operation, :mode
extend T::Sig

sig { returns(String) }
attr_accessor :name

sig { returns(T.nilable(String)) }
attr_accessor :content

sig { returns(String) }
attr_accessor :directory

sig { returns(String) }
attr_accessor :type

sig { returns(T::Boolean) }
attr_accessor :support_file

sig { returns(T::Boolean) }
attr_accessor :vendored_file

sig { returns(T.nilable(String)) }
attr_accessor :symlink_target

sig { returns(String) }
attr_accessor :content_encoding

sig { returns(String) }
attr_accessor :operation

sig { returns(T.nilable(String)) }
attr_accessor :mode

class ContentEncoding
UTF_8 = "utf-8"
Expand All @@ -25,13 +54,29 @@ class Mode
SUBMODULE = "160000"
end

sig do
params(
name: String,
content: T.nilable(String),
directory: String,
type: String,
support_file: T::Boolean,
vendored_file: T::Boolean,
symlink_target: T.nilable(String),
content_encoding: String,
deleted: T::Boolean,
operation: String,
mode: T.nilable(String)
)
.void
end
def initialize(name:, content:, directory: "/", type: "file",
support_file: false, vendored_file: false, symlink_target: nil,
content_encoding: ContentEncoding::UTF_8, deleted: false,
operation: Operation::UPDATE, mode: nil)
@name = name
@content = content
@directory = clean_directory(directory)
@directory = T.let(clean_directory(directory), String)
@symlink_target = symlink_target
@support_file = support_file
@vendored_file = vendored_file
Expand All @@ -50,7 +95,7 @@ def initialize(name:, content:, directory: "/", type: "file",
@type = type

begin
@mode = File.stat(realpath).mode.to_s(8)
@mode = T.let(File.stat(realpath).mode.to_s(8), T.nilable(String))
rescue StandardError
@mode = mode
end
Expand All @@ -61,6 +106,7 @@ def initialize(name:, content:, directory: "/", type: "file",
raise "Only symlinked files must specify a target!" if symlink_target
end

sig { returns(T::Hash[String, T.untyped]) }
def to_h
details = {
"name" => name,
Expand All @@ -78,62 +124,78 @@ def to_h
details
end

sig { returns(String) }
def path
Pathname.new(File.join(directory, name)).cleanpath.to_path
end

sig { returns(String) }
def realpath
(symlink_target || path).sub(%r{^/}, "")
end

sig { params(other: BasicObject).returns(T::Boolean) }
def ==(other)
return false unless other.instance_of?(self.class)

my_hash = to_h.reject { |k| k == "support_file" }
their_hash = other.to_h.reject { |k| k == "support_file" }
my_hash == their_hash
case other
when DependencyFile
my_hash = to_h.reject { |k| k == "support_file" }
their_hash = other.to_h.reject { |k| k == "support_file" }
my_hash == their_hash
else
false
end
end

sig { returns(Integer) }
def hash
to_h.hash
end

sig { params(other: BasicObject).returns(T::Boolean) }
def eql?(other)
self == other
end

sig { returns(T::Boolean) }
def support_file?
@support_file
end

sig { returns(T::Boolean) }
def vendored_file?
@vendored_file
end

sig { returns(T::Boolean) }
def deleted
@operation == Operation::DELETE
end

sig { params(deleted: T::Boolean).void }
def deleted=(deleted)
@operation = deleted ? Operation::DELETE : Operation::UPDATE
end

sig { returns(T::Boolean) }
def deleted?
deleted
end

sig { returns(T::Boolean) }
def binary?
content_encoding == ContentEncoding::BASE64
end

sig { returns(String) }
def decoded_content
return Base64.decode64(content) if binary?
return Base64.decode64(T.must(content)) if binary?

content
T.must(content)
end

private

sig { params(directory: String).returns(String) }
def clean_directory(directory)
# Directory should always start with a `/`
directory.sub(%r{^/*}, "/")
Expand Down
4 changes: 2 additions & 2 deletions common/lib/dependabot/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ def initialize(directory_name, msg = nil)
class BranchNotFound < DependabotError
extend T::Sig

sig { returns(String) }
sig { returns(T.nilable(String)) }
attr_reader :branch_name

sig { params(branch_name: String, msg: T.nilable(String)).void }
sig { params(branch_name: T.nilable(String), msg: T.nilable(String)).void }
def initialize(branch_name, msg = nil)
@branch_name = branch_name
super(msg)
Expand Down
Loading