Skip to content

Commit

Permalink
✨ allow probes to collect their own data from repo clients (#4052)
Browse files Browse the repository at this point in the history
* introduce independent probe implementations

rather than rely on checks collecting raw data, independent probes
collect their own raw data using the underlying repo client present in
the check request.

Signed-off-by: Spencer Schrock <sschrock@google.com>

* add test

Signed-off-by: Spencer Schrock <sschrock@google.com>

---------

Signed-off-by: Spencer Schrock <sschrock@google.com>
  • Loading branch information
spencerschrock committed Apr 25, 2024
1 parent 0ea8659 commit 71aed95
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 8 deletions.
27 changes: 20 additions & 7 deletions internal/probes/probes.go
Expand Up @@ -48,13 +48,16 @@ const (
)

type Probe struct {
Name string
Implementation ProbeImpl
RequiredRawData []CheckName
Name string
Implementation ProbeImpl
IndependentImplementation IndependentProbeImpl
RequiredRawData []CheckName
}

type ProbeImpl func(*checker.RawResults) ([]finding.Finding, string, error)

type IndependentProbeImpl func(*checker.CheckRequest) ([]finding.Finding, string, error)

// registered is the mapping of all registered probes.
var registered = map[string]Probe{}

Expand All @@ -69,15 +72,25 @@ func MustRegister(name string, impl ProbeImpl, requiredRawData []CheckName) {
}
}

func MustRegisterIndependent(name string, impl IndependentProbeImpl) {
err := register(Probe{
Name: name,
IndependentImplementation: impl,
})
if err != nil {
panic(err)
}
}

func register(p Probe) error {
if p.Name == "" {
return errors.WithMessage(errors.ErrScorecardInternal, "name cannot be empty")
}
if p.Implementation == nil {
return errors.WithMessage(errors.ErrScorecardInternal, "implementation cannot be nil")
if p.Implementation == nil && p.IndependentImplementation == nil {
return errors.WithMessage(errors.ErrScorecardInternal, "at least one implementation must be non-nil")
}
if len(p.RequiredRawData) == 0 {
return errors.WithMessage(errors.ErrScorecardInternal, "probes need some raw data")
if p.Implementation != nil && len(p.RequiredRawData) == 0 {
return errors.WithMessage(errors.ErrScorecardInternal, "non-independent probes need some raw data")
}
registered[p.Name] = p
return nil
Expand Down
12 changes: 12 additions & 0 deletions internal/probes/probes_test.go
Expand Up @@ -27,6 +27,10 @@ func emptyImpl(r *checker.RawResults) ([]finding.Finding, string, error) {
return nil, "", nil
}

func emptyIndependentImpl(c *checker.CheckRequest) ([]finding.Finding, string, error) {
return nil, "", nil
}

var (
p1 = Probe{
Name: "someProbe1",
Expand Down Expand Up @@ -84,6 +88,14 @@ func Test_register(t *testing.T) {
},
wantErr: false,
},
{
name: "independent probe registration",
probe: Probe{
Name: "bar",
IndependentImplementation: emptyIndependentImpl,
},
wantErr: false,
},
}
for _, tt := range tests {
tt := tt
Expand Down
7 changes: 6 additions & 1 deletion pkg/scorecard.go
Expand Up @@ -207,7 +207,12 @@ func runEnabledProbes(request *checker.CheckRequest,
return fmt.Errorf("getting probe %q: %w", probeName, err)
}
// Run probe
findings, _, err := probe.Implementation(&ret.RawResults)
var findings []finding.Finding
if probe.IndependentImplementation != nil {
findings, _, err = probe.IndependentImplementation(request)
} else {
findings, _, err = probe.Implementation(&ret.RawResults)
}
if err != nil {
return sce.WithMessage(sce.ErrScorecardInternal, "ending run")
}
Expand Down
6 changes: 6 additions & 0 deletions probes/entries.go
Expand Up @@ -66,6 +66,9 @@ import (
// ProbeImpl is the implementation of a probe.
type ProbeImpl func(*checker.RawResults) ([]finding.Finding, string, error)

// IndependentProbeImpl is the implementation of an independent probe.
type IndependentProbeImpl func(*checker.CheckRequest) ([]finding.Finding, string, error)

var (
// All represents all the probes.
All []ProbeImpl
Expand Down Expand Up @@ -160,6 +163,9 @@ var (
codeReviewOneReviewers.Run,
hasBinaryArtifacts.Run,
}

// Probes which don't use pre-computed raw data but rather collect it themselves.
Independent = []IndependentProbeImpl{}
)

//nolint:gochecknoinits
Expand Down

0 comments on commit 71aed95

Please sign in to comment.