Change the way we parse list-devcontainers response
This commit is contained in:
parent
03b8b16585
commit
9554e522af
7 changed files with 51 additions and 28 deletions
|
|
@ -762,9 +762,14 @@ func (a *API) DeleteCodespace(ctx context.Context, codespaceName string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
type DevContainerEntry struct {
|
||||
Path string `json:"path"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// ListDevContainers returns a list of valid devcontainer.json files for the repo. Pass a negative limit to request all pages from
|
||||
// the API until all devcontainer.json files have been fetched.
|
||||
func (a *API) ListDevContainers(ctx context.Context, repoID int, branch string, limit int) (devcontainers []string, err error) {
|
||||
func (a *API) ListDevContainers(ctx context.Context, repoID int, branch string, limit int) (devcontainers []DevContainerEntry, err error) {
|
||||
perPage := 100
|
||||
if limit > 0 && limit < 100 {
|
||||
perPage = limit
|
||||
|
|
@ -792,8 +797,9 @@ func (a *API) ListDevContainers(ctx context.Context, repoID int, branch string,
|
|||
}
|
||||
|
||||
var response struct {
|
||||
Devcontainers []string `json:"devcontainers"`
|
||||
Devcontainers []DevContainerEntry `json:"devcontainers"`
|
||||
}
|
||||
|
||||
dec := json.NewDecoder(resp.Body)
|
||||
if err := dec.Decode(&response); err != nil {
|
||||
return nil, fmt.Errorf("error unmarshaling response: %w", err)
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ type apiClient interface {
|
|||
GetCodespaceRegionLocation(ctx context.Context) (string, error)
|
||||
GetCodespacesMachines(ctx context.Context, repoID int, branch, location string) ([]*api.Machine, error)
|
||||
GetCodespaceRepositoryContents(ctx context.Context, codespace *api.Codespace, path string) ([]byte, error)
|
||||
ListDevContainers(ctx context.Context, repoID int, branch string, limit int) (devcontainers []string, err error)
|
||||
ListDevContainers(ctx context.Context, repoID int, branch string, limit int) (devcontainers []api.DevContainerEntry, err error)
|
||||
GetCodespaceRepoSuggestions(ctx context.Context, partialSearch string, params api.RepoSearchParameters) ([]string, error)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ func (a *App) Create(ctx context.Context, opts createOptions) error {
|
|||
|
||||
locationCh := getLocation(ctx, vscsLocation, a.apiClient)
|
||||
|
||||
DEFAULT_DEVCONTAINER_DEFINITIONS := []string{".devcontainer.json", ".devcontainer/devcontainer.json"}
|
||||
|
||||
userInputs := struct {
|
||||
Repository string
|
||||
Branch string
|
||||
|
|
@ -113,23 +115,35 @@ func (a *App) Create(ctx context.Context, opts createOptions) error {
|
|||
// now that we have repo+branch, we can list available devcontainer.json files (if any)
|
||||
if len(opts.devContainerPath) < 1 {
|
||||
a.StartProgressIndicatorWithLabel("Fetching devcontainer.json files")
|
||||
devContainerPaths, err := a.apiClient.ListDevContainers(ctx, repository.ID, branch, 100)
|
||||
devcontainers, err := a.apiClient.ListDevContainers(ctx, repository.ID, branch, 100)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting devcontainer.json paths: %w", err)
|
||||
}
|
||||
a.StopProgressIndicator()
|
||||
|
||||
if len(devContainerPaths) > 0 {
|
||||
devContainerPathQuestion := &survey.Question{
|
||||
Name: "devContainerPath",
|
||||
Prompt: &survey.Select{
|
||||
Message: "Devcontainer definition file:",
|
||||
Options: append([]string{"default"}, devContainerPaths...),
|
||||
},
|
||||
}
|
||||
if len(devcontainers) > 0 {
|
||||
|
||||
if err := ask([]*survey.Question{devContainerPathQuestion}, &devContainerPath); err != nil {
|
||||
return fmt.Errorf("failed to prompt: %w", err)
|
||||
// if there is only one devcontainer.json file and it is one of the default paths we can auto-select it
|
||||
if len(devcontainers) == 1 && utils.StringInSlice(devcontainers[0].Path, DEFAULT_DEVCONTAINER_DEFINITIONS) {
|
||||
devContainerPath = devcontainers[0].Path
|
||||
} else {
|
||||
promptOptions := []string{"default"}
|
||||
|
||||
for _, devcontainer := range devcontainers {
|
||||
promptOptions = append(promptOptions, devcontainer.Path)
|
||||
}
|
||||
|
||||
devContainerPathQuestion := &survey.Question{
|
||||
Name: "devContainerPath",
|
||||
Prompt: &survey.Select{
|
||||
Message: "Devcontainer definition file:",
|
||||
Options: promptOptions,
|
||||
},
|
||||
}
|
||||
|
||||
if err := ask([]*survey.Question{devContainerPathQuestion}, &devContainerPath); err != nil {
|
||||
return fmt.Errorf("failed to prompt: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ func TestApp_Create(t *testing.T) {
|
|||
DefaultBranch: "main",
|
||||
}, nil
|
||||
},
|
||||
ListDevContainersFunc: func(ctx context.Context, repoID int, branch string, limit int) ([]string, error) {
|
||||
return []string{}, nil
|
||||
ListDevContainersFunc: func(ctx context.Context, repoID int, branch string, limit int) ([]api.DevContainerEntry, error) {
|
||||
return []api.DevContainerEntry{}, nil
|
||||
},
|
||||
GetCodespacesMachinesFunc: func(ctx context.Context, repoID int, branch, location string) ([]*api.Machine, error) {
|
||||
return []*api.Machine{
|
||||
|
|
@ -139,7 +139,7 @@ func TestApp_Create(t *testing.T) {
|
|||
DefaultBranch: "main",
|
||||
}, nil
|
||||
},
|
||||
ListDevContainersFunc: func(ctx context.Context, repoID int, branch string, limit int) ([]string, error) {
|
||||
ListDevContainersFunc: func(ctx context.Context, repoID int, branch string, limit int) ([]api.DevContainerEntry, error) {
|
||||
return nil, fmt.Errorf("some error")
|
||||
},
|
||||
},
|
||||
|
|
@ -167,8 +167,8 @@ func TestApp_Create(t *testing.T) {
|
|||
DefaultBranch: "main",
|
||||
}, nil
|
||||
},
|
||||
ListDevContainersFunc: func(ctx context.Context, repoID int, branch string, limit int) ([]string, error) {
|
||||
return []string{}, nil
|
||||
ListDevContainersFunc: func(ctx context.Context, repoID int, branch string, limit int) ([]api.DevContainerEntry, error) {
|
||||
return []api.DevContainerEntry{}, nil
|
||||
},
|
||||
GetCodespacesMachinesFunc: func(ctx context.Context, repoID int, branch, location string) ([]*api.Machine, error) {
|
||||
return []*api.Machine{
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ import (
|
|||
// ListCodespacesFunc: func(ctx context.Context, limit int) ([]*api.Codespace, error) {
|
||||
// panic("mock out the ListCodespaces method")
|
||||
// },
|
||||
// ListDevContainersFunc: func(ctx context.Context, repoID int, branch string, limit int) ([]string, error) {
|
||||
// ListDevContainersFunc: func(ctx context.Context, repoID int, branch string, limit int) ([]api.DevContainerEntry, error) {
|
||||
// panic("mock out the ListDevContainers method")
|
||||
// },
|
||||
// StartCodespaceFunc: func(ctx context.Context, name string) error {
|
||||
|
|
@ -105,7 +105,7 @@ type apiClientMock struct {
|
|||
ListCodespacesFunc func(ctx context.Context, limit int) ([]*api.Codespace, error)
|
||||
|
||||
// ListDevContainersFunc mocks the ListDevContainers method.
|
||||
ListDevContainersFunc func(ctx context.Context, repoID int, branch string, limit int) ([]string, error)
|
||||
ListDevContainersFunc func(ctx context.Context, repoID int, branch string, limit int) ([]api.DevContainerEntry, error)
|
||||
|
||||
// StartCodespaceFunc mocks the StartCodespace method.
|
||||
StartCodespaceFunc func(ctx context.Context, name string) error
|
||||
|
|
@ -687,7 +687,7 @@ func (mock *apiClientMock) ListCodespacesCalls() []struct {
|
|||
}
|
||||
|
||||
// ListDevContainers calls ListDevContainersFunc.
|
||||
func (mock *apiClientMock) ListDevContainers(ctx context.Context, repoID int, branch string, limit int) ([]string, error) {
|
||||
func (mock *apiClientMock) ListDevContainers(ctx context.Context, repoID int, branch string, limit int) ([]api.DevContainerEntry, error) {
|
||||
if mock.ListDevContainersFunc == nil {
|
||||
panic("apiClientMock.ListDevContainersFunc: method is nil but apiClient.ListDevContainers was just called")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"repository_id": 392831291,
|
||||
"location": "WestUs2",
|
||||
"devcontainer_path": ".devcontainer/foo ' \" bar/devcontainer.json",
|
||||
"vscs_target": "development"
|
||||
}
|
||||
|
|
@ -83,3 +83,12 @@ func DisplayURL(urlStr string) string {
|
|||
func ValidURL(urlStr string) bool {
|
||||
return len(urlStr) < 8192
|
||||
}
|
||||
|
||||
func StringInSlice(a string, slice []string) bool {
|
||||
for _, b := range slice {
|
||||
if b == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue