license_finder 2.0.4 → 2.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -4
  3. data/.travis/install_godep.sh +6 -0
  4. data/.travis/install_gradle.sh +1 -1
  5. data/.travis/install_rebar.sh +7 -5
  6. data/CHANGELOG.rdoc +13 -0
  7. data/CONTRIBUTING.md +16 -2
  8. data/README.md +41 -4
  9. data/Rakefile +8 -2
  10. data/features/features/{cli_spec.rb → cli/cli_spec.rb} +24 -18
  11. data/features/features/configure/add_dependencies_spec.rb +18 -1
  12. data/features/features/configure/approve_dependencies_spec.rb +31 -1
  13. data/features/features/configure/assign_licenses_spec.rb +18 -3
  14. data/features/features/configure/blacklist_licenses_spec.rb +30 -0
  15. data/features/features/configure/ignore_dependencies_spec.rb +1 -1
  16. data/features/features/configure/ignore_groups_spec.rb +16 -1
  17. data/features/features/configure/name_project_spec.rb +1 -1
  18. data/features/features/configure/set_project_path_spec.rb +1 -1
  19. data/features/features/configure/whitelist_licenses_spec.rb +1 -3
  20. data/features/features/package_managers/bower_spec.rb +1 -1
  21. data/features/features/package_managers/cocoapods_spec.rb +1 -1
  22. data/features/features/package_managers/godep_spec.rb +17 -0
  23. data/features/features/package_managers/gradle_spec.rb +18 -4
  24. data/features/features/package_managers/maven_spec.rb +1 -1
  25. data/features/features/package_managers/npm_spec.rb +1 -1
  26. data/features/features/package_managers/nuget_spec.rb +14 -0
  27. data/features/features/package_managers/pip_spec.rb +1 -1
  28. data/features/features/package_managers/rebar_spec.rb +1 -1
  29. data/features/features/report/composite_spec.rb +15 -0
  30. data/features/features/report/csv_spec.rb +1 -1
  31. data/features/features/report/diff_spec.rb +190 -0
  32. data/features/features/report/html_spec.rb +1 -1
  33. data/features/features/report/subproject_spec.rb +52 -0
  34. data/features/fixtures/file-based-libs-gradle/build.gradle +18 -0
  35. data/features/fixtures/file-based-libs-gradle/libs/data.json-0.2.3.jar +0 -0
  36. data/features/fixtures/gopath/src/github.com/pivotal/foo/Godeps/Godeps.json +16 -0
  37. data/features/fixtures/gopath/src/github.com/pivotal/foo/Godeps/Readme +5 -0
  38. data/features/fixtures/gopath/src/github.com/pivotal/foo/foo.go +6 -0
  39. data/features/fixtures/multi-module-gradle/build.gradle +18 -0
  40. data/features/fixtures/multi-module-gradle/module1/build.gradle +3 -0
  41. data/features/fixtures/multi-module-gradle/module2/build.gradle +3 -0
  42. data/features/fixtures/multi-module-gradle/settings.gradle +1 -0
  43. data/features/fixtures/nuget/Fun.Test/packages.config +4 -0
  44. data/features/fixtures/nuget/Fun/packages.config +5 -0
  45. data/features/fixtures/nuget/packages/Microsoft.AspNet.Mvc.4.0.30506.0/.keep +0 -0
  46. data/features/fixtures/nuget/packages/NUnit.2.6.4/.keep +0 -0
  47. data/features/fixtures/nuget/packages/Ninject.MVC4.3.2.1.0/.keep +0 -0
  48. data/features/fixtures/nuget/packages/repositories.config +6 -0
  49. data/features/fixtures/{build.gradle → single-module-gradle/build.gradle} +0 -0
  50. data/{spec → features/support}/feature_helper.rb +5 -1
  51. data/features/support/testing_dsl.rb +297 -212
  52. data/lib/license_finder/cli.rb +1 -0
  53. data/lib/license_finder/cli/base.rb +16 -3
  54. data/lib/license_finder/cli/blacklist.rb +30 -0
  55. data/lib/license_finder/cli/main.rb +62 -4
  56. data/lib/license_finder/configuration.rb +39 -8
  57. data/lib/license_finder/core.rb +13 -10
  58. data/lib/license_finder/decision_applier.rb +14 -9
  59. data/lib/license_finder/decisions.rb +24 -6
  60. data/lib/license_finder/diff.rb +47 -0
  61. data/lib/license_finder/license_aggregator.rb +25 -0
  62. data/lib/license_finder/package.rb +39 -6
  63. data/lib/license_finder/package_delta.rb +65 -0
  64. data/lib/license_finder/package_manager.rb +10 -3
  65. data/lib/license_finder/package_managers/bower.rb +3 -1
  66. data/lib/license_finder/package_managers/bundler.rb +18 -9
  67. data/lib/license_finder/package_managers/bundler_package.rb +6 -2
  68. data/lib/license_finder/package_managers/go_dep.rb +25 -0
  69. data/lib/license_finder/package_managers/go_package.rb +19 -0
  70. data/lib/license_finder/package_managers/go_workspace.rb +35 -0
  71. data/lib/license_finder/package_managers/gradle.rb +16 -17
  72. data/lib/license_finder/package_managers/gradle_dependency_finder.rb +13 -0
  73. data/lib/license_finder/package_managers/gradle_package.rb +6 -1
  74. data/lib/license_finder/package_managers/maven.rb +3 -1
  75. data/lib/license_finder/package_managers/merged_package.rb +43 -0
  76. data/lib/license_finder/package_managers/npm.rb +42 -24
  77. data/lib/license_finder/package_managers/nuget.rb +50 -0
  78. data/lib/license_finder/package_managers/nuget_package.rb +4 -0
  79. data/lib/license_finder/package_managers/pip_package.rb +1 -0
  80. data/lib/license_finder/package_managers/rebar.rb +2 -6
  81. data/lib/license_finder/platform.rb +4 -1
  82. data/lib/license_finder/project_finder.rb +56 -0
  83. data/lib/license_finder/report.rb +3 -2
  84. data/lib/license_finder/reports/csv_report.rb +6 -2
  85. data/lib/license_finder/reports/diff_report.rb +33 -0
  86. data/lib/license_finder/reports/merged_report.rb +13 -0
  87. data/lib/license_finder/version.rb +1 -1
  88. data/license_finder.gemspec +6 -2
  89. data/spec/dummy_app/Gemfile +6 -0
  90. data/spec/fixtures/all_pms/.envrc +0 -0
  91. data/spec/fixtures/all_pms/Godeps/Godeps.json +0 -0
  92. data/spec/fixtures/all_pms/packages/.keep +0 -0
  93. data/spec/fixtures/composite/Gemfile +0 -0
  94. data/spec/fixtures/composite/nested_project/.envrc +8 -0
  95. data/spec/fixtures/composite/nested_project/src/github.com/pivotal/foo/Godeps/Godeps.json +16 -0
  96. data/spec/fixtures/composite/nested_project/src/github.com/pivotal/foo/Godeps/Readme +5 -0
  97. data/spec/fixtures/composite/nested_project/src/github.com/pivotal/foo/foo.go +6 -0
  98. data/spec/fixtures/composite/not_a_project/DONTREADME.md +0 -0
  99. data/spec/fixtures/composite/project1/Gemfile +0 -0
  100. data/spec/fixtures/composite/project2/package.json +0 -0
  101. data/spec/lib/license_finder/cli/approvals_spec.rb +1 -1
  102. data/spec/lib/license_finder/cli/blacklist_spec.rb +58 -0
  103. data/spec/lib/license_finder/cli/dependencies_spec.rb +1 -1
  104. data/spec/lib/license_finder/cli/ignored_dependencies_spec.rb +1 -1
  105. data/spec/lib/license_finder/cli/ignored_groups_spec.rb +1 -1
  106. data/spec/lib/license_finder/cli/licenses_spec.rb +1 -1
  107. data/spec/lib/license_finder/cli/main_spec.rb +113 -7
  108. data/spec/lib/license_finder/cli/project_name_spec.rb +1 -1
  109. data/spec/lib/license_finder/cli/whitelist_spec.rb +1 -1
  110. data/spec/lib/license_finder/configuration_spec.rb +63 -4
  111. data/spec/lib/license_finder/core_spec.rb +49 -0
  112. data/spec/lib/license_finder/decision_applier_spec.rb +101 -1
  113. data/spec/lib/license_finder/decisions_spec.rb +62 -0
  114. data/spec/lib/license_finder/diff_spec.rb +106 -0
  115. data/spec/lib/license_finder/license_aggregator_spec.rb +61 -0
  116. data/spec/lib/license_finder/package_delta_spec.rb +18 -0
  117. data/spec/lib/license_finder/package_managers/bower_spec.rb +8 -6
  118. data/spec/lib/license_finder/package_managers/bundler_package_spec.rb +4 -2
  119. data/spec/lib/license_finder/package_managers/go_dep_spec.rb +72 -0
  120. data/spec/lib/license_finder/package_managers/go_workspace_spec.rb +69 -0
  121. data/spec/lib/license_finder/package_managers/gradle_package_spec.rb +9 -0
  122. data/spec/lib/license_finder/package_managers/gradle_spec.rb +94 -44
  123. data/spec/lib/license_finder/package_managers/maven_spec.rb +8 -6
  124. data/spec/lib/license_finder/package_managers/merged_package_spec.rb +52 -0
  125. data/spec/lib/license_finder/package_managers/npm_spec.rb +59 -20
  126. data/spec/lib/license_finder/package_managers/nuget_spec.rb +82 -0
  127. data/spec/lib/license_finder/package_managers/pip_package_spec.rb +1 -0
  128. data/spec/lib/license_finder/package_managers/rebar_spec.rb +12 -12
  129. data/spec/lib/license_finder/package_spec.rb +59 -2
  130. data/spec/lib/license_finder/project_finder_spec.rb +33 -0
  131. data/spec/lib/license_finder/reports/csv_report_spec.rb +9 -3
  132. data/spec/lib/license_finder/reports/diff_report_spec.rb +56 -0
  133. data/spec/lib/license_finder/reports/merged_report_spec.rb +21 -0
  134. metadata +82 -9
  135. data/.travis/install_virtualenv.sh +0 -9
@@ -1,33 +1,32 @@
1
- require "xmlsimple"
1
+ require 'xmlsimple'
2
+ require_relative 'gradle_dependency_finder'
2
3
 
3
4
  module LicenseFinder
4
5
  class Gradle < PackageManager
5
6
  def initialize(options={})
6
7
  super
7
- @command = options[:gradle_command] || "gradle"
8
+ @command = options[:gradle_command] || 'gradle'
8
9
  end
9
10
 
10
11
  def current_packages
11
- `#{@command} downloadLicenses`
12
-
13
- xml = license_report.read
14
-
15
- options = {
16
- 'GroupTags' => { 'dependencies' => 'dependency' }
17
- }
18
- dependencies = XmlSimple.xml_in(xml, options).fetch('dependency', [])
19
-
20
- dependencies.map do |dep|
21
- GradlePackage.new(dep, logger: logger)
12
+ command = "#{@command} downloadLicenses"
13
+ output, success = Dir.chdir(project_path) { capture(command) }
14
+ raise "Command '#{command}' failed to execute: #{output}" unless success
15
+
16
+ dependencies = GradleDependencyFinder.new(project_path).dependencies
17
+ packages = dependencies.flat_map do |xml_file|
18
+ options = {'GroupTags' => {'dependencies' => 'dependency'}}
19
+ contents = XmlSimple.xml_in(xml_file, options).fetch('dependency', [])
20
+ contents.map do |dep|
21
+ GradlePackage.new(dep, logger: logger)
22
+ end
22
23
  end
24
+
25
+ packages.uniq
23
26
  end
24
27
 
25
28
  private
26
29
 
27
- def license_report
28
- project_path.join('build/reports/license/dependency-license.xml')
29
- end
30
-
31
30
  def package_path
32
31
  project_path.join('build.gradle')
33
32
  end
@@ -0,0 +1,13 @@
1
+ module LicenseFinder
2
+ class GradleDependencyFinder
3
+ def initialize(project_path)
4
+ @project_path = project_path
5
+ end
6
+
7
+ def dependencies
8
+ Pathname
9
+ .glob(@project_path.join('**', 'dependency-license.xml'))
10
+ .map(&:read)
11
+ end
12
+ end
13
+ end
@@ -1,7 +1,12 @@
1
1
  module LicenseFinder
2
2
  class GradlePackage < Package
3
3
  def initialize(spec, options={})
4
- _, name, version = spec["name"].split(":")
4
+ name = spec["name"]
5
+ if name.scan(":").size == 2
6
+ _, name, version = name.split(":")
7
+ else
8
+ version = "unknown"
9
+ end
5
10
  licenses = Array(spec["license"])
6
11
  .map { |l| l["name"] }
7
12
  .reject { |name| name == "No license found" }
@@ -3,7 +3,9 @@ require "xmlsimple"
3
3
  module LicenseFinder
4
4
  class Maven < PackageManager
5
5
  def current_packages
6
- `mvn license:download-licenses`
6
+ command = 'mvn license:download-licenses'
7
+ output, success = Dir.chdir(project_path) { capture(command) }
8
+ raise "Command '#{command}' failed to execute: #{output}" unless success
7
9
 
8
10
  xml = license_report.read
9
11
 
@@ -0,0 +1,43 @@
1
+ module LicenseFinder
2
+ class MergedPackage
3
+
4
+ attr_reader :dependency
5
+
6
+ def initialize(dependency, subproject_paths)
7
+ @dependency = dependency
8
+ @subproject_paths = subproject_paths.map { |p| Pathname(p) }
9
+ end
10
+
11
+ def name
12
+ dependency.name
13
+ end
14
+
15
+ def version
16
+ dependency.version
17
+ end
18
+
19
+ def licenses
20
+ dependency.licenses
21
+ end
22
+
23
+ def subproject_paths
24
+ @subproject_paths.map { |p| p.expand_path.to_s }
25
+ end
26
+
27
+ def <=>(other)
28
+ dependency <=> other.dependency
29
+ end
30
+
31
+ def eql?(other)
32
+ dependency.eql?(other.dependency)
33
+ end
34
+
35
+ def hash
36
+ dependency.hash
37
+ end
38
+
39
+ def method_missing(method_name)
40
+ nil
41
+ end
42
+ end
43
+ end
@@ -5,22 +5,46 @@ module LicenseFinder
5
5
  DEPENDENCY_GROUPS = ["dependencies", "devDependencies"]
6
6
 
7
7
  def current_packages
8
- json = npm_json
9
- dependencies = DEPENDENCY_GROUPS
10
- .map { |g| (json[g] || {}).values }
11
- .flatten(1)
12
- .reject{ |d| d.is_a?(String) }
13
-
14
- pkgs = {} # name => spec
15
- dependencies.each { |d| recursive_dependencies(d, pkgs) }
16
- pkgs.values.map { |d| NpmPackage.new(d, logger: logger) }
8
+ packages = {}
9
+ direct_dependencies.each do |dep|
10
+ group_name = dep[:group]
11
+ walk_dependency_tree(dep[:name]) do |dependency|
12
+ package_id = dependency["name"]
13
+ packages[package_id] ||= NpmPackage.new(dependency, logger: logger)
14
+ packages[package_id].groups << group_name unless packages[package_id].groups.include?(group_name)
15
+ end
16
+ end
17
+ packages.values
17
18
  end
18
19
 
19
20
  private
20
21
 
22
+ def direct_dependencies
23
+ package_json = JSON.parse(File.read(package_path))
24
+ DEPENDENCY_GROUPS.map do |group|
25
+ package_json.fetch(group, {}).keys.map do |dependency|
26
+ {
27
+ group: group,
28
+ name: dependency
29
+ }
30
+ end
31
+ end.flatten
32
+ end
33
+
34
+ def walk_dependency_tree(dependency, &block)
35
+ @json ||= npm_json
36
+ deps = @json.fetch("dependencies", {}).reject { |_,d| d.is_a?(String) }
37
+ current_dep = deps[dependency]
38
+ block.call(current_dep) if current_dep
39
+ recursive_dependencies(current_dep) do |d|
40
+ block.call(d)
41
+ end
42
+ end
43
+
21
44
  def npm_json
22
- command = "npm list --json --long"
23
- output, success = capture(command)
45
+ command = 'npm list --json --long'
46
+ output, success = Dir.chdir(project_path) { capture(command) }
47
+
24
48
  if success
25
49
  json = JSON(output)
26
50
  else
@@ -30,32 +54,26 @@ module LicenseFinder
30
54
  nil
31
55
  end
32
56
  if json
33
- $stderr.puts "Command #{command} returned error but parsing succeeded."
57
+ $stderr.puts "Command '#{command}' returned an error but parsing succeeded."
34
58
  else
35
- raise "Command #{command} failed to execute: #{output}"
59
+ raise "Command '#{command}' failed to execute: #{output}"
36
60
  end
37
61
  end
38
- json
39
- end
40
62
 
41
- def capture(command)
42
- [`#{command}`, $?.success?]
63
+ json
43
64
  end
44
65
 
45
66
  def package_path
46
67
  project_path.join('package.json')
47
68
  end
48
69
 
49
- # node_module can be empty hash if it is included elsewhere
50
- def recursive_dependencies(node_module, memo)
51
- key = node_module['name']
52
- memo[key] ||= {}
53
- memo[key].merge!(node_module)
70
+ def recursive_dependencies(node_module, &block)
71
+ return unless node_module # node_module can be empty hash if it is included elsewhere
72
+ block.call(node_module)
54
73
  node_module.fetch('dependencies', {}).each do |dep_key, data|
55
74
  data['name'] ||= dep_key
56
- recursive_dependencies(data, memo)
75
+ recursive_dependencies(data, &block)
57
76
  end
58
- memo
59
77
  end
60
78
  end
61
79
  end
@@ -0,0 +1,50 @@
1
+ require "rexml/document"
2
+
3
+ module LicenseFinder
4
+ class Nuget < PackageManager
5
+ def package_path
6
+ project_path.join('packages')
7
+ end
8
+
9
+ def assemblies
10
+ Dir[project_path.join("**", "packages.config")].map do |d|
11
+ path = Pathname.new(d).dirname
12
+ name = path.basename.to_s
13
+ Assembly.new path, name
14
+ end
15
+ end
16
+
17
+ def current_packages
18
+ dependencies.reduce({}) do |memo, dep|
19
+ memo[dep.name] ||= NugetPackage.new(dep.name, dep.version)
20
+ memo[dep.name].groups << dep.assembly if !memo[dep.name].groups.include? dep.assembly
21
+ memo
22
+ end.values
23
+ end
24
+
25
+ def dependencies
26
+ assemblies.flat_map(&:dependencies)
27
+ end
28
+
29
+ class Assembly
30
+ attr_reader :name, :path
31
+ def initialize(path, name)
32
+ @path = path
33
+ @name = name
34
+ end
35
+
36
+ def dependencies
37
+ xml = REXML::Document.new(File.read(path.join("packages.config")))
38
+ packages = REXML::XPath.match(xml, "//package")
39
+ packages.map do |p|
40
+ attrs = p.attributes
41
+ Dependency.new(attrs["id"], attrs["version"], self.name)
42
+ end
43
+ end
44
+ end
45
+
46
+ class Dependency < Struct.new(:name, :version, :assembly)
47
+ end
48
+ end
49
+ end
50
+
@@ -0,0 +1,4 @@
1
+ module LicenseFinder
2
+ class NugetPackage < Package
3
+ end
4
+ end
@@ -19,6 +19,7 @@ module LicenseFinder
19
19
  name,
20
20
  version,
21
21
  options.merge(
22
+ authors: spec["author"],
22
23
  summary: spec["summary"],
23
24
  description: spec["description"],
24
25
  homepage: spec["home_page"],
@@ -22,8 +22,8 @@ module LicenseFinder
22
22
 
23
23
  def rebar_ouput
24
24
  command = "#{@command} list-deps"
25
- output, success = capture(command)
26
- raise "Command #{command} failed to execute: #{output}" unless success
25
+ output, success = Dir.chdir(project_path) { capture(command) }
26
+ raise "Command '#{command}' failed to execute: #{output}" unless success
27
27
 
28
28
  output
29
29
  .each_line
@@ -31,10 +31,6 @@ module LicenseFinder
31
31
  .map { |line| line.split(" ") }
32
32
  end
33
33
 
34
- def capture(command)
35
- [`#{command}`, $?.success?]
36
- end
37
-
38
34
  def package_path
39
35
  project_path.join('rebar.config')
40
36
  end
@@ -3,6 +3,9 @@ module LicenseFinder
3
3
  def self.darwin?
4
4
  RUBY_PLATFORM =~ /darwin/
5
5
  end
6
+
7
+ def self.windows?
8
+ RUBY_PLATFORM =~ /mswin|cygwin|mingw/
9
+ end
6
10
  end
7
11
  end
8
-
@@ -0,0 +1,56 @@
1
+ module LicenseFinder
2
+ class ProjectFinder
3
+ def initialize(main_project_path)
4
+ @package_managers = LicenseFinder::PackageManager.package_managers
5
+ @main_project_path = main_project_path
6
+ end
7
+
8
+ def find_projects
9
+ project_paths = []
10
+ all_paths = find_all_paths
11
+ until all_paths.empty?
12
+ project_paths << collect_project_path(all_paths)
13
+ all_paths.shift
14
+ end
15
+ project_paths.compact
16
+ end
17
+
18
+ def collect_project_path(all_paths)
19
+ potential_project_path = all_paths.first
20
+ if active_project?(potential_project_path)
21
+ remove_nested(potential_project_path, all_paths)
22
+ return potential_project_path.to_s
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def find_all_paths
29
+ Dir.glob("#{@main_project_path}/**/").map { |path| full_path(path) }
30
+ end
31
+
32
+ def remove_nested(pathname, paths)
33
+ return if project_root?(pathname)
34
+ paths.reject! { |path| nested_path?(path, pathname) }
35
+ end
36
+
37
+ def project_root?(pathname)
38
+ full_path(@main_project_path).to_s == pathname.to_s
39
+ end
40
+
41
+ def active_project?(project_path)
42
+ active_project = @package_managers.map do |pm|
43
+ pm.new(project_path: project_path).active?
44
+ end
45
+ active_project.include?(true)
46
+ end
47
+
48
+ def full_path(rel_path)
49
+ Pathname.new(rel_path).expand_path
50
+ end
51
+
52
+ def nested_path?(path, pathname)
53
+ (path.to_s).start_with?(pathname.to_s) && path.to_s != pathname.to_s
54
+ end
55
+ end
56
+ end
@@ -13,14 +13,15 @@ module LicenseFinder
13
13
  attr_reader :dependencies, :project_name
14
14
 
15
15
  def sorted_dependencies
16
- dependencies.sort_by(&:name)
16
+ dependencies.sort
17
17
  end
18
18
  end
19
19
  end
20
20
 
21
21
  require 'license_finder/reports/erb_report'
22
-
23
22
  require 'license_finder/reports/csv_report'
24
23
  require 'license_finder/reports/text_report'
24
+ require 'license_finder/reports/diff_report'
25
+ require 'license_finder/reports/merged_report'
25
26
  require 'license_finder/reports/html_report'
26
27
  require 'license_finder/reports/markdown_report'
@@ -3,12 +3,12 @@ require 'csv'
3
3
  module LicenseFinder
4
4
  class CsvReport < Report
5
5
  COMMA_SEP = ","
6
- AVAILABLE_COLUMNS = %w[name version licenses approved summary description homepage]
6
+ AVAILABLE_COLUMNS = %w[name version authors licenses approved summary description homepage]
7
7
  MISSING_DEPENDENCY_TEXT = "This package is not installed. Please install to determine licenses."
8
8
 
9
9
  def initialize(dependencies, options)
10
10
  super
11
- @columns = Array(options[:columns]) & AVAILABLE_COLUMNS
11
+ @columns = Array(options[:columns]) & self.class::AVAILABLE_COLUMNS
12
12
  end
13
13
 
14
14
  def to_s
@@ -35,6 +35,10 @@ module LicenseFinder
35
35
  dep.version
36
36
  end
37
37
 
38
+ def format_authors(dep)
39
+ dep.authors.to_s.strip
40
+ end
41
+
38
42
  def format_homepage(dep)
39
43
  dep.homepage
40
44
  end
@@ -0,0 +1,33 @@
1
+ module LicenseFinder
2
+ class DiffReport < CsvReport
3
+ AVAILABLE_COLUMNS = AVAILABLE_COLUMNS + %w[status current_version previous_version project_paths]
4
+
5
+ def initialize(dependencies, options={})
6
+ super(dependencies, options.merge(columns: build_columns(dependencies)))
7
+ end
8
+
9
+ def format_status(dep)
10
+ dep.status
11
+ end
12
+
13
+ def format_current_version(dep)
14
+ dep.current_version
15
+ end
16
+
17
+ def format_previous_version(dep)
18
+ dep.previous_version
19
+ end
20
+
21
+ def format_project_paths(dep)
22
+ dep.subproject_paths.join(self.class::COMMA_SEP)
23
+ end
24
+
25
+ private
26
+
27
+ def build_columns(dependencies)
28
+ columns = %w[status name current_version previous_version licenses]
29
+ columns << 'project_paths' if dependencies.all? { |delta| delta.merged_package? }
30
+ columns
31
+ end
32
+ end
33
+ end