Skip to content

Commit

Permalink
Add generator for openapi (#27)
Browse files Browse the repository at this point in the history
* Add generator for openapi

* Add property to path schema

* Added reference MR for the generator changes
  • Loading branch information
tirthct authored Nov 29, 2023
1 parent 8609f7d commit 2c58209
Show file tree
Hide file tree
Showing 5 changed files with 405 additions and 11 deletions.
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,5 +216,20 @@ EOF

### Make a new Kind

1. Add to openapi.yaml
2. Generate the new structs/clients (`make generate`)
Generator scripts can be used to auto generate a new Kind. Run the following command to generate a new kind:
```shell
go run ./scripts/generator.go --kind KindName
```

Following manual changes are required to run the application successfully:
- `pkg/api/presenters/kind.go` : Add case statement for the kind
- `pkg/api/presenters/path.go` : Add case statement for the kind
- `pkg/api/presenters/` : Add presenters file (if missing)
- `cmd/trex/environments/service_types.go` : Add new service locator for the kind
- `cmd/trex/environments/types.go` : Add service locator and use `cmd/trex/environments/framework.go` to instantiate
- `cmd/trex/server/routes.go` : Add service routes (if missing)
- Add validation methods in handler if required
- `pkg/db/migrations/migration_structs.go` : Add migration name
- `test/factories.go` : Add helper functions

Here's a reference MR for the same : https://github.com/openshift-online/rh-trex/pull/25
2 changes: 2 additions & 0 deletions openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ paths:
$ref: '#/components/schemas/Error'
parameters:
- $ref: '#/components/parameters/id'
# AUTO-ADD NEW PATHS
components:
securitySchemes:
Bearer:
Expand Down Expand Up @@ -267,6 +268,7 @@ components:
properties:
species:
type: string
# AUTO-ADD NEW SCHEMAS
parameters:
id:
name: id
Expand Down
77 changes: 76 additions & 1 deletion scripts/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"bufio"
"bytes"
"flag"
"fmt"
"os"
Expand All @@ -25,7 +26,13 @@ TODO: all of it can be better
*/

var (
kind string = "Asteroid"
kind string = "Asteroid"
openapiEndpointStart string = "# NEW ENDPOINT START"
openapiEndpointEnd string = "# NEW ENDPOINT END"
openApiSchemaStart string = "# NEW SCHEMA START"
openApiSchemaEnd string = "# NEW SCHEMA END"
openApiEndpointMatchingLine string = " # AUTO-ADD NEW PATHS"
openApiSchemaMatchingLine string = " # AUTO-ADD NEW SCHEMAS"
)

func init() {
Expand All @@ -47,6 +54,8 @@ func main() {
"mock",
"migration",
"test",
"handlers",
"openapi-kind",
}

for _, nm := range templates {
Expand Down Expand Up @@ -78,6 +87,8 @@ func main() {
outPath = fmt.Sprintf("pkg/db/migrations/%s_add_%s.go", k.ID, k.KindLowerPlural)
} else if strings.Contains(nm, "test") {
outPath = fmt.Sprintf("test/integration/%s_test.go", k.KindLowerPlural)
} else if strings.Contains(nm, "openapi") {
outPath = fmt.Sprintf("openapi/openapi.%s.yaml", k.KindLowerPlural)
} else {
outPath = fmt.Sprintf("pkg/%s/%s.go", nm, k.KindLowerSingular)
}
Expand All @@ -95,6 +106,10 @@ func main() {
}
w.Flush()
f.Sync()

if strings.Contains(nm, "openapi") {
modifyOpenapi("openapi/openapi.yaml", fmt.Sprintf("openapi/openapi.%s.yaml", k.KindLowerPlural))
}
}
}

Expand All @@ -112,3 +127,63 @@ type myWriter struct {
KindLowerSingular string
ID string
}

func modifyOpenapi(mainPath string, kindPath string) {
endpointStrings := readBetweenLines(kindPath, openapiEndpointStart, openapiEndpointEnd)
kindFileName := strings.Split(kindPath, "/")[1]
for _, line := range endpointStrings {
endpointStr := strings.TrimSpace(line)
endpointStr = strings.Replace(endpointStr, "/", "~1", -1)
endpointStr = strings.Replace(endpointStr, ":", "", -1)
refPath := fmt.Sprintf(` $ref: '%s#/paths/%s'`, kindFileName, endpointStr)
pathsLine := fmt.Sprintf("%s%s", line, refPath)
writeAfterLine(mainPath, openApiEndpointMatchingLine, pathsLine)
}
schemaStrings := readBetweenLines(kindPath, openApiSchemaStart, openApiSchemaEnd)
for _, line := range schemaStrings {
schemaStr := strings.TrimSpace(line)
schemaStr = strings.Replace(schemaStr, ":", "", -1)
refPath := fmt.Sprintf(` $ref: '%s#/components/schemas/%s'`, kindFileName, schemaStr)
pathsLine := fmt.Sprintf("%s%s", line, refPath)
writeAfterLine(mainPath, openApiSchemaMatchingLine, pathsLine)
}
}

func readBetweenLines(path string, startLine string, endLine string) []string {
readFile, err := os.Open(path)
if err != nil {
fmt.Println(err)
}
fileScanner := bufio.NewScanner(readFile)
fileScanner.Split(bufio.ScanLines)
readFlag := false
var totalMatches []string
var matchedString strings.Builder
for fileScanner.Scan() {
trimmed := strings.TrimSpace(fileScanner.Text())
if trimmed == startLine {
readFlag = true
} else if trimmed == endLine {
readFlag = false
totalMatches = append(totalMatches, matchedString.String())
matchedString.Reset()
} else if readFlag {
matchedString.WriteString(fileScanner.Text() + "\n")
}
}
readFile.Close()
return totalMatches
}

func writeAfterLine(path string, matchingLine string, lineToWrite string) {
input, err := os.ReadFile(path)
if err != nil {
panic(err)
}
_ = strings.Replace(string(input), matchingLine, lineToWrite+"\n"+matchingLine, -1)
output := bytes.Replace(input, []byte(matchingLine), []byte(lineToWrite+"\n"+matchingLine), -1)
if err = os.WriteFile(path, output, 0666); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
Loading

0 comments on commit 2c58209

Please sign in to comment.