github.com/torresashjian/cli@v0.10.1-0.20210916231452-89080fe7069c/commands/pluginhelper.go (about)

     1  package commands
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"go/parser"
     7  	"go/printer"
     8  	"go/token"
     9  	"os"
    10  	"os/exec"
    11  	"path/filepath"
    12  	"runtime"
    13  	"text/template"
    14  	"time"
    15  
    16  	"github.com/torresashjian/cli/common"
    17  	"github.com/torresashjian/cli/util"
    18  )
    19  
    20  const (
    21  	fileImportsGo = "imports.go"
    22  
    23  	UpdateOptRebuild = iota
    24  	UpdateOptAdd
    25  	UpdateOptRemove
    26  	UpdateOptUpdate
    27  )
    28  
    29  func UpdateCLI(pluginPkg string, updateOption int) error {
    30  
    31  	exPath, err := os.Executable()
    32  	if err != nil {
    33  		return err
    34  	}
    35  
    36  	pluginSet := make(map[string]struct{})
    37  
    38  	//add installed plugins
    39  	installedPlugins := common.GetPluginPkgs()
    40  	for _, aPluginPkg := range installedPlugins {
    41  		pluginSet[aPluginPkg] = struct{}{}
    42  		fmt.Println(aPluginPkg)
    43  	}
    44  
    45  	if updateOption == UpdateOptAdd {
    46  		// add new plugin
    47  		pluginSet[pluginPkg] = struct{}{}
    48  	} else if updateOption == UpdateOptRemove {
    49  		delete(pluginSet, pluginPkg)
    50  	}
    51  
    52  	path, ver, err := util.GetCLIInfo()
    53  
    54  	tmpDir := os.TempDir()
    55  	basePath := filepath.Join(tmpDir, "cli")
    56  	cliCmdPath := filepath.Join(basePath, "cmd", "flogo")
    57  
    58  	err = os.RemoveAll(basePath)
    59  	if err != nil {
    60  		fmt.Println("del err:", err)
    61  	}
    62  
    63  	err = util.Copy(path, basePath, false)
    64  	if err != nil {
    65  		return err
    66  	}
    67  
    68  	err = util.CreateVersionFile(cliCmdPath, ver)
    69  	if err != nil {
    70  		return err
    71  	}
    72  
    73  	err = createPluginListFile(basePath, pluginSet)
    74  	if err != nil {
    75  		return err
    76  	}
    77  
    78  	for plugin := range pluginSet {
    79  		_, err := addPlugin(cliCmdPath, plugin)
    80  		if err != nil {
    81  			fmt.Println("error:", err)
    82  		}
    83  	}
    84  
    85  	if updateOption == UpdateOptUpdate {
    86  		err = util.ExecCmd(exec.Command("go", "get", "-u", pluginPkg), cliCmdPath)
    87  		if err != nil {
    88  			return err
    89  		}
    90  	}
    91  
    92  	err = util.ExecCmd(exec.Command("go", "mod", "download"), basePath)
    93  	if err != nil {
    94  		return err
    95  	}
    96  
    97  	err = util.ExecCmd(exec.Command("go", "build"), cliCmdPath)
    98  	if err != nil {
    99  		//fmt.Fprintf(os.Stderr, "Error: %v\n", osErr)
   100  		return err
   101  	}
   102  
   103  	cliExe := "flogo"
   104  	if runtime.GOOS == "windows" || os.Getenv("GOOS") == "windows" {
   105  		cliExe = cliExe + ".exe"
   106  	}
   107  
   108  	err = util.Copy(filepath.Join(cliCmdPath, cliExe), exPath, false)
   109  	if err != nil {
   110  		//fmt.Fprintf(os.Stderr, "Error: %v\n", osErr)
   111  		return err
   112  	}
   113  
   114  	return nil
   115  }
   116  
   117  func addPlugin(cliCmdPath, pluginPkg string) (bool, error) {
   118  
   119  	err := util.ExecCmd(exec.Command("go", "get", pluginPkg), cliCmdPath)
   120  	if err != nil {
   121  		return false, err
   122  	}
   123  
   124  	added, err := addPluginImport(cliCmdPath, pluginPkg)
   125  	if err != nil {
   126  		return added, err
   127  	}
   128  
   129  	return added, nil
   130  }
   131  
   132  func addPluginImport(cliCmdPath, pkg string) (bool, error) {
   133  	importsFile := filepath.Join(cliCmdPath, fileImportsGo)
   134  
   135  	fset := token.NewFileSet()
   136  	file, _ := parser.ParseFile(fset, importsFile, nil, parser.ImportsOnly)
   137  
   138  	if file.Imports == nil {
   139  		return false, errors.New("no imports found")
   140  	}
   141  
   142  	successful := util.AddImport(fset, file, pkg)
   143  
   144  	if successful {
   145  		f, err := os.Create(importsFile)
   146  		if err != nil {
   147  			return false, err
   148  		}
   149  		defer f.Close()
   150  		if err := printer.Fprint(f, fset, file); err != nil {
   151  			return false, err
   152  		}
   153  	}
   154  
   155  	return successful, nil
   156  }
   157  
   158  func createPluginListFile(basePath string, plugins map[string]struct{}) error {
   159  
   160  	f, err := os.Create(filepath.Join(basePath, "common", "pluginlist.go"))
   161  	if err != nil {
   162  		return err
   163  	}
   164  	defer f.Close()
   165  
   166  	err = pluginListTemplate.Execute(f, struct {
   167  		Timestamp  time.Time
   168  		PluginList map[string]struct{}
   169  	}{
   170  		Timestamp:  time.Now(),
   171  		PluginList: plugins,
   172  	})
   173  
   174  	return err
   175  }
   176  
   177  var pluginListTemplate = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT.
   178  // {{ .Timestamp }}
   179  package common
   180  
   181  func init() {
   182  
   183  	{{range $k, $v := .PluginList}}
   184  	pluginPkgs = append(pluginPkgs, "{{$k}}")
   185  	{{end}}
   186  }
   187  `))