From 571abf917bb3a6aa7ac7dd40969ed59ce84d78db Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Fri, 3 Sep 2021 00:02:31 -0500 Subject: Add clean option and fix issue with dir propegation --- cmd/planr/main.go | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'cmd/planr/main.go') diff --git a/cmd/planr/main.go b/cmd/planr/main.go index 4e0e05b..85b766e 100644 --- a/cmd/planr/main.go +++ b/cmd/planr/main.go @@ -19,6 +19,8 @@ func printUsage(w io.Writer) { fmt.Fprintln(w, " version ") fmt.Fprintln(w, " build ") fmt.Fprintln(w, " evaluate ") + fmt.Fprintln(w, " clean ") + } func dieUsage() { @@ -45,6 +47,8 @@ func main() { sub.Build(subargs) case "evaluate","eval": sub.Evaluate(subargs) + case "clean": + sub.Clean(subargs) case "help", "-h", "-help", "--help": printUsage(os.Stdout) default: -- cgit v1.2.3 From d670eeb256094deaceef13656e6c60e0f9ff5427 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Fri, 3 Sep 2021 18:13:49 -0500 Subject: Add config command to retrieve configuration values and clean command to clean build files --- cmd/planr/main.go | 51 ++++++++++++++++++++++++++++++++++++++++------- cmd/planr/sub/build.go | 17 ++-------------- cmd/planr/sub/clean.go | 6 ++++-- cmd/planr/sub/config.go | 28 ++++++++++++++++++++++++++ cmd/planr/sub/evaluate.go | 4 ++-- runner.go | 24 ++++++++++++++++++++++ 6 files changed, 104 insertions(+), 26 deletions(-) create mode 100644 cmd/planr/sub/config.go (limited to 'cmd/planr/main.go') diff --git a/cmd/planr/main.go b/cmd/planr/main.go index 85b766e..4b4a965 100644 --- a/cmd/planr/main.go +++ b/cmd/planr/main.go @@ -5,8 +5,11 @@ import ( "io" "log" "os" + "flag" + "golang.furkistan.com/planr" "golang.furkistan.com/planr/cmd/planr/sub" + "golang.furkistan.com/planr/adapters/gtest" ) const ( @@ -20,7 +23,7 @@ func printUsage(w io.Writer) { fmt.Fprintln(w, " build ") fmt.Fprintln(w, " evaluate ") fmt.Fprintln(w, " clean ") - + fmt.Fprintln(w, " config ") } func dieUsage() { @@ -28,6 +31,36 @@ func dieUsage() { os.Exit(1) } +func NewRunner() planr.Runner { + r := planr.Runner {} + + r.RegisterAdapter(>est.GtestAdapter{}) + + if wd, err := os.Getwd(); err == nil { + r.SetConfigDirFromTree(wd) + } + + src := flag.String("srcdir", "", "source directory") + config := flag.String("configdir", "", "config directory") + build := flag.String("builddir", "", "build directory") + + flag.Parse() + + if src != nil && *src != "" { + r.SetSrcDir(*src) + } + + if config != nil && *config != "" { + r.SetConfigDir(*config) + } + + if build != nil && *build != "" { + r.SetBuildDir(*build) + } + + return r +} + func main() { log.SetFlags(log.Llongfile | log.Lmsgprefix) @@ -37,18 +70,22 @@ func main() { dieUsage() } - subcommand := os.Args[1] - subargs := os.Args[2:] + runner := NewRunner() + + subcommand := flag.Arg(0) + subargs := flag.Args()[1:] switch subcommand { case "version": fmt.Printf("%s\n", VERSION) case "build": - sub.Build(subargs) - case "evaluate","eval": - sub.Evaluate(subargs) + sub.Build(runner, subargs) + case "evaluate", "eval": + sub.Evaluate(runner, subargs) case "clean": - sub.Clean(subargs) + sub.Clean(runner, subargs) + case "config": + sub.Config(runner, subargs) case "help", "-h", "-help", "--help": printUsage(os.Stdout) default: diff --git a/cmd/planr/sub/build.go b/cmd/planr/sub/build.go index d6e7456..bddeb4b 100644 --- a/cmd/planr/sub/build.go +++ b/cmd/planr/sub/build.go @@ -2,22 +2,9 @@ package sub import ( "golang.furkistan.com/planr" - "golang.furkistan.com/planr/adapters/gtest" - "os" ) -func Runner() planr.Runner { - r := planr.Runner {} - r.RegisterAdapter(>est.GtestAdapter{}) - - if wd, err := os.Getwd(); err == nil { - r.SetConfigDirFromTree(wd) - } - - return r -} - -func Build(params []string) { - Runner().Build() +func Build(runner planr.Runner, params []string) { + runner.Build() } diff --git a/cmd/planr/sub/clean.go b/cmd/planr/sub/clean.go index d40e967..ca27027 100644 --- a/cmd/planr/sub/clean.go +++ b/cmd/planr/sub/clean.go @@ -1,5 +1,7 @@ package sub -func Clean(params []string) { - Runner().Clean() +import "golang.furkistan.com/planr" + +func Clean(runner planr.Runner, params []string) { + runner.Clean() } diff --git a/cmd/planr/sub/config.go b/cmd/planr/sub/config.go new file mode 100644 index 0000000..ce03f9e --- /dev/null +++ b/cmd/planr/sub/config.go @@ -0,0 +1,28 @@ +package sub + +import ( + "golang.furkistan.com/planr" + "fmt" + "os" +) + + +func Config(runner planr.Runner, params []string) { + if len(params) != 1 { + fmt.Fprintf(os.Stderr, "Usage: planr config \n") + os.Exit(1) + } + + key := params[0] + + switch key { + case "builddir": + fmt.Printf("%s\n", runner.BuildDir()) + case "configdir": + fmt.Printf("%s\n", runner.ConfigDir()) + case "srcdir": + fmt.Printf("%s\n", runner.SrcDir()) + default: + fmt.Fprintf(os.Stderr, "\"%s\" not found in configuration\n", key) + } +} diff --git a/cmd/planr/sub/evaluate.go b/cmd/planr/sub/evaluate.go index 3223304..f8ec509 100644 --- a/cmd/planr/sub/evaluate.go +++ b/cmd/planr/sub/evaluate.go @@ -4,8 +4,8 @@ import ( "golang.furkistan.com/planr" ) -func Evaluate(params []string) { - tcs := Runner().Evaluate() +func Evaluate(runner planr.Runner, params []string) { + tcs := runner.Evaluate() earned := 0.0 total := 0.0 diff --git a/runner.go b/runner.go index 0a6243c..9014b8c 100644 --- a/runner.go +++ b/runner.go @@ -125,3 +125,27 @@ func (r Runner) Clean() { func (r * Runner) SetConfigDirFromTree(childPath string) { r.dirs.SetConfigFromTree(childPath) } + +func (r * Runner) SetBuildDir(dir string) { + r.dirs.SetBuild(dir) +} + +func (r * Runner) SetConfigDir(dir string) { + r.dirs.SetConfig(dir) +} + +func (r * Runner) SetSrcDir(dir string) { + r.dirs.SetSrc(dir) +} + +func (r Runner) BuildDir() string { + return r.dirs.Build(); +} + +func (r Runner) ConfigDir() string { + return r.dirs.Config() +} + +func (r Runner) SrcDir() string { + return r.dirs.Src() +} -- cgit v1.2.3 From 31e48c3cb0c73d8eb2b9b6d9bb063d3bce3c3d79 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Fri, 3 Sep 2021 20:07:51 -0500 Subject: Use version code in PLANR for the CLI --- cmd/planr/main.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'cmd/planr/main.go') diff --git a/cmd/planr/main.go b/cmd/planr/main.go index 4b4a965..028c776 100644 --- a/cmd/planr/main.go +++ b/cmd/planr/main.go @@ -12,10 +12,6 @@ import ( "golang.furkistan.com/planr/adapters/gtest" ) -const ( - VERSION = "0.0.3" -) - func printUsage(w io.Writer) { fmt.Fprintf (w, "usage: %s command args ... \n", os.Args[0]) fmt.Fprintln(w, " help ") @@ -77,7 +73,7 @@ func main() { switch subcommand { case "version": - fmt.Printf("%s\n", VERSION) + fmt.Printf("%s\n", planr.VERSION) case "build": sub.Build(runner, subargs) case "evaluate", "eval": -- cgit v1.2.3 From a70cfc735be53ac01cd6065c13fc9884bd96ae03 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Fri, 3 Sep 2021 21:14:28 -0500 Subject: Add new test runner API --- adapters/gtest/adapter.go | 7 +++++-- cmd/planr/main.go | 21 ++++++++++----------- runner.go | 20 -------------------- runner_builder.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 33 deletions(-) create mode 100644 runner_builder.go (limited to 'cmd/planr/main.go') diff --git a/adapters/gtest/adapter.go b/adapters/gtest/adapter.go index 29e2df7..2cc5603 100644 --- a/adapters/gtest/adapter.go +++ b/adapters/gtest/adapter.go @@ -188,8 +188,7 @@ func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { // compilation failure if !ok { - fmt.Printf("CAN'T FIND %s: status %d\n", tc.Cname, tc.Result.Status) - + if tc.Result.Status == planr.PASSING { cfg := tc.AdapterConfig().(*GtestConfig) @@ -214,3 +213,7 @@ func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { tc.Result.TestOutput = result.testOutput } } + +func New() *GtestAdapter { + return new(GtestAdapter) +} diff --git a/cmd/planr/main.go b/cmd/planr/main.go index 028c776..413787b 100644 --- a/cmd/planr/main.go +++ b/cmd/planr/main.go @@ -27,15 +27,14 @@ func dieUsage() { os.Exit(1) } -func NewRunner() planr.Runner { - r := planr.Runner {} - - r.RegisterAdapter(>est.GtestAdapter{}) +func getConfiguredRunner() planr.Runner { + r := planr.ConfigureRunner() + r = planr.RegisterAdapter(r, gtest.New()) if wd, err := os.Getwd(); err == nil { - r.SetConfigDirFromTree(wd) + r = planr.SetConfigDirFromTree(r, wd) } - + src := flag.String("srcdir", "", "source directory") config := flag.String("configdir", "", "config directory") build := flag.String("builddir", "", "build directory") @@ -43,18 +42,18 @@ func NewRunner() planr.Runner { flag.Parse() if src != nil && *src != "" { - r.SetSrcDir(*src) + r = planr.SetSrcDir(r, *src) } if config != nil && *config != "" { - r.SetConfigDir(*config) + r = planr.SetConfigDir(r, *config) } if build != nil && *build != "" { - r.SetBuildDir(*build) + r = planr.SetBuildDir(r, *build) } - return r + return r.New() } func main() { @@ -66,7 +65,7 @@ func main() { dieUsage() } - runner := NewRunner() + runner := getConfiguredRunner() subcommand := flag.Arg(0) subargs := flag.Args()[1:] diff --git a/runner.go b/runner.go index c0c926a..1cc509e 100644 --- a/runner.go +++ b/runner.go @@ -11,10 +11,6 @@ type Runner struct { dirs DirConfig } -func (r *Runner) RegisterAdapter(a Adapter) { - r.adapters = append(r.adapters, a) -} - func (r Runner) adapterCfgs() []AdapterConfig { cgs := make([]AdapterConfig, len(r.adapters)) @@ -122,22 +118,6 @@ func (r Runner) Clean() { r.dirs.CleanBuild() } -func (r * Runner) SetConfigDirFromTree(childPath string) { - r.dirs.SetConfigFromTree(childPath) -} - -func (r * Runner) SetBuildDir(dir string) { - r.dirs.SetBuild(dir) -} - -func (r * Runner) SetConfigDir(dir string) { - r.dirs.SetConfig(dir) -} - -func (r * Runner) SetSrcDir(dir string) { - r.dirs.SetSrc(dir) -} - func (r Runner) BuildDir() string { return r.dirs.Build(); } diff --git a/runner_builder.go b/runner_builder.go new file mode 100644 index 0000000..848d09b --- /dev/null +++ b/runner_builder.go @@ -0,0 +1,42 @@ +package planr + +type RunnerBuilder struct { + adapters [] Adapter + dirs DirConfig +} + +func ConfigureRunner() RunnerBuilder { + return RunnerBuilder {} +} + +func RegisterAdapter(b RunnerBuilder, a Adapter) RunnerBuilder { + b.adapters = append(b.adapters, a) + return b +} + +func SetConfigDirFromTree(b RunnerBuilder, childPath string) RunnerBuilder { + b.dirs.SetConfigFromTree(childPath) + return b +} + +func SetConfigDir(b RunnerBuilder, dir string) RunnerBuilder { + b.dirs.SetConfig(dir) + return b +} + +func SetBuildDir(b RunnerBuilder, dir string) RunnerBuilder { + b.dirs.SetBuild(dir) + return b +} + +func SetSrcDir(b RunnerBuilder, dir string) RunnerBuilder { + b.dirs.SetSrc(dir) + return b +} + +func (b RunnerBuilder) New() Runner { + return Runner { + dirs: b.dirs, + adapters: b.adapters, + } +} -- cgit v1.2.3 From 80c205a1d6d25f5a80853a76afcd1f527a894f56 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Sat, 4 Sep 2021 15:38:30 -0500 Subject: Refactor build/eval pipeline to use clearer IO model and adapter segmentation methods --- adapters.go | 4 +- adapters/gtest/adapter.go | 44 ++++++++++---------- adapters/gtest/config.go | 18 ++++----- cmd/planr/main.go | 2 +- cmd/planr/sub/build.go | 3 +- cmd/planr/sub/evaluate.go | 3 +- runner.go | 100 ++++++++++++++++++++++++++++------------------ runner_builder.go | 9 +++-- 8 files changed, 107 insertions(+), 76 deletions(-) (limited to 'cmd/planr/main.go') diff --git a/adapters.go b/adapters.go index f4e53ce..b7c4b27 100644 --- a/adapters.go +++ b/adapters.go @@ -14,10 +14,10 @@ type Adapter interface { Init(dirs DirConfig) // Called once to preform expensive code generation - Build(testCase []*TestCase) + Build(testCase []TestCase) // Called every time source changes - Evaluate(testCase []*TestCase) + Evaluate(testCase []TestCase) []TestCase } // A parser function takes a blob of TOML and decodes it into diff --git a/adapters/gtest/adapter.go b/adapters/gtest/adapter.go index 2cc5603..c727805 100644 --- a/adapters/gtest/adapter.go +++ b/adapters/gtest/adapter.go @@ -16,8 +16,8 @@ import ( const GTEST_CMAKE = "CMakeLists.txt" -func makeUnit(tc *planr.TestCase, dirs planr.DirConfig) cmakeUnit { - cfg := tc.AdapterConfig().(*GtestConfig) +func makeUnit(tc planr.TestCase, dirs planr.DirConfig) cmakeUnit { + cfg := tc.AdapterConfig().(*Config) testpath := path.Join(dirs.Tests(), *cfg.Testfile) srclist := cfg.srcList(dirs.Src()) @@ -41,7 +41,7 @@ func safeWd() string{ type ResultFromId map[string] Result -func (adapter *GtestAdapter) execTests(cnames []string) ResultFromId { +func (adapter *Adapter) execTests(cnames []string) ResultFromId { buildDir := safeWd() lut := make(ResultFromId, 0) @@ -89,7 +89,7 @@ func (adapter *GtestAdapter) execTests(cnames []string) ResultFromId { // An executable may contain more than one test // Gather all executables and deduplicate them -func exes(tcs []*planr.TestCase) []string { +func exes(tcs []planr.TestCase) []string { set := make(map[string] bool, 0) for _, tc := range tcs { @@ -112,12 +112,12 @@ func exes(tcs []*planr.TestCase) []string { return exes } -func id(tc *planr.TestCase) string { - cfg := tc.AdapterConfig().(*GtestConfig) +func id(tc planr.TestCase) string { + cfg := tc.AdapterConfig().(*Config) return tc.Cname + "." + *cfg.Suite + "." + *cfg.Name } -func compile(wg * sync.WaitGroup, tc *planr.TestCase) { +func compile(wg * sync.WaitGroup, tc * planr.TestCase) { defer wg.Done() cmd := exec.Command("make", tc.Cname) @@ -137,11 +137,11 @@ func compile(wg * sync.WaitGroup, tc *planr.TestCase) { tc.Result.DebugOutput = string(out) } -type GtestAdapter struct { +type Adapter struct { dirs planr.DirConfig } -func (a *GtestAdapter) Config() planr.AdapterConfig { +func (a *Adapter) Config() planr.AdapterConfig { return planr.AdapterConfig { Name: "gtest", ParseConfig: ParseConfig, @@ -149,18 +149,18 @@ func (a *GtestAdapter) Config() planr.AdapterConfig { } } -func (a *GtestAdapter) Init(dirs planr.DirConfig) { +func (a *Adapter) Init(dirs planr.DirConfig) { a.dirs = dirs } -func (adapter *GtestAdapter) Build(tcs []*planr.TestCase) { +func (adapter Adapter) Build(tcs []planr.TestCase) { buildDir := safeWd() cmakeFile := path.Join(buildDir, GTEST_CMAKE) units := make([]cmakeUnit, 0) for _, tc := range tcs { - cfg := tc.AdapterConfig().(*GtestConfig) + cfg := tc.AdapterConfig().(*Config) cfg.ensureSatisfied(tc.Path) units = append(units, makeUnit(tc, adapter.dirs)) @@ -172,9 +172,10 @@ func (adapter *GtestAdapter) Build(tcs []*planr.TestCase) { } // ./planr eval 0.93s user 0.16s system 100% cpu 1.089 total -func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { +func (adapter *Adapter) Evaluate(tcs []planr.TestCase) [] planr.TestCase { var wg sync.WaitGroup - for _, tc := range tcs { + for i := range tcs { + tc := &tcs[i] wg.Add(1) go compile(&wg, tc) } @@ -183,14 +184,15 @@ func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { files := exes(tcs) resultById := adapter.execTests(files) - for _, tc := range tcs { - result, ok := resultById[id(tc)] + for i := range tcs { + tc := &tcs[i] + result, ok := resultById[id(*tc)] // compilation failure if !ok { if tc.Result.Status == planr.PASSING { - cfg := tc.AdapterConfig().(*GtestConfig) + cfg := tc.AdapterConfig().(*Config) log.Printf( "Could not find testcase %s with name=\"%s\" and suite=\"%s\". Does such a test exist in the test source?", @@ -200,7 +202,7 @@ func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { ) tc.Result.Status = planr.COMPILATION_FAILURE - tc.Result.DebugOutput += fmt.Sprintf("planr: Did not find testcase %s in any test executable\n", id(tc)) + tc.Result.DebugOutput += fmt.Sprintf("planr: Did not find testcase %s in any test executable\n", id(*tc)) } continue @@ -212,8 +214,10 @@ func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { tc.Result.TestOutput = result.testOutput } + + return tcs } -func New() *GtestAdapter { - return new(GtestAdapter) +func NewAdapter() *Adapter { + return new(Adapter) } diff --git a/adapters/gtest/config.go b/adapters/gtest/config.go index ba7efb1..8057d94 100644 --- a/adapters/gtest/config.go +++ b/adapters/gtest/config.go @@ -12,7 +12,7 @@ const ( DEFAULT_TIMEOUT = 1000 ) -type GtestDefaults struct { +type Defaults struct { Name *string Suite *string Testfile *string @@ -20,8 +20,8 @@ type GtestDefaults struct { Timeout *uint } -func (child *GtestDefaults) Inherit(p interface{}) { - parent := p.(*GtestDefaults) +func (child *Defaults) Inherit(p interface{}) { + parent := p.(*Defaults) if(child.Name == nil) { child.Name = parent.Name } if(child.Suite == nil) { child.Suite = parent.Suite } @@ -31,11 +31,11 @@ func (child *GtestDefaults) Inherit(p interface{}) { } -type GtestConfig struct { - GtestDefaults +type Config struct { + Defaults } -func (g GtestConfig) ensureSatisfied(path string) { +func (g Config) ensureSatisfied(path string) { if g.Name == nil { log.Fatalf("\"name\" is not defined for unit: %s\n", path) } else if g.Suite == nil { @@ -50,7 +50,7 @@ func (g GtestConfig) ensureSatisfied(path string) { } } -func (cfg GtestConfig) srcList(srcDir string) string { +func (cfg Config) srcList(srcDir string) string { var srcList string if cfg.Srcs != nil { @@ -66,7 +66,7 @@ func (cfg GtestConfig) srcList(srcDir string) string { } func ParseConfig(prim toml.Primitive) (planr.InheritableConfig, error) { - config := GtestConfig{} + config := Config{} if err := toml.PrimitiveDecode(prim, &config); err != nil { return nil, err @@ -76,7 +76,7 @@ func ParseConfig(prim toml.Primitive) (planr.InheritableConfig, error) { } func ParseDefaultConfig(prim toml.Primitive) (planr.InheritableConfig, error) { - config := GtestDefaults{} + config := Defaults{} if err := toml.PrimitiveDecode(prim, &config); err != nil { return nil, err diff --git a/cmd/planr/main.go b/cmd/planr/main.go index 413787b..527d277 100644 --- a/cmd/planr/main.go +++ b/cmd/planr/main.go @@ -29,7 +29,7 @@ func dieUsage() { func getConfiguredRunner() planr.Runner { r := planr.ConfigureRunner() - r = planr.RegisterAdapter(r, gtest.New()) + r = planr.RegisterAdapter(r, gtest.NewAdapter()) if wd, err := os.Getwd(); err == nil { r = planr.SetConfigDirFromTree(r, wd) diff --git a/cmd/planr/sub/build.go b/cmd/planr/sub/build.go index bddeb4b..caf7bde 100644 --- a/cmd/planr/sub/build.go +++ b/cmd/planr/sub/build.go @@ -6,5 +6,6 @@ import ( func Build(runner planr.Runner, params []string) { - runner.Build() + tcs := runner.CollectCases() + runner.Build(tcs) } diff --git a/cmd/planr/sub/evaluate.go b/cmd/planr/sub/evaluate.go index f8ec509..32e19a6 100644 --- a/cmd/planr/sub/evaluate.go +++ b/cmd/planr/sub/evaluate.go @@ -5,7 +5,8 @@ import ( ) func Evaluate(runner planr.Runner, params []string) { - tcs := runner.Evaluate() + tcs := runner.CollectCases() + tcs = runner.Evaluate(tcs) earned := 0.0 total := 0.0 diff --git a/runner.go b/runner.go index d3d4b08..f613d44 100644 --- a/runner.go +++ b/runner.go @@ -7,8 +7,8 @@ import ( ) type Runner struct { - adapters []Adapter - dirs DirConfig + adapters map[string] Adapter + dirs DirConfig } func (r Runner) adapterCfgs() []AdapterConfig { @@ -21,20 +21,7 @@ func (r Runner) adapterCfgs() []AdapterConfig { return cgs } -type tcTab map[string] []*TestCase - -func (r Runner) buildTcLUT(tcs []TestCase) tcTab { - m := make(tcTab, 0) - - for i := range tcs { - tc := &tcs[i] - nm := *tc.Config.Adapter - m[nm] = append(m[nm], tc) - } - - return m -} - +// TODO: Move into configuration parsing func (r Runner) checkConfig(tcs []TestCase) { for _, tc := range tcs { tc.Config.ensureSatisfied(tc.Path) @@ -54,55 +41,90 @@ func (r Runner) setupEnv(adapter Adapter) { safeCd(wd) } -func (r Runner) build(tcs []TestCase) { +type adapterTestSet struct { + adapter Adapter + tcs []TestCase +} + +func (r Runner) groupByAdapter(tcs []TestCase) []adapterTestSet { r.checkConfig(tcs) + + pairs := make(map[string] adapterTestSet, 0) - tcTab := r.buildTcLUT(tcs) + for _, tc := range tcs { + // TODO: Make non-pointer + adptNm := *tc.Config.Adapter + + // See if adapter if contained in map + adapter, contained := r.adapters[adptNm] + + if !contained { + log.Fatalf("Cannot find adapter \"%s\" for testcase \"%s\"", adptNm, tc.Cname) + } - for _, adapter := range r.adapters { - nm := adapter.Config().Name - r.setupEnv(adapter) + pair, exists := pairs[adptNm] - adapter.Build(tcTab[nm]) + if !exists { + pair.adapter = adapter + } + + pair.tcs = append(pair.tcs, tc) + + pairs[adptNm] = pair } - safeCd(r.dirs.Config()) + + // Convert to slice + set := make([]adapterTestSet, 0) + + for _, pair := range pairs { + set = append(set, pair) + } + + return set } -func (r Runner) units() []TestCase { +func (r Runner) CollectCases() []TestCase { return collectUnits(r.dirs.Rubric(), r.adapterCfgs()) } -func (r Runner) Build() { - units := r.units() +func (r Runner) Build(tcs []TestCase) { if !directoryExists(r.dirs.Build()) { r.dirs.MkBuild() } - r.build(units) -} + testSets := r.groupByAdapter(tcs) -func (r Runner) evaluate(tcs []TestCase) { - tcTab := r.buildTcLUT(tcs) - - for _, adapter := range r.adapters { - nm := adapter.Config().Name + for _, pair := range testSets { + adapter := pair.adapter + cases := pair.tcs r.setupEnv(adapter) - adapter.Evaluate(tcTab[nm]) + + adapter.Build(cases) } safeCd(r.dirs.Config()) } -func (r Runner) Evaluate() []TestCase { +func (r Runner) Evaluate(tcs []TestCase) []TestCase { + testSets := r.groupByAdapter(tcs) + results := make([]TestCase, 0) - units := r.units() + for _, pair := range testSets { + adapter := pair.adapter + cases := pair.tcs + + r.setupEnv(adapter) + resultSet := adapter.Evaluate(cases) - r.evaluate(units) + results = append(results, resultSet...) + } + + safeCd(r.dirs.Config()) - return units + return results } func (r Runner) Clean() { @@ -121,7 +143,7 @@ func (r Runner) SrcDir() string { return r.dirs.Src() } -func NewRunner(adapters []Adapter, dirs DirConfig) Runner { +func NewRunner(adapters map[string]Adapter, dirs DirConfig) Runner { r := Runner{adapters, dirs} for _, adapter := range r.adapters { diff --git a/runner_builder.go b/runner_builder.go index b369635..b3c07d9 100644 --- a/runner_builder.go +++ b/runner_builder.go @@ -1,16 +1,19 @@ package planr type RunnerBuilder struct { - adapters [] Adapter + adapters map[string] Adapter dirs DirConfig } func ConfigureRunner() RunnerBuilder { - return RunnerBuilder {} + builder := RunnerBuilder{} + builder.adapters = make(map[string] Adapter, 0) + return builder } func RegisterAdapter(b RunnerBuilder, a Adapter) RunnerBuilder { - b.adapters = append(b.adapters, a) + nm := a.Config().Name + b.adapters[nm] = a return b } -- cgit v1.2.3 From 76a134a0c5a0f4b8905c7ffa91517cdc1e9d0414 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Sun, 5 Sep 2021 02:11:09 -0500 Subject: Add CPU profiling flag --- cmd/planr/main.go | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'cmd/planr/main.go') diff --git a/cmd/planr/main.go b/cmd/planr/main.go index 527d277..779ee58 100644 --- a/cmd/planr/main.go +++ b/cmd/planr/main.go @@ -1,15 +1,16 @@ package main import ( + "flag" "fmt" "io" "log" "os" - "flag" + "runtime/pprof" "golang.furkistan.com/planr" - "golang.furkistan.com/planr/cmd/planr/sub" "golang.furkistan.com/planr/adapters/gtest" + "golang.furkistan.com/planr/cmd/planr/sub" ) func printUsage(w io.Writer) { @@ -27,6 +28,11 @@ func dieUsage() { os.Exit(1) } +var src = flag.String("srcdir", "", "source directory") +var config = flag.String("configdir", "", "config directory") +var build = flag.String("builddir", "", "build directory") +var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file") + func getConfiguredRunner() planr.Runner { r := planr.ConfigureRunner() r = planr.RegisterAdapter(r, gtest.NewAdapter()) @@ -35,21 +41,15 @@ func getConfiguredRunner() planr.Runner { r = planr.SetConfigDirFromTree(r, wd) } - src := flag.String("srcdir", "", "source directory") - config := flag.String("configdir", "", "config directory") - build := flag.String("builddir", "", "build directory") - - flag.Parse() - - if src != nil && *src != "" { + if *src != "" { r = planr.SetSrcDir(r, *src) } - if config != nil && *config != "" { + if *config != "" { r = planr.SetConfigDir(r, *config) } - if build != nil && *build != "" { + if *build != "" { r = planr.SetBuildDir(r, *build) } @@ -57,6 +57,18 @@ func getConfiguredRunner() planr.Runner { } func main() { + flag.Parse() + + if *cpuprofile != "" { + f, err := os.Create(*cpuprofile) + + if err != nil { + log.Fatal(err) + } + + pprof.StartCPUProfile(f) + defer pprof.StopCPUProfile() + } log.SetFlags(log.Llongfile | log.Lmsgprefix) log.SetPrefix("planr: ") -- cgit v1.2.3 From db947b801555913179c5e700e8b526166e3582ca Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Sun, 5 Sep 2021 02:41:21 -0500 Subject: Add config w/ version information --- cmd/planr/main.go | 6 ++++-- cmd/planr/sub/build.go | 4 ++-- cmd/planr/sub/common.go | 15 +++++++++++++++ cmd/planr/sub/evaluate.go | 4 +++- config.go | 31 ++++++++++++++++++++++--------- fs.go | 4 ++-- rubric_config.go | 4 ++-- 7 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 cmd/planr/sub/common.go (limited to 'cmd/planr/main.go') diff --git a/cmd/planr/main.go b/cmd/planr/main.go index 779ee58..9db30de 100644 --- a/cmd/planr/main.go +++ b/cmd/planr/main.go @@ -79,6 +79,8 @@ func main() { runner := getConfiguredRunner() + cfg := planr.DecodeConfig(runner.ConfigDir()) + subcommand := flag.Arg(0) subargs := flag.Args()[1:] @@ -86,9 +88,9 @@ func main() { case "version": fmt.Printf("%s\n", planr.VERSION) case "build": - sub.Build(runner, subargs) + sub.Build(runner, subargs, cfg) case "evaluate", "eval": - sub.Evaluate(runner, subargs) + sub.Evaluate(runner, subargs, cfg) case "clean": sub.Clean(runner, subargs) case "config": diff --git a/cmd/planr/sub/build.go b/cmd/planr/sub/build.go index caf7bde..2617a68 100644 --- a/cmd/planr/sub/build.go +++ b/cmd/planr/sub/build.go @@ -4,8 +4,8 @@ import ( "golang.furkistan.com/planr" ) - -func Build(runner planr.Runner, params []string) { +func Build(runner planr.Runner, params []string, cfg planr.Config) { + dieIncompatibleVersion(cfg) tcs := runner.CollectCases() runner.Build(tcs) } diff --git a/cmd/planr/sub/common.go b/cmd/planr/sub/common.go new file mode 100644 index 0000000..7e896c1 --- /dev/null +++ b/cmd/planr/sub/common.go @@ -0,0 +1,15 @@ +package sub + +import ( + "golang.furkistan.com/planr" + "os" + "fmt" +) + +func dieIncompatibleVersion(cfg planr.Config) { + if cfg.IncompatibleWithVersion() { + fmt.Fprintf(os.Stderr, "This version of PlanR (%v) is incompatible with config version %s\n", planr.VERSION, cfg.Version) + fmt.Fprintf(os.Stderr, "Please upgrade to version %s or greater\n", cfg.Version) + os.Exit(1) + } +} diff --git a/cmd/planr/sub/evaluate.go b/cmd/planr/sub/evaluate.go index fe864ad..5719b10 100644 --- a/cmd/planr/sub/evaluate.go +++ b/cmd/planr/sub/evaluate.go @@ -4,7 +4,9 @@ import ( "golang.furkistan.com/planr" ) -func Evaluate(runner planr.Runner, params []string) { +func Evaluate(runner planr.Runner, params []string, cfg planr.Config) { + dieIncompatibleVersion(cfg) + tcs := runner.CollectCases() trs := runner.Evaluate(tcs) diff --git a/config.go b/config.go index d2d32e9..88495e3 100644 --- a/config.go +++ b/config.go @@ -4,19 +4,19 @@ import ( "github.com/BurntSushi/toml" "log" "path" + "strings" ) -type planrConfig struct { - Version string - Project_title string +type Config struct { + Version string } -const PLANR_CONFIG = "config.toml" +const PLANR_CONFIG_FILE = "config.toml" -func decodeConfig(configDir string) planrConfig { - cfg := planrConfig { } +func DecodeConfig(configDir string) Config { + cfg := Config { } - configFile := path.Join(configDir, PLANR_CONFIG) + configFile := path.Join(configDir, PLANR_CONFIG_FILE) if _, err := toml.DecodeFile(configFile, &cfg); err != nil { // TODO: handle missing config @@ -26,6 +26,19 @@ func decodeConfig(configDir string) planrConfig { return cfg } -func (cfg planrConfig) isIncompatibleWithVersion() bool { - return cfg.Version > VERSION +func (cfg Config) IncompatibleWithVersion() bool { + if strings.Count(cfg.Version, ".") != 2 { + log.Fatalf("Version %s is not semantic", cfg.Version) + } + + cfgbits := strings.SplitN(cfg.Version, ".", 2) + bits := strings.SplitN(VERSION, ".", 2) + + // major version change + if cfgbits[0] != bits[0] { + return true + } + + // Config newer, possible feature additions + return cfgbits[1] > bits[1] } diff --git a/fs.go b/fs.go index a42ff2c..04a3522 100644 --- a/fs.go +++ b/fs.go @@ -99,7 +99,7 @@ func collectFromDir( // Process defaults for this directory if a defaults.toml is found defaultsPath := path.Join(dir, DEFAULTS) if info, err := os.Stat(defaultsPath); err == nil && !info.IsDir() { - d, err := DecodeDefaults(defaultsPath, cfgs) + d, err := DecodeRubricDefaults(defaultsPath, cfgs) if err != nil { log.Fatalf("Error encounter in %s: %v\n", defaultsPath, err); @@ -135,7 +135,7 @@ func collectFromDir( } // Decode a unit - config, err := DecodeConfig(child, cfgs) + config, err := DecodeRubricConfig(child, cfgs) if err != nil { log.Fatalf("Error encountered in %s: %v", child, config) diff --git a/rubric_config.go b/rubric_config.go index 887bbb0..322e58a 100644 --- a/rubric_config.go +++ b/rubric_config.go @@ -135,7 +135,7 @@ func (defaults *Defaults) decodeAdapters( } // Decode defaults.toml -func DecodeDefaults(path string, adapterCfg []AdapterConfig) (Defaults, error) { +func DecodeRubricDefaults(path string, adapterCfg []AdapterConfig) (Defaults, error) { defaults := Defaults { } if _, err := toml.DecodeFile(path, &defaults); err != nil { @@ -151,7 +151,7 @@ func DecodeDefaults(path string, adapterCfg []AdapterConfig) (Defaults, error) { } // Decode an individual unit -func DecodeConfig(path string, adapterCfg []AdapterConfig) (TestCaseConfig, error) { +func DecodeRubricConfig(path string, adapterCfg []AdapterConfig) (TestCaseConfig, error) { config := TestCaseConfig { } if _, err := toml.DecodeFile(path, &config); err != nil { -- cgit v1.2.3 From 8b28f4b5996387b47de06ae89fc947a489489378 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Sun, 5 Sep 2021 04:30:33 -0500 Subject: Add bash adapter --- adapters/bash/adapter.go | 96 ++++++++++++++++++++++++++++++++++++++++++++++++ adapters/bash/config.go | 64 ++++++++++++++++++++++++++++++++ cmd/planr/main.go | 11 +++--- 3 files changed, 166 insertions(+), 5 deletions(-) create mode 100644 adapters/bash/adapter.go create mode 100644 adapters/bash/config.go (limited to 'cmd/planr/main.go') diff --git a/adapters/bash/adapter.go b/adapters/bash/adapter.go new file mode 100644 index 0000000..196001f --- /dev/null +++ b/adapters/bash/adapter.go @@ -0,0 +1,96 @@ +package bash + +import ( + "context" + "errors" + "log" + "os" + "os/exec" + "path" + "strings" + "time" + "fmt" + + "golang.furkistan.com/planr" +) + +type Adapter struct { + dirs planr.DirConfig +} + +func (a *Adapter) Config() planr.AdapterConfig { + return planr.AdapterConfig { + Name: "bash", + ParseConfig: ParseConfig, + ParseDefaultConfig: ParseDefaultConfig, + } +} + +func safeWd() string{ + wd, err := os.Getwd() + + if err != nil { + log.Fatalf("Could not get GtestBuildDir %s %v\n", wd, err) + } + + return wd +} + +func (a *Adapter) Init(dirs planr.DirConfig) { + a.dirs = dirs +} + +func (adapter Adapter) Build(tcs []planr.TestCase) { } + +func executeScriptedTest(testdir string, tc planr.TestCase) planr.TestResult { + cfg := tc.AdapterConfig().(*Config) + + timeout := time.Duration(cfg.Timeout) * time.Millisecond + + ctx, cancel := context.WithTimeout(context.Background(), timeout) + + defer cancel() + + path := path.Join(testdir, cfg.Testfile) + + result := planr.TestResult {} + result.Tc = tc + + cmd := exec.CommandContext(ctx, "bash", path) + + if out, err := cmd.CombinedOutput(); err != nil { + result.Status = planr.RUNTIME_FAILURE + result.TestOutput = string(out) + + var exiterr *exec.ExitError + if !errors.As(err, &exiterr) { + log.Fatalf("Test script %s failed with unknown error %v\n", path, err) + } else { + if strings.Contains(exiterr.String(), "killed") { + result.TestOutput += fmt.Sprintf("TEST TERMINATED (Timeout=%d)\n", cfg.Timeout) + } + } + + return result + } + + result.Status = planr.PASSING + + + return result +} + +func (adapter Adapter) Evaluate(tcs []planr.TestCase) [] planr.TestResult { + finalizeConfigs(tcs) + + trs := make([]planr.TestResult, len(tcs)) + for i, tc := range tcs { + trs[i] = executeScriptedTest(adapter.dirs.Tests(), tc) + } + + return trs +} + +func NewAdapter() *Adapter { + return new(Adapter) +} diff --git a/adapters/bash/config.go b/adapters/bash/config.go new file mode 100644 index 0000000..bcae5c7 --- /dev/null +++ b/adapters/bash/config.go @@ -0,0 +1,64 @@ +package bash + +import ( + "log" + "golang.furkistan.com/planr" + "github.com/BurntSushi/toml" +) + +const ( + DEFAULT_TIMEOUT=1000 +) + +type Defaults struct { + Testfile string + Timeout uint +} + +func (child *Defaults) Inherit(p interface{}) { + parent := p.(*Defaults) + + if(child.Timeout == 0) { child.Timeout = parent.Timeout } +} + +type Config struct { + Defaults +} + +func (c *Config) finalize(path string) { + if c.Testfile == "" { + log.Fatalf("\"Testfile\" is not defined for unit %s\n", path) + } + + if c.Timeout == 0 { + c.Timeout = DEFAULT_TIMEOUT; + } +} + +func finalizeConfigs(tcs []planr.TestCase) { + for i := range tcs { + cfg := tcs[i].AdapterConfig().(*Config) + + cfg.finalize(tcs[i].Path) + } +} + +func ParseConfig(prim toml.Primitive) (planr.InheritableConfig, error) { + config := Config {} + + if err := toml.PrimitiveDecode(prim, &config); err != nil { + return nil, err + } + + return &config, nil +} + +func ParseDefaultConfig(prim toml.Primitive) (planr.InheritableConfig, error) { + config := Defaults{} + + if err := toml.PrimitiveDecode(prim, &config); err != nil { + return nil, err + } + + return &config, nil +} diff --git a/cmd/planr/main.go b/cmd/planr/main.go index 9db30de..2745a64 100644 --- a/cmd/planr/main.go +++ b/cmd/planr/main.go @@ -1,7 +1,6 @@ package main -import ( - "flag" +import ( "flag" "fmt" "io" "log" @@ -10,6 +9,7 @@ import ( "golang.furkistan.com/planr" "golang.furkistan.com/planr/adapters/gtest" + "golang.furkistan.com/planr/adapters/bash" "golang.furkistan.com/planr/cmd/planr/sub" ) @@ -28,14 +28,15 @@ func dieUsage() { os.Exit(1) } -var src = flag.String("srcdir", "", "source directory") -var config = flag.String("configdir", "", "config directory") -var build = flag.String("builddir", "", "build directory") +var src = flag.String("srcdir", "", "source directory") +var config = flag.String("configdir", "", "config directory") +var build = flag.String("builddir", "", "build directory") var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file") func getConfiguredRunner() planr.Runner { r := planr.ConfigureRunner() r = planr.RegisterAdapter(r, gtest.NewAdapter()) + r = planr.RegisterAdapter(r, bash.NewAdapter()) if wd, err := os.Getwd(); err == nil { r = planr.SetConfigDirFromTree(r, wd) -- cgit v1.2.3 From 84215b6d06294f16f2690176304d25dba4b464d4 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Sun, 5 Sep 2021 13:52:39 -0500 Subject: Add flag for JSON eval output --- cmd/planr/main.go | 1 + cmd/planr/sub/evaluate.go | 52 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 8 deletions(-) (limited to 'cmd/planr/main.go') diff --git a/cmd/planr/main.go b/cmd/planr/main.go index 2745a64..0a16cd0 100644 --- a/cmd/planr/main.go +++ b/cmd/planr/main.go @@ -19,6 +19,7 @@ func printUsage(w io.Writer) { fmt.Fprintln(w, " version ") fmt.Fprintln(w, " build ") fmt.Fprintln(w, " evaluate ") + fmt.Fprintln(w, " evaluate -json ") fmt.Fprintln(w, " clean ") fmt.Fprintln(w, " config ") } diff --git a/cmd/planr/sub/evaluate.go b/cmd/planr/sub/evaluate.go index c0df1e7..d2d077f 100644 --- a/cmd/planr/sub/evaluate.go +++ b/cmd/planr/sub/evaluate.go @@ -1,21 +1,57 @@ package sub import ( - "golang.furkistan.com/planr" + "encoding/json" + "fmt" + "log" + "flag" + + "golang.furkistan.com/planr" ) +type gradingResults struct { + TestResults []planr.TestResult + Score planr.Scoring +} + +func prettyPrint(results gradingResults) { + for _, tr := range results.TestResults { + tcPprint(tr) + } + + printScoring(results.Score) +} + +func jsonPrint(results gradingResults) { + res, err := json.Marshal(results) + + if err != nil { + log.Fatalf("Error printing JSON: %v\n", err) + } + + fmt.Println(string(res)) +} func Evaluate(runner planr.Runner, params []string, cfg planr.Config) { + f := flag.NewFlagSet("evaluate", flag.ExitOnError) + + jsonOutput := f.Bool("json", false, "print json output") + + f.Parse(params) + dieIncompatibleVersion(cfg) tcs := runner.CollectCases() trs := runner.Evaluate(tcs) - - score := planr.Score(trs) - - for _, tr := range trs { - tcPprint(tr) + + results := gradingResults { + TestResults: trs, + Score: planr.Score(trs), + } + + if *jsonOutput { + jsonPrint(results) + } else { + prettyPrint(results) } - - printScoring(score) } -- cgit v1.2.3 From b87500f02bff2ff69945b55a07f8be582e8c4e91 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Sun, 5 Sep 2021 14:01:17 -0500 Subject: Clarify config cmd in version --- cmd/planr/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmd/planr/main.go') diff --git a/cmd/planr/main.go b/cmd/planr/main.go index 0a16cd0..53313e0 100644 --- a/cmd/planr/main.go +++ b/cmd/planr/main.go @@ -21,7 +21,7 @@ func printUsage(w io.Writer) { fmt.Fprintln(w, " evaluate ") fmt.Fprintln(w, " evaluate -json ") fmt.Fprintln(w, " clean ") - fmt.Fprintln(w, " config ") + fmt.Fprintln(w, " config ") } func dieUsage() { -- cgit v1.2.3 From c1fa815dca778097c145359860c5d506195e016b Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Sun, 5 Sep 2021 14:18:31 -0500 Subject: Add mechanism to conditionally run some tests - FS approch should be taken upon revision --- cmd/planr/main.go | 1 + cmd/planr/sub/evaluate.go | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 6 deletions(-) (limited to 'cmd/planr/main.go') diff --git a/cmd/planr/main.go b/cmd/planr/main.go index 53313e0..8a78e3c 100644 --- a/cmd/planr/main.go +++ b/cmd/planr/main.go @@ -19,6 +19,7 @@ func printUsage(w io.Writer) { fmt.Fprintln(w, " version ") fmt.Fprintln(w, " build ") fmt.Fprintln(w, " evaluate ") + fmt.Fprintln(w, " evaluate ... ") fmt.Fprintln(w, " evaluate -json ") fmt.Fprintln(w, " clean ") fmt.Fprintln(w, " config ") diff --git a/cmd/planr/sub/evaluate.go b/cmd/planr/sub/evaluate.go index d2d077f..dac42d0 100644 --- a/cmd/planr/sub/evaluate.go +++ b/cmd/planr/sub/evaluate.go @@ -14,12 +14,14 @@ type gradingResults struct { Score planr.Scoring } -func prettyPrint(results gradingResults) { +func prettyPrint(results gradingResults, summarize bool) { for _, tr := range results.TestResults { tcPprint(tr) } - printScoring(results.Score) + if summarize { + printScoring(results.Score) + } } func jsonPrint(results gradingResults) { @@ -37,12 +39,34 @@ func Evaluate(runner planr.Runner, params []string, cfg planr.Config) { jsonOutput := f.Bool("json", false, "print json output") - f.Parse(params) - dieIncompatibleVersion(cfg) + f.Parse(params) + tcs := runner.CollectCases() - trs := runner.Evaluate(tcs) + + // Filter those tests which patch IDs in params + filteredTcs := make([]planr.TestCase, 0) + summarizeScore := false + if f.NArg() > 0 { + ids := f.Args() + + membershipFun := make(map[string] bool, 0) + for _, id := range ids { + membershipFun[id] = true + } + + for i := range tcs { + if membershipFun[tcs[i].Cname] { + filteredTcs = append(filteredTcs, tcs[i]) + } + } + } else { + summarizeScore = true + filteredTcs = tcs + } + + trs := runner.Evaluate(filteredTcs) results := gradingResults { TestResults: trs, @@ -52,6 +76,6 @@ func Evaluate(runner planr.Runner, params []string, cfg planr.Config) { if *jsonOutput { jsonPrint(results) } else { - prettyPrint(results) + prettyPrint(results, summarizeScore) } } -- cgit v1.2.3 From 4b964d0d7b0d77d4cfcc6ddc1be1d3373cef82b2 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Sun, 5 Sep 2021 20:17:00 -0500 Subject: Fix bug where standard dirs are not set due to abs positioning --- cmd/planr/main.go | 2 +- stddirs.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'cmd/planr/main.go') diff --git a/cmd/planr/main.go b/cmd/planr/main.go index 8a78e3c..1cf931a 100644 --- a/cmd/planr/main.go +++ b/cmd/planr/main.go @@ -76,7 +76,7 @@ func main() { log.SetFlags(log.Llongfile | log.Lmsgprefix) log.SetPrefix("planr: ") - if len(os.Args) < 2 { + if flag.NArg() < 1 { dieUsage() } diff --git a/stddirs.go b/stddirs.go index 1eae439..581af87 100644 --- a/stddirs.go +++ b/stddirs.go @@ -68,17 +68,17 @@ func dirFromEnv(name, env string) *string { func (c *DirConfig) SetSrc(srcDir string) { dieDirAbsent("src", srcDir) - c.src = srcDir + c.src = abs(srcDir) } func (c *DirConfig) SetConfig(configDir string) { dieDirAbsent("planr (config)", configDir) - c.config = configDir + c.config = abs(configDir) } func (c *DirConfig) SetBuild(buildDir string) { dieDirAbsent("build", buildDir) - c.build = buildDir + c.build = abs(buildDir) } func (c *DirConfig) SetConfigFromTree(cdir string) { @@ -147,8 +147,8 @@ func abs(path string) string { } func (c DirConfig) Build() string { - if c.src != "" { - return c.src + if c.build != "" { + return c.build } if dir := dirFromEnv("build", ENV_BUILD_DIR); dir != nil { -- cgit v1.2.3