From f180d59232f49c0e12c05327ef873788a29aca0a Mon Sep 17 00:00:00 2001 From: adohe Date: Mon, 19 Feb 2024 17:08:44 +0800 Subject: [PATCH] WIP: add code runner for configuration code execution --- pkg/cmd/generate/run/fake.go | 1 + pkg/cmd/generate/run/run.go | 71 ++++++++++++++++++++++++++++++++ pkg/cmd/generate/run/run_test.go | 1 + 3 files changed, 73 insertions(+) create mode 100644 pkg/cmd/generate/run/fake.go create mode 100644 pkg/cmd/generate/run/run.go create mode 100644 pkg/cmd/generate/run/run_test.go diff --git a/pkg/cmd/generate/run/fake.go b/pkg/cmd/generate/run/fake.go new file mode 100644 index 000000000..bbe6ec607 --- /dev/null +++ b/pkg/cmd/generate/run/fake.go @@ -0,0 +1 @@ +package run diff --git a/pkg/cmd/generate/run/run.go b/pkg/cmd/generate/run/run.go new file mode 100644 index 000000000..0eb934732 --- /dev/null +++ b/pkg/cmd/generate/run/run.go @@ -0,0 +1,71 @@ +package run + +import ( + kcl "kcl-lang.io/kcl-go" + kclpkg "kcl-lang.io/kcl-go/pkg/kcl" + "kcl-lang.io/kpm/pkg/api" + "kcl-lang.io/kpm/pkg/opt" +) + +// CodeRunner compiles and runs the target DSL based configuration code +// and returns configuration data in plain format. +type CodeRunner interface { + Run(workingDir string, arguments map[string]string) ([]byte, error) +} + +// KPMRunner should implement the CodeRunner interface. +var _ CodeRunner = &KPMRunner{} + +// KPMRunner implements the CodeRunner interface. +type KPMRunner struct{} + +// Run calls KPM api to compile and run KCL based configuration code. +func (r *KPMRunner) Run(workingDir string, arguments map[string]string) ([]byte, error) { + optList, err := buildKCLOptions(workingDir, arguments) + if err != nil { + return nil, err + } + + result, err := api.RunWithOpts( + opt.WithKclOption(*kclpkg.NewOption().Merge(optList...)), + opt.WithNoSumCheck(true), + opt.WithLogWriter(nil), + ) + if err != nil { + return nil, err + } + + return []byte(result.GetRawYamlResult()), nil +} + +// buildKCLOptions returns list of KCL options. +func buildKCLOptions(workingDir string, arguments map[string]string) ([]kcl.Option, error) { + optList := make([]kcl.Option, 0) + + // build arguments option + for k, v := range arguments { + argStr := k + "=" + v + withOpt := kcl.WithOptions(argStr) + if withOpt.Err != nil { + return nil, withOpt.Err + } + + optList = append(optList, withOpt) + } + + // build workDir option + withOpt := kcl.WithWorkDir(workingDir) + if withOpt.Err != nil { + return nil, withOpt.Err + } + optList = append(optList, withOpt) + + // eliminate null values in the result + withOpt = kcl.WithDisableNone(true) + if withOpt.Err != nil { + return nil, withOpt.Err + } + optList = append(optList, withOpt) + + return optList, nil +} diff --git a/pkg/cmd/generate/run/run_test.go b/pkg/cmd/generate/run/run_test.go new file mode 100644 index 000000000..bbe6ec607 --- /dev/null +++ b/pkg/cmd/generate/run/run_test.go @@ -0,0 +1 @@ +package run