Skip to content

Commit cbb8253

Browse files
committed
consolidate survey functions
1 parent 6b0510f commit cbb8253

File tree

8 files changed

+108
-94
lines changed

8 files changed

+108
-94
lines changed

cmd/ghcs/code.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"os"
88

99
"github.com/github/ghcs/api"
10-
"github.com/github/ghcs/internal/codespaces"
1110
"github.com/skratchdot/open-golang/open"
1211
"github.com/spf13/cobra"
1312
)
@@ -47,9 +46,9 @@ func code(codespaceName string, useInsiders bool) error {
4746
}
4847

4948
if codespaceName == "" {
50-
codespace, err := codespaces.ChooseCodespace(ctx, apiClient, user)
49+
codespace, err := chooseCodespace(ctx, apiClient, user)
5150
if err != nil {
52-
if err == codespaces.ErrNoCodespaces {
51+
if err == errNoCodespaces {
5352
return err
5453
}
5554
return fmt.Errorf("error choosing codespace: %v", err)

cmd/ghcs/common.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package main
2+
3+
// This file defines functions common to the entire ghcs command set.
4+
5+
import (
6+
"context"
7+
"errors"
8+
"fmt"
9+
"sort"
10+
11+
"github.com/AlecAivazis/survey/v2"
12+
"github.com/github/ghcs/api"
13+
"golang.org/x/term"
14+
)
15+
16+
var errNoCodespaces = errors.New("You have no codespaces.")
17+
18+
func chooseCodespace(ctx context.Context, apiClient *api.API, user *api.User) (*api.Codespace, error) {
19+
codespaces, err := apiClient.ListCodespaces(ctx, user)
20+
if err != nil {
21+
return nil, fmt.Errorf("error getting codespaces: %v", err)
22+
}
23+
24+
if len(codespaces) == 0 {
25+
return nil, errNoCodespaces
26+
}
27+
28+
sort.Slice(codespaces, func(i, j int) bool {
29+
return codespaces[i].CreatedAt > codespaces[j].CreatedAt
30+
})
31+
32+
codespacesByName := make(map[string]*api.Codespace)
33+
codespacesNames := make([]string, 0, len(codespaces))
34+
for _, codespace := range codespaces {
35+
codespacesByName[codespace.Name] = codespace
36+
codespacesNames = append(codespacesNames, codespace.Name)
37+
}
38+
39+
sshSurvey := []*survey.Question{
40+
{
41+
Name: "codespace",
42+
Prompt: &survey.Select{
43+
Message: "Choose codespace:",
44+
Options: codespacesNames,
45+
Default: codespacesNames[0],
46+
},
47+
Validate: survey.Required,
48+
},
49+
}
50+
51+
var answers struct {
52+
Codespace string
53+
}
54+
if err := ask(sshSurvey, &answers); err != nil {
55+
return nil, fmt.Errorf("error getting answers: %v", err)
56+
}
57+
58+
codespace := codespacesByName[answers.Codespace]
59+
return codespace, nil
60+
}
61+
62+
func getOrChooseCodespace(ctx context.Context, apiClient *api.API, user *api.User, codespaceName string) (codespace *api.Codespace, token string, err error) {
63+
if codespaceName == "" {
64+
codespace, err = chooseCodespace(ctx, apiClient, user)
65+
if err != nil {
66+
if err == errNoCodespaces {
67+
return nil, "", err
68+
}
69+
return nil, "", fmt.Errorf("choosing codespace: %v", err)
70+
}
71+
codespaceName = codespace.Name
72+
73+
token, err = apiClient.GetCodespaceToken(ctx, user.Login, codespaceName)
74+
if err != nil {
75+
return nil, "", fmt.Errorf("getting codespace token: %v", err)
76+
}
77+
} else {
78+
token, err = apiClient.GetCodespaceToken(ctx, user.Login, codespaceName)
79+
if err != nil {
80+
return nil, "", fmt.Errorf("getting codespace token for given codespace: %v", err)
81+
}
82+
83+
codespace, err = apiClient.GetCodespace(ctx, token, user.Login, codespaceName)
84+
if err != nil {
85+
return nil, "", fmt.Errorf("getting full codespace details: %v", err)
86+
}
87+
}
88+
89+
return codespace, token, nil
90+
}
91+
92+
var hasTTY = term.IsTerminal(0) && term.IsTerminal(1) // is process connected to a terminal?
93+
94+
// ask asks survey questions on the terminal, using standard options.
95+
// It fails unless hasTTY, but ideally callers should avoid calling it in that case.
96+
func ask(qs []*survey.Question, response interface{}) error {
97+
if !hasTTY {
98+
return fmt.Errorf("no terminal")
99+
}
100+
return survey.Ask(qs, response, survey.WithShowCursor(true))
101+
}

cmd/ghcs/create.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,3 @@ func getMachineName(ctx context.Context, machine string, user *api.User, repo *a
286286

287287
return machine, nil
288288
}
289-
290-
// ask asks survery questions using standard options.
291-
func ask(qs []*survey.Question, response interface{}) error {
292-
return survey.Ask(qs, response, survey.WithShowCursor(true))
293-
}

cmd/ghcs/delete.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88

99
"github.com/github/ghcs/api"
1010
"github.com/github/ghcs/cmd/ghcs/output"
11-
"github.com/github/ghcs/internal/codespaces"
1211
"github.com/spf13/cobra"
1312
)
1413

@@ -63,7 +62,7 @@ func delete_(codespaceName string) error {
6362
return fmt.Errorf("error getting user: %v", err)
6463
}
6564

66-
codespace, token, err := codespaces.GetOrChooseCodespace(ctx, apiClient, user, codespaceName)
65+
codespace, token, err := getOrChooseCodespace(ctx, apiClient, user, codespaceName)
6766
if err != nil {
6867
return fmt.Errorf("get or choose codespace: %v", err)
6968
}

cmd/ghcs/logs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func logs(ctx context.Context, tail bool, codespaceName string) error {
5151
return fmt.Errorf("getting user: %v", err)
5252
}
5353

54-
codespace, token, err := codespaces.GetOrChooseCodespace(ctx, apiClient, user, codespaceName)
54+
codespace, token, err := getOrChooseCodespace(ctx, apiClient, user, codespaceName)
5555
if err != nil {
5656
return fmt.Errorf("get or choose codespace: %v", err)
5757
}

cmd/ghcs/ports.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ func ports(opts *portsOptions) error {
6767
return fmt.Errorf("error getting user: %v", err)
6868
}
6969

70-
codespace, token, err := codespaces.GetOrChooseCodespace(ctx, apiClient, user, opts.codespaceName)
70+
codespace, token, err := getOrChooseCodespace(ctx, apiClient, user, opts.codespaceName)
7171
if err != nil {
72-
if err == codespaces.ErrNoCodespaces {
72+
if err == errNoCodespaces {
7373
return err
7474
}
7575
return fmt.Errorf("error choosing codespace: %v", err)

cmd/ghcs/ssh.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func ssh(ctx context.Context, sshProfile, codespaceName string, localSSHServerPo
5252
return fmt.Errorf("error getting user: %v", err)
5353
}
5454

55-
codespace, token, err := codespaces.GetOrChooseCodespace(ctx, apiClient, user, codespaceName)
55+
codespace, token, err := getOrChooseCodespace(ctx, apiClient, user, codespaceName)
5656
if err != nil {
5757
return fmt.Errorf("get or choose codespace: %v", err)
5858
}

internal/codespaces/codespaces.go

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -4,62 +4,12 @@ import (
44
"context"
55
"errors"
66
"fmt"
7-
"sort"
87
"time"
98

10-
"github.com/AlecAivazis/survey/v2"
119
"github.com/github/ghcs/api"
1210
"github.com/github/go-liveshare"
1311
)
1412

15-
var (
16-
ErrNoCodespaces = errors.New("You have no codespaces.")
17-
)
18-
19-
func ChooseCodespace(ctx context.Context, apiClient *api.API, user *api.User) (*api.Codespace, error) {
20-
codespaces, err := apiClient.ListCodespaces(ctx, user)
21-
if err != nil {
22-
return nil, fmt.Errorf("error getting codespaces: %v", err)
23-
}
24-
25-
if len(codespaces) == 0 {
26-
return nil, ErrNoCodespaces
27-
}
28-
29-
sort.Slice(codespaces, func(i, j int) bool {
30-
return codespaces[i].CreatedAt > codespaces[j].CreatedAt
31-
})
32-
33-
codespacesByName := make(map[string]*api.Codespace)
34-
codespacesNames := make([]string, 0, len(codespaces))
35-
for _, codespace := range codespaces {
36-
codespacesByName[codespace.Name] = codespace
37-
codespacesNames = append(codespacesNames, codespace.Name)
38-
}
39-
40-
sshSurvey := []*survey.Question{
41-
{
42-
Name: "codespace",
43-
Prompt: &survey.Select{
44-
Message: "Choose codespace:",
45-
Options: codespacesNames,
46-
Default: codespacesNames[0],
47-
},
48-
Validate: survey.Required,
49-
},
50-
}
51-
52-
answers := struct {
53-
Codespace string
54-
}{}
55-
if err := survey.Ask(sshSurvey, &answers); err != nil {
56-
return nil, fmt.Errorf("error getting answers: %v", err)
57-
}
58-
59-
codespace := codespacesByName[answers.Codespace]
60-
return codespace, nil
61-
}
62-
6313
type logger interface {
6414
Print(v ...interface{}) (int, error)
6515
Println(v ...interface{}) (int, error)
@@ -123,33 +73,3 @@ func ConnectToLiveshare(ctx context.Context, log logger, apiClient *api.API, use
12373

12474
return lsclient.JoinWorkspace(ctx)
12575
}
126-
127-
func GetOrChooseCodespace(ctx context.Context, apiClient *api.API, user *api.User, codespaceName string) (codespace *api.Codespace, token string, err error) {
128-
if codespaceName == "" {
129-
codespace, err = ChooseCodespace(ctx, apiClient, user)
130-
if err != nil {
131-
if err == ErrNoCodespaces {
132-
return nil, "", err
133-
}
134-
return nil, "", fmt.Errorf("choosing codespace: %v", err)
135-
}
136-
codespaceName = codespace.Name
137-
138-
token, err = apiClient.GetCodespaceToken(ctx, user.Login, codespaceName)
139-
if err != nil {
140-
return nil, "", fmt.Errorf("getting codespace token: %v", err)
141-
}
142-
} else {
143-
token, err = apiClient.GetCodespaceToken(ctx, user.Login, codespaceName)
144-
if err != nil {
145-
return nil, "", fmt.Errorf("getting codespace token for given codespace: %v", err)
146-
}
147-
148-
codespace, err = apiClient.GetCodespace(ctx, token, user.Login, codespaceName)
149-
if err != nil {
150-
return nil, "", fmt.Errorf("getting full codespace details: %v", err)
151-
}
152-
}
153-
154-
return codespace, token, nil
155-
}

0 commit comments

Comments
 (0)