diff --git a/pkg/cmd/profile/profile.go b/pkg/cmd/profile/profile.go index 2319c242..3a9b0330 100644 --- a/pkg/cmd/profile/profile.go +++ b/pkg/cmd/profile/profile.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/brevdev/brev-cli/pkg/cmd/completions" - "github.com/brevdev/brev-cli/pkg/cmd/start" "github.com/brevdev/brev-cli/pkg/config" "github.com/brevdev/brev-cli/pkg/entity" breverrors "github.com/brevdev/brev-cli/pkg/errors" @@ -95,8 +94,8 @@ func profile(personalSettingsRepo string, t *terminal.Terminal, profileStore Pro return breverrors.WrapAndTrace(err) } - temp := start.MakeNewWorkspaceFromURL(personalSettingsRepo) - t.Vprint(temp.GitRepo) + gitRepo := makeGitRepoFromURL(personalSettingsRepo) + t.Vprint(gitRepo) // TODO: make sure the git repo format works!!!!!!! @@ -104,7 +103,7 @@ func profile(personalSettingsRepo string, t *terminal.Terminal, profileStore Pro Username: user.Username, Name: user.Name, Email: user.Email, - BaseWorkspaceRepo: temp.GitRepo, + BaseWorkspaceRepo: gitRepo, }) if err != nil { return breverrors.WrapAndTrace(err) @@ -113,3 +112,20 @@ func profile(personalSettingsRepo string, t *terminal.Terminal, profileStore Pro t.Vprintf("Your personal config has been updated. All new instances will run this script.\n") return nil } + +func makeGitRepoFromURL(url string) string { + if strings.Contains(url, "http") { + split := strings.Split(url, ".com/") + provider := strings.Split(split[0], "://")[1] + + if strings.Contains(split[1], ".git") { + return fmt.Sprintf("%s.com:%s", provider, split[1]) + } else { + return fmt.Sprintf("%s.com:%s.git", provider, split[1]) + } + } else { + split := strings.Split(url, ".com:") + provider := strings.Split(split[0], "@")[1] + return fmt.Sprintf("%s.com:%s", provider, split[1]) + } +} diff --git a/pkg/cmd/start/start.go b/pkg/cmd/start/start.go index 2ce046ef..a5d78857 100644 --- a/pkg/cmd/start/start.go +++ b/pkg/cmd/start/start.go @@ -3,32 +3,23 @@ package start import ( "fmt" - "net/url" - "path/filepath" "strings" "time" "github.com/brevdev/brev-cli/pkg/cmd/completions" "github.com/brevdev/brev-cli/pkg/cmd/util" - "github.com/brevdev/brev-cli/pkg/config" "github.com/brevdev/brev-cli/pkg/entity" - "github.com/brevdev/brev-cli/pkg/featureflag" - "github.com/brevdev/brev-cli/pkg/instancetypes" - "github.com/brevdev/brev-cli/pkg/mergeshells" "github.com/brevdev/brev-cli/pkg/store" "github.com/brevdev/brev-cli/pkg/terminal" - allutil "github.com/brevdev/brev-cli/pkg/util" "github.com/spf13/cobra" breverrors "github.com/brevdev/brev-cli/pkg/errors" ) var ( - startLong = "Start a Brev machine that's in a paused or off state or create one from a url" + startLong = "Start a Brev instance that's in a paused or off state" startExample = ` - brev start - brev start - brev start --org myFancyOrg + brev start ` ) @@ -40,27 +31,16 @@ type StartStore interface { StartWorkspace(workspaceID string) (*entity.Workspace, error) GetWorkspace(workspaceID string) (*entity.Workspace, error) GetOrganizations(options *store.GetOrganizationsOptions) ([]entity.Organization, error) - CreateWorkspace(organizationID string, options *store.CreateWorkspacesOptions) (*entity.Workspace, error) - GetSetupScriptContentsByURL(url string) (string, error) - GetFileAsString(path string) (string, error) } func NewCmdStart(t *terminal.Terminal, startStore StartStore, noLoginStartStore StartStore) *cobra.Command { - var org string - var name string var detached bool - var empty bool - var setupScript string - var setupRepo string - var setupPath string - var gpu string - var cpu string cmd := &cobra.Command{ Annotations: map[string]string{"workspace": ""}, Use: "start", DisableFlagsInUseLine: true, - Short: "Start an instance if it's stopped, or create one from url", + Short: "Start an existing instance that is stopped", Long: startLong, Example: startExample, ValidArgsFunction: completions.GetAllWorkspaceNameCompletionHandler(noLoginStartStore, t), @@ -70,64 +50,23 @@ func NewCmdStart(t *terminal.Terminal, startStore StartStore, noLoginStartStore repoOrPathOrNameOrID = args[0] } - if gpu != "" { - isValid := instancetypes.ValidateInstanceType(gpu) - if !isValid { - err := fmt.Errorf("invalid GPU instance type: %s, see https://brev.dev/docs/reference/gpu for a list of valid GPU instance types", gpu) - return breverrors.WrapAndTrace(err) - } - } - err := runStartWorkspace(t, StartOptions{ RepoOrPathOrNameOrID: repoOrPathOrNameOrID, - Name: name, - OrgName: org, - SetupScript: setupScript, - SetupRepo: setupRepo, - SetupPath: setupPath, - WorkspaceClass: cpu, Detached: detached, - InstanceType: gpu, }, startStore) if err != nil { - if strings.Contains(err.Error(), "duplicate instance with name") { - t.Vprint(t.Yellow("try running:")) - t.Vprint(t.Yellow("\tbrev start --name [different name] [repo] # or")) - t.Vprint(t.Yellow("\tbrev delete [name]")) - } return breverrors.WrapAndTrace(err) } return nil }, } cmd.Flags().BoolVarP(&detached, "detached", "d", false, "run the command in the background instead of blocking the shell") - cmd.Flags().BoolVarP(&empty, "empty", "e", false, "create an empty workspace") - cmd.Flags().StringVarP(&name, "name", "n", "", "name your workspace when creating a new one") - cmd.Flags().StringVarP(&cpu, "cpu", "c", "", "CPU instance type. Defaults to 2x8 [2x8, 4x16, 8x32, 16x32]. See docs.brev.dev/cpu for details") - cmd.Flags().StringVarP(&setupScript, "setup-script", "s", "", "takes a raw gist url to an env setup script") - cmd.Flags().StringVarP(&setupRepo, "setup-repo", "r", "", "repo that holds env setup script. you must pass in --setup-path if you use this argument") - cmd.Flags().StringVarP(&setupPath, "setup-path", "p", "", "path to env setup script. If you include --setup-repo we will apply this argument to that repo") - cmd.Flags().StringVarP(&org, "org", "o", "", "organization (will override active org if creating a workspace)") - // GPU options - cmd.Flags().StringVarP(&gpu, "gpu", "g", "n1-highmem-4:nvidia-tesla-t4:1", "GPU instance type. See https://brev.dev/docs/reference/gpu for details") - err := cmd.RegisterFlagCompletionFunc("org", completions.GetOrgsNameCompletionHandler(noLoginStartStore, t)) - if err != nil { - breverrors.GetDefaultErrorReporter().ReportError(breverrors.WrapAndTrace(err)) - fmt.Print(breverrors.WrapAndTrace(err)) - } return cmd } type StartOptions struct { - RepoOrPathOrNameOrID string // todo make invidual options - Name string - OrgName string - SetupScript string - SetupRepo string - SetupPath string - WorkspaceClass string + RepoOrPathOrNameOrID string // workspace name or ID to start Detached bool - InstanceType string } func runStartWorkspace(t *terminal.Terminal, options StartOptions, startStore StartStore) error { @@ -136,31 +75,7 @@ func runStartWorkspace(t *terminal.Terminal, options StartOptions, startStore St return breverrors.WrapAndTrace(err) } - didStart, err := maybeStartEmpty(t, user, options, startStore) - if err != nil { - return breverrors.WrapAndTrace(err) - } - if didStart { - return nil - } - - didStart, err = maybeStartFromGitURL(t, user, options, startStore) - if err != nil { - return breverrors.WrapAndTrace(err) - } - if didStart { - return nil - } - - didStart, err = maybeStartStoppedOrJoin(t, user, options, startStore) - if err != nil { - return breverrors.WrapAndTrace(err) - } - if didStart { - return nil - } - - didStart, err = maybeStartWithLocalPath(options, user, t, startStore) + didStart, err := maybeStartStoppedOrJoin(t, user, options, startStore) if err != nil { return breverrors.WrapAndTrace(err) } @@ -168,20 +83,11 @@ func runStartWorkspace(t *terminal.Terminal, options StartOptions, startStore St return nil } - return nil -} - -func maybeStartWithLocalPath(options StartOptions, user *entity.User, t *terminal.Terminal, startStore StartStore) (bool, error) { - if allutil.DoesPathExist(options.RepoOrPathOrNameOrID) { - err := startWorkspaceFromPath(user, t, options, startStore) - if err != nil { - return false, breverrors.WrapAndTrace(err) - } - return true, nil + if options.RepoOrPathOrNameOrID == "" { + return breverrors.NewValidationError("Please specify a workspace name or ID to start. Use 'brev create' to create a new workspace.") } else { - t.Print(t.Yellow("tried to start with local path but path not found")) + return breverrors.NewValidationError(fmt.Sprintf("No workspace found with name or ID '%s'. Use 'brev create' to create a new workspace.", options.RepoOrPathOrNameOrID)) } - return false, nil } func maybeStartStoppedOrJoin(t *terminal.Terminal, user *entity.User, options StartOptions, startStore StartStore) (bool, error) { @@ -204,9 +110,6 @@ func maybeStartStoppedOrJoin(t *terminal.Terminal, user *entity.User, options St return false, breverrors.NewValidationError(fmt.Sprintf("workspace with id/name %s is a failed workspace", options.RepoOrPathOrNameOrID)) } } - if allutil.DoesPathExist(options.RepoOrPathOrNameOrID) { - t.Print(t.Yellow(fmt.Sprintf("Warning: local path found and instance name/id found %s. Using instance name/id. If you meant to specify a local path change directory and try again.", options.RepoOrPathOrNameOrID))) - } errr := startStopppedWorkspace(&userWorkspaces[0], startStore, t, options) if errr != nil { return false, breverrors.WrapAndTrace(errr) @@ -214,209 +117,13 @@ func maybeStartStoppedOrJoin(t *terminal.Terminal, user *entity.User, options St return true, nil } - if len(workspaces) > 0 { - err = joinProjectWithNewWorkspace(t, workspaces[0], org.ID, startStore, user, options) - if err != nil { - return false, breverrors.WrapAndTrace(err) - } - return true, nil - } return false, nil } -func maybeStartFromGitURL(t *terminal.Terminal, user *entity.User, options StartOptions, startStore StartStore) (bool, error) { - if allutil.IsGitURL(options.RepoOrPathOrNameOrID) { // todo this is function is not complete, some cloneable urls are not identified - err := createNewWorkspaceFromGit(user, t, options.SetupScript, options, startStore) - if err != nil { - return true, breverrors.WrapAndTrace(err) - } - return true, nil - } - return false, nil -} - -func maybeStartEmpty(t *terminal.Terminal, user *entity.User, options StartOptions, startStore StartStore) (bool, error) { - if options.RepoOrPathOrNameOrID == "" { - err := createEmptyWorkspace(user, t, options, startStore) - if err != nil { - return true, breverrors.WrapAndTrace(err) - } - return true, nil - } - return false, nil -} - -func startWorkspaceFromPath(user *entity.User, t *terminal.Terminal, options StartOptions, startStore StartStore) error { - pathExists := allutil.DoesPathExist(options.RepoOrPathOrNameOrID) - if !pathExists { - return fmt.Errorf(strings.Join([]string{"Path:", options.RepoOrPathOrNameOrID, "does not exist."}, " ")) - } - var gitpath string - if options.RepoOrPathOrNameOrID == "." { - gitpath = filepath.Join(".git", "config") - } else { - gitpath = filepath.Join(options.RepoOrPathOrNameOrID, ".git", "config") - } - file, error := startStore.GetFileAsString(gitpath) - if error != nil { - return fmt.Errorf(strings.Join([]string{"Could not read .git/config at", options.RepoOrPathOrNameOrID}, " ")) - } - // Get GitUrl - var gitURL string - for _, v := range strings.Split(file, "\n") { - if strings.Contains(v, "url") { - gitURL = strings.Split(v, "= ")[1] - } - } - if len(gitURL) == 0 { - return fmt.Errorf("no git url found") - } - gitParts := strings.Split(gitURL, "/") - options.Name = strings.Split(gitParts[len(gitParts)-1], ".")[0] - localSetupPath := filepath.Join(options.RepoOrPathOrNameOrID, ".brev", "setup.sh") - if options.RepoOrPathOrNameOrID == "." { - localSetupPath = filepath.Join(".brev", "setup.sh") - } - if !allutil.DoesPathExist(localSetupPath) { - fmt.Println(strings.Join([]string{"Generating setup script at", localSetupPath}, "\n")) - mergeshells.ImportPath(t, options.RepoOrPathOrNameOrID, startStore) - fmt.Println("setup script generated.") - } - - // createNewWorkspaceFromGit expects this field to be a git url, but above - // logic wants it to be the directory path, so set it only before calling - // createNewWorkspaceFromGit - options.RepoOrPathOrNameOrID = gitURL - err := createNewWorkspaceFromGit(user, t, localSetupPath, options, startStore) - if err != nil { - return breverrors.WrapAndTrace(err) - } - - return err -} - -func createEmptyWorkspace(user *entity.User, t *terminal.Terminal, options StartOptions, startStore StartStore) error { //nolint:funlen,gocyclo // TODO refactor - // ensure name - if len(options.Name) == 0 { - return breverrors.NewValidationError("name field is required for empty workspaces") - } - - // ensure org - var orgID string - if options.OrgName == "" { - activeorg, err := startStore.GetActiveOrganizationOrDefault() - if err != nil { - return breverrors.WrapAndTrace(err) - } - if activeorg == nil { - return breverrors.NewValidationError("no org exist") - } - orgID = activeorg.ID - } else { - orgs, err := startStore.GetOrganizations(&store.GetOrganizationsOptions{Name: options.OrgName}) - if err != nil { - return breverrors.WrapAndTrace(err) - } - if len(orgs) == 0 { - return breverrors.NewValidationError(fmt.Sprintf("no org with name %s", options.OrgName)) - } else if len(orgs) > 1 { - return breverrors.NewValidationError(fmt.Sprintf("more than one org with name %s", options.OrgName)) - } - orgID = orgs[0].ID - } - - var setupScriptContents string - var err error - if len(options.SetupScript) > 0 { - contents, err1 := startStore.GetSetupScriptContentsByURL(options.SetupScript) - setupScriptContents += "\n" + contents - - if err1 != nil { - t.Vprintf(t.Red("Couldn't fetch setup script from %s\n", options.SetupScript) + t.Yellow("Continuing with default setup script 👍")) - return breverrors.WrapAndTrace(err1) - } - } - - clusterID := config.GlobalConfig.GetDefaultClusterID() - cwOptions := store.NewCreateWorkspacesOptions(clusterID, options.Name) - - if options.WorkspaceClass != "" { - cwOptions.WithClassID(options.WorkspaceClass) - } - - cwOptions = resolveWorkspaceUserOptions(cwOptions, user) - - if len(setupScriptContents) > 0 { - cwOptions.WithStartupScript(setupScriptContents) - } - - if options.InstanceType != "" { - cwOptions.WithInstanceType(options.InstanceType) - } - - t.Vprintf("Creating instance %s in org %s\n", t.Green(cwOptions.Name), t.Green(orgID)) - t.Vprintf("\tname %s\n", t.Green(cwOptions.Name)) - if options.InstanceType != "" { - t.Vprintf("\tGPU instance %s\n", t.Green(options.InstanceType)) - } else { - t.Vprintf("\tCPU instance %s\n", t.Green(cwOptions.WorkspaceClassID)) - } - t.Vprintf("\tCloud %s\n\n", t.Green(cwOptions.WorkspaceGroupID)) - - s := t.NewSpinner() - s.Suffix = " Creating your instance. Hang tight 🤙" - s.Start() - w, err := startStore.CreateWorkspace(orgID, cwOptions) - if err != nil { - return breverrors.WrapAndTrace(err) - } - s.Stop() - - if options.Detached { - return nil - } else { - err = pollUntil(t, w.ID, entity.Running, startStore, true) - if err != nil { - return breverrors.WrapAndTrace(err) - } - - fmt.Print("\n") - t.Vprint(t.Green("Your instance is ready!\n")) - displayConnectBreadCrumb(t, w) - - return nil - } -} - -func resolveWorkspaceUserOptions(options *store.CreateWorkspacesOptions, user *entity.User) *store.CreateWorkspacesOptions { - if options.WorkspaceTemplateID == "" { - if featureflag.IsAdmin(user.GlobalUserType) { - options.WorkspaceTemplateID = store.DevWorkspaceTemplateID - } else { - options.WorkspaceTemplateID = store.UserWorkspaceTemplateID - } - } - if options.WorkspaceClassID == "" { - if featureflag.IsAdmin(user.GlobalUserType) { - options.WorkspaceClassID = store.DevWorkspaceClassID - } else { - options.WorkspaceClassID = store.UserWorkspaceClassID - } - } - return options -} - func startStopppedWorkspace(workspace *entity.Workspace, startStore StartStore, t *terminal.Terminal, startOptions StartOptions) error { if workspace.Status != entity.Stopped { return breverrors.NewValidationError(fmt.Sprintf("Instance is not stopped status=%s", workspace.Status)) } - if startOptions.WorkspaceClass != "" { - return breverrors.NewValidationError("Instance already exists. Can not pass instance class flag to start stopped instance") - } - - if startOptions.Name != "" { - t.Vprint("Existing instance found. Name flag ignored.") - } startedWorkspace, err := startStore.StartWorkspace(workspace.ID) if err != nil { @@ -442,222 +149,6 @@ func startStopppedWorkspace(workspace *entity.Workspace, startStore StartStore, return nil } -// "https://github.com/brevdev/microservices-demo.git -// "https://github.com/brevdev/microservices-demo.git" -// "git@github.com:brevdev/microservices-demo.git" -func joinProjectWithNewWorkspace(t *terminal.Terminal, templateWorkspace entity.Workspace, orgID string, startStore StartStore, user *entity.User, startOptions StartOptions) error { - clusterID := config.GlobalConfig.GetDefaultClusterID() - if startOptions.WorkspaceClass == "" { - startOptions.WorkspaceClass = templateWorkspace.WorkspaceClassID - } - - cwOptions := store.NewCreateWorkspacesOptions(clusterID, templateWorkspace.Name).WithGitRepo(templateWorkspace.GitRepo).WithWorkspaceClassID(startOptions.WorkspaceClass) - if startOptions.Name != "" { - cwOptions.Name = startOptions.Name - } else { - t.Vprintf("Name flag omitted, using auto generated name: %s\n", t.Green(cwOptions.Name)) - } - - cwOptions = resolveWorkspaceUserOptions(cwOptions, user) - - t.Vprintf("Creating instance %s in org %s\n", t.Green(cwOptions.Name), t.Green(orgID)) - t.Vprintf("\tname %s\n", cwOptions.Name) - if cwOptions.InstanceType != "" { - t.Vprintf("\tGPU instance %s\n", cwOptions.InstanceType) - } else { - t.Vprintf("\tCPU instance %s\n", cwOptions.WorkspaceClassID) - } - t.Vprintf("\tCloud %s\n", cwOptions.WorkspaceGroupID) - - s := t.NewSpinner() - s.Suffix = " Creating your instance. Hang tight 🤙" - s.Start() - w, err := startStore.CreateWorkspace(orgID, cwOptions) - if err != nil { - return breverrors.WrapAndTrace(err) - } - s.Stop() - - err = pollUntil(t, w.ID, entity.Running, startStore, true) - if err != nil { - return breverrors.WrapAndTrace(err) - } - - displayConnectBreadCrumb(t, w) - - return nil -} - -func IsURL(str string) bool { - u, err := url.Parse(str) - return err == nil && u.Scheme != "" && u.Host != "" -} - -func createNewWorkspaceFromGit(user *entity.User, t *terminal.Terminal, setupScriptURLOrPath string, startOptions StartOptions, startStore StartStore) error { - // https://gist.githubusercontent.com/naderkhalil/4a45d4d293dc3a9eb330adcd5440e148/raw/3ab4889803080c3be94a7d141c7f53e286e81592/setup.sh - // fetch contents of file - // todo: read contents of file - - var setupScriptContents string - var err error - if len(startOptions.RepoOrPathOrNameOrID) > 0 && len(startOptions.SetupPath) > 0 { - // STUFF HERE - } else if len(setupScriptURLOrPath) > 0 { - if IsURL(setupScriptURLOrPath) { - contents, err1 := startStore.GetSetupScriptContentsByURL(setupScriptURLOrPath) - if err1 != nil { - t.Vprintf(t.Red("Couldn't fetch setup script from %s\n", setupScriptURLOrPath) + t.Yellow("Continuing with default setup script 👍")) - return breverrors.WrapAndTrace(err1) - } - setupScriptContents += "\n" + contents - } else { - // ERROR: not sure what this use case is for - var err2 error - setupScriptContents, err2 = startStore.GetFileAsString(setupScriptURLOrPath) - if err2 != nil { - return breverrors.WrapAndTrace(err2) - } - } - } - _ = setupScriptContents - - newWorkspace := MakeNewWorkspaceFromURL(startOptions.RepoOrPathOrNameOrID) - - if (startOptions.Name) != "" { - newWorkspace.Name = startOptions.Name - } else { - t.Vprintf("Name flag omitted, using auto generated name: %s\n", t.Green(newWorkspace.Name)) - } - - var orgID string - if startOptions.OrgName == "" { - activeorg, err2 := startStore.GetActiveOrganizationOrDefault() - if err2 != nil { - return breverrors.WrapAndTrace(err) - } - if activeorg == nil { - return breverrors.NewValidationError("no org exist") - } - orgID = activeorg.ID - } else { - orgs, err2 := startStore.GetOrganizations(&store.GetOrganizationsOptions{Name: startOptions.OrgName}) - if err2 != nil { - return breverrors.WrapAndTrace(err) - } - if len(orgs) == 0 { - return breverrors.NewValidationError(fmt.Sprintf("no org with name %s", startOptions.OrgName)) - } else if len(orgs) > 1 { - return breverrors.NewValidationError(fmt.Sprintf("more than one org with name %s", startOptions.OrgName)) - } - orgID = orgs[0].ID - } - - err = createWorkspace(user, t, newWorkspace, orgID, startStore, startOptions) - if err != nil { - return breverrors.WrapAndTrace(err) - } - return nil -} - -type NewWorkspace struct { - Name string `json:"name"` - GitRepo string `json:"gitRepo"` -} - -func MakeNewWorkspaceFromURL(url string) NewWorkspace { - var name string - if strings.Contains(url, "http") { - split := strings.Split(url, ".com/") - provider := strings.Split(split[0], "://")[1] - - if strings.Contains(split[1], ".git") { - name = strings.Split(split[1], ".git")[0] - if strings.Contains(name, "/") { - name = strings.Split(name, "/")[1] - } - return NewWorkspace{ - GitRepo: fmt.Sprintf("%s.com:%s", provider, split[1]), - Name: name, - } - } else { - name = split[1] - if strings.Contains(name, "/") { - name = strings.Split(name, "/")[1] - } - return NewWorkspace{ - GitRepo: fmt.Sprintf("%s.com:%s.git", provider, split[1]), - Name: name, - } - } - } else { - split := strings.Split(url, ".com:") - provider := strings.Split(split[0], "@")[1] - name = strings.Split(split[1], ".git")[0] - if strings.Contains(name, "/") { - name = strings.Split(name, "/")[1] - } - return NewWorkspace{ - GitRepo: fmt.Sprintf("%s.com:%s", provider, split[1]), - Name: name, - } - } -} - -func createWorkspace(user *entity.User, t *terminal.Terminal, workspace NewWorkspace, orgID string, startStore StartStore, startOptions StartOptions) error { - clusterID := config.GlobalConfig.GetDefaultClusterID() - - options := store.NewCreateWorkspacesOptions(clusterID, workspace.Name).WithGitRepo(workspace.GitRepo) - - if startOptions.WorkspaceClass != "" { - options = options.WithWorkspaceClassID(startOptions.WorkspaceClass) - } - - options = resolveWorkspaceUserOptions(options, user) - - if startOptions.SetupRepo != "" { - options.WithCustomSetupRepo(startOptions.SetupRepo, startOptions.SetupPath) - } else if startOptions.SetupPath != "" { - options.StartupScriptPath = startOptions.SetupPath - } - - if startOptions.SetupScript != "" { - options.WithStartupScript(startOptions.SetupScript) - } - - if startOptions.InstanceType != "" { - options.WithInstanceType(startOptions.InstanceType) - } - - t.Vprintf("Creating instance %s in org %s\n", t.Green(workspace.Name), t.Green(orgID)) - t.Vprintf("\tname %s\n", workspace.Name) - if options.InstanceType != "" { - t.Vprintf("\tGPU instance %s\n", options.InstanceType) - } else { - t.Vprintf("\tCPU instance %s\n", options.WorkspaceClassID) - } - t.Vprintf("\tCloud %s\n", options.WorkspaceGroupID) - - s := t.NewSpinner() - s.Suffix = " Creating your instance. Hang tight 🤙" - s.Start() - w, err := startStore.CreateWorkspace(orgID, options) - if err != nil { - return breverrors.WrapAndTrace(err) - } - s.Stop() - - err = pollUntil(t, w.ID, entity.Running, startStore, true) - if err != nil { - return breverrors.WrapAndTrace(err) - } - fmt.Print("\n") - t.Vprint(t.Green("Your instance is ready!\n")) - - displayConnectBreadCrumb(t, w) - - return nil -} - func displayConnectBreadCrumb(t *terminal.Terminal, workspace *entity.Workspace) { t.Vprintf(t.Green("Connect to the instance:\n")) t.Vprintf(t.Yellow(fmt.Sprintf("\tbrev open %s\t# brev open -> open instance in VS Code\n", workspace.Name))) @@ -665,7 +156,7 @@ func displayConnectBreadCrumb(t *terminal.Terminal, workspace *entity.Workspace) // t.Vprintf(t.Yellow(fmt.Sprintf("\tssh %s\t# ssh -> ssh directly to instance\n", workspace.GetLocalIdentifier()))) } -func pollUntil(t *terminal.Terminal, wsid string, state string, startStore StartStore, canSafelyExit bool) error { //nolint:unparam // TODO refactor +func pollUntil(t *terminal.Terminal, wsid string, state string, startStore StartStore, canSafelyExit bool) error { s := t.NewSpinner() isReady := false if canSafelyExit { diff --git a/pkg/cmd/start/start_test.go b/pkg/cmd/start/start_test.go index 8ee68cab..d4133131 100644 --- a/pkg/cmd/start/start_test.go +++ b/pkg/cmd/start/start_test.go @@ -5,43 +5,8 @@ import ( "github.com/brevdev/brev-cli/pkg/entity" "github.com/brevdev/brev-cli/pkg/terminal" - "github.com/stretchr/testify/assert" ) -func TestMakeNewWorkspaceFromURL(t *testing.T) { - gitTruth := "github.com:brevdev/brev-cli.git" - nameTruth := "brev-cli" - - wksTruth := NewWorkspace{ - Name: nameTruth, - GitRepo: gitTruth, - } - - naked := "https://github.com/brevdev/brev-cli" - res := MakeNewWorkspaceFromURL(naked) - if !assert.Equal(t, wksTruth, res) { - return - } - - http := "http://github.com/brevdev/brev-cli.git" - res = MakeNewWorkspaceFromURL(http) - if !assert.Equal(t, wksTruth, res) { - return - } - - https := "https://github.com/brevdev/brev-cli.git" - res = MakeNewWorkspaceFromURL(https) - if !assert.Equal(t, wksTruth, res) { - return - } - - ssh := "git@github.com:brevdev/brev-cli.git" - res = MakeNewWorkspaceFromURL(ssh) - if !assert.Equal(t, wksTruth, res) { - return - } -} - func Test_DisplayBC(t *testing.T) { term := terminal.New() displayConnectBreadCrumb(term, &entity.Workspace{