Skip to content

Commit 2e2ea94

Browse files
feat: Ignore top-level keys started with x-
Currently, go-feature-flag doesn't support reusable targeting conditions out of the box. So we cannot define set of rules ```yaml my-custom-group: - query: role eq "admin" - query: group eq "QA" - query: email eq "custom@example.com" ... my-flag: targeting: - query: my-custom-group eq true variation: enabled ``` But something similar can be achieved using YAML anchors. The issue with this approach is go-feature-flag treats every top-level key as a flag. So this is invalid configuration because my-custom-group is invalid flag: ```yaml x-custom-group: &x-custom-group - query: role eq "admin" variation: enabled - query: group eq "QA" variation: enabled - query: email eq "custom@example.com" variation: enabled ... my-flag: variations: enabled: true disabled: false targeting: - *x-custom-group defaultRule: variation: disabled ``` It is possible to define anchors as part of the flag and then reuse it, but it lowers readability of the config file. Usually, YAML consumers ignores keys started with `x-`. E.g. docker compose does this since 2017, openapi allows `x-` keys for extending schema since it was swagger, etc. So this commit brings this approach into `go-feature-flag`. Now we can define top-level anchors started with `x-` and reuse these snippets to define multiple flags. I've decided to ignore `x-` keys for JSON and TOML too. E.g. for JSON it might be used as a comment, so there is still value provided. And it is nice to be able to transparently convert flags definition between formats so they remain valid.
1 parent 42f2ccd commit 2e2ea94

2 files changed

Lines changed: 14 additions & 8 deletions

File tree

cmd/cli/helper/read_config_file.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,22 @@ func readConfigFile(configFile, configFormat string) (map[string]dto.DTO, error)
6666
if err != nil {
6767
return nil, fmt.Errorf("%s: could not parse file (toml): %w", configFile, err)
6868
}
69-
return flags, nil
7069
case "json":
7170
err := json.Unmarshal(dat, &flags)
7271
if err != nil {
7372
return nil, fmt.Errorf("%s: could not parse file (json): %w", configFile, err)
7473
}
75-
return flags, nil
7674
default:
7775
// default is YAML
7876
err := yaml.Unmarshal(dat, &flags)
7977
if err != nil {
8078
return nil, fmt.Errorf("%s: could not parse file (yaml): %w", configFile, err)
8179
}
82-
return flags, nil
8380
}
81+
for key := range flags {
82+
if strings.HasPrefix(key, "x-") {
83+
delete(flags, key)
84+
}
85+
}
86+
return flags, nil
8487
}

testdata/flag-config.yaml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,20 @@ test-flag:
1616
description: this is a simple feature flag
1717
issue-link: https://jira.xxx/GOFF-01
1818

19+
x-reusable-targeting: &x-reusable-targeting
20+
name: rule1
21+
query: key eq "not-a-key"
22+
percentage:
23+
False: 0
24+
True: 100
25+
1926
test-flag2:
2027
variations:
2128
Default: false
2229
False: false
2330
True: true
2431
targeting:
25-
- name: rule1
26-
query: key eq "not-a-key"
27-
percentage:
28-
False: 0
29-
True: 100
32+
- *x-reusable-targeting
3033
defaultRule:
3134
name: defaultRule
3235
variation: Default

0 commit comments

Comments
 (0)