licensed 2.15.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 13bec80f1d0dba11fc88692fe346f3dd1f2961ba79f21eb23d7c20e8e40df01b
4
- data.tar.gz: bd4794c594cbe624ce18d0c3483d0ad05c3d37734b11eb376778a2f48fffd81a
3
+ metadata.gz: 26f8098aaee2e88489ccdebc2a4a37a6da75bc2bb7c1179a94eb9c62bd6428ea
4
+ data.tar.gz: f2bcc523cc918a383559164e953c3453f4b456f71ce4ea6edf6ff207adeae99e
5
5
  SHA512:
6
- metadata.gz: cb096d054153724f25b5dc7871131a6eb2b1a7d86360f40654af2f1f41ec62ae829e470d49818a8e943ee8d8d5b533e6407f3dc3dffe272a29c40ca7b0a03b75
7
- data.tar.gz: a302d4ab4db6da100c861020527dedf4d1249f0edfbc31ffea9cef1137063e30cf51ca737f59cf90c100301748f14b84edfae61ee634d665f8fa008715257117
6
+ metadata.gz: 5d31ba213998214f387fb053b1038c6010bfffc42babb0dcf502062a6effced42404a09f1d22741d60ab92a9723c64c6af5a0333f1576f1970c9a5adcc89f2cf
7
+ data.tar.gz: b06150a91ba3d2b0364f1c4a8347fa55b1ebd4ecbf97524e267f613dfc9138a8ced44a308fc80d25238147d1a237cead91dc8e9ccb29cd0736195d977d0aa516
data/CHANGELOG.md CHANGED
@@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## 3.0.0
10
+
11
+ 2021-04-27
12
+
13
+ **This is a major release and includes potentially breaking changes to bundler dependency enumeration.**
14
+
15
+ ### Changed
16
+
17
+ - The bundler source will return an error when run from an executable. Please install licensed as a gem to continue using the bundler source. Please see the [v3 migration document](./docs/migrations/v3.md) for full details and migration strategies.
18
+
9
19
  ## 2.15.2
10
20
 
11
21
  2021-04-06
@@ -411,4 +421,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
411
421
 
412
422
  Initial release :tada:
413
423
 
414
- [Unreleased]: https://github.com/github/licensed/compare/2.15.2...HEAD
424
+ [Unreleased]: https://github.com/github/licensed/compare/3.0.0...HEAD
data/README.md CHANGED
@@ -12,12 +12,24 @@ Licensed is **not** a complete open source license compliance solution. Please u
12
12
 
13
13
  Licensed is in active development and currently used at GitHub. See the [open issues](https://github.com/github/licensed/issues) for a list of potential work.
14
14
 
15
+ ## Licensed v3
16
+
17
+ Licensed v3 includes a breaking change if both of the following are true:
18
+
19
+ 1. a project uses bundler to manage ruby dependencies
20
+ 2. a project uses the self-contained executable build of licensed
21
+
22
+ All other usages of licensed should not encounter any major changes migrating from the latest 2.x build to 3.0.
23
+
24
+ See [CHANGELOG.md](./CHANGELOG.md) for more details on what's changed.
25
+ See the [v3 migration documentation](./docs/migrations/v3.md) for more info on migrating to v3.
26
+
15
27
  ## Licensed v2
16
28
 
17
29
  Licensed v2 includes many internal changes intended to make licensed more extensible and easier to update in the future. While not too much has changed externally, v2 is incompatible with configuration files and cached records from previous versions. Fortunately, migrating is easy using the `licensed migrate` command.
18
30
 
19
31
  See [CHANGELOG.md](./CHANGELOG.md) for more details on what's changed.
20
- See the [migration documentation](./docs/migrating_to_newer_versions.md) for more info on migrating to v2, or run `licensed help migrate`.
32
+ See the [v2 migration documentation](./docs/migrations/v2.md) for more info on migrating to v2, or run `licensed help migrate`.
21
33
 
22
34
  ## Installation
23
35
 
@@ -82,7 +94,6 @@ The [bundler-licensed plugin](https://github.com/sergey-alekseev/bundler-license
82
94
  The [licensed-ci](https://github.com/marketplace/actions/licensed-ci) GitHub Action runs `licensed` as part of an opinionated CI workflow and can be configured to run on any GitHub Action event. See the linked actions for usage and details.
83
95
 
84
96
  The [setup-licensed](https://github.com/marketplace/actions/setup-github-licensed) GitHub Action installs `licensed` to the workflow environment. See the linked actions for usage and details.
85
- - This action is intended for projects that don't have a ruby installation setup. If your workflow has ruby setup please install `licensed` via `Gemfile` + `bundle install` or with `gem install`.
86
97
 
87
98
  ### Configuration
88
99
 
@@ -1,3 +1,3 @@
1
- # Migrating your licensed configuration and cached records to the latest version of licensed
1
+ # Migrating your licensed configuration and cached records to licensed v2
2
2
 
3
3
  Licensed v2+ ships with an additional executable, `licensed-migrator`, that can be used to update your licensed files to the format expected by the currently installed version. To run, execute `licensed migrate --from v1 -c <path to licensed configuration file>`, replacing `v1` with the major version of licensed to migrate from.
@@ -0,0 +1,109 @@
1
+ # Breaking changes to bundler dependency enumeration in v3
2
+
3
+ **NOTE** If you are migrating from a version earlier than v2, please first [migrate to v2](./v2.md) before continuing.
4
+
5
+ Licensed v3 includes a breaking change to bundler dependency enumeration when using the executable form of licensed. Bundler dependency enumeration will no longer work with the licensed executable as of 3.0.0.
6
+
7
+ **If your project does not use bundler, or if you already install the licensed gem, you are not affected by this breaking change.**
8
+
9
+ ## Migrating bundler enumeration for v3
10
+
11
+ When using licensed v3 with bundler dependencies, licensed must be installed from its [gem](https://rubygems.org/gems/licensed). This can be accomplished with `gem install`, or by adding licensed to a bundler gem file.
12
+
13
+ ### Usage in a GitHub Actions workflow
14
+
15
+ Using licensed to enumerate bundler dependencies in a GitHub Actions workflow will require ruby to be available in the actions VM environment. Ruby can be setup in an actions workflow using [ruby/setup-ruby](https://github.com/ruby/setup-ruby)(preferred) or [actions/setup-ruby](https://github.com/actions/setup-ruby)(deprecated).
16
+
17
+ If you are using licensed in a GitHub Actions workflow, [jonabc/setup-licensed](https://github.com/jonabc/setup-licensed) has been updated according to this breaking change. `setup-licensed` will install the licensed gem when ruby is available, or the licensed executable when ruby is not available. Alternatively, you can `gem install` licensed directly as an actions step.
18
+
19
+ This is an example workflow definition that runs [jonabc/licensed-ci](https://github.com/jonabc/licensed-ci)'s opinionated license compliance workflow in CI. It includes jobs that demonstrate installing licensed using
20
+ - `gem install`
21
+ - [jonabc/setup-licensed](https://github.com/jonabc/setup-licensed)
22
+ - installing when included in a bundler gem file
23
+
24
+ ```yml
25
+ name: Cache and verify dependency license metadata
26
+
27
+ on:
28
+ # run when PRs are opened, reopened or updated
29
+ pull_request:
30
+ types:
31
+ - opened
32
+ - reopened
33
+ - synchronize
34
+
35
+ # run on demand
36
+ workflow_dispatch:
37
+
38
+ jobs:
39
+ # install licensed with setup-licensed
40
+ licensed-ci-setup-licensed:
41
+ runs-on: ubuntu-latest
42
+
43
+ steps:
44
+ # checkout the repo
45
+ - uses: actions/checkout@v1
46
+
47
+ # install ruby
48
+ - uses: ruby/setup-ruby@v1
49
+ with:
50
+ ruby-version: "3.0"
51
+
52
+ # install licensed gem using setup-licensed
53
+ - uses: jonabc/setup-licensed@v1
54
+ with:
55
+ version: '3.x'
56
+
57
+ # install dependencies in CI environment
58
+ - run: bundle install
59
+
60
+ # run licensed-ci to cache any metadata changes and verify compliance
61
+ - uses: jonabc/licensed-ci@v1
62
+
63
+ # OR
64
+
65
+ # install licensed using gem install
66
+ licensed-ci-gem:
67
+ runs-on: ubuntu-latest
68
+
69
+ steps:
70
+ # checkout the repo
71
+ - uses: actions/checkout@v1
72
+
73
+ # install ruby and bundler
74
+ - uses: ruby/setup-ruby@v1
75
+ with:
76
+ ruby-version: "3.0"
77
+
78
+ # install licensed gem using setup-licensed
79
+ - run: gem install licensed -v '~> 3.0'
80
+
81
+ # install dependencies in CI environment
82
+ - run: bundle install
83
+
84
+ # run licensed-ci to cache any metadata changes and verify compliance
85
+ - uses: jonabc/licensed-ci@v1
86
+
87
+ # OR
88
+
89
+ # install licensed as part of bundle installation
90
+ licensed-ci-bundle:
91
+ runs-on: ubuntu-latest
92
+
93
+ steps:
94
+ # checkout the repo
95
+ - uses: actions/checkout@v1
96
+
97
+ # install ruby and bundler
98
+ - uses: ruby/setup-ruby@v1
99
+ with:
100
+ ruby-version: "3.0"
101
+
102
+ # install licensed and other dependencies in CI environment
103
+ - run: bundle install
104
+
105
+ # run licensed-ci to cache any metadata changes and verify compliance
106
+ - uses: jonabc/licensed-ci@v1
107
+ with:
108
+ command: 'bundle exec licensed' # run licensed within the bundler context
109
+ ```
@@ -2,17 +2,7 @@
2
2
 
3
3
  The bundler source will detect dependencies `Gemfile` and `Gemfile.lock` files are found at an apps `source_path`. The source uses the `Bundler` API to enumerate dependencies from `Gemfile` and `Gemfile.lock`.
4
4
 
5
- ### Enumerating bundler dependencies when using the licensed executable
6
-
7
- **Note** this content only applies to running licensed from an executable. It does not apply when using licensed as a gem.
8
-
9
- _It is required that the ruby runtime is available when running the licensed executable._
10
-
11
- The licensed executable contains and runs a version of ruby. When using the Bundler APIs, a mismatch between the version of ruby built into the licensed executable and the version of licensed used during `bundle install` can occur. This mismatch can lead to licensed raising errors due to not finding dependencies.
12
-
13
- For example, if `bundle install` was run with ruby 2.5.0 then the bundler specification path would be `<bundle path>/ruby/2.5.0/specifications`. However, if the licensed executable contains ruby 2.4.0, then licensed will be looking for specifications at `<bundle path>/ruby/2.4.0/specifications`. That path may not exist, or it may contain invalid or stale content.
14
-
15
- To prevent confusion, licensed uses the local ruby runtime to determine the ruby version for local gems during `bundle install`. If bundler is also available, then the ruby command will be run from a `bundle exec` context.
5
+ **Note** The bundler source cannot be used when running the [packaged licensed executable](../packaging.md)
16
6
 
17
7
  ### Excluding gem groups
18
8
 
data/lib/licensed/cli.rb CHANGED
@@ -74,11 +74,14 @@ module Licensed
74
74
  method_option :from, aliases: "-f", type: :string, required: true,
75
75
  desc: "Licensed version to migrate from - #{Licensed.previous_major_versions.map { |major| "v#{major}" }.join(", ")}"
76
76
  def migrate
77
+ shell = Thor::Base.shell.new
77
78
  case options["from"]
78
79
  when "v1"
79
80
  Licensed::Migrations::V2.migrate(options["config"])
81
+ when "v2"
82
+ shell.say "No configuration or cached file migration needed."
83
+ shell.say "Please see the documentation at https://github.com/github/licensed/tree/master/docs/migrations/v3.md for details."
80
84
  else
81
- shell = Thor::Base.shell.new
82
85
  shell.say "Unrecognized option from=#{options["from"]}", :red
83
86
  CLI.command_help(shell, "migrate")
84
87
  exit 1
@@ -2,56 +2,19 @@
2
2
  require "delegate"
3
3
  begin
4
4
  require "bundler"
5
+ require "licensed/sources/bundler/missing_specification"
5
6
  rescue LoadError
6
7
  end
7
8
 
8
9
  module Licensed
9
10
  module Sources
10
11
  class Bundler < Source
11
- class MissingSpecification < Gem::BasicSpecification
12
- attr_reader :name, :requirement
13
- alias_method :version, :requirement
14
- def initialize(name:, requirement:)
15
- @name = name
16
- @requirement = requirement
17
- end
18
-
19
- def dependencies
20
- []
21
- end
22
-
23
- def source
24
- nil
25
- end
26
-
27
- def platform; end
28
- def gem_dir; end
29
- def gems_dir
30
- Gem.dir
31
- end
32
- def summary; end
33
- def homepage; end
34
-
35
- def error
36
- "could not find #{name} (#{requirement}) in any sources"
37
- end
38
- end
39
-
40
- class BundlerSpecification < ::SimpleDelegator
41
- def gem_dir
42
- dir = super
43
- return dir if File.exist?(dir)
44
-
45
- File.join(Gem.dir, "gems", full_name)
46
- end
47
- end
48
-
49
12
  class Dependency < Licensed::Dependency
50
13
  attr_reader :loaded_from
51
14
 
52
- def initialize(name:, version:, path:, loaded_from:, errors: [], metadata: {})
15
+ def initialize(name:, version:, path:, loaded_from:, search_root:, errors: [], metadata: {})
53
16
  @loaded_from = loaded_from
54
- super name: name, version: version, path: path, errors: errors, metadata: metadata
17
+ super name: name, version: version, path: path, errors: errors, metadata: metadata, search_root: search_root
55
18
  end
56
19
 
57
20
  # Load a package manager file from the base Licensee::Projects::FsProject
@@ -76,6 +39,7 @@ module Licensed
76
39
 
77
40
  GEMFILES = { "Gemfile" => "Gemfile.lock", "gems.rb" => "gems.locked" }
78
41
  DEFAULT_WITHOUT_GROUPS = %i{development test}
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."
79
43
 
80
44
  def enabled?
81
45
  # running a ruby-packer-built licensed exe when ruby isn't available
@@ -85,14 +49,20 @@ module Licensed
85
49
  end
86
50
 
87
51
  def enumerate_dependencies
52
+ raise Licensed::Sources::Source::Error.new(RUBY_PACKER_ERROR) if ruby_packer?
53
+
88
54
  with_local_configuration do
89
55
  specs.map do |spec|
56
+ next if spec.name == "bundler" && !include_bundler?
57
+ next if spec.name == config["name"]
58
+
90
59
  error = spec.error if spec.respond_to?(:error)
91
60
  Dependency.new(
92
61
  name: spec.name,
93
62
  version: spec.version.to_s,
94
63
  path: spec.gem_dir,
95
64
  loaded_from: spec.loaded_from,
65
+ search_root: spec_root(spec),
96
66
  errors: Array(error),
97
67
  metadata: {
98
68
  "type" => Bundler.type,
@@ -106,137 +76,31 @@ module Licensed
106
76
 
107
77
  # Returns an array of Gem::Specifications for all gem dependencies
108
78
  def specs
109
- # get the specifications for all dependencies in a Gemfile
110
- root_dependencies = definition.dependencies.select { |d| include?(d, nil) }
111
- root_specs = specs_for_dependencies(root_dependencies, nil).compact
112
-
113
- # recursively find the remaining specifications
114
- all_specs = recursive_specs(root_specs)
115
-
116
- # delete any specifications loaded from a gemspec
117
- all_specs.delete_if { |s| s.source.is_a?(::Bundler::Source::Gemspec) }
118
- end
119
-
120
- # Recursively finds the dependencies for Gem specifications.
121
- # Returns a `Set` containing the package names for all dependencies
122
- def recursive_specs(specs, results = Set.new)
123
- return [] if specs.nil? || specs.empty?
124
-
125
- new_specs = Set.new(specs) - results.to_a
126
- return [] if new_specs.empty?
127
-
128
- results.merge new_specs
129
-
130
- dependency_specs = new_specs.flat_map { |s| specs_for_dependencies(s.dependencies, s.source) }
131
-
132
- return results if dependency_specs.empty?
133
-
134
- results.merge recursive_specs(dependency_specs, results)
135
- end
136
-
137
- # Returns the specs for dependencies that pass the checks in `include?`.
138
- # Returns a `MissingSpecification` if a gem specification isn't found.
139
- def specs_for_dependencies(dependencies, source)
140
- included_dependencies = dependencies.select { |d| include?(d, source) }
141
- included_dependencies.map do |dep|
142
- gem_spec(dep) || MissingSpecification.new(name: dep.name, requirement: dep.requirement)
143
- end
144
- end
145
-
146
- # Returns a Gem::Specification for the provided gem argument.
147
- def gem_spec(dependency)
148
- return unless dependency
149
-
150
- # find a specifiction from the resolved ::Bundler::Definition specs
151
- spec = definition.resolve.find { |s| s.satisfies?(dependency) }
152
-
153
- # a nil spec should be rare, generally only seen from bundler
154
- return matching_spec(dependency) || bundle_exec_gem_spec(dependency.name, dependency.requirement) if spec.nil?
155
-
156
- # try to find a non-lazy specification that matches `spec`
157
- # spec.source.specs gives access to specifications with more
158
- # information than spec itself, including platform-specific gems.
159
- # these objects should have all the information needed to detect license metadata
160
- source_spec = spec.source.specs.find { |s| s.name == spec.name && s.version == spec.version }
161
- return source_spec if source_spec
162
-
163
- # look for a specification at the bundler specs path
164
- spec_path = ::Bundler.specs_path.join("#{spec.full_name}.gemspec")
165
- return Gem::Specification.load(spec_path.to_s) if File.exist?(spec_path.to_s)
166
-
167
- # if the specification file doesn't exist, get the specification using
168
- # the bundler and gem CLI
169
- bundle_exec_gem_spec(dependency.name, dependency.requirement)
79
+ @specs ||= definition.specs_for(groups)
170
80
  end
171
81
 
172
- # Returns whether a dependency should be included in the final
173
- def include?(dependency, source)
174
- # ::Bundler::Dependency has an extra `should_include?`
175
- return false unless dependency.should_include? if dependency.respond_to?(:should_include?)
176
-
177
- # Don't return gems added from `add_development_dependency` in a gemspec
178
- # if the :development group is excluded
179
- gemspec_source = source.is_a?(::Bundler::Source::Gemspec)
180
- return false if dependency.type == :development && (!gemspec_source || exclude_development_dependencies?)
181
-
182
- # Gem::Dependency don't have groups - in our usage these objects always
183
- # come as child-dependencies and are never directly from a Gemfile.
184
- # We assume that all Gem::Dependencies are ok at this point
185
- return true if dependency.groups.nil?
186
-
187
- # check if the dependency is in any groups we're interested in
188
- (dependency.groups & groups).any?
189
- end
190
-
191
- # Returns whether development dependencies should be excluded
192
- def exclude_development_dependencies?
193
- @include_development ||= begin
194
- # check whether the development dependency group is explicitly removed
195
- # or added via bundler and licensed configurations
196
- groups = [:development] - Array(::Bundler.settings[:without]) + Array(::Bundler.settings[:with]) - exclude_groups
197
- !groups.include?(:development)
82
+ # Returns whether to include bundler as a listed dependency of the project
83
+ def include_bundler?
84
+ @include_bundler ||= begin
85
+ # include if bundler is listed as a direct dependency that should be included
86
+ requested_dependencies = definition.dependencies.select { |d| (d.groups & groups).any? && d.should_include? }
87
+ return true if requested_dependencies.any? { |d| d.name == "bundler" }
88
+ # include if bundler is an indirect dependency
89
+ return true if specs.flat_map(&:dependencies).any? { |d| d.name == "bundler" }
90
+ false
198
91
  end
199
92
  end
200
93
 
201
- # Load a gem specification from the YAML returned from `gem specification`
202
- # This is a last resort when licensed can't obtain a specification from other means
203
- def bundle_exec_gem_spec(name, requirement)
204
- # `gem` must be available to run `gem specification`
205
- return unless Licensed::Shell.tool_available?("gem")
206
-
207
- # use `gem specification` with a clean ENV and clean Gem.dir paths
208
- # to get gem specification at the right directory
209
- begin
210
- ::Bundler.with_original_env do
211
- ::Bundler.rubygems.clear_paths
212
- yaml = Licensed::Shell.execute(*ruby_command_args("gem", "specification", name, "-v", requirement.to_s))
213
- spec = Gem::Specification.from_yaml(yaml)
214
- # this is horrible, but it will cache the gem_dir using the clean env
215
- # so that it can be used outside of this block when running from
216
- # the ruby packer executable environment
217
- spec.gem_dir if ruby_packer?
218
- spec
219
- end
220
- rescue Licensed::Shell::Error
221
- # return nil
222
- ensure
223
- ::Bundler.configure
224
- end
225
- end
94
+ # Returns a search root for a specification, one of:
95
+ # - the local bundler gem location
96
+ # - the system rubygems install gem location
97
+ # - nil
98
+ def spec_root(spec)
99
+ return if spec.gem_dir.nil?
100
+ root = [Gem.default_dir, Gem.dir].find { |dir| spec.gem_dir.start_with?(dir) }
101
+ return unless root
226
102
 
227
- # Loads a dependency specification using rubygems' built-in
228
- # `Dependency#matching_specs` and `Dependency#to_spec`, from the original
229
- # gem environment
230
- def matching_spec(dependency)
231
- begin
232
- ::Bundler.with_original_env do
233
- ::Bundler.rubygems.clear_paths
234
- return unless dependency.matching_specs(true).any?
235
- BundlerSpecification.new(dependency.to_spec)
236
- end
237
- ensure
238
- ::Bundler.configure
239
- end
103
+ "#{root}/gems/#{spec.full_name}"
240
104
  end
241
105
 
242
106
  # Build the bundler definition
@@ -283,23 +147,6 @@ module Licensed
283
147
  @lockfile_path ||= gemfile_path.dirname.join(GEMFILES[gemfile_path.basename.to_s])
284
148
  end
285
149
 
286
- # Returns the configured bundler executable to use, or "bundle" by default.
287
- def bundler_exe
288
- @bundler_exe ||= begin
289
- exe = config.dig("bundler", "bundler_exe")
290
- return "bundle" unless exe
291
- return exe if Licensed::Shell.tool_available?(exe)
292
- config.root.join(exe)
293
- end
294
- end
295
-
296
- # Determines if the configured bundler executable is available and returns
297
- # shell command args with or without `bundle exec` depending on availability.
298
- def ruby_command_args(*args)
299
- return Array(args) unless Licensed::Shell.tool_available?(bundler_exe)
300
- [bundler_exe, "exec", *args]
301
- end
302
-
303
150
  private
304
151
 
305
152
  # helper to clear all bundler environment around a yielded block
@@ -307,18 +154,8 @@ module Licensed
307
154
  # force bundler to use the local gem file
308
155
  original_bundle_gemfile, ENV["BUNDLE_GEMFILE"] = ENV["BUNDLE_GEMFILE"], gemfile_path.to_s
309
156
 
310
- if ruby_packer?
311
- # if running under ruby-packer, set environment from host
312
-
313
- # hack: setting this ENV var allows licensed to use Gem paths outside
314
- # of the ruby-packer filesystem. this is needed to find spec sources
315
- # from the host filesystem
316
- ENV["ENCLOSE_IO_RUBYC_1ST_PASS"] = "1"
317
- ruby_version = Gem::ConfigMap[:ruby_version]
318
- # set the ruby version in Gem::ConfigMap to the ruby version from the host.
319
- # this helps Bundler find the correct spec sources and paths
320
- Gem::ConfigMap[:ruby_version] = host_ruby_version
321
- end
157
+ # silence any bundler warnings while running licensed
158
+ bundler_ui, ::Bundler.ui = ::Bundler.ui, ::Bundler::UI::Silent.new
322
159
 
323
160
  # reset all bundler configuration
324
161
  ::Bundler.reset!
@@ -327,15 +164,10 @@ module Licensed
327
164
 
328
165
  yield
329
166
  ensure
330
- if ruby_packer?
331
- # if running under ruby-packer, restore environment after block is finished
332
- ENV.delete("ENCLOSE_IO_RUBYC_1ST_PASS")
333
- Gem::ConfigMap[:ruby_version] = ruby_version
334
- end
335
-
336
167
  ENV["BUNDLE_GEMFILE"] = original_bundle_gemfile
168
+ ::Bundler.ui = bundler_ui
169
+
337
170
  # restore bundler configuration
338
- ::Bundler.reset!
339
171
  ::Bundler.configure
340
172
  end
341
173
 
@@ -343,11 +175,6 @@ module Licensed
343
175
  def ruby_packer?
344
176
  @ruby_packer ||= RbConfig::TOPDIR =~ /__enclose_io_memfs__/
345
177
  end
346
-
347
- # Returns the ruby version found in the bundler environment
348
- def host_ruby_version
349
- Licensed::Shell.execute(*ruby_command_args("ruby", "-e", "puts Gem::ConfigMap[:ruby_version]"))
350
- end
351
178
  end
352
179
  end
353
180
  end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/match_platform"
4
+
5
+ # Bundler normally raises a "GemNotFound" error when a specification
6
+ # can't be materialized which halts bundler dependency enumeration.
7
+
8
+ # This monkey patch instead creates MissingSpecification objects to
9
+ # identify missing specs without raising errors and halting enumeration.
10
+ # It was the most minimal-touch solution I could think of that should reliably
11
+ # work across many bundler versions
12
+
13
+ module Licensed
14
+ module Bundler
15
+ class MissingSpecification < Gem::BasicSpecification
16
+ include ::Bundler::MatchPlatform
17
+
18
+ attr_reader :name, :version, :platform, :source
19
+ def initialize(name:, version:, platform:, source:)
20
+ @name = name
21
+ @version = version
22
+ @platform = platform
23
+ @source = source
24
+ end
25
+
26
+ def dependencies
27
+ []
28
+ end
29
+
30
+ def gem_dir; end
31
+ def gems_dir
32
+ Gem.dir
33
+ end
34
+ def summary; end
35
+ def homepage; end
36
+
37
+ def error
38
+ "could not find #{name} (#{version}) in any sources"
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ module Bundler
45
+ 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
53
+ end
54
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Licensed
3
- VERSION = "2.15.2".freeze
3
+ VERSION = "3.0.0".freeze
4
4
 
5
5
  def self.previous_major_versions
6
6
  major_version = Gem::Version.new(Licensed::VERSION).segments.first
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: 2.15.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-04-06 00:00:00.000000000 Z
11
+ date: 2021-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: licensee
@@ -243,7 +243,8 @@ files:
243
243
  - docs/adding_a_new_source.md
244
244
  - docs/commands.md
245
245
  - docs/configuration.md
246
- - docs/migrating_to_newer_versions.md
246
+ - docs/migrations/v2.md
247
+ - docs/migrations/v3.md
247
248
  - docs/packaging.md
248
249
  - docs/reporters.md
249
250
  - docs/sources/bower.md
@@ -290,6 +291,7 @@ files:
290
291
  - lib/licensed/sources.rb
291
292
  - lib/licensed/sources/bower.rb
292
293
  - lib/licensed/sources/bundler.rb
294
+ - lib/licensed/sources/bundler/missing_specification.rb
293
295
  - lib/licensed/sources/cabal.rb
294
296
  - lib/licensed/sources/composer.rb
295
297
  - lib/licensed/sources/dep.rb