Skip to content

Commit

Permalink
Condense gvt paths with identical shas into their common path
Browse files Browse the repository at this point in the history
[Finish #155382947, #154072994, #155830792]

Signed-off-by: Vikram Yadav <vyadav@pivotal.io>
  • Loading branch information
Ryan Collins authored and Ryan Collins committed Mar 21, 2018
1 parent f2e6238 commit 9e1071d
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 3 deletions.
27 changes: 24 additions & 3 deletions lib/license_finder/package_managers/gvt.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'license_finder/shared_helpers/common_path'
module LicenseFinder
class Gvt < PackageManager
def possible_package_paths
Expand Down Expand Up @@ -47,12 +48,32 @@ def self.takes_priority_over

def packages_from_output(output, path)
package_lines = output.split("\n")
package_lines.map do |package_line|
import_path, revision, repo = package_line.split
packages_by_sha = {}
package_lines.each do |p|
package_path, sha, repo = p.split
if packages_by_sha[sha].nil?
packages_by_sha[sha] = {}
packages_by_sha[sha]['paths'] = [package_path]
packages_by_sha[sha]['repo'] = repo
else
packages_by_sha[sha]['paths'] << package_path
end
end

result = []
packages_by_sha.each do |sha, info|
paths = CommonPathHelper.shortest_common_paths(info['paths'])

paths.each { |p| result << [sha, p, info['repo']] }
end

result.map do |package_info|
sha, import_path, repo = package_info

GoPackage.from_dependency({
'ImportPath' => import_path,
'InstallPath' => path.join(import_path),
'Rev' => revision,
'Rev' => sha,
'Homepage' => repo
}, nil, true)
end
Expand Down
25 changes: 25 additions & 0 deletions lib/license_finder/shared_helpers/common_path.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module CommonPathHelper
def self.shortest_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.sort_by { |path| path.split('/').length }.first
shortest_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('/')

# 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
end
common_paths << shortest_common_path
end
end
end
end
55 changes: 55 additions & 0 deletions spec/lib/license_finder/package_managers/gvt_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,61 @@ module LicenseFinder
end
end

context 'when the GVT returns entries with same sha with common base path' do
let(:gvt_output_with_common_paths) do
<<OUTPUT
cloud.google.com/go/bigquery abcd gcloud-repo
cloud.google.com/go/civil abcd gcloud-repo
cloud.google.com/go/compute/metadata abcd gcloud-repo
OUTPUT
end
let(:gvt_output_without_common_paths) do
<<OUTPUT
cloud.google.com/go/bigquery/adsf abcd gcloud-repo
cloud.google.com/go/civil abcd gcloud-repo
cloud.aws.com/go/metadata abcd gcloud-repo
OUTPUT
end

before do
FileUtils.mkdir_p '/app/vendor'
File.write('/app/vendor/manifest', content)
end

it 'only shows the entry with common base path once' do
allow(SharedHelpers::Cmd).to receive(:run).with('gvt list -f "{{.Importpath}} {{.Revision}} {{.Repository}}"') do
[gvt_output_with_common_paths, '', cmd_success]
end
expect(subject.current_packages.length).to eq 1

package = subject.current_packages.first
expect(package.name).to eq 'cloud.google.com/go'
expect(package.install_path).to eq Pathname('/app/vendor/cloud.google.com/go')
expect(package.version).to eq 'abcd'
expect(package.homepage).to eq 'gcloud-repo'
end

it 'shows entries with same sha when they do not have a common base path' do
allow(SharedHelpers::Cmd).to receive(:run).with('gvt list -f "{{.Importpath}} {{.Revision}} {{.Repository}}"') do
[gvt_output_without_common_paths, '', cmd_success]
end

expect(subject.current_packages.length).to eq 2

first = subject.current_packages.first
expect(first.name).to eq 'cloud.google.com/go'
expect(first.install_path).to eq Pathname('/app/vendor/cloud.google.com/go')
expect(first.version).to eq 'abcd'
expect(first.homepage).to eq 'gcloud-repo'

last = subject.current_packages.last
expect(last.name).to eq 'cloud.aws.com/go/metadata'
expect(last.install_path).to eq Pathname('/app/vendor/cloud.aws.com/go/metadata')
expect(last.version).to eq 'abcd'
expect(last.homepage).to eq 'gcloud-repo'
end
end

it 'returns empty package list if \'gvt list\' fails' do
allow(SharedHelpers::Cmd).to receive(:run).with(anything) do
["my-package-name 123abc example.com\npackage-name-2 456xyz anotherurl.com", '', cmd_failure]
Expand Down
23 changes: 23 additions & 0 deletions spec/lib/license_finder/shared_helpers/common_path_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require 'spec_helper'
require 'license_finder/shared_helpers/common_path'

describe CommonPathHelper do
context 'when the GVT returns entries with same sha with common base path' do
let(:gvt_output_with_common_paths) do
%w[cloud.google.com/go/bigquery cloud.google.com/go/civil cloud.google.com/go/compute/metadata]
end
let(:gvt_output_without_common_paths) do
%w[cloud.google.com/go/bigquery/adsf cloud.google.com/go/civil cloud.aws.com/go/metadata]
end

it 'only shows the entry with common base path once' do
paths = CommonPathHelper.shortest_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
expect(paths).to match_array %w[cloud.google.com/go cloud.aws.com/go/metadata]
end
end
end

0 comments on commit 9e1071d

Please sign in to comment.