Skip to content

Commit cac1f24

Browse files
committed
feat(generators): treat Client/client as reserved symbols with collision warning
Flag keys that transform to a reserved generator symbol (Client in Go, client in Node.js) are excluded from the generated output and a warning is emitted at generation time. Documents the reserved symbols per generator in the generators README.
1 parent 4b95162 commit cac1f24

3 files changed

Lines changed: 67 additions & 1 deletion

File tree

internal/generators/README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,23 @@ To add a new generator, follow these steps:
5555
6. Write tests for your generator to ensure it works as expected.
5656
7. Update the documentation to include information about your new generator.
5757

58-
We appreciate your contributions and look forward to seeing your new generators!
58+
We appreciate your contributions and look forward to seeing your new generators!
59+
60+
## Reserved Keywords
61+
62+
Each generator reserves certain symbol names that it exports in the generated output. If a flag key transforms to a reserved name, that flag will be **excluded** from the generated output and a warning will be printed.
63+
64+
| Generator | Reserved names | Transform applied |
65+
|-----------|---------------|-------------------|
66+
| Go | `Client` | `ToPascal` |
67+
| Node.js | `client` | `ToCamel` |
68+
69+
For example, a flag key `"client"` in a Go manifest would transform to `Client` (via `ToPascal`), colliding with the exported `var Client` that the Go generator places in every generated file. The flag will be skipped and the following warning emitted:
70+
71+
```
72+
Flag "client" transforms to "Client" which is a reserved symbol in the Go generator. This flag will be excluded from the generated output.
73+
```
74+
75+
To avoid this, rename any flags whose transformed name matches a reserved symbol.
76+
77+
When adding a new generator, document its reserved names in the table above and enforce them in the generator's `Generate()` method using the same pattern.

internal/generators/golang/golang.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import (
1010
"strings"
1111
"text/template"
1212

13+
"github.com/iancoleman/strcase"
1314
"github.com/open-feature/cli/internal/flagset"
1415
"github.com/open-feature/cli/internal/generators"
16+
"github.com/open-feature/cli/internal/logger"
1517
"golang.org/x/tools/imports"
1618
)
1719

@@ -128,7 +130,28 @@ func formatNestedValue(value any) string {
128130
}
129131
}
130132

133+
// reservedNames are symbols exported by the Go generator itself. Flag keys
134+
// that transform (via ToPascal) to one of these names will be excluded from
135+
// the generated output and a warning will be emitted.
136+
var reservedNames = map[string]bool{
137+
"Client": true,
138+
}
139+
131140
func (g *GolangGenerator) Generate(params *generators.Params[Params]) error {
141+
filtered := &flagset.Flagset{}
142+
for _, flag := range g.Flagset.Flags {
143+
transformed := strcase.ToCamel(flag.Key)
144+
if reservedNames[transformed] {
145+
logger.Default.Warning(fmt.Sprintf(
146+
"Flag %q transforms to %q which is a reserved symbol in the Go generator. This flag will be excluded from the generated output.",
147+
flag.Key, transformed,
148+
))
149+
continue
150+
}
151+
filtered.Flags = append(filtered.Flags, flag)
152+
}
153+
g.Flagset = filtered
154+
132155
funcs := template.FuncMap{
133156
"SupportImports": supportImports,
134157
"OpenFeatureType": openFeatureType,

internal/generators/nodejs/nodejs.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ package nodejs
33
import (
44
_ "embed"
55
"encoding/json"
6+
"fmt"
67
"text/template"
78

9+
"github.com/iancoleman/strcase"
810
"github.com/open-feature/cli/internal/flagset"
911
"github.com/open-feature/cli/internal/generators"
12+
"github.com/open-feature/cli/internal/logger"
1013
)
1114

1215
type NodejsGenerator struct {
@@ -43,7 +46,28 @@ func toJSONString(value any) string {
4346
return string(bytes)
4447
}
4548

49+
// reservedNames are symbols exported by the Node.js generator itself. Flag
50+
// keys that transform (via ToCamel) to one of these names will be excluded
51+
// from the generated output and a warning will be emitted.
52+
var reservedNames = map[string]bool{
53+
"client": true,
54+
}
55+
4656
func (g *NodejsGenerator) Generate(params *generators.Params[Params]) error {
57+
filtered := &flagset.Flagset{}
58+
for _, flag := range g.Flagset.Flags {
59+
transformed := strcase.ToLowerCamel(flag.Key)
60+
if reservedNames[transformed] {
61+
logger.Default.Warning(fmt.Sprintf(
62+
"Flag %q transforms to %q which is a reserved symbol in the Node.js generator. This flag will be excluded from the generated output.",
63+
flag.Key, transformed,
64+
))
65+
continue
66+
}
67+
filtered.Flags = append(filtered.Flags, flag)
68+
}
69+
g.Flagset = filtered
70+
4771
funcs := template.FuncMap{
4872
"OpenFeatureType": openFeatureType,
4973
"ToJSONString": toJSONString,

0 commit comments

Comments
 (0)