Skip to content

Commit 443f8a8

Browse files
fix: add explicit flags for overlay commands to match documentation (#135)
1 parent 0fe6793 commit 443f8a8

5 files changed

Lines changed: 199 additions & 31 deletions

File tree

cmd/openapi/commands/overlay/README.md

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,18 @@ OpenAPI Overlays provide a way to modify OpenAPI and Arazzo specifications witho
3030
Apply an overlay to an OpenAPI specification.
3131

3232
```bash
33-
# Apply overlay to a specification
33+
# Apply overlay to a specification (positional arguments)
34+
openapi overlay apply overlay.yaml spec.yaml
35+
36+
# Apply overlay to a specification (flags)
3437
openapi overlay apply --overlay overlay.yaml --schema spec.yaml
3538

3639
# Apply overlay with output to file
3740
openapi overlay apply --overlay overlay.yaml --schema spec.yaml --out modified-spec.yaml
3841

3942
# Apply overlay when overlay has extends key set
43+
openapi overlay apply overlay.yaml
44+
# or
4045
openapi overlay apply --overlay overlay.yaml
4146
```
4247

@@ -46,17 +51,21 @@ Features:
4651
- Supports all OpenAPI Overlay Specification operations
4752
- Handles complex nested modifications
4853
- Preserves original document structure where not modified
54+
- Supports both positional arguments and explicit flags
4955

5056
### `validate`
5157

5258
Validate an overlay file for compliance with the OpenAPI Overlay Specification.
5359

5460
```bash
55-
# Validate an overlay file
61+
# Validate an overlay file (positional argument)
62+
openapi overlay validate overlay.yaml
63+
64+
# Validate an overlay file (flag)
5665
openapi overlay validate --overlay overlay.yaml
5766

5867
# Validate with verbose output
59-
openapi overlay validate -v --overlay overlay.yaml
68+
openapi overlay validate -v overlay.yaml
6069
```
6170

6271
This command checks for:
@@ -73,11 +82,14 @@ Note: This validates the overlay file structure itself, not whether it will appl
7382
Generate an OpenAPI Overlay specification from two input files.
7483

7584
```bash
76-
# Generate overlay from two specifications
77-
openapi overlay compare --before spec1.yaml --after spec2.yaml --out overlay.yaml
85+
# Generate overlay from two specifications (positional arguments)
86+
openapi overlay compare spec1.yaml spec2.yaml
7887

79-
# Generate overlay with console output
88+
# Generate overlay from two specifications (flags)
8089
openapi overlay compare --before spec1.yaml --after spec2.yaml
90+
91+
# Generate overlay with output to file
92+
openapi overlay compare --before spec1.yaml --after spec2.yaml --out overlay.yaml
8193
```
8294

8395
Features:
@@ -86,6 +98,7 @@ Features:
8698
- Generates overlay operations for all changes
8799
- Provides diagnostic output showing detected changes
88100
- Creates overlay files that can recreate the transformation
101+
- Supports both positional arguments and explicit flags
89102

90103
### `upgrade`
91104

@@ -172,9 +185,24 @@ All commands support these common options:
172185
173186
- `-h, --help`: Show help for the command
174187
- `-v, --verbose`: Enable verbose output (global flag)
175-
- `--overlay`: Path to the overlay file
176-
- `--schema`: Path to the OpenAPI specification (for apply command)
177-
- `--out`: Output file path (optional, defaults to stdout)
188+
189+
Command-specific flags:
190+
191+
**apply command:**
192+
193+
- `--overlay`: Path to the overlay file (alternative to positional argument)
194+
- `--schema`: Path to the OpenAPI specification (alternative to positional argument)
195+
- `-o, --out`: Output file path (optional, defaults to stdout)
196+
197+
**validate command:**
198+
199+
- `--overlay`: Path to the overlay file (alternative to positional argument)
200+
201+
**compare command:**
202+
203+
- `--before`: Path to the first (before) specification file (alternative to positional argument)
204+
- `--after`: Path to the second (after) specification file (alternative to positional argument)
205+
- `-o, --out`: Output file path (optional, defaults to stdout)
178206

179207
## Output Formats
180208

@@ -185,30 +213,39 @@ All commands work with both YAML and JSON input files, but always output YAML at
185213
### Basic Workflow
186214

187215
```bash
188-
# Create an overlay by comparing two specs
216+
# Create an overlay by comparing two specs (using flags)
189217
openapi overlay compare --before original.yaml --after modified.yaml --out changes.overlay.yaml
190218
219+
# Or using positional arguments
220+
openapi overlay compare original.yaml modified.yaml --out changes.overlay.yaml
221+
191222
# Validate the generated overlay
192-
openapi overlay validate --overlay changes.overlay.yaml
223+
openapi overlay validate changes.overlay.yaml
193224
194-
# Apply the overlay to the original spec
225+
# Apply the overlay to the original spec (using flags)
195226
openapi overlay apply --overlay changes.overlay.yaml --schema original.yaml --out final.yaml
227+
228+
# Or using positional arguments
229+
openapi overlay apply changes.overlay.yaml original.yaml --out final.yaml
196230
```
197231

198232
### Environment-Specific Modifications
199233

200234
```bash
201-
# Apply production overlay
235+
# Apply production overlay (using flags)
202236
openapi overlay apply --overlay prod.overlay.yaml --schema base-spec.yaml --out prod-spec.yaml
203237
238+
# Or using positional arguments
239+
openapi overlay apply prod.overlay.yaml base-spec.yaml --out prod-spec.yaml
240+
204241
# Apply development overlay
205-
openapi overlay apply --overlay dev.overlay.yaml --schema base-spec.yaml --out dev-spec.yaml
242+
openapi overlay apply dev.overlay.yaml base-spec.yaml --out dev-spec.yaml
206243
```
207244

208245
### Integration with Other Commands
209246

210247
```bash
211248
# Validate base spec, apply overlay, then validate result
212249
openapi spec validate ./base-spec.yaml
213-
openapi overlay apply --overlay ./modifications.yaml --schema ./base-spec.yaml --out ./modified-spec.yaml
250+
openapi overlay apply ./modifications.yaml ./base-spec.yaml --out ./modified-spec.yaml
214251
openapi spec validate ./modified-spec.yaml

cmd/openapi/commands/overlay/apply.go

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,60 @@ import (
88
"gopkg.in/yaml.v3"
99
)
1010

11+
var (
12+
applyOverlayFlag string
13+
applySchemaFlag string
14+
applyOutFlag string
15+
)
16+
1117
var applyCmd = &cobra.Command{
1218
Use: "apply <overlay> [ <spec> ]",
1319
Short: "Given an overlay, it will apply it to the spec. If omitted, spec will be loaded via extends (only from local file system).",
14-
Args: cobra.RangeArgs(1, 2),
20+
Args: cobra.RangeArgs(0, 2),
1521
Run: RunApply,
22+
Example: ` # Apply overlay using positional arguments
23+
openapi overlay apply overlay.yaml spec.yaml
24+
25+
# Apply overlay using flags
26+
openapi overlay apply --overlay overlay.yaml --schema spec.yaml
27+
28+
# Apply overlay with output to file
29+
openapi overlay apply --overlay overlay.yaml --schema spec.yaml --out modified-spec.yaml
30+
31+
# Apply overlay when overlay has extends key set
32+
openapi overlay apply overlay.yaml`,
33+
}
34+
35+
func init() {
36+
applyCmd.Flags().StringVar(&applyOverlayFlag, "overlay", "", "Path to the overlay file")
37+
applyCmd.Flags().StringVar(&applySchemaFlag, "schema", "", "Path to the OpenAPI specification file")
38+
applyCmd.Flags().StringVarP(&applyOutFlag, "out", "o", "", "Output file path (defaults to stdout)")
1639
}
1740

1841
func RunApply(cmd *cobra.Command, args []string) {
19-
overlayFile := args[0]
42+
// Determine overlay file path from flag or positional argument
43+
var overlayFile string
44+
if applyOverlayFlag != "" {
45+
overlayFile = applyOverlayFlag
46+
} else if len(args) > 0 {
47+
overlayFile = args[0]
48+
} else {
49+
Dief("overlay file is required (use --overlay flag or provide as first argument)")
50+
}
2051

2152
o, err := loader.LoadOverlay(overlayFile)
2253
if err != nil {
2354
Die(err)
2455
}
2556

57+
// Determine spec file path from flag or positional argument
2658
var specFile string
27-
if len(args) > 1 {
59+
if applySchemaFlag != "" {
60+
specFile = applySchemaFlag
61+
} else if len(args) > 1 {
2862
specFile = args[1]
2963
}
64+
3065
ys, specFile, err := loader.LoadEitherSpecification(specFile, o)
3166
if err != nil {
3267
Die(err)
@@ -37,7 +72,18 @@ func RunApply(cmd *cobra.Command, args []string) {
3772
Dief("Failed to apply overlay to spec file %q: %v", specFile, err)
3873
}
3974

40-
err = yaml.NewEncoder(os.Stdout).Encode(ys)
75+
// Write to output file if specified, otherwise stdout
76+
out := os.Stdout
77+
if applyOutFlag != "" {
78+
f, err := os.Create(applyOutFlag)
79+
if err != nil {
80+
Dief("Failed to create output file %q: %v", applyOutFlag, err)
81+
}
82+
defer f.Close()
83+
out = f
84+
}
85+
86+
err = yaml.NewEncoder(out).Encode(ys)
4187
if err != nil {
4288
Dief("Failed to encode spec file %q: %v", specFile, err)
4389
}

cmd/openapi/commands/overlay/compare.go

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,83 @@ import (
99
"github.com/spf13/cobra"
1010
)
1111

12+
var (
13+
compareBeforeFlag string
14+
compareAfterFlag string
15+
compareOutFlag string
16+
)
17+
1218
var compareCmd = &cobra.Command{
1319
Use: "compare <spec1> <spec2>",
1420
Short: "Given two specs, it will output an overlay that describes the differences between them",
15-
Args: cobra.ExactArgs(2),
21+
Args: cobra.RangeArgs(0, 2),
1622
Run: RunCompare,
23+
Example: ` # Compare specs using positional arguments
24+
openapi overlay compare spec1.yaml spec2.yaml
25+
26+
# Compare specs using flags
27+
openapi overlay compare --before spec1.yaml --after spec2.yaml
28+
29+
# Compare specs with output to file
30+
openapi overlay compare --before spec1.yaml --after spec2.yaml --out overlay.yaml`,
31+
}
32+
33+
func init() {
34+
compareCmd.Flags().StringVar(&compareBeforeFlag, "before", "", "Path to the first (before) specification file")
35+
compareCmd.Flags().StringVar(&compareAfterFlag, "after", "", "Path to the second (after) specification file")
36+
compareCmd.Flags().StringVarP(&compareOutFlag, "out", "o", "", "Output file path (defaults to stdout)")
1737
}
1838

1939
func RunCompare(cmd *cobra.Command, args []string) {
20-
y1, err := loader.LoadSpecification(args[0])
40+
// Determine first spec file path from flag or positional argument
41+
var spec1 string
42+
if compareBeforeFlag != "" {
43+
spec1 = compareBeforeFlag
44+
} else if len(args) > 0 {
45+
spec1 = args[0]
46+
} else {
47+
Dief("first specification file is required (use --before flag or provide as first argument)")
48+
}
49+
50+
// Determine second spec file path from flag or positional argument
51+
var spec2 string
52+
if compareAfterFlag != "" {
53+
spec2 = compareAfterFlag
54+
} else if len(args) > 1 {
55+
spec2 = args[1]
56+
} else {
57+
Dief("second specification file is required (use --after flag or provide as second argument)")
58+
}
59+
60+
y1, err := loader.LoadSpecification(spec1)
2161
if err != nil {
22-
Dief("Failed to load %q: %v", args[0], err)
62+
Dief("Failed to load %q: %v", spec1, err)
2363
}
2464

25-
y2, err := loader.LoadSpecification(args[1])
65+
y2, err := loader.LoadSpecification(spec2)
2666
if err != nil {
27-
Dief("Failed to load %q: %v", args[1], err)
67+
Dief("Failed to load %q: %v", spec2, err)
2868
}
2969

30-
title := fmt.Sprintf("Overlay %s => %s", args[0], args[1])
70+
title := fmt.Sprintf("Overlay %s => %s", spec1, spec2)
3171

3272
o, err := overlay.Compare(title, y1, *y2)
3373
if err != nil {
34-
Dief("Failed to compare spec files %q and %q: %v", args[0], args[1], err)
74+
Dief("Failed to compare spec files %q and %q: %v", spec1, spec2, err)
75+
}
76+
77+
// Write to output file if specified, otherwise stdout
78+
out := os.Stdout
79+
if compareOutFlag != "" {
80+
f, err := os.Create(compareOutFlag)
81+
if err != nil {
82+
Dief("Failed to create output file %q: %v", compareOutFlag, err)
83+
}
84+
defer f.Close()
85+
out = f
3586
}
3687

37-
err = o.Format(os.Stdout)
88+
err = o.Format(out)
3889
if err != nil {
3990
Dief("Failed to format overlay: %v", err)
4091
}

cmd/openapi/commands/overlay/validate.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,44 @@ import (
77
"github.com/spf13/cobra"
88
)
99

10+
var validateOverlayFlag string
11+
1012
var validateCmd = &cobra.Command{
1113
Use: "validate <overlay>",
1214
Short: "Given an overlay, it will state whether it appears to be valid or describe the problems found",
13-
Args: cobra.ExactArgs(1),
15+
Args: cobra.RangeArgs(0, 1),
1416
Run: RunValidateOverlay,
17+
Example: ` # Validate overlay using positional argument
18+
openapi overlay validate overlay.yaml
19+
20+
# Validate overlay using flag
21+
openapi overlay validate --overlay overlay.yaml`,
22+
}
23+
24+
func init() {
25+
validateCmd.Flags().StringVar(&validateOverlayFlag, "overlay", "", "Path to the overlay file")
1526
}
1627

1728
func RunValidateOverlay(cmd *cobra.Command, args []string) {
18-
o, err := loader.LoadOverlay(args[0])
29+
// Determine overlay file path from flag or positional argument
30+
var overlayFile string
31+
if validateOverlayFlag != "" {
32+
overlayFile = validateOverlayFlag
33+
} else if len(args) > 0 {
34+
overlayFile = args[0]
35+
} else {
36+
Dief("overlay file is required (use --overlay flag or provide as first argument)")
37+
}
38+
39+
o, err := loader.LoadOverlay(overlayFile)
1940
if err != nil {
2041
Die(err)
2142
}
2243

2344
err = o.Validate()
2445
if err != nil {
25-
Dief("Overlay file %q failed validation:\n%v", args[0], err)
46+
Dief("Overlay file %q failed validation:\n%v", overlayFile, err)
2647
}
2748

28-
fmt.Printf("Overlay file %q is valid.\n", args[0])
49+
fmt.Printf("Overlay file %q is valid.\n", overlayFile)
2950
}

mise-tasks/test-cli

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,19 @@ $CLI overlay compare overlay/testdata/openapi.yaml overlay/testdata/openapi-over
220220
echo " ✓ Validating generated overlay..."
221221
$CLI overlay validate dist/test/test-overlay-generated.yaml > /dev/null
222222

223+
# Test overlay commands with flags
224+
echo " ✓ Testing overlay validate with --overlay flag..."
225+
$CLI overlay validate --overlay overlay/testdata/overlay.yaml > /dev/null
226+
227+
echo " ✓ Testing overlay apply with --overlay and --schema flags..."
228+
$CLI overlay apply --overlay overlay/testdata/overlay.yaml --schema overlay/testdata/openapi.yaml > dist/test/test-overlayed-flags.yaml
229+
230+
echo " ✓ Testing overlay compare with --before and --after flags..."
231+
$CLI overlay compare --before overlay/testdata/openapi.yaml --after overlay/testdata/openapi-overlayed.yaml > dist/test/test-overlay-generated-flags.yaml
232+
233+
echo " ✓ Validating overlay generated with flags..."
234+
$CLI overlay validate --overlay dist/test/test-overlay-generated-flags.yaml > /dev/null
235+
223236
# Test error cases - commands that should fail
224237
echo " ✓ Testing error cases..."
225238

0 commit comments

Comments
 (0)