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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c1d1776e2037eecfee3695b1e520c68812be38a83926d7187f5e3387b0427da9
4
- data.tar.gz: 0f2b8ea750a6994523425a6b533c3027826e2ee44b2e1ec4a02e4990d6ef9eb3
3
+ metadata.gz: 87a59fb2fa654c13d509d6736a43c423713eb7419966b85860217839e6e5bf98
4
+ data.tar.gz: dff5ce7cd3e7d3471a8509a3e194ab722c98beef4d413429075dcaa03d3ef4f9
5
5
  SHA512:
6
- metadata.gz: c95027418ff1983569da3918c4413f764e0e2ffc19e4b6048fc1c8a0540aa4b197339225f1740188105f42f0598df572a70aae0222c3f8b979a25041ef3d008a
7
- data.tar.gz: 37d6a7539128a0fd30d3025512fe1129a7a1c41a465e19939abe80f84581ef819ac4206f54d2855db3c5e68919449adf39b2fd306d1827ff87c7f3f91d1ec531
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 Ruby Advisory Database
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 confirm each upgrade (uses tty-prompt)
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 asked per gem: `Upgrade nokogiri 1.12.0 1.14.3?` Answering “no” skips that gem.
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
- - [ ] **Enhanced Vulnerability Sources**: Additional security databases
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
  ---
@@ -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.select do |fix|
132
- question = "Upgrade #{fix[:gem_name]} #{fix[:current_version]} → #{fix[:target_version]}?"
133
- prompt.yes?(question)
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)
@@ -16,7 +16,7 @@ module GemGuard
16
16
  "include_dev_dependencies" => false
17
17
  },
18
18
  "scan" => {
19
- "sources" => ["osv", "ruby_advisory_db"],
19
+ "sources" => ["osv", "ruby_advisory_db", "ghsa", "nvd", "cu_advisory_db"],
20
20
  "timeout" => 30
21
21
  }
22
22
  }.freeze
@@ -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
 
@@ -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
- report = []
22
- report << "🚨 Security Vulnerabilities Found"
23
- report << "=" * 50
24
- report << ""
25
- report << "Summary:"
26
- report << " Total vulnerabilities: #{analysis.vulnerability_count}"
27
- report << " High/Critical severity: #{analysis.high_severity_count}"
28
- report << ""
29
- report << "Details:"
30
- report << ""
31
-
32
- analysis.vulnerable_dependencies.each do |vuln_dep|
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
- report << "📦 #{dep.name} (#{dep.version})"
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
- report.join("\n")
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)
@@ -1,3 +1,3 @@
1
1
  module GemGuard
2
- VERSION = "1.2.2"
2
+ VERSION = "1.2.5"
3
3
  end
@@ -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.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-08-18 00:00:00.000000000 Z
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.6.2
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