github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/servicex/internal/project.go (about)

     1  package internal
     2  
     3  import (
     4  	"strings"
     5  	"fmt"
     6  	"gopkg.in/yaml.v2"
     7  	"io/ioutil"
     8  	"os"
     9  	"os/exec"
    10  	"runtime"
    11  	"reflect"
    12  	"github.com/johnnyeven/libtools/executil"
    13  )
    14  
    15  var ProjectFile = "profzone.yml"
    16  
    17  var (
    18  	DOCKER_REGISTRY_KEY = "PROFZONE_DOCKER_REGISTRY"
    19  	DOCKER_REGISTRY     = "registry.profzone.net:5000"
    20  )
    21  
    22  type Project struct {
    23  	Name            string            `env:"name" yaml:"name"`
    24  	Group           string            `env:"group" yaml:"group,omitempty"`
    25  	Version         Version           `env:"version" yaml:"version"`
    26  	Desc            string            `env:"description" yaml:"description"`
    27  	ProgramLanguage string            `env:"program_language" yaml:"program_language"`
    28  	Scripts         map[string]Script `yaml:"scripts,omitempty"`
    29  	Feature         string            `yaml:"feature,omitempty"`
    30  }
    31  
    32  func (p *Project) UnmarshalFromFile() error {
    33  	bytes, err := ioutil.ReadFile(ProjectFile)
    34  	if err != nil {
    35  		return err
    36  	}
    37  	errForUnmarshal := yaml.Unmarshal(bytes, p)
    38  	if errForUnmarshal != nil {
    39  		return errForUnmarshal
    40  	}
    41  	return nil
    42  }
    43  
    44  func (p Project) WithVersion(s string) Project {
    45  	v, err := FromVersionString(s)
    46  	if err != nil {
    47  		panic(err)
    48  	}
    49  	p.Version = *v
    50  	return p
    51  }
    52  
    53  func (p Project) WithGroup(group string) Project {
    54  	p.Group = group
    55  	return p
    56  }
    57  
    58  func (p Project) WithDesc(desc string) Project {
    59  	p.Desc = desc
    60  	return p
    61  }
    62  
    63  func (p Project) WithName(name string) Project {
    64  	p.Name = name
    65  	return p
    66  }
    67  
    68  func (p Project) WithLanguage(pl string) Project {
    69  	p.ProgramLanguage = pl
    70  	return p
    71  }
    72  
    73  func (p Project) WithFeature(f string) Project {
    74  	p.Feature = f
    75  	return p
    76  }
    77  
    78  func (p Project) WithScripts(key string, scripts ...string) Project {
    79  	if p.Scripts == nil {
    80  		p.Scripts = map[string]Script{}
    81  	}
    82  	p.Scripts[key] = append(Script{}, scripts...)
    83  	return p
    84  }
    85  
    86  func WrapEnv(s string) string {
    87  	return strings.ToUpper("PROJECT_" + s)
    88  }
    89  
    90  func SetEnv(k string, v string) {
    91  	os.Setenv(k, v)
    92  	fmt.Printf("export %s=%s\n", k, v)
    93  }
    94  
    95  func (p *Project) SetEnviron() {
    96  	if os.Getenv(DOCKER_REGISTRY_KEY) == "" {
    97  		SetEnv(DOCKER_REGISTRY_KEY, DOCKER_REGISTRY)
    98  	}
    99  
   100  	tpe := reflect.TypeOf(p).Elem()
   101  	rv := reflect.Indirect(reflect.ValueOf(p))
   102  
   103  	for i := 0; i < tpe.NumField(); i++ {
   104  		field := tpe.Field(i)
   105  		env := field.Tag.Get("env")
   106  
   107  		if len(env) > 0 {
   108  			value := rv.FieldByName(field.Name)
   109  
   110  			if stringer, ok := value.Interface().(fmt.Stringer); ok {
   111  				v := stringer.String()
   112  				if len(v) > 0 {
   113  					SetEnv(WrapEnv(env), v)
   114  				}
   115  			} else {
   116  				SetEnv(WrapEnv(env), value.String())
   117  			}
   118  		}
   119  	}
   120  }
   121  
   122  func (p *Project) Command(args ...string) *exec.Cmd {
   123  	p.SetEnviron()
   124  
   125  	sh := "sh"
   126  	if runtime.GOOS == "windows" {
   127  		sh = "bash"
   128  	}
   129  
   130  	envVars := executil.EnvVars{}
   131  	envVars.LoadFromEnviron()
   132  
   133  	return exec.Command(sh, "-c", envVars.Parse(strings.Join(args, " ")))
   134  }
   135  
   136  func (p *Project) Run(commands ...*exec.Cmd) {
   137  	for _, cmd := range commands {
   138  		if cmd != nil {
   139  			executil.StdRun(cmd)
   140  		}
   141  	}
   142  }
   143  
   144  func (p *Project) Execute(args ...string) {
   145  	p.Run(p.Command(args...))
   146  }
   147  
   148  func (p *Project) WriteToFile() {
   149  	bytes, err := yaml.Marshal(p)
   150  	if err != nil {
   151  		panic(err)
   152  	}
   153  	ioutil.WriteFile(ProjectFile, bytes, os.ModePerm)
   154  }
   155  
   156  type Script []string
   157  
   158  func (s Script) IsZero() bool {
   159  	return len(s) == 0
   160  }
   161  
   162  func (s Script) String() string {
   163  	return strings.Join(s, " && ")
   164  }
   165  
   166  func (s Script) MarshalYAML() (interface{}, error) {
   167  	if len(s) > 1 {
   168  		return s, nil
   169  	}
   170  	return s[0], nil
   171  }
   172  
   173  func (s *Script) UnmarshalYAML(unmarshal func(interface{}) error) error {
   174  	var str string
   175  	err := unmarshal(&str)
   176  	if err == nil {
   177  		*s = []string{str}
   178  	} else {
   179  		var values []string
   180  		err := unmarshal(&values)
   181  		if err != nil {
   182  			return err
   183  		}
   184  		*s = values
   185  	}
   186  	return nil
   187  }