-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: function to normalize the spec
Signed-off-by: Johannes Würbach <[email protected]>
- Loading branch information
1 parent
b611331
commit 2f2e139
Showing
4 changed files
with
159 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ Reference library for the parsing and loading SCORE files in Go. | |
This can be added to your project via: | ||
|
||
```sh | ||
$ go get -u github.com/score-spec/score-go@latest | ||
go get -u github.com/score-spec/score-go@latest | ||
``` | ||
|
||
**NOTE**: if you project is still using the hand-written types, you will need to stay on `github.com/score-spec/[email protected]` | ||
|
@@ -17,58 +17,61 @@ This library includes a few utility methods to parse source SCORE files. | |
|
||
```go | ||
import ( | ||
"io" | ||
"os" | ||
|
||
"github.com/score-spec/score-go/loader" | ||
"github.com/score-spec/score-go/schema" | ||
score "github.com/score-spec/score-go/types" | ||
) | ||
|
||
func main() { | ||
var ( | ||
err error | ||
src io.Reader | ||
) | ||
src, err := os.Open("score.yaml") | ||
if err != nil { | ||
panic(err) | ||
} | ||
defer src.Close() | ||
|
||
if src, err = os.Open("score.yaml"); err != nil { | ||
var srcMap map[string]interface{} | ||
if err := loader.ParseYAML(&srcMap, src); err != nil { | ||
panic(err) | ||
} | ||
defer src.Close() | ||
|
||
var srcMap map[string]interface{} | ||
if err = loader.ParseYAML(&srcMap, src); err != nil { | ||
if err := schema.Validate(srcMap); err != nil { | ||
panic(err) | ||
} | ||
|
||
var spec score.Workload | ||
if err := loader.MapSpec(&spec, srcMap); err != nil { | ||
panic(err) | ||
} | ||
|
||
var spec score.WorkloadSpec | ||
if err = loader.MapSpec(&spec, srcMap); err != nil { | ||
if err := loader.Normalize(&spec, "."); err != nil { | ||
panic(err) | ||
} | ||
|
||
// Do something with the spec | ||
// ... | ||
} | ||
|
||
``` | ||
|
||
## Upgrading the schema version | ||
|
||
When the Score JSON schema is updated in https://github.com/score-spec/schema, this repo should be updated to match. | ||
When the Score JSON schema is updated in <https://github.com/score-spec/schema>, this repo should be updated to match. | ||
|
||
First update the subtree: | ||
|
||
``` | ||
```sh | ||
make update-schema | ||
``` | ||
|
||
Then regenerate the defined types: | ||
|
||
``` | ||
```sh | ||
make generate | ||
``` | ||
|
||
And ensure the tests still pass: | ||
|
||
``` | ||
```sh | ||
go test -v ./... | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Hello World |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package loader | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/score-spec/score-go/types" | ||
) | ||
|
||
// Normalize normalizes the target Workload by: | ||
// * embedding container file sources as content | ||
func Normalize(w *types.Workload, baseDir string) error { | ||
for name, c := range w.Containers { | ||
for i, f := range c.Files { | ||
if f.Source != nil { | ||
raw, err := readFile(baseDir, *f.Source) | ||
if err != nil { | ||
return fmt.Errorf("embedding file '%s' for container '%s': %w", *f.Source, name, err) | ||
} | ||
|
||
c.Files[i].Source = nil | ||
c.Files[i].Content = &raw | ||
} | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// readFile reads a text file into memory | ||
func readFile(baseDir, path string) (string, error) { | ||
if !filepath.IsAbs(path) { | ||
path = filepath.Join(baseDir, path) | ||
} | ||
|
||
raw, err := os.ReadFile(path) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return string(raw), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package loader | ||
|
||
import ( | ||
"errors" | ||
"io" | ||
"testing" | ||
|
||
"github.com/score-spec/score-go/types" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestNormalize(t *testing.T) { | ||
var tests = []struct { | ||
Name string | ||
Source io.Reader | ||
Input *types.Workload | ||
Output *types.Workload | ||
Error error | ||
}{ | ||
{ | ||
Name: "Embeds source file", | ||
Input: &types.Workload{ | ||
ApiVersion: "score.dev/v1b1", | ||
Metadata: types.WorkloadMetadata{ | ||
"name": "hello-world", | ||
}, | ||
Containers: types.WorkloadContainers{ | ||
"hello": types.Container{ | ||
Files: []types.ContainerFilesElem{ | ||
{ | ||
Source: stringRef("./test_file.txt"), | ||
Target: "/etc/hello-world/config.yaml", | ||
Mode: stringRef("666"), | ||
NoExpand: boolRef(true), | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
Output: &types.Workload{ | ||
ApiVersion: "score.dev/v1b1", | ||
Metadata: types.WorkloadMetadata{ | ||
"name": "hello-world", | ||
}, | ||
Containers: types.WorkloadContainers{ | ||
"hello": types.Container{ | ||
Files: []types.ContainerFilesElem{ | ||
{ | ||
Target: "/etc/hello-world/config.yaml", | ||
Mode: stringRef("666"), | ||
Content: stringRef("Hello World\n"), | ||
NoExpand: boolRef(true), | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
Name: "Errors when the source file does not exist", | ||
Input: &types.Workload{ | ||
ApiVersion: "score.dev/v1b1", | ||
Metadata: types.WorkloadMetadata{ | ||
"name": "hello-world", | ||
}, | ||
Containers: types.WorkloadContainers{ | ||
"hello": types.Container{ | ||
Files: []types.ContainerFilesElem{ | ||
{ | ||
Source: stringRef("./not_existing.txt"), | ||
Target: "/etc/hello-world/config.yaml", | ||
Mode: stringRef("666"), | ||
NoExpand: boolRef(true), | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
Error: errors.New("embedding file './not_existing.txt' for container 'hello': open fixtures/not_existing.txt: no such file or directory"), | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.Name, func(t *testing.T) { | ||
var err = Normalize(tt.Input, "./fixtures") | ||
if tt.Error != nil { | ||
assert.EqualError(t, err, tt.Error.Error()) | ||
} else { | ||
assert.NoError(t, err) | ||
assert.Equal(t, tt.Output, tt.Input) | ||
} | ||
}) | ||
} | ||
} |