aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlu0r1ne <flur01ne@flu0r1ne.net>2021-09-02 02:16:20 -0500
committerFlu0r1ne <flur01ne@flu0r1ne.net>2021-09-02 02:16:20 -0500
commit96701f87a114557f1a013229e889b4b726aa7dc1 (patch)
treef1952b1322c3cb8aa3664a284a68033d2c9e2762
parent582f4847fc388d8a64eb00143d4ffdd98a13aef0 (diff)
downloadplanr-96701f87a114557f1a013229e889b4b726aa7dc1.tar.xz
planr-96701f87a114557f1a013229e889b4b726aa7dc1.zip
Break searching / error handling for standard directory structure into auxiliary file / struct
-rw-r--r--stddirs.go177
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
+}