diff options
| -rw-r--r-- | stddirs.go | 177 | 
1 files changed, 177 insertions, 0 deletions
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 +}  | 
