Skip to content

Commit

Permalink
fix EXP-626: initial image plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
akosyakov committed Sep 18, 2023
1 parent c700636 commit 7ba9460
Showing 1 changed file with 128 additions and 24 deletions.
152 changes: 128 additions & 24 deletions components/ide/jetbrains/launcher/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
package main

import (
"archive/zip"
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
Expand Down Expand Up @@ -67,6 +69,7 @@ type LaunchContext struct {
configDir string
systemDir string
projectConfigDir string
projectSystemDir string
projectContextDir string
riderSolutionFile string

Expand Down Expand Up @@ -418,14 +421,19 @@ func launch(launchCtx *LaunchContext) {
launchCtx.riderSolutionFile = riderSolutionFile
launchCtx.projectContextDir = resolveProjectContextDir(launchCtx)
launchCtx.projectConfigDir = fmt.Sprintf("%s/RemoteDev-%s/%s", launchCtx.configDir, launchCtx.info.ProductCode, strings.ReplaceAll(launchCtx.projectContextDir, "/", "_"))
launchCtx.projectSystemDir = fmt.Sprintf("%s/RemoteDev-%s/%s", launchCtx.systemDir, launchCtx.info.ProductCode, strings.ReplaceAll(launchCtx.projectContextDir, "/", "_"))
launchCtx.env = resolveLaunchContextEnv(launchCtx.configDir, launchCtx.systemDir)

// sync initial options
err = syncOptions(launchCtx)
err = syncInitialContent(launchCtx, Options)
if err != nil {
log.WithError(err).Error("failed to sync initial options")
}

err = syncInitialContent(launchCtx, Plugins)
if err != nil {
log.WithError(err).Error("failed to sync initial plugins")
}

// install project plugins
version_2022_1, _ := version.NewVersion("2022.1")
if version_2022_1.LessThanOrEqual(launchCtx.backendVersion) {
Expand Down Expand Up @@ -710,53 +718,149 @@ func resolveProductInfo(backendDir string) (*ProductInfo, error) {
return &info, err
}

func syncOptions(launchCtx *LaunchContext) error {
userHomeDir, err := os.UserHomeDir()
type SyncTarget string

const (
Options SyncTarget = "options"
Plugins SyncTarget = "plugins"
)

func syncInitialContent(launchCtx *LaunchContext, target SyncTarget) error {
destDir, err := ensureSyncDest(launchCtx, target)
if !os.IsNotExist(err) {
// already synced skipping, i.e. restart of jb backend
return nil
}
if err != nil {
return err
}

srcDirs, err := collectSyncSources(launchCtx, target)
if err != nil {
return err
}
if len(srcDirs) == 0 {
// nothing to sync
return nil
}

for _, srcDir := range srcDirs {
if target == Plugins {
files, err := ioutil.ReadDir(srcDir)
if err != nil {
return err
}

for _, file := range files {
if file.IsDir() {
cp := exec.Command("cp", "-rf", filepath.Join(srcDir, file.Name()), destDir)
err = cp.Run()
if err != nil {
return err
}
} else if filepath.Ext(file.Name()) == ".zip" {
folderName := strings.TrimSuffix(file.Name(), ".zip")
targetFolder := filepath.Join(destDir, folderName)
err = unzipArchive(filepath.Join(srcDir, file.Name()), targetFolder)
if err != nil {
return err
}
}
}
} else {
cp := exec.Command("cp", "-rf", srcDir+"/.", destDir)
err = cp.Run()
if err != nil {
return err
}
}
}
return nil
}

func ensureSyncDest(launchCtx *LaunchContext, target SyncTarget) (string, error) {
projectDestDir := launchCtx.projectConfigDir
if target == Plugins {
projectDestDir = launchCtx.projectSystemDir
}
destDir := fmt.Sprintf("%s/%s", projectDestDir, target)
_, err := os.Stat(destDir)
if err != nil {
return "", err
}
err = os.MkdirAll(destDir, os.ModePerm)
if err != nil {
return "", err
}
return destDir, nil
}

func collectSyncSources(launchCtx *LaunchContext, target SyncTarget) ([]string, error) {
userHomeDir, err := os.UserHomeDir()
if err != nil {
return nil, err
}
var srcDirs []string
for _, srcDir := range []string{
fmt.Sprintf("%s/.gitpod/jetbrains/options", userHomeDir),
fmt.Sprintf("%s/.gitpod/jetbrains/%s/options", userHomeDir, launchCtx.alias),
fmt.Sprintf("%s/.gitpod/jetbrains/options", launchCtx.projectDir),
fmt.Sprintf("%s/.gitpod/jetbrains/%s/options", launchCtx.projectDir, launchCtx.alias),
fmt.Sprintf("%s/.gitpod/jetbrains/%s", userHomeDir, target),
fmt.Sprintf("%s/.gitpod/jetbrains/%s/%s", userHomeDir, launchCtx.alias, target),
fmt.Sprintf("%s/.gitpod/jetbrains/%s", launchCtx.projectDir, target),
fmt.Sprintf("%s/.gitpod/jetbrains/%s/%s", launchCtx.projectDir, launchCtx.alias, target),
} {
srcStat, err := os.Stat(srcDir)
if os.IsNotExist(err) {
// nothing to sync
continue
}
if err != nil {
return err
return nil, err
}
if !srcStat.IsDir() {
return fmt.Errorf("%s is not a directory", srcDir)
return nil, fmt.Errorf("%s is not a directory", srcDir)
}
srcDirs = append(srcDirs, srcDir)
}
if len(srcDirs) == 0 {
// nothing to sync
return nil
}
return srcDirs, nil
}

destDir := fmt.Sprintf("%s/options", launchCtx.projectConfigDir)
_, err = os.Stat(destDir)
if !os.IsNotExist(err) {
// already synced skipping, i.e. restart of jb backend
return nil
}
err = os.MkdirAll(destDir, os.ModePerm)
func unzipArchive(src, dest string) error {
r, err := zip.OpenReader(src)
if err != nil {
return err
}
defer r.Close()

for _, srcDir := range srcDirs {
cp := exec.Command("cp", "-rf", srcDir+"/.", destDir)
err = cp.Run()
for _, f := range r.File {
rc, err := f.Open()
if err != nil {
return err
}
defer rc.Close()

fpath := filepath.Join(dest, f.Name)
if f.FileInfo().IsDir() {
err := os.MkdirAll(fpath, os.ModePerm)
if err != nil {
return err
}
} else {
fdir := filepath.Dir(fpath)
err := os.MkdirAll(fdir, os.ModePerm)
if err != nil {
return err
}

outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return err
}
defer outFile.Close()

_, err = io.Copy(outFile, rc)
if err != nil {
return err
}
}
}
return nil
}
Expand Down

0 comments on commit 7ba9460

Please sign in to comment.