licensed 1.4.0 → 1.5.1

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
  SHA1:
3
- metadata.gz: 5c9bec838ecfcc1a05a17a40200bd1c166197d01
4
- data.tar.gz: 87dad427c0c7b78f05015031b8be76132ccb96f4
3
+ metadata.gz: 1985113209d911393981eb8f69dfaae7f5924593
4
+ data.tar.gz: e7ba321109bae085d9345e41c599370e24547fb2
5
5
  SHA512:
6
- metadata.gz: b868455d7be394025fee42db87172e8722423750f9f938f345f253e036673a0ada06982b4c5012ce4f530d068fb6f4bdea0cf5cb43bfa07a1a28cb91f293ca9b
7
- data.tar.gz: 1810f02787fa0133f93fa7d482190da18c5579abab12b3ec2f698a0ecdf60814a3bd75335144a50b03b62a4761e011a315cd6fc1a412a6203bacf6a325e572a0
6
+ metadata.gz: a5046d1ebce6f3b386d94b8e0606e3ad1b7d93eba73bc94d37e2fa933129f649ea3efca557fe828386aedda310e40d796b32ddac9aa1f2dbaa95bc0c0ca8db1d
7
+ data.tar.gz: ec5ccf83bb05ba32038a7a45092f236be2835e1947959c3fcd8c67c8f0d25b92d1e7ff82cfe927204af3d1c5fe2c19ca1fb9afd6d680e058d4bc3530ec4fdbb4
@@ -6,6 +6,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## 1.5.1 - 2018-10-30
10
+
11
+ ### Fixed
12
+ - Fixed a scenario where licensed wasn't finding bundler dependencies when run as an executable due to a ruby version mismatch (https://github.com/github/licensed/pull/106)
13
+
14
+ ## 1.5.0 - 2018-10-24
15
+ ### Added
16
+ - `licensed (version | -v | --version)` command to see the current licensed version (:tada: @mwagz! https://github.com/github/licensed/pull/101)
17
+
18
+ ### Fixed
19
+ - NPM source no longer raises an error when ignored dependencies aren't found (:tada: @mwagz! https://github.com/github/licensed/pull/100)
20
+ - Checking for a Git repo will no longer possibly modify `.git/index` (:tada: @dbussink https://github.com/github/licensed/pull/102)
21
+ - Fixed a scenario where licensed wasn't finding bundler dependencies when run as an executable (https://github.com/github/licensed/pull/103)
22
+
9
23
  ## 1.4.0 - 2018-10-20
10
24
  ### Added
11
25
  - Git Submodules dependency source :tada:
@@ -90,4 +104,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
90
104
 
91
105
  Initial release :tada:
92
106
 
93
- [Unreleased]: https://github.com/github/licensed/compare/1.4.0...HEAD
107
+ [Unreleased]: https://github.com/github/licensed/compare/1.5.1...HEAD
data/README.md CHANGED
@@ -74,9 +74,11 @@ Warnings:
74
74
  3 dependencies checked, 3 warnings found.
75
75
  ```
76
76
 
77
+ - `licensed version`: Show current installed version of Licensed. Aliases: `-v|--version`
78
+
77
79
  ### Configuration
78
80
 
79
- All commands accept a `-c|--config` option to specify a path to a configuration file or directory.
81
+ All commands, except `version`, accept a `-c|--config` option to specify a path to a configuration file or directory.
80
82
 
81
83
  If a directory is specified, `licensed` will look in that directory for a file named (in order of preference):
82
84
  1. `.licensed.yml`
@@ -2,6 +2,18 @@
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 strongly recommended that ruby is always 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
+ If ruby is available when running licensed, licensed will determine the ruby version used during `bundle install` and prefer that version string over the version contained in the executable. If bundler is also available, then the ruby command will be run from a `bundle exec` context.
16
+
5
17
  ### Excluding gem groups
6
18
 
7
19
  The bundler source determines which gem groups to include or exclude with the following logic, in order of precedence.
@@ -15,14 +27,14 @@ The bundler source determines which gem groups to include or exclude with the fo
15
27
  Strings and string arrays are both :+1:
16
28
 
17
29
  ```yml
18
- rubygems:
30
+ rubygem:
19
31
  without: development
20
32
  ```
21
33
 
22
34
  or
23
35
 
24
36
  ```yml
25
- rubygems:
37
+ rubygem:
26
38
  without:
27
39
  - build
28
40
  - development
@@ -17,4 +17,5 @@ require "licensed/configuration"
17
17
  require "licensed/command/cache"
18
18
  require "licensed/command/status"
19
19
  require "licensed/command/list"
20
+ require "licensed/command/version"
20
21
  require "licensed/ui/shell"
@@ -30,6 +30,13 @@ module Licensed
30
30
  run Licensed::Command::List.new(config)
31
31
  end
32
32
 
33
+ map "-v" => :version
34
+ map "--version" => :version
35
+ desc "version", "Show Installed Version of Licensed, [-v, --version]"
36
+ def version
37
+ run Licensed::Command::Version.new
38
+ end
39
+
33
40
  private
34
41
 
35
42
  # Returns a configuration object for the CLI command
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ module Licensed
3
+ module Command
4
+ class Version
5
+ def initialize
6
+ @ui = Licensed::UI::Shell.new
7
+ end
8
+
9
+ def run
10
+ @ui.info(Licensed::VERSION)
11
+ end
12
+
13
+ def success?
14
+ true
15
+ end
16
+ end
17
+ end
18
+ end
@@ -11,9 +11,13 @@ module Licensed
11
11
  ].freeze
12
12
  SOURCE_TYPES = Source.constants.map { |c| Source.const_get(c) }.freeze
13
13
 
14
+ attr_reader :ui
15
+
14
16
  def initialize(options = {}, inherited_options = {})
15
17
  super()
16
18
 
19
+ @ui = Licensed::UI::Shell.new
20
+
17
21
  # update order:
18
22
  # 1. anything inherited from root config
19
23
  # 2. app defaults
@@ -120,8 +124,6 @@ module Licensed
120
124
  class Configuration < AppConfiguration
121
125
  class LoadError < StandardError; end
122
126
 
123
- attr_accessor :ui
124
-
125
127
  # Loads and returns a Licensed::Configuration object from the given path.
126
128
  # The path can be relative or absolute, and can point at a file or directory.
127
129
  # If the path given is a directory, the directory will be searched for a
@@ -133,8 +135,6 @@ module Licensed
133
135
  end
134
136
 
135
137
  def initialize(options = {})
136
- @ui = Licensed::UI::Shell.new
137
-
138
138
  apps = options.delete("apps") || []
139
139
  super(default_options.merge(options))
140
140
 
@@ -7,16 +7,16 @@ module Licensed
7
7
  @git ||= Licensed::Shell.tool_available?("git")
8
8
  end
9
9
 
10
- def git_repo?
11
- return false unless available?
12
- !Licensed::Shell.execute("git", "status", allow_failure: true).empty?
13
- end
14
-
15
10
  # Returns the root of the current git repository
16
11
  # or nil if not in a git repository.
17
12
  def repository_root
18
- return unless git_repo?
19
- Licensed::Shell.execute("git", "rev-parse", "--show-toplevel")
13
+ return unless available?
14
+ Licensed::Shell.execute("git", "rev-parse", "--show-toplevel", allow_failure: true)
15
+ end
16
+
17
+ # Returns true if a git repository is found, false otherwise
18
+ def git_repo?
19
+ !repository_root.to_s.empty?
20
20
  end
21
21
 
22
22
  # Returns the most recent git SHA for a file or directory
@@ -80,13 +80,11 @@ module Licensed
80
80
  def gem_spec(dependency)
81
81
  return unless dependency
82
82
 
83
- # bundler specifications aren't put in ::Bundler.specs_path, even if the
84
- # gem is a runtime dependency. it needs to be handled specially
85
- return bundler_spec if dependency.name == "bundler"
86
-
87
83
  # find a specifiction from the resolved ::Bundler::Definition specs
88
84
  spec = definition.resolve.find { |s| s.satisfies?(dependency) }
89
- return spec unless spec.is_a?(::Bundler::LazySpecification)
85
+
86
+ # a nil spec should be rare, generally only seen from bundler
87
+ return bundle_exec_gem_spec(dependency.name) if spec.nil?
90
88
 
91
89
  # try to find a non-lazy specification that matches `spec`
92
90
  # spec.source.specs gives access to specifications with more
@@ -97,8 +95,11 @@ module Licensed
97
95
 
98
96
  # look for a specification at the bundler specs path
99
97
  spec_path = ::Bundler.specs_path.join("#{spec.full_name}.gemspec")
100
- return unless File.exist?(spec_path.to_s)
101
- Gem::Specification.load(spec_path.to_s)
98
+ return Gem::Specification.load(spec_path.to_s) if File.exist?(spec_path.to_s)
99
+
100
+ # if the specification file doesn't exist, get the specification using
101
+ # the bundler and gem CLI
102
+ bundle_exec_gem_spec(dependency.name)
102
103
  end
103
104
 
104
105
  # Returns whether a dependency should be included in the final
@@ -130,24 +131,15 @@ module Licensed
130
131
  end
131
132
  end
132
133
 
133
- # Returns a gemspec for bundler, found and loaded by running `gem specification bundler`
134
- # This is a hack to work around bundler not placing it's own spec at
135
- # `::Bundler.specs_path` when it's an explicit dependency
136
- def bundler_spec
137
- # cache this so we run CLI commands as few times as possible
138
- return @bundler_spec if defined?(@bundler_spec)
139
-
140
- # finding the bundler gem is dependent on having `gem` available
141
- unless Licensed::Shell.tool_available?("gem")
142
- @bundler_spec = nil
143
- return
144
- end
134
+ # Load a gem specification from the YAML returned from `gem specification`
135
+ # This is a last resort when licensed can't obtain a specification from other means
136
+ def bundle_exec_gem_spec(name)
137
+ # `gem` must be available to run `gem specification`
138
+ return unless Licensed::Shell.tool_available?("gem")
145
139
 
146
- # Bundler is always used from the default gem install location.
147
- # we can use `gem specification bundler` with a clean ENV to
148
- # get the system bundler gem as YAML
149
- yaml = ::Bundler.with_original_env { Licensed::Shell.execute("gem", "specification", "bundler") }
150
- @bundler_spec = Gem::Specification.from_yaml(yaml)
140
+ # use `gem specification` with a clean ENV to get gem specification YAML
141
+ yaml = ::Bundler.with_original_env { Licensed::Shell.execute(*ruby_command_args("gem", "specification", name)) }
142
+ Gem::Specification.from_yaml(yaml)
151
143
  end
152
144
 
153
145
  # Build the bundler definition
@@ -166,8 +158,9 @@ module Licensed
166
158
  # Defaults to [:development, :test] + ::Bundler.settings[:without]
167
159
  def exclude_groups
168
160
  @exclude_groups ||= begin
169
- exclude = Array(@config.dig("rubygems", "without"))
170
- exclude.push(*DEFAULT_WITHOUT_GROUPS) if exclude.empty?
161
+ exclude = Array(@config.dig("rubygem", "without"))
162
+ exclude = Array(@config.dig("rubygems", "without")) if exclude.empty? # :sad:
163
+ exclude = DEFAULT_WITHOUT_GROUPS if exclude.empty?
171
164
  exclude.uniq.map(&:to_sym)
172
165
  end
173
166
  end
@@ -184,6 +177,23 @@ module Licensed
184
177
  @lockfile_path ||= gemfile_path.dirname.join("#{gemfile_path.basename}.lock")
185
178
  end
186
179
 
180
+ # Returns the configured bundler executable to use, or "bundle" by default.
181
+ def bundler_exe
182
+ @bundler_exe ||= begin
183
+ exe = @config.dig("rubygem", "bundler_exe")
184
+ return "bundle" unless exe
185
+ return exe if Licensed::Shell.tool_available?(exe)
186
+ @config.root.join(exe)
187
+ end
188
+ end
189
+
190
+ # Determines if the configured bundler executable is available and returns
191
+ # shell command args with or without `bundle exec` depending on availability.
192
+ def ruby_command_args(*args)
193
+ return Array(args) unless Licensed::Shell.tool_available?(bundler_exe)
194
+ [bundler_exe, "exec", *args]
195
+ end
196
+
187
197
  private
188
198
 
189
199
  # helper to clear all bundler environment around a yielded block
@@ -191,6 +201,35 @@ module Licensed
191
201
  # force bundler to use the local gem file
192
202
  original_bundle_gemfile, ENV["BUNDLE_GEMFILE"] = ENV["BUNDLE_GEMFILE"], gemfile_path.to_s
193
203
 
204
+ if ruby_packer?
205
+ # if running under ruby-packer, set environment from host
206
+
207
+ # hack: setting this ENV var allows licensed to use Gem paths outside
208
+ # of the ruby-packer filesystem. this is needed to find spec sources
209
+ # from the host filesystem
210
+ ENV["ENCLOSE_IO_RUBYC_1ST_PASS"] = "1"
211
+ ruby_version = Gem::ConfigMap[:ruby_version]
212
+
213
+ if Licensed::Shell.tool_available?("ruby")
214
+ # set the ruby version in Gem::ConfigMap to the ruby version from the host.
215
+ # this helps Bundler find the correct spec sources and paths
216
+ Gem::ConfigMap[:ruby_version] = host_ruby_version
217
+ else
218
+ # running a ruby-packer-built licensed exe when ruby and bundler aren't available
219
+ # is possible but could lead to errors if the host ruby version doesn't
220
+ # match the built executable's ruby version
221
+ @config.ui.warn <<~WARNING
222
+ Ruby wasn't found when enumerating bundler
223
+ dependencies using the licensed executable. This can cause a
224
+ ruby mismatch between licensed and bundled dependencies and a
225
+ failure to find gem specifications.
226
+
227
+ If licensed is unable to find gem specifications that you believe are present,
228
+ please ensure that ruby and bundler are available and try again.
229
+ WARNING
230
+ end
231
+ end
232
+
194
233
  # reset all bundler configuration
195
234
  ::Bundler.reset!
196
235
  # and re-configure with settings for current directory
@@ -198,11 +237,27 @@ module Licensed
198
237
 
199
238
  yield
200
239
  ensure
240
+ if ruby_packer?
241
+ # if running under ruby-packer, restore environment after block is finished
242
+ ENV.delete("ENCLOSE_IO_RUBYC_1ST_PASS")
243
+ Gem::ConfigMap[:ruby_version] = ruby_version
244
+ end
245
+
201
246
  ENV["BUNDLE_GEMFILE"] = original_bundle_gemfile
202
247
  # restore bundler configuration
203
248
  ::Bundler.reset!
204
249
  ::Bundler.configure
205
250
  end
251
+
252
+ # Returns whether the current licensed execution is running ruby-packer
253
+ def ruby_packer?
254
+ @ruby_packer ||= RbConfig::TOPDIR =~ /__enclose_io_memfs__/
255
+ end
256
+
257
+ # Returns the ruby version found in the bundler environment
258
+ def host_ruby_version
259
+ Licensed::Shell.execute(*ruby_command_args("ruby", "-e", "puts Gem::ConfigMap[:ruby_version]"))
260
+ end
206
261
  end
207
262
  end
208
263
  end
@@ -34,6 +34,7 @@ module Licensed
34
34
  def packages
35
35
  root_dependencies = JSON.parse(package_metadata_command)["dependencies"]
36
36
  recursive_dependencies(root_dependencies).each_with_object({}) do |(name, results), hsh|
37
+ next if @config.ignored?("type" => NPM.type, "name" => name)
37
38
  results.uniq! { |package| package["version"] }
38
39
  if results.size == 1
39
40
  hsh[name] = results[0]
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Licensed
3
- VERSION = "1.4.0".freeze
3
+ VERSION = "1.5.1".freeze
4
4
  end
@@ -37,8 +37,8 @@ BUILD_DEST="$(mktemp -d)"
37
37
  trap "rm -rf $BUILD_DEST" EXIT
38
38
 
39
39
  if [ -n "$VERSION" ]; then
40
- git checkout "$VERSION"
41
40
  CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
41
+ git checkout "$VERSION"
42
42
  trap "rm -rf $BUILD_DEST; git checkout $CURRENT_BRANCH" EXIT
43
43
  else
44
44
  VERSION="$(git rev-parse --abbrev-ref HEAD)"
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: 1.4.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-21 00:00:00.000000000 Z
11
+ date: 2018-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: licensee
@@ -188,6 +188,7 @@ files:
188
188
  - lib/licensed/command/cache.rb
189
189
  - lib/licensed/command/list.rb
190
190
  - lib/licensed/command/status.rb
191
+ - lib/licensed/command/version.rb
191
192
  - lib/licensed/configuration.rb
192
193
  - lib/licensed/dependency.rb
193
194
  - lib/licensed/git.rb