Skip to content

Commit 584bc26

Browse files
refactor: use the function options pattern for external functions (#31)
1 parent b97861a commit 584bc26

File tree

15 files changed

+210
-136
lines changed

15 files changed

+210
-136
lines changed

README.md

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,51 +15,55 @@ $ go get github.com/snyk/code-client-go
1515

1616
Use the HTTP client to make HTTP requests with configured retriable codes and authorisation headers for Snyk Rest APIs.
1717

18-
Implement the `github.com/snyk/code-client-go/http.Config` interface to configure the Snyk Code API client from applications.
18+
You can either configure the client using the functional options pattern provided or by implementing the interfaces.
1919

20-
Provide a net/http.Client factory to customize the underlying HTTP protocol behavior (timeouts, etc).
20+
Provide a `net/http.Client` factory to customize the underlying HTTP protocol behavior (timeouts, etc).
2121

2222
```go
2323
import (
2424
"net/http"
2525

2626
"github.com/rs/zerolog"
27-
codehttp "github.com/snyk/code-client-go/http"
27+
codeClientHTTP "github.com/snyk/code-client-go/http"
28+
codeClientObservability "github.com/snyk/code-client-go/observability"
2829
)
2930

3031
logger := zerlog.NewLogger(...)
31-
config := newConfigForMyApp()
32-
httpClient := codehttp.NewHTTPClient(logger, config, func() *http.Client { return http.DefaultClient }, codeInstrumentor, codeErrorReporter)
32+
instrumentor := codeClientObservability.NewInstrumentor()
33+
errorReporter := codeClientObservability.NewErrorReporter()
34+
httpClient := codeClientHTTP.NewHTTPClient(
35+
func() *http.Client {
36+
return &http.Client{
37+
Timeout: time.Duration(1) * time.Second,
38+
}
39+
},
40+
codeClientHTTP.WithRetryCount(1),
41+
codeClientHTTP.WithLogger(logger),
42+
codeClientHTTP.WithInstrumentor(instrumentor),
43+
codeClientHTTP.WithErrorReporter(errorReporter),
44+
)
3345
```
3446

35-
The HTTP client exposes a `DoCall` function.
47+
The HTTP client exposes a `Do` function.
3648

3749
### Configuration
3850

39-
Implement the `http.Config` interface to configure the Snyk Code API client from applications.
51+
Implement the `config.Config` interface to configure the Snyk Code API client from applications.
4052

4153
### Code Scanner
4254

4355
Use the Code Scanner to trigger a scan for a Snyk Code workspace using the Bundle Manager created above.
56+
4457
The Code Scanner exposes a `UploadAndAnalyze` function, which can be used like this:
4558

4659
```go
47-
import (
48-
"net/http"
49-
50-
"github.com/rs/zerolog"
51-
code "github.com/snyk/code-client-go"
52-
)
53-
54-
logger := zerlog.NewLogger(...)
5560
config := newConfigForMyApp()
56-
5761
codeScanner := code.NewCodeScanner(
5862
httpClient,
59-
config,
60-
codeInstrumentor,
61-
codeErrorReporter,
62-
logger,
63+
config,
64+
codeClientHTTP.WithLogger(logger),
65+
codeClientHTTP.WithInstrumentor(instrumentor),
66+
codeClientHTTP.WithErrorReporter(errorReporter),
6367
)
6468
code.UploadAndAnalyze(context.Background(), requestId, "path/to/workspace", channelForWalkingFiles, changedFiles)
6569
```

http/http.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,14 @@ type HTTPClient interface {
3333
Do(req *http.Request) (*http.Response, error)
3434
}
3535

36+
type HTTPClientFactory func() *http.Client
37+
3638
type httpClient struct {
37-
retryCount int
38-
clientFactory func() *http.Client
39-
instrumentor observability.Instrumentor
40-
errorReporter observability.ErrorReporter
41-
logger *zerolog.Logger
39+
retryCount int
40+
httpClientFactory HTTPClientFactory
41+
instrumentor observability.Instrumentor
42+
errorReporter observability.ErrorReporter
43+
logger *zerolog.Logger
4244
}
4345

4446
type OptionFunc func(*httpClient)
@@ -68,18 +70,18 @@ func WithLogger(logger *zerolog.Logger) OptionFunc {
6870
}
6971

7072
func NewHTTPClient(
71-
clientFactory func() *http.Client,
73+
httpClientFactory HTTPClientFactory,
7274
options ...OptionFunc,
7375
) HTTPClient {
7476
nopLogger := zerolog.Nop()
7577
instrumentor := observability.NewInstrumentor()
7678
errorReporter := observability.NewErrorReporter(&nopLogger)
7779
client := &httpClient{
78-
retryCount: 3,
79-
clientFactory: clientFactory,
80-
instrumentor: instrumentor,
81-
errorReporter: errorReporter,
82-
logger: &nopLogger,
80+
retryCount: 3,
81+
httpClientFactory: httpClientFactory,
82+
instrumentor: instrumentor,
83+
errorReporter: errorReporter,
84+
logger: &nopLogger,
8385
}
8486

8587
for _, option := range options {
@@ -137,7 +139,7 @@ func (s *httpClient) httpCall(req *http.Request) (*http.Response, error) {
137139
req.Body = reqBody
138140
s.logger.Debug().Str("url", req.URL.String()).Str("snyk-request-id", requestId).Str("requestBody", string(reqBuf)).Msg("SEND TO REMOTE")
139141
}
140-
response, err := s.clientFactory().Do(req)
142+
response, err := s.httpClientFactory().Do(req)
141143
req.Body = copyReqBody
142144
if response != nil {
143145
var copyResBody io.ReadCloser

internal/analysis/analysis.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ type AnalysisOrchestrator interface {
5353
}
5454

5555
func NewAnalysisOrchestrator(
56+
config config.Config,
5657
logger *zerolog.Logger,
5758
httpClient codeClientHTTP.HTTPClient,
5859
instrumentor observability.Instrumentor,
5960
errorReporter observability.ErrorReporter,
60-
config config.Config,
6161
) *analysisOrchestrator {
6262
return &analysisOrchestrator{
6363
httpClient,

internal/analysis/analysis_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func TestAnalysis_CreateWorkspace(t *testing.T) {
7070

7171
logger := zerolog.Nop()
7272

73-
analysisOrchestrator := analysis.NewAnalysisOrchestrator(&logger, mockHTTPClient, mockInstrumentor, mockErrorReporter, mockConfig)
73+
analysisOrchestrator := analysis.NewAnalysisOrchestrator(mockConfig, &logger, mockHTTPClient, mockInstrumentor, mockErrorReporter)
7474
_, err := analysisOrchestrator.CreateWorkspace(
7575
context.Background(),
7676
"4a72d1db-b465-4764-99e1-ecedad03b06a",
@@ -99,7 +99,7 @@ func TestAnalysis_CreateWorkspace_NotARepository(t *testing.T) {
9999
logger := zerolog.Nop()
100100

101101
repoDir := t.TempDir()
102-
analysisOrchestrator := analysis.NewAnalysisOrchestrator(&logger, mockHTTPClient, mockInstrumentor, mockErrorReporter, mockConfig)
102+
analysisOrchestrator := analysis.NewAnalysisOrchestrator(mockConfig, &logger, mockHTTPClient, mockInstrumentor, mockErrorReporter)
103103
_, err := analysisOrchestrator.CreateWorkspace(
104104
context.Background(),
105105
"4a72d1db-b465-4764-99e1-ecedad03b06a",
@@ -143,7 +143,7 @@ func TestAnalysis_CreateWorkspace_Failure(t *testing.T) {
143143

144144
logger := zerolog.Nop()
145145

146-
analysisOrchestrator := analysis.NewAnalysisOrchestrator(&logger, mockHTTPClient, mockInstrumentor, mockErrorReporter, mockConfig)
146+
analysisOrchestrator := analysis.NewAnalysisOrchestrator(mockConfig, &logger, mockHTTPClient, mockInstrumentor, mockErrorReporter)
147147
_, err := analysisOrchestrator.CreateWorkspace(
148148
context.Background(),
149149
"4a72d1db-b465-4764-99e1-ecedad03b06a",
@@ -240,7 +240,7 @@ func TestAnalysis_RunAnalysis(t *testing.T) {
240240

241241
logger := zerolog.Nop()
242242

243-
analysisOrchestrator := analysis.NewAnalysisOrchestrator(&logger, mockHTTPClient, mockInstrumentor, mockErrorReporter, mockConfig)
243+
analysisOrchestrator := analysis.NewAnalysisOrchestrator(mockConfig, &logger, mockHTTPClient, mockInstrumentor, mockErrorReporter)
244244
actual, err := analysisOrchestrator.RunAnalysis()
245245
require.NoError(t, err)
246246
assert.Equal(t, "COMPLETE", actual.Status)

internal/bundle/bundle.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ type Bundle interface {
3434
}
3535

3636
type deepCodeBundle struct {
37-
SnykCode deepcode.SnykCodeClient
37+
SnykCode deepcode.DeepcodeClient
3838
instrumentor observability.Instrumentor
3939
errorReporter observability.ErrorReporter
4040
logger *zerolog.Logger
@@ -46,7 +46,7 @@ type deepCodeBundle struct {
4646
}
4747

4848
func NewBundle(
49-
snykCode deepcode.SnykCodeClient,
49+
snykCode deepcode.DeepcodeClient,
5050
instrumentor observability.Instrumentor,
5151
errorReporter observability.ErrorReporter,
5252
logger *zerolog.Logger,

internal/bundle/bundle_manager.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import (
3131

3232
// TODO: add progress tracker for percentage progress
3333
type bundleManager struct {
34-
SnykCode deepcode.SnykCodeClient
34+
deepcodeClient deepcode.DeepcodeClient
3535
instrumentor observability.Instrumentor
3636
errorReporter observability.ErrorReporter
3737
logger *zerolog.Logger
@@ -57,13 +57,13 @@ type BundleManager interface {
5757
}
5858

5959
func NewBundleManager(
60+
deepcodeClient deepcode.DeepcodeClient,
6061
logger *zerolog.Logger,
61-
SnykCode deepcode.SnykCodeClient,
6262
instrumentor observability.Instrumentor,
6363
errorReporter observability.ErrorReporter,
6464
) *bundleManager {
6565
return &bundleManager{
66-
SnykCode: SnykCode,
66+
deepcodeClient: deepcodeClient,
6767
instrumentor: instrumentor,
6868
errorReporter: errorReporter,
6969
logger: logger,
@@ -133,10 +133,10 @@ func (b *bundleManager) Create(ctx context.Context,
133133
var bundleHash string
134134
var missingFiles []string
135135
if len(fileHashes) > 0 {
136-
bundleHash, missingFiles, err = b.SnykCode.CreateBundle(span.Context(), fileHashes)
136+
bundleHash, missingFiles, err = b.deepcodeClient.CreateBundle(span.Context(), fileHashes)
137137
}
138138
bundle = NewBundle(
139-
b.SnykCode,
139+
b.deepcodeClient,
140140
b.instrumentor,
141141
b.errorReporter,
142142
b.logger,
@@ -213,7 +213,7 @@ func (b *bundleManager) groupInBatches(
213213

214214
func (b *bundleManager) IsSupported(ctx context.Context, file string) (bool, error) {
215215
if b.supportedExtensions.Size() == 0 && b.supportedConfigFiles.Size() == 0 {
216-
filters, err := b.SnykCode.GetFilters(ctx)
216+
filters, err := b.deepcodeClient.GetFilters(ctx)
217217
if err != nil {
218218
b.logger.Error().Err(err).Msg("could not get filters")
219219
return false, err

0 commit comments

Comments
 (0)