Skip to content

Commit

Permalink
feat: add cli plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
FabianKramm committed Jul 29, 2020
1 parent 5578600 commit ea38ac1
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -4,6 +4,7 @@
# Created by devspace init
/.devspace/
/chart/
/test

# Build files
*.exe
Expand Down
1 change: 1 addition & 0 deletions cmd/flags/flags.go
Expand Up @@ -50,6 +50,7 @@ func (gf *GlobalFlags) ToConfigOptions() *loader.ConfigOptions {
Profile: gf.Profile,
ConfigPath: gf.ConfigPath,
KubeContext: gf.KubeContext,
Namespace: gf.Namespace,
Vars: gf.Vars,
}
}
Expand Down
2 changes: 2 additions & 0 deletions cmd/root.go
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/devspace-cloud/devspace/cmd/status"
"github.com/devspace-cloud/devspace/cmd/update"
"github.com/devspace-cloud/devspace/cmd/use"
"github.com/devspace-cloud/devspace/pkg/devspace/config/loader"
"github.com/devspace-cloud/devspace/pkg/devspace/plugin"
"github.com/devspace-cloud/devspace/pkg/devspace/upgrade"
"github.com/devspace-cloud/devspace/pkg/util/analytics/cloudanalytics"
Expand Down Expand Up @@ -149,5 +150,6 @@ func BuildRoot(f factory.Factory) *cobra.Command {

// Add plugin commands
plugin.AddPluginCommands(rootCmd, plugins, "")
loader.AddPredefinedVars(plugins)
return rootCmd
}
1 change: 1 addition & 0 deletions pkg/devspace/config/loader/get.go
Expand Up @@ -123,6 +123,7 @@ func (l *configLoader) New() *latest.Config {
type ConfigOptions struct {
Profile string
KubeContext string
Namespace string
ConfigPath string

GeneratedConfig *generated.Config
Expand Down
24 changes: 24 additions & 0 deletions pkg/devspace/config/loader/predefined_vars.go
@@ -1,7 +1,10 @@
package loader

import (
"bytes"
"fmt"
"github.com/devspace-cloud/devspace/pkg/devspace/plugin"
"github.com/pkg/errors"
"path/filepath"
"strconv"
"strings"
Expand Down Expand Up @@ -162,6 +165,27 @@ var predefinedVars = map[string]func(loader *configLoader) (string, error){
},
}

func AddPredefinedVars(plugins []plugin.Metadata) {
for _, p := range plugins {
pluginFolder := p.PluginFolder
for _, variable := range p.Vars {
v := variable
predefinedVars[variable.Name] = func(configLoader *configLoader) (string, error) {
buffer := &bytes.Buffer{}
err := plugin.CallPluginExecutable(filepath.Join(pluginFolder, plugin.PluginBinary), v.BaseArgs, map[string]string{
"DEVSPACE_PLUGIN_KUBE_CONTEXT_FLAG": configLoader.options.KubeContext,
"DEVSPACE_PLUGIN_KUBE_NAMESPACE_FLAG": configLoader.options.Namespace,
}, buffer)
if err != nil {
return "", errors.Wrapf(err, "executing plugin: %s", buffer.String())
}

return strings.TrimSpace(buffer.String()), nil
}
}
}
}

func (l *configLoader) resolvePredefinedVar(name string) (bool, string, error) {
name = strings.ToUpper(name)
if getVar, ok := predefinedVars[name]; ok {
Expand Down
4 changes: 2 additions & 2 deletions pkg/devspace/deploy/deployer/kubectl/kubectl.go
Expand Up @@ -330,10 +330,10 @@ func (d *DeployConfig) buildManifests(manifest string) ([]*unstructured.Unstruct
}

func (d *DeployConfig) isKustomizeInstalled(path string) bool {
out, err := d.commandExecuter.RunCommand(path, []string{"version"})
_, err := d.commandExecuter.RunCommand(path, []string{"version"})
if err != nil {
return false
}

return strings.Index(string(out), `kustomize`) != -1
return true
}
20 changes: 12 additions & 8 deletions pkg/devspace/plugin/plugin.go
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/mitchellh/go-homedir"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"io"
"io/ioutil"
"os"
"os/exec"
Expand All @@ -22,11 +23,11 @@ var encoding = base32.StdEncoding.WithPadding('0')

const pluginYaml = "plugin.yaml"

var pluginBinary = "binary"
var PluginBinary = "binary"

func init() {
if runtime.GOOS == "windows" {
pluginBinary += ".exe"
PluginBinary += ".exe"
}
}

Expand Down Expand Up @@ -96,6 +97,7 @@ func (c *client) install(path, version string) error {
return err
}

pluginFolder = filepath.Join(pluginFolder, Encode(path))
err = os.MkdirAll(pluginFolder, 0755)
if err != nil {
return err
Expand All @@ -106,13 +108,12 @@ func (c *client) install(path, version string) error {
return err
}

pluginFolder = filepath.Join(pluginFolder, Encode(path))
err = ioutil.WriteFile(filepath.Join(pluginFolder, pluginYaml), out, 0666)
if err != nil {
return err
}

outBinaryPath := filepath.Join(pluginFolder, pluginBinary)
outBinaryPath := filepath.Join(pluginFolder, PluginBinary)
err = c.installer.DownloadBinary(path, version, binaryPath, outBinaryPath)
if err != nil {
return errors.Wrap(err, "download plugin binary")
Expand Down Expand Up @@ -292,7 +293,6 @@ func Decode(encoded string) ([]byte, error) {
func AddPluginCommands(base *cobra.Command, plugins []Metadata, subCommand string) {
for _, plugin := range plugins {
pluginFolder := plugin.PluginFolder

for _, pluginCommand := range plugin.Commands {
if pluginCommand.SubCommand == subCommand {
md := pluginCommand
Expand All @@ -308,7 +308,7 @@ func AddPluginCommands(base *cobra.Command, plugins []Metadata, subCommand strin
newArgs := []string{}
newArgs = append(newArgs, md.BaseArgs...)
newArgs = append(newArgs, args...)
return callPluginExecutable(filepath.Join(pluginFolder, pluginBinary), newArgs)
return CallPluginExecutable(filepath.Join(pluginFolder, PluginBinary), newArgs, nil, os.Stdout)
},
// This passes all the flags to the subcommand.
DisableFlagParsing: true,
Expand All @@ -322,12 +322,16 @@ func AddPluginCommands(base *cobra.Command, plugins []Metadata, subCommand strin

// This function is used to setup the environment for the plugin and then
// call the executable specified by the parameter 'main'
func callPluginExecutable(main string, argv []string) error {
func CallPluginExecutable(main string, argv []string, extraEnvVars map[string]string, out io.Writer) error {
env := os.Environ()
for k, v := range extraEnvVars {
env = append(env, k + "=" + v)
}

prog := exec.Command(main, argv...)
prog.Env = env
prog.Stdin = os.Stdin
prog.Stdout = os.Stdout
prog.Stdout = out
prog.Stderr = os.Stderr
if err := prog.Run(); err != nil {
if eerr, ok := err.(*exec.ExitError); ok {
Expand Down
2 changes: 0 additions & 2 deletions pkg/util/factory/factory.go
Expand Up @@ -20,11 +20,9 @@ import (
"github.com/devspace-cloud/devspace/pkg/devspace/plugin"
"github.com/devspace-cloud/devspace/pkg/devspace/registry"
"github.com/devspace-cloud/devspace/pkg/devspace/services"
"github.com/devspace-cloud/devspace/pkg/devspace/services"
"github.com/devspace-cloud/devspace/pkg/devspace/services/targetselector"
"github.com/devspace-cloud/devspace/pkg/util/kubeconfig"
"github.com/devspace-cloud/devspace/pkg/util/log"
"github.com/docker/docker/pkg/plugins"
)

// Factory is the main interface for various client creations
Expand Down
15 changes: 15 additions & 0 deletions test/plugin.yaml
@@ -0,0 +1,15 @@
name: test
version: 0.0.3
commands:
- name: "test"
baseArgs: ["test"]
- name: "subtest"
baseArgs: ["sutest"]
subCommand: "add"
vars:
- name: DEVSPACE_TEST
baseArgs: ["var"]
binaries:
- os: darwin
arch: amd64
path: main
59 changes: 58 additions & 1 deletion test/test.go
Expand Up @@ -2,9 +2,66 @@ package main

import (
"fmt"
"github.com/spf13/cobra"
"os"
)

func main() {
fmt.Println(os.RemoveAll("saagdafshkjakfjhasdhkjahksdhkjdashkjadskhjdhkjaskjhasdjk"))
rootCmd := &cobra.Command{
Use: "sdfssfd",
Short: "Welcome to the DevSpace!",
Long: `Example bois`,
}

testCmd := &cobra.Command{
Use: "test",
Short: "Welcome to the DevSpace!",
Long: `Example bois`,
}

testCmd.AddCommand(&cobra.Command{
Use: "abc",
Short: "Welcome to the DevSpace!",
Long: `Example bois`,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Printf("abc v2 %v", args)
return nil
},
})
testCmd.AddCommand(&cobra.Command{
Use: "def",
Short: "Welcome to the DevSpace!",
Long: `Example bois`,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Printf("def %v", args)
return nil
},
})

rootCmd.AddCommand(testCmd)
rootCmd.AddCommand(&cobra.Command{
Use: "sutest",
Short: "Welcome to the DevSpace!",
Long: `Example bois`,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Printf("sutest %v", args)
return nil
},
})
rootCmd.AddCommand(&cobra.Command{
Use: "var",
Short: "Welcome to the DevSpace!",
Long: `Example bois`,
RunE: func(cmd *cobra.Command, args []string) error {
for _, v := range os.Environ() {
fmt.Println(v)
}
return nil
},
})

err := rootCmd.Execute()
if err != nil {
fmt.Println(err)
}
}

0 comments on commit ea38ac1

Please sign in to comment.