package-audit 0.8.1 → 0.8.2
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 +4 -4
- data/LICENSE.txt +21 -0
- data/README.md +218 -0
- data/docs/example.png +0 -0
- data/lib/package/audit/const/cmd.rb +0 -4
- data/lib/package/audit/npm/vulnerability_finder.rb +129 -30
- data/lib/package/audit/ruby/gem_meta_data.rb +2 -2
- data/lib/package/audit/services/command_parser.rb +1 -1
- data/lib/package/audit/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7e0d76f96e0ad7b87f59b178565e72e9d52dddf9f7a579e016ff6779fac6d58a
|
|
4
|
+
data.tar.gz: cb917258a2025355d73123cb76762254dd92bdac817c72375e4297fbe8cb6b8f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 280d5c3c95dd19ff526723fb7b9c5b387180c63a67d64eab8be9301512c9b3f5d4e252ba1e82317fb5b95e6f86380908344ea766de9ad4539fecd20afeadd3d7
|
|
7
|
+
data.tar.gz: '09f40855f0197f00fa9fc05826da2ec42506fef23d387569dd108e4623488eb059982e47d7b0bb99f718de6e62140db3817b119b90aea473cc837a7ad2038b60'
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Vadim Kononov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Package::Audit
|
|
2
|
+
|
|
3
|
+
[](https://rubygems.org/gems/package-audit)
|
|
4
|
+
[](https://github.com/vkononov/package-audit/blob/main/.github/workflows/test.yml)
|
|
5
|
+
[](https://github.com/vkononov/package-audit/actions/workflows/test.yml)
|
|
6
|
+
[](https://github.com/vkononov/package-audit/actions/workflows/lint.yml)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
|
|
9
|
+
A useful tool for patch management and prioritization, `package-audit` produces a list of dependencies that are outdated, deprecated or have security vulnerabilities.
|
|
10
|
+
|
|
11
|
+
Supports **Ruby 2.6 → latest**, with the full Ruby matrix tested daily in CI.
|
|
12
|
+
|
|
13
|
+
[](https://www.buymeacoffee.com/vkononov)
|
|
14
|
+
|
|
15
|
+
## Supported Technologies
|
|
16
|
+
|
|
17
|
+
* Ruby
|
|
18
|
+
* Node (using Yarn)
|
|
19
|
+
|
|
20
|
+
## Report Example
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
### Understanding the Flags Column
|
|
25
|
+
|
|
26
|
+
The Flags column shows which risk types apply to each package:
|
|
27
|
+
|
|
28
|
+
- `⦗V··⦘` - Vulnerable (has security vulnerabilities)
|
|
29
|
+
- `⦗·O·⦘` - Outdated (newer version available)
|
|
30
|
+
- `⦗··D⦘` - Deprecated (no updates in 2+ years)
|
|
31
|
+
- `⦗VO·⦘` - Both vulnerable and outdated
|
|
32
|
+
- `⦗VOD⦘` - All three risk types apply
|
|
33
|
+
|
|
34
|
+
The footer uses the same notation (⦗V⦘ulnerable, ⦗O⦘utdated, ⦗D⦘eprecated) as a legend.
|
|
35
|
+
|
|
36
|
+
## Continuous Integration
|
|
37
|
+
|
|
38
|
+
This gem provides a return code of `0` to indicate success and `1` to indicate failure. It is specifically designed for seamless integration into continuous integration pipelines.
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
Add this line to your application's Gemfile:
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
gem 'package-audit', require: false
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
And then execute:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
bundle
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Or install it yourself as:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
gem install package-audit
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Usage
|
|
61
|
+
|
|
62
|
+
### Basic Report
|
|
63
|
+
|
|
64
|
+
Run a full audit (`DIR` defaults to current directory):
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
package-audit [DIR]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Filtering by Risk Type
|
|
71
|
+
|
|
72
|
+
Show only specific risk types:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# Show only deprecated packages
|
|
76
|
+
package-audit [DIR] --deprecated
|
|
77
|
+
|
|
78
|
+
# Show only vulnerable packages
|
|
79
|
+
package-audit [DIR] --vulnerable
|
|
80
|
+
|
|
81
|
+
# Show packages that are deprecated and/or vulnerable
|
|
82
|
+
package-audit [DIR] --deprecated --vulnerable
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Excluding Risk Types
|
|
86
|
+
|
|
87
|
+
Exclude specific risk types from the report:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Show everything except deprecated packages
|
|
91
|
+
package-audit [DIR] --skip-deprecated
|
|
92
|
+
|
|
93
|
+
# Show everything except outdated packages
|
|
94
|
+
package-audit [DIR] --skip-outdated
|
|
95
|
+
|
|
96
|
+
# Show only vulnerable packages (exclude deprecated and outdated)
|
|
97
|
+
package-audit [DIR] --skip-deprecated --skip-outdated
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Important:** Packages with multiple risk types are handled intelligently. For example, a package that is both outdated and vulnerable will still appear when using `--skip-outdated` because it has a vulnerability.
|
|
101
|
+
|
|
102
|
+
### Understanding the Flags Column
|
|
103
|
+
|
|
104
|
+
The Flags column in the output shows which risk types apply to each package:
|
|
105
|
+
|
|
106
|
+
- `⦗V··⦘` - Vulnerable (has security vulnerabilities)
|
|
107
|
+
- `⦗·O·⦘` - Outdated (newer version available)
|
|
108
|
+
- `⦗··D⦘` - Deprecated (no updates in 2+ years)
|
|
109
|
+
- `⦗VO·⦘` - Both vulnerable and outdated
|
|
110
|
+
- `⦗VOD⦘` - All three risk types apply
|
|
111
|
+
|
|
112
|
+
The footer uses the same notation `⦗V⦘ulnerable, ⦗O⦘utdated, ⦗D⦘eprecated` as a legend.
|
|
113
|
+
|
|
114
|
+
### Scoping Options
|
|
115
|
+
|
|
116
|
+
Filter by technology or group:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# Specific technologies
|
|
120
|
+
package-audit [DIR] -t node -t ruby
|
|
121
|
+
package-audit [DIR] --technology node --technology ruby
|
|
122
|
+
|
|
123
|
+
# Specific groups
|
|
124
|
+
package-audit [DIR] -g staging -g production
|
|
125
|
+
package-audit [DIR] --group staging --group production
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Note:** `Package::Audit` will attempt to automatically detect the technologies used by the project.
|
|
129
|
+
|
|
130
|
+
### Configuration
|
|
131
|
+
|
|
132
|
+
Use a custom configuration file (see [Configuration File](#configuration-file) for details):
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
package-audit [DIR] --config .package-audit.yml
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Include packages normally ignored by configuration:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
package-audit [DIR] --include-ignored
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Output Formats
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# CSV format
|
|
148
|
+
package-audit [DIR] --format csv
|
|
149
|
+
|
|
150
|
+
# Markdown format
|
|
151
|
+
package-audit [DIR] --format md
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Other Commands
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Show how risk is calculated
|
|
158
|
+
package-audit risk
|
|
159
|
+
|
|
160
|
+
# Show version
|
|
161
|
+
package-audit version
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Getting Help
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
package-audit help
|
|
168
|
+
package-audit help [COMMAND]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Configuration File
|
|
172
|
+
|
|
173
|
+
The `package-audit` gem automatically searches for `.package-audit.yml` in the current directory or in the specified `DIR` if available. However, you have the option to override the default configuration file location by using the `--config` (or `-c`) flag.
|
|
174
|
+
|
|
175
|
+
#### Below is an example of a configuration file:
|
|
176
|
+
|
|
177
|
+
```YAML
|
|
178
|
+
technology:
|
|
179
|
+
node:
|
|
180
|
+
nth-check:
|
|
181
|
+
version: 1.0.2
|
|
182
|
+
vulnerable: false
|
|
183
|
+
ruby:
|
|
184
|
+
devise-async:
|
|
185
|
+
version: 1.0.0
|
|
186
|
+
deprecated: false
|
|
187
|
+
puma:
|
|
188
|
+
version: 6.3.0
|
|
189
|
+
deprecated: false
|
|
190
|
+
selenium-webdriver:
|
|
191
|
+
version: 4.1.0
|
|
192
|
+
outdated: false
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
#### This configuration file allows you to specify the following exclusions:
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
* Ignore all security vulnerabilities associated with `nth-check@1.0.2`.
|
|
199
|
+
* Suppress messages regarding potential deprecations for `device-async@1.0.0` and `puma@6.3.0`.
|
|
200
|
+
* Disable warnings about newer available versions of `selenium-webdriver@4.1.0`
|
|
201
|
+
|
|
202
|
+
**Note:** If the installed package version differs from the expected package version specified in the configuration file, the exclusion settings will not apply to that particular package.
|
|
203
|
+
|
|
204
|
+
**Note:** If a package is reported for multiple reasons (e.g. vulnerable and outdated), it will still be reported unless the exclusion criteria match every reason for being on the report.
|
|
205
|
+
|
|
206
|
+
> By design, wildcard (`*`) version exclusions are not supported to prevent developers from inadvertently overlooking crucial messages when packages are updated.
|
|
207
|
+
|
|
208
|
+
## Contributing
|
|
209
|
+
|
|
210
|
+
1. Fork it
|
|
211
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
212
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
213
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
214
|
+
5. Create new Pull Request
|
|
215
|
+
|
|
216
|
+
## License
|
|
217
|
+
|
|
218
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/docs/example.png
ADDED
|
Binary file
|
|
@@ -6,10 +6,6 @@ module Package
|
|
|
6
6
|
BUNDLE_AUDIT_JSON = 'bundle-audit check --update --quiet --format json "%s" 2>/dev/null'
|
|
7
7
|
|
|
8
8
|
NPM_AUDIT = 'npm audit'
|
|
9
|
-
NPM_AUDIT_JSON = 'npm audit --json'
|
|
10
|
-
|
|
11
|
-
YARN_AUDIT = 'yarn audit'
|
|
12
|
-
YARN_AUDIT_JSON = 'yarn audit --json --cwd "%s"'
|
|
13
9
|
end
|
|
14
10
|
end
|
|
15
11
|
end
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
require 'openssl'
|
|
2
4
|
|
|
3
|
-
require_relative '../const/
|
|
5
|
+
require_relative '../const/file'
|
|
4
6
|
require_relative '../enum/vulnerability_type'
|
|
5
7
|
|
|
6
8
|
module Package
|
|
7
9
|
module Audit
|
|
8
10
|
module Npm
|
|
9
|
-
class VulnerabilityFinder
|
|
10
|
-
|
|
11
|
+
class VulnerabilityFinder # rubocop:disable Metrics/ClassLength
|
|
12
|
+
BULK_ADVISORY_URL = 'https://registry.npmjs.org/-/npm/v1/security/advisories/bulk'
|
|
13
|
+
BATCH_SIZE = 100
|
|
14
|
+
TIMEOUT = 30
|
|
15
|
+
VERSION_LINE = /^\s+"?version"?\s+"([^"]+)"/
|
|
11
16
|
|
|
12
17
|
def initialize(dir, pkgs)
|
|
13
18
|
@dir = dir
|
|
@@ -16,48 +21,142 @@ module Package
|
|
|
16
21
|
end
|
|
17
22
|
|
|
18
23
|
def run
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
env_vars = { 'NODE_NO_WARNINGS' => '1' }
|
|
24
|
+
versions_by_name = collect_versions_by_name
|
|
25
|
+
return [] if versions_by_name.empty?
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
versions_by_name.each_slice(BATCH_SIZE) do |batch|
|
|
28
|
+
batch_versions = batch.to_h
|
|
29
|
+
fetch_advisories(batch_versions).each do |name, advisories|
|
|
30
|
+
package_name = name.to_s
|
|
31
|
+
apply_advisories(package_name, Array(advisories), batch_versions[package_name] || [])
|
|
32
|
+
end
|
|
29
33
|
end
|
|
34
|
+
|
|
30
35
|
@vuln_hash.values
|
|
31
36
|
end
|
|
32
37
|
|
|
33
38
|
private
|
|
34
39
|
|
|
35
|
-
def
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
def collect_versions_by_name
|
|
41
|
+
versions_by_name = {}
|
|
42
|
+
|
|
43
|
+
(lockfile_packages + @pkg_hash.values.map { |pkg| [pkg.name, pkg.version] }).each do |name, version|
|
|
44
|
+
next if version.to_s.empty? || version == 'unknown'
|
|
45
|
+
|
|
46
|
+
versions = versions_by_name[name] ||= []
|
|
47
|
+
versions << version unless versions.include?(version)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
versions_by_name
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def lockfile_packages
|
|
54
|
+
path = "#{@dir}/#{Const::File::YARN_LOCK}"
|
|
55
|
+
return [] unless File.exist?(path)
|
|
56
|
+
|
|
57
|
+
packages = []
|
|
58
|
+
current_names = []
|
|
59
|
+
File.foreach(path) do |line|
|
|
60
|
+
current_names, packages = process_lockfile_line(line, current_names, packages)
|
|
61
|
+
end
|
|
62
|
+
packages
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def process_lockfile_line(line, current_names, packages)
|
|
66
|
+
if lockfile_key_line?(line)
|
|
67
|
+
[package_names_from_lock_key(line.strip.chomp(':')), packages]
|
|
68
|
+
elsif (match = line.match(VERSION_LINE))
|
|
69
|
+
match_version = match[1]
|
|
70
|
+
current_names.each { |name| packages << [name, match_version] }
|
|
71
|
+
[[], packages]
|
|
72
|
+
else
|
|
73
|
+
[current_names, packages]
|
|
74
|
+
end
|
|
75
|
+
end
|
|
38
76
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
package_info = extract_package_info(advisory)
|
|
42
|
-
update_vulnerability_info(package_info, parent_name, advisory[:severity])
|
|
77
|
+
def lockfile_key_line?(line)
|
|
78
|
+
line.match?(/^\S/) && line.include?('@') && line.strip.end_with?(':')
|
|
43
79
|
end
|
|
44
80
|
|
|
45
|
-
def
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
81
|
+
def package_names_from_lock_key(key)
|
|
82
|
+
key.split(',').map do |entry|
|
|
83
|
+
package_name_from_spec(entry.strip.gsub(/\A["']|["']\z/, ''))
|
|
84
|
+
end.uniq
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def package_name_from_spec(spec)
|
|
88
|
+
if spec.start_with?('@')
|
|
89
|
+
"@#{spec.split('@', 3)[1]}"
|
|
90
|
+
else
|
|
91
|
+
spec.split('@', 2).first
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def fetch_advisories(versions_by_name)
|
|
96
|
+
uri = URI(BULK_ADVISORY_URL)
|
|
97
|
+
response = make_request(uri, versions_by_name.to_json)
|
|
98
|
+
unless response.is_a?(Net::HTTPSuccess)
|
|
99
|
+
warn "Warning: Unable to fetch npm advisories (#{response.code} #{response.message})."
|
|
100
|
+
return {}
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
JSON.parse(response.body)
|
|
104
|
+
rescue StandardError => e
|
|
105
|
+
warn "Warning: Error while fetching npm advisories: #{e.message}"
|
|
106
|
+
{}
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def make_request(uri, body)
|
|
110
|
+
request = Net::HTTP::Post.new(uri)
|
|
111
|
+
request['Content-Type'] = 'application/json'
|
|
112
|
+
request['Accept'] = 'application/json'
|
|
113
|
+
request.body = body
|
|
114
|
+
create_http_client(uri).request(request)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def create_http_client(uri)
|
|
118
|
+
Net::HTTP.new(uri.host, uri.port).tap do |http|
|
|
119
|
+
http.use_ssl = true
|
|
120
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
121
|
+
http.cert_store = OpenSSL::X509::Store.new
|
|
122
|
+
http.cert_store.set_default_paths
|
|
123
|
+
http.read_timeout = TIMEOUT
|
|
124
|
+
http.open_timeout = TIMEOUT
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def apply_advisories(name, advisories, versions)
|
|
129
|
+
advisories.each do |advisory|
|
|
130
|
+
Array(versions).each do |version|
|
|
131
|
+
next unless version_matches?(version, advisory['vulnerable_versions'])
|
|
132
|
+
|
|
133
|
+
update_vulnerability_info(name, version, advisory['severity'])
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def version_matches?(version, vulnerable_versions)
|
|
139
|
+
return true if vulnerable_versions.nil? || vulnerable_versions.empty?
|
|
140
|
+
|
|
141
|
+
vulnerable_versions.split(/\s*\|\|\s*/).any? do |range|
|
|
142
|
+
requirements = range.split(/\s+/).reject(&:empty?)
|
|
143
|
+
next true if requirements.empty?
|
|
144
|
+
|
|
145
|
+
Gem::Requirement.new(*requirements).satisfied_by?(Gem::Version.new(version))
|
|
146
|
+
rescue ArgumentError
|
|
147
|
+
true
|
|
148
|
+
end
|
|
50
149
|
end
|
|
51
150
|
|
|
52
|
-
def update_vulnerability_info(
|
|
53
|
-
name = package_info[:name]
|
|
54
|
-
version = package_info[:version]
|
|
151
|
+
def update_vulnerability_info(name, version, severity)
|
|
55
152
|
full_name = "#{name}@#{version}"
|
|
56
153
|
vulnerability = severity || Enum::VulnerabilityType::UNKNOWN
|
|
57
154
|
|
|
58
155
|
@vuln_hash[full_name] ||= Package.new(name, version, 'node')
|
|
59
|
-
@vuln_hash[full_name].update
|
|
60
|
-
|
|
156
|
+
@vuln_hash[full_name].update(
|
|
157
|
+
vulnerabilities: @vuln_hash[full_name].vulnerabilities + [vulnerability],
|
|
158
|
+
groups: @pkg_hash[name]&.groups&.map(&:to_s) || []
|
|
159
|
+
)
|
|
61
160
|
end
|
|
62
161
|
end
|
|
63
162
|
end
|
|
@@ -226,8 +226,8 @@ module Package
|
|
|
226
226
|
|
|
227
227
|
def parse_version_dates(response_body)
|
|
228
228
|
versions = JSON.parse(response_body)
|
|
229
|
-
versions.
|
|
230
|
-
|
|
229
|
+
versions.to_h do |version_info|
|
|
230
|
+
[version_info['number'], version_info['created_at']]
|
|
231
231
|
end
|
|
232
232
|
end
|
|
233
233
|
|
|
@@ -140,7 +140,7 @@ module Package
|
|
|
140
140
|
when Enum::Technology::RUBY
|
|
141
141
|
Const::Cmd::BUNDLE_AUDIT
|
|
142
142
|
when Enum::Technology::NODE
|
|
143
|
-
Const::Cmd::
|
|
143
|
+
Const::Cmd::NPM_AUDIT
|
|
144
144
|
else
|
|
145
145
|
raise ArgumentError, "Unexpected technology \"#{technology}\" found in #{__method__}"
|
|
146
146
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: package-audit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vadim Kononov
|
|
@@ -46,6 +46,9 @@ executables:
|
|
|
46
46
|
extensions: []
|
|
47
47
|
extra_rdoc_files: []
|
|
48
48
|
files:
|
|
49
|
+
- LICENSE.txt
|
|
50
|
+
- README.md
|
|
51
|
+
- docs/example.png
|
|
49
52
|
- exe/package-audit
|
|
50
53
|
- lib/package/audit/cli.rb
|
|
51
54
|
- lib/package/audit/const/cmd.rb
|
|
@@ -111,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
111
114
|
- !ruby/object:Gem::Version
|
|
112
115
|
version: '0'
|
|
113
116
|
requirements: []
|
|
114
|
-
rubygems_version:
|
|
117
|
+
rubygems_version: 4.0.10
|
|
115
118
|
specification_version: 4
|
|
116
119
|
summary: A helper tool to find outdated, deprecated and vulnerable dependencies.
|
|
117
120
|
test_files: []
|