mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-18 20:17:04 +00:00
Feat: vela cuex eval (#5562)
* Feat: vela cuex render Signed-off-by: Somefive <yd219913@alibaba-inc.com> * feat: CLI command `vela cuex eval <file>` Signed-off-by: Zhenghao Lou <rhzx3519@gmail.com> * responsive writer Signed-off-by: Somefive <yd219913@alibaba-inc.com> --------- Signed-off-by: Somefive <yd219913@alibaba-inc.com> Signed-off-by: Zhenghao Lou <rhzx3519@gmail.com> Co-authored-by: Zhenghao Lou <rhzx3519@gmail.com>
This commit is contained in:
@@ -53,7 +53,7 @@ require (
|
||||
github.com/hashicorp/hcl/v2 v2.16.2
|
||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174
|
||||
github.com/imdario/mergo v0.3.13
|
||||
github.com/kubevela/pkg v1.8.1-0.20230410075324-9f0ba3b09495
|
||||
github.com/kubevela/pkg v1.8.1-0.20230421100856-841accb6dd92
|
||||
github.com/kubevela/workflow v0.5.1-0.20230412142834-be9e5a10baf0
|
||||
github.com/kyokomi/emoji v2.2.4+incompatible
|
||||
github.com/magiconair/properties v1.8.7
|
||||
|
||||
@@ -964,8 +964,8 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kubevela/pkg v1.8.1-0.20230410075324-9f0ba3b09495 h1:maT6E7JSrZgv4T1grgTBL69px7oUldc+tHIPxJ5SD9Y=
|
||||
github.com/kubevela/pkg v1.8.1-0.20230410075324-9f0ba3b09495/go.mod h1:dGT23SGBw16frh5ReEYMFraxjppkX6jPCltBgTeLUhE=
|
||||
github.com/kubevela/pkg v1.8.1-0.20230421100856-841accb6dd92 h1:wbsdJ6p6OhwUMRLpqCTFI1WxdjLxRrfWnNSHv/PVzsI=
|
||||
github.com/kubevela/pkg v1.8.1-0.20230421100856-841accb6dd92/go.mod h1:dGT23SGBw16frh5ReEYMFraxjppkX6jPCltBgTeLUhE=
|
||||
github.com/kubevela/workflow v0.5.1-0.20230412142834-be9e5a10baf0 h1:/ZPmjKpd/+fpCjJfNfUnE7jdESuCcZeP+fyTUAU9an0=
|
||||
github.com/kubevela/workflow v0.5.1-0.20230412142834-be9e5a10baf0/go.mod h1:0GhIWFIPP+Zt31m4Aslx9mihoyNz3HrOvCV69ljMIBo=
|
||||
github.com/kylelemons/godebug v0.0.0-20160406211939-eadb3ce320cb/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
|
||||
@@ -113,6 +113,7 @@ func NewCommandWithIOStreams(ioStream util.IOStreams) *cobra.Command {
|
||||
NewProviderCommand(commandArgs, "10", ioStream),
|
||||
AuthCommandGroup(f, ioStream),
|
||||
KubeCommandGroup(f, ioStream),
|
||||
CueXCommandGroup(f),
|
||||
|
||||
// Config management
|
||||
ConfigCommandGroup(f, ioStream),
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright 2023 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/kubevela/pkg/cue/cuex"
|
||||
"github.com/kubevela/pkg/cue/util"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
velacmd "github.com/oam-dev/kubevela/pkg/cmd"
|
||||
)
|
||||
|
||||
// CueXCommandGroup commands for cuex management
|
||||
func CueXCommandGroup(f velacmd.Factory) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "cuex",
|
||||
Short: i18n.T("Manage CueX engine for compile."),
|
||||
Annotations: map[string]string{
|
||||
types.TagCommandType: types.TypeExtension,
|
||||
},
|
||||
}
|
||||
cmd.AddCommand(NewCueXEvalCommand(f))
|
||||
return cmd
|
||||
}
|
||||
|
||||
// CueXEvalOption option for compile cuex
|
||||
type CueXEvalOption struct {
|
||||
Format string
|
||||
Path string
|
||||
File string
|
||||
}
|
||||
|
||||
// Run compile cuex
|
||||
func (in *CueXEvalOption) Run(cmd *cobra.Command) error {
|
||||
if in.File == "" {
|
||||
return fmt.Errorf("file must be provided for compile")
|
||||
}
|
||||
bs, err := os.ReadFile(in.File)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
val, err := cuex.CompileString(cmd.Context(), string(bs))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bs, err = util.Print(val, util.WithFormat(in.Format), util.WithPath(in.Path))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.Println(string(bs))
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
cuexEvalLong = templates.LongDesc(i18n.T(`
|
||||
Eval cue file with CueX engine.
|
||||
|
||||
Evaluate your cue file with the CueX engine. When your cue file does not
|
||||
use KubeVela's extension, it will work similarly to the native CUE CLI.
|
||||
When using KubeVela's extensions, this command will execute the extension
|
||||
functions and resolve values, in addition to the native CUE compile process.
|
||||
`))
|
||||
|
||||
cuexEvalExample = templates.Examples(i18n.T(`
|
||||
# Evaluate a cue file
|
||||
vela cuex eval -f my.cue
|
||||
|
||||
# Evaluate a cue file into json format
|
||||
vela cuex eval -f my.cue -o json
|
||||
|
||||
# Evaluate a cue file and output the target path
|
||||
vela cuex eval -f my.cue -p key.path
|
||||
`))
|
||||
)
|
||||
|
||||
// NewCueXEvalCommand `vela cuex eval` command
|
||||
func NewCueXEvalCommand(f velacmd.Factory) *cobra.Command {
|
||||
opt := &CueXEvalOption{
|
||||
Format: string(util.PrintFormatCue),
|
||||
}
|
||||
cmd := &cobra.Command{
|
||||
Use: "eval",
|
||||
Short: i18n.T("Eval cue file with CueX engine."),
|
||||
Long: cuexEvalLong,
|
||||
Example: cuexEvalExample,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return opt.Run(cmd)
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVarP(&opt.Format, "format", "o", opt.Format, "format of the output")
|
||||
cmd.Flags().StringVarP(&opt.File, "file", "f", opt.File, "file for eval")
|
||||
cmd.Flags().StringVarP(&opt.Path, "path", "p", opt.Path, "path for eval")
|
||||
return velacmd.NewCommandBuilder(f, cmd).
|
||||
WithResponsiveWriter().
|
||||
Build()
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
Copyright 2023 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/kubevela/pkg/util/stringtools"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
testdataDir = "test-data/cuex"
|
||||
)
|
||||
|
||||
func TestCueXEval(t *testing.T) {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
cmd := NewCueXEvalCommand(nil)
|
||||
cmd.SetOut(buffer)
|
||||
|
||||
testCases := map[string]struct {
|
||||
filepath string
|
||||
path string
|
||||
format string
|
||||
expect string
|
||||
}{
|
||||
"normal evaluate": {
|
||||
filepath.Join(testdataDir, "foo.cue"),
|
||||
"S.name",
|
||||
"",
|
||||
"\"Postgres\"",
|
||||
},
|
||||
"json": {
|
||||
filepath.Join(testdataDir, "foo.cue"),
|
||||
"",
|
||||
"json",
|
||||
`{"label":"app","S":{"name":"Postgres","version":"13","label":"app","image":"docker.io/postgres:13"}}`,
|
||||
},
|
||||
"yaml": {
|
||||
filepath.Join(testdataDir, "foo.cue"),
|
||||
"",
|
||||
"yaml",
|
||||
`
|
||||
S:
|
||||
image: docker.io/postgres:13
|
||||
label: app
|
||||
name: Postgres
|
||||
version: "13"
|
||||
label: app`,
|
||||
},
|
||||
"http": {
|
||||
filepath.Join(testdataDir, "httpget.cue"),
|
||||
"statusCode",
|
||||
"",
|
||||
"200",
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
buffer.Truncate(0)
|
||||
r := require.New(t)
|
||||
cmd.SetArgs([]string{"-f", tc.filepath, "-p", tc.path, "-o", tc.format})
|
||||
err := cmd.Execute()
|
||||
r.NoError(err)
|
||||
r.Equal(stringtools.TrimLeadingIndent(tc.expect), stringtools.TrimLeadingIndent(buffer.String()))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import "strings"
|
||||
|
||||
label: "app"
|
||||
// alias for label
|
||||
let L = label
|
||||
S: {
|
||||
name: "Postgres"
|
||||
// intermediate value
|
||||
let lower = strings.ToLower(name)
|
||||
version: "13"
|
||||
label: L
|
||||
image: "docker.io/\(lower):\(version)"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import "vela/http"
|
||||
|
||||
req: http.#Get & {
|
||||
$params: {
|
||||
url: "https://cuelang.org"
|
||||
}
|
||||
}
|
||||
|
||||
body: req.$returns.body
|
||||
statusCode: req.$returns.statusCode
|
||||
Reference in New Issue
Block a user