Skip to content
This repository was archived by the owner on Jan 22, 2026. It is now read-only.

Commit 5e94d54

Browse files
committed
Refactoring
1 parent 5f3161d commit 5e94d54

File tree

6 files changed

+45
-55
lines changed

6 files changed

+45
-55
lines changed

lib/git/pkgs/commands/vulns/base.rb

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -148,34 +148,12 @@ def sync_packages(packages)
148148
error "Failed to query OSV API: #{e.message}"
149149
end
150150

151-
# Collect all unique vuln IDs and fetch full details
152-
vuln_ids = results.flatten.map { |v| v["id"] }.uniq
153-
vuln_ids.each do |vuln_id|
154-
next if Models::Vulnerability.first(id: vuln_id)&.vulnerability_packages&.any?
155-
156-
begin
157-
full_vuln = client.get_vulnerability(vuln_id)
158-
Models::Vulnerability.from_osv(full_vuln)
159-
rescue OsvClient::ApiError => e
160-
$stderr.puts "Warning: Failed to fetch vulnerability #{vuln_id}: #{e.message}" unless Git::Pkgs.quiet
161-
end
162-
end
151+
fetch_vulnerability_details(client, results)
163152

164-
# Update package sync timestamps
165153
packages.each do |pkg|
166154
bib_ecosystem = Ecosystems.from_osv(pkg[:ecosystem])
167155
purl = Ecosystems.generate_purl(bib_ecosystem, pkg[:name])
168-
169-
if purl
170-
Models::Package.update_or_create(
171-
{ purl: purl },
172-
{
173-
ecosystem: bib_ecosystem,
174-
name: pkg[:name],
175-
vulns_synced_at: Time.now
176-
}
177-
)
178-
end
156+
mark_package_synced(purl, bib_ecosystem, pkg[:name]) if purl
179157
end
180158
end
181159

@@ -207,33 +185,36 @@ def ensure_vulns_synced
207185
end.compact
208186

209187
results = client.query_batch(queries)
188+
fetch_vulnerability_details(client, results)
210189

211-
# Collect all unique vuln IDs and fetch full details
212-
vuln_ids = results.flatten.map { |v| v["id"] }.uniq
213-
vuln_ids.each do |vuln_id|
214-
next if Models::Vulnerability.first(id: vuln_id)&.vulnerability_packages&.any?
215-
216-
begin
217-
full_vuln = client.get_vulnerability(vuln_id)
218-
Models::Vulnerability.from_osv(full_vuln)
219-
rescue OsvClient::ApiError => e
220-
$stderr.puts "Warning: Failed to fetch vulnerability #{vuln_id}: #{e.message}" unless Git::Pkgs.quiet
221-
end
222-
end
223-
224-
# Update package sync timestamps
225190
batch.each do |pkg|
226191
purl = Ecosystems.generate_purl(pkg.ecosystem, pkg.name)
227-
next unless purl
192+
mark_package_synced(purl, pkg.ecosystem, pkg.name) if purl
193+
end
194+
end
195+
end
196+
197+
def fetch_vulnerability_details(client, results)
198+
vuln_ids = results.flatten.map { |v| v["id"] }.uniq
199+
vuln_ids.each do |vuln_id|
200+
next if Models::Vulnerability.first(id: vuln_id)&.vulnerability_packages&.any?
228201

229-
Models::Package.update_or_create(
230-
{ purl: purl },
231-
{ ecosystem: pkg.ecosystem, name: pkg.name, vulns_synced_at: Time.now }
232-
)
202+
begin
203+
full_vuln = client.get_vulnerability(vuln_id)
204+
Models::Vulnerability.from_osv(full_vuln)
205+
rescue OsvClient::ApiError => e
206+
$stderr.puts "Warning: Failed to fetch vulnerability #{vuln_id}: #{e.message}" unless Git::Pkgs.quiet
233207
end
234208
end
235209
end
236210

211+
def mark_package_synced(purl, ecosystem, name)
212+
Models::Package.update_or_create(
213+
{ purl: purl },
214+
{ ecosystem: ecosystem, name: name, vulns_synced_at: Time.now }
215+
)
216+
end
217+
237218
def format_commit_info(commit)
238219
return nil unless commit
239220

lib/git/pkgs/commands/vulns/exposure.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ def compute_exposure_summary(data)
297297

298298
post_disclosure_times = fixed.map { |d| d[:post_disclosure_days] }.compact
299299
mean_remediation = post_disclosure_times.empty? ? nil : (post_disclosure_times.sum.to_f / post_disclosure_times.size).round(1)
300-
median_remediation = post_disclosure_times.empty? ? nil : post_disclosure_times.sort[post_disclosure_times.size / 2]
300+
median_remediation = median(post_disclosure_times)
301301

302302
oldest_ongoing = ongoing.map { |d| d[:post_disclosure_days] }.compact.max
303303

@@ -399,6 +399,18 @@ def output_exposure_table(data)
399399
puts ""
400400
output_exposure_summary(data)
401401
end
402+
403+
def median(values)
404+
return nil if values.empty?
405+
406+
sorted = values.sort
407+
mid = sorted.size / 2
408+
if sorted.size.odd?
409+
sorted[mid]
410+
else
411+
((sorted[mid - 1] + sorted[mid]) / 2.0).round(1)
412+
end
413+
end
402414
end
403415
end
404416
end

lib/git/pkgs/commands/vulns/praise.rb

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -228,13 +228,7 @@ def output_praise_text(results)
228228
end
229229

230230
line = "#{severity} #{id} #{pkg} #{commit_info} #{days_info}"
231-
colored_line = case result[:severity]&.downcase
232-
when "critical", "high" then Color.green(line)
233-
when "medium" then Color.green(line)
234-
when "low" then Color.green(line)
235-
else Color.green(line)
236-
end
237-
puts colored_line
231+
puts Color.green(line)
238232
end
239233
end
240234
end

lib/git/pkgs/commands/vulns/show.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def find_exposure_for_vuln(vuln, vuln_pkgs, repo)
166166
begin
167167
commit_sha = repo.rev_parse(ref)
168168
target_commit = Models::Commit.first(sha: commit_sha)
169-
rescue StandardError
169+
rescue Rugged::ReferenceError
170170
return exposures
171171
end
172172

lib/git/pkgs/commands/vulns/sync.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def run
4040
repo = Repository.new
4141

4242
unless Database.exists?(repo.git_dir)
43-
error "No database found. Run 'git pkgs init' first or use --stateless."
43+
error "No database found. Run 'git pkgs init' first."
4444
end
4545

4646
Database.connect(repo.git_dir)

lib/git/pkgs/osv_client.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,16 +129,19 @@ def http_client(uri)
129129
end
130130
end
131131

132-
# Handle pagination for single query endpoint
132+
MAX_PAGES = 100
133+
133134
def fetch_all_pages(response, original_payload)
134135
vulns = response["vulns"] || []
135136
page_token = response["next_page_token"]
137+
pages_fetched = 0
136138

137-
while page_token
139+
while page_token && pages_fetched < MAX_PAGES
138140
payload = original_payload.merge(page_token: page_token)
139141
response = post("/query", payload)
140142
vulns.concat(response["vulns"] || [])
141143
page_token = response["next_page_token"]
144+
pages_fetched += 1
142145
end
143146

144147
vulns

0 commit comments

Comments
 (0)