Skip to content
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
13 changes: 7 additions & 6 deletions cmd/cycloid/environments/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ func NewCreateCommand() *cobra.Command {
}

func create(cmd *cobra.Command, args []string) error {
api := common.NewAPI()
m := middleware.NewMiddleware(api)

org, err := cyargs.GetOrg(cmd)
if err != nil {
return err
Expand All @@ -46,7 +43,7 @@ func create(cmd *cobra.Command, args []string) error {
return err
}

env, err := cyargs.GetEnv(cmd)
env, err := cyargs.GetEnvOrEmpty(cmd)
if err != nil {
return err
}
Expand All @@ -55,8 +52,9 @@ func create(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
if name == "" {
name = env
name, env, err = middleware.NameOrCanonical(&name, &env)
if err != nil {
return err
}

color, err := cyargs.GetColor(cmd)
Expand All @@ -80,6 +78,9 @@ func create(cmd *cobra.Command, args []string) error {
return errors.Wrap(err, "unable to get printer")
}

api := common.NewAPI()
m := middleware.NewMiddleware(api)

if update {
environments, _, err := m.ListProjectsEnv(org, project)
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions cmd/cycloid/middleware/organization_project_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ func (m *middleware) GetEnv(org, project, env string) (*models.Environment, *htt
}

func (m *middleware) CreateEnv(org, project, env, envName, color string) (*models.Environment, *http.Response, error) {
envName, env, err := NameOrCanonical(&envName, &env)
if err != nil {
return nil, nil, err
}

envBody := models.NewEnvironment{
Name: &envName,
Canonical: env,
Expand Down
6 changes: 3 additions & 3 deletions cmd/cycloid/middleware/organization_projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ func (m *middleware) GetProject(org, project string) (*models.Project, *http.Res
}

func (m *middleware) CreateProject(org, projectName, project, description, configRepository, owner, team, color, icon string) (*models.Project, *http.Response, error) {
if projectName == "" {
// If name is empty, use the canonical
projectName = project
projectName, project, err := NameOrCanonical(&projectName, &project)
if err != nil {
return nil, nil, err
}

body := &models.NewProject{
Expand Down
3 changes: 3 additions & 0 deletions cmd/cycloid/middleware/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ func NameOrCanonical(name, canonical *string) (string, string, error) {

nameValue := ptr.Value(name)
canonicalValue := ptr.Value(canonical)
if nameValue == "" && canonicalValue == "" {
return "", "", fmt.Errorf("name or canonical is required, both are empty")
}

if canonicalValue == "" {
return nameValue, ToCanonical(nameValue), nil
Expand Down
55 changes: 54 additions & 1 deletion cmd/cycloid/middleware/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package middleware_test
import (
"testing"

"github.com/cycloidio/cycloid-cli/cmd/cycloid/middleware"
"github.com/stretchr/testify/assert"

"github.com/cycloidio/cycloid-cli/cmd/cycloid/middleware"
)

func TestToCanonical(t *testing.T) {
Expand All @@ -28,3 +29,55 @@ func TestToCanonical(t *testing.T) {
})
}
}

func TestNameOrCanonical(t *testing.T) {
testCases := []struct {
name string
inputName string
inputCanonical string
expectedName string
expectedCan string
expectErr bool
}{
{
name: "name-only infers canonical",
inputName: "My Cool Project",
expectedName: "My Cool Project",
expectedCan: "my_cool_project",
expectErr: false,
},
{
name: "canonical-only infers name",
inputCanonical: "my-project",
expectedName: "My-project",
expectedCan: "my-project",
expectErr: false,
},
{
name: "both provided keep values",
inputName: "Existing Name",
inputCanonical: "existing-canonical",
expectedName: "Existing Name",
expectedCan: "existing-canonical",
expectErr: false,
},
{
name: "both empty return error",
expectErr: true,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
gotName, gotCanonical, err := middleware.NameOrCanonical(&tc.inputName, &tc.inputCanonical)
if tc.expectErr {
assert.Error(t, err)
return
}

assert.NoError(t, err)
assert.Equal(t, tc.expectedName, gotName)
assert.Equal(t, tc.expectedCan, gotCanonical)
})
}
}
12 changes: 8 additions & 4 deletions cmd/cycloid/projects/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,12 @@ func NewCreateCommand() *cobra.Command {
}

func create(cmd *cobra.Command, args []string) error {
api := common.NewAPI()
m := middleware.NewMiddleware(api)

org, err := cyargs.GetOrg(cmd)
if err != nil {
return err
}

project, err := cyargs.GetProject(cmd)
project, err := cyargs.GetProjectOrEmpty(cmd)
if err != nil {
return err
}
Expand All @@ -53,6 +50,10 @@ func create(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
name, project, err = middleware.NameOrCanonical(&name, &project)
if err != nil {
return err
}

description, err := cyargs.GetDescription(cmd)
if err != nil {
Expand Down Expand Up @@ -95,6 +96,9 @@ func create(cmd *cobra.Command, args []string) error {
return errors.Wrap(err, "unable to get printer")
}

api := common.NewAPI()
m := middleware.NewMiddleware(api)

if update {
projects, _, err := m.ListProjects(org)
if err != nil {
Expand Down
43 changes: 43 additions & 0 deletions e2e/environments_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/stretchr/testify/assert"

"github.com/cycloidio/cycloid-cli/client/models"
"github.com/cycloidio/cycloid-cli/cmd/cycloid/middleware"
"github.com/cycloidio/cycloid-cli/internal/cyargs"
)

Expand Down Expand Up @@ -37,6 +38,48 @@ func TestEnvs(t *testing.T) {
}
})

t.Run("CreateWithNameOnly", func(t *testing.T) {
var (
nameOnly = "Environment Name " + randomCanonical("e2e")
inferred = middleware.ToCanonical(nameOnly)
nameColor = cyargs.PickRandomColor(&inferred)
)

args := []string{
"--output", "json",
"env", "create",
"--project", project,
"--name", nameOnly,
"--color", nameColor,
}
out, err := executeCommand(args)
if err != nil {
t.Errorf("failed to create env with name-only '%s': %v", nameOnly, err)
}

defer t.Run("DeleteNameOnlyEnv", func(t *testing.T) {
args := []string{
"env", "delete",
"--project", project,
"--env", inferred,
}
_, err := executeCommand(args)
if err != nil {
t.Errorf("failed to delete inferred env '%s': %v", inferred, err)
}
})

var createdEnv models.Environment
err = json.Unmarshal([]byte(out), &createdEnv)
if err != nil {
t.Errorf("failed to parse json output for inferred env creation: %v\noutput: %s", err, out)
}

assert.Equal(t, inferred, *createdEnv.Canonical)
assert.Equal(t, nameOnly, createdEnv.Name)
assert.Equal(t, nameColor, *createdEnv.Color)
})

defer t.Run("Delete", func(t *testing.T) {
args := []string{
"env", "delete",
Expand Down
4 changes: 2 additions & 2 deletions e2e/organizations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ func TestOrganizations(t *testing.T) {

var outOrg *models.Organization
err := json.Unmarshal([]byte(cmdOut), &outOrg)
is.NoErr(err) // output should be deserializable
is.Equal(updatedName, *outOrg.Name) // name should be updated
is.NoErr(err) // output should be deserializable
is.Equal(updatedName, *outOrg.Name) // name should be updated
})

t.Run("SuccessOrganizationsAddSubscription", func(t *testing.T) {
Expand Down
71 changes: 70 additions & 1 deletion e2e/projects_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import (
"github.com/stretchr/testify/assert"

"github.com/cycloidio/cycloid-cli/client/models"
"github.com/cycloidio/cycloid-cli/cmd/cycloid/middleware"
"github.com/cycloidio/cycloid-cli/internal/cyargs"
)


func TestProjects(t *testing.T) {

os.Setenv("CY_API_URL", config.APIUrl)
Expand Down Expand Up @@ -43,6 +43,75 @@ func TestProjects(t *testing.T) {
}
})

t.Run("CreateWithNameOnlyAndUpdate", func(t *testing.T) {
var (
nameOnly = "Project Name " + randomCanonical("e2e")
canonical = middleware.ToCanonical(nameOnly)
updatedDesc = "Updated inferred project description"
newIcon = cyargs.PickRandomIcon(nil)
newColor = cyargs.PickRandomColor(nil)
)

createArgs := []string{
"--output", "json",
"project", "create",
"--name", nameOnly,
"--description", description,
"--owner", owner,
"--icon", icon,
"--color", color,
}
createOut, err := executeCommand(createArgs)
if err != nil {
t.Errorf("failed to create project with name-only '%s': %v", nameOnly, err)
}

defer t.Run("DeleteNameOnlyProject", func(t *testing.T) {
args := []string{
"project", "delete",
"--project", canonical,
}
_, err := executeCommand(args)
if err != nil {
t.Errorf("failed to delete project '%s': %v", canonical, err)
}
})

var createdProject models.Project
err = json.Unmarshal([]byte(createOut), &createdProject)
if err != nil {
t.Errorf("failed to parse create output for inferred project: %v\noutput: %s", err, createOut)
}
assert.Equal(t, nameOnly, *createdProject.Name)
assert.Equal(t, canonical, *createdProject.Canonical)

updateArgs := []string{
"--output", "json",
"project", "create",
"--name", nameOnly,
"--description", updatedDesc,
"--owner", owner,
"--icon", newIcon,
"--color", newColor,
"--update",
}
updateOut, err := executeCommand(updateArgs)
if err != nil {
t.Errorf("failed to create --update project with name-only '%s': %v", nameOnly, err)
}

var updatedProject models.Project
err = json.Unmarshal([]byte(updateOut), &updatedProject)
if err != nil {
t.Errorf("failed to parse update output for inferred project: %v\noutput: %s", err, updateOut)
}
assert.Equal(t, canonical, *updatedProject.Canonical)
assert.Equal(t, nameOnly, *updatedProject.Name)
assert.Equal(t, updatedDesc, updatedProject.Description)
assert.Equal(t, newColor, *updatedProject.Color)
assert.Equal(t, newIcon, *updatedProject.Icon)
})

defer t.Run("Delete", func(t *testing.T) {
args := []string{
"project", "delete",
Expand Down
32 changes: 24 additions & 8 deletions internal/cyargs/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,24 @@ func AddProjectFlag(cmd *cobra.Command) {
}

func GetProject(cmd *cobra.Command) (string, error) {
project, err := GetProjectOrEmpty(cmd)
if err != nil {
return "", err
}
if project == "" {
return "", errors.New("project is not set, use --project flag or CY_PROJECT env var")
}

return project, nil
}

func GetProjectOrEmpty(cmd *cobra.Command) (string, error) {
project, _ := cmd.Flags().GetString("project")
if project != "" {
return project, nil
}

project = v.GetString("project")
if project == "" {
return "", errors.New("project is not set, use --project flag or CY_PROJECT env var")
}

return project, nil
}

Expand Down Expand Up @@ -201,16 +209,24 @@ func AddEnvFlag(cmd *cobra.Command) {
}

func GetEnv(cmd *cobra.Command) (string, error) {
env, err := GetEnvOrEmpty(cmd)
if err != nil {
return "", err
}
if env == "" {
return "", errors.New("env is not set, use --env flag or CY_ENV env var")
}

return env, nil
}

func GetEnvOrEmpty(cmd *cobra.Command) (string, error) {
env, _ := cmd.Flags().GetString("env")
if env != "" {
return env, nil
}

env = v.GetString("env")
if env == "" {
return "", errors.New("env is not set, use --env flag or CY_ENV env var")
}

return env, nil
}

Expand Down