licensed 3.5.0 → 3.7.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
  SHA256:
3
- metadata.gz: d2fafd3b11ba6f63760979021e1628aa1d4ae0e0cd5b0b413b06c6163a1b64fd
4
- data.tar.gz: d5fe530e59e0091b44f0ae08403f72707f6dc4db391a6d7e39e4b620c01b1da9
3
+ metadata.gz: 03de72b78b61eb285dc7f28303375a782ac1061997cd8a1dc7e664874d017ab6
4
+ data.tar.gz: af3660d69f8a235b7b40b08ede58f0bc8250ead97aa3a19c51cebfb88922c5e9
5
5
  SHA512:
6
- metadata.gz: a2b691823b7cbc692fb155bc672772fea156932a3d7d38111634927a0babf427343f992eded7d219041575e64e698a9821fdf1e9e12390f8e29a2c95a42e340a
7
- data.tar.gz: 61872b213231ead8c7ce5d209af8332964e8562e8809dbbf7c3e5fd95b84cfffcc7b9c4391f0e81d6e094325293bbe61520458d4cc1233072f4b0c41b04cd165
6
+ metadata.gz: 2e8125e6de6e0892a1afca36dd6cf5ae6091d101b7bbc58a3fd3086c1ac58838323f4979d859ea2de7e3ecc32f4af222f3eab433d6cccd95b73687b1f2626eb3
7
+ data.tar.gz: 4c18508e167faeb8d81dfb1548e9f5ed71fbc38c18b0a610dbc230911f7940062deadc4bed7a153e39ff8d94642bcab82b61a9ad7948860f508a84dc0b2f6175
data/CHANGELOG.md CHANGED
@@ -6,6 +6,36 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## 3.7.1
10
+
11
+ ### Fixed
12
+
13
+ - Dependencies' legal notice file matching has been made more strict to reduce false positives on code files containing the word `legal` (https://github.com/github/licensed/pull/510)
14
+
15
+ ## 3.7.0
16
+
17
+ ### Changed
18
+
19
+ - Pip and pipenv sources will find dependency licenses under `dist-info/license_files` when available (https://github.com/github/licensed/pull/504)
20
+
21
+ ## 3.6.0
22
+
23
+ 2022-03-17
24
+
25
+ ### Added
26
+
27
+ - Composer dev dependencies can optionally be included in enumerated PHP dependencies (:tada: @digilist https://github.com/github/licensed/pull/486)
28
+ - Getting started usage documentation (https://github.com/github/licensed/pull/483)
29
+ - Initial support for NPM workspaces (https://github.com/github/licensed/pull/485)
30
+
31
+ ### Changed
32
+
33
+ - Transitive dependencies are now enumerated by the `pip` source (https://github.com/github/licensed/pull/480)
34
+
35
+ ### Fixed
36
+
37
+ - `licensed cache --force` will now correctly overwrite existing license classifications (https://github.com/github/licensed/pull/473)
38
+
9
39
  ## 3.5.0
10
40
 
11
41
  2022-02-24
@@ -579,4 +609,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
579
609
 
580
610
  Initial release :tada:
581
611
 
582
- [Unreleased]: https://github.com/github/licensed/compare/3.4.4...HEAD
612
+ [Unreleased]: https://github.com/github/licensed/compare/3.7.1...HEAD
data/README.md CHANGED
@@ -74,6 +74,8 @@ For system wide usage, install licensed to a location on `$PATH`, e.g. `/usr/loc
74
74
 
75
75
  ## Usage
76
76
 
77
+ See [getting started](./docs/getting_started.md) for guidance using Licensed as part of your developer workflow.
78
+
77
79
  ### Available commands
78
80
 
79
81
  See the [commands documentation](./docs/commands) for documentation on available commands, or run `licensed -h` to see all of the current available commands.
@@ -86,18 +88,6 @@ A configuration file is required for most commands. See the [configuration file
86
88
 
87
89
  Licensed can enumerate dependency for many languages, package managers, and frameworks. See the [sources documentation](./docs/sources) for the list of currently available sources. Sources can be explicitly enabled and disabled as a [configuration option](./docs/configuration/dependency_source_enumerators.md.md).
88
90
 
89
- ### Automation
90
-
91
- #### Bundler
92
-
93
- The [bundler-licensed plugin](https://github.com/sergey-alekseev/bundler-licensed) runs `licensed cache` automatically when using `bundler`. See the linked repo for usage and details.
94
-
95
- #### GitHub Actions
96
-
97
- 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.
98
-
99
- 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.
100
-
101
91
  ## Development
102
92
 
103
93
  To get started after checking out the repo, run
@@ -8,6 +8,6 @@ Licensed uses [Licensee](https://github.com/licensee/licensee) to detect and eva
8
8
  licensee:
9
9
  # the confidence threshold is an integer between 1 and 100. the value represents
10
10
  # the minimum percentage confidence that Licensee must have to report a matched license
11
- # https://github.com/licensee/licensee/blob/jonabc-patch-1/docs/customizing.md#adjusting-the-confidence-threshold
11
+ # https://github.com/licensee/licensee/blob/master/docs/customizing.md#adjusting-the-confidence-threshold
12
12
  confidence_threshold: 90 # default value: 98
13
13
  ```
@@ -0,0 +1,40 @@
1
+ # Getting Started
2
+
3
+ Licensed's core workflow is a multi-step process:
4
+
5
+ 1. `licensed cache` ([docs](./commands/cache.md)) is run manually and/or in an automated workflow
6
+ - Creates or updates files in a git repo containing metadata including licenses and other legal text for each dependency used by a project
7
+ 1. `licensed status` ([docs](./commands/status.md)) is run manually and/or in an automated workflow
8
+ - Validate that every detected dependency has a metadata file written in the repository, and that each dependency's stored metadata passes a number of compliance checks
9
+ 1. Any detected errors/warnings are manually [resolved](./commands/status.md#status-errors-and-resolutions)
10
+ 1. Repeat the above steps until all dependencies have metadata files stored in the repository and `licensed status` is not reporting any errors.
11
+
12
+ ## Caching dependency metadata
13
+
14
+ Caching depedency metadata into the repository brings the metadata contents closer to the dependencies where they are used, making status validation faster and possible in offline scenarios. Keeping metadata alongside your code in git gives teams an easily auditable trail for dependency updates over time, and ties into common review practices to ensure that changes aren't quietly ignored.
15
+
16
+ Caching metadata should be done whenever project code changes, to ensure that metadata files are in sync with the current state of the project code.
17
+
18
+ ## Checking dependency metadata status
19
+
20
+ Dependency metadata checks verify that every dependency
21
+
22
+ - has a metadata file available, or has been explicitly ignored by the project owners or OSS experts
23
+ - is using an approved OSS license, or has been reviewed and signed off by an OSS expert
24
+ - is up to date with the current state of a project
25
+
26
+ Checking dependencies for compliance violations should be performed whenever code changes in a repository. Moving compliance checks inline in the development workflow reduces friction later, and can even prevent costly situations later if a non-compliant dependency would need to be removed from a project.
27
+
28
+ ## Automated workflows
29
+
30
+ Integrating github/licensed into your workflow can be tedious, and luckily there are a few automated tools available to make usage easier.
31
+
32
+ ### Bundler
33
+
34
+ The [bundler-licensed plugin](https://github.com/sergey-alekseev/bundler-licensed) runs `licensed cache` automatically when using `bundler`. See the linked repo for usage and details.
35
+
36
+ ### GitHub Actions
37
+
38
+ 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 to automatically update the cached metadata files and check their status. See the linked action for usage and details.
39
+
40
+ 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.
@@ -12,3 +12,12 @@ The default composer application file location is `<repository root>/composer.ph
12
12
  composer:
13
13
  application_path: "/path/to/composer"
14
14
  ```
15
+
16
+ ### Dev dependencies
17
+
18
+ By default licensed ignores all dev dependencies. To consider dev dependencies as well, use the `composer.include_dev` configuration setting.
19
+
20
+ ```yml
21
+ composer:
22
+ include_dev: true
23
+ ```
data/docs/sources/npm.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  The npm source will detect dependencies `package.json` is found at an apps `source_path`. It uses `npm list` to enumerate dependencies and metadata.
4
4
 
5
- ### Including development dependencies
5
+ ## Including development dependencies
6
6
 
7
7
  By default, the npm source will exclude all development dependencies. To include development or test dependencies, set `production_only: false` in the licensed configuration.
8
8
 
@@ -10,3 +10,13 @@ By default, the npm source will exclude all development dependencies. To include
10
10
  npm:
11
11
  production_only: false
12
12
  ```
13
+
14
+ ## Using licensed with npm workspaces
15
+
16
+ Licensed requires npm version 8.5.0 or later to enumerate dependencies inside of npm workspaces. For the best results, treat each workspace directory as a separate app `source_path`:
17
+
18
+ ```yml
19
+ apps:
20
+ - source_path: path/to/workspace/a
21
+ - source_path: path/to/workspace/b
22
+ ```
data/docs/sources/pip.md CHANGED
@@ -2,11 +2,6 @@
2
2
 
3
3
  The pip source uses `pip` CLI commands to enumerate dependencies and properties. It is expected that `pip` is available in the `virtual_env_dir` specific directory before running `licensed`.
4
4
 
5
- Your repository root should also contain a `requirements.txt` file which contains all the packages and dependences that are needed. You can generate one with `pip` using the command:
6
- ```
7
- pip freeze > requirements.txt
8
- ```
9
-
10
5
  A `virtualenv` directory is required before running `licensed`. You can setup a `virtualenv` by running the command:
11
6
  ```
12
7
  virtualenv <your_venv_dir>
@@ -82,15 +82,8 @@ module Licensed
82
82
  report["filename"] = filename.to_s
83
83
  report["version"] = dependency.version
84
84
 
85
- if options[:force] || save_dependency_record?(dependency, cached_record)
86
- if dependency.record.matches?(cached_record)
87
- # use the cached license value if the license text wasn't updated
88
- dependency.record["license"] = cached_record["license"]
89
- elsif cached_record && app.reviewed?(dependency.record)
90
- # if the license text changed and the dependency is set as reviewed
91
- # force a re-review of the dependency
92
- dependency.record["review_changed_license"] = true
93
- end
85
+ if save_dependency_record?(dependency, cached_record)
86
+ update_dependency_from_cached_record(app, dependency, cached_record)
94
87
 
95
88
  dependency.record.save(filename)
96
89
  report["cached"] = true
@@ -119,6 +112,7 @@ module Licensed
119
112
  # Returns true if dependency's record should be saved
120
113
  def save_dependency_record?(dependency, cached_record)
121
114
  return true if cached_record.nil?
115
+ return true if options[:force]
122
116
 
123
117
  cached_version = cached_record["version"]
124
118
  return true if cached_version.nil? || cached_version.empty?
@@ -126,6 +120,23 @@ module Licensed
126
120
  false
127
121
  end
128
122
 
123
+ # Update dependency metadata from the cached record, to support:
124
+ # 1. continuity between cache runs to cut down on churn
125
+ # 2. notifying users when changed content needs to be reviewed
126
+ def update_dependency_from_cached_record(app, dependency, cached_record)
127
+ return if cached_record.nil?
128
+ return if options[:force]
129
+
130
+ if dependency.record.matches?(cached_record)
131
+ # use the cached license value if the license text wasn't updated
132
+ dependency.record["license"] = cached_record["license"]
133
+ elsif app.reviewed?(dependency.record)
134
+ # if the license text changed and the dependency is set as reviewed
135
+ # force a re-review of the dependency
136
+ dependency.record["review_changed_license"] = true
137
+ end
138
+ end
139
+
129
140
  # Clean up cached files that dont match current dependencies
130
141
  #
131
142
  # Returns nothing
@@ -3,7 +3,7 @@ require "licensee"
3
3
 
4
4
  module Licensed
5
5
  class Dependency < Licensee::Projects::FSProject
6
- LEGAL_FILES_PATTERN = /(AUTHORS|NOTICE|LEGAL)(?:\..*)?\z/i
6
+ LEGAL_FILES_PATTERN = /#{File::SEPARATOR}(AUTHORS|NOTICE|LEGAL)(?:\..*)?\z/i
7
7
 
8
8
  attr_reader :name
9
9
  attr_reader :version
@@ -28,7 +28,10 @@ module Licensed
28
28
  end
29
29
 
30
30
  def packages
31
- JSON.parse(File.read(composer_lock))["packages"]
31
+ packages = JSON.parse(File.read(composer_lock))
32
+ return packages["packages"] unless include_dev?
33
+
34
+ packages["packages"] + packages["packages-dev"]
32
35
  end
33
36
 
34
37
  # Returns the output from running `php composer.phar` to get package metadata
@@ -56,6 +59,11 @@ module Licensed
56
59
  def composer_lock
57
60
  config.pwd.join("composer.lock")
58
61
  end
62
+
63
+ # Returns whether to include dev packages based on the licensed configuration settings
64
+ def include_dev?
65
+ config.dig("composer", "include_dev") == true
66
+ end
59
67
  end
60
68
  end
61
69
  end
@@ -24,11 +24,13 @@ module Licensed
24
24
  end
25
25
 
26
26
  def enabled?
27
- Licensed::Shell.tool_available?("npm") && File.exist?(config.pwd.join("package.json"))
27
+ Licensed::Shell.tool_available?("npm") && File.exist?(package_json_path)
28
28
  end
29
29
 
30
30
  def enumerate_dependencies
31
31
  packages.map do |name, package|
32
+ next if package["name"] == project_name
33
+
32
34
  errors = package["problems"] unless package["path"]
33
35
  Dependency.new(
34
36
  name: name,
@@ -159,6 +161,26 @@ module Licensed
159
161
  def extract_version(parent, name)
160
162
  parent&.dig("_dependencies", name) || peer_dependency(parent, name)
161
163
  end
164
+
165
+ # Returns the current projects name
166
+ def project_name
167
+ return unless package_json
168
+ package_json["name"]
169
+ end
170
+
171
+ ## Returns the parse package.json for the current project
172
+ def package_json
173
+ return unless File.exist?(package_json_path)
174
+
175
+ @package_json ||= JSON.parse(File.read(package_json_path))
176
+ rescue JSON::ParserError => e
177
+ message = "Licensed was unable to parse package.json. JSON Error: #{e.message}"
178
+ raise Licensed::Sources::Source::Error, message
179
+ end
180
+
181
+ def package_json_path
182
+ @package_json_path ||= File.join(config.pwd, "package.json")
183
+ end
162
184
  end
163
185
  end
164
186
  end
@@ -7,24 +7,20 @@ require "parallel"
7
7
  module Licensed
8
8
  module Sources
9
9
  class Pip < Source
10
- VERSION_OPERATORS = %w(< > <= >= == !=).freeze
11
- PACKAGE_REGEX = /^([\w\.-]+)(#{VERSION_OPERATORS.join("|")})?/
10
+ PACKAGE_INFO_SEPARATOR = "\n---\n"
12
11
 
13
12
  def enabled?
14
- return unless virtual_env_pip && Licensed::Shell.tool_available?(virtual_env_pip)
15
- File.exist?(config.pwd.join("requirements.txt"))
13
+ !pip_command.empty? && Licensed::Shell.tool_available?(pip_command.join(""))
16
14
  end
17
15
 
18
16
  def enumerate_dependencies
19
- Parallel.map(packages_from_requirements_txt, in_threads: Parallel.processor_count) do |package_name|
20
- package = package_info(package_name)
21
- location = File.join(package["Location"], package["Name"].gsub("-", "_") + "-" + package["Version"] + ".dist-info")
17
+ packages.map do |package|
22
18
  Dependency.new(
23
19
  name: package["Name"],
24
20
  version: package["Version"],
25
- path: location,
21
+ path: package_license_location(package),
26
22
  metadata: {
27
- "type" => Pip.type,
23
+ "type" => self.class.type,
28
24
  "summary" => package["Summary"],
29
25
  "homepage" => package["Home-page"]
30
26
  }
@@ -32,32 +28,63 @@ module Licensed
32
28
  end
33
29
  end
34
30
 
31
+ protected
32
+
33
+ # Returns the command to run pip
34
+ def pip_command
35
+ return [] unless virtual_env_dir
36
+ Array(File.join(virtual_env_dir, "bin", "pip"))
37
+ end
38
+
35
39
  private
36
40
 
37
- def packages_from_requirements_txt
38
- File.read(config.pwd.join("requirements.txt"))
39
- .lines
40
- .reject { |line| line.include?("://") }
41
- .map { |line| line.strip.match(PACKAGE_REGEX) { |match| match.captures.first } }
42
- .compact
41
+ # Returns the location of license files in the package, checking for the inclusion of a new `license_files`
42
+ # folder per https://peps.python.org/pep-0639/
43
+ def package_license_location(package)
44
+ dist_info = File.join(package["Location"], package["Name"].gsub("-", "_") + "-" + package["Version"] + ".dist-info")
45
+ license_files = File.join(dist_info, "license_files")
46
+ return File.exist?(license_files) ? license_files : dist_info
47
+ end
48
+
49
+ # Returns parsed information for all packages used by the project,
50
+ # using `pip list` to determine what packages are used and `pip show`
51
+ # to gather package information
52
+ def packages
53
+ all_packages = pip_show_command(package_names)
54
+ all_packages.split(PACKAGE_INFO_SEPARATOR).reduce([]) do |accum, val|
55
+ accum << parse_package_info(val)
56
+ end
57
+ end
58
+
59
+ # Returns the names of all of the packages used by the current project,
60
+ # as returned from `pip list`
61
+ def package_names
62
+ @package_names ||= begin
63
+ JSON.parse(pip_list_command).map { |package| package["name"] }
64
+ rescue JSON::ParserError => e
65
+ message = "Licensed was unable to parse the output from 'npm list'. JSON Error: #{e.message}"
66
+ raise Licensed::Sources::Source::Error, message
67
+ end
43
68
  end
44
69
 
45
- def package_info(package_name)
46
- p_info = pip_command(package_name).lines
47
- p_info.each_with_object(Hash.new(0)) { |pkg, a|
70
+ # Returns a hash filled with package info parsed from the email-header formatted output
71
+ # returned by `pip show`
72
+ def parse_package_info(package_info)
73
+ package_info.lines.each_with_object(Hash.new(0)) { |pkg, a|
48
74
  k, v = pkg.split(":", 2)
49
75
  next if k.nil? || k.empty?
50
76
  a[k.strip] = v&.strip
51
77
  }
52
78
  end
53
79
 
54
- def pip_command(*args)
55
- Licensed::Shell.execute(virtual_env_pip, "--disable-pip-version-check", "show", *args)
80
+ # Returns the output from `pip list --format=json`
81
+ def pip_list_command
82
+ Licensed::Shell.execute(*pip_command, "--disable-pip-version-check", "list", "--format=json")
56
83
  end
57
84
 
58
- def virtual_env_pip
59
- return unless virtual_env_dir
60
- File.join(virtual_env_dir, "bin", "pip")
85
+ # Returns the output from `pip show <package> <package> ...`
86
+ def pip_show_command(packages)
87
+ Licensed::Shell.execute(*pip_command, "--disable-pip-version-check", "show", *packages)
61
88
  end
62
89
 
63
90
  def virtual_env_dir
@@ -4,44 +4,16 @@ require "parallel"
4
4
 
5
5
  module Licensed
6
6
  module Sources
7
- class Pipenv < Source
7
+ class Pipenv < Pip
8
8
  def enabled?
9
9
  Licensed::Shell.tool_available?("pipenv") && File.exist?(config.pwd.join("Pipfile.lock"))
10
10
  end
11
11
 
12
- def enumerate_dependencies
13
- Parallel.map(pakages_from_pipfile_lock, in_threads: Parallel.processor_count) do |package_name|
14
- package = package_info(package_name)
15
- location = File.join(package["Location"], package["Name"].gsub("-", "_") + "-" + package["Version"] + ".dist-info")
16
- Dependency.new(
17
- name: package["Name"],
18
- version: package["Version"],
19
- path: location,
20
- metadata: {
21
- "type" => Pipenv.type,
22
- "summary" => package["Summary"],
23
- "homepage" => package["Home-page"]
24
- }
25
- )
26
- end
27
- end
28
-
29
- private
30
-
31
- def pakages_from_pipfile_lock
32
- Licensed::Shell.execute("pipenv", "run", "pip", "list")
33
- .lines
34
- .drop(2) # Header
35
- .map { |line| line.strip.split.first.strip }
36
- end
12
+ protected
37
13
 
38
- def package_info(package_name)
39
- p_info = Licensed::Shell.execute("pipenv", "run", "pip", "--disable-pip-version-check", "show", package_name).lines
40
- p_info.each_with_object(Hash.new(0)) { |pkg, a|
41
- k, v = pkg.split(":", 2)
42
- next if k.nil? || k.empty?
43
- a[k.strip] = v&.strip
44
- }
14
+ # Returns the command to run pip
15
+ def pip_command
16
+ %w(pipenv run pip)
45
17
  end
46
18
  end
47
19
  end
@@ -14,8 +14,13 @@ module Licensed
14
14
  class << self
15
15
  attr_reader :sources
16
16
  def inherited(klass)
17
- # add child source classes are defined,
18
- # add them to the known sources list
17
+ # register the inherited class as a source on the Licensed::Sources::Source class
18
+ Licensed::Sources::Source.register_source(klass)
19
+ end
20
+
21
+ def register_source(klass)
22
+ # add the source class to the known sources list
23
+ return unless klass < Licensed::Sources::Source
19
24
  (@sources ||= []) << klass
20
25
  end
21
26
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Licensed
3
- VERSION = "3.5.0".freeze
3
+ VERSION = "3.7.1".freeze
4
4
 
5
5
  def self.previous_major_versions
6
6
  major_version = Gem::Version.new(Licensed::VERSION).segments.first
data/licensed.gemspec CHANGED
@@ -35,7 +35,7 @@ Gem::Specification.new do |spec|
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", "< 1.20"
38
+ spec.add_development_dependency "rubocop", "~> 1.26", "< 1.27"
39
39
  spec.add_development_dependency "rubocop-github", "~> 0.6"
40
- spec.add_development_dependency "byebug", "~> 11.0.1"
40
+ spec.add_development_dependency "byebug", "~> 11.1.3"
41
41
  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: 3.5.0
4
+ version: 3.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-02-24 00:00:00.000000000 Z
11
+ date: 2022-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: licensee
@@ -188,20 +188,20 @@ dependencies:
188
188
  requirements:
189
189
  - - "~>"
190
190
  - !ruby/object:Gem::Version
191
- version: '0.49'
191
+ version: '1.26'
192
192
  - - "<"
193
193
  - !ruby/object:Gem::Version
194
- version: '1.20'
194
+ version: '1.27'
195
195
  type: :development
196
196
  prerelease: false
197
197
  version_requirements: !ruby/object:Gem::Requirement
198
198
  requirements:
199
199
  - - "~>"
200
200
  - !ruby/object:Gem::Version
201
- version: '0.49'
201
+ version: '1.26'
202
202
  - - "<"
203
203
  - !ruby/object:Gem::Version
204
- version: '1.20'
204
+ version: '1.27'
205
205
  - !ruby/object:Gem::Dependency
206
206
  name: rubocop-github
207
207
  requirement: !ruby/object:Gem::Requirement
@@ -222,14 +222,14 @@ dependencies:
222
222
  requirements:
223
223
  - - "~>"
224
224
  - !ruby/object:Gem::Version
225
- version: 11.0.1
225
+ version: 11.1.3
226
226
  type: :development
227
227
  prerelease: false
228
228
  version_requirements: !ruby/object:Gem::Requirement
229
229
  requirements:
230
230
  - - "~>"
231
231
  - !ruby/object:Gem::Version
232
- version: 11.0.1
232
+ version: 11.1.3
233
233
  description: Licensed automates extracting and validating the licenses of dependencies.
234
234
  email:
235
235
  - opensource+licensed@github.com
@@ -266,6 +266,7 @@ files:
266
266
  - docs/configuration/ignoring_dependencies.md
267
267
  - docs/configuration/metadata_cache.md
268
268
  - docs/configuration/reviewing_dependencies.md
269
+ - docs/getting_started.md
269
270
  - docs/migrations/v2.md
270
271
  - docs/migrations/v3.md
271
272
  - docs/packaging.md