diff --git a/.gitpod.yml b/.gitpod.yml index ba4b1eca0975d9..df332fb5930cfa 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -42,6 +42,11 @@ tasks: gp env -u GCP_ADC_FILE fi exit 0 + - name: Install `gitpod` CLI + command: | + leeway run components/local-app:install-cli + leeway run components/local-app:cli-completion + exit 0 # This task takes care of configuring your workspace so it can manage and interact # with preview environments. - name: Preview environment configuration diff --git a/components/local-app/BUILD.yaml b/components/local-app/BUILD.yaml index 4665c0cc20aadb..9eee7881858b21 100644 --- a/components/local-app/BUILD.yaml +++ b/components/local-app/BUILD.yaml @@ -13,3 +13,15 @@ packages: image: - ${imageRepoBase}/local-app:${version} - ${imageRepoBase}/local-app:commit-${__git_commit} + +scripts: + - name: install-cli + description: "Install gitpod-cli as `gitpod` command and add auto-completion. Usage: '. $(leeway run components/local-app:install-cli)'" + script: | + go build -o gitpod ./main/gitpod-cli + sudo mv gitpod /usr/bin/gitpod + sudo chmod +x /usr/bin/gitpod + - name: cli-completion + description: "Add completion of gitpod-cli to bash-completion. Usage: '. $(leeway run components/local-app:cli-completion)'" + script: | + sudo /usr/bin/gitpod completion bash | sudo tee /usr/share/bash-completion/completions/gitpod > /dev/null diff --git a/components/local-app/README.md b/components/local-app/README.md index fd754b3a3e81f8..5b8ce3b65d675f 100644 --- a/components/local-app/README.md +++ b/components/local-app/README.md @@ -1,4 +1,4 @@ - # local-app +# local-app ## gitpod-cli @@ -27,6 +27,20 @@ Start by logging in with `gitpod login`, which will also create a default contex To develop the CLI with Gitpod, you can run it just like locally, but in Gitpod workspaces, a browser and a keyring are not available. To log in despite these limitations, provide a PAT via the `GITPOD_TOKEN` environment variable, or use the `--token` flag with the login command. +#### in Gitpod workspace + +[![Open in Gitpod](https://www.gitpod.io/svg/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/gitpod-io/gitpod) + +You will have gitpod-cli ready as `gitpod` in your CDE (Cloud Development Environments) workspace, will commands below you can install again easily. + +``` +# Install as `gitpod` again +leeway run components/local-app:install-cli + +# Add completion again +leeway run components/local-app:cli-completion +``` + ## local-app **Beware**: this is very much work in progress and will likely break things. diff --git a/components/local-app/cmd/root.go b/components/local-app/cmd/root.go index 6ea0cf3f0f09ed..d8b0e1a8d77972 100644 --- a/components/local-app/cmd/root.go +++ b/components/local-app/cmd/root.go @@ -101,7 +101,13 @@ var rootTestingOpts struct { WriterOut io.Writer } +var clientCache *client.Gitpod + func getGitpodClient(ctx context.Context) (*client.Gitpod, error) { + // There will be only one client in a command context right now + if clientCache != nil { + return clientCache, nil + } cfg := config.FromContext(ctx) gpctx, err := cfg.GetActiveContext() if err != nil { @@ -154,6 +160,7 @@ func getGitpodClient(ctx context.Context) (*client.Gitpod, error) { if err != nil { return nil, err } + clientCache = res return res, nil } diff --git a/components/local-app/cmd/workspace-create.go b/components/local-app/cmd/workspace-create.go index 9c40350056c054..34c5761e8f0f6d 100644 --- a/components/local-app/cmd/workspace-create.go +++ b/components/local-app/cmd/workspace-create.go @@ -143,10 +143,53 @@ var workspaceCreateOpts struct { Editor string } +func classCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + ctx := cmd.Context() + gitpod, err := getGitpodClient(ctx) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + resp, err := gitpod.Workspaces.ListWorkspaceClasses(ctx, connect.NewRequest(&v1.ListWorkspaceClassesRequest{})) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + items := resp.Msg.GetResult() + completionStr := []string{} + for _, cls := range items { + defaultDesc := "" + if cls.IsDefault { + defaultDesc = "(default)" + } + completionStr = append(completionStr, fmt.Sprintf("%s\t%s%s - %s", cls.Id, cls.DisplayName, defaultDesc, cls.Description)) + } + return completionStr, cobra.ShellCompDirectiveNoFileComp +} + +func editorCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + ctx := cmd.Context() + gitpod, err := getGitpodClient(ctx) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + resp, err := gitpod.Editors.ListEditorOptions(ctx, connect.NewRequest(&v1.ListEditorOptionsRequest{})) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + items := resp.Msg.GetResult() + completionStr := []string{} + for _, editor := range items { + completionStr = append(completionStr, fmt.Sprintf("%s\t%s", editor.Id, editor.Title)) + } + return completionStr, cobra.ShellCompDirectiveNoFileComp +} + func init() { workspaceCmd.AddCommand(workspaceCreateCmd) addWorkspaceStartOptions(workspaceCreateCmd, &workspaceCreateOpts.StartOpts) workspaceCreateCmd.Flags().StringVar(&workspaceCreateOpts.WorkspaceClass, "class", "", "the workspace class") workspaceCreateCmd.Flags().StringVar(&workspaceCreateOpts.Editor, "editor", "code", "the editor to use") + + _ = workspaceCreateCmd.RegisterFlagCompletionFunc("class", classCompletionFunc) + _ = workspaceCreateCmd.RegisterFlagCompletionFunc("editor", editorCompletionFunc) } diff --git a/components/local-app/cmd/workspace-up.go b/components/local-app/cmd/workspace-up.go index c7505ac40d3477..4eb5bffb4a63f4 100644 --- a/components/local-app/cmd/workspace-up.go +++ b/components/local-app/cmd/workspace-up.go @@ -291,4 +291,7 @@ func init() { workspaceUpCmd.Flags().StringVar(&workspaceCreateOpts.WorkspaceClass, "class", "", "the workspace class") workspaceUpCmd.Flags().StringVar(&workspaceCreateOpts.Editor, "editor", "code", "the editor to use") + + _ = workspaceUpCmd.RegisterFlagCompletionFunc("class", classCompletionFunc) + _ = workspaceUpCmd.RegisterFlagCompletionFunc("editor", editorCompletionFunc) }