diff --git a/cmd/list.go b/cmd/list.go index 1de7e0c..f66636f 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -16,9 +16,13 @@ func List() { for _, p := range w.Projects { tasks := []string{} for t, _ := range p.Tasks { - tasks = append(tasks, t) + if !strings.HasPrefix(t, "_") { + tasks = append(tasks, t) + } + } + if len(tasks) > 0 { + table.Append([]string{p.Name, strings.Join(p.Tags, ", "), strings.Join(tasks, ", ")}) } - table.Append([]string{p.Name, strings.Join(p.Tags, ", "), strings.Join(tasks, ", ")}) } table.Render() diff --git a/cmd/run.go b/cmd/run.go index c86b0bd..8a8fe6a 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -13,9 +13,9 @@ func Run(qs []string) { w := loadWorkspace() for _, q := range queries { - ms := q.Search(&w) - for _, m := range ms { - core.Execute(&w, &m.Project, &m.Task) + err := core.ExecuteQuery(&w, q) + if err != nil { + log.Fatal(err) } } } diff --git a/core/execution.go b/core/execution.go index 62f80c6..97a21f8 100644 --- a/core/execution.go +++ b/core/execution.go @@ -1,9 +1,90 @@ package core import ( - "log" + "fmt" + "time" + "os" + "os/exec" ) -func Execute(w *Workspace, p *Project, t *Task) { - log.Printf("Running: %v/%v", p.Name, t.Name) +type Execution struct { + Workspace *Workspace + Project *Project + Task *Task +} + +func ExecuteQuery(w *Workspace, q Query) error { + matches := q.Search(w) + for _, match := range matches { + e := Execution{Workspace:w, Project:&match.Project, Task:&match.Task} + err := e.Execute() + if err != nil { + return err + } + } + return nil +} + +func (e *Execution) Execute() error { + start := time.Now() + fmt.Printf("%v/%v: Running\n", e.Project.Name, e.Task.Name) + + err := e.ExecuteDependent(e.Task.Before) + if err == nil { + err = e.ExecuteSelf() + if err == nil { + err = e.ExecuteDependent(e.Task.After) + } + } + + elapsed := time.Since(start) + if err != nil { + fmt.Printf("%v/%v: Failed, Took: %v\n", e.Project.Name, e.Task.Name, elapsed) + } else { + fmt.Printf("%v/%v: Completed, Took: %v\n", e.Project.Name, e.Task.Name, elapsed) + } + + return err +} + +func (e *Execution) ExecuteSelf() error { + return e.Cmd().Run() +} + +func (e *Execution) ExecuteDependent(qs []string) error { + for _, q := range qs { + query, err := ParseQuery(q) + if err != nil { + return err + } + if len(query.Tags) == 0 { + query.Tags = []string{e.Project.Name} + } + if !query.Match(e.Project, e.Task) { + err = ExecuteQuery(e.Workspace, query) + if err != nil { + return err + } + } + } + return nil +} + +func (e *Execution) Cmd() *exec.Cmd { + cmd := exec.Command("sh", "-exc", e.Task.Cmd) + cmd.Dir = e.Project.Cwd + cmd.Env = envList(e.Project.Env) + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd +} + +func envList(env map[string]string) []string { + env["PATH"] = env["PATH"] + string(os.PathListSeparator) + os.Getenv("PATH") + envList := make([]string, len(env)) + for k, v := range env { + envList = append(envList, fmt.Sprintf("%v=%v", k, v)) + } + return envList } diff --git a/core/project.go b/core/project.go index 39d448b..c8ba5fd 100644 --- a/core/project.go +++ b/core/project.go @@ -31,7 +31,11 @@ func ParseProject(path string) (Project, error) { if info, err := os.Stat(src); err != nil { return Project{}, err } else if info.IsDir() { - src = filepath.Join(src, "myke.yml") + if mp, err := ParseProject(filepath.Join(src, "myke.yml")); err != nil { + return ParseProject(filepath.Join(src, "s2do.yml")) + } else { + return mp, err + } } p, err := loadProjectYaml(src) @@ -45,7 +49,8 @@ func ParseProject(path string) (Project, error) { for _, epath := range p.EnvFiles { p.Env = mergeEnv(p.Env, loadEnvFile(epath)) } - // TODO: Merge OsEnv() + + p.Env = mergeEnv(p.Env, loadOsEnv()) p.Env["PATH"] = normalizePaths(p.Cwd, p.Env["PATH"]) for _, epath := range p.Extends { diff --git a/core/task.go b/core/task.go index 0b518eb..756d405 100644 --- a/core/task.go +++ b/core/task.go @@ -20,9 +20,13 @@ func loadTaskJson(name string, json gjson.Result) Task { if j := json.Get("desc"); j.Exists() { t.Desc = j.String() + } else { + t.Desc = "" } if j := json.Get("cmd"); j.Exists() { t.Cmd = j.String() + } else { + t.Cmd = "" } if j := json.Get("before"); j.Exists() { for _, s := range j.Array() { diff --git a/core/util.go b/core/util.go index 00287bf..16a9838 100644 --- a/core/util.go +++ b/core/util.go @@ -40,7 +40,10 @@ func loadOsEnv() (map[string]string) { env := make(map[string]string) for _, e := range os.Environ() { pair := strings.SplitN(e, "=", 2) - env[pair[0]] = pair[1] + if pair[0] != "PATH" { + // PATH is handled as a special case, so lets skip it + env[pair[0]] = pair[1] + } } return env }