dependabot-core / common /lib /dependabot /dependency_file.rb
AbdulElahGwaith's picture
Upload folder using huggingface_hub
e98c0d7 verified
# typed: strong
# frozen_string_literal: true
require "pathname"
require "sorbet-runtime"
module Dependabot
class DependencyFile
extend T::Sig
sig { returns(String) }
attr_accessor :name
sig { returns(T.nilable(String)) }
attr_accessor :content
# This is the directory of the job source, not the directory of the file itself.
# The name actually contains the relative path from the job directory.
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"
BASE64 = "base64"
end
class Operation
UPDATE = "update"
CREATE = "create"
DELETE = "delete"
end
class Mode
EXECUTABLE = "100755"
FILE = "100644"
TREE = "040000"
SUBMODULE = "160000"
SYMLINK = "120000"
end
# See https://github.com/git/git/blob/a36e024e989f4d35f35987a60e3af8022cac3420/object.h#L144-L153
VALID_MODES = T.let(
[Mode::FILE, Mode::EXECUTABLE, Mode::TREE, Mode::SUBMODULE, Mode::SYMLINK].freeze,
T::Array[String]
)
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 = T.let(clean_directory(directory), String)
@symlink_target = symlink_target
@support_file = support_file
@vendored_file = vendored_file
@content_encoding = content_encoding
@operation = operation
@mode = mode
raise ArgumentError, "Invalid Git mode: #{mode}" if mode && !VALID_MODES.include?(mode)
# Make deleted override the operation. Deleted is kept when operation
# was introduced to keep compatibility with downstream dependants.
@operation = Operation::DELETE if deleted
# Type is used *very* sparingly. It lets the git_modules updater know that
# a "file" is actually a submodule, and lets our Go updaters know which
# file represents the main.go.
# New use cases should be avoided if at all possible (and use the
# support_file flag instead)
@type = type
return unless (type == "symlink") ^ symlink_target
raise "Symlinks must specify a target!" unless symlink_target
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,
"content" => content,
"directory" => directory,
"type" => type,
"support_file" => support_file,
"content_encoding" => content_encoding,
"deleted" => deleted,
"operation" => operation
}
details["mode"] = mode if mode
details["symlink_target"] = symlink_target if symlink_target
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)
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(T.must(content)) if binary?
T.must(content)
end
private
sig { params(directory: String).returns(String) }
def clean_directory(directory)
# Directory should always start with a `/`
directory.sub(%r{^/*}, "/")
end
end
end