Skip to content

Commit

Permalink
Merge pull request #87 from fm-tibco/master
Browse files Browse the repository at this point in the history
Update CLI plugin support
  • Loading branch information
mellistibco committed Oct 9, 2019
2 parents 22cf3e3 + b0c2e58 commit af34582
Show file tree
Hide file tree
Showing 10 changed files with 368 additions and 292 deletions.
29 changes: 4 additions & 25 deletions cmd/flogo/gen/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@
package main

import (
"log"
"os"
"text/template"
"time"

"github.com/project-flogo/cli/util"
"os"
)

// This Go program is aimed at being called by go:generate from "cmd/flogo/main.go" to create a "currentversion.go" file
Expand All @@ -20,29 +16,12 @@ import (
// Users getting the CLI with a classic "go get" command will still have the version retrieved from the directory
// $GOPATH/src/github.com/project-flogo/cli
func main() {
currentVersion := util.GetVersion(false)

f, err := os.Create("./currentversion.go")
_, currentVersion, _ := util.GetCLIInfo()
wd, err := os.Getwd()
if err != nil {
log.Fatal(err)
return
}
defer f.Close()

packageTemplate.Execute(f, struct {
Timestamp time.Time
Version string
}{
Timestamp: time.Now(),
Version: currentVersion,
})
}

var packageTemplate = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT.
// {{ .Timestamp }}
package main

func init() {
Version = "{{ .Version }}"
util.CreateVersionFile(wd, currentVersion)
}
`))
2 changes: 1 addition & 1 deletion cmd/flogo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var Version string = ""
//go:generate go run gen/version.go
func main() {
//Initialize the commands
os.Setenv("GO111MODULE", "on")
_ = os.Setenv("GO111MODULE", "on")
commands.Initialize(Version)
commands.Execute()
}
242 changes: 15 additions & 227 deletions commands/plugin.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,10 @@
package commands

import (
"errors"
"fmt"
"go/parser"
"go/printer"
"go/token"
"os"
"os/exec"
"path/filepath"
"runtime"

"github.com/project-flogo/cli/common"
"github.com/project-flogo/cli/util"
"github.com/spf13/cobra"
)

const (
fileImportsGo = "imports.go"
add = false
remove = true
"os"
)

func init() {
Expand All @@ -30,12 +15,6 @@ func init() {
rootCmd.AddCommand(pluginCmd)
}

var (
goPath = os.Getenv("GOPATH")
cliPath = filepath.Join(goPath, filepath.Join("src", "github.com", "project-flogo", "cli"))
cliCmdPath = filepath.Join(cliPath, "cmd", "flogo")
)

var pluginCmd = &cobra.Command{
Use: "plugin",
Short: "manage CLI plugins",
Expand All @@ -52,40 +31,17 @@ var pluginInstallCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {

err := useBuildGoMod()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}

defer restoreGoMod()

pluginPkg := args[0]

fmt.Printf("Installing plugin: %s\n", pluginPkg)

added, err := updatePlugin(pluginPkg, add)
err := UpdateCLI(pluginPkg, UpdateOptAdd)
if err != nil {
fmt.Fprintf(os.Stderr, "Error adding plugin: %v\n", err)
os.Exit(1)
}

if added {
err = updateCLI()

if err != nil {
fmt.Fprintf(os.Stderr, "Error updating CLI: %v\n", err)
//remove plugin import on failure

modifyPluginImports(pluginPkg, true)

os.Exit(1)
}

fmt.Printf("Installed plugin\n")
} else {
fmt.Printf("Plugin '%s' already installed\n", pluginPkg)
}
fmt.Printf("Installed plugin: %s\n", pluginPkg)
},
}

Expand All @@ -94,8 +50,9 @@ var pluginListCmd = &cobra.Command{
Short: "list installed plugins",
Long: "Lists installed CLI plugins",
Run: func(cmd *cobra.Command, args []string) {
for _, cmd := range common.GetPlugins() {
fmt.Println(cmd.Name())

for _, pluginPkg := range common.GetPluginPkgs() {
fmt.Println(pluginPkg)
}
},
}
Expand All @@ -106,24 +63,18 @@ var pluginRemoveCmd = &cobra.Command{
Long: "Remove installed CLI plugins",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {

pluginPkg := args[0]
removed, err := updatePlugin(pluginPkg, remove)

fmt.Printf("Removing plugin: %s\n", pluginPkg)

err := UpdateCLI(pluginPkg, UpdateOptRemove)
if err != nil {
fmt.Fprintf(os.Stderr, "Error adding plugin: %v\n", err)
os.Exit(1)
}

if removed {
err = updateCLI()
if err != nil {
fmt.Fprintf(os.Stderr, "Error updating CLI: %v\n", err)
//remove plugin import on failure
os.Exit(1)
}
fmt.Printf("Removed plugin %v \n", pluginPkg)
}

fmt.Printf("Removed plugin: %s\n", pluginPkg)
},
}

Expand All @@ -134,179 +85,16 @@ var pluginUpdateCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {

err := useBuildGoMod()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}

defer restoreGoMod()
pluginPkg := args[0]

plugin := args[0]
fmt.Printf("Updating plugin: %s\n", plugin)
fmt.Printf("Updating plugin: %s\n", pluginPkg)

err = util.ExecCmd(exec.Command("go", "get", "-u", plugin), cliCmdPath)
err := UpdateCLI(pluginPkg, UpdateOptUpdate)
if err != nil {
fmt.Fprintf(os.Stderr, "Error updating plugin: %v\n", err)
os.Exit(1)
}

err = updateCLI()
if err != nil {
fmt.Fprintf(os.Stderr, "Error updating CLI: %v\n", err)
os.Exit(1)
}
fmt.Printf("Updated plugin\n")
fmt.Printf("Updated plugin: %s\n", pluginPkg)
},
}

func useBuildGoMod() error {

baseGoMod := filepath.Join(cliPath, "go.mod")
bakGoMod := filepath.Join(cliPath, "go.mod.bak")
buildGoMod := filepath.Join(cliPath, "go.mod.build")

if _, err := os.Stat(buildGoMod); err != nil {

if verbose {
fmt.Printf("Creating plugin build go.mod")
}

err := util.CopyFile(baseGoMod, buildGoMod)
if err != nil {
return err
}
}

if verbose {
fmt.Printf("Switching to plugin build go.mod")
}

err := os.Rename(baseGoMod, bakGoMod)
if err != nil {
return err
}

err = os.Rename(buildGoMod, baseGoMod)
if err != nil {
return err
}

return nil
}

func restoreGoMod() {

if verbose {
fmt.Printf("Restoring default CLI go.mod")
}
baseGoMod := filepath.Join(cliPath, "go.mod")
bakGoMod := filepath.Join(cliPath, "go.mod.bak")
buildGoMod := filepath.Join(cliPath, "go.mod.build")

err := os.Rename(baseGoMod, buildGoMod)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
}
err = os.Rename(bakGoMod, baseGoMod)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
}
}

func updatePlugin(pluginPkg string, opt bool) (bool, error) {

err := util.ExecCmd(exec.Command("go", "get", pluginPkg), cliCmdPath)
if err != nil {
return false, err
}

added, err := modifyPluginImports(pluginPkg, opt)
if err != nil {
return added, err
}

if added {
//Download all the modules. This is just to ensure all packages are downloaded before go build.
err := util.ExecCmd(exec.Command("go", "mod", "download"), cliCmdPath)
if err != nil {
modifyPluginImports(pluginPkg, true)
return false, err
}
}

return added, nil
}

func updateCLI() error {

exe, err := os.Executable()
if err != nil {
return err
}

backupExe := exe + ".bak"
if _, err := os.Stat(exe); err == nil {
err = os.Rename(exe, backupExe)
if err != nil {
return err
}
}

err = util.ExecCmd(exec.Command("go", "build"), cliCmdPath)
if err != nil {
osErr := os.Rename(backupExe, exe)
fmt.Fprintf(os.Stderr, "Error: %v\n", osErr)
return err
}
cliExe := "flogo"
if runtime.GOOS == "windows" || os.Getenv("GOOS") == "windows" {
cliExe = cliExe + ".exe"
}

err = os.Rename(filepath.Join(cliCmdPath, cliExe), exe)
if err != nil {
return err
}

err = os.Remove(backupExe)
if err != nil {
return err
}

return nil
}

func modifyPluginImports(pkg string, remove bool) (bool, error) {

importsFile := filepath.Join(cliCmdPath, fileImportsGo)

fset := token.NewFileSet()
file, _ := parser.ParseFile(fset, importsFile, nil, parser.ImportsOnly)

if file.Imports == nil {
return false, errors.New("No Imports found.")
}

successful := false

if remove {

successful = util.DeleteImport(fset, file, pkg)
} else {
successful = util.AddImport(fset, file, pkg)
}

if successful {
f, err := os.Create(importsFile)
if err != nil {
return false, err
}
defer f.Close()
if err := printer.Fprint(f, fset, file); err != nil {
return false, err
}
}

return successful, nil
}

0 comments on commit af34582

Please sign in to comment.