Skip to content

Commit

Permalink
Change Go modules to list imported modules
Browse files Browse the repository at this point in the history
If module mode is enabled (`-m`), all possible module dependencies are
listed, regardless of whether the packages requiring the module are
actually imported.

This results in un-imported modules being listed, which is incongruous
with other Go package manager implementations.

The removal of the `-m` flag causes `go list` to list imported packages.
A format string is used so that the corresponding module is listed in
place of each imported package.
  • Loading branch information
miquella committed Jul 7, 2020
1 parent 284cc5c commit 34361fd
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 8 deletions.
28 changes: 23 additions & 5 deletions lib/license_finder/package_managers/go_modules.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,30 @@ def current_packages

def packages_info
Dir.chdir(project_path) do
info_output, stderr, _status = Cmd.run("GO111MODULE=on go list -m -f '{{.Path}},{{.Version}},{{.Dir}}' all")
if stderr =~ Regexp.compile("can't compute 'all' using the vendor directory")
info_output, _stderr, _status = Cmd.run("GO111MODULE=on go list -m -mod=mod -f '{{.Path}},{{.Version}},{{.Dir}}' all")
end
# Explanations:
# * Ignore standard library packages
# (not .Standard)
# * Replacement modules are respected
# (or .Module.Replace .Module)
# * Module cache directory or (vendored) package directory
# (or $mod.Dir .Dir)
format_str = \
'{{ if not .Standard }}'\
'{{ $mod := (or .Module.Replace .Module) }}'\
'{{ $mod.Path }},{{ $mod.Version }},{{ or $mod.Dir .Dir }}'\
'{{ end }}'

info_output.split("\n")
# The module list flag (`-m`) is intentionally not used here. If the module
# dependency tree were followed, transitive dependencies that are never imported
# may be included.
#
# Instead, the owning module is listed for each imported package. This better
# matches the implementation of other Go package managers.
info_output, stderr, _status = Cmd.run("GO111MODULE=on go list -f '#{format_str}' all")
info_output, _stderr, _status = Cmd.run("GO111MODULE=on go list -mod=mod -f '#{format_str}' all") if stderr =~ Regexp.compile("can't compute 'all' using the vendor directory")

# Since many packages may belong to a single module, #uniq is used to deduplicate
info_output.split("\n").uniq
end
end

Expand Down
8 changes: 5 additions & 3 deletions spec/lib/license_finder/package_managers/go_modules_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ module LicenseFinder
let(:src_path) { '/workspace/code' }
let(:mod_path) { "#{src_path}/go.mod" }
let(:vendor_path) { "#{src_path}/vendor" }
let(:go_list_format) { '{{ if not .Standard }}{{ $mod := (or .Module.Replace .Module) }}{{ $mod.Path }},{{ $mod.Version }},{{ or $mod.Dir .Dir }}{{ end }}' }
let(:go_list_string) do
"foo,,/workspace/code/\ngopkg.in/check.v1,v0.0.0-20161208181325-20d25e280405,"\
"/workspace/LicenseFinder/features/fixtures/go_modules/vendor/gopkg.in/check.v1\n"\
"gopkg.in/yaml.v2,v2.2.1,/workspace/LicenseFinder/features/fixtures/go_modules/vendor/gopkg.in/yaml.v2\n"\
'gopkg.in/yaml.v2,v2.2.1,/workspace/LicenseFinder/features/fixtures/go_modules/vendor/gopkg.in/yaml.v2'
end
subject { GoModules.new(project_path: Pathname(src_path), logger: double(:logger, active: nil)) }
Expand All @@ -24,7 +26,7 @@ module LicenseFinder
FileUtils.mkdir_p(vendor_path)
File.write(mod_path, content)

allow(SharedHelpers::Cmd).to receive(:run).with("GO111MODULE=on go list -m -f '{{.Path}},{{.Version}},{{.Dir}}' all").and_return(go_list_string)
allow(SharedHelpers::Cmd).to receive(:run).with("GO111MODULE=on go list -f '#{go_list_format}' all").and_return(go_list_string)
end

after do
Expand Down Expand Up @@ -58,10 +60,10 @@ module LicenseFinder
context 'when compute is not allowed on vendor' do
before do
allow(SharedHelpers::Cmd).to receive(:run)
.with("GO111MODULE=on go list -m -f '{{.Path}},{{.Version}},{{.Dir}}' all")
.with("GO111MODULE=on go list -f '#{go_list_format}' all")
.and_return(['', "go list -m: can't compute 'all' using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)\n", 1])
allow(SharedHelpers::Cmd).to receive(:run)
.with("GO111MODULE=on go list -m -mod=mod -f '{{.Path}},{{.Version}},{{.Dir}}' all")
.with("GO111MODULE=on go list -mod=mod -f '#{go_list_format}' all")
.and_return(go_list_string)
end

Expand Down

0 comments on commit 34361fd

Please sign in to comment.