Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions pkg/cli/deps_report.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cli

import (
"context"
"encoding/json"
"fmt"
"os"
Expand All @@ -25,7 +26,7 @@ type DependencyReport struct {
}

// GenerateDependencyReport creates a comprehensive dependency health report
func GenerateDependencyReport(verbose bool) (*DependencyReport, error) {
func GenerateDependencyReport(ctx context.Context, verbose bool) (*DependencyReport, error) {
depsReportLog.Print("Generating dependency report")

// Find go.mod file
Expand Down Expand Up @@ -76,7 +77,7 @@ func GenerateDependencyReport(verbose bool) (*DependencyReport, error) {
}

// Check for security advisories
advisories, err := CheckSecurityAdvisories(verbose)
advisories, err := CheckSecurityAdvisories(ctx, verbose)
if err != nil {
if verbose {
fmt.Fprintln(os.Stderr, console.FormatWarningMessage(fmt.Sprintf("Warning: could not check security advisories: %v", err)))
Expand Down
9 changes: 5 additions & 4 deletions pkg/cli/deps_security.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cli

import (
"context"
"encoding/json"
"fmt"
"io"
Expand Down Expand Up @@ -47,7 +48,7 @@ type GitHubAdvisoryResponse struct {
}

// CheckSecurityAdvisories checks for security vulnerabilities in dependencies
func CheckSecurityAdvisories(verbose bool) ([]SecurityAdvisory, error) {
func CheckSecurityAdvisories(ctx context.Context, verbose bool) ([]SecurityAdvisory, error) {
depsSecurityLog.Print("Starting security advisory check")

// Find go.mod file
Expand Down Expand Up @@ -75,7 +76,7 @@ func CheckSecurityAdvisories(verbose bool) ([]SecurityAdvisory, error) {
}

// Query GitHub Security Advisory API
advisories, err := querySecurityAdvisories(depVersions, verbose)
advisories, err := querySecurityAdvisories(ctx, depVersions, verbose)
if err != nil {
return nil, fmt.Errorf("failed to query security advisories: %w", err)
}
Expand Down Expand Up @@ -130,13 +131,13 @@ func DisplaySecurityAdvisories(advisories []SecurityAdvisory) {
}

// querySecurityAdvisories queries the GitHub Security Advisory API
func querySecurityAdvisories(depVersions map[string]string, verbose bool) ([]SecurityAdvisory, error) {
func querySecurityAdvisories(ctx context.Context, depVersions map[string]string, verbose bool) ([]SecurityAdvisory, error) {
// GitHub Security Advisory API endpoint
url := "https://api.github.com/advisories?ecosystem=go&per_page=100"

depsSecurityLog.Printf("Querying GitHub Security Advisory API: url=%s, dep_count=%d", url, len(depVersions))
client := &http.Client{Timeout: 30 * time.Second}
req, err := http.NewRequest(http.MethodGet, url, nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnose] The fix is correct — http.NewRequestWithContext is the right call here. Per the /diagnose Phase 5 guidance, a regression test at the correct seam should accompany the fix.

Consider adding a test that verifies context cancellation is honoured, for example using httptest.NewServer with a handler that blocks, then cancelling the context:

func TestCheckSecurityAdvisories_ContextCancelled(t *testing.T) {
    srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        <-r.Context().Done()
    }))
    defer srv.Close()

    ctx, cancel := context.WithCancel(context.Background())
    cancel() // cancel immediately

    _, err := CheckSecurityAdvisories(ctx, false)

    assert.Error(t, err, "cancelled context should produce an error")
}

Without this, the only assurance that context wiring is correct is code inspection — it won't catch a regression if the context is inadvertently dropped in a future refactor.

if err != nil {
return nil, err
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/cli/upgrade_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ Examples:

// Handle audit mode
if auditFlag {
return runDependencyAudit(verbose, jsonOutput)
return runDependencyAudit(cmd.Context(), verbose, jsonOutput)
}

if createPR {
Expand Down Expand Up @@ -130,11 +130,11 @@ Examples:
}

// runDependencyAudit performs a dependency health audit
func runDependencyAudit(verbose bool, jsonOutput bool) error {
func runDependencyAudit(ctx context.Context, verbose bool, jsonOutput bool) error {
upgradeLog.Print("Running dependency health audit")

// Generate comprehensive report
report, err := GenerateDependencyReport(verbose)
report, err := GenerateDependencyReport(ctx, verbose)
if err != nil {
return fmt.Errorf("failed to generate dependency report: %w", err)
}
Expand Down
Loading