From 96701f87a114557f1a013229e889b4b726aa7dc1 Mon Sep 17 00:00:00 2001 From: Flu0r1ne 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 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