Skip to content
Open
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
6 changes: 5 additions & 1 deletion command/report/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
type ReportOptions struct {
Analyzer string
AnalyzerType string
CommitOID string
Key string
Value string
ValueFile string
Expand Down Expand Up @@ -110,6 +111,8 @@ func NewCmdReportWithDeps(deps *container.Container) *cobra.Command {

cmd.Flags().StringVar(&opts.AnalyzerType, "analyzer-type", "", "type of the analyzer (example: community)")

cmd.Flags().StringVar(&opts.CommitOID, "commit", "", "commit SHA to report against (skips git detection)")

cmd.Flags().StringVar(&opts.Key, "key", "", "shortcode of the language (example: go)")

cmd.Flags().StringVar(&opts.Value, "value", "", "value of the artifact")
Expand Down Expand Up @@ -165,6 +168,7 @@ func (opts *ReportOptions) Run(ctx context.Context, svc *reportsvc.Service, outp
result, err := svc.Report(ctx, reportsvc.Options{
Analyzer: opts.Analyzer,
AnalyzerType: opts.AnalyzerType,
CommitOID: opts.CommitOID,
Key: opts.Key,
Value: opts.Value,
ValueFile: opts.ValueFile,
Expand Down Expand Up @@ -193,7 +197,7 @@ func setReportUsageFunc(cmd *cobra.Command) {
title string
flags []string
}{
{"Artifact", []string{"analyzer", "analyzer-type", "key", "value", "value-file"}},
{"Artifact", []string{"analyzer", "analyzer-type", "commit", "key", "value", "value-file"}},
{"Authentication", []string{"use-oidc", "oidc-provider", "oidc-request-token", "oidc-request-url", "host"}},
{"Output", []string{"output"}},
{"General", []string{"skip-verify", "help"}},
Expand Down
13 changes: 9 additions & 4 deletions internal/services/report/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,15 @@ func (s *Service) Report(ctx context.Context, opts Options) (*Result, error) {
return nil, uerr
}

headCommitOID, warning, err := s.git.GetHead(currentDir)
if err != nil {
s.capture(err)
return nil, errors.New("Unable to get commit OID HEAD. Make sure you are running the CLI from a git repository")
var headCommitOID, warning string
if opts.CommitOID != "" {
headCommitOID = opts.CommitOID
} else {
headCommitOID, warning, err = s.git.GetHead(currentDir)
if err != nil {
s.capture(err)
return nil, errors.New("Unable to get commit OID HEAD. Make sure you are running the CLI from a git repository or use --commit flag")
}
}

artifactValue, err := s.resolveArtifactValue(opts)
Expand Down
53 changes: 53 additions & 0 deletions internal/services/report/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,59 @@ func TestReportCreateArtifactEmptyError(t *testing.T) {
assert.Contains(t, err.Error(), "raw response")
}

func TestReportExplicitCommitSkipsGit(t *testing.T) {
tempDir := t.TempDir()
artifactPath := filepath.Join(tempDir, "coverage.xml")
assert.NoError(t, os.WriteFile(artifactPath, []byte("<coverage/>"), 0o644))

var capturedCommit string
httpClient := &mockHTTPClient{DoFunc: func(req *http.Request) (*http.Response, error) {
body, _ := io.ReadAll(req.Body)
_ = req.Body.Close()
if bytes.Contains(body, []byte("ArtifactMetadataInput")) {
payload := `{"data":{"__type":{"inputFields":[]}}}`
return httpResponse(200, payload), nil
}
if bytes.Contains(body, []byte("createArtifact")) {
var q ReportQuery
_ = json.Unmarshal(body, &q)
capturedCommit = q.Variables.Input.CommitOID
payload := `{"data":{"createArtifact":{"ok":true,"message":"ok","error":""}}}`
return httpResponse(200, payload), nil
}
return httpResponse(400, `{"error":"unexpected"}`), nil
}}

// Git client returns an error — simulates no git repo available
git := adapters.NewMockGitClient()
git.SetError(errors.New("not a git repository"))
env := adapters.NewMockEnvironment()
env.Set("DEEPSOURCE_DSN", "https://token@localhost:8080")

svc := NewService(ServiceDeps{
GitClient: git,
HTTPClient: httpClient,
FileSystem: adapters.NewOSFileSystem(),
Environment: env,
Sentry: adapters.NewNoOpSentry(),
Output: adapters.NewBufferOutput(),
Workdir: func() (string, error) { return tempDir, nil },
})

result, err := svc.Report(context.Background(), Options{
Analyzer: "test-coverage",
Key: "python",
ValueFile: artifactPath,
CommitOID: "deadbeef1234567890abcdef1234567890abcdef",
})

assert.NoError(t, err)
if assert.NotNil(t, result) {
assert.Equal(t, "ok", result.Message)
}
assert.Equal(t, "deadbeef1234567890abcdef1234567890abcdef", capturedCommit)
}

func TestCaptureSkipsUserErrors(t *testing.T) {
captured := false
mockSentry := &captureSentry{onCapture: func(_ error) { captured = true }}
Expand Down
1 change: 1 addition & 0 deletions internal/services/report/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type QueryResponse struct {
type Options struct {
Analyzer string
AnalyzerType string
CommitOID string
Key string
Value string
ValueFile string
Expand Down
Loading