Skip to content

Commit 6db3161

Browse files
committed
feat: return result metadata
1 parent c4e2ce8 commit 6db3161

File tree

6 files changed

+87
-74
lines changed

6 files changed

+87
-74
lines changed

internal/analysis/analysis.go

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ type AnalysisOrchestrator interface {
5252
RunAnalysis(ctx context.Context, orgId string, rootPath string, workspaceId string) (*sarif.SarifResponse, error)
5353
RunIncrementalAnalysis(ctx context.Context, orgId string, rootPath string, workspaceId string, limitToFiles []string) (*sarif.SarifResponse, error)
5454

55-
RunTest(ctx context.Context, orgId string, b bundle.Bundle, target scan.Target, reportingOptions AnalysisConfig) (*sarif.SarifResponse, error)
56-
RunTestRemote(ctx context.Context, orgId string, interactionId string, reportingOptions AnalysisConfig) (*sarif.SarifResponse, error)
55+
RunTest(ctx context.Context, orgId string, b bundle.Bundle, target scan.Target, reportingOptions AnalysisConfig) (*sarif.SarifResponse, *scan.ResultMetaData, error)
56+
RunTestRemote(ctx context.Context, orgId string, reportingOptions AnalysisConfig) (*sarif.SarifResponse, *scan.ResultMetaData, error)
5757
}
5858

5959
type AnalysisConfig struct {
@@ -74,6 +74,8 @@ type analysisOrchestrator struct {
7474
testType testModels.Scan
7575
}
7676

77+
var _ AnalysisOrchestrator = (*analysisOrchestrator)(nil)
78+
7779
type OptionFunc func(*analysisOrchestrator)
7880

7981
func WithInstrumentor(instrumentor observability.Instrumentor) func(*analysisOrchestrator) {
@@ -485,24 +487,24 @@ func (a *analysisOrchestrator) host(isHidden bool) string {
485487
return fmt.Sprintf("%s/%s", apiUrl, path)
486488
}
487489

488-
func (a *analysisOrchestrator) createTestAndGetResults(ctx context.Context, orgId string, body *testApi.CreateTestApplicationVndAPIPlusJSONRequestBody, progressString string) (*sarif.SarifResponse, error) {
490+
func (a *analysisOrchestrator) createTestAndGetResults(ctx context.Context, orgId string, body *testApi.CreateTestApplicationVndAPIPlusJSONRequestBody, progressString string) (*sarif.SarifResponse, *scan.ResultMetaData, error) {
489491
tracker := a.trackerFactory.GenerateTracker()
490492
tracker.Begin(progressString, "Retrieving results...")
491493

492-
innerFunction := func() (*sarif.SarifResponse, error) {
494+
innerFunction := func() (*sarif.SarifResponse, *scan.ResultMetaData, error) {
493495
params := testApi.CreateTestParams{Version: testApi.ApiVersion}
494496
orgUuid := uuid.MustParse(orgId)
495497
host := a.host(true)
496498

497499
client, err := testApi.NewClient(host, testApi.WithHTTPClient(a.httpClient))
498500
if err != nil {
499-
return nil, err
501+
return nil, nil, err
500502
}
501503

502504
// create test
503505
resp, err := client.CreateTestWithApplicationVndAPIPlusJSONBody(ctx, orgUuid, &params, *body)
504506
if err != nil {
505-
return nil, err
507+
return nil, nil, err
506508
}
507509

508510
parsedResponse, err := testApi.ParseCreateTestResponse(resp)
@@ -514,28 +516,28 @@ func (a *analysisOrchestrator) createTestAndGetResults(ctx context.Context, orgI
514516
}()
515517
if err != nil {
516518
a.logger.Debug().Msg(err.Error())
517-
return nil, err
519+
return nil, nil, err
518520
}
519521

520522
switch parsedResponse.StatusCode() {
521523
case http.StatusCreated:
522524
// poll results
523525
return a.pollTestForFindings(ctx, client, orgUuid, parsedResponse.ApplicationvndApiJSON201.Data.Id)
524526
}
525-
return nil, nil
527+
return nil, nil, nil
526528
}
527529

528-
result, err := innerFunction()
530+
result, metadata, err := innerFunction()
529531
if err != nil {
530532
tracker.End("Analysis failed.")
531533
} else {
532534
tracker.End("Analysis completed.")
533535
}
534536

535-
return result, err
537+
return result, metadata, err
536538
}
537539

538-
func (a *analysisOrchestrator) RunTest(ctx context.Context, orgId string, b bundle.Bundle, target scan.Target, reportingConfig AnalysisConfig) (*sarif.SarifResponse, error) {
540+
func (a *analysisOrchestrator) RunTest(ctx context.Context, orgId string, b bundle.Bundle, target scan.Target, reportingConfig AnalysisConfig) (*sarif.SarifResponse, *scan.ResultMetaData, error) {
539541
var repoUrl *string = nil
540542
if repoTarget, ok := target.(*scan.RepositoryTarget); ok {
541543
tmp := repoTarget.GetRepositoryUrl()
@@ -553,9 +555,9 @@ func (a *analysisOrchestrator) RunTest(ctx context.Context, orgId string, b bund
553555
return a.createTestAndGetResults(ctx, orgId, body, "Snyk Code analysis for "+target.GetPath())
554556
}
555557

556-
func (a *analysisOrchestrator) RunTestRemote(ctx context.Context, orgId string, interactionId string, cfg AnalysisConfig) (*sarif.SarifResponse, error) {
558+
func (a *analysisOrchestrator) RunTestRemote(ctx context.Context, orgId string, cfg AnalysisConfig) (*sarif.SarifResponse, *scan.ResultMetaData, error) {
557559
if cfg.ProjectId == nil || cfg.CommitId == nil {
558-
return nil, errors.New("projectId and commitId are required")
560+
return nil, nil, errors.New("projectId and commitId are required")
559561
}
560562

561563
legacyScmProject := testApi.NewTestInputLegacyScmProject(*cfg.ProjectId, *cfg.CommitId)
@@ -569,7 +571,7 @@ func (a *analysisOrchestrator) RunTestRemote(ctx context.Context, orgId string,
569571
return a.createTestAndGetResults(ctx, orgId, body, "Snyk Code analysis for remote project")
570572
}
571573

572-
func (a *analysisOrchestrator) pollTestForFindings(ctx context.Context, client *testApi.Client, org uuid.UUID, testId openapi_types.UUID) (*sarif.SarifResponse, error) {
574+
func (a *analysisOrchestrator) pollTestForFindings(ctx context.Context, client *testApi.Client, org uuid.UUID, testId openapi_types.UUID) (*sarif.SarifResponse, *scan.ResultMetaData, error) {
573575
method := "analysis.pollTestForFindings"
574576
logger := a.logger.With().Str("method", method).Logger()
575577

@@ -582,24 +584,24 @@ func (a *analysisOrchestrator) pollTestForFindings(ctx context.Context, client *
582584
case <-timeoutTimer.C:
583585
msg := "Snyk Code analysis timed out"
584586
logger.Error().Str("scanJobId", testId.String()).Msg(msg)
585-
return nil, errors.New(msg)
587+
return nil, nil, errors.New(msg)
586588
case <-pollingTicker.C:
587-
findingsUrl, complete, err := a.retrieveTestURL(ctx, client, org, testId)
589+
resultMetaData, complete, err := a.retrieveTestURL(ctx, client, org, testId)
588590
if err != nil {
589-
return nil, err
591+
return nil, nil, err
590592
}
591593
if complete {
592-
findings, findingsErr := a.retrieveFindings(ctx, testId, findingsUrl)
594+
findings, findingsErr := a.retrieveFindings(ctx, testId, resultMetaData.FindingsUrl)
593595
if findingsErr != nil {
594-
return nil, findingsErr
596+
return nil, nil, findingsErr
595597
}
596-
return findings, nil
598+
return findings, resultMetaData, nil
597599
}
598600
}
599601
}
600602
}
601603

602-
func (a *analysisOrchestrator) retrieveTestURL(ctx context.Context, client *testApi.Client, org uuid.UUID, testId openapi_types.UUID) (url string, completed bool, err error) {
604+
func (a *analysisOrchestrator) retrieveTestURL(ctx context.Context, client *testApi.Client, org uuid.UUID, testId openapi_types.UUID) (resultMetaData *scan.ResultMetaData, completed bool, err error) {
603605
method := "analysis.retrieveTestURL"
604606
logger := a.logger.With().Str("method", method).Logger()
605607
logger.Debug().Msg("retrieving Test URL")
@@ -612,7 +614,7 @@ func (a *analysisOrchestrator) retrieveTestURL(ctx context.Context, client *test
612614
)
613615
if err != nil {
614616
logger.Err(err).Str("testId", testId.String()).Msg("error requesting the ScanJobResult")
615-
return "", false, err
617+
return nil, false, err
616618
}
617619
defer func() {
618620
closeErr := httpResponse.Body.Close()
@@ -623,33 +625,42 @@ func (a *analysisOrchestrator) retrieveTestURL(ctx context.Context, client *test
623625

624626
parsedResponse, err := testApi.ParseGetTestResultResponse(httpResponse)
625627
if err != nil {
626-
return "", false, err
628+
return nil, false, err
627629
}
628630

629631
switch parsedResponse.StatusCode() {
630632
case 200:
631633
stateDiscriminator, stateError := parsedResponse.ApplicationvndApiJSON200.Data.Attributes.Discriminator()
632634
if stateError != nil {
633-
return "", false, stateError
635+
return nil, false, stateError
634636
}
635637

636638
switch stateDiscriminator {
637639
case string(testModels.TestAcceptedStateStatusAccepted):
638640
fallthrough
639641
case string(testModels.TestInProgressStateStatusInProgress):
640-
return "", false, nil
642+
return nil, false, nil
641643
case string(testModels.TestCompletedStateStatusCompleted):
642644
testCompleted, stateCompleteError := parsedResponse.ApplicationvndApiJSON200.Data.Attributes.AsTestCompletedState()
643645
if stateCompleteError != nil {
644-
return "", false, stateCompleteError
646+
return nil, false, stateCompleteError
645647
}
646648

649+
tes := "/org/team-cli-testing/project/ff7a6ceb-fab5-4f68-bdbf-4dbc919e8074/history/65e25f20-af06-45ff-8515-40aea39af878"
650+
647651
findingsUrl := a.host(true) + testCompleted.Documents.EnrichedSarif + "?version=" + testApi.DocumentApiVersion
648-
return findingsUrl, true, nil
652+
result := &scan.ResultMetaData{
653+
FindingsUrl: findingsUrl,
654+
WebUiUrl: tes,
655+
}
656+
if testCompleted.Results.Webui != nil && testCompleted.Results.Webui.Link != nil {
657+
result.WebUiUrl = *testCompleted.Results.Webui.Link
658+
}
659+
return result, true, nil
649660
default:
650-
return "", false, fmt.Errorf("unexpected test status \"%s\"", stateDiscriminator)
661+
return nil, false, fmt.Errorf("unexpected test status \"%s\"", stateDiscriminator)
651662
}
652663
default:
653-
return "", false, fmt.Errorf("unexpected response status \"%d\"", parsedResponse.StatusCode())
664+
return nil, false, fmt.Errorf("unexpected response status \"%d\"", parsedResponse.StatusCode())
654665
}
655666
}

internal/analysis/analysis_test.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -780,10 +780,9 @@ func TestAnalysis_RunTestRemote(t *testing.T) {
780780
analysis.WithErrorReporter(mockErrorReporter),
781781
)
782782

783-
result, err := analysisOrchestrator.RunTestRemote(
783+
result, _, err := analysisOrchestrator.RunTestRemote(
784784
context.Background(),
785785
"4a72d1db-b465-4764-99e1-ecedad03b06a",
786-
"b372d1db-b465-4764-99e1-ecedad03b06a",
787786
analysis.AnalysisConfig{
788787
ProjectId: &projectId,
789788
CommitId: &commitId,
@@ -809,10 +808,9 @@ func TestAnalysis_RunTestRemote_MissingRequiredParams(t *testing.T) {
809808
)
810809

811810
t.Run("missing both projectId and commitId", func(t *testing.T) {
812-
result, err := analysisOrchestrator.RunTestRemote(
811+
result, _, err := analysisOrchestrator.RunTestRemote(
813812
context.Background(),
814813
"4a72d1db-b465-4764-99e1-ecedad03b06a",
815-
"b372d1db-b465-4764-99e1-ecedad03b06a",
816814
analysis.AnalysisConfig{},
817815
)
818816

@@ -823,10 +821,9 @@ func TestAnalysis_RunTestRemote_MissingRequiredParams(t *testing.T) {
823821

824822
t.Run("missing projectId", func(t *testing.T) {
825823
commitId := "abc123"
826-
result, err := analysisOrchestrator.RunTestRemote(
824+
result, _, err := analysisOrchestrator.RunTestRemote(
827825
context.Background(),
828826
"4a72d1db-b465-4764-99e1-ecedad03b06a",
829-
"b372d1db-b465-4764-99e1-ecedad03b06a",
830827
analysis.AnalysisConfig{
831828
CommitId: &commitId,
832829
},
@@ -839,10 +836,9 @@ func TestAnalysis_RunTestRemote_MissingRequiredParams(t *testing.T) {
839836

840837
t.Run("missing commitId", func(t *testing.T) {
841838
projectId := uuid.New()
842-
result, err := analysisOrchestrator.RunTestRemote(
839+
result, _, err := analysisOrchestrator.RunTestRemote(
843840
context.Background(),
844841
"4a72d1db-b465-4764-99e1-ecedad03b06a",
845-
"b372d1db-b465-4764-99e1-ecedad03b06a",
846842
analysis.AnalysisConfig{
847843
ProjectId: &projectId,
848844
},

internal/analysis/mocks/analysis.go

Lines changed: 11 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scan.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ type CodeScanner interface {
5555
files <-chan string,
5656
changedFiles map[string]bool,
5757
options ...AnalysisOption,
58-
) (*sarif.SarifResponse, string, error)
58+
) (*sarif.SarifResponse, string, *scan.ResultMetaData, error)
5959
}
6060

6161
var _ CodeScanner = (*codeScanner)(nil)
@@ -190,28 +190,28 @@ func (c *codeScanner) UploadAndAnalyze(
190190
files <-chan string,
191191
changedFiles map[string]bool,
192192
options ...AnalysisOption,
193-
) (*sarif.SarifResponse, string, error) {
193+
) (*sarif.SarifResponse, string, *scan.ResultMetaData, error) {
194194
cfg := analysis.AnalysisConfig{}
195195
for _, opt := range options {
196196
opt(&cfg)
197197
}
198198

199199
if ctx.Err() != nil {
200200
c.logger.Info().Msg("Canceling Code scan - Code scanner received cancellation signal")
201-
return nil, "", nil
201+
return nil, "", nil, nil
202202
}
203203
b, err := c.bundleManager.Create(ctx, requestId, target.GetPath(), files, changedFiles)
204204
if err != nil {
205205
if bundle.IsNoFilesError(err) {
206-
return nil, "", nil
206+
return nil, "", nil, nil
207207
}
208208
if ctx.Err() == nil { // Only report errors that are not intentional cancellations
209209
msg := "error creating bundle..."
210210
c.errorReporter.CaptureError(errors.Wrap(err, msg), observability.ErrorReporterOptions{ErrorDiagnosticPath: target.GetPath()})
211-
return nil, "", err
211+
return nil, "", nil, err
212212
} else {
213213
c.logger.Info().Msg("Canceling Code scan - Code scanner received cancellation signal")
214-
return nil, "", nil
214+
return nil, "", nil, nil
215215
}
216216
}
217217

@@ -223,44 +223,44 @@ func (c *codeScanner) UploadAndAnalyze(
223223
if ctx.Err() != nil { // Only handle errors that are not intentional cancellations
224224
msg := "error uploading files..."
225225
c.errorReporter.CaptureError(errors.Wrap(err, msg), observability.ErrorReporterOptions{ErrorDiagnosticPath: target.GetPath()})
226-
return nil, bundleHash, err
226+
return nil, bundleHash, nil, err
227227
} else {
228228
c.logger.Info().Msg("Canceling Code scan - Code scanner received cancellation signal")
229-
return nil, bundleHash, nil
229+
return nil, bundleHash, nil, nil
230230
}
231231
}
232232

233233
if bundleHash == "" {
234234
c.logger.Debug().Msg("empty bundle, no Snyk Code analysis")
235-
return nil, bundleHash, nil
235+
return nil, bundleHash, nil, nil
236236
}
237237

238-
response, err := c.analysisOrchestrator.RunTest(ctx, c.config.Organization(), b, target, cfg)
238+
response, metadata, err := c.analysisOrchestrator.RunTest(ctx, c.config.Organization(), b, target, cfg)
239239

240240
if ctx.Err() != nil {
241241
c.logger.Info().Msg("Canceling Code scan - Code scanner received cancellation signal")
242-
return nil, bundleHash, nil
242+
return nil, bundleHash, nil, nil
243243
}
244244

245-
return response, bundleHash, err
245+
return response, bundleHash, metadata, err
246246
}
247247

248-
func (c *codeScanner) AnalyzeRemote(ctx context.Context, interactionId string, options ...AnalysisOption) (*sarif.SarifResponse, error) {
248+
func (c *codeScanner) AnalyzeRemote(ctx context.Context, options ...AnalysisOption) (*sarif.SarifResponse, *scan.ResultMetaData, error) {
249249
cfg := analysis.AnalysisConfig{}
250250
for _, opt := range options {
251251
opt(&cfg)
252252
}
253253

254254
if ctx.Err() != nil {
255255
c.logger.Info().Msg("Canceling Code scan - Code scanner received cancellation signal")
256-
return nil, nil
256+
return nil, nil, nil
257257
}
258-
response, err := c.analysisOrchestrator.RunTestRemote(ctx, c.config.Organization(), interactionId, cfg)
258+
response, metadata, err := c.analysisOrchestrator.RunTestRemote(ctx, c.config.Organization(), cfg)
259259

260260
if ctx.Err() != nil {
261261
c.logger.Info().Msg("Canceling Code scan - Code scanner received cancellation signal")
262-
return nil, nil
262+
return nil, nil, nil
263263
}
264264

265-
return response, err
265+
return response, metadata, err
266266
}

scan/resultmetadata.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package scan
2+
3+
type ResultMetaData struct {
4+
FindingsUrl string
5+
WebUiUrl string
6+
}

0 commit comments

Comments
 (0)