licensed 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4578c64f9787f2894b6366165f1a1075f61ac7eb
4
- data.tar.gz: 34ffddfaa1572948bce8bc116a5cfd093c685a13
3
+ metadata.gz: 45476f98c8dd054a36758218f6337826e90b1112
4
+ data.tar.gz: e040ac55ae8dbd3b7dd498318b8046a271c58832
5
5
  SHA512:
6
- metadata.gz: 0c9861f9d076050e389843122baeb96501f9a53e5252309576512e102fdef4f1dc7196593c66254e30a793c734a0127b53942215366a78e6f7444e04bffe9e27
7
- data.tar.gz: 51880d49fca93099ee44997b2878c29d7ed25bc88d221439fcf73039a9728ee6079d0843fd90a615ffb21f6871ce9dadd310765c3a98799e13e81138630bf7fd
6
+ metadata.gz: 6773ae7dc4f41afd8f0597c11e3ea4bda59c10de44654c9fd9b6b91bce6f2a0b0b092ecccb95dc39ce6da5678736672d6fb3fa9b48b47bf82eb1758cecc91297
7
+ data.tar.gz: 80c82cfccb88980bc3b1b04da520e740683bb18d52cc3dcc5e60801e529f5c926d64c9df80a24dfc431e4ff2271a4fef67389b7bf4b9779edd7aeb739d015036
@@ -28,7 +28,7 @@ jobs:
28
28
 
29
29
  - uses: actions/upload-artifact@master
30
30
  with:
31
- name: licensed-${{github.event.ref}}-linux-x64.tar.gz
31
+ name: ${{github.event.ref}}-linux
32
32
  path: pkg/${{github.event.ref}}/licensed-${{github.event.ref}}-linux-x64.tar.gz
33
33
 
34
34
  package_mac:
@@ -49,28 +49,28 @@ jobs:
49
49
 
50
50
  - uses: actions/upload-artifact@master
51
51
  with:
52
- name: licensed-${{github.event.ref}}-darwin-x64.tar.gz
52
+ name: ${{github.event.ref}}-darwin
53
53
  path: pkg/${{github.event.ref}}/licensed-${{github.event.ref}}-darwin-x64.tar.gz
54
-
54
+
55
55
  build_gem:
56
56
  runs-on: ubuntu-latest
57
57
  needs: tag_filter
58
-
58
+
59
59
  steps:
60
60
  - uses: actions/checkout@master
61
61
  - name: Set up Ruby 2.6
62
62
  uses: actions/setup-ruby@v1
63
63
  with:
64
64
  version: 2.6.x
65
-
65
+
66
66
  - name: Build gem
67
67
  run: gem build *.gemspec
68
-
68
+
69
69
  - uses: actions/upload-artifact@master
70
70
  with:
71
- name: licensed-${{github.event.ref}}.gem
71
+ name: ${{github.event.ref}}-gem
72
72
  path: licensed-${{github.event.ref}}.gem
73
-
73
+
74
74
  create_release:
75
75
  runs-on: ubuntu-latest
76
76
  needs: [package_linux, package_mac, build_gem]
@@ -86,38 +86,40 @@ jobs:
86
86
  needs: [create_release]
87
87
 
88
88
  steps:
89
+ - name: Set up Ruby 2.6
90
+ uses: actions/setup-ruby@v1
91
+ with:
92
+ version: 2.6.x
93
+
89
94
  - name: Download linux package
90
95
  uses: actions/download-artifact@master
91
96
  with:
92
- name: licensed-${{github.event.ref}}-linux-x64.tar.gz
97
+ name: ${{github.event.ref}}-linux
98
+
93
99
  - name: Download macOS package
94
100
  uses: actions/download-artifact@master
95
101
  with:
96
- name: licensed-${{github.event.ref}}-darwin-x64.tar.gz
102
+ name: ${{github.event.ref}}-darwin
103
+
104
+ - name: Download gem
105
+ uses: actions/download-artifact@master
106
+ with:
107
+ name: ${{github.event.ref}}-gem
97
108
 
98
109
  - name: Publish packages to GitHub Release
99
110
  uses: Roang-zero1/github-upload-release-artifacts-action@v2.0.0
100
111
  with:
101
- args: licensed-${{github.event.ref}}-linux-x64.tar.gz licensed-${{github.event.ref}}-darwin-x64.tar.gz
112
+ args: ${{github.event.ref}}-linux ${{github.event.ref}}-darwin
102
113
  env:
103
114
  GITHUB_TOKEN: ${{secrets.API_AUTH_TOKEN}}
104
115
 
105
- - name: Download gem
106
- uses: actions/download-artifact@master
107
- with:
108
- name: licensed-${{github.event.ref}}.gem
109
-
110
- - name: Set up Ruby 2.6
111
- uses: actions/setup-ruby@v1
112
- with:
113
- version: 2.6.x
114
-
115
116
  - name: Publish gem to RubyGems
116
117
  run: |
117
118
  mkdir -p $HOME/.gem
118
119
  touch $HOME/.gem/credentials
119
120
  chmod 0600 $HOME/.gem/credentials
120
121
  printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
121
- gem push *.gem
122
+ gem push "$GEM"
122
123
  env:
123
124
  GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}}
125
+ GEM: ${{github.event.ref}}-gem/*.gem
@@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## 2.5.0
10
+ 2019-09-26
11
+
12
+ ### Added
13
+ - `env` command to output application environment configuration (https://github.com/github/licensed/pull/187, https://github.com/github/licensed/pull/191)
14
+
15
+ ### Changed
16
+ - `status` command will pass if multiple allowed licenses are found (https://github.com/github/licensed/pull/188)
17
+
9
18
  ## 2.4.0
10
19
  2019-09-15
11
20
 
@@ -214,4 +223,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
214
223
 
215
224
  Initial release :tada:
216
225
 
217
- [Unreleased]: https://github.com/github/licensed/compare/2.4.0...HEAD
226
+ [Unreleased]: https://github.com/github/licensed/compare/2.5.0...HEAD
data/README.md CHANGED
@@ -8,7 +8,7 @@ Licensed is **not** a complete open source license compliance solution. Please u
8
8
 
9
9
  ## Current Status
10
10
 
11
- [![Build Status](https://travis-ci.org/github/licensed.svg?branch=master)](https://travis-ci.org/github/licensed)
11
+ ![Build status](https://github.com/github/licensed/workflows/Test/badge.svg)
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
 
@@ -25,8 +25,15 @@ The status command finds all dependencies and checks whether each dependency has
25
25
  A dependency will fail the status checks if:
26
26
  1. No cached record is found
27
27
  2. The cached record's version is different than the current dependency's version
28
- 3. The cached record doesn't contain any license text
28
+ 3. The cached record's `licenses` data is empty
29
29
  4. The cached record's `license` metadata doesn't match an `allowed` license from the dependency's application configuration.
30
+ - If `license: other` is specified and all of the `licenses` entries match an `allowed` license a failure will not be logged
31
+
32
+ ## `env`
33
+
34
+ Prints the runtime environment used by licensed after loading a configuration file. By default the output is in YAML format, but can be output in JSON using the `--json` flag.
35
+
36
+ The output will not be equivalent to configuration input. For example, all paths will be
30
37
 
31
38
  ## `version`
32
39
 
@@ -41,7 +48,7 @@ Licensed commands inherit and override the [`Licensed::Sources::Command`](../lib
41
48
  #### Required method overrides
42
49
  1. `Licensed::Commands::Command#evaluate_dependency`
43
50
  - Runs a command execution on an application dependency.
44
-
51
+
45
52
  The `evaluate_dependency` method should contain the specific command logic. This method has access to the application configuration, dependency source enumerator and dependency currently being evaluated as well as a reporting hash to contain information about the command execution.
46
53
 
47
54
  #### Optional method overrides
@@ -59,23 +66,14 @@ The following methods break apart the different levels of command execution. Ea
59
66
 
60
67
  As an example, `Licensed::Commands::Command#run_app` calls `Reporter#report_app` to wrap every call to `Licensed::Commands::Command#run_source`.
61
68
 
62
- ##### Overriding optional methods
69
+ ##### Specifying additional report data
63
70
 
64
- The `run` methods can be overridden to provide additional reporting data or functionality. Overriding a method should call the original method with a block for the additional logic.
71
+ The `run` methods can be overridden and pass a block to `super` to provide additional reporting data or functionality.
65
72
 
66
73
  ```ruby
67
74
  def run_app(app)
68
75
  super do |report|
69
- result = yield report
70
-
71
- # do other thing
72
- call_additional_functionality(app)
73
-
74
- # add reporting information
75
- report["result"] = result
76
-
77
- # return the result
78
- result
76
+ report["my_app_data"] = true
79
77
  end
80
78
  end
81
79
  ```
@@ -35,6 +35,15 @@ module Licensed
35
35
  puts Licensed::VERSION
36
36
  end
37
37
 
38
+ desc "env", "Output licensed environment configuration"
39
+ method_option :format, enum: ["yaml", "json"], default: "yaml",
40
+ desc: "Output format"
41
+ method_option :config, aliases: "-c", type: :string,
42
+ desc: "Path to licensed configuration file"
43
+ def env
44
+ run Licensed::Commands::Environment.new(config: config), format: options[:format]
45
+ end
46
+
38
47
  desc "migrate", "Migrate from a previous version of licensed"
39
48
  method_option :config, aliases: "-c", type: :string, required: true,
40
49
  desc: "Path to licensed configuration file"
@@ -5,5 +5,6 @@ module Licensed
5
5
  require "licensed/commands/cache"
6
6
  require "licensed/commands/status"
7
7
  require "licensed/commands/list"
8
+ require "licensed/commands/environment"
8
9
  end
9
10
  end
@@ -2,8 +2,13 @@
2
2
  module Licensed
3
3
  module Commands
4
4
  class Cache < Command
5
- def initialize(config:, reporter: Licensed::Reporters::CacheReporter.new)
6
- super(config: config, reporter: reporter)
5
+ # Create a reporter to use during a command run
6
+ #
7
+ # options - The options the command was run with
8
+ #
9
+ # Raises a Licensed::Reporters::CacheReporter
10
+ def create_reporter(options)
11
+ Licensed::Reporters::CacheReporter.new
7
12
  end
8
13
 
9
14
  protected
@@ -6,9 +6,8 @@ module Licensed
6
6
  attr_reader :reporter
7
7
  attr_reader :options
8
8
 
9
- def initialize(config:, reporter:)
9
+ def initialize(config:)
10
10
  @config = config
11
- @reporter = reporter
12
11
  end
13
12
 
14
13
  # Run the command
@@ -18,19 +17,33 @@ module Licensed
18
17
  # Returns whether the command was a success
19
18
  def run(**options)
20
19
  @options = options
20
+ @reporter = create_reporter(options)
21
21
  begin
22
- result = reporter.report_run(self) do
22
+ result = reporter.report_run(self) do |report|
23
+ # allow additional report data to be given by commands
24
+ yield report if block_given?
25
+
23
26
  config.apps.sort_by { |app| app["name"] }
24
27
  .map { |app| run_app(app) }
25
28
  .all?
26
29
  end
27
30
  ensure
28
31
  @options = nil
32
+ @reporter = nil
29
33
  end
30
34
 
31
35
  result
32
36
  end
33
37
 
38
+ # Create a reporter to use during a command run
39
+ #
40
+ # options - The options the command was run with
41
+ #
42
+ # Raises an error
43
+ def create_reporter(options)
44
+ raise "`create_reporter` must be implemented by commands"
45
+ end
46
+
34
47
  protected
35
48
 
36
49
  # Run the command for all enabled sources for an application configuration,
@@ -43,6 +56,9 @@ module Licensed
43
56
  reporter.report_app(app) do |report|
44
57
  Dir.chdir app.source_path do
45
58
  begin
59
+ # allow additional report data to be given by commands
60
+ yield report if block_given?
61
+
46
62
  app.sources.select(&:enabled?)
47
63
  .sort_by { |source| source.class.type }
48
64
  .map { |source| run_source(app, source) }.all?
@@ -64,6 +80,9 @@ module Licensed
64
80
  def run_source(app, source)
65
81
  reporter.report_source(source) do |report|
66
82
  begin
83
+ # allow additional report data to be given by commands
84
+ yield report if block_given?
85
+
67
86
  source.dependencies.sort_by { |dependency| dependency.name }
68
87
  .map { |dependency| run_dependency(app, source, dependency) }
69
88
  .all?
@@ -94,6 +113,9 @@ module Licensed
94
113
  end
95
114
 
96
115
  begin
116
+ # allow additional report data to be given by commands
117
+ yield report if block_given?
118
+
97
119
  evaluate_dependency(app, source, dependency, report)
98
120
  rescue Licensed::Shell::Error => err
99
121
  report.errors << err.message
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+ module Licensed
3
+ module Commands
4
+ class Environment < Command
5
+ class AppEnvironment
6
+ include Licensed::Sources::ContentVersioning
7
+
8
+ attr_reader :config
9
+ def initialize(config)
10
+ @config = config
11
+ end
12
+
13
+ def enabled_source_types
14
+ config.sources.select { |s| s.enabled? }.map { |s| s.class.type }
15
+ end
16
+
17
+ def to_h
18
+ {
19
+ "name" => config["name"],
20
+ "source_path" => config.source_path,
21
+ "cache_path" => config.cache_path,
22
+ "sources" => enabled_source_types,
23
+ "allowed" => config["allowed"],
24
+ "ignored" => config["ignored"],
25
+ "reviewed" => config["reviewed"],
26
+ "version_strategy" => self.version_strategy
27
+ }
28
+ end
29
+ end
30
+
31
+ def run(**options)
32
+ super do |report|
33
+ report["root"] = config.root
34
+ report["git_repo"] = Licensed::Git.git_repo?
35
+ end
36
+ end
37
+
38
+ def create_reporter(options)
39
+ case options[:format]
40
+ when "json"
41
+ Licensed::Reporters::JsonReporter.new
42
+ else
43
+ Licensed::Reporters::YamlReporter.new
44
+ end
45
+ end
46
+
47
+ protected
48
+
49
+ def run_app(app)
50
+ reporter.report_app(app) do |report|
51
+ report.merge! AppEnvironment.new(app).to_h
52
+ true
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -2,8 +2,13 @@
2
2
  module Licensed
3
3
  module Commands
4
4
  class List < Command
5
- def initialize(config:, reporter: Licensed::Reporters::ListReporter.new)
6
- super(config: config, reporter: reporter)
5
+ # Create a reporter to use during a command run
6
+ #
7
+ # options - The options the command was run with
8
+ #
9
+ # Returns a Licensed::Reporters::ListReporter
10
+ def create_reporter(options)
11
+ Licensed::Reporters::ListReporter.new
7
12
  end
8
13
 
9
14
  protected
@@ -4,8 +4,13 @@ require "yaml"
4
4
  module Licensed
5
5
  module Commands
6
6
  class Status < Command
7
- def initialize(config:, reporter: Licensed::Reporters::StatusReporter.new)
8
- super(config: config, reporter: reporter)
7
+ # Create a reporter to use during a command run
8
+ #
9
+ # options - The options the command was run with
10
+ #
11
+ # Returns a Licensed::Reporters::StatusReporter
12
+ def create_reporter(options)
13
+ Licensed::Reporters::StatusReporter.new
9
14
  end
10
15
 
11
16
  protected
@@ -30,20 +35,52 @@ module Licensed
30
35
  else
31
36
  report.errors << "cached dependency record out of date" if cached_record["version"] != dependency.version
32
37
  report.errors << "missing license text" if cached_record.licenses.empty?
33
- report.errors << "license needs review: #{cached_record["license"]}" unless allowed_or_reviewed?(app, cached_record)
38
+ report.errors << "license needs review: #{cached_record["license"]}" if license_needs_review?(app, cached_record)
34
39
  end
35
40
 
36
41
  report.errors.empty?
37
42
  end
38
43
 
39
- def allowed_or_reviewed?(app, dependency)
40
- app.allowed?(dependency) || app.reviewed?(dependency)
44
+ # Returns true if a cached record needs further review based on the
45
+ # record's license(s) and the app's configuration
46
+ def license_needs_review?(app, cached_record)
47
+ # review is not needed if the record is set as reviewed
48
+ return false if app.reviewed?(cached_record)
49
+ # review is not needed if the top level license is allowed
50
+ return false if app.allowed?(cached_record["license"])
51
+
52
+ # the remaining checks are meant to allow records marked as "other"
53
+ # that have multiple licenses, all of which are allowed
54
+
55
+ # review is needed for non-"other" licenses
56
+ return true unless cached_record["license"] == "other"
57
+
58
+ licenses = cached_record.licenses.map { |license| license_from_text(license.text) }
59
+
60
+ # review is needed when there is only one license notice
61
+ # this is a performance optimization for the single license case
62
+ return true unless licenses.length > 1
63
+
64
+ # review is needed if any license notices don't represent an allowed license
65
+ licenses.any? { |license| !app.allowed?(license) }
41
66
  end
42
67
 
43
68
  def cached_record(filename)
44
69
  return nil unless File.exist?(filename)
45
70
  DependencyRecord.read(filename)
46
71
  end
72
+
73
+ # Returns a license key based on the content from a cached records `licenses`
74
+ # entry content
75
+ def license_from_text(text)
76
+ licenses = [
77
+ Licensee::ProjectFiles::LicenseFile.new(text).license&.key,
78
+ Licensee::ProjectFiles::ReadmeFile.new(text).license&.key,
79
+ "other"
80
+ ].compact
81
+
82
+ licenses.sort_by { |license| license != "other" ? 0 : 1 }.first
83
+ end
47
84
  end
48
85
  end
49
86
  end
@@ -79,8 +79,8 @@ module Licensed
79
79
  end
80
80
 
81
81
  # Is the license of the dependency allowed?
82
- def allowed?(dependency)
83
- Array(self["allowed"]).include?(dependency["license"])
82
+ def allowed?(license)
83
+ Array(self["allowed"]).include?(license)
84
84
  end
85
85
 
86
86
  # Ignore a dependency
@@ -5,6 +5,28 @@ require "licensee"
5
5
 
6
6
  module Licensed
7
7
  class DependencyRecord
8
+ class License
9
+ attr_reader :text, :sources
10
+ def initialize(content)
11
+ @sources = []
12
+
13
+ if content.is_a?(String)
14
+ @text = content.to_s
15
+ elsif content.respond_to?(:[])
16
+ @sources.concat content["sources"].to_s.split(", ")
17
+ @text = content["text"]
18
+ end
19
+ end
20
+
21
+ def to_cache
22
+ return text if sources.empty?
23
+ {
24
+ "sources" => sources.join(", "),
25
+ "text" => text
26
+ }
27
+ end
28
+ end
29
+
8
30
  include Licensee::ContentHelper
9
31
  extend Forwardable
10
32
 
@@ -36,7 +58,7 @@ module Licensed
36
58
  # notices - a string, or array of strings, representing the content of each legal notice
37
59
  # metadata - a Hash of the metadata for the package
38
60
  def initialize(licenses: [], notices: [], metadata: {})
39
- @licenses = [licenses].flatten.compact
61
+ @licenses = [licenses].flatten.compact.map { |l| DependencyRecord::License.new(l) }
40
62
  @notices = [notices].flatten.compact
41
63
  @metadata = metadata
42
64
  end
@@ -46,7 +68,7 @@ module Licensed
46
68
  # filename - The destination file to save record contents at
47
69
  def save(filename)
48
70
  data_to_save = @metadata.merge({
49
- "licenses" => licenses,
71
+ "licenses" => licenses.map(&:to_cache),
50
72
  "notices" => notices
51
73
  })
52
74
 
@@ -58,13 +80,7 @@ module Licensed
58
80
  # `Licensee::CotentHelper`
59
81
  def content
60
82
  return if licenses.nil? || licenses.empty?
61
- licenses.map do |license|
62
- if license.is_a?(String)
63
- license
64
- elsif license.respond_to?(:[])
65
- license["text"]
66
- end
67
- end.join
83
+ licenses.map(&:text).compact.join
68
84
  end
69
85
 
70
86
  # Returns whether two records match based on their contents
@@ -5,5 +5,7 @@ module Licensed
5
5
  require "licensed/reporters/cache_reporter"
6
6
  require "licensed/reporters/status_reporter"
7
7
  require "licensed/reporters/list_reporter"
8
+ require "licensed/reporters/json_reporter"
9
+ require "licensed/reporters/yaml_reporter"
8
10
  end
9
11
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+ require "json"
3
+
4
+ module Licensed
5
+ module Reporters
6
+ class JsonReporter < Reporter
7
+ def report_run(command)
8
+ super do |report|
9
+ result = yield report
10
+
11
+ report["apps"] = report.reports.map(&:to_h) if report.reports.any?
12
+ shell.info JSON.pretty_generate(report.to_h)
13
+
14
+ result
15
+ end
16
+ end
17
+
18
+ def report_app(app)
19
+ super do |report|
20
+ result = yield report
21
+ report["sources"] = report.reports.map(&:to_h) if report.reports.any?
22
+ result
23
+ end
24
+ end
25
+
26
+ def report_source(source)
27
+ super do |report|
28
+ result = yield report
29
+ report["dependencies"] = report.reports.map(&:to_h) if report.reports.any?
30
+ result
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -28,6 +28,19 @@ module Licensed
28
28
  result << self
29
29
  result.push(*reports.flat_map(&:all_reports))
30
30
  end
31
+
32
+ # Returns the data from the report as a hash
33
+ def to_h
34
+ # add name, errors and warnings if they have real data
35
+ output = {}
36
+ output["name"] = name unless name.to_s.empty?
37
+ output["errors"] = errors.dup if errors.any?
38
+ output["warnings"] = warnings.dup if warnings.any?
39
+
40
+ # merge the hash data from the report. command-specified data always
41
+ # overwrites local data
42
+ output.merge(super)
43
+ end
31
44
  end
32
45
 
33
46
  class ReportingError < StandardError; end;
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+ module Licensed
3
+ module Reporters
4
+ class YamlReporter < Reporter
5
+ def report_run(command)
6
+ super do |report|
7
+ result = yield report
8
+
9
+ report["apps"] = report.reports.map(&:to_h) if report.reports.any?
10
+ shell.info sanitize(report.to_h).to_yaml
11
+
12
+ result
13
+ end
14
+ end
15
+
16
+ def report_app(app)
17
+ super do |report|
18
+ result = yield report
19
+ report["sources"] = report.reports.map(&:to_h) if report.reports.any?
20
+ result
21
+ end
22
+ end
23
+
24
+ def report_source(source)
25
+ super do |report|
26
+ result = yield report
27
+ report["dependencies"] = report.reports.map(&:to_h) if report.reports.any?
28
+ result
29
+ end
30
+ end
31
+
32
+ def sanitize(object)
33
+ case object
34
+ when String, TrueClass, FalseClass, Numeric
35
+ object
36
+ when Array
37
+ object.compact.map { |item| sanitize(item) }
38
+ when Hash
39
+ object.reject { |_, v| v.nil? }
40
+ .map { |k, v| [k.to_s, sanitize(v)] }
41
+ .to_h
42
+ else
43
+ object.to_s
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Licensed
3
- VERSION = "2.4.0".freeze
3
+ VERSION = "2.5.0".freeze
4
4
 
5
5
  def self.previous_major_versions
6
6
  major_version = Gem::Version.new(Licensed::VERSION).segments.first
@@ -36,4 +36,5 @@ Gem::Specification.new do |spec|
36
36
  spec.add_development_dependency "rubocop", "~> 0.49", "< 0.67"
37
37
  spec.add_development_dependency "rubocop-github", "~> 0.6"
38
38
  spec.add_development_dependency "byebug", "~> 10.0.0"
39
+ spec.add_development_dependency "spy", "~> 1.0.0"
39
40
  end
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.4.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-09-15 00:00:00.000000000 Z
11
+ date: 2019-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: licensee
@@ -184,6 +184,20 @@ dependencies:
184
184
  - - "~>"
185
185
  - !ruby/object:Gem::Version
186
186
  version: 10.0.0
187
+ - !ruby/object:Gem::Dependency
188
+ name: spy
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "~>"
192
+ - !ruby/object:Gem::Version
193
+ version: 1.0.0
194
+ type: :development
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - "~>"
199
+ - !ruby/object:Gem::Version
200
+ version: 1.0.0
187
201
  description: Licensed automates extracting and validating the licenses of dependencies.
188
202
  email:
189
203
  - opensource+licensed@github.com
@@ -231,6 +245,7 @@ files:
231
245
  - lib/licensed/commands.rb
232
246
  - lib/licensed/commands/cache.rb
233
247
  - lib/licensed/commands/command.rb
248
+ - lib/licensed/commands/environment.rb
234
249
  - lib/licensed/commands/list.rb
235
250
  - lib/licensed/commands/status.rb
236
251
  - lib/licensed/configuration.rb
@@ -241,9 +256,11 @@ files:
241
256
  - lib/licensed/migrations/v2.rb
242
257
  - lib/licensed/reporters.rb
243
258
  - lib/licensed/reporters/cache_reporter.rb
259
+ - lib/licensed/reporters/json_reporter.rb
244
260
  - lib/licensed/reporters/list_reporter.rb
245
261
  - lib/licensed/reporters/reporter.rb
246
262
  - lib/licensed/reporters/status_reporter.rb
263
+ - lib/licensed/reporters/yaml_reporter.rb
247
264
  - lib/licensed/shell.rb
248
265
  - lib/licensed/sources.rb
249
266
  - lib/licensed/sources/bower.rb