impr: modular sandbox configs

This commit is contained in:
Anton
2023-12-05 00:53:50 +05:00
parent 07b523cd4d
commit cfe8970ebf
9 changed files with 113 additions and 62 deletions

View File

@@ -1,14 +0,0 @@
{
"sh": {
"run": {
"engine": "docker",
"entry": "main.sh",
"steps": [
{
"box": "alpine",
"command": ["sh", "main.sh"]
}
]
}
}
}

12
configs/commands/sh.json Normal file
View File

@@ -0,0 +1,12 @@
{
"run": {
"engine": "docker",
"entry": "main.sh",
"steps": [
{
"box": "alpine",
"command": ["sh", "main.sh"]
}
]
}
}

View File

@@ -4,12 +4,15 @@ import (
"encoding/json"
"os"
"path/filepath"
"strings"
"github.com/nalgeon/codapi/internal/fileio"
)
const (
configFilename = "config.json"
boxesFilename = "boxes.json"
commandsFilename = "commands.json"
commandsDirname = "commands"
)
// Read reads application config from JSON files.
@@ -24,7 +27,7 @@ func Read(path string) (*Config, error) {
return nil, err
}
cfg, err = ReadCommands(cfg, filepath.Join(path, commandsFilename))
cfg, err = ReadCommands(cfg, filepath.Join(path, commandsDirname))
if err != nil {
return nil, err
}
@@ -71,19 +74,28 @@ func ReadBoxes(cfg *Config, path string) (*Config, error) {
// ReadCommands reads commands config from a JSON file.
func ReadCommands(cfg *Config, path string) (*Config, error) {
data, err := os.ReadFile(path)
fnames, err := filepath.Glob(filepath.Join(path, "*.json"))
if err != nil {
return nil, err
}
commands := make(map[string]SandboxCommands)
err = json.Unmarshal(data, &commands)
cfg.Commands = make(map[string]SandboxCommands, len(fnames))
for _, fname := range fnames {
sandbox := strings.TrimSuffix(filepath.Base(fname), ".json")
commands, err := fileio.ReadJson[SandboxCommands](fname)
if err != nil {
return nil, err
break
}
setCommandDefaults(commands, cfg)
cfg.Commands[sandbox] = commands
}
for _, playCmds := range commands {
for _, cmd := range playCmds {
return cfg, err
}
// setCommandDefaults applies global defaults to sandbox commands.
func setCommandDefaults(commands SandboxCommands, cfg *Config) {
for _, cmd := range commands {
if cmd.Before != nil {
setStepDefaults(cmd.Before, cfg.Step)
}
@@ -94,8 +106,4 @@ func ReadCommands(cfg *Config, path string) (*Config, error) {
setStepDefaults(cmd.After, cfg.Step)
}
}
}
cfg.Commands = commands
return cfg, err
}

View File

@@ -1,25 +0,0 @@
{
"python": {
"run": {
"engine": "docker",
"entry": "main.py",
"steps": [
{
"box": "python",
"command": ["python", "main.py"]
}
]
},
"test": {
"engine": "docker",
"entry": "test_main.py",
"steps": [
{
"box": "python",
"command": ["python", "-m", "unittest"],
"noutput": 8192
}
]
}
}
}

View File

@@ -0,0 +1,23 @@
{
"run": {
"engine": "docker",
"entry": "main.py",
"steps": [
{
"box": "python",
"command": ["python", "main.py"]
}
]
},
"test": {
"engine": "docker",
"entry": "test_main.py",
"steps": [
{
"box": "python",
"command": ["python", "-m", "unittest"],
"noutput": 8192
}
]
}
}

View File

@@ -2,6 +2,7 @@
package fileio
import (
"encoding/json"
"io"
"os"
"path/filepath"
@@ -37,3 +38,17 @@ func CopyFiles(pattern string, dstDir string) error {
return nil
}
// ReadJson reads the file and decodes it from JSON.
func ReadJson[T any](path string) (T, error) {
var obj T
data, err := os.ReadFile(path)
if err != nil {
return obj, err
}
err = json.Unmarshal(data, &obj)
if err != nil {
return obj, err
}
return obj, err
}

View File

@@ -3,6 +3,7 @@ package fileio
import (
"os"
"path/filepath"
"reflect"
"testing"
)
@@ -54,3 +55,30 @@ func TestCopyFiles(t *testing.T) {
t.Errorf("unexpected file content: got %q, want %q", data, expected)
}
}
func TestReadJson(t *testing.T) {
type Person struct{ Name string }
t.Run("valid", func(t *testing.T) {
got, err := ReadJson[Person](filepath.Join("testdata", "valid.json"))
if err != nil {
t.Fatalf("unexpected error %v", err)
}
want := Person{"alice"}
if !reflect.DeepEqual(got, want) {
t.Errorf("expected %v, got %v", want, got)
}
})
t.Run("invalid", func(t *testing.T) {
_, err := ReadJson[Person](filepath.Join("testdata", "invalid.json"))
if err == nil {
t.Fatal("expected error, got nil")
}
})
t.Run("does not exist", func(t *testing.T) {
_, err := ReadJson[Person](filepath.Join("testdata", "missing.json"))
if err == nil {
t.Fatal("expected error, got nil")
}
})
}

1
internal/fileio/testdata/invalid.json vendored Normal file
View File

@@ -0,0 +1 @@
name: alice

3
internal/fileio/testdata/valid.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"name": "alice"
}