Skip to content

Commit 50e2c0c

Browse files
author
Pete Wagner
authored
Merge pull request dependabot#2596 from dependabot/jurre/go-vendor
Add vendoring support for go_modules
2 parents a94e32d + e452572 commit 50e2c0c

File tree

16 files changed

+758
-8
lines changed

16 files changed

+758
-8
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Gemfile.lock
99
vendor
1010
!bundler/spec/fixtures/vendored_gems/vendor
1111
!common/spec/fixtures/projects/**/*/vendor
12+
!go_modules/spec/fixtures/projects/**/*
1213
.DS_Store
1314
*.pyc
1415
*git.store

go_modules/lib/dependabot/go_modules/file_updater.rb

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require "dependabot/shared_helpers"
44
require "dependabot/file_updaters"
55
require "dependabot/file_updaters/base"
6+
require "dependabot/file_updaters/vendor_updater"
67

78
module Dependabot
89
module GoModules
@@ -54,6 +55,12 @@ def updated_dependency_files
5455
content: file_updater.updated_go_sum_content
5556
)
5657
end
58+
59+
vendor_updater.
60+
updated_vendor_cache_files(base_directory: directory).
61+
each do |file|
62+
updated_files << file
63+
end
5764
end
5865

5966
raise "No files changed!" if updated_files.none?
@@ -81,16 +88,36 @@ def directory
8188
dependency_files.first.directory
8289
end
8390

91+
def vendor_dir
92+
File.join(repo_contents_path, directory, "vendor")
93+
end
94+
95+
def vendor_updater
96+
Dependabot::FileUpdaters::VendorUpdater.new(
97+
repo_contents_path: repo_contents_path,
98+
vendor_dir: vendor_dir
99+
)
100+
end
101+
84102
def file_updater
85103
@file_updater ||=
86104
GoModUpdater.new(
87105
dependencies: dependencies,
88106
credentials: credentials,
89107
repo_contents_path: repo_contents_path,
90108
directory: directory,
91-
tidy: !@repo_contents_stub && options.fetch(:go_mod_tidy, false)
109+
options: { tidy: tidy?, vendor: vendor? }
92110
)
93111
end
112+
113+
def tidy?
114+
!@repo_contents_stub && options.fetch(:go_mod_tidy, false)
115+
end
116+
117+
def vendor?
118+
File.exist?(File.join(vendor_dir, "modules.txt")) &&
119+
options.fetch(:go_mod_vendor, false)
120+
end
94121
end
95122
end
96123
end

go_modules/lib/dependabot/go_modules/file_updater/go_mod_updater.rb

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ class GoModUpdater
2626
].freeze
2727

2828
def initialize(dependencies:, credentials:, repo_contents_path:,
29-
directory:, tidy:)
29+
directory:, options:)
3030
@dependencies = dependencies
3131
@credentials = credentials
3232
@repo_contents_path = repo_contents_path
3333
@directory = directory
34-
@tidy = tidy
34+
@tidy = options.fetch(:tidy, false)
35+
@vendor = options.fetch(:vendor, false)
3536
end
3637

3738
def updated_go_mod_content
@@ -51,7 +52,7 @@ def updated_files
5152
@updated_files ||= update_files
5253
end
5354

54-
def update_files
55+
def update_files # rubocop:disable Metrics/AbcSize
5556
in_repo_path do
5657
# Map paths in local replace directives to path hashes
5758

@@ -71,6 +72,7 @@ def update_files
7172
# Then run `go get` to pick up other changes to the file caused by
7273
# the upgrade
7374
run_go_get
75+
run_go_vendor
7476
run_go_mod_tidy
7577

7678
# At this point, the go.mod returned from run_go_get contains the
@@ -111,6 +113,14 @@ def run_go_mod_tidy
111113
handle_subprocess_error(stderr) unless status.success?
112114
end
113115

116+
def run_go_vendor
117+
return unless vendor?
118+
119+
command = "go mod vendor"
120+
_, stderr, status = Open3.capture3(ENVIRONMENT, command)
121+
handle_subprocess_error(stderr) unless status.success?
122+
end
123+
114124
def update_go_mod(dependencies)
115125
deps = dependencies.map do |dep|
116126
{
@@ -273,6 +283,10 @@ def write_go_mod(body)
273283
def tidy?
274284
!!@tidy
275285
end
286+
287+
def vendor?
288+
!!@vendor
289+
end
276290
end
277291
end
278292
end

go_modules/spec/dependabot/go_modules/file_updater/go_mod_updater_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
}],
1818
repo_contents_path: repo_contents_path,
1919
directory: "/",
20-
tidy: tidy
20+
options: { tidy: tidy, vendor: false }
2121
)
2222
end
2323

go_modules/spec/dependabot/go_modules/file_updater_spec.rb

Lines changed: 105 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
let(:files) { [go_mod, go_sum] }
2323
let(:project_name) { "go_sum" }
2424
let(:repo_contents_path) { build_tmp_repo(project_name) }
25+
let(:vendor) { false }
2526

2627
let(:credentials) do
2728
[{
@@ -31,7 +32,7 @@
3132
"password" => "token"
3233
}]
3334
end
34-
let(:options) { {} }
35+
let(:options) { { go_mod_vendor: vendor } }
3536

3637
let(:go_mod) do
3738
Dependabot::DependencyFile.new(name: "go.mod", content: go_mod_body)
@@ -93,7 +94,7 @@
9394
end
9495

9596
context "options" do
96-
let(:options) { { go_mod_tidy: true } }
97+
let(:options) { { go_mod_tidy: true, go_mod_vendor: vendor } }
9798
let(:dummy_updater) do
9899
instance_double(
99100
Dependabot::GoModules::FileUpdater::GoModUpdater,
@@ -110,11 +111,24 @@
110111
credentials: credentials,
111112
repo_contents_path: repo_contents_path,
112113
directory: "/",
113-
tidy: true
114+
options: { tidy: true, vendor: false }
114115
).and_return(dummy_updater)
115116

116117
updater.updated_dependency_files
117118
end
119+
120+
context "vendor option is passed but vendor directory not checked in" do
121+
let(:vendor) { true }
122+
123+
it "does not includes the vendored files" do
124+
expect(updater.updated_dependency_files.map(&:name)).to match_array(
125+
%w(
126+
go.mod
127+
go.sum
128+
)
129+
)
130+
end
131+
end
118132
end
119133

120134
context "without a go.sum" do
@@ -163,5 +177,93 @@
163177
expect(updated_files.find { |f| f.name == "go.sum" }).to_not be_nil
164178
end
165179
end
180+
181+
context "vendoring" do
182+
let(:project_name) { "vendor" }
183+
let(:vendor) { true }
184+
185+
let(:dependency_name) { "github.com/pkg/errors" }
186+
let(:dependency_version) { "v0.9.1" }
187+
let(:dependency_previous_version) { "v0.8.0" }
188+
let(:requirements) do
189+
[{
190+
file: "go.mod",
191+
requirement: dependency_version,
192+
groups: [],
193+
source: {
194+
type: "default",
195+
source: "github.com/pkg"
196+
}
197+
}]
198+
end
199+
let(:previous_requirements) do
200+
[{
201+
file: "go.mod",
202+
requirement: dependency_previous_version,
203+
groups: [],
204+
source: {
205+
type: "default",
206+
source: "github.com/pkg"
207+
}
208+
}]
209+
end
210+
211+
it "updates the go.mod" do
212+
expect(go_mod_body).to include("github.com/pkg/errors v0.8.0")
213+
214+
updater.updated_dependency_files
215+
216+
go_mod_file = updater.updated_dependency_files.find do |file|
217+
file.name == "go.mod"
218+
end
219+
220+
expect(go_mod_file.content).to include "github.com/pkg/errors v0.9.1"
221+
end
222+
223+
it "includes the vendored files" do
224+
expect(updater.updated_dependency_files.map(&:name)).to match_array(
225+
%w(
226+
go.mod
227+
go.sum
228+
vendor/github.com/pkg/errors/.travis.yml
229+
vendor/github.com/pkg/errors/Makefile
230+
vendor/github.com/pkg/errors/README.md
231+
vendor/github.com/pkg/errors/errors.go
232+
vendor/github.com/pkg/errors/go113.go
233+
vendor/github.com/pkg/errors/stack.go
234+
vendor/modules.txt
235+
)
236+
)
237+
end
238+
239+
it "updates the vendor/modules.txt file to the right version" do
240+
modules_file = updater.updated_dependency_files.find do |file|
241+
file.name == "vendor/modules.txt"
242+
end
243+
244+
expect(modules_file.content).
245+
to_not include "github.com/pkg/errors v0.8.0"
246+
expect(modules_file.content).to include "github.com/pkg/errors v0.9.1"
247+
end
248+
249+
it "includes the new source code" do
250+
# Sample to verify the source code matches:
251+
# https://github.com/pkg/errors/compare/v0.8.0...v0.9.1
252+
stack_file = updater.updated_dependency_files.find do |file|
253+
file.name == "vendor/github.com/pkg/errors/stack.go"
254+
end
255+
256+
expect(stack_file.content).to include(
257+
<<~LINE
258+
Format formats the stack of Frames according to the fmt.Formatter interface.
259+
LINE
260+
)
261+
expect(stack_file.content).to_not include(
262+
<<~LINE
263+
segments from the beginning of the file path until the number of path
264+
LINE
265+
)
266+
end
267+
end
166268
end
167269
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module github.com/dependabot/vgotest
2+
3+
go 1.12
4+
5+
require github.com/pkg/errors v0.8.0
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
2+
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package main
2+
3+
import (
4+
_ "github.com/pkg/errors"
5+
)
6+
7+
func main() {
8+
}

go_modules/spec/fixtures/projects/vendor/vendor/github.com/pkg/errors/.gitignore

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go_modules/spec/fixtures/projects/vendor/vendor/github.com/pkg/errors/.travis.yml

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go_modules/spec/fixtures/projects/vendor/vendor/github.com/pkg/errors/LICENSE

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)