licensed 3.1.0 → 3.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +19 -0
  3. data/.github/workflows/release.yml +4 -4
  4. data/.github/workflows/test.yml +169 -48
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +51 -1
  7. data/README.md +25 -80
  8. data/docker/Dockerfile.build-linux +1 -1
  9. data/docs/adding_a_new_source.md +11 -8
  10. data/docs/commands/README.md +59 -0
  11. data/docs/commands/cache.md +35 -0
  12. data/docs/commands/env.md +10 -0
  13. data/docs/commands/list.md +23 -0
  14. data/docs/commands/migrate.md +10 -0
  15. data/docs/commands/notices.md +12 -0
  16. data/docs/commands/status.md +74 -0
  17. data/docs/commands/version.md +3 -0
  18. data/docs/configuration/README.md +11 -0
  19. data/docs/configuration/allowed_licenses.md +17 -0
  20. data/docs/configuration/application_name.md +63 -0
  21. data/docs/configuration/application_source.md +64 -0
  22. data/docs/configuration/configuration_root.md +27 -0
  23. data/docs/configuration/configuring_multiple_apps.md +58 -0
  24. data/docs/configuration/dependency_source_enumerators.md +28 -0
  25. data/docs/configuration/ignoring_dependencies.md +19 -0
  26. data/docs/configuration/metadata_cache.md +106 -0
  27. data/docs/configuration/reviewing_dependencies.md +18 -0
  28. data/docs/configuration.md +9 -173
  29. data/lib/licensed/cli.rb +2 -2
  30. data/lib/licensed/commands/cache.rb +21 -20
  31. data/lib/licensed/commands/command.rb +108 -73
  32. data/lib/licensed/commands/environment.rb +12 -11
  33. data/lib/licensed/commands/list.rb +0 -19
  34. data/lib/licensed/commands/notices.rb +0 -19
  35. data/lib/licensed/commands/status.rb +13 -15
  36. data/lib/licensed/configuration.rb +77 -7
  37. data/lib/licensed/report.rb +44 -0
  38. data/lib/licensed/reporters/cache_reporter.rb +48 -64
  39. data/lib/licensed/reporters/json_reporter.rb +19 -21
  40. data/lib/licensed/reporters/list_reporter.rb +45 -58
  41. data/lib/licensed/reporters/notices_reporter.rb +33 -46
  42. data/lib/licensed/reporters/reporter.rb +37 -104
  43. data/lib/licensed/reporters/status_reporter.rb +58 -56
  44. data/lib/licensed/reporters/yaml_reporter.rb +19 -21
  45. data/lib/licensed/sources/bundler/definition.rb +36 -0
  46. data/lib/licensed/sources/bundler/missing_specification.rb +10 -7
  47. data/lib/licensed/sources/bundler.rb +34 -70
  48. data/lib/licensed/sources/dep.rb +2 -2
  49. data/lib/licensed/sources/go.rb +3 -3
  50. data/lib/licensed/sources/gradle.rb +2 -2
  51. data/lib/licensed/sources/helpers/content_versioning.rb +2 -1
  52. data/lib/licensed/sources/npm.rb +4 -3
  53. data/lib/licensed/sources/nuget.rb +1 -2
  54. data/lib/licensed/version.rb +1 -1
  55. data/lib/licensed.rb +1 -0
  56. data/licensed.gemspec +4 -4
  57. data/script/source-setup/go +1 -1
  58. metadata +45 -13
  59. data/docs/commands.md +0 -95
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Licensed
4
+ module Bundler
5
+ module DefinitionExtensions
6
+ attr_accessor :force_exclude_groups
7
+
8
+ # Override specs to avoid logic that would raise Gem::NotFound
9
+ # which is handled in this ./missing_specification.rb, and to not add
10
+ # bundler as a dependency if it's not a user-requested gem.
11
+ #
12
+ # Newer versions of Bundler have changed the implementation of specs_for
13
+ # as well which no longer calls this function. Overriding this function
14
+ # gives a stable access point for licensed
15
+ def specs
16
+ @specs ||= begin
17
+ specs = resolve.materialize(requested_dependencies)
18
+
19
+ all_dependencies = requested_dependencies.concat(specs.flat_map(&:dependencies))
20
+ if all_dependencies.any? { |d| d.name == "bundler" } && !specs["bundler"].any?
21
+ bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", ::Bundler::VERSION)).last
22
+ specs["bundler"] = bundler
23
+ end
24
+
25
+ specs
26
+ end
27
+ end
28
+
29
+ # Override requested_groups to also exclude any groups that are
30
+ # in the "bundler.without" section of the licensed configuration file.
31
+ def requested_groups
32
+ super - Array(force_exclude_groups)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -38,17 +38,20 @@ module Licensed
38
38
  "could not find #{name} (#{version}) in any sources"
39
39
  end
40
40
  end
41
+
42
+ module LazySpecification
43
+ def __materialize__
44
+ spec = super
45
+ return spec if spec
46
+
47
+ Licensed::Bundler::MissingSpecification.new(name: name, version: version, platform: platform, source: source)
48
+ end
49
+ end
41
50
  end
42
51
  end
43
52
 
44
53
  module Bundler
45
54
  class LazySpecification
46
- alias_method :orig_materialize, :__materialize__
47
- def __materialize__
48
- spec = orig_materialize
49
- return spec if spec
50
-
51
- Licensed::Bundler::MissingSpecification.new(name: name, version: version, platform: platform, source: source)
52
- end
55
+ prepend ::Licensed::Bundler::LazySpecification
53
56
  end
54
57
  end
@@ -3,6 +3,7 @@ require "delegate"
3
3
  begin
4
4
  require "bundler"
5
5
  require "licensed/sources/bundler/missing_specification"
6
+ require "licensed/sources/bundler/definition"
6
7
  rescue LoadError
7
8
  end
8
9
 
@@ -29,7 +30,7 @@ module Licensed
29
30
  # `loaded_from` if available.
30
31
  def spec_file
31
32
  return @spec_file if defined?(@spec_file)
32
- return @spec_file = nil unless loaded_from && File.exist?(loaded_from)
33
+ return @spec_file = nil unless loaded_from && File.file?(loaded_from)
33
34
  @spec_file = begin
34
35
  file = { name: File.basename(loaded_from), dir: File.dirname(loaded_from) }
35
36
  Licensee::ProjectFiles::PackageManagerFile.new(File.read(loaded_from), file)
@@ -37,7 +38,6 @@ module Licensed
37
38
  end
38
39
  end
39
40
 
40
- GEMFILES = { "Gemfile" => "Gemfile.lock", "gems.rb" => "gems.locked" }
41
41
  DEFAULT_WITHOUT_GROUPS = %i{development test}
42
42
  RUBY_PACKER_ERROR = "The bundler source cannot be used from the executable built with ruby-packer. Please install licensed using `gem install` or using bundler."
43
43
 
@@ -45,15 +45,20 @@ module Licensed
45
45
  # running a ruby-packer-built licensed exe when ruby isn't available
46
46
  # could lead to errors if the host ruby doesn't exist
47
47
  return false if ruby_packer? && !Licensed::Shell.tool_available?("ruby")
48
- defined?(::Bundler) && lockfile_path && lockfile_path.exist?
48
+
49
+ # if Bundler isn't loaded, this enumerator won't work!
50
+ return false unless defined?(::Bundler)
51
+
52
+ with_application_environment { ::Bundler.default_lockfile&.exist? }
53
+ rescue ::Bundler::GemfileNotFound
54
+ false
49
55
  end
50
56
 
51
57
  def enumerate_dependencies
52
58
  raise Licensed::Sources::Source::Error.new(RUBY_PACKER_ERROR) if ruby_packer?
53
59
 
54
- with_local_configuration do
55
- specs.map do |spec|
56
- next if spec.name == "bundler" && !include_bundler?
60
+ with_application_environment do
61
+ definition.specs.map do |spec|
57
62
  next if spec.name == config["name"]
58
63
 
59
64
  error = spec.error if spec.respond_to?(:error)
@@ -73,41 +78,13 @@ module Licensed
73
78
  end
74
79
  end
75
80
 
76
- # Returns an array of Gem::Specifications for all gem dependencies
77
- def specs
78
- @specs ||= definition.specs_for(groups)
79
- end
80
-
81
- # Returns whether to include bundler as a listed dependency of the project
82
- def include_bundler?
83
- @include_bundler ||= begin
84
- # include if bundler is listed as a direct dependency that should be included
85
- requested_dependencies = definition.dependencies.select { |d| (d.groups & groups).any? && d.should_include? }
86
- return true if requested_dependencies.any? { |d| d.name == "bundler" }
87
- # include if bundler is an indirect dependency
88
- return true if specs.flat_map(&:dependencies).any? { |d| d.name == "bundler" }
89
- false
90
- end
91
- end
92
-
93
- # Build the bundler definition
94
81
  def definition
95
- @definition ||= ::Bundler::Definition.build(gemfile_path, lockfile_path, nil)
96
- end
97
-
98
- # Returns the bundle definition groups, removing "without" groups,
99
- # and including "with" groups
100
- def groups
101
- @groups ||= definition.groups - bundler_setting_array(:without) + bundler_setting_array(:with) - exclude_groups
102
- end
103
-
104
- # Returns a bundler setting as an array.
105
- # Depending on the version of bundler, array values are either returned as
106
- # a raw string ("a:b:c") or as an array ([:a, :b, :c])
107
- def bundler_setting_array(key)
108
- setting = ::Bundler.settings[key]
109
- setting = setting.split(":").map(&:to_sym) if setting.is_a?(String)
110
- Array(setting)
82
+ @definition ||= begin
83
+ definition = ::Bundler::Definition.build(::Bundler.default_gemfile, ::Bundler.default_lockfile, nil)
84
+ definition.extend Licensed::Bundler::DefinitionExtensions
85
+ definition.force_exclude_groups = exclude_groups
86
+ definition
87
+ end
111
88
  end
112
89
 
113
90
  # Returns any groups to exclude specified from both licensed configuration
@@ -121,46 +98,33 @@ module Licensed
121
98
  end
122
99
  end
123
100
 
124
- # Returns the path to the Bundler Gemfile
125
- def gemfile_path
126
- @gemfile_path ||= GEMFILES.keys
127
- .map { |g| config.pwd.join g }
128
- .find { |f| f.exist? }
129
- end
101
+ # helper to clear all bundler environment around a yielded block
102
+ def with_application_environment
103
+ backup = nil
130
104
 
131
- # Returns the path to the Bundler Gemfile.lock
132
- def lockfile_path
133
- return unless gemfile_path
134
- @lockfile_path ||= gemfile_path.dirname.join(GEMFILES[gemfile_path.basename.to_s])
135
- end
105
+ ::Bundler.ui.silence do
106
+ if ::Bundler.root != config.source_path
107
+ backup = ENV.to_hash
108
+ ENV.replace(::Bundler.original_env)
136
109
 
137
- # helper to clear all bundler environment around a yielded block
138
- def with_local_configuration
139
- # silence any bundler warnings while running licensed
140
- bundler_ui, ::Bundler.ui = ::Bundler.ui, ::Bundler::UI::Silent.new
110
+ # reset bundler to load from the current app's source path
111
+ ::Bundler.reset!
112
+ end
141
113
 
142
- original_bundle_gemfile = nil
143
- if gemfile_path.to_s != ENV["BUNDLE_GEMFILE"]
144
- # force bundler to use the local gem file
145
- original_bundle_gemfile, ENV["BUNDLE_GEMFILE"] = ENV["BUNDLE_GEMFILE"], gemfile_path.to_s
114
+ # ensure the bundler environment is loaded before enumeration
115
+ ::Bundler.load
146
116
 
147
- # reset all bundler configuration
148
- ::Bundler.reset!
149
- # and re-configure with settings for current directory
150
- ::Bundler.configure
117
+ yield
151
118
  end
152
-
153
- yield
154
119
  ensure
155
- if original_bundle_gemfile
156
- ENV["BUNDLE_GEMFILE"] = original_bundle_gemfile
157
-
120
+ if backup
158
121
  # restore bundler configuration
122
+ ENV.replace(backup)
159
123
  ::Bundler.reset!
160
- ::Bundler.configure
161
124
  end
162
125
 
163
- ::Bundler.ui = bundler_ui
126
+ # reload the bundler environment after enumeration
127
+ ::Bundler.load
164
128
  end
165
129
 
166
130
  # Returns whether the current licensed execution is running ruby-packer
@@ -40,10 +40,10 @@ module Licensed
40
40
  end
41
41
  end
42
42
 
43
- # Returns the godoc.org page for a package.
43
+ # Returns the pkg.go.dev page for a package.
44
44
  def homepage(import_path)
45
45
  return unless import_path
46
- "https://godoc.org/#{import_path}"
46
+ "https://pkg.go.dev/#{import_path}"
47
47
  end
48
48
 
49
49
  # Returns whether the package is part of the go std list. Replaces
@@ -98,7 +98,7 @@ module Licensed
98
98
  # Returns whether the package is local to the current project
99
99
  def local_package?(package)
100
100
  return false unless package && package["Dir"]
101
- return false unless File.fnmatch?("#{config.root.to_s}*", package["Dir"], File::FNM_CASEFOLD)
101
+ return false unless File.fnmatch?("#{config.root}*", package["Dir"], File::FNM_CASEFOLD)
102
102
  vendored_path_parts(package).nil?
103
103
  end
104
104
 
@@ -132,10 +132,10 @@ module Licensed
132
132
  end
133
133
  end
134
134
 
135
- # Returns the godoc.org page for a package.
135
+ # Returns the pkg.go.dev page for a package.
136
136
  def homepage(import_path)
137
137
  return unless import_path
138
- "https://godoc.org/#{import_path}"
138
+ "https://pkg.go.dev/#{import_path}"
139
139
  end
140
140
 
141
141
  # Returns the root directory to search for a package license
@@ -125,10 +125,10 @@ module Licensed
125
125
  def self.add_gradle_license_report_plugins_block(gradle_build_file)
126
126
 
127
127
  if gradle_build_file.include? "plugins"
128
- gradle_build_file.gsub(/(?<=plugins)\s+{/, " { id 'com.github.jk1.dependency-license-report' version '1.6'")
128
+ gradle_build_file.gsub(/(?<=plugins)\s+{/, " { id 'com.github.jk1.dependency-license-report' version '1.16'")
129
129
  else
130
130
 
131
- gradle_build_file = " plugins { id 'com.github.jk1.dependency-license-report' version '1.6' }" + gradle_build_file
131
+ gradle_build_file = " plugins { id 'com.github.jk1.dependency-license-report' version '1.16' }" + gradle_build_file
132
132
  end
133
133
  end
134
134
 
@@ -61,11 +61,12 @@ module Licensed
61
61
 
62
62
  paths = paths.compact.select { |path| File.file?(path) }
63
63
  return if paths.empty?
64
-
64
+ # rubocop:disable GitHub/InsecureHashAlgorithm
65
65
  paths.sort
66
66
  .reduce(Digest::XXHash64.new, :file)
67
67
  .digest
68
68
  .to_s(16) # convert to hex
69
+ # rubocop:enable GitHub/InsecureHashAlgorithm
69
70
  end
70
71
  end
71
72
  end
@@ -33,11 +33,12 @@ module Licensed
33
33
 
34
34
  def enumerate_dependencies
35
35
  packages.map do |name, package|
36
- path = package["path"]
36
+ errors = package["problems"] unless package["path"]
37
37
  Dependency.new(
38
38
  name: name,
39
- version: package["version"],
40
- path: path,
39
+ version: package["version"] || package["required"],
40
+ path: package["path"],
41
+ errors: Array(errors),
41
42
  metadata: {
42
43
  "type" => NPM.type,
43
44
  "name" => package["name"],
@@ -234,8 +234,7 @@ module Licensed
234
234
  ].compact
235
235
 
236
236
  nuget_package_dirs.map { |dir| File.join(dir, dependency_path) }
237
- .select { |path| File.directory?(path) }
238
- .first
237
+ .find { |path| File.directory?(path) }
239
238
  end
240
239
  end
241
240
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Licensed
3
- VERSION = "3.1.0".freeze
3
+ VERSION = "3.2.3".freeze
4
4
 
5
5
  def self.previous_major_versions
6
6
  major_version = Gem::Version.new(Licensed::VERSION).segments.first
data/lib/licensed.rb CHANGED
@@ -6,6 +6,7 @@ require "licensed/dependency"
6
6
  require "licensed/git"
7
7
  require "licensed/sources"
8
8
  require "licensed/configuration"
9
+ require "licensed/report"
9
10
  require "licensed/reporters"
10
11
  require "licensed/commands"
11
12
  require "licensed/ui/shell"
data/licensed.gemspec CHANGED
@@ -26,16 +26,16 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency "licensee", ">= 9.14.0", "< 10.0.0"
27
27
  spec.add_dependency "thor", ">= 0.19"
28
28
  spec.add_dependency "pathname-common_prefix", "~> 0.0.1"
29
- spec.add_dependency "tomlrb", "~> 1.2"
29
+ spec.add_dependency "tomlrb", ">= 1.2", "< 3.0"
30
30
  spec.add_dependency "bundler", ">= 1.10"
31
31
  spec.add_dependency "ruby-xxHash", "~> 0.4"
32
32
  spec.add_dependency "parallel", ">= 0.18.0"
33
- spec.add_dependency "reverse_markdown", "~> 1.0"
33
+ spec.add_dependency "reverse_markdown", ">= 1", "< 3"
34
34
 
35
35
  spec.add_development_dependency "rake", ">= 12.3.3"
36
36
  spec.add_development_dependency "minitest", "~> 5.8"
37
37
  spec.add_development_dependency "mocha", "~> 1.0"
38
- spec.add_development_dependency "rubocop", "~> 0.49", "< 0.67"
38
+ spec.add_development_dependency "rubocop", "~> 0.49", "< 1.20"
39
39
  spec.add_development_dependency "rubocop-github", "~> 0.6"
40
- spec.add_development_dependency "byebug", "~> 10.0.0"
40
+ spec.add_development_dependency "byebug", "~> 11.0.1"
41
41
  end
@@ -25,7 +25,7 @@ if [ "$1" == "-f" ]; then
25
25
  fi
26
26
  fi
27
27
 
28
- (cd src/test && go get)
28
+ (export GO111MODULE=off && cd src/test && go get)
29
29
  if go help mod >/dev/null; then
30
30
  (cd src/modules_test && GO111MODULE=on go mod download)
31
31
  fi
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: licensed
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-06-16 00:00:00.000000000 Z
11
+ date: 2021-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: licensee
@@ -62,16 +62,22 @@ dependencies:
62
62
  name: tomlrb
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - "~>"
65
+ - - ">="
66
66
  - !ruby/object:Gem::Version
67
67
  version: '1.2'
68
+ - - "<"
69
+ - !ruby/object:Gem::Version
70
+ version: '3.0'
68
71
  type: :runtime
69
72
  prerelease: false
70
73
  version_requirements: !ruby/object:Gem::Requirement
71
74
  requirements:
72
- - - "~>"
75
+ - - ">="
73
76
  - !ruby/object:Gem::Version
74
77
  version: '1.2'
78
+ - - "<"
79
+ - !ruby/object:Gem::Version
80
+ version: '3.0'
75
81
  - !ruby/object:Gem::Dependency
76
82
  name: bundler
77
83
  requirement: !ruby/object:Gem::Requirement
@@ -118,16 +124,22 @@ dependencies:
118
124
  name: reverse_markdown
119
125
  requirement: !ruby/object:Gem::Requirement
120
126
  requirements:
121
- - - "~>"
127
+ - - ">="
122
128
  - !ruby/object:Gem::Version
123
- version: '1.0'
129
+ version: '1'
130
+ - - "<"
131
+ - !ruby/object:Gem::Version
132
+ version: '3'
124
133
  type: :runtime
125
134
  prerelease: false
126
135
  version_requirements: !ruby/object:Gem::Requirement
127
136
  requirements:
128
- - - "~>"
137
+ - - ">="
129
138
  - !ruby/object:Gem::Version
130
- version: '1.0'
139
+ version: '1'
140
+ - - "<"
141
+ - !ruby/object:Gem::Version
142
+ version: '3'
131
143
  - !ruby/object:Gem::Dependency
132
144
  name: rake
133
145
  requirement: !ruby/object:Gem::Requirement
@@ -179,7 +191,7 @@ dependencies:
179
191
  version: '0.49'
180
192
  - - "<"
181
193
  - !ruby/object:Gem::Version
182
- version: '0.67'
194
+ version: '1.20'
183
195
  type: :development
184
196
  prerelease: false
185
197
  version_requirements: !ruby/object:Gem::Requirement
@@ -189,7 +201,7 @@ dependencies:
189
201
  version: '0.49'
190
202
  - - "<"
191
203
  - !ruby/object:Gem::Version
192
- version: '0.67'
204
+ version: '1.20'
193
205
  - !ruby/object:Gem::Dependency
194
206
  name: rubocop-github
195
207
  requirement: !ruby/object:Gem::Requirement
@@ -210,14 +222,14 @@ dependencies:
210
222
  requirements:
211
223
  - - "~>"
212
224
  - !ruby/object:Gem::Version
213
- version: 10.0.0
225
+ version: 11.0.1
214
226
  type: :development
215
227
  prerelease: false
216
228
  version_requirements: !ruby/object:Gem::Requirement
217
229
  requirements:
218
230
  - - "~>"
219
231
  - !ruby/object:Gem::Version
220
- version: 10.0.0
232
+ version: 11.0.1
221
233
  description: Licensed automates extracting and validating the licenses of dependencies.
222
234
  email:
223
235
  - opensource+licensed@github.com
@@ -226,6 +238,7 @@ executables:
226
238
  extensions: []
227
239
  extra_rdoc_files: []
228
240
  files:
241
+ - ".github/dependabot.yml"
229
242
  - ".github/workflows/release.yml"
230
243
  - ".github/workflows/test.yml"
231
244
  - ".gitignore"
@@ -241,8 +254,25 @@ files:
241
254
  - Rakefile
242
255
  - docker/Dockerfile.build-linux
243
256
  - docs/adding_a_new_source.md
244
- - docs/commands.md
257
+ - docs/commands/README.md
258
+ - docs/commands/cache.md
259
+ - docs/commands/env.md
260
+ - docs/commands/list.md
261
+ - docs/commands/migrate.md
262
+ - docs/commands/notices.md
263
+ - docs/commands/status.md
264
+ - docs/commands/version.md
245
265
  - docs/configuration.md
266
+ - docs/configuration/README.md
267
+ - docs/configuration/allowed_licenses.md
268
+ - docs/configuration/application_name.md
269
+ - docs/configuration/application_source.md
270
+ - docs/configuration/configuration_root.md
271
+ - docs/configuration/configuring_multiple_apps.md
272
+ - docs/configuration/dependency_source_enumerators.md
273
+ - docs/configuration/ignoring_dependencies.md
274
+ - docs/configuration/metadata_cache.md
275
+ - docs/configuration/reviewing_dependencies.md
246
276
  - docs/migrations/v2.md
247
277
  - docs/migrations/v3.md
248
278
  - docs/packaging.md
@@ -280,6 +310,7 @@ files:
280
310
  - lib/licensed/git.rb
281
311
  - lib/licensed/migrations.rb
282
312
  - lib/licensed/migrations/v2.rb
313
+ - lib/licensed/report.rb
283
314
  - lib/licensed/reporters.rb
284
315
  - lib/licensed/reporters/cache_reporter.rb
285
316
  - lib/licensed/reporters/json_reporter.rb
@@ -292,6 +323,7 @@ files:
292
323
  - lib/licensed/sources.rb
293
324
  - lib/licensed/sources/bower.rb
294
325
  - lib/licensed/sources/bundler.rb
326
+ - lib/licensed/sources/bundler/definition.rb
295
327
  - lib/licensed/sources/bundler/missing_specification.rb
296
328
  - lib/licensed/sources/cabal.rb
297
329
  - lib/licensed/sources/composer.rb