Skip to content

Commit

Permalink
feat: support setting KCL setting-files when building an Intent (#649)
Browse files Browse the repository at this point in the history
  • Loading branch information
SparkYuan committed Dec 5, 2023
1 parent 681d5b3 commit f4d08f2
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 48 deletions.
6 changes: 3 additions & 3 deletions go.mod
Expand Up @@ -63,9 +63,9 @@ require (
k8s.io/component-base v0.27.2
k8s.io/kubectl v0.27.1
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
kcl-lang.io/kcl-go v0.6.0-alpha.1
kcl-lang.io/kcl-go v0.7.0
kcl-lang.io/kcl-plugin v0.5.0
kcl-lang.io/kpm v0.3.6
kcl-lang.io/kpm v0.4.2
kusionstack.io/kube-api v0.0.0-20230817144216-4714955f3801
sigs.k8s.io/controller-runtime v0.15.1
)
Expand Down Expand Up @@ -241,7 +241,7 @@ require (
gopkg.in/warnings.v0 v0.1.2 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
kcl-lang.io/kcl-artifact-go v0.6.0-alpha.1 // indirect
kcl-lang.io/kcl-artifact-go v0.7.1 // indirect
lukechampine.com/frand v1.4.2 // indirect
oras.land/oras-go v1.2.3 // indirect
oras.land/oras-go/v2 v2.3.0 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Expand Up @@ -852,14 +852,14 @@ k8s.io/kubectl v0.27.1 h1:9T5c5KdpburYiW8XKQSH0Uly1kMNE90aGSnbYUZNdcA=
k8s.io/kubectl v0.27.1/go.mod h1:QsAkSmrRsKTPlAFzF8kODGDl4p35BIwQnc9XFhkcsy8=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
kcl-lang.io/kcl-artifact-go v0.6.0-alpha.1 h1:RaRbhPGTGbG8s2w0qAh6J3V+TmwfMZtryxiyxVTvLKA=
kcl-lang.io/kcl-artifact-go v0.6.0-alpha.1/go.mod h1:c07mqi9Hu2UjPW7lYfHhAAWOlZiB7lo7Vkr4jL5ov/M=
kcl-lang.io/kcl-go v0.6.0-alpha.1 h1:BhMQ2GNRp9AccWxB2QydvZF6g6iVlPkkSSPa+RAdYx0=
kcl-lang.io/kcl-go v0.6.0-alpha.1/go.mod h1:tHMTzp0dtah8Hn6h6UfnwbrEv737+TKf0xjIJkUkuaU=
kcl-lang.io/kcl-artifact-go v0.7.1 h1:tPSJxVKNm3+QseqtyDwtfx9qTeAioyHNYJIUsz7djqU=
kcl-lang.io/kcl-artifact-go v0.7.1/go.mod h1:c07mqi9Hu2UjPW7lYfHhAAWOlZiB7lo7Vkr4jL5ov/M=
kcl-lang.io/kcl-go v0.7.0 h1:mcYpQA+0JvlJ48rGec10GaASsRclJgAY18tz3AjWbEc=
kcl-lang.io/kcl-go v0.7.0/go.mod h1:ZEA8AA/L+vvp68PeBX16aR1Se81hLAWNp+7Qa2cYWdo=
kcl-lang.io/kcl-plugin v0.5.0 h1:eoh6y4l81rwA8yhJXU4hN7YmJeTUNB1nfYCP9OffSxc=
kcl-lang.io/kcl-plugin v0.5.0/go.mod h1:QnZ5OLcyBw5nOnHpChRHtvBq8wvjwiHu/ZZ8j1dfz48=
kcl-lang.io/kpm v0.3.6 h1:iprev+h4d1PmWMTEQhMT33NLFRxIQ7KB703r4GeOlLc=
kcl-lang.io/kpm v0.3.6/go.mod h1:4mFfj1q7QAu3286xeCCQi+Sr37HkJk1GJC5ZGlSa46U=
kcl-lang.io/kpm v0.4.2 h1:rEjfUdX+2kmwwuBaYvsNURQ5D97C3qLNBYAd+XT+DbU=
kcl-lang.io/kpm v0.4.2/go.mod h1:9C/Q9RhRDinbhN7HzQxEexw00HVWUYwWbarMuC1E4xM=
kusionstack.io/kube-api v0.0.0-20230817144216-4714955f3801 h1:rWNki+bYgDqEgia/t8Vfk681NqTV0EbTXc8+JnkvZyM=
kusionstack.io/kube-api v0.0.0-20230817144216-4714955f3801/go.mod h1:QIQrH+MK9xuV+mXCAkk6DN8z6b8oyf4XN0VRccmHH/k=
lukechampine.com/frand v1.4.2 h1:RzFIpOvkMXuPMBb9maa4ND4wjBn71E1Jpf8BzJHMaVw=
Expand Down
1 change: 1 addition & 0 deletions pkg/cmd/apply/options.go
Expand Up @@ -69,6 +69,7 @@ func (o *Options) Run() error {
IsKclPkg: o.IsKclPkg,
WorkDir: o.WorkDir,
Filenames: o.Filenames,
Settings: o.Settings,
Arguments: o.Arguments,
NoStyle: o.NoStyle,
}
Expand Down
7 changes: 6 additions & 1 deletion pkg/cmd/build/build.go
Expand Up @@ -27,8 +27,11 @@ func NewCmdBuild() *cobra.Command {
# Build main.k with work directory
kusion build -w appops/demo/dev
# Build main.k and write result into output.yaml
# Build configurations and write result into an output.yaml
kusion build -o output.yaml
# Build configurations with arguments from settings.yaml
kusion build -Y settings.yaml
# Build without output style and color
kusion build --no-style=true`)
Expand Down Expand Up @@ -61,6 +64,8 @@ func NewCmdBuild() *cobra.Command {
func (o *Options) AddBuildFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.WorkDir, "workdir", "w", "",
i18n.T("Specify the work directory"))
cmd.Flags().StringSliceVarP(&o.Settings, "setting", "Y", []string{},
i18n.T("Specify the command line setting files"))
cmd.Flags().StringToStringVarP(&o.Arguments, "argument", "D", map[string]string{},
i18n.T("Specify the top-level argument"))
}
20 changes: 18 additions & 2 deletions pkg/cmd/build/builders/kcl/kcl_builder.go
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"os/exec"
"path"
"path/filepath"
"strings"

kcl "kcl-lang.io/kcl-go"
Expand Down Expand Up @@ -66,7 +67,7 @@ func (g *Builder) Build(o *builders.Options, _ *project.Project, stack *stack.St
}

func Run(o *builders.Options, stack *stack.Stack) (*CompileResult, error) {
optList, err := BuildOptions(o.WorkDir, o.Arguments)
optList, err := BuildKCLOptions(o)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -146,8 +147,23 @@ func readCRDs(workDir string) ([]interface{}, error) {
return visitor.Visit()
}

func BuildOptions(workDir string, arguments map[string]string) ([]kcl.Option, error) {
func BuildKCLOptions(o *builders.Options) ([]kcl.Option, error) {
optList := make([]kcl.Option, 0)
settings := o.Settings
workDir := o.WorkDir
arguments := o.Arguments

// build settings option
for _, setting := range settings {
if workDir != "" {
setting = filepath.Join(workDir, setting)
}
settingOptions := kcl.WithSettings(setting)
if settingOptions.Err != nil {
return nil, settingOptions.Err
}
optList = append(optList, settingOptions)
}

// build arguments option
for k, v := range arguments {
Expand Down
7 changes: 7 additions & 0 deletions pkg/cmd/build/options.go
Expand Up @@ -23,6 +23,7 @@ type Options struct {
type Flags struct {
Output string
WorkDir string
Settings []string
Arguments map[string]string
NoStyle bool
}
Expand All @@ -34,6 +35,7 @@ func NewBuildOptions() *Options {
Filenames: []string{},
Flags: Flags{
Arguments: map[string]string{},
Settings: make([]string, 0),
},
}
}
Expand Down Expand Up @@ -74,6 +76,7 @@ func (o *Options) Run() error {
IsKclPkg: o.IsKclPkg,
WorkDir: o.WorkDir,
Filenames: o.Filenames,
Settings: o.Settings,
Arguments: o.Arguments,
NoStyle: o.NoStyle,
},
Expand Down Expand Up @@ -119,5 +122,9 @@ func (o *Options) PreSet(preCheck func(cur string) bool) error {
o.IsKclPkg = true
return nil
}

if len(o.Settings) == 0 {
o.Settings = []string{project.KclFile}
}
return nil
}
7 changes: 5 additions & 2 deletions pkg/cmd/build/options_test.go
Expand Up @@ -45,7 +45,8 @@ func TestCompileOptions_preSet(t *testing.T) {
Output string
}
type want struct {
Output string
Settings []string
Output string
}

tests := []struct {
Expand All @@ -59,7 +60,8 @@ func TestCompileOptions_preSet(t *testing.T) {
Output: "",
},
want: want{
Output: "",
Output: "",
Settings: []string{"kcl.yaml"},
},
},
}
Expand All @@ -74,6 +76,7 @@ func TestCompileOptions_preSet(t *testing.T) {

wantOpt := NewBuildOptions()
wantOpt.Output = tt.want.Output
wantOpt.Settings = tt.want.Settings

assert.Equal(t, wantOpt, o)
})
Expand Down
30 changes: 16 additions & 14 deletions pkg/cmd/build/util.go
Expand Up @@ -62,23 +62,25 @@ func Intent(o *builders.Options, p *project.Project, s *stack.Stack) (*intent.In
pg := p.Generator

// default AppsConfigBuilder
var bt project.BuilderType
if pg == nil {
builder = &kcl.Builder{}
bt = project.AppConfigurationBuilder
} else {
gt := pg.Type
// we can add more generators here
switch gt {
case project.KCLBuilder:
builder = &kcl.Builder{}
case project.AppConfigurationBuilder:
appConfigs, err := buildAppConfigs(o, s)
if err != nil {
return nil, err
}
builder = &builders.AppsConfigBuilder{Apps: appConfigs}
default:
return nil, fmt.Errorf("unknow generator type:%s", gt)
bt = pg.Type
}

// we can add more generators here
switch bt {
case project.KCLBuilder:
builder = &kcl.Builder{}
case project.AppConfigurationBuilder:
appConfigs, err := buildAppConfigs(o, s)
if err != nil {
return nil, err
}
builder = &builders.AppsConfigBuilder{Apps: appConfigs}
default:
return nil, fmt.Errorf("unknow generator type:%s", bt)
}

i, err := builder.Build(o, p, s)
Expand Down
45 changes: 25 additions & 20 deletions pkg/cmd/build/util_test.go
Expand Up @@ -19,7 +19,7 @@ import (
)

var (
spec1 = `
intent1 = `
resources:
- id: v1:Namespace:default
type: Kubernetes
Expand All @@ -32,7 +32,7 @@ resources:
spec: {}
status: {}
`
specModel1 = &intent.Intent{
intentModel1 = &intent.Intent{
Resources: []intent.Resource{
{
ID: "v1:Namespace:default",
Expand All @@ -51,7 +51,7 @@ resources:
},
}

spec2 = `
intent2 = `
resources:
- id: v1:Namespace:default
type: Kubernetes
Expand All @@ -69,7 +69,7 @@ resources:
name: kube-system
`

specModel2 = &intent.Intent{
intentModel2 = &intent.Intent{
Resources: []intent.Resource{
{
ID: "v1:Namespace:default",
Expand All @@ -96,7 +96,7 @@ resources:
},
}

specModel3 = &intent.Intent{
intentModel3 = &intent.Intent{
Resources: []intent.Resource{
{
ID: "v1:Namespace:default",
Expand All @@ -119,7 +119,7 @@ resources:
}
)

func TestGenerateSpecFromFile(t *testing.T) {
func TestBuildIntentFromFile(t *testing.T) {
tests := []struct {
name string
path string
Expand All @@ -130,14 +130,14 @@ func TestGenerateSpecFromFile(t *testing.T) {
{
name: "test1",
path: "kusion_intent.yaml",
content: spec1,
want: specModel1,
content: intent1,
want: intentModel1,
},
{
name: "test2",
path: "kusion_intent.yaml",
content: spec2,
want: specModel2,
content: intent2,
want: intentModel2,
},
{
name: "test3",
Expand All @@ -162,7 +162,7 @@ func TestGenerateSpecFromFile(t *testing.T) {
}
}

func TestGenerateSpec(t *testing.T) {
func TestBuildIntent(t *testing.T) {
apc := &appconfigmodel.AppConfiguration{}
var apcMap map[string]interface{}
tmp, _ := json.Marshal(apc)
Expand All @@ -181,21 +181,26 @@ func TestGenerateSpec(t *testing.T) {
wantErr bool
}{
{
name: "nil generator", args: struct {
name: "nil builder", args: struct {
o *builders.Options
project *project.Project
stack *stack.Stack
mocker *mockey.MockBuilder
}{
o: &builders.Options{},
project: &project.Project{},
stack: &stack.Stack{},
mocker: mockey.Mock((*kcl.Builder).Build).Return(nil, nil),
o: &builders.Options{Arguments: map[string]string{}},
project: &project.Project{
Configuration: project.Configuration{
Name: "default",
},
}, stack: &stack.Stack{},
mocker: mockey.Mock(kcl.Run).Return(&kcl.CompileResult{
Documents: []kclgo.KCLResult{apcMap},
}, nil),
},
want: nil,
want: intentModel3,
},
{
name: "kcl generator", args: struct {
name: "kcl builder", args: struct {
o *builders.Options
project *project.Project
stack *stack.Stack
Expand All @@ -215,7 +220,7 @@ func TestGenerateSpec(t *testing.T) {
want: nil,
},
{
name: "app generator", args: struct {
name: "app builder", args: struct {
o *builders.Options
project *project.Project
stack *stack.Stack
Expand All @@ -235,7 +240,7 @@ func TestGenerateSpec(t *testing.T) {
Documents: []kclgo.KCLResult{apcMap},
}, nil),
},
want: specModel3,
want: intentModel3,
},
}

Expand Down
1 change: 1 addition & 0 deletions pkg/cmd/preview/options.go
Expand Up @@ -125,6 +125,7 @@ func (o *Options) Run() error {
IsKclPkg: o.IsKclPkg,
WorkDir: o.WorkDir,
Filenames: o.Filenames,
Settings: o.Settings,
Arguments: o.Arguments,
NoStyle: o.NoStyle,
}
Expand Down

0 comments on commit f4d08f2

Please sign in to comment.