licensed 4.3.0 → 4.4.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: 8fbd6fc2c6122a9b41d7ac258d08861114f6425df01f7e6fd0f482e03a9d3efb
4
- data.tar.gz: 292fce45466f23cc690e3ffd8db6464928b80581c0cc99ab54dedf1e130b0adb
3
+ metadata.gz: 0aa51288268aeff291057d44b430bd4e8b03a1d396eaa1073f2f5401a69a75d5
4
+ data.tar.gz: 340dcf2edab467791df510d35abcf8a48f14239d5edb7d1f09b5df9cf04b40df
5
5
  SHA512:
6
- metadata.gz: 3b462f9f482e65519349ad62b8c8cb53cbadd693dd8a0449e730c6aad63bf5484c78e39b5a67d61aa68169e5bcd65ef3131a591a0bd5965d8fcb0962d382e609
7
- data.tar.gz: 399c6ff21a5a02c849e122365ccf4f8e5813bc7be628236fd5402894d012677501c9dd729cfbb597566f9fb4425f36360df59de8177b5cc0cb456c116e318916
6
+ metadata.gz: 23f1ac2d64039e0942ebd6e39dca3d8fd17d4143308cf0d5d03b9d7b7d6efda6ca7ea998af78caf8f00755631f63960d640c75deeb15fb1f76512895d1f5611a
7
+ data.tar.gz: a7f32b2517e130a2f645678b775c7a0a6b8ae4ce64514a9763fe0d3f174f8f4a28afb79d6c88b49b5e47a225d837ad2cff943142bcc0c00cec80b508827035fd
data/CHANGELOG.md CHANGED
@@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## 4.4.0
10
+
11
+ ### Added
12
+
13
+ - Licensed status command will alert on stale cached dependency records (https://github.com/github/licensed/pull/657)
14
+
15
+ ## 4.3.1
16
+
17
+ ### Changed
18
+
19
+ - Bump nokogiri to resolve vulnerabilities (https://github.com/github/licensed/pull/648)
20
+
9
21
  ## 4.3.0
10
22
 
11
23
  ### Added
@@ -729,4 +741,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
729
741
 
730
742
  Initial release :tada:
731
743
 
732
- [Unreleased]: https://github.com/github/licensed/compare/4.3.0...HEAD
744
+ [Unreleased]: https://github.com/github/licensed/compare/4.4.0...HEAD
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- licensed (4.3.0)
4
+ licensed (4.4.0)
5
5
  json (~> 2.6)
6
6
  licensee (~> 9.16)
7
7
  parallel (~> 1.22)
@@ -44,13 +44,13 @@ GEM
44
44
  minitest (> 5.3)
45
45
  mocha (2.0.2)
46
46
  ruby2_keywords (>= 0.0.5)
47
- nokogiri (1.14.2)
47
+ nokogiri (1.14.3)
48
48
  mini_portile2 (~> 2.8.0)
49
49
  racc (~> 1.4)
50
50
  octokit (6.1.0)
51
51
  faraday (>= 1, < 3)
52
52
  sawyer (~> 0.9)
53
- parallel (1.22.1)
53
+ parallel (1.23.0)
54
54
  parser (3.2.0.0)
55
55
  ast (~> 2.4.1)
56
56
  pathname-common_prefix (0.0.1)
@@ -93,7 +93,7 @@ GEM
93
93
  sawyer (0.9.2)
94
94
  addressable (>= 2.3.5)
95
95
  faraday (>= 0.17.3, < 3)
96
- thor (1.2.1)
96
+ thor (1.2.2)
97
97
  tomlrb (2.0.3)
98
98
  tzinfo (2.0.6)
99
99
  concurrent-ruby (~> 1.0)
@@ -31,6 +31,21 @@ A dependency will fail the status checks if:
31
31
  - If `license: other` is specified and all of the `licenses` entries match an `allowed` license a failure will not be logged
32
32
  - A `reviewed` entry must reference a specific version of the depdency, e.g. `<name>@<version>`. The version identifier must specify a specific dependency version, ranges are not allowed.
33
33
 
34
+ ## Detect and alert on stale cached metadata files
35
+
36
+ Licensed can alert on any metadata files that don't correlate to a currently used dependency when `licensed status` is run. To configure this behavior, set a root-level `stale_records_action` value in your [licensed configuration file](./../configuration.md).
37
+
38
+ Available values are:
39
+
40
+ 1. `'error'`: Treat stale cached records as errors. Licensed will output errors for any stale metadata files and will cause `licensed status` to fail.
41
+ 1. `'warn'`, `''`, or unset (default): Treat stale cached records as warnings. Licensed will output warnings for any stale metadata files but will not cause `licensed status` to fail.
42
+ 1. `'ignore'`, any other value: Ignore stale cached records. Licensed will not output any notifications about stale metadata files.
43
+
44
+ ```yaml
45
+ # in the licensed configuration file
46
+ stale_records_action: 'warn'
47
+ ```
48
+
34
49
  ## Options
35
50
 
36
51
  - `--config`/`-c`: the path to the licensed configuration file
@@ -26,6 +26,15 @@ cache_path: 'relative/path/to/cache'
26
26
  # Defaults to current directory when running `licensed`
27
27
  source_path: 'relative/path/to/source'
28
28
 
29
+ # Whether to take any action when records are detected in the cache paths that don't map to evaluated
30
+ # dependencies.
31
+ # Available values are:
32
+ # - 'error': treat stale cached records as errors. Notify the user and fail status checks
33
+ # - 'warn', '', unset: treat stale cached records as warnings. Notify the user but do not fail status checks
34
+ # - 'ignore': Ignore stale cached records. Do not notify the user and do not fail status checks
35
+ # Optional, when not set this defaults to 'warn' behavior
36
+ stale_records_action: 'warn'
37
+
29
38
  # Sources of metadata
30
39
  sources:
31
40
  bower: true
@@ -23,6 +23,7 @@ module Licensed
23
23
  def run_command(report)
24
24
  super do |result|
25
25
  clear_stale_cached_records if result
26
+ result
26
27
  end
27
28
  ensure
28
29
  cache_paths.clear
@@ -69,7 +69,7 @@ module Licensed
69
69
 
70
70
  result = results.all?
71
71
 
72
- yield(result) if block_given?
72
+ result = yield(result) if block_given?
73
73
 
74
74
  result
75
75
  ensure
@@ -103,7 +103,7 @@ module Licensed
103
103
 
104
104
  result = results.all?
105
105
 
106
- yield(result) if block_given?
106
+ result = yield(result) if block_given?
107
107
 
108
108
  result
109
109
  end
@@ -142,7 +142,7 @@ module Licensed
142
142
 
143
143
  result = results.all?
144
144
 
145
- yield(result) if block_given?
145
+ result = yield(result) if block_given?
146
146
 
147
147
  result
148
148
  rescue Licensed::Shell::Error => err
@@ -175,7 +175,7 @@ module Licensed
175
175
 
176
176
  result = evaluate_dependency(app, source, dependency, report)
177
177
 
178
- yield(result) if block_given?
178
+ result = yield(result) if block_given?
179
179
 
180
180
  result
181
181
  rescue Licensed::DependencyRecord::Error, Licensed::Shell::Error => err
@@ -23,10 +23,48 @@ module Licensed
23
23
  # Returns whether the command succeeded based on the call to super
24
24
  def run_command(report)
25
25
  super do |result|
26
- next if result
26
+ stale_records = stale_cached_records
27
+ if stale_records.any?
28
+ messages = stale_records.map { |f| "Stale dependency record found: #{f}" }
29
+ messages << "Please run the licensed cache command to clean up stale records"
30
+
31
+ case config["stale_records_action"].to_s
32
+ when "error"
33
+ report.errors.concat messages
34
+ result = false
35
+ when "warn", ""
36
+ report.warnings.concat messages
37
+ end
38
+ end
39
+
40
+ next result if result
27
41
 
28
42
  report.errors << "Licensed found errors during source enumeration. Please see https://github.com/github/licensed/tree/master/docs/commands/status.md#status-errors-and-resolutions for possible resolutions."
43
+
44
+ result
29
45
  end
46
+ ensure
47
+ cache_paths.clear
48
+ files.clear
49
+ end
50
+
51
+ # Run the command for all enumerated dependencies found in a dependency source,
52
+ # recording results in a report.
53
+ # Enumerating dependencies in the source is skipped if a :sources option
54
+ # is provided and the evaluated `source.class.type` is not in the :sources values
55
+ #
56
+ # app - The application configuration for the source
57
+ # source - A dependency source enumerator
58
+ #
59
+ # Returns whether the command succeeded for the dependency source enumerator
60
+ def run_source(app, source, report)
61
+ result = super
62
+
63
+ # add the full cache path to the list of cache paths
64
+ # that should be checked for extra files after the command run
65
+ cache_paths << app.cache_path.join(source.class.type) unless result == :skipped
66
+
67
+ result
30
68
  end
31
69
 
32
70
  # Evaluates a dependency for any compliance errors.
@@ -49,6 +87,9 @@ module Licensed
49
87
  filename = app.cache_path.join(source.class.type, "#{dependency.name}.#{DependencyRecord::EXTENSION}")
50
88
  report["filename"] = filename
51
89
  record = cached_record(filename)
90
+
91
+ # add the absolute dependency file path to the list of files seen during this licensed run
92
+ files << filename.to_s
52
93
  end
53
94
 
54
95
  if record.nil?
@@ -133,6 +174,26 @@ module Licensed
133
174
 
134
175
  licenses.sort_by { |license| license != "other" ? 0 : 1 }.first
135
176
  end
177
+
178
+ # Check for cached files that don't match current dependencies
179
+ #
180
+ # Returns an array of any cached records that do not match a currently used dependency
181
+ def stale_cached_records
182
+ cache_paths.flat_map do |cache_path|
183
+ record_search_glob_pattern = cache_path.join("**/*.#{DependencyRecord::EXTENSION}")
184
+ Dir.glob(record_search_glob_pattern).select { |file| !files.include?(file) }
185
+ end.uniq
186
+ end
187
+
188
+ # Set of unique cache paths that are evaluted during the run
189
+ def cache_paths
190
+ @cache_paths ||= Set.new
191
+ end
192
+
193
+ # Set of unique absolute file paths of cached records evaluted during the run
194
+ def files
195
+ @files ||= Set.new
196
+ end
136
197
  end
137
198
  end
138
199
  end
@@ -274,6 +274,7 @@ module Licensed
274
274
  end
275
275
 
276
276
  def initialize(options = {})
277
+ @options = options
277
278
  apps = options.delete("apps") || []
278
279
  apps << default_options.merge(options) if apps.empty?
279
280
 
@@ -285,6 +286,10 @@ module Licensed
285
286
  @apps = apps.map { |app| AppConfiguration.new(app, options) }
286
287
  end
287
288
 
289
+ def [](key)
290
+ @options&.fetch(key, nil)
291
+ end
292
+
288
293
  private
289
294
 
290
295
  def self.expand_app_source_path(app_config)
@@ -8,6 +8,11 @@ module Licensed
8
8
  # command - The command being run
9
9
  # report - A report object containing information about the command run
10
10
  def end_report_command(command, report)
11
+ if report.warnings.any?
12
+ shell.newline
13
+ report.warnings.each { |e| shell.warn e }
14
+ end
15
+
11
16
  if report.errors.any?
12
17
  shell.newline
13
18
  report.errors.each { |e| shell.error e }
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Licensed
3
- VERSION = "4.3.0".freeze
3
+ VERSION = "4.4.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: 4.3.0
4
+ version: 4.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-03-20 00:00:00.000000000 Z
11
+ date: 2023-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: licensee