Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add meta flags and options for common logic and data #1005

Merged
merged 1 commit into from
Apr 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ require (
github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/hcl/v2 v2.16.1
github.com/hashicorp/vault/api v1.10.0
github.com/hashicorp/waypoint-plugin-sdk v0.0.0-20230412210808-dcdb2a03f714
github.com/howieyuen/uilive v0.0.6
github.com/jinzhu/copier v0.3.2
github.com/lucasb-eyer/go-colorful v1.0.3
Expand Down Expand Up @@ -85,6 +86,7 @@ require (
cloud.google.com/go/iam v1.1.5 // indirect
cloud.google.com/go/storage v1.36.0 // indirect
github.com/Microsoft/hcsshim v0.11.0 // indirect
github.com/VividCortex/ewma v1.1.1 // indirect
github.com/alibabacloud-go/darabonba-array v0.1.0 // indirect
github.com/alibabacloud-go/darabonba-encode-util v0.0.2 // indirect
github.com/alibabacloud-go/darabonba-map v0.0.2 // indirect
Expand All @@ -98,6 +100,9 @@ require (
github.com/aliyun/alibabacloud-dkms-gcs-go-sdk v0.5.1 // indirect
github.com/aliyun/alibabacloud-dkms-transfer-go-sdk v0.1.8 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/briandowns/spinner v1.11.1 // indirect
github.com/cheggaaa/pb/v3 v3.0.5 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/deckarep/golang-set v1.7.1 // indirect
Expand All @@ -117,17 +122,24 @@ require (
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lab47/vterm v0.0.0-20201001232628-a9dd795f94c2 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/mitchellh/go-glint v0.0.0-20201015034436-f80573c636de // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/oklog/run v1.0.0 // indirect
github.com/olekukonko/tablewriter v0.0.4 // indirect
github.com/orcaman/concurrent-map v0.0.0-20210501183033-44dafcb38ecc // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/tj/go-spin v1.1.0 // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/ulikunitz/xz v0.5.10 // indirect
github.com/vbatts/tar-split v0.11.3 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
github.com/y0ssar1an/q v1.0.7 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
Expand Down
35 changes: 35 additions & 0 deletions go.sum

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pkg/cmd/apply/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (o *Options) Run() error {
}

// parse project and stack of work directory
currentProject, currentStack, err := project.DetectProjectAndStack(o.Options.WorkDir)
currentProject, currentStack, err := project.DetectProjectAndStackFrom(o.Options.WorkDir)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/apply/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ var (
)

func mockPatchDetectProjectAndStack() *mockey.Mocker {
return mockey.Mock(project.DetectProjectAndStack).To(func(stackDir string) (*apiv1.Project, *apiv1.Stack, error) {
return mockey.Mock(project.DetectProjectAndStackFrom).To(func(stackDir string) (*apiv1.Project, *apiv1.Stack, error) {
proj.Path = stackDir
stack.Path = stackDir
return proj, stack, nil
Expand Down
21 changes: 10 additions & 11 deletions pkg/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ import (

"kusionstack.io/kusion/pkg/cmd/apply"
"kusionstack.io/kusion/pkg/cmd/config"
"kusionstack.io/kusion/pkg/cmd/destroy"
"kusionstack.io/kusion/pkg/cmd/generate"
cmdinit "kusionstack.io/kusion/pkg/cmd/init"
"kusionstack.io/kusion/pkg/cmd/mod"
"kusionstack.io/kusion/pkg/cmd/workspace"

"kusionstack.io/kusion/pkg/cmd/destroy"
"kusionstack.io/kusion/pkg/cmd/preview"
"kusionstack.io/kusion/pkg/cmd/version"
"kusionstack.io/kusion/pkg/cmd/workspace"
"kusionstack.io/kusion/pkg/util/i18n"
)

Expand Down Expand Up @@ -57,7 +56,7 @@ func NewKusionctlCmd(o KusionctlOptions) *cobra.Command {
_ = i18n.LoadTranslations(i18n.DomainKusion, nil)

// Parent command to which all subcommands are added.
cmds := &cobra.Command{
rootCmd := &cobra.Command{
Use: "kusion",
Short: i18n.T(`Kusion is the Platform Orchestrator of Internal Developer Platform`),
Long: templates.LongDesc(`
Expand All @@ -82,9 +81,9 @@ func NewKusionctlCmd(o KusionctlOptions) *cobra.Command {
}

// From this point and forward we get warnings on flags that contain "_" separators
cmds.SetGlobalNormalizationFunc(cliflag.WarnWordSepNormalizeFunc)
rootCmd.SetGlobalNormalizationFunc(cliflag.WarnWordSepNormalizeFunc)

flags := cmds.PersistentFlags()
flags := rootCmd.PersistentFlags()

addProfilingFlags(flags)

Expand Down Expand Up @@ -113,15 +112,15 @@ func NewKusionctlCmd(o KusionctlOptions) *cobra.Command {
},
},
}
groups.Add(cmds)
groups.Add(rootCmd)

filters := []string{"options"}

templates.ActsAsRootCommand(cmds, filters, groups...)
cmds.AddCommand(version.NewCmdVersion())
cmds.AddCommand(options.NewCmdOptions(o.IOStreams.Out))
templates.ActsAsRootCommand(rootCmd, filters, groups...)
rootCmd.AddCommand(version.NewCmdVersion())
rootCmd.AddCommand(options.NewCmdOptions(o.IOStreams.Out))

return cmds
return rootCmd
}

func runHelp(cmd *cobra.Command, args []string) {
Expand Down
9 changes: 0 additions & 9 deletions pkg/cmd/cmd_test.go

This file was deleted.

2 changes: 1 addition & 1 deletion pkg/cmd/destroy/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (o *Options) Run() error {
// listen for interrupts or the SIGTERM signal
signals.HandleInterrupt()
// parse project and stack of work directory
proj, stack, err := project.DetectProjectAndStack(o.Options.WorkDir)
proj, stack, err := project.DetectProjectAndStackFrom(o.Options.WorkDir)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/destroy/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ var (
)

func mockDetectProjectAndStack() {
mockey.Mock(project.DetectProjectAndStack).To(func(stackDir string) (*apiv1.Project, *apiv1.Stack, error) {
mockey.Mock(project.DetectProjectAndStackFrom).To(func(stackDir string) (*apiv1.Project, *apiv1.Stack, error) {
proj.Path = stackDir
stack.Path = stackDir
return proj, stack, nil
Expand Down
52 changes: 21 additions & 31 deletions pkg/cmd/generate/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import (
"kusionstack.io/kusion/pkg/backend"
"kusionstack.io/kusion/pkg/cmd/generate/generator"
"kusionstack.io/kusion/pkg/cmd/generate/run"
"kusionstack.io/kusion/pkg/cmd/meta"
cmdutil "kusionstack.io/kusion/pkg/cmd/util"
"kusionstack.io/kusion/pkg/engine/spec"
"kusionstack.io/kusion/pkg/project"
"kusionstack.io/kusion/pkg/util/i18n"
"kusionstack.io/kusion/pkg/util/pretty"
)
Expand Down Expand Up @@ -46,27 +46,24 @@ var (
// This structure reduces the transformation to wiring and makes the logic itself easy to unit test.
type GenerateFlags struct {
WorkDir string
Backend string
Workspace string
MetaFlags *meta.MetaFlags

genericiooptions.IOStreams
}

// GenerateOptions defines flags and other configuration parameters for the `generate` command.
type GenerateOptions struct {
WorkDir string
*meta.MetaOptions

Project *v1.Project
Stack *v1.Stack
Workspace *v1.Workspace
WorkDir string

SpecStorage spec.Storage
Generator generator.Generator
}

// NewGenerateFlags returns a default GenerateFlags
func NewGenerateFlags(streams genericiooptions.IOStreams) *GenerateFlags {
return &GenerateFlags{
MetaFlags: meta.NewMetaFlags(),
IOStreams: streams,
}
}
Expand Down Expand Up @@ -97,9 +94,10 @@ func NewCmdGenerate(ioStreams genericiooptions.IOStreams) *cobra.Command {

// AddFlags registers flags for a cli.
func (flags *GenerateFlags) AddFlags(cmd *cobra.Command) {
// bind flag structs
flags.MetaFlags.AddFlags(cmd)

cmd.Flags().StringVarP(&flags.WorkDir, "workdir", "w", flags.WorkDir, i18n.T("The working directory for generate (default is current dir where executed)."))
cmd.Flags().StringVarP(&flags.Backend, "backend", "", flags.Backend, i18n.T("The backend to use, supports 'local', 'oss' and 's3'."))
cmd.Flags().StringVarP(&flags.Workspace, "workspace", "", flags.Workspace, i18n.T("The name of target workspace to operate in."))
}

// ToOptions converts from CLI inputs to runtime inputs.
Expand All @@ -110,35 +108,27 @@ func (flags *GenerateFlags) ToOptions() (*GenerateOptions, error) {
workDir, _ = os.Getwd()
}

// Parse project and currentStack of work directory
currentProject, currentStack, err := project.DetectProjectAndStack(workDir)
if err != nil {
return nil, err
}

// Get current workspace from backend
workspaceStorage, err := backend.NewWorkspaceStorage(flags.Backend)
if err != nil {
return nil, err
}
currentWorkspace, err := workspaceStorage.Get(flags.Workspace)
// Convert meta options
metaOptions, err := flags.MetaFlags.ToOptions()
if err != nil {
return nil, err
}

// Get target spec storage
specStorage, err := backend.NewSpecStorage(flags.Backend, currentProject.Name, currentStack.Name, flags.Workspace)
specStorage, err := backend.NewSpecStorage(
*flags.MetaFlags.Backend,
metaOptions.RefProject.Name,
metaOptions.RefStack.Name,
metaOptions.RefWorkspace.Name,
)
if err != nil {
return nil, err
}

o := &GenerateOptions{
WorkDir: workDir,
Project: currentProject,
Stack: currentStack,
Workspace: currentWorkspace,
MetaOptions: metaOptions,
SpecStorage: specStorage,
Generator: nil,
}

return o, nil
Expand All @@ -155,11 +145,11 @@ func (o *GenerateOptions) Validate(cmd *cobra.Command, args []string) error {

// Run executes the `generate` command.
func (o *GenerateOptions) Run() error {
spec, err := GenerateSpecWithSpinner(o.Project, o.Stack, o.Workspace, true)
versionedSpec, err := GenerateSpecWithSpinner(o.RefProject, o.RefStack, o.RefWorkspace, true)
if err != nil {
return err
}
return o.SpecStorage.Apply(spec)
return o.SpecStorage.Apply(versionedSpec)
}

// GenerateSpecWithSpinner calls generator to generate versioned Spec. Add a method wrapper for testing purposes.
Expand Down Expand Up @@ -189,7 +179,7 @@ func GenerateSpecWithSpinner(project *v1.Project, stack *v1.Stack, workspace *v1
// style means color and prompt here. Currently, sp will be nil only when o.NoStyle is true
style := !noStyle && sp != nil

spec, err := defaultGenerator.Generate(stack.Path, nil)
versionedSpec, err := defaultGenerator.Generate(stack.Path, nil)
if err != nil {
if style {
sp.Fail()
Expand All @@ -206,7 +196,7 @@ func GenerateSpecWithSpinner(project *v1.Project, stack *v1.Stack, workspace *v1
fmt.Println()
}

return spec, nil
return versionedSpec, nil
}

func SpecFromFile(filePath string) (*v1.Spec, error) {
Expand Down
99 changes: 99 additions & 0 deletions pkg/cmd/meta/meta.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright 2024 KusionStack 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 meta

import (
"github.com/spf13/cobra"

v1 "kusionstack.io/kusion/pkg/apis/api.kusion.io/v1"
"kusionstack.io/kusion/pkg/backend"
"kusionstack.io/kusion/pkg/project"
"kusionstack.io/kusion/pkg/util/i18n"
)

// MetaFlags directly reflect the information that CLI is gathering via flags. They will be converted to
// MetaOptions, which reflect the runtime requirements for the command.
//
// This structure reduces the transformation to wiring and makes the logic itself easy to unit test.
type MetaFlags struct {
Application *string
Workspace *string

Backend *string
}

// MetaOptions are the meta-options that are available on all or most commands.
type MetaOptions struct {
// RefProject references the project for this CLI invocation.
RefProject *v1.Project

// RefStack referenced the stack for this CLI invocation
RefStack *v1.Stack

// RefWorkspace referenced the workspace for this CLI invocation
RefWorkspace *v1.Workspace
}

// NewMetaFlags provides default flags and values for use in other commands.
func NewMetaFlags() *MetaFlags {
application := ""
workspace := ""
backendType := ""

return &MetaFlags{
Application: &application,
Workspace: &workspace,
Backend: &backendType,
}
}

// AddFlags registers flags for a cli.
func (f *MetaFlags) AddFlags(cmd *cobra.Command) {
if f.Workspace != nil {
cmd.Flags().StringVarP(f.Workspace, "workspace", "", *f.Workspace, i18n.T("The name of target workspace to operate in."))
}
if f.Backend != nil {
cmd.Flags().StringVarP(f.Backend, "backend", "", *f.Backend, i18n.T("The backend to use, supports 'local', 'oss' and 's3'."))
}
}

// ToOptions converts MetaFlags to MetaOptions.
func (f *MetaFlags) ToOptions() (*MetaOptions, error) {
opts := &MetaOptions{}

// Parse project and currentStack of work directory
refProject, refStack, err := project.DetectProjectAndStacks()
if err != nil {
return nil, err
}

opts.RefProject = refProject
opts.RefStack = refStack

// Get current workspace from backend
if f.Backend != nil && f.Workspace != nil {
workspaceStorage, err := backend.NewWorkspaceStorage(*f.Backend)
if err != nil {
return nil, err
}
refWorkspace, err := workspaceStorage.Get(*f.Workspace)
if err != nil {
return nil, err
}
opts.RefWorkspace = refWorkspace
}

return opts, nil
}
2 changes: 1 addition & 1 deletion pkg/cmd/preview/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func (o *Options) Run() error {
}

// Parse project and currentStack of work directory
currentProject, currentStack, err := project.DetectProjectAndStack(o.WorkDir)
currentProject, currentStack, err := project.DetectProjectAndStackFrom(o.WorkDir)
if err != nil {
return err
}
Expand Down
Loading
Loading