Skip to content

Commit

Permalink
Merge pull request #48 from aris-bunnyshell/ND-7015
Browse files Browse the repository at this point in the history
Add new project subcommands and project & environment configurable build settings
  • Loading branch information
aris-bunnyshell authored Dec 22, 2023
2 parents bbcb3d2 + f9eb915 commit 6689edd
Show file tree
Hide file tree
Showing 60 changed files with 2,386 additions and 153 deletions.
110 changes: 110 additions & 0 deletions cmd/component/action/update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package action

import (
"fmt"

"bunnyshell.com/cli/cmd/environment/action"
"bunnyshell.com/cli/pkg/api/common"
"bunnyshell.com/cli/pkg/api/component"
"bunnyshell.com/cli/pkg/api/environment"
"bunnyshell.com/cli/pkg/build"
"bunnyshell.com/cli/pkg/config"
githelper "bunnyshell.com/cli/pkg/helper/git"
"bunnyshell.com/cli/pkg/lib"
"bunnyshell.com/cli/pkg/util"
"github.com/spf13/cobra"
)

type EditComponentData struct {
common.ItemOptions

K8SIntegration string

GitTarget string

WithDeploy bool
}

var commandExample = fmt.Sprintf(`This command updates the Git details for a component
You can update both the repository and the Git branch / ref:
%[1]s%[2]s components update --id dMVwZO5jGN --git-target https://github.com/my-fork/my-repo@my-main
You can update only the Git branch / ref:
%[1]s%[2]s components update --id dMVwZO5jGN --git-target @fix/bug-1234
.`, "\t", build.Name)

func init() {
settings := config.GetSettings()
options := config.GetOptions()

editComponentsData := &EditComponentData{
ItemOptions: *common.NewItemOptions(""),
}

command := &cobra.Command{
Use: "update",

Example: commandExample,

ValidArgsFunction: cobra.NoFileCompletions,

RunE: func(cmd *cobra.Command, args []string) error {
editComponentsData.ID = settings.Profile.Context.ServiceComponent

gitRepository, gitRef, err := githelper.ParseGitSec(editComponentsData.GitTarget)
if err != nil {
return lib.FormatCommandError(cmd, fmt.Errorf("invalid git spec for %s: %w", editComponentsData.GitTarget, err))
}

model, err := component.Get(&editComponentsData.ItemOptions)
if err != nil {
return lib.FormatCommandError(cmd, err)
}

if settings.IsStylish() {
cmd.Printf(`Updating component "%s" (%s)%s`, editComponentsData.ID, model.GetName(), "\n\n")
}

editOptions := environment.NewEditComponentOptions()
editOptions.ID = model.GetEnvironment()
editOptions.Component = model.GetName()
editOptions.TargetRepository = gitRepository
editOptions.TargetBranch = gitRef

_, err = environment.EditComponents(editOptions)
if err != nil {
return lib.FormatCommandError(cmd, err)
}

if settings.IsStylish() {
cmd.Printf("Successfully updated component...%s", "\n\n")
}

if !editComponentsData.WithDeploy {
return lib.FormatCommandData(cmd, model)
}

deployOptions := &editOptions.DeployOptions
deployOptions.ID = model.GetEnvironment()

if err = action.HandleDeploy(cmd, deployOptions, "updated", editComponentsData.K8SIntegration); err != nil {
return err
}

return lib.FormatCommandData(cmd, model)
},
}

flags := command.Flags()

flags.StringVar(&editComponentsData.GitTarget, "git-target", editComponentsData.GitTarget, "Target git spec (e.g. https://github.com/fork/templates@main)")
util.MarkFlagRequiredWithHelp(flags.Lookup("git-target"), "The target git spec (e.g. https://github.com/fork/templates@main)")

flags.AddFlag(options.ServiceComponent.GetRequiredFlag("id"))

flags.BoolVar(&editComponentsData.WithDeploy, "deploy", editComponentsData.WithDeploy, "Deploy the environment after update")
flags.StringVar(&editComponentsData.K8SIntegration, "k8s", editComponentsData.K8SIntegration, "Set Kubernetes integration for the environment (if not set)")

mainCmd.AddCommand(command)
}
2 changes: 1 addition & 1 deletion cmd/environment/action/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func init() {
deployOptions := &createOptions.DeployOptions
deployOptions.ID = model.GetId()

return handleDeploy(cmd, deployOptions, "created", createOptions.GetKubernetesIntegration())
return HandleDeploy(cmd, deployOptions, "created", createOptions.GetKubernetesIntegration())
},
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/environment/action/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func init() {
RunE: func(cmd *cobra.Command, args []string) error {
deployOptions.ID = settings.Profile.Context.Environment

return handleDeploy(cmd, deployOptions, "", deployData.K8SIntegration)
return HandleDeploy(cmd, deployOptions, "", deployData.K8SIntegration)
},
}

Expand Down
3 changes: 2 additions & 1 deletion cmd/environment/action/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func validateActionOptions(actionOptions *common.ActionOptions) error {
return fmt.Errorf("%w when following pipelines", lib.ErrNotStylish)
}

func handleDeploy(cmd *cobra.Command, deployOptions *environment.DeployOptions, action string, kubernetesIntegration string) error {
func HandleDeploy(cmd *cobra.Command, deployOptions *environment.DeployOptions, action string, kubernetesIntegration string) error {
if err := ensureKubernetesIntegration(deployOptions, kubernetesIntegration); err != nil {
return err
}
Expand Down Expand Up @@ -107,6 +107,7 @@ func ensureKubernetesIntegration(deployOptions *environment.DeployOptions, kuber
}

editSettingsOptions := environment.NewEditSettingsOptions(deployOptions.ID)
editSettingsOptions.UpdateEditSettingsForType(model.GetType())

editSettingsOptions.EnvironmentEditSettings.KubernetesIntegration.Set(&kubernetesIntegration)

Expand Down
103 changes: 103 additions & 0 deletions cmd/environment/action/update.build_settings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package action

import (
"bunnyshell.com/cli/pkg/api/build_settings"
"bunnyshell.com/cli/pkg/api/environment"
"bunnyshell.com/cli/pkg/config"
"bunnyshell.com/cli/pkg/config/enum"
"bunnyshell.com/cli/pkg/lib"
"bunnyshell.com/cli/pkg/util"
"bunnyshell.com/sdk"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)

func init() {
options := config.GetOptions()
settings := config.GetSettings()

useClusterProjectSettings := enum.BoolFalse
useRegistryProjectSettings := enum.BoolFalse

editBuildSettingsOptions := environment.NewEditBuildSettingsOptions("")

command := &cobra.Command{
Use: "update-build-settings",

ValidArgsFunction: cobra.NoFileCompletions,

RunE: func(cmd *cobra.Command, args []string) error {
editBuildSettingsOptions.ID = settings.Profile.Context.Environment

parseEditBuildSettingsOptions(cmd.Flags(), editBuildSettingsOptions, useClusterProjectSettings, useRegistryProjectSettings)

_, err := environment.EditBuildSettings(editBuildSettingsOptions)
if err != nil {
return lib.FormatCommandError(cmd, err)
}

model, err := build_settings.CheckBuildSettingsValidation[sdk.EnvironmentItem](
environment.Get,
&editBuildSettingsOptions.EditOptions,
settings.IsStylish(),
)
if err != nil {
return lib.FormatCommandError(cmd, err)
}

return lib.FormatCommandData(cmd, model)
},
}

flags := command.Flags()

flags.AddFlag(options.Environment.GetFlag("id", util.FlagRequired))

useClusterProjectSettingsFlag := enum.BoolFlag(
&useClusterProjectSettings,
"use-project-k8s",
"Use the project build cluster settings",
)
flags.AddFlag(useClusterProjectSettingsFlag)
useClusterProjectSettingsFlag.NoOptDefVal = "true"

useRegistryProjectSettingsFlag := enum.BoolFlag(
&useRegistryProjectSettings,
"use-project-registry",
"Use the project build registry settings",
)
flags.AddFlag(useRegistryProjectSettingsFlag)
useRegistryProjectSettingsFlag.NoOptDefVal = "true"

editBuildSettingsOptions.UpdateFlagSet(flags)

// use-project-settings excludes the other build settings flags for the cluster
command.MarkFlagsMutuallyExclusive("use-project-k8s", "use-managed-k8s")
command.MarkFlagsMutuallyExclusive("use-project-k8s", "k8s")
command.MarkFlagsMutuallyExclusive("use-project-k8s", "cpu")
command.MarkFlagsMutuallyExclusive("use-project-k8s", "memory")

command.MarkFlagsMutuallyExclusive("use-project-registry", "use-managed-registry")
command.MarkFlagsMutuallyExclusive("use-project-registry", "registry")

mainCmd.AddCommand(command)
}

func parseEditBuildSettingsOptions(
flags *pflag.FlagSet,
editBuildSettingsOptions *environment.EditBuildSettingsOptions,
useClusterProjectSettings enum.Bool,
useRegistryProjectSettings enum.Bool,
) {
if useClusterProjectSettings == enum.BoolTrue {
editBuildSettingsOptions.EditData.UseManagedCluster = enum.BoolFalse
editBuildSettingsOptions.SetKubernetesIntegration("")
editBuildSettingsOptions.Cpu = sdk.NullableString{}
editBuildSettingsOptions.Memory = sdk.NullableInt32{}
}

if useRegistryProjectSettings == enum.BoolTrue {
editBuildSettingsOptions.EditData.UseManagedRegistry = enum.BoolFalse
editBuildSettingsOptions.SetRegistryIntegration("")
}
}
54 changes: 17 additions & 37 deletions cmd/environment/action/update.components.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package action

import (
"fmt"
"net/url"
"strings"

"bunnyshell.com/cli/pkg/api/component/git"
"bunnyshell.com/cli/pkg/api/environment"
"bunnyshell.com/cli/pkg/build"
"bunnyshell.com/cli/pkg/config"
githelper "bunnyshell.com/cli/pkg/helper/git"
"bunnyshell.com/cli/pkg/lib"
"bunnyshell.com/cli/pkg/util"
"bunnyshell.com/sdk"
Expand All @@ -18,10 +18,10 @@ import (
type EditComponentsSource struct {
// filters
Component string
Source string
GitSource string

// updates
Target string
GitTarget string

// deployment
K8SIntegration string
Expand All @@ -30,13 +30,13 @@ type EditComponentsSource struct {
var commandExample = fmt.Sprintf(`This command updates the Git details for components in an environment.
You can update the Git details for a specific component in an environment by using the --component-name flag:
%[1]s%[2]s env update-components --component-name my-component --target https://github.com/my-fork/my-repo@my-main
%[1]s%[2]s env update-components --component-name my-component --git-target https://github.com/my-fork/my-repo@my-main
You can update all components matching a specific repository:
%[1]s%[2]s env update-components --source https://github.com/original/repo --target [email protected]/my-fork/my-repo
%[1]s%[2]s env update-components --git-source https://github.com/original/repo --git-target [email protected]/my-fork/my-repo
You can update all components matching a specific branch:
%[1]s%[2]s env update-components --source @main --target @feature-branch`, "\t", build.Name)
%[1]s%[2]s env update-components --git-source @main --git-target @feature-branch`, "\t", build.Name)

func init() {
options := config.GetOptions()
Expand Down Expand Up @@ -86,7 +86,7 @@ func init() {
deployOptions := &editOptions.DeployOptions
deployOptions.ID = model.GetId()

if err = handleDeploy(cmd, deployOptions, "updated", editSource.K8SIntegration); err != nil {
if err = HandleDeploy(cmd, deployOptions, "updated", editSource.K8SIntegration); err != nil {
return err
}

Expand All @@ -100,14 +100,14 @@ func init() {

editOptions.UpdateFlagSet(flags)

flags.StringVar(&editSource.Target, "target", editSource.Target, "Target git spec (e.g. https://github.com/fork/templates@main)")
flags.StringVar(&editSource.GitTarget, "git-target", editSource.GitTarget, "Target git spec (e.g. https://github.com/fork/templates@main)")

targetFlag := flags.Lookup("target")
targetFlag := flags.Lookup("git-target")
util.MarkFlagRequiredWithHelp(targetFlag, "Update components git repository and branch. Example: https://github.com/my-fork/my-repo@my-branch")

flags.StringVar(&editSource.Source, "source", editSource.Source, "Filter by git spec (e.g. https://github.com/bunnyshell/templates@main)")
flags.StringVar(&editSource.GitSource, "git-source", editSource.GitSource, "Filter by git spec (e.g. https://github.com/bunnyshell/templates@main)")
flags.StringVar(&editSource.Component, "component-name", editSource.Component, "Filter by component name")
command.MarkFlagsMutuallyExclusive("source", "component-name")
command.MarkFlagsMutuallyExclusive("git-source", "component-name")

mainCmd.AddCommand(command)
}
Expand Down Expand Up @@ -150,10 +150,10 @@ func componentToString(matched []sdk.ComponentGitCollection) string {
}

func fillWithGitSpec(editSource *EditComponentsSource, editOptions *environment.EditComponentOptions) error {
if editSource.Target != "" {
target, branch, err := parseGitSec(editSource.Target)
if editSource.GitTarget != "" {
target, branch, err := githelper.ParseGitSec(editSource.GitTarget)
if err != nil {
return fmt.Errorf("invalid git spec for %s: %w", editSource.Target, err)
return fmt.Errorf("invalid git spec for %s: %w", editSource.GitTarget, err)
}

editOptions.TargetRepository = target
Expand All @@ -166,37 +166,17 @@ func fillWithGitSpec(editSource *EditComponentsSource, editOptions *environment.
return nil
}

if editSource.Source == "" {
if editSource.GitSource == "" {
return nil
}

target, branch, err := parseGitSec(editSource.Source)
target, branch, err := githelper.ParseGitSec(editSource.GitSource)
if err != nil {
return fmt.Errorf("invalid git spec for %s: %w", editSource.Source, err)
return fmt.Errorf("invalid git spec for %s: %w", editSource.GitSource, err)
}

editOptions.SourceRepository = target
editOptions.SourceBranch = branch

return nil
}

func parseGitSec(spec string) (string, string, error) {
if spec[0] == '@' {
return "", spec[1:], nil
}

info, err := url.Parse(spec)
if err != nil {
return "", "", err
}

if !strings.Contains(info.Path, "@") {
return spec, "", nil
}

chunks := strings.SplitN(info.Path, "@", 2)
info.Path = chunks[0]

return info.String(), chunks[1], nil
}
2 changes: 1 addition & 1 deletion cmd/environment/action/update.configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func init() {
deployOptions := &editConfigurationOptions.DeployOptions
deployOptions.ID = model.GetId()

return handleDeploy(cmd, deployOptions, "updated", editConfigurationOptions.K8SIntegration)
return HandleDeploy(cmd, deployOptions, "updated", editConfigurationOptions.K8SIntegration)
},
}

Expand Down
6 changes: 6 additions & 0 deletions cmd/environment/action/update.settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ func init() {
RunE: func(cmd *cobra.Command, args []string) error {
editSettingsOptions.ID = settings.Profile.Context.Environment

environmentModel, err := environment.Get(&editSettingsOptions.ItemOptions)
if err != nil {
return lib.FormatCommandError(cmd, err)
}
editSettingsOptions.UpdateEditSettingsForType(environmentModel.GetType())

model, err := environment.EditSettings(editSettingsOptions)
if err != nil {
return lib.FormatCommandError(cmd, err)
Expand Down
Loading

0 comments on commit 6689edd

Please sign in to comment.