Skip to content

Commit

Permalink
Dep: Hook up UpdateChecker for dependencies that specify a version
Browse files Browse the repository at this point in the history
  • Loading branch information
greysteil committed Jul 22, 2018
1 parent 4666c4c commit 5e48ff9
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 33 deletions.
75 changes: 44 additions & 31 deletions lib/dependabot/update_checkers/go/dep.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ module Dependabot
module UpdateCheckers
module Go
class Dep < Dependabot::UpdateCheckers::Base
require_relative "dep/file_preparer"
require_relative "dep/latest_version_finder"
require_relative "dep/version_resolver"

def latest_version
@latest_version ||=
Expand All @@ -19,20 +21,28 @@ def latest_version
end

def latest_resolvable_version
# Resolving the dependency files to get the latest version of
# this dependency that doesn't cause conflicts is hard, and needs to
# be done through a language helper that piggy-backs off of the
# package manager's own resolution logic (see PHP, for example).
@latest_resolvable_version ||=
if git_dependency?
latest_resolvable_version_for_git_dependency
else
fetch_latest_resolvable_version(unlock_requirement: true)
end
end

def latest_resolvable_version_with_no_unlock
# Will need the same resolution logic as above, just without the
# file unlocking.
@latest_resolvable_version_with_no_unlock ||=
if git_dependency?
latest_resolvable_commit_with_unchanged_git_source
else
fetch_latest_resolvable_version(unlock_requirement: false)
end
end

def updated_requirements
# If the dependency file needs to be updated we store the updated
# requirements on the dependency.
#
# TODO!
dependency.requirements
end

Expand All @@ -47,37 +57,40 @@ def updated_dependencies_after_full_unlock
raise NotImplementedError
end

def dependencies_to_import
# There's no way to tell whether dependencies that appear in the
# lockfile are there because they're imported themselves or because
# they're sub-dependencies of something else. v0.5.0 will fix that
# problem, but for now we just have to import everything.
#
# NOTE: This means the `inputs-digest` we generate will be wrong.
# That's a pity, but we'd have to iterate through too many
# possibilities to get it right. Again, this is fixed in v0.5.0.
parsed_file(lockfile).fetch("required").map do |detail|
detail["name"]
end
def latest_resolvable_version_for_git_dependency
# TODO
end

def latest_resolvable_commit_with_unchanged_git_source
# TODO
end

def parsed_file(file)
@parsed_file ||= {}
@parsed_file[file.name] ||= TomlRB.parse(file.content)
rescue TomlRB::ParseError
raise Dependabot::DependencyFileNotParseable, file.path
def fetch_latest_resolvable_version(unlock_requirement:)
prepared_files = FilePreparer.new(
dependency_files: dependency_files,
dependency: dependency,
unlock_requirement: unlock_requirement,
remove_git_source: git_dependency?,
latest_allowable_version: latest_version
).prepared_dependency_files

VersionResolver.new(
dependency: dependency,
dependency_files: prepared_files,
credentials: credentials
).latest_resolvable_version
end

def manifest
@manifest ||= dependency_files.find { |f| f.name == "Gopkg.toml" }
raise "No Gopkg.lock!" unless @manifest
@manifest
def git_dependency?
git_commit_checker.git_dependency?
end

def lockfile
@lockfile = dependency_files.find { |f| f.name == "Gopkg.lock" }
raise "No Gopkg.lock!" unless @lockfile
@lockfile
def git_commit_checker
@git_commit_checker ||=
GitCommitChecker.new(
dependency: dependency,
credentials: credentials
)
end
end
end
Expand Down
27 changes: 25 additions & 2 deletions lib/dependabot/update_checkers/go/dep/version_resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,31 @@ def go_dir
end

def dummy_app_content
"package main\n\nimport \"fmt\"\n\nfunc main() {\n"\
" fmt.Printf(\"hello, world\\n\")\n}"
base = "package main\n\n"\
"import \"fmt\"\n\n"

dependencies_to_import.each { |nm| base += "import \"#{nm}\"\n\n" }

base + "func main() {\n fmt.Printf(\"hello, world\\n\")\n}"
end

def dependencies_to_import
# There's no way to tell whether dependencies that appear in the
# lockfile are there because they're imported themselves or because
# they're sub-dependencies of something else. v0.5.0 will fix that
# problem, but for now we just have to import everything.
#
# NOTE: This means the `inputs-digest` we generate will be wrong.
# That's a pity, but we'd have to iterate through too many
# possibilities to get it right. Again, this is fixed in v0.5.0.
return [] unless lockfile
TomlRB.parse(lockfile.content).fetch("projects").map do |detail|
detail["name"]
end
end

def lockfile
@lockfile = dependency_files.find { |f| f.name == "Gopkg.lock" }
end

def version_class
Expand Down
67 changes: 67 additions & 0 deletions spec/dependabot/update_checkers/go/dep_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,71 @@
expect(checker.latest_version).to eq(Gem::Version.new("0.3.0"))
end
end

describe "#latest_resolvable_version" do
subject { checker.latest_resolvable_version }

it "delegates to VersionResolver" do
prepped_files = described_class::FilePreparer.new(
dependency_files: dependency_files,
dependency: dependency,
unlock_requirement: true,
remove_git_source: false,
latest_allowable_version: Gem::Version.new("0.3.0")
).prepared_dependency_files

expect(described_class::VersionResolver).to receive(:new).with(
dependency: dependency,
dependency_files: prepped_files,
credentials: credentials
).and_call_original

expect(checker.latest_resolvable_version).to eq(Gem::Version.new("0.3.0"))
end

context "with a manifest file that needs unlocking" do
let(:manifest_fixture_name) { "bare_version.toml" }
let(:lockfile_fixture_name) { "bare_version.lock" }
let(:req_str) { "0.2.0" }

it "unlocks the manifest and gets the correct version" do
expect(checker.latest_resolvable_version).
to eq(Gem::Version.new("0.3.0"))
end
end
end

describe "#latest_resolvable_version_with_no_unlock" do
subject { checker.latest_resolvable_version_with_no_unlock }

it "delegates to VersionResolver" do
prepped_files = described_class::FilePreparer.new(
dependency_files: dependency_files,
dependency: dependency,
unlock_requirement: true,
remove_git_source: false,
latest_allowable_version: Gem::Version.new("0.3.0")
).prepared_dependency_files

expect(described_class::VersionResolver).to receive(:new).with(
dependency: dependency,
dependency_files: prepped_files,
credentials: credentials
).and_call_original

expect(checker.latest_resolvable_version_with_no_unlock).
to eq(Gem::Version.new("0.3.0"))
end

context "with a manifest file that needs unlocking" do
let(:manifest_fixture_name) { "bare_version.toml" }
let(:lockfile_fixture_name) { "bare_version.lock" }
let(:req_str) { "0.2.0" }

it "doesn't unlock the manifest" do
expect(checker.latest_resolvable_version_with_no_unlock).
to eq(Gem::Version.new("0.2.0"))
end
end
end
end

0 comments on commit 5e48ff9

Please sign in to comment.