Skip to content

Commit

Permalink
Local App v2 :) (#18971)
Browse files Browse the repository at this point in the history
* Local App v2 :)

* bind variables correctly

* Play around with units

* Port more commands over

* Separate commands (1 per file)

* `gitpod workspace delete`

* Extract login

* Show help text when run without a command

* Fix login

* `gitpod logout`

* Simple logging

* Remove unused import

* Make host use consistent

* Fix GetToken

* Split distribution

* 🤷‍♂️

* Fix paths 🤷🤦

* Change URL of binaries

* Fix proxy binary handling

Co-authored-by: Pudong <[email protected]>

* Improve logging

* Change workspace list to be up-to-spec

* `gitpod organizations list`

* Simplify table code

* `gitpod workspace get`

* Created at

* `gitpod organization get <id>`

* Hide open for now

* `workspace start --ssh`

* `ws start --open`

* server: OAuth client

* Use OAuth app

* logs

* `gitpod workspace create`

* Rename to follow singular noun semantics

* Fix nil pointers in list and go cmds

* `--field` for `gitpod organizations list`

* `gitpod ws list --field`

* Simplify some of the ws code

* Unify WS data structure

* Allow opening browser-based WSs

* `gitpod workspace open`

* Constants package to get rid of circular dependency issues

* No config file by default

* Guidance when missing in path

* Fix local companion maybe 🤷‍♂️

* Create wait for start by default

* Align scopes

* KeychainName constant

* Provide token via flag instead

* Host in scope error lookup message

* 🤷‍♂️

* Name for consistency

* Editors in go client of papi

* `gitpod workspace list-classes`

* `gitpod config`

* Infer orgs if applicable

* Remove redundant error log

* Retry mechanism for streaming

* More useful error message for unauthed

* README update

* Allow `function:getTeam`

* return org inference errors properly

* Replace config with context

* Fix config file path

* Wrap up pretty printer

* Name changes

* Remove unused vars

* 🇺🇸

* Update README

* Fix login

* [local-app] Add whoami command

* [local-app] Add context management

* Refactor common package

* Harmonise output and formatting

* Add error resolution support

* Improve resolution printing

* Add apology for system exceptions

* Add class resolutions

* Apologise more

* Add unknown field resolution

* Add better login context name

* Make it build

* `gitpod workspace list-editors`

* Fix multiple ws IDs for `ws get`

* Simplify open code

* Update local-app README with usage instructions

* Help for editor options

* Remove unused config code

* Call workspace ID field ID instead of workspace

* Improve long format output

* Fix whoami output

* Streamline workspace listing

* Introduce fancy intro

* Improve set-context feedback

* Remove common package

* Add first unit test

* Harmonise field order

* Consistency across get commands

* Consistency among list command aliases

* Fix column name in whoami

* Fix nil refs for empty hosts

* Make prettyprint writer typesafe

* Add resolutions for no token or no host found

* Fix typo

* Fix CI build

* Properly record org ID on login

* Print orgs in wide format

* Added "workspace up" functionality back in

but hidden

* Make "Git" casing consistent

https://english.stackexchange.com/questions/611711/tech-related-should-i-capitalize-the-word-git-in-this-context-or-not

* Introduce workspace up intermediary

* Fix proxied binary name

---------

Co-authored-by: Pudong <[email protected]>
Co-authored-by: Christian Weichel (Chris) <[email protected]>
  • Loading branch information
3 people authored Nov 6, 2023
1 parent 0d19e87 commit e51d974
Show file tree
Hide file tree
Showing 46 changed files with 3,354 additions and 266 deletions.
9 changes: 2 additions & 7 deletions components/ide-proxy/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,8 @@ FROM cgr.dev/chainguard/wolfi-base:latest@sha256:a8c9c2888304e62c133af76f520c9c9

RUN apk add brotli gzip

COPY components-local-app--app/components-local-app--app-linux-amd64/local-app /bin/gitpod-local-companion-linux-amd64
COPY components-local-app--app/components-local-app--app-darwin-amd64/local-app /bin/gitpod-local-companion-darwin-amd64
COPY components-local-app--app/components-local-app--app-windows-amd64/local-app.exe /bin/gitpod-local-companion-windows-amd64.exe
COPY components-local-app--app/components-local-app--app-linux-arm64/local-app /bin/gitpod-local-companion-linux-arm64
COPY components-local-app--app/components-local-app--app-darwin-arm64/local-app /bin/gitpod-local-companion-darwin-arm64
COPY components-local-app--app/components-local-app--app-windows-386/local-app.exe /bin/gitpod-local-companion-windows-arm64.exe
COPY components-local-app--app/components-local-app--app-windows-386/local-app.exe /bin/gitpod-local-companion-windows-386.exe
# Gitpod CLI and Local App
COPY components-local-app--app/bin/* /bin/

RUN for FILE in `ls /bin/gitpod-local-companion*`;do \
gzip -v -f -9 -k "$FILE"; \
Expand Down
63 changes: 63 additions & 0 deletions components/local-app/BUILD.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const generatePackage = function (goos, goarch, binaryName, mainFile) {
let name = binaryName + "-" + goos + "-" + goarch;
let dontTest = !(goos === "linux" && goarch === "amd64");
if (goos === "windows") {
binaryName += ".exe";
}
let pkg = {
name,
type: "go",
srcs: ["go.mod", "go.sum", "**/*.go"],
deps: [
"components/supervisor-api/go:lib",
"components/gitpod-protocol/go:lib",
"components/local-app-api/go:lib",
"components/public-api/go:lib",
],
env: ["GOOS=" + goos, "GOARCH=" + goarch, "CGO_ENABLED=0"],
config: {
packaging: "app",
dontTest: dontTest,
buildCommand: [
"go",
"build",
"-trimpath",
"-ldflags",
"-buildid= -w -s -X 'github.com/gitpod-io/local-app/pkg/common.Version=commit-${__git_commit}'",
"-o",
binaryName,
mainFile,
],
},
binaryName,
};
return pkg;
};

const packages = [];
for (binaryName of ["gitpod-local-companion", "gitpod-cli"]) {
for (goos of ["linux", "darwin", "windows"]) {
for (goarch of ["amd64", "arm64"]) {
packages.push(generatePackage(goos, goarch, binaryName, "main/" + binaryName + "/main.go"));
}
}
}

let appCmds = packages.map((p) => {
let binName = p.name;
if (p.name.includes("windows")) {
binName += ".exe";
}
return ["cp", "components-local-app--" + p.name + "/" + p.binaryName, "bin/" + binName];
});
appCmds.unshift(["mkdir", "bin"]);
appCmds.push(["sh", "-c", "rm -rf components-*"]);

packages.push({
name: "app",
type: "generic",
deps: packages.map((d) => ":" + d.name),
config: {
commands: appCmds,
},
});
132 changes: 1 addition & 131 deletions components/local-app/BUILD.yaml
Original file line number Diff line number Diff line change
@@ -1,135 +1,5 @@
packages:
- name: app
type: generic
config:
commands: [["echo"]]
deps:
- :app-linux-amd64
- :app-linux-arm64
- :app-darwin-amd64
- :app-darwin-arm64
- :app-windows-386
- :app-windows-amd64
- :app-windows-arm64
- name: app-linux-amd64
type: go
srcs:
- go.mod
- go.sum
- "**/*.go"
deps:
- components/supervisor-api/go:lib
- components/gitpod-protocol/go:lib
- components/local-app-api/go:lib
env:
- CGO_ENABLED=0
- GOOS=linux
- GOARCH=amd64
config:
packaging: app
buildCommand: ["go", "build", "-trimpath", "-ldflags", "-buildid= -w -s -X 'github.com/gitpod-io/local-app.Version=commit-${__git_commit}'"]
- name: app-linux-arm64
type: go
srcs:
- go.mod
- go.sum
- "**/*.go"
deps:
- components/supervisor-api/go:lib
- components/gitpod-protocol/go:lib
- components/local-app-api/go:lib
env:
- CGO_ENABLED=0
- GOOS=linux
- GOARCH=arm64
config:
packaging: app
buildCommand: ["go", "build", "-trimpath", "-ldflags", "-buildid= -w -s -X 'github.com/gitpod-io/local-app.Version=commit-${__git_commit}'"]
- name: app-darwin-amd64
type: go
srcs:
- go.mod
- go.sum
- "**/*.go"
deps:
- components/supervisor-api/go:lib
- components/gitpod-protocol/go:lib
- components/local-app-api/go:lib
env:
- CGO_ENABLED=0
- GOOS=darwin
- GOARCH=amd64
config:
packaging: app
buildCommand: ["go", "build", "-trimpath", "-ldflags", "-buildid= -w -s -X 'github.com/gitpod-io/local-app.Version=commit-${__git_commit}'"]
- name: app-darwin-arm64
type: go
srcs:
- go.mod
- go.sum
- "**/*.go"
deps:
- components/supervisor-api/go:lib
- components/gitpod-protocol/go:lib
- components/local-app-api/go:lib
env:
- CGO_ENABLED=0
- GOOS=darwin
- GOARCH=arm64
config:
packaging: app
buildCommand: ["go", "build", "-trimpath", "-ldflags", "-buildid= -w -s -X 'github.com/gitpod-io/local-app.Version=commit-${__git_commit}'"]
- name: app-windows-amd64
type: go
srcs:
- go.mod
- go.sum
- "**/*.go"
deps:
- components/supervisor-api/go:lib
- components/gitpod-protocol/go:lib
- components/local-app-api/go:lib
env:
- CGO_ENABLED=0
- GOOS=windows
- GOARCH=amd64
config:
packaging: app
buildCommand: ["go", "build", "-trimpath", "-ldflags", "-buildid= -w -s -X 'github.com/gitpod-io/local-app.Version=commit-${__git_commit}'"]
- name: app-windows-386
type: go
srcs:
- go.mod
- go.sum
- "**/*.go"
deps:
- components/supervisor-api/go:lib
- components/gitpod-protocol/go:lib
- components/local-app-api/go:lib
env:
- CGO_ENABLED=0
- GOOS=windows
- GOARCH=386
config:
packaging: app
buildCommand: ["go", "build", "-trimpath", "-ldflags", "-buildid= -w -s -X 'github.com/gitpod-io/local-app.Version=commit-${__git_commit}'"]
- name: app-windows-arm64
type: go
srcs:
- go.mod
- go.sum
- "**/*.go"
deps:
- components/supervisor-api/go:lib
- components/gitpod-protocol/go:lib
- components/local-app-api/go:lib
env:
- CGO_ENABLED=0
- GOOS=windows
- GOARCH=arm64
config:
packaging: app
buildCommand: ["go", "build", "-trimpath", "-ldflags", "-buildid= -w -s -X 'github.com/gitpod-io/local-app.Version=commit-${__git_commit}'"]
# remaining packages are added by the BUILD.js generator
- name: docker
type: docker
deps:
Expand Down
40 changes: 36 additions & 4 deletions components/local-app/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,50 @@
# local-app
# local-app

## gitpod-cli

All of the accessible commands can be listed with `gitpod --help` .

### Installing

1. Download the CLI for your platform and make it executable:

```bash
wget -O gitpod https://gitpod.io/static/bin/gitpod-cli-darwin-arm64
chmod u+x gitpod
```

2. Optionally, make it available globally. On macOS:

```bash
sudo mv gitpod /usr/local/bin/
```

### Usage

Start by logging in with `gitpod login`, which will also create a default context in the configuration file (`~/.gitpod/config.yaml`).

### Development

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.

## local-app

**Beware**: this is very much work in progress and will likely break things.

## How to install
### How to install

```
docker run --rm -it -v /tmp/dest:/out eu.gcr.io/gitpod-core-dev/build/local-app:<version>
```

## How to run
### How to run

```
./local-app
```

## How to run in Gitpod against a dev-staging environment
### How to run in Gitpod against a dev-staging environment

```
cd components/local-app
BROWSER= GITPOD_HOST=<URL-of-your-preview-env> go run main.go --mock-keyring run
Expand Down
58 changes: 58 additions & 0 deletions components/local-app/cmd/config-delete-context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) 2023 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License.AGPL.txt in the project root for license information.

package cmd

import (
"log/slog"

"github.com/gitpod-io/local-app/pkg/auth"
"github.com/gitpod-io/local-app/pkg/config"
"github.com/spf13/cobra"
)

var configDeleteCmd = &cobra.Command{
Use: "delete-context <name>",
Short: "Deletes a context",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) (err error) {
cmd.SilenceUsage = true

targetContext := args[0]
cfg := config.FromContext(cmd.Context())

var update bool
defer func() {
if err == nil && update {
slog.Debug("saving config", "filename", cfg.Filename)
err = config.SaveConfig(cfg.Filename, cfg)
}
}()

if cfg.ActiveContext == targetContext {
slog.Info("deleting active context - use `gitpod config use-context` to set a new active context")
cfg.ActiveContext = ""
update = true
}

gpctx := cfg.Contexts[targetContext]
if gpctx == nil {
return nil
}
delete(cfg.Contexts, targetContext)
update = true

err = auth.DeleteToken(gpctx.Host.String())
if err != nil {
slog.Warn("did not delete token from keyring", "err", err)
err = nil
}

return nil
},
}

func init() {
configCmd.AddCommand(configDeleteCmd)
}
49 changes: 49 additions & 0 deletions components/local-app/cmd/config-get-contexts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) 2023 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License.AGPL.txt in the project root for license information.

package cmd

import (
"github.com/gitpod-io/local-app/pkg/config"
"github.com/gitpod-io/local-app/pkg/prettyprint"
"github.com/spf13/cobra"
)

var configGetContextsCmd = &cobra.Command{
Use: "get-contexts",
Short: "Lists the available contexts",
RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true

cfg := config.FromContext(cmd.Context())

res := make([]tabularContext, 0, len(cfg.Contexts))
for name, ctx := range cfg.Contexts {
res = append(res, tabularContext{
Active: name == cfg.ActiveContext,
Name: name,
Host: ctx.Host.String(),
Organization: ctx.OrganizationID,
})
}

return WriteTabular(res, configGetContextsOpts.Format, prettyprint.WriterFormatWide)
},
}

type tabularContext struct {
Active bool
Name string
Host string
Organization string
}

var configGetContextsOpts struct {
Format formatOpts
}

func init() {
configCmd.AddCommand(configGetContextsCmd)
addFormatFlags(configGetContextsCmd, &configGetContextsOpts.Format)
}
Loading

0 comments on commit e51d974

Please sign in to comment.