diff --git a/lib/license_finder/package_managers/go_dep.rb b/lib/license_finder/package_managers/go_dep.rb index afe22d434..1d2677b61 100644 --- a/lib/license_finder/package_managers/go_dep.rb +++ b/lib/license_finder/package_managers/go_dep.rb @@ -10,20 +10,8 @@ def initialize(options = {}) end def current_packages - json = JSON.parse(detected_package_path.read) + packages_from_json(detected_package_path.read) # godep includes subpackages as a seperate dependency, we can de-dup that - - dependencies_info = json['Deps'].map do |dep_json| - { - 'Homepage' => homepage(dep_json), - 'ImportPath' => import_path(dep_json), - 'InstallPath' => dep_json['InstallPath'], - 'Rev' => dep_json['Rev'] - } - end - dependencies_info.uniq.map do |info| - GoPackage.from_dependency(info, install_prefix, @full_version) - end end def self.takes_priority_over @@ -53,15 +41,31 @@ def workspace_dir project_path.join('Godeps/_workspace') end - def homepage(dependency_json) - import_path dependency_json - end + def packages_from_json(json_string) + all_packages = JSON.parse(json_string)['Deps'] + packages_grouped_by_revision = all_packages.group_by { |package| package['Rev'] } - def import_path(dependency_json) - import_path = dependency_json['ImportPath'] - return import_path unless import_path.include?('github.com') + result = [] + packages_grouped_by_revision.each do |_sha, packages_in_group| + all_paths_in_group = packages_in_group.map { |p| p['ImportPath'] } + common_paths = CommonPathHelper.longest_common_paths(all_paths_in_group) + package_info = packages_in_group.first + + common_paths.each do |common_path| + dependency_info_hash = { + 'Homepage' => common_path, + 'ImportPath' => common_path, + 'InstallPath' => package_info['InstallPath'], + 'Rev' => package_info['Rev'] + } + + result << GoPackage.from_dependency(dependency_info_hash, + install_prefix, + @full_version) + end + end - import_path.split('/')[0..2].join('/') + result end end end diff --git a/lib/license_finder/package_managers/govendor.rb b/lib/license_finder/package_managers/govendor.rb index 53a6348cd..321bd9b66 100644 --- a/lib/license_finder/package_managers/govendor.rb +++ b/lib/license_finder/package_managers/govendor.rb @@ -57,7 +57,7 @@ def packages_from_json(json_string) result = packages_with_no_sha packages_by_sha.each do |sha, paths| - common_paths = CommonPathHelper.shortest_common_paths(paths) + common_paths = CommonPathHelper.longest_common_paths(paths) common_paths.each { |cp| result << { sha: sha, path: cp } } end diff --git a/lib/license_finder/package_managers/gvt.rb b/lib/license_finder/package_managers/gvt.rb index 4c83bb6b1..bedf5e4de 100644 --- a/lib/license_finder/package_managers/gvt.rb +++ b/lib/license_finder/package_managers/gvt.rb @@ -66,7 +66,7 @@ def packages_from_output(output, path) result = [] packages_by_sha.each do |sha, info| - paths = CommonPathHelper.shortest_common_paths(info['paths']) + paths = CommonPathHelper.longest_common_paths(info['paths']) paths.each { |p| result << [sha, p, info['repo']] } end diff --git a/lib/license_finder/shared_helpers/common_path.rb b/lib/license_finder/shared_helpers/common_path.rb index e20bd3eee..06967bd72 100644 --- a/lib/license_finder/shared_helpers/common_path.rb +++ b/lib/license_finder/shared_helpers/common_path.rb @@ -1,26 +1,26 @@ # frozen_string_literal: true module CommonPathHelper - def self.shortest_common_paths(paths) + def self.longest_common_paths(paths) [].tap do |common_paths| # organize by matching root paths paths_with_roots = paths.group_by { |path| path.split('/').first } paths_with_roots.each do |common_root, full_paths| # use the shortest path as the 'template' shortest_path = full_paths.min_by { |path| path.split('/').length } - shortest_common_path = common_root + longest_common_path = common_root # iterate through each subpath of the 'template' shortest_path.split('/').each_with_index do |subpath, i| - potential_path = i.zero? ? shortest_common_path : [shortest_common_path, subpath].join('/') + potential_path = i.zero? ? longest_common_path : [longest_common_path, subpath].join('/') # check each for the existence of the subsequent subpath mismatch = full_paths.any? { |path| !path.start_with?(potential_path) } break if mismatch - shortest_common_path = potential_path + longest_common_path = potential_path end - common_paths << shortest_common_path + common_paths << longest_common_path end end end diff --git a/spec/fixtures/config/godep_with_duplicates.json b/spec/fixtures/config/godep_with_duplicates.json index 4aff7d88b..acf6fa632 100644 --- a/spec/fixtures/config/godep_with_duplicates.json +++ b/spec/fixtures/config/godep_with_duplicates.json @@ -11,8 +11,12 @@ "Rev": "28838aae6e8158e3695cf90e2f0ed2498b68ee1d" }, { - "ImportPath": "github.com/foo/baz/sub3", + "ImportPath": "code.google.com/foo/bar", "Rev": "28838aae6e8158e3695cf90e2f0ed2498b68ee1d" + }, + { + "ImportPath": "github.com/foo/baz/sub3", + "Rev": "28838aae6e8158e3695cf90e2f0ed2498b68ee1e" } ] } diff --git a/spec/lib/license_finder/package_managers/go_dep_spec.rb b/spec/lib/license_finder/package_managers/go_dep_spec.rb index bb7dbfc82..c24c39e38 100644 --- a/spec/lib/license_finder/package_managers/go_dep_spec.rb +++ b/spec/lib/license_finder/package_managers/go_dep_spec.rb @@ -45,6 +45,44 @@ module LicenseFinder expect(packages[2].homepage).to eq('code.google.com/foo/bar') end + context 'when the GoDep returns entries with same sha and common base path' do + let(:options) { { go_full_version: true } } + let(:all_packages) { subject.current_packages } + + before do + File.write('/fake/path/Godeps/Godeps.json', content_with_duplicates) + end + + it 'filters dependencies based on same shas and common paths' do + expect(all_packages.length).to eq(3) + end + + it 'removes duplicate entries having same sha with common base path' do + packages_with_common_path = all_packages.select do |package| + package.name == 'github.com/foo/baz' + end + + expect(packages_with_common_path.length).to eq(1) + expect(packages_with_common_path.first.name).to eq('github.com/foo/baz') + expect(packages_with_common_path.first.version).to eq('28838aae6e8158e3695cf90e2f0ed2498b68ee1d') + end + + it 'shows entries having same shas with no common base path' do + packages_with_same_sha = all_packages.select do |package| + package.version == '28838aae6e8158e3695cf90e2f0ed2498b68ee1d' + end + + expect(packages_with_same_sha.length).to eq(2) + expect(packages_with_same_sha[0].name).to eq('github.com/foo/baz') + expect(packages_with_same_sha[1].name).to eq('code.google.com/foo/bar') + end + + it 'shows entries with different shas' do + expect(all_packages.last.name).to eq('github.com/foo/baz/sub3') + expect(all_packages.last.version).to eq('28838aae6e8158e3695cf90e2f0ed2498b68ee1e') + end + end + context 'when dependencies are vendored' do before do allow(FileTest).to receive(:directory?).with('/fake/path/Godeps/_workspace').and_return(true) @@ -64,6 +102,7 @@ module LicenseFinder context 'when requesting the full version' do let(:options) { { go_full_version: true } } + it 'list the dependencies with full version' do expect(subject.current_packages.map(&:version)).to eq %w[ 61164e49940b423ba1f12ddbdf01632ac793e5e9 @@ -74,18 +113,6 @@ module LicenseFinder end end - context 'when there are duplicate dependencies' do - before do - File.write('/fake/path/Godeps/Godeps.json', content_with_duplicates) - end - - it 'should return one dependency only' do - packages = subject.current_packages - expect(packages.map(&:name)).to eq(['github.com/foo/baz']) - expect(packages.map(&:version)).to eq(['28838aa']) - end - end - context 'when dependencies are not vendored' do before do @orig_gopath = ENV['GOPATH'] diff --git a/spec/lib/license_finder/shared_helpers/common_path_spec.rb b/spec/lib/license_finder/shared_helpers/common_path_spec.rb index f58155a1e..5c8f53aed 100644 --- a/spec/lib/license_finder/shared_helpers/common_path_spec.rb +++ b/spec/lib/license_finder/shared_helpers/common_path_spec.rb @@ -13,12 +13,12 @@ end it 'only shows the entry with common base path once' do - paths = CommonPathHelper.shortest_common_paths gvt_output_with_common_paths + paths = CommonPathHelper.longest_common_paths gvt_output_with_common_paths expect(paths).to match_array %w[cloud.google.com/go] end it 'shows entries with same sha when they do not have a common base path' do - paths = CommonPathHelper.shortest_common_paths gvt_output_without_common_paths + paths = CommonPathHelper.longest_common_paths gvt_output_without_common_paths expect(paths).to match_array %w[cloud.google.com/go cloud.aws.com/go/metadata] end end