From ac43c7f2d44d5f815d16a01d1171835538b4f532 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Thu, 2 Sep 2021 02:16:20 -0500 Subject: Break searching / error handling for standard directory structure into auxiliary file / struct --- stddirs.go | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 stddirs.go (limited to 'stddirs.go') diff --git a/stddirs.go b/stddirs.go new file mode 100644 index 0000000..adefce8 --- /dev/null +++ b/stddirs.go @@ -0,0 +1,177 @@ +package planr + +import ( + "os" + "log" + "path" + "path/filepath" +) + +// Standard Directories: +// +// Planr relies on a standard directory structure to resolve paths to source code +// These directories can be overridden via environmental variables // +// Directories: +// - `.` root directory +// - `src` contains source code +// - `planr` contains test metadata (also called configuration directory) +// - `planr/rubric` contains test case configuration +// - `planr/tests` contains source code for test cases +// - `planr/build` contains all files written during the build process (ephemeral) + +// Env overrides +const ( + ENV_CONFIG_DIR="PLANR_PLANR_DIR" + ENV_SRC_DIR="ENV_SRC_DIR" + ENV_BUILD_DIR="PLANR_BUILD_DIR" +) + +// Try these search directories +var CONFIG_SEARCH_DIRS = [2] string { + "planr", + ".planr", +} + +// Path are relative to the "planr" project config directory +const ( + DEFAULT_PATH_SRC="../src" + DEFAULT_PATH_BUILD="build" + DEFAULT_PATH_RUBRIC="rubric" + DEFAULT_PATH_TESTS="tests" +) + +type dirConfig struct { + src string + config string + build string +} + +func dieDirAbsent(name, path string) { + if !directoryExists(path) { + log.Fatalf("Could not find %s directory tried %s", name, path) + } +} + +func dirFromEnv(name, env string) *string { + if dir, isSet := os.LookupEnv(env); isSet { + + dieDirAbsent(name, dir) + + return &dir + } + + return nil +} + +func (c *dirConfig) SetSrcDir(srcDir string) { + dieDirAbsent("src", srcDir) + c.src = srcDir +} + +func (c *dirConfig) SetConfigDir(configDir string) { + dieDirAbsent("planr (config)", configDir) + c.config = configDir +} + +func (c *dirConfig) SetBuildDir(buildDir string) { + dieDirAbsent("build", buildDir) + c.build = buildDir +} + +func (c *dirConfig) SetConfigDirFromTree(cdir string) { + var configDir string + + found := traverseUp(cdir, func (path string) bool { + + for _, dir := range CONFIG_SEARCH_DIRS { + configDir = filepath.Join(path, dir) + + if directoryExists(configDir) { + return true + } + } + + return false + }); + + if !found { + log.Fatal("Could not find planr directory"); + } + + c.config = configDir +} + +func (c dirConfig) ConfigDir() string { + if c.config != "" { + return c.config + } + + dir := dirFromEnv("config", ENV_CONFIG_DIR) + if dir == nil { + log.Fatal("Could not find directory") + } + + c.config = *dir + return c.config +} + +func (c dirConfig) SrcDir() string { + if c.src != "" { + return c.src + } + + if dir := dirFromEnv("src", ENV_SRC_DIR); dir != nil { + c.src = *dir + return c.src + } + + // set path relative to config + dir := c.ConfigDir() + return path.Join(dir, DEFAULT_PATH_SRC) +} + +func (c dirConfig) BuildDir() string { + if c.src != "" { + return c.src + } + + if dir := dirFromEnv("build", ENV_BUILD_DIR); dir != nil { + c.build = *dir + return c.build + } + + dir := c.ConfigDir() + return path.Join(dir, DEFAULT_PATH_BUILD) +} + +func (c dirConfig) CleanBuildDir() { + build := c.BuildDir() + + if err := os.RemoveAll(build); err != nil { + log.Fatalf("Cannot build directory %v\n", err) + } + + if err := os.Remove(build); err != nil { + log.Fatalf("Could not remove build directory %v\n", err) + } +} + +func (c dirConfig) MkBuildDir() { + build := c.BuildDir() + + if err := os.Mkdir(build, 0755); err != nil { + log.Fatalf("Could not create build directory %v\n", err) + } +} + +func (c dirConfig) RubricDir() string { + rubric := path.Join(c.ConfigDir(), "rubric") + dieDirAbsent("rubric", rubric) + return rubric +} + +func (c dirConfig) TestsDir() string { + tests := path.Join(c.ConfigDir(), "tests") + dieDirAbsent("tests", tests) + return tests +} -- cgit v1.2.3 From 2af7117891cdb67758219a7075f39c05dc02f3f5 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Thu, 2 Sep 2021 03:14:47 -0500 Subject: Make adapters and internals complient with new directory structure --- adapters.go | 24 ++++++++- adapters/gtest/adapter.go | 77 ++++++++++++++++++----------- adapters/gtest/config.go | 21 ++------ adapters/gtest/templating.go | 2 - cmd/planr/sub/build.go | 12 +++-- cmd/planr/sub/evaluate.go | 4 +- config.go | 33 ------------- fs.go | 115 +++---------------------------------------- runner.go | 48 ++++++++++++------ stddirs.go | 53 +++++++++++--------- testcase.go | 19 ++++++- 11 files changed, 170 insertions(+), 238 deletions(-) (limited to 'stddirs.go') diff --git a/adapters.go b/adapters.go index 8419c8b..f4e53ce 100644 --- a/adapters.go +++ b/adapters.go @@ -1,16 +1,38 @@ package planr +import ( + "github.com/BurntSushi/toml" +) + // Test adapters must implement all life cycle hooks // This allows common config, code generation, etc // Test cases matching adapter configurations will be // fed into the adapter interface type Adapter interface { - // Config() AdapterConfig + Init(dirs DirConfig) + // Called once to preform expensive code generation Build(testCase []*TestCase) // Called every time source changes Evaluate(testCase []*TestCase) } + +// A parser function takes a blob of TOML and decodes it into +// configuration relevant to an adapter +type TomlParser func (toml.Primitive) (InheritableConfig, error) + +// The name under which an adapter registers corresponds +// to a table under the super-table adapters. All corresponding +// TOML will be passed to the ParseConfig method or ParseDefaultConfig +// for parsing. The ParseConfig file parses options in test case files. +// The ParseDefaultConfig is parsed by `defaults.toml` files and can +// be used to establish default configuration that will be inherited +// by all units in a common directory (collection) +type AdapterConfig struct { + Name string + ParseConfig TomlParser + ParseDefaultConfig TomlParser +} diff --git a/adapters/gtest/adapter.go b/adapters/gtest/adapter.go index 43e24c8..f91a524 100644 --- a/adapters/gtest/adapter.go +++ b/adapters/gtest/adapter.go @@ -11,55 +11,38 @@ import ( "path" "sync" "time" - "golang.furkistan.com/planr" ) const GTEST_CMAKE = "CMakeLists.txt" -func mkUnit(tc *planr.TestCase) cmakeUnit { +func makeUnit(tc *planr.TestCase, dirs planr.DirConfig) cmakeUnit { cfg := tc.AdapterConfig().(*GtestConfig) + testpath := path.Join(dirs.TestsDir(), *cfg.Testfile) + srclist := cfg.srcList(dirs.SrcDir()) + return cmakeUnit { tc.Cname, - cfg.joinTests(*cfg.Testfile), - cfg.srcList(), + testpath, + srclist, }; } +func safeWd() string{ + wd, err := os.Getwd() -type GtestAdapter struct {} - -func (a *GtestAdapter) Config() planr.AdapterConfig { - return planr.AdapterConfig { - Name: "gtest", - ParseConfig: ParseConfig, - ParseDefaultConfig: ParseDefaultConfig, - } -} - -func (adapter *GtestAdapter) Build(tcs []*planr.TestCase) { - buildDir := adapter.Config().Dir() - cmakeFile := path.Join(buildDir, GTEST_CMAKE) - - units := make([]cmakeUnit, 0) - for _, tc := range tcs { - - cfg := tc.AdapterConfig().(*GtestConfig) - cfg.ensureSatisfied(tc.Path) - - units = append(units, mkUnit(tc)) + if err != nil { + log.Fatalf("Could not get GtestBuildDir %s %v\n", wd, err) } - genCmake(cmakeFile, units) - - planr.RunCmd("cmake", "-S", ".", "-B", ".") + return wd } type ResultFromId map[string] Result func (adapter *GtestAdapter) execTests(cnames []string) ResultFromId { - buildDir := adapter.Config().Dir() + buildDir := safeWd() lut := make(ResultFromId, 0) for _, exe := range cnames { @@ -154,6 +137,40 @@ func compile(wg * sync.WaitGroup, tc *planr.TestCase) { tc.Result.DebugOutput = string(out) } +type GtestAdapter struct { + dirs planr.DirConfig +} + +func (a *GtestAdapter) Config() planr.AdapterConfig { + return planr.AdapterConfig { + Name: "gtest", + ParseConfig: ParseConfig, + ParseDefaultConfig: ParseDefaultConfig, + } +} + +func (a *GtestAdapter) Init(dirs planr.DirConfig) { + a.dirs = dirs +} + +func (adapter *GtestAdapter) 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.ensureSatisfied(tc.Path) + + units = append(units, makeUnit(tc, adapter.dirs)) + } + + genCmake(cmakeFile, units) + + planr.RunCmd("cmake", "-S", ".", "-B", ".") +} + // ./planr eval 0.93s user 0.16s system 100% cpu 1.089 total func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { var wg sync.WaitGroup @@ -169,7 +186,7 @@ func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { for _, tc := range tcs { result, ok := resultById[id(tc)] - // compilation failure + // compilation failure if !ok { fmt.Printf("CAN'T FIND %s: status %d\n", tc.Cname, tc.Result.Status) diff --git a/adapters/gtest/config.go b/adapters/gtest/config.go index 2db1bfb..bf5c9f2 100644 --- a/adapters/gtest/config.go +++ b/adapters/gtest/config.go @@ -5,6 +5,7 @@ import ( "golang.furkistan.com/planr" "strings" "github.com/BurntSushi/toml" + "path" ) type GtestDefaults struct { @@ -42,29 +43,13 @@ func (g GtestConfig) ensureSatisfied(path string) { } } -func (cfg GtestConfig) joinTests(path_ string) string { - if cfg.Test_root == nil { - return planr.JoinConfigDir("tests", path_) - } - - return planr.JoinConfigDir(*cfg.Test_root, path_) -} - -func (cfg GtestConfig) joinSrcs(path_ string) string { - if cfg.Srcs_root == nil { - return planr.JoinConfigDir("../src", path_) - } - - return planr.JoinConfigDir(*cfg.Srcs_root, path_) -} - -func (cfg GtestConfig) srcList() string { +func (cfg GtestConfig) srcList(srcDir string) string { var srcList string if cfg.Srcs != nil { srcs := make([]string, len(*cfg.Srcs)) for i, src := range *cfg.Srcs { - srcs[i] = "\"" + cfg.joinSrcs(src) + "\"" + srcs[i] = "\"" + path.Join(srcDir, src) + "\"" } srcList = strings.Join(srcs, "\n ") diff --git a/adapters/gtest/templating.go b/adapters/gtest/templating.go index c49f170..a9a3b07 100644 --- a/adapters/gtest/templating.go +++ b/adapters/gtest/templating.go @@ -80,5 +80,3 @@ include(GoogleTest) FetchContent_MakeAvailable(googletest) `)) } - - diff --git a/cmd/planr/sub/build.go b/cmd/planr/sub/build.go index 6c4332c..066245c 100644 --- a/cmd/planr/sub/build.go +++ b/cmd/planr/sub/build.go @@ -3,17 +3,21 @@ 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) { - - rd := planr.RubricDir() - - Runner().Build(rd) + Runner().Build() } diff --git a/cmd/planr/sub/evaluate.go b/cmd/planr/sub/evaluate.go index de0ba5c..3223304 100644 --- a/cmd/planr/sub/evaluate.go +++ b/cmd/planr/sub/evaluate.go @@ -5,9 +5,7 @@ import ( ) func Evaluate(params []string) { - rd := planr.RubricDir() - - tcs := Runner().Evaluate(rd) + tcs := Runner().Evaluate() earned := 0.0 total := 0.0 diff --git a/config.go b/config.go index bc0fa6a..887bbb0 100644 --- a/config.go +++ b/config.go @@ -1,11 +1,8 @@ package planr import ( - "log" "github.com/BurntSushi/toml" ) - - /* TODO: Every property defined within the defaults currently has to implement the "inherit" method to conditionally inherit a @@ -38,22 +35,6 @@ type InheritableConfig interface { Inherit(parent interface{}) } -// A parser function takes a blob of TOML and decodes it into -// configuration relevant to an adapter -type TomlParser func (toml.Primitive) (InheritableConfig, error) - -// The name under which an adapter registers corresponds -// to a table under the super-table adapters. All corresponding -// TOML will be passed to the ParseConfig method or ParseDefaultConfig -// for parsing. The ParseConfig file parses options in test case files. -// The ParseDefaultConfig is parsed by `defaults.toml` files and can -// be used to establish default configuration that will be inherited -// by all units in a common directory (collection) -type AdapterConfig struct { - Name string - ParseConfig TomlParser - ParseDefaultConfig TomlParser -} // Program-wide configuration which is recognized // in defaults.toml @@ -82,18 +63,6 @@ type Defaults struct { configs_ *[]AdapterConfig } -// Program-wide testcase config -type TestCaseConfig struct { - Defaults - Title *string - Description *string -} - -func (c TestCaseConfig) ensureSatisfied(name string) { - if (c.Adapter == nil) { - log.Fatalf("Adapter must be provided for testcase %s", name) - } -} // The default configuration must be able in inherit from // other defaults further up the tree @@ -169,8 +138,6 @@ func (defaults *Defaults) decodeAdapters( func DecodeDefaults(path string, adapterCfg []AdapterConfig) (Defaults, error) { defaults := Defaults { } - - if _, err := toml.DecodeFile(path, &defaults); err != nil { return defaults, err } diff --git a/fs.go b/fs.go index 86de16b..ffc5f05 100644 --- a/fs.go +++ b/fs.go @@ -45,115 +45,6 @@ func directoryExists(path string) bool { return info.IsDir() } -// Find the configuration directory -// Uses: -// 1. PlANR_DIRECTORY env if set -// 2. planr -// 3. .planr -func ConfigDir() string { - - // Return environmental override if set - if dir, isSet := os.LookupEnv("PLANR_DIRECTORY"); isSet { - - if !directoryExists(dir) { - log.Fatalf("Cannot find planr directory %s", dir); - } - - return dir; - } - - cwd, err := os.Getwd() - - if err != nil { - log.Fatal(err) - } - - var rubricDir string - - rubric_search_dirs := [2]string{ - "planr", - ".planr", - } - - found := traverseUp(cwd, func (path string) bool { - - for _, dir := range rubric_search_dirs { - rubricDir = filepath.Join(path, dir) - - if directoryExists(rubricDir) { - return true - } - } - - return false - }); - - if !found { - log.Fatal("Could not find planr directory"); - } - - return rubricDir -} - -func JoinConfigDir(path_ string, file string) string { - if path.IsAbs(path_) { - return path.Join(path_, file) - } - - return path.Join(ConfigDir(), path_, file) -} - -func RootDir() string { - return path.Join(ConfigDir(), "..") -} - -// Find rubric directory at PLANR_DIR/rubric -func RubricDir() string { - rubricDir := path.Join(ConfigDir(), "rubric"); - - if !directoryExists(rubricDir) { - log.Fatal("Could not find the rubric directory inside of planr") - } - - return rubricDir -} - -func BuildDir() string { - buildDir := path.Join(ConfigDir(), "build") - - if !directoryExists(buildDir) { - err := os.Mkdir(buildDir, 0755) - - if err != nil { - log.Fatalf("Cannot create build directory %v\n", err) - } - } - - return buildDir -} - -func CleanBuildDir() { - buildDir := path.Join(ConfigDir(), "build") - if err := os.RemoveAll(buildDir); err != nil { - log.Fatalf("Cannot clean (removeAll) in build directory %v\n", err) - } -} - -func (ac AdapterConfig) Dir() string { - dir := BuildDir() - dir = path.Join(dir, ac.Name) - - if !directoryExists(dir) { - err := os.Mkdir(dir, 0755) - - if err != nil { - log.Fatalf("Cannot create build/%s directory %v\n", ac.Name, err) - } - } - - return dir -} - func basename(path string) string { ext := filepath.Ext(path) return path[0:len(path) - len(ext)] @@ -262,3 +153,9 @@ func collectFromDir( } } } + +func safeCd(newWd string) { + if err := os.Chdir(newWd); err != nil { + log.Fatalf("Could not change into directory %v\n", err) + } +} diff --git a/runner.go b/runner.go index 3bee17a..f2eb8e9 100644 --- a/runner.go +++ b/runner.go @@ -3,10 +3,12 @@ package planr import ( "log" "os" + "path" ) type Runner struct { adapters []Adapter + DirConfig } func (r *Runner) RegisterAdapter(a Adapter) { @@ -43,12 +45,17 @@ func (r Runner) checkConfig(tcs []TestCase) { } } -func cdBuild(adapter Adapter) { - dir := adapter.Config().Dir() +func (r Runner) setupEnv(adapter Adapter) { + nm := adapter.Config().Name + wd := path.Join(r.BuildDir(), nm) - if err := os.Chdir(dir); err != nil { - log.Fatal(err) - } + if !directoryExists(wd) { + if err := os.Mkdir(wd, 0755); err != nil { + log.Fatalf("Could not create adapter config %s %v\n", wd, err) + } + } + + safeCd(wd) } func (r Runner) build(tcs []TestCase) { @@ -58,18 +65,25 @@ func (r Runner) build(tcs []TestCase) { for _, adapter := range r.adapters { nm := adapter.Config().Name - cdBuild(adapter) + r.setupEnv(adapter) adapter.Build(tcTab[nm]) } + + safeCd(r.ConfigDir()) } -func (r Runner) units(root string) []TestCase { - return collectUnits(root, r.adapterCfgs()) +func (r Runner) units() []TestCase { + return collectUnits(r.RubricDir(), r.adapterCfgs()) } -func (r Runner) Build(root string) { - units := r.units(root) +func (r Runner) Build() { + units := r.units() + + if !directoryExists(r.BuildDir()) { + r.MkBuildDir() + } + r.build(units) } @@ -78,16 +92,22 @@ func (r Runner) evaluate(tcs []TestCase) { for _, adapter := range r.adapters { nm := adapter.Config().Name - cdBuild(adapter) - + + r.setupEnv(adapter) adapter.Evaluate(tcTab[nm]) } + + safeCd(r.ConfigDir()) } -func (r Runner) Evaluate(root string) []TestCase { - units := r.units(root) +func (r Runner) Evaluate() []TestCase { + units := r.units() r.evaluate(units) return units } + +func (r Runner) Clean() { + r.CleanBuildDir() +} diff --git a/stddirs.go b/stddirs.go index adefce8..14776d8 100644 --- a/stddirs.go +++ b/stddirs.go @@ -40,10 +40,13 @@ const ( DEFAULT_PATH_TESTS="tests" ) -type dirConfig struct { - src string - config string - build string +type DirConfig struct { + src string + config string + build string + + // Config falls back to the config found in the parent directory if the env variable hasn't been overridden + pdFallback string } func dieDirAbsent(name, path string) { @@ -63,22 +66,22 @@ func dirFromEnv(name, env string) *string { return nil } -func (c *dirConfig) SetSrcDir(srcDir string) { +func (c *DirConfig) SetSrcDir(srcDir string) { dieDirAbsent("src", srcDir) c.src = srcDir } -func (c *dirConfig) SetConfigDir(configDir string) { +func (c *DirConfig) SetConfigDir(configDir string) { dieDirAbsent("planr (config)", configDir) c.config = configDir } -func (c *dirConfig) SetBuildDir(buildDir string) { +func (c *DirConfig) SetBuildDir(buildDir string) { dieDirAbsent("build", buildDir) c.build = buildDir } -func (c *dirConfig) SetConfigDirFromTree(cdir string) { +func (c *DirConfig) SetConfigDirFromTree(cdir string) { var configDir string found := traverseUp(cdir, func (path string) bool { @@ -94,28 +97,32 @@ func (c *dirConfig) SetConfigDirFromTree(cdir string) { return false }); - if !found { - log.Fatal("Could not find planr directory"); - } - c.config = configDir + if found { + c.pdFallback = configDir + } } -func (c dirConfig) ConfigDir() string { +func (c DirConfig) ConfigDir() string { if c.config != "" { return c.config } - dir := dirFromEnv("config", ENV_CONFIG_DIR) - if dir == nil { - log.Fatal("Could not find directory") + + if dir := dirFromEnv("config", ENV_CONFIG_DIR); dir != nil { + c.config = *dir + return c.config + } + + if c.pdFallback == "" { + log.Fatal("Could not find planr directory"); } - c.config = *dir + c.config = c.pdFallback; return c.config } -func (c dirConfig) SrcDir() string { +func (c DirConfig) SrcDir() string { if c.src != "" { return c.src } @@ -130,7 +137,7 @@ func (c dirConfig) SrcDir() string { return path.Join(dir, DEFAULT_PATH_SRC) } -func (c dirConfig) BuildDir() string { +func (c DirConfig) BuildDir() string { if c.src != "" { return c.src } @@ -144,7 +151,7 @@ func (c dirConfig) BuildDir() string { return path.Join(dir, DEFAULT_PATH_BUILD) } -func (c dirConfig) CleanBuildDir() { +func (c DirConfig) CleanBuildDir() { build := c.BuildDir() if err := os.RemoveAll(build); err != nil { @@ -156,7 +163,7 @@ func (c dirConfig) CleanBuildDir() { } } -func (c dirConfig) MkBuildDir() { +func (c DirConfig) MkBuildDir() { build := c.BuildDir() if err := os.Mkdir(build, 0755); err != nil { @@ -164,13 +171,13 @@ func (c dirConfig) MkBuildDir() { } } -func (c dirConfig) RubricDir() string { +func (c DirConfig) RubricDir() string { rubric := path.Join(c.ConfigDir(), "rubric") dieDirAbsent("rubric", rubric) return rubric } -func (c dirConfig) TestsDir() string { +func (c DirConfig) TestsDir() string { tests := path.Join(c.ConfigDir(), "tests") dieDirAbsent("tests", tests) return tests diff --git a/testcase.go b/testcase.go index 8506b84..7e0bf17 100644 --- a/testcase.go +++ b/testcase.go @@ -1,9 +1,13 @@ package planr +import ( + "log" +) + type TestStatus uint const ( - PASSING TestStatus = iota + PASSING TestStatus = iota COMPILATION_FAILURE RUNTIME_FAILURE ) @@ -15,6 +19,19 @@ type TestResult struct { TestOutput string } +// Program-wide testcase config +type TestCaseConfig struct { + Defaults + Title *string + Description *string +} + +func (c TestCaseConfig) ensureSatisfied(name string) { + if (c.Adapter == nil) { + log.Fatalf("Adapter must be provided for testcase %s", name) + } +} + type TestCase struct { // absolute path to the test case configuration Path string -- cgit v1.2.3 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 --- Makefile | 8 +++++++- adapters/gtest/adapter.go | 4 ++-- adapters/gtest/config.go | 4 ---- cmd/planr/main.go | 4 ++++ cmd/planr/sub/build.go | 2 +- cmd/planr/sub/clean.go | 5 +++++ runner.go | 32 +++++++++++++++++++++++--------- stddirs.go | 41 ++++++++++++++++++++--------------------- 8 files changed, 62 insertions(+), 38 deletions(-) create mode 100644 cmd/planr/sub/clean.go (limited to 'stddirs.go') diff --git a/Makefile b/Makefile index 424c67d..dd6031f 100644 --- a/Makefile +++ b/Makefile @@ -8,8 +8,14 @@ endif CMD := planr +ifdef DEBUG + FLAGS=-ldflags=-w +endif + +MAIN_PKG := ./cmd/planr/main.go + $(CMD): - go build -o $(CMD) ./cmd/planr/main.go + go build $(FLAGS) -o $(CMD) $(MAIN_PKG) install: mkdir -p $(DESTDIR)$(PREFIX)$(BINDIR)/ diff --git a/adapters/gtest/adapter.go b/adapters/gtest/adapter.go index f91a524..29e2df7 100644 --- a/adapters/gtest/adapter.go +++ b/adapters/gtest/adapter.go @@ -19,8 +19,8 @@ const GTEST_CMAKE = "CMakeLists.txt" func makeUnit(tc *planr.TestCase, dirs planr.DirConfig) cmakeUnit { cfg := tc.AdapterConfig().(*GtestConfig) - testpath := path.Join(dirs.TestsDir(), *cfg.Testfile) - srclist := cfg.srcList(dirs.SrcDir()) + testpath := path.Join(dirs.Tests(), *cfg.Testfile) + srclist := cfg.srcList(dirs.Src()) return cmakeUnit { tc.Cname, diff --git a/adapters/gtest/config.go b/adapters/gtest/config.go index bf5c9f2..173809d 100644 --- a/adapters/gtest/config.go +++ b/adapters/gtest/config.go @@ -12,9 +12,7 @@ type GtestDefaults struct { Name *string Suite *string Testfile *string - Test_root *string Srcs *[]string - Srcs_root *string } func (child *GtestDefaults) Inherit(p interface{}) { @@ -23,9 +21,7 @@ func (child *GtestDefaults) Inherit(p interface{}) { if(child.Name == nil) { child.Name = parent.Name } if(child.Suite == nil) { child.Suite = parent.Suite } if(child.Testfile == nil) { child.Testfile = parent.Testfile } - if(child.Test_root == nil) { child.Test_root = parent.Test_root } if(child.Srcs == nil) { child.Srcs = parent.Srcs } - if(child.Srcs_root == nil) { child.Srcs_root = parent.Srcs_root } } 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: diff --git a/cmd/planr/sub/build.go b/cmd/planr/sub/build.go index 066245c..d6e7456 100644 --- a/cmd/planr/sub/build.go +++ b/cmd/planr/sub/build.go @@ -11,7 +11,7 @@ func Runner() planr.Runner { r.RegisterAdapter(>est.GtestAdapter{}) - if wd, err := os.Getwd(); err != nil { + if wd, err := os.Getwd(); err == nil { r.SetConfigDirFromTree(wd) } diff --git a/cmd/planr/sub/clean.go b/cmd/planr/sub/clean.go new file mode 100644 index 0000000..d40e967 --- /dev/null +++ b/cmd/planr/sub/clean.go @@ -0,0 +1,5 @@ +package sub + +func Clean(params []string) { + Runner().Clean() +} diff --git a/runner.go b/runner.go index f2eb8e9..0a6243c 100644 --- a/runner.go +++ b/runner.go @@ -8,7 +8,7 @@ import ( type Runner struct { adapters []Adapter - DirConfig + dirs DirConfig } func (r *Runner) RegisterAdapter(a Adapter) { @@ -47,7 +47,7 @@ func (r Runner) checkConfig(tcs []TestCase) { func (r Runner) setupEnv(adapter Adapter) { nm := adapter.Config().Name - wd := path.Join(r.BuildDir(), nm) + wd := path.Join(r.dirs.Build(), nm) if !directoryExists(wd) { if err := os.Mkdir(wd, 0755); err != nil { @@ -70,18 +70,26 @@ func (r Runner) build(tcs []TestCase) { adapter.Build(tcTab[nm]) } - safeCd(r.ConfigDir()) + safeCd(r.dirs.Config()) +} + +func (r Runner) init_adapters() { + for _, adapter := range r.adapters { + adapter.Init(r.dirs) + } } func (r Runner) units() []TestCase { - return collectUnits(r.RubricDir(), r.adapterCfgs()) + return collectUnits(r.dirs.Rubric(), r.adapterCfgs()) } func (r Runner) Build() { - units := r.units() + r.init_adapters() - if !directoryExists(r.BuildDir()) { - r.MkBuildDir() + units := r.units() + + if !directoryExists(r.dirs.Build()) { + r.dirs.MkBuild() } r.build(units) @@ -97,10 +105,12 @@ func (r Runner) evaluate(tcs []TestCase) { adapter.Evaluate(tcTab[nm]) } - safeCd(r.ConfigDir()) + safeCd(r.dirs.Config()) } func (r Runner) Evaluate() []TestCase { + r.init_adapters() + units := r.units() r.evaluate(units) @@ -109,5 +119,9 @@ func (r Runner) Evaluate() []TestCase { } func (r Runner) Clean() { - r.CleanBuildDir() + r.dirs.CleanBuild() +} + +func (r * Runner) SetConfigDirFromTree(childPath string) { + r.dirs.SetConfigFromTree(childPath) } diff --git a/stddirs.go b/stddirs.go index 14776d8..2385529 100644 --- a/stddirs.go +++ b/stddirs.go @@ -66,22 +66,22 @@ func dirFromEnv(name, env string) *string { return nil } -func (c *DirConfig) SetSrcDir(srcDir string) { +func (c *DirConfig) SetSrc(srcDir string) { dieDirAbsent("src", srcDir) c.src = srcDir } -func (c *DirConfig) SetConfigDir(configDir string) { +func (c *DirConfig) SetConfig(configDir string) { dieDirAbsent("planr (config)", configDir) c.config = configDir } -func (c *DirConfig) SetBuildDir(buildDir string) { +func (c *DirConfig) SetBuild(buildDir string) { dieDirAbsent("build", buildDir) c.build = buildDir } -func (c *DirConfig) SetConfigDirFromTree(cdir string) { +func (c *DirConfig) SetConfigFromTree(cdir string) { var configDir string found := traverseUp(cdir, func (path string) bool { @@ -103,12 +103,11 @@ func (c *DirConfig) SetConfigDirFromTree(cdir string) { } } -func (c DirConfig) ConfigDir() string { +func (c DirConfig) Config() string { if c.config != "" { return c.config } - if dir := dirFromEnv("config", ENV_CONFIG_DIR); dir != nil { c.config = *dir return c.config @@ -122,7 +121,7 @@ func (c DirConfig) ConfigDir() string { return c.config } -func (c DirConfig) SrcDir() string { +func (c DirConfig) Src() string { if c.src != "" { return c.src } @@ -133,11 +132,11 @@ func (c DirConfig) SrcDir() string { } // set path relative to config - dir := c.ConfigDir() + dir := c.Config() return path.Join(dir, DEFAULT_PATH_SRC) } -func (c DirConfig) BuildDir() string { +func (c DirConfig) Build() string { if c.src != "" { return c.src } @@ -147,38 +146,38 @@ func (c DirConfig) BuildDir() string { return c.build } - dir := c.ConfigDir() + dir := c.Config() return path.Join(dir, DEFAULT_PATH_BUILD) } -func (c DirConfig) CleanBuildDir() { - build := c.BuildDir() +func (c DirConfig) CleanBuild() { + build := c.Build() if err := os.RemoveAll(build); err != nil { log.Fatalf("Cannot build directory %v\n", err) } - if err := os.Remove(build); err != nil { - log.Fatalf("Could not remove build directory %v\n", err) - } + // if err := os.Remove(build); err != nil { + // log.Fatalf("Could not remove build directory %v\n", err) + // } } -func (c DirConfig) MkBuildDir() { - build := c.BuildDir() +func (c DirConfig) MkBuild() { + build := c.Build() if err := os.Mkdir(build, 0755); err != nil { log.Fatalf("Could not create build directory %v\n", err) } } -func (c DirConfig) RubricDir() string { - rubric := path.Join(c.ConfigDir(), "rubric") +func (c DirConfig) Rubric() string { + rubric := path.Join(c.Config(), "rubric") dieDirAbsent("rubric", rubric) return rubric } -func (c DirConfig) TestsDir() string { - tests := path.Join(c.ConfigDir(), "tests") +func (c DirConfig) Tests() string { + tests := path.Join(c.Config(), "tests") dieDirAbsent("tests", tests) return tests } -- cgit v1.2.3 From adccaeb36de036904c735ca5face1c929a4ba0b2 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Fri, 3 Sep 2021 00:51:47 -0500 Subject: BUG: Fix decoding when no defaults is present --- adapters/gtest/config.go | 11 +++++++++++ fs.go | 4 +++- stddirs.go | 11 ++++------- 3 files changed, 18 insertions(+), 8 deletions(-) (limited to 'stddirs.go') diff --git a/adapters/gtest/config.go b/adapters/gtest/config.go index 173809d..ba7efb1 100644 --- a/adapters/gtest/config.go +++ b/adapters/gtest/config.go @@ -8,11 +8,16 @@ import ( "path" ) +const ( + DEFAULT_TIMEOUT = 1000 +) + type GtestDefaults struct { Name *string Suite *string Testfile *string Srcs *[]string + Timeout *uint } func (child *GtestDefaults) Inherit(p interface{}) { @@ -22,6 +27,7 @@ func (child *GtestDefaults) Inherit(p interface{}) { if(child.Suite == nil) { child.Suite = parent.Suite } if(child.Testfile == nil) { child.Testfile = parent.Testfile } if(child.Srcs == nil) { child.Srcs = parent.Srcs } + if(child.Timeout == nil) { child.Timeout = parent.Timeout } } @@ -37,6 +43,11 @@ func (g GtestConfig) ensureSatisfied(path string) { } else if g.Testfile == nil { log.Fatalf("\"testfile\" is not defined for unit: %s\n", path) } + + if g.Timeout == nil { + g.Timeout = new(uint) + *g.Timeout = DEFAULT_TIMEOUT; + } } func (cfg GtestConfig) srcList(srcDir string) string { diff --git a/fs.go b/fs.go index ffc5f05..575517c 100644 --- a/fs.go +++ b/fs.go @@ -141,7 +141,9 @@ func collectFromDir( log.Fatalf("Error encountered in %s: %v", child, config) } - config.Inherit(*defaults) + if defaults != nil { + config.Inherit(*defaults) + } tc := TestCase { Path: child, diff --git a/stddirs.go b/stddirs.go index 2385529..e6b510d 100644 --- a/stddirs.go +++ b/stddirs.go @@ -21,13 +21,13 @@ import ( // Env overrides const ( - ENV_CONFIG_DIR="PLANR_PLANR_DIR" - ENV_SRC_DIR="ENV_SRC_DIR" + ENV_CONFIG_DIR="PLANR_CONFIG_DIR" + ENV_SRC_DIR="PLANR_SRC_DIR" ENV_BUILD_DIR="PLANR_BUILD_DIR" ) // Try these search directories -var CONFIG_SEARCH_DIRS = [2] string { +var CONFIG_SEARCH_DIRS = [] string { "planr", ".planr", } @@ -88,7 +88,7 @@ func (c *DirConfig) SetConfigFromTree(cdir string) { for _, dir := range CONFIG_SEARCH_DIRS { configDir = filepath.Join(path, dir) - + if directoryExists(configDir) { return true } @@ -157,9 +157,6 @@ func (c DirConfig) CleanBuild() { log.Fatalf("Cannot build directory %v\n", err) } - // if err := os.Remove(build); err != nil { - // log.Fatalf("Could not remove build directory %v\n", err) - // } } func (c DirConfig) MkBuild() { -- cgit v1.2.3 From d052e22025c386f8071d53252eb49223031f7d65 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Fri, 3 Sep 2021 18:12:38 -0500 Subject: Ensure stddirs returns an absolute path for correct operation in adapter build directories --- stddirs.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'stddirs.go') diff --git a/stddirs.go b/stddirs.go index e6b510d..1eae439 100644 --- a/stddirs.go +++ b/stddirs.go @@ -109,7 +109,7 @@ func (c DirConfig) Config() string { } if dir := dirFromEnv("config", ENV_CONFIG_DIR); dir != nil { - c.config = *dir + c.config = abs(*dir) return c.config } @@ -117,7 +117,7 @@ func (c DirConfig) Config() string { log.Fatal("Could not find planr directory"); } - c.config = c.pdFallback; + c.config = abs(c.pdFallback); return c.config } @@ -136,6 +136,16 @@ func (c DirConfig) Src() string { return path.Join(dir, DEFAULT_PATH_SRC) } +func abs(path string) string { + apath, err := filepath.Abs(path) + + if err != nil { + log.Fatalf("Could not find path %s", path) + } + + return apath +} + func (c DirConfig) Build() string { if c.src != "" { return c.src @@ -168,13 +178,13 @@ func (c DirConfig) MkBuild() { } func (c DirConfig) Rubric() string { - rubric := path.Join(c.Config(), "rubric") + rubric := path.Join(c.Config(), DEFAULT_PATH_RUBRIC) dieDirAbsent("rubric", rubric) return rubric } func (c DirConfig) Tests() string { - tests := path.Join(c.Config(), "tests") + tests := path.Join(c.Config(), DEFAULT_PATH_TESTS) dieDirAbsent("tests", tests) return tests } -- 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 'stddirs.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