add cli subcommands
Some checks are pending
Lint / golangci-lint (push) Waiting to run
Declarative Tests / test (push) Waiting to run
Declarative Tests / build-fedora (push) Waiting to run
Declarative Tests / build-ubuntu-focal (push) Waiting to run

This commit is contained in:
Matthew Rich 2024-09-25 04:41:26 +00:00
parent 21e9525e76
commit 614b4426c2
2 changed files with 85 additions and 12 deletions

View File

@ -9,6 +9,7 @@ _ "decl/internal/fan"
_ "decl/internal/config" _ "decl/internal/config"
_ "decl/internal/resource" _ "decl/internal/resource"
"decl/internal/fs" "decl/internal/fs"
"decl/internal/builtin"
_ "errors" _ "errors"
"fmt" "fmt"
"context" "context"
@ -34,6 +35,16 @@ func NewClient() *App {
return a return a
} }
// Load compiled-in config documents.
func (a *App) BuiltInConfiguration() (err error) {
var defaultConfigurations []data.Document
if defaultConfigurations, err = builtin.BuiltInDocuments(); len(defaultConfigurations) > 0 {
slog.Info("Client.BuiltInConfiguration()", "documents", defaultConfigurations, "error", err)
a.Config.AppendConfigurations(defaultConfigurations)
}
return
}
// Load config documents from default system config path. Ignore if missing. // Load config documents from default system config path. Ignore if missing.
func (a *App) SystemConfiguration(configPath string) (err error) { func (a *App) SystemConfiguration(configPath string) (err error) {
var extractor data.Converter var extractor data.Converter
@ -48,6 +59,7 @@ func (a *App) SystemConfiguration(configPath string) (err error) {
u := folio.URI(fmt.Sprintf("file://%s", path)) u := folio.URI(fmt.Sprintf("file://%s", path))
if ! file.IsDir() { if ! file.IsDir() {
slog.Info("Client.SystemConfiguration()", "uri", u)
if extractor, loadErr = folio.DocumentRegistry.ConverterTypes.New(string(u)); loadErr == nil { if extractor, loadErr = folio.DocumentRegistry.ConverterTypes.New(string(u)); loadErr == nil {
if sourceResource, loadErr = u.NewResource(nil); loadErr == nil { if sourceResource, loadErr = u.NewResource(nil); loadErr == nil {
if loaded, loadErr = extractor.(data.ManyExtractor).ExtractMany(sourceResource, nil); loadErr == nil { if loaded, loadErr = extractor.(data.ManyExtractor).ExtractMany(sourceResource, nil); loadErr == nil {
@ -153,11 +165,14 @@ func (a *App) Apply(ctx context.Context, deleteResources bool) (err error) {
} }
d.ResolveIds(ctx) d.ResolveIds(ctx)
_ = d.Apply("stat")
if ! d.CheckConstraints() { if ! d.CheckConstraints() {
slog.Info("Client.Apply() document constrains failed", "requires", d) slog.Info("Client.Apply() document constraints failed", "requires", d)
continue continue
} }
slog.Info("Client.Apply()", "document", d, "state", overrideState, "error", err)
if e := d.(*folio.Document).Apply(overrideState); e != nil { if e := d.(*folio.Document).Apply(overrideState); e != nil {
slog.Info("Client.Apply() error", "error", e) slog.Info("Client.Apply() error", "error", e)
return e return e
@ -256,9 +271,12 @@ func (a *App) DiffCmd(docs []string) (err error) {
output := os.Stdout output := os.Stdout
var leftDocuments, rightDocuments []data.Document var leftDocuments, rightDocuments []data.Document
var rightSource folio.URI
//leftSource := folio.URI(docs[0]) //leftSource := folio.URI(docs[0])
rightSource := folio.URI(docs[1]) if len(docs) > 1 {
rightSource = folio.URI(docs[1])
}
if leftDocuments, err = a.ImportSource(docs[0]); err == nil { if leftDocuments, err = a.ImportSource(docs[0]); err == nil {
if rightSource.IsEmpty() { if rightSource.IsEmpty() {
@ -266,13 +284,34 @@ func (a *App) DiffCmd(docs []string) (err error) {
_, err = doc.DiffState(output) _, err = doc.DiffState(output)
} }
} else { } else {
rightDocuments, err = a.ImportSource(docs[1]) if rightDocuments, err = a.ImportSource(docs[1]); err == nil {
err = a.Diff(leftDocuments, rightDocuments) err = a.Diff(leftDocuments, rightDocuments)
} }
} }
}
return err return err
} }
func (a *App) ConfigCmd(docs []string, includeSystemConfig bool) (err error) {
if err = a.BuiltInConfiguration(); err != nil {
slog.Warn("BuiltInConfiguration()", "error", err)
}
if err = a.Import(docs); err != nil {
return
}
if err = a.LoadDocumentImports(); err != nil {
return
}
if includeSystemConfig {
_, err = a.emitter.Emit(a.Config, nil)
}
_, err = a.emitter.(data.ManyEmitter).EmitMany(a.Documents, nil)
return
}
func (a *App) Quiet() (err error) { func (a *App) Quiet() (err error) {
output := os.Stdout output := os.Stdout
for _, d := range a.Documents { for _, d := range a.Documents {

View File

@ -28,8 +28,7 @@ var ProcessTestGroupName string
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
LoggerConfig() LoggerConfig()
var err error err := TempDir.Create()
err = TempDir.Create()
if err != nil || TempDir == "" { if err != nil || TempDir == "" {
log.Fatal(err) log.Fatal(err)
} }
@ -161,12 +160,12 @@ func TestClientEmit(t *testing.T) {
func BenchmarkClientSystemConfigurations(b *testing.B) { func BenchmarkClientSystemConfigurations(b *testing.B) {
assert.Nil(b, TempDir.Mkdir("benchconfig", 0700)) assert.Nil(b, TempDir.Mkdir("benchconfig", 0700))
ConfDir := tempdir.Path(TempDir.FilePath("benchconfig")) ConfDir := tempdir.Path(TempDir.FilePath("benchconfig"))
ConfDir.CreateFile("cfg.jx.yaml", ` assert.Nil(b, ConfDir.CreateFile("cfg.jx.yaml", `
configurations: configurations:
- name: files - name: files
values: values:
prefix: /usr prefix: /usr
`) `))
configDirURI := fmt.Sprintf("file://%s", ConfDir) configDirURI := fmt.Sprintf("file://%s", ConfDir)
@ -174,7 +173,7 @@ configurations:
b.Run("systemconfiguration", func(b *testing.B) { b.Run("systemconfiguration", func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
c := NewClient() c := NewClient()
c.SystemConfiguration(configDirURI) _ = c.SystemConfiguration(configDirURI)
} }
}) })
programLevel.Set(slog.LevelDebug) programLevel.Set(slog.LevelDebug)
@ -187,12 +186,12 @@ func TestClientSystemConfiguration(t *testing.T) {
assert.Nil(t, TempDir.Mkdir("config", 0700)) assert.Nil(t, TempDir.Mkdir("config", 0700))
ConfDir := tempdir.Path(TempDir.FilePath("config")) ConfDir := tempdir.Path(TempDir.FilePath("config"))
ConfDir.CreateFile("cfg.jx.yaml", ` assert.Nil(t, ConfDir.CreateFile("cfg.jx.yaml", `
configurations: configurations:
- name: files - name: files
values: values:
prefix: /usr prefix: /usr
`) `))
//configDirURI := fmt.Sprintf("file://%s", ConfDir) //configDirURI := fmt.Sprintf("file://%s", ConfDir)
configErr := c.SystemConfiguration(string(ConfDir)) configErr := c.SystemConfiguration(string(ConfDir))
@ -207,5 +206,40 @@ configurations:
value, valueErr := cfg.GetValue("prefix") value, valueErr := cfg.GetValue("prefix")
assert.Nil(t, valueErr) assert.Nil(t, valueErr)
assert.Equal(t, "/usr", value.(string)) assert.Equal(t, "/usr", value.(string))
return }
func TestClientApply(t *testing.T) {
ctx := context.Background()
c := NewClient()
assert.NotNil(t, c)
assert.Nil(t, TempDir.Mkdir("apply", 0700))
ApplyDir := tempdir.Path(TempDir.FilePath("apply"))
DocSource := ApplyDir.FilePath("res.jx.yaml")
TestFile := ApplyDir.FilePath("testfile.txt")
assert.Nil(t, ApplyDir.CreateFile("res.jx.yaml", fmt.Sprintf(`
resources:
- type: file
transition: create
attributes:
path: %s
content: |
a test string
owner: %s
group: %s
mode: 0644
`, TestFile, ProcessTestUserName, ProcessTestGroupName)))
assert.Nil(t, c.Import([]string{DocSource}))
assert.Nil(t, c.LoadDocumentImports())
assert.Nil(t, c.Apply(ctx, false))
assert.FileExists(t, TestFile)
assert.Nil(t, c.Apply(ctx, true))
assert.NoFileExists(t, TestFile)
} }