Skip to content
This repository has been archived by the owner on Sep 15, 2024. It is now read-only.

feat: common configuration package #46

Merged
merged 11 commits into from
Apr 12, 2021
Merged
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
!/internal/repository/
/repository.yaml
/blox
/_build/
/_build/
cli/blox/blox
File renamed without changes.
32 changes: 16 additions & 16 deletions cmd/blox_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,12 @@ var buildCmd = &cobra.Command{
Use: "build",
Short: "Validate and build your data",
Run: func(cmd *cobra.Command, args []string) {
// This can happen at a global Cobra level, if I knew how
config, err := cuedb.NewRuntime()
cobra.CheckErr(err)
cobra.CheckErr(config.LoadConfig())

runtime, err := cuedb.NewRuntime()
engine, err := cuedb.NewEngine()
cobra.CheckErr(err)

// Load Schemas!
schemaDir, err := config.GetString("schema_dir")
schemaDir, err := engine.Config.GetString("schema_dir")
pterm.Debug.Printf("\t\tSchema Directory: %s\n", schemaDir)
cobra.CheckErr(err)

err = filepath.WalkDir(schemaDir, func(path string, d fs.DirEntry, err error) error {
Expand All @@ -46,35 +42,37 @@ var buildCmd = &cobra.Command{
if err != nil {
return err
}
pterm.Debug.Printf("\t\tLoading Schema: %s\n", path)

err = runtime.RegisterSchema(string(bb))
err = engine.RegisterSchema(string(bb))
if err != nil {
return err
}
}
return nil
})
cobra.CheckErr(err)
pterm.Debug.Println("\t\tBuilding Models")

cobra.CheckErr(buildModels(&config, &runtime))
cobra.CheckErr(buildModels(engine))

if referentialIntegrity {
pterm.Info.Println("Checking Referential Integrity")
err = runtime.ReferentialIntegrity()
err = engine.ReferentialIntegrity()
if err != nil {
pterm.Error.Println(err)
} else {
pterm.Success.Println("Foreign Keys Validated")
}
}

output, err := runtime.GetOutput()
output, err := engine.GetOutput()
cobra.CheckErr(err)

jso, err := output.MarshalJSON()
cobra.CheckErr(err)

buildDir, err := config.GetString("build_dir")
buildDir, err := engine.Config.GetString("build_dir")
cobra.CheckErr(err)
err = os.MkdirAll(buildDir, 0755)
cobra.CheckErr(err)
Expand All @@ -86,15 +84,17 @@ var buildCmd = &cobra.Command{
},
}

func buildModels(config *cuedb.Runtime, runtime *cuedb.Runtime) error {
func buildModels(engine *cuedb.Engine) error {
var errors error

pterm.Info.Println("Validating ...")

for _, dataSet := range runtime.GetDataSets() {
for _, dataSet := range engine.GetDataSets() {
pterm.Debug.Printf("\t\tDataset: %s\n", dataSet.ID())

// We're using the Or variant of GetString because we know this call can't
// fail, as the config isn't valid without.
dataSetDirectory := fmt.Sprintf("%s/%s", config.GetStringOr("data_dir", ""), dataSet.GetDataDirectory())
dataSetDirectory := fmt.Sprintf("%s/%s", engine.Config.GetStringOr("data_dir", ""), dataSet.GetDataDirectory())

err := os.MkdirAll(dataSetDirectory, 0755)
if err != nil {
Expand Down Expand Up @@ -148,7 +148,7 @@ func buildModels(config *cuedb.Runtime, runtime *cuedb.Runtime) error {
record := make(map[string]interface{})
record[slug] = istruct

err = runtime.Insert(dataSet, record)
err = engine.Insert(dataSet, record)
if err != nil {
return multierror.Append(err)
}
Expand Down
6 changes: 2 additions & 4 deletions cmd/remote_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,10 @@ to quickly create a Cobra application.`,
}
}
}
config, err := cuedb.NewRuntime()
engine, err := cuedb.NewEngine()
cobra.CheckErr(err)
cobra.CheckErr(config.LoadConfig())

cobra.CheckErr(err)
schemaDir := config.GetStringOr("schema_dir", "schema")
schemaDir := engine.Config.GetStringOr("schema_dir", "schema")

err = os.MkdirAll(schemaDir, 0755)
cobra.CheckErr(err)
Expand Down
1 change: 1 addition & 0 deletions cmd/repo_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) {
repo, err := repository.GetRepository()
cobra.CheckErr(err)
pterm.Info.Println("Building Repository")
cobra.CheckErr(repo.Build())
pterm.Success.Println("Build Complete")
},
Expand Down
76 changes: 76 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package blox

import (
"fmt"
"io/ioutil"

"cuelang.org/go/cue"
"github.com/pterm/pterm"
)

type Config struct {
*Runtime
bketelsen marked this conversation as resolved.
Show resolved Hide resolved
}

// New setup a new config type with
// base as the defaults
func NewConfig(base string) (*Config, error) {
r, err := NewRuntimeWithBase(base)
if err != nil {
return nil, err
}
config := &Config{
Runtime: r,
}

return config, nil
}

// LoadConfig opens the configuration file
// specified in `path` and validates it against
// the configuration provided in when the `Engine`
// was initialized with `New()`
func (r *Config) LoadConfig(path string) error {
pterm.Debug.Printf("\t\tLoading config: %s\n", path)
cueConfig, err := ioutil.ReadFile(path)
if err != nil {
return err
}

return r.LoadConfigString(string(cueConfig))
}

func (r *Config) LoadConfigString(cueConfig string) error {
cueInstance, err := r.CueRuntime.Compile("", cueConfig)
if err != nil {
return err
}

cueValue := cueInstance.Value()

r.Database = r.Database.Unify(cueValue)
if err = r.Database.Validate(); err != nil {
return err
}

return nil
}
func (r *Config) GetString(key string) (string, error) {
keyValue := r.Database.LookupPath(cue.ParsePath(key))

if keyValue.Exists() {
return keyValue.String()
}

return "", fmt.Errorf("couldn't find key '%s'", key)
}

func (r *Config) GetStringOr(key string, def string) string {
cueValue, err := r.GetString(key)

if err != nil {
return def
}

return cueValue
}
20 changes: 17 additions & 3 deletions internal/cuedb/config_test.go → config_test.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,40 @@
package cuedb
package blox

import (
"testing"

"github.com/stretchr/testify/assert"
)

const base = `{
data_dir: string
schema_dir: string | *"schemas"
build_dir: string | *"_build"
}
`

func TestGetString(t *testing.T) {
runtime, err := NewRuntime()
runtime, err := NewConfig(base)

if err != nil {
t.Fatal("Failed to create a NewRuntime, which should never happen")
}

err = runtime.loadConfigString(`{
err = runtime.LoadConfigString(`{
data_dir: "my-data-dir"
}`)
assert.Equal(t, nil, err)

// test non-existent key
_, err = runtime.GetString("data_dir_non_exist")
assert.NotEqual(t, nil, err)

// test defaulted key
schDir, err := runtime.GetString("schema_dir")
assert.Equal(t, nil, err)
assert.Equal(t, "schemas", schDir)

// test parsed key
configString, err := runtime.GetString("data_dir")
assert.Equal(t, nil, err)
assert.Equal(t, "my-data-dir", configString)
Expand Down
5 changes: 0 additions & 5 deletions internal/config/config.cue

This file was deleted.

8 changes: 0 additions & 8 deletions internal/config/config.go

This file was deleted.

55 changes: 0 additions & 55 deletions internal/cuedb/config.go

This file was deleted.

68 changes: 68 additions & 0 deletions internal/cuedb/dataset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package cuedb

import (
"fmt"

"cuelang.org/go/cue"
)

// Can't use schemaField, yet.
const SchemaMetadataCue = `{
_schema: {
namespace: string
name: string
}
}`

type SchemaMetadata struct {
Namespace string
Name string
}

// Can't use dataSetField, yet.
const DataSetMetadataCue = `{
_dataset: {
plural: string
supportedExtensions: [...string]
}
}`

type DataSetMetadata struct {
Plural string
SupportedExtensions []string
}

type DataSet struct {
name string
schemaMetadata SchemaMetadata
cuePath cue.Path
metadata DataSetMetadata
}

// AddDataMap
func (d *DataSet) GetDataMapCue() string {
return fmt.Sprintf(`{
%s: %s: _
%s: %s: [ID=string]: %s.%s & {id: (ID)}
}`,
d.GetInlinePath(), d.name,
dataPathRoot, d.metadata.Plural, d.cuePath.String(), d.name,
)
}
func (d *DataSet) CueDataPath() cue.Path {
return cue.ParsePath(fmt.Sprintf("%s.%s", dataPathRoot, d.metadata.Plural))
}

func (d *DataSet) IsSupportedExtension(ext string) bool {
for _, val := range d.metadata.SupportedExtensions {
if val == ext {
return true
}
}

return false
}

func (d *DataSet) GetSupportedExtensions() []string {
return d.metadata.SupportedExtensions
}
Loading