Skip to content
This repository has been archived by the owner on Jul 12, 2022. It is now read-only.

Feature/any languages #48

Merged
merged 13 commits into from
Apr 28, 2020
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/fatih/color v1.9.0 // indirect
github.com/gofrs/flock v0.7.1
github.com/google/uuid v1.1.1
github.com/gosuri/uitable v0.0.4
github.com/manifoldco/promptui v0.7.0
github.com/mattn/go-runewidth v0.0.9 // indirect
Expand Down
1 change: 1 addition & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ type Command struct {
type Formula struct {
Path string `json:"path"`
Bin string `json:"bin"`
Bundle string `json:"bundle"`
Config string `json:"config"`
RepoURL string `json:"repoUrl"`
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/cmd/formulas.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
const (
fPath = "fPath"
fBin = "fBin"
fBundle = "fBundle"
fConfig = "fConfig"
fRepoURL = "fRepoURL"
subcmd = " SUBCOMMAND"
Expand Down Expand Up @@ -65,6 +66,7 @@ func (f FormulaCommand) newFormulaCmd(cmd api.Command) *cobra.Command {
annotations := make(map[string]string)
annotations[fPath] = frm.Path
annotations[fBin] = frm.Bin
annotations[fBundle] = frm.Bundle
annotations[fConfig] = frm.Config
annotations[fRepoURL] = frm.RepoURL

Expand All @@ -81,11 +83,13 @@ func execFormulaFunc(formulaRunner formula.Runner) func(cmd *cobra.Command, args
return func(cmd *cobra.Command, args []string) error {
fPath := cmd.Annotations[fPath]
fBin := cmd.Annotations[fBin]
fBundle := cmd.Annotations[fBundle]
fConf := cmd.Annotations[fConfig]
fRepoURL := cmd.Annotations[fRepoURL]
frm := formula.Definition{
Path: fPath,
Bin: fBin,
Bundle: fBundle,
Config: fConf,
RepoUrl: fRepoURL,
}
Expand Down
48 changes: 48 additions & 0 deletions pkg/file/fileutil/file_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,51 @@ func Unzip(src string, dest string) error {
func IsNotExistErr(err error) bool {
return os.IsNotExist(errors.Cause(err))
}

// Read all files and dir in current directory
func readFilesDir(path string) ([]os.FileInfo, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
fl, err := f.Readdir(-1)
f.Close()
return fl, err
}

//Move files from oPath to nPath
func MoveFiles(oPath, nPath string, files []string) error {
for _, f := range files {
pwdOF := fmt.Sprintf("%s/%s", oPath, f)
pwdNF := fmt.Sprintf("%s/%s", nPath, f)
if err := os.Rename(pwdOF, pwdNF); err != nil {
return err
}
}
return nil
}

// List new files in nPath differing of oPath
func ListNewFiles(oPath, nPath string) ([]string, error) {
of, err := readFilesDir(oPath)
if err != nil {
return nil, err
}
nf, err := readFilesDir(nPath)
if err != nil {
return nil, err
}
control := make(map[string]int)
for _, file := range of {
control[file.Name()]++
}
var new []string
for _, file := range nf {
if control[file.Name()] == 0 {
new = append(new, file.Name())
}
}
return new, nil
}


3 changes: 2 additions & 1 deletion pkg/formula/creator.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (c CreateManager) Create(fCmd string) error {
return err
}
log.Println("Formula successfully created!")
log.Printf("Your formula is in %s.", c.formPath)
log.Printf("Your formula is in %s", c.formPath)
return nil
}

Expand Down Expand Up @@ -274,6 +274,7 @@ func updateTree(fCmd string, t Tree, i int) Tree {
Formula: api.Formula{
Path: pathValue,
Bin: fn + "-${so}",
Bundle: "${so}.zip",
Config: "config.json",
},
Parent: parent,
Expand Down
28 changes: 25 additions & 3 deletions pkg/formula/formula.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (

const (
PathPattern = "%s/formulas/%s"
TmpDirPattern = "%s/tmp/%s"
TmpBinDirPattern = "%s/tmp/%s/%s"
DefaultConfig = "config.json"
ConfigPattern = "%s/%s"
CommandEnv = "COMMAND"
Expand Down Expand Up @@ -52,6 +54,7 @@ type Cache struct {
type Definition struct {
Path string
Bin string
Bundle string
Config string
RepoUrl string
}
Expand All @@ -61,6 +64,14 @@ func (d *Definition) FormulaPath(home string) string {
return fmt.Sprintf(PathPattern, home, d.Path)
}

// TmpWorkDirPath builds the tmp paths to run formula, first parameter is tmpDir created
// second parameter is tmpBinDir
func (d *Definition) TmpWorkDirPath(home, uuidHash string) (string, string) {
tmpDir := fmt.Sprintf(TmpDirPattern, home, uuidHash)
tmpBinDir := fmt.Sprintf(TmpBinDirPattern, home, uuidHash, d.Path)
return tmpDir, tmpBinDir
}

// BinName builds the bin name from definition params
func (d *Definition) BinName() string {
if strings.Contains(d.Bin, "${so}") {
Expand All @@ -76,6 +87,17 @@ func (d *Definition) BinName() string {
return d.Bin
}

// BinName builds the bin name from definition params
func (d *Definition) BundleName() string {
if strings.Contains(d.Bundle, "${so}") {
so := runtime.GOOS
bundleSO := strings.ReplaceAll(d.Bundle, "${so}", so)

return bundleSO
}
return d.Bundle
}

// BinPath builds the bin path from formula path
func (d *Definition) BinPath(formula string) string {
return fmt.Sprintf(BinPathPattern, formula)
Expand All @@ -87,8 +109,8 @@ func (d *Definition) BinFilePath(binPath, binName string) string {
}

// BinUrl builds the bin url
func (d *Definition) BinUrl() string {
return fmt.Sprintf("%s/bin/%s.zip", d.RepoUrl, d.BinName())
func (d *Definition) BundleUrl() string {
return fmt.Sprintf("%s/%s/%s", d.RepoUrl, d.Path, d.BundleName())
}

// ConfigName resolver de config name
Expand All @@ -106,7 +128,7 @@ func (d *Definition) ConfigPath(formula, configName string) string {

// ConfigUrl builds the config url
func (d *Definition) ConfigUrl(configName string) string {
return fmt.Sprintf("%s/%s", d.RepoUrl, configName)
return fmt.Sprintf("%s/%s/%s", d.RepoUrl, d.Path, configName)
}

type Runner interface {
Expand Down
81 changes: 60 additions & 21 deletions pkg/formula/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/google/uuid"
"io"
"io/ioutil"
"log"
Expand Down Expand Up @@ -53,47 +54,40 @@ func NewRunner(

// Run default implementation of function Manager.Run
func (d DefaultRunner) Run(def Definition) error {
cPwd, _ := os.Getwd()
fPath := def.FormulaPath(d.ritchieHome)

var config *Config
cName := def.ConfigName()
cPath := def.ConfigPath(fPath, cName)
if !fileutil.Exists(cPath) {
if err := d.downloadConfig(def.ConfigUrl(cName), fPath, cName); err != nil {
return err
}
}

configFile, err := ioutil.ReadFile(cPath)
config, err := d.loadConfig(def)
if err != nil {
return err
}

config = &Config{}
if err := json.Unmarshal(configFile, config); err != nil {
return err
}

bName := def.BinName()
bPath := def.BinPath(fPath)
bFilePath := def.BinFilePath(bPath, bName)
if !fileutil.Exists(bFilePath) {
zipFile, err := d.downloadFormulaBin(def.BinUrl(), bPath, bName)
zipFile, err := d.downloadFormulaBundle(def.BundleUrl(), fPath, def.BundleName())
if err != nil {
return err
}

if err := d.unzipFile(zipFile, bPath); err != nil {
if err := d.unzipFile(zipFile, fPath); err != nil {
return err
}
}
tDir, tBDir, err := d.createWorkDir(def)
if err != nil {
return err
}
defer fileutil.RemoveDir(tDir)
os.Chdir(tBDir)
bFilePath = def.BinFilePath(tBDir, bName)

cmd := exec.Command(bFilePath)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

if err := d.inputs(cmd, fPath, config); err != nil {
if err := d.inputs(cmd, fPath, &config); err != nil {
return err
}

Expand All @@ -105,6 +99,13 @@ func (d DefaultRunner) Run(def Definition) error {
return err
}

df, err := fileutil.ListNewFiles(bPath, tBDir)
if err != nil {
return err
}
if err = fileutil.MoveFiles(tBDir, cPwd, df); err != nil {
return err
}
return nil
}

Expand Down Expand Up @@ -158,6 +159,43 @@ func (d DefaultRunner) inputs(cmd *exec.Cmd, formulaPath string, config *Config)
return nil
}

func (d DefaultRunner) loadConfig(def Definition) (Config, error) {
fPath := def.FormulaPath(d.ritchieHome)
var config Config
cName := def.ConfigName()
cPath := def.ConfigPath(fPath, cName)
if !fileutil.Exists(cPath) {
if err := d.downloadConfig(def.ConfigUrl(cName), fPath, cName); err != nil {
return Config{}, err
}
}

configFile, err := ioutil.ReadFile(cPath)
if err != nil {
return Config{}, err
}

if err := json.Unmarshal(configFile, &config); err != nil {
return Config{}, err
}
return config, nil
}

func (d DefaultRunner) createWorkDir(def Definition) (string, string, error) {
fPath := def.FormulaPath(d.ritchieHome)
u := uuid.New().String()
tDir, tBDir := def.TmpWorkDirPath(d.ritchieHome, u)

if err := fileutil.CreateDirIfNotExists(tBDir, 0755); err != nil {
return "", "", err
}

if err := fileutil.CopyDirectory(def.BinPath(fPath), tBDir); err != nil {
return "", "", err
}
return tDir, tBDir, nil
}

func (d DefaultRunner) persistCache(formulaPath, inputVal string, input Input, items []string) {
cachePath := fmt.Sprintf(CachePattern, formulaPath, strings.ToUpper(input.Name))
if input.Cache.Active {
Expand Down Expand Up @@ -247,7 +285,7 @@ func (d DefaultRunner) resolveIfReserved(input Input) (string, error) {
return "", nil
}

func (d DefaultRunner) downloadFormulaBin(url, destPath, binName string) (string, error) {
func (d DefaultRunner) downloadFormulaBundle(url, destPath, zipName string) (string, error) {
log.Println("Download formula...")

resp, err := http.Get(url)
Expand All @@ -269,7 +307,7 @@ func (d DefaultRunner) downloadFormulaBin(url, destPath, binName string) (string
return "", errors.New("unknown error when downloading your formula")
}

file := fmt.Sprintf("%s/%s.zip", destPath, binName)
file := fmt.Sprintf("%s/%s", destPath, zipName)

if err := fileutil.CreateDirIfNotExists(destPath, 0755); err != nil {
return "", err
Expand Down Expand Up @@ -343,3 +381,4 @@ func (d DefaultRunner) unzipFile(filename, destPath string) error {
log.Println("Done.")
return nil
}

Loading