Skip to content

Commit

Permalink
chore: stable schema registry (#51)
Browse files Browse the repository at this point in the history
* chore: stable schema registry

* chore: multiple case

* chore: refactor

* chore: 6 characters at most
  • Loading branch information
ThomasRooney authored Aug 15, 2024
1 parent 56f5ce4 commit d4dbb10
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 40 deletions.
82 changes: 50 additions & 32 deletions workflow/source.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package workflow

import (
"crypto/sha256"
"fmt"
"math/rand"
"os"
"path/filepath"
"slices"
"strings"

"github.com/speakeasy-api/sdk-gen-config/workspace"
Expand Down Expand Up @@ -129,41 +129,59 @@ func (s Source) Validate() error {
}

func (s Source) GetOutputLocation() (string, error) {
// If we have an output location, we can just return that
if s.Output != nil {
output := *s.Output
if s.Output != nil {
if len(s.Inputs) > 1 && !isYAMLFile(*s.Output) {
return "", fmt.Errorf("when merging multiple inputs, output must be a yaml file")
}
return *s.Output, nil
}

if len(s.Inputs) == 1 && len(s.Overlays) == 0 {
return s.handleSingleInput()
}

return s.generateOutputPath()
}

ext := filepath.Ext(output)
if len(s.Inputs) > 1 && !slices.Contains([]string{".yaml", ".yml"}, ext) {
return "", fmt.Errorf("when merging multiple inputs, output must be a yaml file")
}
func (s Source) handleSingleInput() (string, error) {
input := s.Inputs[0].Location
switch getFileStatus(input) {
case fileStatusLocal:
return input, nil
case fileStatusNotExists:
return "", fmt.Errorf("input file %s does not exist", input)
case fileStatusRemote, fileStatusRegistry:
return s.generateRegistryPath(input)
default:
return "", fmt.Errorf("unknown file status for %s", input)
}
}

return output, nil
}
func (s Source) generateRegistryPath(input string) (string, error) {
ext := filepath.Ext(input)
if ext == "" {
ext = ".yaml"
}
hash := fmt.Sprintf("%x", sha256.Sum256([]byte(input)))
return filepath.Join(GetTempDir(), fmt.Sprintf("registry_%s%s", hash[:6], ext)), nil
}

ext := ".yaml"

// If we only have a single input, no overlays and its a local path, we can just use that
if len(s.Inputs) == 1 && len(s.Overlays) == 0 {
inputFile := s.Inputs[0].Location

switch getFileStatus(inputFile) {
case fileStatusRegistry:
return filepath.Join(GetTempDir(), fmt.Sprintf("registry_%s", randStringBytes(10))), nil
case fileStatusLocal:
return inputFile, nil
case fileStatusNotExists:
return "", fmt.Errorf("input file %s does not exist", inputFile)
case fileStatusRemote:
ext = filepath.Ext(inputFile)
if ext == "" {
ext = ".yaml"
}
}
}
func (s Source) generateOutputPath() (string, error) {
hashInputs := func() string {
var combined string
for _, input := range s.Inputs {
combined += input.Location
}
hash := sha256.Sum256([]byte(combined))
return fmt.Sprintf("%x", hash)[:6]
}

return filepath.Join(GetTempDir(), fmt.Sprintf("output_%s.yaml", hashInputs())), nil
}

// Otherwise output will go to a temp file
return filepath.Join(GetTempDir(), fmt.Sprintf("output_%s%s", randStringBytes(10), ext)), nil
func isYAMLFile(path string) bool {
ext := filepath.Ext(path)
return ext == ".yaml" || ext == ".yml"
}

func GetTempDir() string {
Expand Down
12 changes: 4 additions & 8 deletions workflow/source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,10 +356,6 @@ func TestSource_Validate(t *testing.T) {
}

func TestSource_GetOutputLocation(t *testing.T) {
workflow.SetRandStringBytesFunc(func(n int) string {
return "testrandomstring"
})

type args struct {
source workflow.Source
}
Expand Down Expand Up @@ -392,7 +388,7 @@ func TestSource_GetOutputLocation(t *testing.T) {
},
},
},
wantOutputLocation: ".speakeasy/temp/output_testrandomstring.json",
wantOutputLocation: ".speakeasy/temp/registry_e8ba45.json",
},
{
name: "simple remote source without extension returns auto-generated output location assumed to be yaml",
Expand All @@ -405,7 +401,7 @@ func TestSource_GetOutputLocation(t *testing.T) {
},
},
},
wantOutputLocation: ".speakeasy/temp/output_testrandomstring.yaml",
wantOutputLocation: ".speakeasy/temp/registry_94359d.yaml",
},
{
name: "source with multiple inputs returns specified output location",
Expand Down Expand Up @@ -438,7 +434,7 @@ func TestSource_GetOutputLocation(t *testing.T) {
},
},
},
wantOutputLocation: ".speakeasy/temp/output_testrandomstring.yaml",
wantOutputLocation: ".speakeasy/temp/output_6a0196.yaml",
},
{
name: "source with overlays returns specified output location",
Expand Down Expand Up @@ -471,7 +467,7 @@ func TestSource_GetOutputLocation(t *testing.T) {
},
},
},
wantOutputLocation: ".speakeasy/temp/output_testrandomstring.yaml",
wantOutputLocation: ".speakeasy/temp/output_d910ba.yaml",
},
}
for _, tt := range tests {
Expand Down

0 comments on commit d4dbb10

Please sign in to comment.