gem_guard 1.2.2 → 1.2.5
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/README.md +29 -10
- data/lib/gem_guard/auto_fixer.rb +12 -3
- data/lib/gem_guard/cli.rb +33 -0
- data/lib/gem_guard/config.rb +1 -1
- data/lib/gem_guard/parser.rb +1 -1
- data/lib/gem_guard/reporter.rb +15 -22
- data/lib/gem_guard/version.rb +1 -1
- data/lib/gem_guard/vulnerability_fetcher.rb +111 -0
- metadata +48 -4
- data/gem_guard.gemspec +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87a59fb2fa654c13d509d6736a43c423713eb7419966b85860217839e6e5bf98
|
4
|
+
data.tar.gz: dff5ce7cd3e7d3471a8509a3e194ab722c98beef4d413429075dcaa03d3ef4f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c9414ccc305fd9049dbe5da0d6da8a51f61de59f604e864d0d7d66ad09cced58925984f603af1a3e80de7fb616f6c59ace614354c13a57a1f5c47994d9445de
|
7
|
+
data.tar.gz: 9f603299ce272eea65380e9fa3334b4980e0564a027de8599683ca73bb3a2b453e02f55aab6fad3aa5ddd823de24b0d1c5d51ecd1103b15f5772fca48ec942d7
|
data/README.md
CHANGED
@@ -13,7 +13,7 @@ GemGuard is your one-stop solution for Ruby supply chain security. Detect vulner
|
|
13
13
|
## ✨ Features
|
14
14
|
|
15
15
|
### 🔍 **Vulnerability Scanning**
|
16
|
-
- Detect known CVEs from OSV.dev and
|
16
|
+
- Detect known CVEs from OSV.dev, Ruby Advisory Database, GitHub Security Advisories (GHSA), National Vulnerability Database (NVD), and Curesec Advisory Database
|
17
17
|
- Smart deduplication handles platform-specific gems
|
18
18
|
- Severity-based filtering and thresholds
|
19
19
|
- Actionable fix recommendations with exact commands
|
@@ -132,7 +132,7 @@ Use `fix` to apply recommended upgrades. Start with a dry run to preview changes
|
|
132
132
|
# Preview only — shows what would change, does not modify files
|
133
133
|
gem_guard fix --dry-run
|
134
134
|
|
135
|
-
# Interactively
|
135
|
+
# Interactively select which upgrades to apply
|
136
136
|
gem_guard fix --interactive
|
137
137
|
|
138
138
|
# Apply fixes non-interactively
|
@@ -152,12 +152,20 @@ Run without --dry-run to apply these fixes.
|
|
152
152
|
|
153
153
|
Behavior notes:
|
154
154
|
|
155
|
-
- **Interactive**: You’ll be
|
155
|
+
- **Interactive**: You’ll be presented with a multi-select prompt to choose which fixes to apply.
|
156
156
|
- **Backups**: A `Gemfile.lock.backup.YYYYMMDD_HHMMSS` is created only if at least one fix is approved/applied.
|
157
157
|
- **Requirements**: `Gemfile` and `Gemfile.lock` must exist. Interactive prompts require a TTY-capable environment.
|
158
158
|
|
159
159
|
> Exit codes: 0 = success, 2 = error. See [Exit Codes](#exit-codes). Use `--verbose` for diagnostics if a file/permission error occurs.
|
160
160
|
|
161
|
+
### Interactive mode
|
162
|
+
|
163
|
+
For a more streamlined experience, use the `interactive` command. This command will first scan for vulnerabilities, display the results, and then ask if you want to enter the interactive fixing mode.
|
164
|
+
|
165
|
+
```bash
|
166
|
+
gem_guard interactive
|
167
|
+
```
|
168
|
+
|
161
169
|
### 🎯 Typosquat Detection
|
162
170
|
|
163
171
|
**Basic typosquat check:**
|
@@ -245,6 +253,13 @@ typosquat:
|
|
245
253
|
sbom:
|
246
254
|
format: "spdx" # spdx, cyclone-dx
|
247
255
|
project_name: "my-project"
|
256
|
+
scan:
|
257
|
+
sources:
|
258
|
+
- "osv"
|
259
|
+
- "ruby_advisory_db"
|
260
|
+
- "ghsa"
|
261
|
+
- "nvd"
|
262
|
+
- "cu_advisory_db"
|
248
263
|
```
|
249
264
|
|
250
265
|
### Configuration Options
|
@@ -261,6 +276,7 @@ sbom:
|
|
261
276
|
| `typosquat.enabled` | Enable typosquat detection | `true` |
|
262
277
|
| `sbom.format` | SBOM format (spdx/cyclone-dx) | `"spdx"` |
|
263
278
|
| `sbom.project_name` | Project name in SBOM | `"ruby-project"` |
|
279
|
+
| `scan.sources` | Vulnerability sources to check | `["osv", "ruby_advisory_db", "ghsa", "nvd", "cu_advisory_db"]` |
|
264
280
|
|
265
281
|
## 🔄 CI/CD Integration
|
266
282
|
|
@@ -287,19 +303,19 @@ jobs:
|
|
287
303
|
with:
|
288
304
|
ruby-version: '3.2'
|
289
305
|
bundler-cache: true
|
290
|
-
|
306
|
+
|
291
307
|
- name: Install GemGuard
|
292
308
|
run: gem install gem_guard
|
293
|
-
|
309
|
+
|
294
310
|
- name: Vulnerability Scan
|
295
311
|
run: gem_guard scan --format json --output vulnerabilities.json
|
296
|
-
|
312
|
+
|
297
313
|
- name: Typosquat Check
|
298
314
|
run: gem_guard typosquat --format json --output typosquats.json
|
299
|
-
|
315
|
+
|
300
316
|
- name: Generate SBOM
|
301
317
|
run: gem_guard sbom --output sbom.json
|
302
|
-
|
318
|
+
|
303
319
|
- name: Upload Security Reports
|
304
320
|
uses: actions/upload-artifact@v4
|
305
321
|
if: always()
|
@@ -454,7 +470,7 @@ We welcome contributions! Here's how you can help:
|
|
454
470
|
|
455
471
|
## 📊 Roadmap
|
456
472
|
|
457
|
-
- [
|
473
|
+
- [x] **Enhanced Vulnerability Sources**: Additional security databases
|
458
474
|
- [ ] **Auto-Fix Suggestions**: Automated dependency updates
|
459
475
|
- [ ] **Web Dashboard**: Browser-based security monitoring
|
460
476
|
- [ ] **IDE Integrations**: VS Code, RubyMine plugins
|
@@ -465,7 +481,7 @@ We welcome contributions! Here's how you can help:
|
|
465
481
|
|
466
482
|
| Feature | GemGuard | bundler-audit | Other Tools |
|
467
483
|
|---------|----------|---------------|-------------|
|
468
|
-
| **Vulnerability Scanning** | ✅ OSV.dev + Ruby Advisory | ✅ Ruby Advisory Only | ❌ Limited Sources |
|
484
|
+
| **Vulnerability Scanning** | ✅ OSV.dev + Ruby Advisory + GHSA + NVD + CU Advisories | ✅ Ruby Advisory Only | ❌ Limited Sources |
|
469
485
|
| **Typosquat Detection** | ✅ Fuzzy Matching | ❌ | ❌ |
|
470
486
|
| **SBOM Generation** | ✅ SPDX + CycloneDX | ❌ | ❌ |
|
471
487
|
| **CI/CD Integration** | ✅ Full Support | ⚠️ Basic | ⚠️ Limited |
|
@@ -486,6 +502,9 @@ If you discover a security vulnerability within GemGuard, please see our [Securi
|
|
486
502
|
|
487
503
|
- [OSV.dev](https://osv.dev/) for comprehensive vulnerability data
|
488
504
|
- [Ruby Advisory Database](https://github.com/rubysec/ruby-advisory-db) for Ruby-specific advisories
|
505
|
+
- [GitHub Security Advisories](https://github.com/advisories) for GHSA data
|
506
|
+
- [National Vulnerability Database](https://nvd.nist.gov/) for NVD data
|
507
|
+
- [Curesec Advisory Database](https://github.com/curesec/curesec-advisory-db) for additional security advisories
|
489
508
|
- The Ruby community for continuous feedback and contributions
|
490
509
|
|
491
510
|
---
|
data/lib/gem_guard/auto_fixer.rb
CHANGED
@@ -128,10 +128,19 @@ module GemGuard
|
|
128
128
|
# Determine which fixes to apply
|
129
129
|
selected_fixes = if interactive
|
130
130
|
prompt = TTY::Prompt.new
|
131
|
-
fixes.
|
132
|
-
|
133
|
-
|
131
|
+
choices = fixes.map do |fix|
|
132
|
+
{
|
133
|
+
name: "#{severity_emoji(fix[:severity])} #{fix[:gem_name]}: #{fix[:current_version]} → #{fix[:target_version]} (Vulnerability: #{fix[:vulnerability_id]}, Severity: #{fix[:severity]})",
|
134
|
+
value: fix
|
135
|
+
}
|
136
|
+
end
|
137
|
+
|
138
|
+
if choices.empty?
|
139
|
+
puts "No actionable fixes found."
|
140
|
+
return [], false
|
134
141
|
end
|
142
|
+
|
143
|
+
prompt.multi_select("Select vulnerabilities to fix:", choices, per_page: 15, cycle: true)
|
135
144
|
else
|
136
145
|
fixes
|
137
146
|
end
|
data/lib/gem_guard/cli.rb
CHANGED
@@ -11,6 +11,10 @@ module GemGuard
|
|
11
11
|
# Global options
|
12
12
|
class_option :verbose, type: :boolean, desc: "Print extra diagnostics on errors"
|
13
13
|
|
14
|
+
def self.exit_on_failure?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
14
18
|
desc "scan", "Scan dependencies for known vulnerabilities"
|
15
19
|
option :format, type: :string, desc: "Output format (table, json)"
|
16
20
|
option :lockfile, type: :string, desc: "Path to Gemfile.lock"
|
@@ -306,6 +310,35 @@ module GemGuard
|
|
306
310
|
puts GemGuard::VERSION
|
307
311
|
end
|
308
312
|
|
313
|
+
desc "interactive", "Interactively scan and fix vulnerabilities"
|
314
|
+
option :lockfile, type: :string, desc: "Path to Gemfile.lock"
|
315
|
+
option :gemfile, type: :string, desc: "Path to Gemfile"
|
316
|
+
option :config, type: :string, desc: "Config file path"
|
317
|
+
def interactive
|
318
|
+
config = Config.new(options[:config] || ".gemguard.yml")
|
319
|
+
lockfile_path = options[:lockfile] || config.lockfile_path
|
320
|
+
|
321
|
+
# 1. Scan for vulnerabilities
|
322
|
+
puts "Scanning for vulnerabilities..."
|
323
|
+
dependencies = Parser.new.parse(lockfile_path)
|
324
|
+
vulnerabilities = VulnerabilityFetcher.new.fetch_for(dependencies)
|
325
|
+
analysis = Analyzer.new.analyze(dependencies, vulnerabilities)
|
326
|
+
|
327
|
+
if analysis.vulnerable_dependencies.empty?
|
328
|
+
puts "✅ No vulnerabilities found."
|
329
|
+
exit EXIT_SUCCESS
|
330
|
+
end
|
331
|
+
|
332
|
+
# 2. Report vulnerabilities
|
333
|
+
Reporter.new.report(analysis, format: "table")
|
334
|
+
|
335
|
+
# 3. Ask to fix
|
336
|
+
prompt = TTY::Prompt.new
|
337
|
+
if prompt.yes?("\nWould you like to fix these vulnerabilities interactively?")
|
338
|
+
invoke :fix, [], options.slice("lockfile", "gemfile", "config").merge(interactive: true)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
309
342
|
private
|
310
343
|
|
311
344
|
def filter_vulnerabilities(vulnerabilities, config)
|
data/lib/gem_guard/config.rb
CHANGED
data/lib/gem_guard/parser.rb
CHANGED
@@ -66,7 +66,7 @@ module GemGuard
|
|
66
66
|
# remove optional version tuple e.g., rails, or rails(=7.0.0) case without space
|
67
67
|
name = name.split("(").first
|
68
68
|
|
69
|
-
unless spec_names.include?(name)
|
69
|
+
unless spec_names.include?(name) || name == "bundler"
|
70
70
|
raise GemGuard::InvalidLockfileError, "Invalid Gemfile.lock at #{lockfile_path}: dependency '#{name}' not found in specs"
|
71
71
|
end
|
72
72
|
|
data/lib/gem_guard/reporter.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "json"
|
2
|
+
require "tty-table"
|
2
3
|
|
3
4
|
module GemGuard
|
4
5
|
class Reporter
|
@@ -18,30 +19,22 @@ module GemGuard
|
|
18
19
|
def generate_table_report(analysis)
|
19
20
|
return "✅ No vulnerabilities found!" unless analysis.has_vulnerabilities?
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
dep = vuln_dep.dependency
|
34
|
-
vuln = vuln_dep.vulnerability
|
22
|
+
table = TTY::Table.new(
|
23
|
+
header: ["Gem", "Version", "Vulnerability", "Severity", "Fix"],
|
24
|
+
rows: analysis.vulnerable_dependencies.map do |vuln_dep|
|
25
|
+
[
|
26
|
+
vuln_dep.dependency.name,
|
27
|
+
vuln_dep.dependency.version,
|
28
|
+
vuln_dep.vulnerability.id,
|
29
|
+
vuln_dep.vulnerability.severity,
|
30
|
+
vuln_dep.recommended_fix
|
31
|
+
]
|
32
|
+
end
|
33
|
+
)
|
35
34
|
|
36
|
-
|
37
|
-
report << " 🔍 Vulnerability: #{vuln.id}"
|
38
|
-
report << " ⚠️ Severity: #{vuln.severity}"
|
39
|
-
report << " 📝 Summary: #{vuln.summary}" unless vuln.summary.empty?
|
40
|
-
report << " 🔧 Fix: #{vuln_dep.recommended_fix}"
|
41
|
-
report << ""
|
42
|
-
end
|
35
|
+
summary = "Summary: Total vulnerabilities: #{analysis.vulnerability_count}, High/Critical severity: #{analysis.high_severity_count}"
|
43
36
|
|
44
|
-
|
37
|
+
"🚨 Security Vulnerabilities Found\n#{table.render(:unicode, width: 80)}\n\n#{summary}"
|
45
38
|
end
|
46
39
|
|
47
40
|
def generate_json_report(analysis)
|
data/lib/gem_guard/version.rb
CHANGED
@@ -1,18 +1,28 @@
|
|
1
1
|
require "net/http"
|
2
2
|
require "json"
|
3
3
|
require "uri"
|
4
|
+
require "tty-spinner"
|
4
5
|
|
5
6
|
module GemGuard
|
6
7
|
class VulnerabilityFetcher
|
7
8
|
OSV_API_URL = "https://api.osv.dev/v1/query"
|
8
9
|
RUBY_ADVISORY_DB_URL = "https://raw.githubusercontent.com/rubysec/ruby-advisory-db/master/gems"
|
10
|
+
GHSA_API_URL = "https://api.github.com/advisories"
|
11
|
+
NVD_API_URL = "https://services.nvd.nist.gov/rest/json/cves/2.0"
|
12
|
+
CU_ADVISORY_DB_URL = "https://github.com/curesec/curesec-advisory-db"
|
9
13
|
|
10
14
|
def fetch_for(dependencies)
|
15
|
+
spinner = TTY::Spinner.new("[:spinner] Fetching vulnerabilities...", format: :pulse_2)
|
16
|
+
spinner.auto_spin
|
17
|
+
|
11
18
|
vulnerabilities = []
|
12
19
|
|
13
20
|
dependencies.each do |dependency|
|
14
21
|
vulnerabilities.concat(fetch_osv_vulnerabilities(dependency))
|
15
22
|
vulnerabilities.concat(fetch_ruby_advisory_vulnerabilities(dependency))
|
23
|
+
vulnerabilities.concat(fetch_ghsa_vulnerabilities(dependency))
|
24
|
+
vulnerabilities.concat(fetch_nvd_vulnerabilities(dependency))
|
25
|
+
vulnerabilities.concat(fetch_cu_advisory_vulnerabilities(dependency))
|
16
26
|
end
|
17
27
|
|
18
28
|
# Deduplicate vulnerabilities by ID and gem name, merging affected/fixed versions
|
@@ -39,6 +49,8 @@ module GemGuard
|
|
39
49
|
end
|
40
50
|
end
|
41
51
|
|
52
|
+
spinner.success("Done.")
|
53
|
+
|
42
54
|
deduplicated.values
|
43
55
|
end
|
44
56
|
|
@@ -79,6 +91,67 @@ module GemGuard
|
|
79
91
|
[]
|
80
92
|
end
|
81
93
|
|
94
|
+
def fetch_ghsa_vulnerabilities(dependency)
|
95
|
+
# GitHub Security Advisory fetching implementation
|
96
|
+
# Note: This requires GitHub API authentication for full access
|
97
|
+
url = "#{GHSA_API_URL}?ecosystem=rubygems&package=#{dependency.name}"
|
98
|
+
response = make_http_request(url)
|
99
|
+
return [] unless response
|
100
|
+
|
101
|
+
data = JSON.parse(response)
|
102
|
+
return [] unless data.is_a?(Array)
|
103
|
+
|
104
|
+
data.map do |vuln_data|
|
105
|
+
Vulnerability.new(
|
106
|
+
id: vuln_data["ghsa_id"] || vuln_data["id"],
|
107
|
+
gem_name: dependency.name,
|
108
|
+
affected_versions: extract_ghsa_affected_versions(vuln_data),
|
109
|
+
fixed_versions: extract_ghsa_fixed_versions(vuln_data),
|
110
|
+
severity: extract_ghsa_severity(vuln_data),
|
111
|
+
summary: vuln_data["summary"] || "",
|
112
|
+
details: vuln_data["description"] || ""
|
113
|
+
)
|
114
|
+
end
|
115
|
+
rescue JSON::ParserError
|
116
|
+
[]
|
117
|
+
end
|
118
|
+
|
119
|
+
def fetch_nvd_vulnerabilities(dependency)
|
120
|
+
# NVD (National Vulnerability Database) fetching implementation
|
121
|
+
# Search for vulnerabilities related to the gem name
|
122
|
+
url = "#{NVD_API_URL}?keywordSearch=#{dependency.name}"
|
123
|
+
response = make_http_request(url)
|
124
|
+
return [] unless response
|
125
|
+
|
126
|
+
data = JSON.parse(response)
|
127
|
+
return [] unless data["vulnerabilities"]
|
128
|
+
|
129
|
+
data["vulnerabilities"].map do |vuln_data|
|
130
|
+
# Check if this vulnerability actually affects the gem
|
131
|
+
cpe_match = vuln_data.dig("cve", "configurations", 0, "nodes", 0, "cpeMatch") || []
|
132
|
+
next unless cpe_match.any? { |match| match["criteria"]&.include?(dependency.name) }
|
133
|
+
|
134
|
+
Vulnerability.new(
|
135
|
+
id: vuln_data.dig("cve", "id") || "NVD-#{Time.now.to_i}",
|
136
|
+
gem_name: dependency.name,
|
137
|
+
affected_versions: extract_nvd_affected_versions(vuln_data),
|
138
|
+
fixed_versions: extract_nvd_fixed_versions(vuln_data),
|
139
|
+
severity: extract_nvd_severity(vuln_data),
|
140
|
+
summary: vuln_data.dig("cve", "descriptions", 0, "value") || "",
|
141
|
+
details: vuln_data.dig("cve", "descriptions", 0, "value") || ""
|
142
|
+
)
|
143
|
+
end.compact
|
144
|
+
rescue JSON::ParserError
|
145
|
+
[]
|
146
|
+
end
|
147
|
+
|
148
|
+
def fetch_cu_advisory_vulnerabilities(dependency)
|
149
|
+
# CU (Curesec) Advisory DB fetching implementation
|
150
|
+
# This is a placeholder implementation - would need to be expanded
|
151
|
+
# based on the actual structure of the Curesec advisory database
|
152
|
+
[]
|
153
|
+
end
|
154
|
+
|
82
155
|
def make_http_request(url, body = nil)
|
83
156
|
uri = URI(url)
|
84
157
|
http = Net::HTTP.new(uri.host, uri.port)
|
@@ -125,6 +198,44 @@ module GemGuard
|
|
125
198
|
|
126
199
|
vuln_data["severity"].first&.dig("score") || "UNKNOWN"
|
127
200
|
end
|
201
|
+
|
202
|
+
# GHSA-specific extraction methods
|
203
|
+
def extract_ghsa_affected_versions(vuln_data)
|
204
|
+
# Extract affected versions from GHSA data
|
205
|
+
vuln_data.dig("vulnerabilities", 0, "firstPatchedVersion", "identifier") ? [vuln_data.dig("vulnerabilities", 0, "vulnerableVersionRange")] : []
|
206
|
+
rescue
|
207
|
+
[]
|
208
|
+
end
|
209
|
+
|
210
|
+
def extract_ghsa_fixed_versions(vuln_data)
|
211
|
+
# Extract fixed versions from GHSA data
|
212
|
+
fixed = vuln_data.dig("vulnerabilities", 0, "firstPatchedVersion", "identifier")
|
213
|
+
fixed ? [fixed] : []
|
214
|
+
rescue
|
215
|
+
[]
|
216
|
+
end
|
217
|
+
|
218
|
+
def extract_ghsa_severity(vuln_data)
|
219
|
+
# Extract severity from GHSA data
|
220
|
+
vuln_data["severity"] || "UNKNOWN"
|
221
|
+
end
|
222
|
+
|
223
|
+
# NVD-specific extraction methods
|
224
|
+
def extract_nvd_affected_versions(vuln_data)
|
225
|
+
# Extract affected versions from NVD data
|
226
|
+
[]
|
227
|
+
end
|
228
|
+
|
229
|
+
def extract_nvd_fixed_versions(vuln_data)
|
230
|
+
# Extract fixed versions from NVD data
|
231
|
+
[]
|
232
|
+
end
|
233
|
+
|
234
|
+
def extract_nvd_severity(vuln_data)
|
235
|
+
# Extract severity from NVD data
|
236
|
+
metrics = vuln_data.dig("cve", "metrics", "cvssMetricV31", 0) || vuln_data.dig("cve", "metrics", "cvssMetricV2", 0)
|
237
|
+
metrics&.dig("cvssData", "baseScore")&.to_s || "UNKNOWN"
|
238
|
+
end
|
128
239
|
end
|
129
240
|
|
130
241
|
class Vulnerability
|
metadata
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gem_guard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wilbur Suero
|
8
|
+
autorequire:
|
8
9
|
bindir: exe
|
9
10
|
cert_chain: []
|
10
|
-
date: 2025-
|
11
|
+
date: 2025-09-01 00:00:00.000000000 Z
|
11
12
|
dependencies:
|
12
13
|
- !ruby/object:Gem::Dependency
|
13
14
|
name: thor
|
@@ -51,6 +52,34 @@ dependencies:
|
|
51
52
|
- - "~>"
|
52
53
|
- !ruby/object:Gem::Version
|
53
54
|
version: '0.23'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: tty-table
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.12'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.12'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: tty-spinner
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.9'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.9'
|
54
83
|
- !ruby/object:Gem::Dependency
|
55
84
|
name: bundler
|
56
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,6 +136,20 @@ dependencies:
|
|
107
136
|
- - "~>"
|
108
137
|
- !ruby/object:Gem::Version
|
109
138
|
version: '13.0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rspec-snapshot
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '2.0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '2.0'
|
110
153
|
- !ruby/object:Gem::Dependency
|
111
154
|
name: simplecov
|
112
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -137,7 +180,6 @@ files:
|
|
137
180
|
- Rakefile
|
138
181
|
- SECURITY.md
|
139
182
|
- exe/gem_guard
|
140
|
-
- gem_guard.gemspec
|
141
183
|
- lib/gem_guard.rb
|
142
184
|
- lib/gem_guard/analyzer.rb
|
143
185
|
- lib/gem_guard/auto_fixer.rb
|
@@ -160,6 +202,7 @@ metadata:
|
|
160
202
|
source_code_uri: https://github.com/wilburhimself/gem_guard
|
161
203
|
changelog_uri: https://github.com/wilburhimself/gem_guard/blob/main/CHANGELOG.md
|
162
204
|
rubygems_mfa_required: 'true'
|
205
|
+
post_install_message:
|
163
206
|
rdoc_options: []
|
164
207
|
require_paths:
|
165
208
|
- lib
|
@@ -174,7 +217,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
217
|
- !ruby/object:Gem::Version
|
175
218
|
version: '0'
|
176
219
|
requirements: []
|
177
|
-
rubygems_version: 3.
|
220
|
+
rubygems_version: 3.5.22
|
221
|
+
signing_key:
|
178
222
|
specification_version: 4
|
179
223
|
summary: Supply chain security and vulnerability management for Ruby gems
|
180
224
|
test_files: []
|
data/gem_guard.gemspec
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
require_relative "lib/gem_guard/version"
|
2
|
-
|
3
|
-
Gem::Specification.new do |spec|
|
4
|
-
spec.name = "gem_guard"
|
5
|
-
spec.version = GemGuard::VERSION
|
6
|
-
spec.authors = ["Wilbur Suero"]
|
7
|
-
spec.email = ["wilbur@example.com"]
|
8
|
-
|
9
|
-
spec.summary = "Supply chain security and vulnerability management for Ruby gems"
|
10
|
-
spec.description = "A comprehensive tool to detect, report, and remediate dependency-related security risks in Ruby projects. Includes CVE scanning, SBOM generation, and CI/CD integration."
|
11
|
-
spec.homepage = "https://github.com/wilburhimself/gem_guard"
|
12
|
-
spec.license = "MIT"
|
13
|
-
spec.required_ruby_version = ">= 3.0.0"
|
14
|
-
|
15
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
16
|
-
spec.metadata["source_code_uri"] = "https://github.com/wilburhimself/gem_guard"
|
17
|
-
spec.metadata["changelog_uri"] = "https://github.com/wilburhimself/gem_guard/blob/main/CHANGELOG.md"
|
18
|
-
spec.metadata["rubygems_mfa_required"] = "true"
|
19
|
-
|
20
|
-
spec.files = Dir.chdir(__dir__) do
|
21
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
22
|
-
(File.expand_path(f) == __FILE__) ||
|
23
|
-
f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile])
|
24
|
-
end
|
25
|
-
end
|
26
|
-
spec.bindir = "exe"
|
27
|
-
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
28
|
-
spec.require_paths = ["lib"]
|
29
|
-
|
30
|
-
spec.add_dependency "thor", "~> 1.0"
|
31
|
-
spec.add_dependency "json", "~> 2.0"
|
32
|
-
spec.add_dependency "tty-prompt", "~> 0.23"
|
33
|
-
|
34
|
-
spec.add_development_dependency "bundler", ">= 2.0"
|
35
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
36
|
-
spec.add_development_dependency "standard", "~> 1.39"
|
37
|
-
spec.add_development_dependency "rake", "~> 13.0"
|
38
|
-
spec.add_development_dependency "simplecov", "~> 0.22"
|
39
|
-
end
|