Skip to content

Commit

Permalink
[jb] enable vmoptions config in .gitpod.yml
Browse files Browse the repository at this point in the history
  • Loading branch information
yaohui-wyh committed Jun 23, 2022
1 parent a705517 commit bd8f35a
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 13 deletions.
16 changes: 16 additions & 0 deletions components/gitpod-protocol/data/gitpod-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,10 @@
"description": "Whether only stable, latest or both versions should be warmed up. Default is stable only."
}
}
},
"vmoptions": {
"type": "string",
"description": "Configure JVM options, for instance '-Xmx=4096m'."
}
}
},
Expand Down Expand Up @@ -317,6 +321,10 @@
"description": "Whether only stable, latest or both versions should be warmed up. Default is stable only."
}
}
},
"vmoptions": {
"type": "string",
"description": "Configure JVM options, for instance '-Xmx=4096m'."
}
}
},
Expand Down Expand Up @@ -347,6 +355,10 @@
"description": "Whether only stable, latest or both versions should be warmed up. Default is stable only."
}
}
},
"vmoptions": {
"type": "string",
"description": "Configure JVM options, for instance '-Xmx=4096m'."
}
}
},
Expand Down Expand Up @@ -377,6 +389,10 @@
"description": "Whether only stable, latest or both versions should be warmed up. Default is stable only."
}
}
},
"vmoptions": {
"type": "string",
"description": "Configure JVM options, for instance '-Xmx=4096m'."
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions components/gitpod-protocol/go/gitpod-config-types.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions components/gitpod-protocol/src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,7 @@ export interface JetBrainsConfig {
}
export interface JetBrainsProductConfig {
prebuilds?: JetBrainsPrebuilds;
vmoptions?: string;
}
export interface JetBrainsPrebuilds {
version?: "stable" | "latest" | "both";
Expand Down
1 change: 1 addition & 0 deletions components/ide/jetbrains/image/status/BUILD.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ packages:
- name: app
type: go
srcs:
- "testdata/**"
- "**/*.go"
- "go.mod"
- "go.sum"
Expand Down
4 changes: 4 additions & 0 deletions components/ide/jetbrains/image/status/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ go 1.18
require (
github.com/gitpod-io/gitpod/supervisor/api v0.0.0-00010101000000-000000000000
github.com/google/go-cmp v0.5.7
github.com/stretchr/testify v1.7.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/sourcegraph/jsonrpc2 v0.0.0-20200429184054-15c2290dcb37 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)

require (
Expand Down
1 change: 1 addition & 0 deletions components/ide/jetbrains/image/status/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
42 changes: 31 additions & 11 deletions components/ide/jetbrains/image/status/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,14 @@ func main() {
}
log.WithField("cost", time.Now().Local().Sub(startTime).Milliseconds()).Info("content available")

repoRoot := wsInfo.GetCheckoutLocation()
gitpodConfig, err := parseGitpodConfig(repoRoot)
if err != nil {
log.WithError(err).Error("failed to parse .gitpod.yml")
}
version_2022_1, _ := version.NewVersion("2022.1")
if version_2022_1.LessThanOrEqual(backendVersion) {
err = installPlugins(wsInfo, alias)
err = installPlugins(repoRoot, gitpodConfig, alias)
installPluginsCost := time.Now().Local().Sub(startTime).Milliseconds()
if err != nil {
log.WithError(err).WithField("cost", installPluginsCost).Error("installing repo plugins: done")
Expand All @@ -87,7 +92,7 @@ func main() {
}
}

err = configureVMOptions(alias)
err = configureVMOptions(gitpodConfig, alias)
if err != nil {
log.WithError(err).Error("failed to configure vmoptions")
}
Expand Down Expand Up @@ -307,7 +312,7 @@ func handleSignal(projectPath string) {
log.Info("asked IDE to terminate")
}

func configureVMOptions(alias string) error {
func configureVMOptions(config *gitpod.GitpodConfig, alias string) error {
idePrefix := alias
if alias == "intellij" {
idePrefix = "idea"
Expand All @@ -318,7 +323,7 @@ func configureVMOptions(alias string) error {
if err != nil {
return err
}
newContent := updateVMOptions(alias, string(content))
newContent := updateVMOptions(config, alias, string(content))
return ioutil.WriteFile(path, []byte(newContent), 0)
}

Expand All @@ -340,7 +345,7 @@ func deduplicateVMOption(oldLines []string, newLines []string, predicate func(l,
return result
}

func updateVMOptions(alias string, content string) string {
func updateVMOptions(config *gitpod.GitpodConfig, alias string, content string) string {
// inspired by how intellij platform merge the VMOptions
// https://github.com/JetBrains/intellij-community/blob/master/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java#L1115
filterFunc := func(l, r string) bool {
Expand All @@ -358,12 +363,24 @@ func updateVMOptions(alias string, content string) string {
gitpodVMOptions := []string{"-Dgtw.disable.exit.dialog=true"}
vmoptions := deduplicateVMOption(ideaVMOptionsLines, gitpodVMOptions, filterFunc)

// user-defined vmoptions
// user-defined vmoptions (EnvVar)
userVMOptionsVar := os.Getenv(strings.ToUpper(alias) + "_VMOPTIONS")
userVMOptions := strings.Fields(userVMOptionsVar)
if len(userVMOptions) > 0 {
vmoptions = deduplicateVMOption(vmoptions, userVMOptions, filterFunc)
}

// project-defined vmoptions (.gitpod.yml)
if config != nil {
productConfig := getProductConfig(config, alias)
if productConfig != nil {
projectVMOptions := strings.Fields(productConfig.VMOptions)
if len(projectVMOptions) > 0 {
vmoptions = deduplicateVMOption(vmoptions, projectVMOptions, filterFunc)
}
}
}

// vmoptions file should end with a newline
return strings.Join(vmoptions, "\n") + "\n"
}
Expand Down Expand Up @@ -410,8 +427,8 @@ func resolveBackendVersion() (*version.Version, error) {
return version.NewVersion(info.Version)
}

func installPlugins(wsInfo *supervisor.WorkspaceInfoResponse, alias string) error {
plugins, err := getPlugins(wsInfo.GetCheckoutLocation(), alias)
func installPlugins(repoRoot string, config *gitpod.GitpodConfig, alias string) error {
plugins, err := getPlugins(config, alias)
if err != nil {
return err
}
Expand All @@ -433,7 +450,7 @@ func installPlugins(wsInfo *supervisor.WorkspaceInfoResponse, alias string) erro

var args []string
args = append(args, "installPlugins")
args = append(args, wsInfo.GetCheckoutLocation())
args = append(args, repoRoot)
args = append(args, plugins...)
cmd := remoteDevServerCmd(args)
cmd.Stdout = io.MultiWriter(w, os.Stdout)
Expand All @@ -458,7 +475,7 @@ func installPlugins(wsInfo *supervisor.WorkspaceInfoResponse, alias string) erro
return nil
}

func getPlugins(repoRoot string, alias string) ([]string, error) {
func parseGitpodConfig(repoRoot string) (*gitpod.GitpodConfig, error) {
if repoRoot == "" {
return nil, errors.New("repoRoot is empty")
}
Expand All @@ -474,11 +491,14 @@ func getPlugins(repoRoot string, alias string) ([]string, error) {
if err = yaml.Unmarshal(data, &config); err != nil {
return nil, errors.New("unmarshal .gitpod.yml file failed" + err.Error())
}
return config, nil
}

func getPlugins(config *gitpod.GitpodConfig, alias string) ([]string, error) {
var plugins []string
if config == nil || config.JetBrains == nil {
return nil, nil
}
var plugins []string
if config.JetBrains.Plugins != nil {
plugins = append(plugins, config.JetBrains.Plugins...)
}
Expand Down
13 changes: 11 additions & 2 deletions components/ide/jetbrains/image/status/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
protocol "github.com/gitpod-io/gitpod/gitpod-protocol"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/stretchr/testify/assert"
)

func TestGetProductConfig(t *testing.T) {
Expand All @@ -26,6 +27,14 @@ func TestGetProductConfig(t *testing.T) {
}
}

func TestParseGitpodConfig(t *testing.T) {
gitpodConfig, _ := parseGitpodConfig("testdata")
assert.Equal(t, 1, len(gitpodConfig.JetBrains.IntelliJ.Plugins))
assert.Equal(t, "both", gitpodConfig.JetBrains.IntelliJ.Prebuilds.Version)
assert.Equal(t, "-Xmx3g", gitpodConfig.JetBrains.IntelliJ.VMOptions)
assert.Equal(t, "-Xmx4096m -XX:MaxRAMPercentage=75", gitpodConfig.JetBrains.GoLand.VMOptions)
}

func TestUpdateVMOptions(t *testing.T) {
tests := []struct {
Desc string
Expand All @@ -49,7 +58,7 @@ func TestUpdateVMOptions(t *testing.T) {
lessFunc := func(a, b string) bool { return a < b }

t.Run(test.Desc, func(t *testing.T) {
actual := updateVMOptions(test.Alias, test.Src)
actual := updateVMOptions(nil, test.Alias, test.Src)
if diff := cmp.Diff(strings.Fields(test.Expectation), strings.Fields(actual), cmpopts.SortSlices(lessFunc)); diff != "" {
t.Errorf("unexpected output (-want +got):\n%s", diff)
}
Expand All @@ -58,7 +67,7 @@ func TestUpdateVMOptions(t *testing.T) {
t.Run("updateVMOptions multiple time should be stable", func(t *testing.T) {
actual := test.Src
for i := 0; i < 5; i++ {
actual = updateVMOptions(test.Alias, actual)
actual = updateVMOptions(nil, test.Alias, actual)
if diff := cmp.Diff(strings.Fields(test.Expectation), strings.Fields(actual), cmpopts.SortSlices(lessFunc)); diff != "" {
t.Errorf("unexpected output (-want +got):\n%s", diff)
}
Expand Down
31 changes: 31 additions & 0 deletions components/ide/jetbrains/image/status/testdata/.gitpod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright (c) 2022 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.

# see https://github.com/gitpod-io/spring-petclinic/blob/master/.gitpod.yml
tasks:
- init: ./mvnw package -DskipTests
command: java -jar target/*.jar
name: Run PetClinic app

# exposed ports
ports:
- port: 8080
onOpen: open-preview

vscode:
extensions:
- redhat.java
- vscjava.vscode-java-debug
- vscjava.vscode-java-test
- pivotal.vscode-spring-boot

jetbrains:
intellij:
plugins:
- com.haulmont.jpab
prebuilds:
version: both
vmoptions: "-Xmx3g"
goland:
vmoptions: "-Xmx4096m -XX:MaxRAMPercentage=75"

0 comments on commit bd8f35a

Please sign in to comment.