mirror of https://github.com/open-feature/cli.git
Merge branch 'main' of https://github.com/Adityasinghvats/cli
This commit is contained in:
commit
80e07f092e
|
|
@ -4,6 +4,7 @@ on:
|
|||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
merge_group:
|
||||
|
||||
permissions:
|
||||
# Required: allow read access to the content for analysis.
|
||||
|
|
@ -28,4 +29,4 @@ jobs:
|
|||
uses: golangci/golangci-lint-action@v6
|
||||
with:
|
||||
version: v1.64
|
||||
only-new-issues: true
|
||||
only-new-issues: true
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ jobs:
|
|||
go-version-file: 'go.mod'
|
||||
|
||||
- name: Run all integration tests with Dagger
|
||||
uses: dagger/dagger-for-github@v5
|
||||
uses: dagger/dagger-for-github@b81317a976cb7f7125469707321849737cd1b3bc # v7
|
||||
with:
|
||||
workdir: .
|
||||
verb: run
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM alpine:3.21
|
||||
FROM alpine:3.22
|
||||
|
||||
COPY ./openfeature usr/local/bin/openfeature
|
||||
|
||||
|
|
|
|||
5
Makefile
5
Makefile
|
|
@ -10,6 +10,11 @@ test-integration-csharp:
|
|||
@echo "Running C# integration test with Dagger..."
|
||||
@go run ./test/integration/cmd/csharp/run.go
|
||||
|
||||
.PHONY: test-integration-go
|
||||
test-integration-go:
|
||||
@echo "Running Go integration test with Dagger..."
|
||||
@go run ./test/integration/cmd/go/run.go
|
||||
|
||||
.PHONY: test-integration
|
||||
test-integration:
|
||||
@echo "Running all integration tests with Dagger..."
|
||||
|
|
|
|||
14
go.mod
14
go.mod
|
|
@ -3,18 +3,18 @@ module github.com/open-feature/cli
|
|||
go 1.23.0
|
||||
|
||||
require (
|
||||
dagger.io/dagger v0.18.9
|
||||
dagger.io/dagger v0.18.10
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/iancoleman/strcase v0.3.0
|
||||
github.com/invopop/jsonschema v0.13.0
|
||||
github.com/pterm/pterm v0.12.80
|
||||
github.com/pterm/pterm v0.12.81
|
||||
github.com/spf13/afero v1.14.0
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/pflag v1.0.6
|
||||
github.com/spf13/viper v1.20.1
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
golang.org/x/text v0.25.0
|
||||
golang.org/x/text v0.26.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ require (
|
|||
atomicgo.dev/cursor v0.2.0 // indirect
|
||||
atomicgo.dev/keyboard v0.2.9 // indirect
|
||||
atomicgo.dev/schedule v0.1.0 // indirect
|
||||
github.com/99designs/gqlgen v0.17.73 // indirect
|
||||
github.com/99designs/gqlgen v0.17.74 // indirect
|
||||
github.com/Khan/genqlient v0.8.1 // indirect
|
||||
github.com/adrg/xdg v0.5.3 // indirect
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
|
|
@ -75,12 +75,12 @@ require (
|
|||
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250530174510-65e920069ea6 // indirect
|
||||
golang.org/x/net v0.40.0 // indirect
|
||||
golang.org/x/sync v0.14.0 // indirect
|
||||
golang.org/x/net v0.41.0 // indirect
|
||||
golang.org/x/sync v0.15.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/term v0.32.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
|
||||
google.golang.org/grpc v1.72.2 // indirect
|
||||
google.golang.org/grpc v1.73.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
)
|
||||
|
|
|
|||
14
go.sum
14
go.sum
|
|
@ -8,8 +8,12 @@ atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs=
|
|||
atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU=
|
||||
dagger.io/dagger v0.18.9 h1:IXZhlGm893LuqYFpo6VHtaCAEP6Qz0VjMhLvyKQVl1Y=
|
||||
dagger.io/dagger v0.18.9/go.mod h1:e6Y+sAPWh04pHvBf4s3sSiOe1QMoCEcccmMv898RnZA=
|
||||
dagger.io/dagger v0.18.10 h1:Ibyz5LqxjjEHfLMlaU9PJ3xt3ju7p29RWy0lVfvSNU0=
|
||||
dagger.io/dagger v0.18.10/go.mod h1:VSj+2HMd/EnaCVt7gTY70p8LBW+oQDYjA1XTadr8vBE=
|
||||
github.com/99designs/gqlgen v0.17.73 h1:A3Ki+rHWqKbAOlg5fxiZBnz6OjW3nwupDHEG15gEsrg=
|
||||
github.com/99designs/gqlgen v0.17.73/go.mod h1:2RyGWjy2k7W9jxrs8MOQthXGkD3L3oGr0jXW3Pu8lGg=
|
||||
github.com/99designs/gqlgen v0.17.74 h1:1FuVtkXxOc87xpKio3f6sohREmec+Jvy86PcYOuwgWo=
|
||||
github.com/99designs/gqlgen v0.17.74/go.mod h1:a+iR6mfRLNRp++kDpooFHiPWYiWX3Yu1BIilQRHgh10=
|
||||
github.com/Khan/genqlient v0.8.1 h1:wtOCc8N9rNynRLXN3k3CnfzheCUNKBcvXmVv5zt6WCs=
|
||||
github.com/Khan/genqlient v0.8.1/go.mod h1:R2G6DzjBvCbhjsEajfRjbWdVglSH/73kSivC9TLWVjU=
|
||||
github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs=
|
||||
|
|
@ -106,6 +110,8 @@ github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5b
|
|||
github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s=
|
||||
github.com/pterm/pterm v0.12.80 h1:mM55B+GnKUnLMUSqhdINe4s6tOuVQIetQ3my8JGyAIg=
|
||||
github.com/pterm/pterm v0.12.80/go.mod h1:c6DeF9bSnOSeFPZlfs4ZRAFcf5SCoTwvwQ5xaKGQlHo=
|
||||
github.com/pterm/pterm v0.12.81 h1:ju+j5I2++FO1jBKMmscgh5h5DPFDFMB7epEjSoKehKA=
|
||||
github.com/pterm/pterm v0.12.81/go.mod h1:TyuyrPjnxfwP+ccJdBTeWHtd/e0ybQHkOS/TakajZCw=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
|
|
@ -206,11 +212,15 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
|
|||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
|
||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
|
||||
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
||||
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
|
||||
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -238,6 +248,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
|||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
|
|
@ -249,6 +261,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:
|
|||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8=
|
||||
google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
||||
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
|
||||
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageReference Include="OpenFeature" Version="2.3.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.6" />
|
||||
<PackageReference Include="OpenFeature" Version="2.6.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
module github.com/open-feature/cli/test/go-integration
|
||||
|
||||
go 1.22
|
||||
|
||||
require github.com/open-feature/go-sdk v1.15.0
|
||||
|
||||
require (
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
google.golang.org/protobuf v1.32.0 // indirect
|
||||
)
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
generated "github.com/open-feature/cli/test/go-integration/openfeature"
|
||||
"github.com/open-feature/go-sdk/openfeature"
|
||||
"github.com/open-feature/go-sdk/openfeature/memprovider"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func run() error {
|
||||
// Set up the in-memory provider with test flags
|
||||
provider := memprovider.NewInMemoryProvider(map[string]memprovider.InMemoryFlag{
|
||||
"discountPercentage": {
|
||||
State: memprovider.Enabled,
|
||||
DefaultVariant: "default",
|
||||
Variants: map[string]any{
|
||||
"default": 0.15,
|
||||
},
|
||||
},
|
||||
"enableFeatureA": {
|
||||
State: memprovider.Enabled,
|
||||
DefaultVariant: "default",
|
||||
Variants: map[string]any{
|
||||
"default": false,
|
||||
},
|
||||
},
|
||||
"greetingMessage": {
|
||||
State: memprovider.Enabled,
|
||||
DefaultVariant: "default",
|
||||
Variants: map[string]any{
|
||||
"default": "Hello there!",
|
||||
},
|
||||
},
|
||||
"usernameMaxLength": {
|
||||
State: memprovider.Enabled,
|
||||
DefaultVariant: "default",
|
||||
Variants: map[string]any{
|
||||
"default": 50,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Set the provider and wait for it to be ready
|
||||
err := openfeature.SetProviderAndWait(provider)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to set provider: %w", err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
evalCtx := openfeature.NewEvaluationContext("someid", map[string]any{})
|
||||
|
||||
// Use the generated code for all flag evaluations
|
||||
enableFeatureA, err := generated.EnableFeatureA.Value(ctx, evalCtx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error evaluating boolean flag: %w", err)
|
||||
}
|
||||
fmt.Printf("enableFeatureA: %v\n", enableFeatureA)
|
||||
|
||||
discount, err := generated.DiscountPercentage.Value(ctx, evalCtx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to get discount: %w", err)
|
||||
}
|
||||
fmt.Printf("Discount Percentage: %.2f\n", discount)
|
||||
|
||||
greetingMessage, err := generated.GreetingMessage.Value(ctx, evalCtx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error evaluating string flag: %w", err)
|
||||
}
|
||||
fmt.Printf("greetingMessage: %v\n", greetingMessage)
|
||||
|
||||
usernameMaxLength, err := generated.UsernameMaxLength.Value(ctx, evalCtx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error evaluating int flag: %v\n", err)
|
||||
}
|
||||
fmt.Printf("usernameMaxLength: %v\n", usernameMaxLength)
|
||||
|
||||
fmt.Println("Generated Go code compiles successfully!")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"dagger.io/dagger"
|
||||
"github.com/open-feature/cli/test/integration"
|
||||
)
|
||||
|
||||
// Test implements the integration test for the Go generator
|
||||
type Test struct {
|
||||
// ProjectDir is the absolute path to the root of the project
|
||||
ProjectDir string
|
||||
// TestDir is the absolute path to the test directory
|
||||
TestDir string
|
||||
}
|
||||
|
||||
// New creates a new Test
|
||||
func New(projectDir, testDir string) *Test {
|
||||
return &Test{
|
||||
ProjectDir: projectDir,
|
||||
TestDir: testDir,
|
||||
}
|
||||
}
|
||||
|
||||
// Run executes the Go integration test using Dagger
|
||||
func (t *Test) Run(ctx context.Context, client *dagger.Client) (*dagger.Container, error) {
|
||||
// Source code container
|
||||
source := client.Host().Directory(t.ProjectDir)
|
||||
testFiles := client.Host().Directory(t.TestDir, dagger.HostDirectoryOpts{
|
||||
Include: []string{"test.go", "go.mod"},
|
||||
})
|
||||
|
||||
// Build the CLI
|
||||
cli := client.Container().
|
||||
From("golang:1.23-alpine").
|
||||
WithExec([]string{"apk", "add", "--no-cache", "git"}).
|
||||
WithDirectory("/src", source).
|
||||
WithWorkdir("/src").
|
||||
WithExec([]string{"go", "mod", "tidy"}).
|
||||
WithExec([]string{"go", "mod", "download"}).
|
||||
WithExec([]string{"go", "build", "-o", "cli", "./cmd/openfeature"})
|
||||
|
||||
// Generate Go client
|
||||
generated := cli.WithExec([]string{
|
||||
"./cli", "generate", "go",
|
||||
"--manifest=/src/sample/sample_manifest.json",
|
||||
"--output=/tmp/generated",
|
||||
"--package-name=openfeature",
|
||||
})
|
||||
|
||||
// Get generated files
|
||||
generatedFiles := generated.Directory("/tmp/generated")
|
||||
|
||||
// Test Go compilation with the generated files
|
||||
goContainer := client.Container().
|
||||
From("golang:1.23-alpine").
|
||||
WithExec([]string{"apk", "add", "--no-cache", "git"}).
|
||||
WithWorkdir("/app").
|
||||
WithDirectory("/app", testFiles).
|
||||
WithDirectory("/app/openfeature", generatedFiles).
|
||||
WithExec([]string{"go", "mod", "tidy"}).
|
||||
WithExec([]string{"go", "build", "-o", "test", "-v"}).
|
||||
WithExec([]string{"./test"})
|
||||
|
||||
return goContainer, nil
|
||||
}
|
||||
|
||||
// Name returns the name of the integration test
|
||||
func (t *Test) Name() string {
|
||||
return "go"
|
||||
}
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
// Get project root
|
||||
projectDir, err := filepath.Abs(os.Getenv("PWD"))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to get project dir: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Get test directory
|
||||
testDir, err := filepath.Abs(filepath.Join(projectDir, "test/go-integration"))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to get test dir: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Create and run the Go integration test
|
||||
test := New(projectDir, testDir)
|
||||
|
||||
if err := integration.RunTest(ctx, test); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,15 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Run the Go integration test
|
||||
goCmd := exec.Command("go", "run", "github.com/open-feature/cli/test/integration/cmd/go")
|
||||
goCmd.Stdout = os.Stdout
|
||||
goCmd.Stderr = os.Stderr
|
||||
if err := goCmd.Run(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error running Go integration test: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Add more tests here as they are available
|
||||
|
||||
fmt.Println("=== All integration tests passed successfully ===")
|
||||
|
|
|
|||
Loading…
Reference in New Issue