Skip to content

Commit db42180

Browse files
committed
Adds scaffold command to generate OpenDeps manifest from OpenAPI specification files.
1 parent 8ea2de1 commit db42180

14 files changed

Lines changed: 278 additions & 44 deletions

File tree

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,25 @@ Flags:
7272
-s, --server stringToString Override server base URL for a dependency (e.g. foo_service=https://example.com) (default [])
7373
```
7474

75+
Create an OpenDeps manifest based on OpenAPI files:
76+
77+
```
78+
Creates an OpenDeps manifest based on the OpenAPI specification files in a directory.
79+
80+
If DIR is not specified, the current working directory is used.
81+
82+
Usage:
83+
opendeps scaffold DIR [flags]
84+
85+
Flags:
86+
-f, --force-overwrite Force overwrite of destination file(s) if already exist
87+
-h, --help help for scaffold
88+
```
89+
7590
Validate OpenDeps file:
7691

7792
```
78-
Validates a YAML file against the OpenDeps schema.
93+
Validates a YAML manifest file against the OpenDeps schema.
7994
8095
Usage:
8196
opendeps validate OPENDEPS_FILE

cmd/mock.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
16+
1617
package cmd
1718

1819
import (

cmd/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
16+
1617
package cmd
1718

1819
import (

cmd/scaffold.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
Copyright © 2021 Pete Cornish <outofcoffee@gmail.com>
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package cmd
18+
19+
import (
20+
"gatehill.io/imposter/fileutil"
21+
imposteropenapi "gatehill.io/imposter/openapi"
22+
"github.com/sirupsen/logrus"
23+
"gopkg.in/yaml.v2"
24+
"opendeps.org/opendeps/model"
25+
"opendeps.org/opendeps/openapi"
26+
"os"
27+
"path/filepath"
28+
"strings"
29+
30+
"github.com/spf13/cobra"
31+
)
32+
33+
var flagForceOverwrite bool
34+
35+
// scaffoldCmd represents the scaffold command
36+
var scaffoldCmd = &cobra.Command{
37+
Use: "scaffold DIR",
38+
Short: "Create an OpenDeps manifest based on OpenAPI files",
39+
Long: `Creates an OpenDeps manifest based on the OpenAPI specification files in a directory.
40+
41+
If DIR is not specified, the current working directory is used.`,
42+
Args: cobra.RangeArgs(0, 1),
43+
Run: func(cmd *cobra.Command, args []string) {
44+
var specDir string
45+
if len(args) == 0 {
46+
specDir = "."
47+
} else {
48+
specDir = args[0]
49+
}
50+
specDir, err := filepath.Abs(specDir)
51+
if err != nil {
52+
logrus.Fatal(err)
53+
}
54+
55+
scaffoldManifest(specDir, flagForceOverwrite)
56+
},
57+
}
58+
59+
func init() {
60+
scaffoldCmd.Flags().BoolVarP(&flagForceOverwrite, "force-overwrite", "f", false, "Force overwrite of destination file(s) if already exist")
61+
rootCmd.AddCommand(scaffoldCmd)
62+
}
63+
64+
func scaffoldManifest(specDir string, forceOverwrite bool) {
65+
openApiSpecs := imposteropenapi.DiscoverOpenApiSpecs(specDir)
66+
logrus.Infof("found %d OpenAPI spec(s)", len(openApiSpecs))
67+
68+
manifest := model.OpenDeps{
69+
OpenDeps: model.OpenDepsSchemaVersion,
70+
Info: &model.Info{
71+
Title: "OpenDeps manifest for " + filepath.Base(specDir),
72+
Version: "1.0.0",
73+
},
74+
Dependencies: make(map[string]model.Dependency),
75+
}
76+
77+
for _, openApiSpec := range openApiSpecs {
78+
spec, err := openapi.Parse(openApiSpec)
79+
if err != nil {
80+
logrus.Fatalf("error parsing openapi spec: %v: %v", openApiSpec, err)
81+
}
82+
83+
depName := strings.TrimSuffix(filepath.Base(openApiSpec), filepath.Ext(openApiSpec))
84+
manifest.Dependencies[depName] = model.Dependency{
85+
Summary: spec.Info.Title,
86+
Spec: "./" + filepath.Base(openApiSpec),
87+
Version: spec.Info.Version,
88+
Availability: &model.Availability{
89+
Path: determineAvailabilityPath(spec),
90+
},
91+
}
92+
}
93+
94+
manifestFileName := fileutil.GenerateFilenameAdjacentToFile(specDir, filepath.Join(specDir, "opendeps"), ".yaml", forceOverwrite)
95+
manifestPath := filepath.Join(specDir, manifestFileName)
96+
97+
file, err := os.Create(manifestPath)
98+
if err != nil {
99+
logrus.Fatalf("error creating opendeps manifest file: %v: %v", manifestPath, err)
100+
}
101+
defer file.Close()
102+
103+
marshalled, err := yaml.Marshal(manifest)
104+
_, err = file.Write(marshalled)
105+
if err != nil {
106+
logrus.Fatalf("error writing opendeps manifest file: %v: %v", manifestPath, err)
107+
}
108+
109+
logrus.Infof("wrote OpenDeps manifest file: %v", manifestPath)
110+
}
111+
112+
func determineAvailabilityPath(spec *openapi.PartialModel) string {
113+
for path, operations := range spec.Paths {
114+
if _, found := operations["get"]; found {
115+
return path
116+
}
117+
}
118+
return "/"
119+
}

cmd/test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
16+
1617
package cmd
1718

1819
import (

cmd/validate.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
16+
1617
package cmd
1718

1819
import (
@@ -31,7 +32,7 @@ import (
3132
var validateCmd = &cobra.Command{
3233
Use: "validate OPENDEPS_FILE",
3334
Short: "Validate a file against the OpenDeps schema",
34-
Long: `Validates a YAML file against the OpenDeps schema.`,
35+
Long: `Validates a YAML manifest file against the OpenDeps schema.`,
3536
Args: cobra.RangeArgs(0, 1),
3637
Run: func(cmd *cobra.Command, args []string) {
3738
specFile, err := fileutil.FindSpecFile(args)

fileutil/fileutil.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
Copyright © 2021 Pete Cornish <outofcoffee@gmail.com>
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
117
package fileutil
218

319
import (

fileutil/specfile.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
Copyright © 2021 Pete Cornish <outofcoffee@gmail.com>
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
117
package fileutil
218

319
import (

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ require (
4343
github.com/opencontainers/go-digest v1.0.0 // indirect
4444
github.com/opencontainers/image-spec v1.0.1 // indirect
4545
github.com/pkg/errors v0.9.1 // indirect
46+
github.com/radovskyb/watcher v1.0.7 // indirect
4647
golang.org/x/net v0.0.0-20210825183410-e898025ed96a // indirect
4748
google.golang.org/genproto v0.0.0-20210830153122-0bac4d21c8ea // indirect
4849
google.golang.org/grpc v1.40.0 // indirect

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,7 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
596596
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
597597
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
598598
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
599+
github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE=
599600
github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg=
600601
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
601602
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=

0 commit comments

Comments
 (0)