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
10 changes: 8 additions & 2 deletions cmd/cli/evaluate/evaluate.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
}

// Evaluate evaluates the feature flags based on the configuration and context
func (e evaluate) Evaluate() (map[string]model.RawVarResult, error) {

Check failure on line 23 in cmd/cli/evaluate/evaluate.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 18 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=thomaspoignant_go-feature-flag&issues=AZrd-5xYfbY5FY_8M6k2&open=AZrd-5xYfbY5FY_8M6k2&pullRequest=4391
c := ffclient.Config{
PollingInterval: 10 * time.Minute,
DisableNotifierOnInit: true,
Expand Down Expand Up @@ -51,14 +51,20 @@
if e.flag != "" {
listFlags = append(listFlags, e.flag)
} else {
flags, _ := goff.GetFlagsFromCache()
flags, err := goff.GetFlagsFromCache()
if err != nil {
return nil, err
}
for key := range flags {
listFlags = append(listFlags, key)
}
}

for _, flag := range listFlags {
res, _ := goff.RawVariation(flag, convertedEvaluationCtx, nil)
res, err := goff.RawVariation(flag, convertedEvaluationCtx, nil)
if err != nil {
return nil, err
}
result[flag] = res
}
return result, nil
Expand Down
3 changes: 1 addition & 2 deletions cmd/cli/evaluate/evaluate_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,8 @@ evaluate --kind postgres --table my-table --column my-column:my-column-type --fl

if checkMode {
return runCheck(cmd, retrieverConf)
} else {
return runEvaluate(cmd, args, evalFlagFormat, retrieverConf, evalFlag, evalCtx)
}
return runEvaluate(cmd, args, evalFlagFormat, retrieverConf, evalFlag, evalCtx)
},
SilenceUsage: true,
SilenceErrors: true,
Expand Down
18 changes: 12 additions & 6 deletions cmd/cli/evaluate/evaluate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ func Test_evaluate_Evaluate(t *testing.T) {
return evaluate{}, err
}

gitHubRetriever, _ := r.(*githubretriever.Retriever)
gitHubRetriever, ok := r.(*githubretriever.Retriever)
assert.True(t, ok, "failed to assert retriever to *githubretriever.Retriever")
gitHubRetriever.SetHTTPClient(&mock.HTTP{})

return evaluate{
Expand Down Expand Up @@ -211,7 +212,8 @@ func Test_evaluate_Evaluate(t *testing.T) {
return evaluate{}, err
}

gitLabRetriever, _ := r.(*gitlabretriever.Retriever)
gitLabRetriever, ok := r.(*gitlabretriever.Retriever)
assert.True(t, ok, "failed to assert retriever to *gitlabretriever.Retriever")
gitLabRetriever.SetHTTPClient(&mock.HTTP{})

return evaluate{
Expand Down Expand Up @@ -251,7 +253,8 @@ func Test_evaluate_Evaluate(t *testing.T) {
return evaluate{}, err
}

bitBucketRetriever, _ := r.(*bitbucketretriever.Retriever)
bitBucketRetriever, ok := r.(*bitbucketretriever.Retriever)
assert.True(t, ok, "failed to assert retriever to *bitbucketretriever.Retriever")
bitBucketRetriever.SetHTTPClient(&mock.HTTP{})

return evaluate{
Expand Down Expand Up @@ -295,7 +298,8 @@ func Test_evaluate_Evaluate(t *testing.T) {
return evaluate{}, err
}

s3Retriever, _ := r.(*s3retrieverv2.Retriever)
s3Retriever, ok := r.(*s3retrieverv2.Retriever)
assert.True(t, ok, "failed to assert retriever to *s3retrieverv2.Retriever")
s3Retriever.SetDownloader(downloader)

_ = s3Retriever.Init(context.Background(), nil)
Expand Down Expand Up @@ -340,7 +344,8 @@ func Test_evaluate_Evaluate(t *testing.T) {
return evaluate{}, err
}

httpRetriever, _ := r.(*httpretriever.Retriever)
httpRetriever, ok := r.(*httpretriever.Retriever)
assert.True(t, ok, "failed to assert retriever to *httpretriever.Retriever")
httpRetriever.SetHTTPClient(&mock.HTTP{})

return evaluate{
Expand Down Expand Up @@ -383,7 +388,8 @@ func Test_evaluate_Evaluate(t *testing.T) {
return evaluate{}, err
}

gcsRetriever, _ := r.(*gcstorageretriever.Retriever)
gcsRetriever, ok := r.(*gcstorageretriever.Retriever)
assert.True(t, ok, "failed to assert retriever to *gcstorageretriever.Retriever")
gcsRetriever.SetOptions([]option.ClientOption{
option.WithCredentials(&google.Credentials{}),
option.WithHTTPClient(mockedStorage.Server.HTTPClient()),
Expand Down
8 changes: 2 additions & 6 deletions cmd/cli/generate/manifest/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ import (
dtoCore "github.com/thomaspoignant/go-feature-flag/modules/core/dto"
)

func NewManifest(
configFile string,
configFormat string,
flagManifestDestination string,
) (Manifest, error) {
func NewManifest(configFile, configFormat, flagManifestDestination string) (Manifest, error) {
if flagManifestDestination == "" {
return Manifest{}, fmt.Errorf("--flag_manifest_destination is mandatory")
}
Expand Down Expand Up @@ -63,7 +59,7 @@ func (m *Manifest) generateDefinitions(flagDTOs map[string]dto.DTO) (
output := helper.Output{}
for flagKey, flagDTO := range flagDTOs {
flag := dtoCore.ConvertDtoToInternalFlag(flagDTO)
flagType, err := helper.GetFlagTypeFromVariations(flag.GetVariations())
flagType, err := helper.FlagTypeFromVariations(flag.GetVariations())
if err != nil {
return model.FlagManifest{}, output,
fmt.Errorf("invalid configuration for flag %s: %s", flagKey, err.Error())
Expand Down
5 changes: 4 additions & 1 deletion cmd/cli/generate/manifest/manifest_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ func NewManifestCmd() *cobra.Command {
"⚠️ note that this is an experimental feature and we may change this command line without warning.",

RunE: func(cmd *cobra.Command, _ []string) error {
m, _ := NewManifest(manifestConfigFile, manifestFlagFormat, flagManifestDestination)
m, err := NewManifest(manifestConfigFile, manifestFlagFormat, flagManifestDestination)
if err != nil {
return err
}
output, err := m.Generate()
if err != nil {
cmd.SilenceUsage = true
Expand Down
2 changes: 1 addition & 1 deletion cmd/cli/helper/number_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/thomaspoignant/go-feature-flag/cmd/cli/generate/manifest/model"
)

func GetFlagTypeFromVariations(variations map[string]*interface{}) (model.FlagType, error) {
func FlagTypeFromVariations(variations map[string]*interface{}) (model.FlagType, error) {
if variations == nil {
return "", fmt.Errorf("impossible to find type, no variations found")
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/cli/helper/number_type_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/thomaspoignant/go-feature-flag/modules/core/testutils/testconvert"
)

func TestGetFlagTypeFromVariations(t *testing.T) {
func TestFlagTypeFromVariations(t *testing.T) {
tests := []struct {
name string
variations map[string]*interface{}
Expand Down Expand Up @@ -101,7 +101,7 @@ func TestGetFlagTypeFromVariations(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := helper.GetFlagTypeFromVariations(tt.variations)
result, err := helper.FlagTypeFromVariations(tt.variations)
if tt.expectErr {
assert.Error(t, err)
} else {
Expand Down
5 changes: 4 additions & 1 deletion cmd/cli/helper/print_output.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ func (o *Output) PrintLines(cmd *cobra.Command) {
default:
outputText = pterm.Sprint(line.Text)
}
_, _ = fmt.Fprintln(writer, outputText)
_, err := fmt.Fprintln(writer, outputText)
if err != nil {
PrintFatalAndExit(err)
}
}
}

Expand Down
7 changes: 4 additions & 3 deletions cmd/cli/helper/read_config_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ func LoadConfigFile(
for _, location := range defaultLocations {
for _, ext := range supportedExtensions {
configFile := fmt.Sprintf("%s%s.%s", location, filename, ext)
if _, err := os.Stat(configFile); err == nil {
return readConfigFile(configFile, ext)
if _, err := os.Stat(configFile); err != nil {
continue
}
return readConfigFile(configFile, ext)
}
}
return nil, fmt.Errorf(
Expand All @@ -53,7 +54,7 @@ func LoadConfigFile(
)
}

func readConfigFile(configFile string, configFormat string) (map[string]dto.DTO, error) {
func readConfigFile(configFile, configFormat string) (map[string]dto.DTO, error) {
dat, err := os.ReadFile(configFile)
if err != nil {
return nil, err
Expand Down
4 changes: 2 additions & 2 deletions cmd/cli/linter/lint_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func NewLintCmd() *cobra.Command {
func runLint(cmd *cobra.Command, args []string, lintFlagFormat string) error {
output := helper.Output{}
l := Linter{
InputFile: getFilePath(args),
InputFile: extractFilePathFromArgs(args),
InputFormat: lintFlagFormat,
}
if errs := l.Lint(); len(errs) > 0 {
Expand All @@ -44,7 +44,7 @@ func runLint(cmd *cobra.Command, args []string, lintFlagFormat string) error {
return nil
}

func getFilePath(args []string) string {
func extractFilePathFromArgs(args []string) string {
if len(args) == 0 {
return ""
}
Expand Down
8 changes: 5 additions & 3 deletions cmd/relayproxy/api/lambda_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/aws/aws-lambda-go/events"
echoadapter "github.com/awslabs/aws-lambda-go-api-proxy/echo"
"github.com/labstack/echo/v4"
"github.com/thomaspoignant/go-feature-flag/cmd/relayproxy/config"
)

// newAwsLambdaHandlerManager is creating a new awsLambdaHandler struct with the echoadapter
Expand Down Expand Up @@ -36,11 +37,12 @@ type awsLambdaHandler struct {
adapterALB *echoadapter.EchoLambdaALB
}

func (h *awsLambdaHandler) GetAdapter(mode string) interface{} {
// SelectAdapter returns the appropriate adapter based on the mode.
func (h *awsLambdaHandler) SelectAdapter(mode string) interface{} {
switch strings.ToUpper(mode) {
case "APIGATEWAYV1":
case strings.ToUpper(config.LambdaAdapterAPIGatewayV1):
return h.HandlerAPIGatewayV1
case "ALB":
case strings.ToUpper(config.LambdaAdapterALB):
return h.HandlerALB
default:
return h.HandlerAPIGatewayV2
Expand Down
4 changes: 2 additions & 2 deletions cmd/relayproxy/api/lambda_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func TestAwsLambdaHandler_GetAdapter(t *testing.T) {
require.NoError(t, err)

// Create a Lambda handler
handler := lambda.NewHandler(apiServer.getLambdaHandler())
handler := lambda.NewHandler(apiServer.lambdaHandler())

// Invoke the handler with the mock event
response, err := handler.Invoke(context.Background(), reqJSON)
Expand Down Expand Up @@ -216,7 +216,7 @@ func TestAwsLambdaHandler_BasePathSupport(t *testing.T) {
require.NoError(t, err)

// Create a Lambda handler
handler := lambda.NewHandler(apiServer.getLambdaHandler())
handler := lambda.NewHandler(apiServer.lambdaHandler())

// Invoke the handler with the mock event
response, err := handler.Invoke(context.Background(), reqJSON)
Expand Down
8 changes: 4 additions & 4 deletions cmd/relayproxy/api/routes_goff.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import (
)

func (s *Server) addGOFFRoutes(
cAllFlags controller.Controller,
cFlagEval controller.Controller,
cEvalDataCollector controller.Controller,
cFlagChange controller.Controller,
cAllFlags,
cFlagEval,
cEvalDataCollector,
cFlagChange,
cFlagConfiguration controller.Controller) {
// Grouping the routes
v1 := s.apiEcho.Group("/v1")
Expand Down
2 changes: 1 addition & 1 deletion cmd/relayproxy/api/routes_monitoring.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func (s *Server) addMonitoringRoutes() {
if s.config.GetMonitoringPort(s.zapLog) != 0 {
if s.config.EffectiveMonitoringPort(s.zapLog) != 0 {
s.monitoringEcho = echo.New()
s.monitoringEcho.HideBanner = true
s.monitoringEcho.HidePort = true
Expand Down
3 changes: 2 additions & 1 deletion cmd/relayproxy/api/routes_monitoring_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func TestPprofEndpointsStarts(t *testing.T) {
Metrics: metric.Metrics{},
}, z)

portToCheck := c.GetServerPort(z)
portToCheck := c.ServerPort(z)
if tt.MonitoringPort != 0 {
portToCheck = tt.MonitoringPort
}
Expand All @@ -77,6 +77,7 @@ func TestPprofEndpointsStarts(t *testing.T) {
defer apiServer.Stop(context.Background())
time.Sleep(1 * time.Second) // waiting for the apiServer to start
resp, err := http.Get(fmt.Sprintf("http://localhost:%d/debug/pprof/heap", portToCheck))
defer func() { _ = resp.Body.Close() }()
require.NoError(t, err)
require.Equal(t, tt.expectedStatusCode, resp.StatusCode)
})
Expand Down
20 changes: 10 additions & 10 deletions cmd/relayproxy/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func (s *Server) StartWithContext(ctx context.Context) {
// we can continue because otel is not mandatory to start the server
}

switch s.config.GetServerMode(s.zapLog) {
switch s.config.ServerMode(s.zapLog) {
case config.ServerModeLambda:
s.startAwsLambda()
case config.ServerModeUnixSocket:
Expand All @@ -134,7 +134,7 @@ func (s *Server) StartWithContext(ctx context.Context) {

// startUnixSocketServer launch the API server as a unix socket.
func (s *Server) startUnixSocketServer(ctx context.Context) {
socketPath := s.config.GetUnixSocketPath()
socketPath := s.config.UnixSocketPath()

// Clean up the old socket file if it exists (important for graceful restarts)
if _, err := os.Stat(socketPath); err == nil {
Expand Down Expand Up @@ -181,7 +181,7 @@ func (s *Server) startAsHTTPServer() {
defer func() { _ = s.monitoringEcho.Close() }()
}

address := fmt.Sprintf("%s:%d", s.config.GetServerHost(), s.config.GetServerPort(s.zapLog))
address := fmt.Sprintf("%s:%d", s.config.ServerHost(), s.config.ServerPort(s.zapLog))
s.zapLog.Info(
"Starting go-feature-flag relay proxy ...",
zap.String("address", address),
Expand All @@ -194,7 +194,7 @@ func (s *Server) startAsHTTPServer() {
}

func (s *Server) startMonitoringServer() {
addressMonitoring := fmt.Sprintf("%s:%d", s.config.GetServerHost(), s.config.GetMonitoringPort(s.zapLog))
addressMonitoring := fmt.Sprintf("%s:%d", s.config.ServerHost(), s.config.EffectiveMonitoringPort(s.zapLog))
s.zapLog.Info(
"Starting monitoring",
zap.String("address", addressMonitoring))
Expand All @@ -206,15 +206,15 @@ func (s *Server) startMonitoringServer() {

// startAwsLambda is starting the relay proxy as an AWS Lambda
func (s *Server) startAwsLambda() {
lambda.Start(s.getLambdaHandler())
lambda.Start(s.lambdaHandler())
}

// getLambdaHandler returns the appropriate lambda handler based on the configuration.
// lambdaHandler returns the appropriate lambda handler based on the configuration.
// We need a dedicated function because it is called from tests as well, this is the
// reason why we can't merged it in startAwsLambda.
func (s *Server) getLambdaHandler() interface{} {
handlerMngr := newAwsLambdaHandlerManager(s.apiEcho, s.config.GetAwsApiGatewayBasePath(s.zapLog))
return handlerMngr.GetAdapter(s.config.GetLambdaAdapter(s.zapLog))
func (s *Server) lambdaHandler() interface{} {
handlerMngr := newAwsLambdaHandlerManager(s.apiEcho, s.config.EffectiveAwsApiGatewayBasePath(s.zapLog))
return handlerMngr.SelectAdapter(s.config.LambdaAdapter(s.zapLog))
}

// Stop shutdown the API server
Expand All @@ -241,5 +241,5 @@ func (s *Server) Stop(ctx context.Context) {

// isMonitoringPortConfigured checks if the monitoring port is configured.
func (s *Server) isMonitoringPortConfigured() bool {
return s.monitoringEcho != nil && s.config.GetMonitoringPort(s.zapLog) > 0
return s.monitoringEcho != nil && s.config.EffectiveMonitoringPort(s.zapLog) > 0
}
Loading
Loading