From 65f1614b4084be2f1cea18421de442e1667b92cf Mon Sep 17 00:00:00 2001 From: workanator Date: Fri, 17 Mar 2017 15:04:59 +0500 Subject: [PATCH 1/6] Add #include and #require directives --- Doc/AUTHORS.md | 2 +- Doc/CONTRIBUTORS.md | 2 +- Doc/NEWS.md | 5 +- README.md | 26 +++++++- read.go | 151 ++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 171 insertions(+), 15 deletions(-) diff --git a/Doc/AUTHORS.md b/Doc/AUTHORS.md index fb97cdc..cbc13f3 100644 --- a/Doc/AUTHORS.md +++ b/Doc/AUTHORS.md @@ -12,8 +12,8 @@ explanation.* * * * +[Andrew Bashkatov](https://github.com/workanator) [Jonas mg](https://github.com/kless) [Miguel Branco](https://github.com/msbranco) [Rob Figueiredo](https://github.com/robfig) [Tom Bruggeman](https://github.com/tmbrggmn) - diff --git a/Doc/CONTRIBUTORS.md b/Doc/CONTRIBUTORS.md index 14d36da..f00469d 100644 --- a/Doc/CONTRIBUTORS.md +++ b/Doc/CONTRIBUTORS.md @@ -23,6 +23,6 @@ because the organization holds the copyright.* ### Other authors +[Andrew Bashkatov](https://github.com/workanator) [Jonas mg](https://github.com/kless) [Tom Bruggeman](https://github.com/tmbrggmn) - diff --git a/Doc/NEWS.md b/Doc/NEWS.md index 7d59d09..2b1e649 100644 --- a/Doc/NEWS.md +++ b/Doc/NEWS.md @@ -12,6 +12,10 @@ * * * +### 2017-03-17 v0.10.0 + ++ Support for #include and #require directives. + ### 2011-??-?? v0.9.6 + Changed to line comments. @@ -49,4 +53,3 @@ comment and separator, and the spaces around separator. after of each new line. + Better documentation. - diff --git a/README.md b/README.md index 8a6f0c6..a38d8bd 100644 --- a/README.md +++ b/README.md @@ -81,10 +81,34 @@ This results in the file: Note that sections, options and values are all case-sensitive. +## Configuration loader directives + +The loader which is responsible for loading configuration files supports +some directives which can be handy in some situations, .e.g in case +multi-file configuration is used. + +Directives are started with hash `#` and followed with the name of the +directive and zero, one or many arguments. For example, +`#include extra/user.cfg`. + +### Including files + +The loader can be instructed to load other configuration file(s). Those +directives tells the loader which file to load and how. + +* `#include ` instructs the loader to load the file if it's found. +* `#require ` instructs the loader to load the file and if it does not +exist loading of the configuration will fail. + +Here `` is the relative or absolute path to the file which should be +loaded, e.g. `#require db.cfg`, `#include /etc/my_tool/extra.cfg`. + +Please notice that all relative paths are relative to the main file path, +this path you passed into `config.Read()` or `config.ReadDefault()`. + ## License The source files are distributed under the [Mozilla Public License, version 2.0](http://mozilla.org/MPL/2.0/), unless otherwise noted. Please read the [FAQ](http://www.mozilla.org/MPL/2.0/FAQ.html) if you have further questions regarding the license. - diff --git a/read.go b/read.go index 595d6d9..ede7e55 100644 --- a/read.go +++ b/read.go @@ -18,44 +18,162 @@ import ( "bufio" "errors" "os" + "path/filepath" + "regexp" "strings" "unicode" ) -// _read is the base to read a file and get the configuration representation. +var ( + // The regexp is for matching include file directive + reIncludeFile = regexp.MustCompile(`^#include\s+(.+?)\s*$`) + // The regexp is for matching require file directive + reRequireFile = regexp.MustCompile(`^#require\s+(.+?)\s*$`) +) + +// configFile identifies a file which should be read. +type configFile struct { + Path string + Required bool + Read bool +} + +// fileList is the list of files to read. +type fileList []*configFile + +// pushFile converts the path into the absolute path and pushes the file +// into the list if it does not contain the same absolute path already. +// All relative paths are relative to the main file which is the first +// file in the list. +func (list *fileList) pushFile(path string, required bool) error { + var ( + absPath string + err error + ) + + // Convert the path into the absolute path + if !filepath.IsAbs(path) { + // Make the path relative to the main file + var relPath string + if len(*list) > 0 { + // Join the relative path with the main file path + relPath = filepath.Join(filepath.Dir((*list)[0].Path), path) + } else { + relPath = path + } + + if absPath, err = filepath.Abs(relPath); err != nil { + return err + } + } else { + absPath = path + } + + // Test the file with the absolute path exists in the list + for _, file := range *list { + if file.Path == absPath { + return nil + } + } + + // Push the new file to the list + *list = append(*list, &configFile{ + Path: absPath, + Required: required, + Read: false, + }) + + return nil +} + +// includeFile is the shorthand for pushFile(path, false) +func (list *fileList) includeFile(path string) error { + return list.pushFile(path, false) +} + +// requireFile is the shorthand for pushFile(path, true) +func (list *fileList) requireFile(path string) error { + return list.pushFile(path, true) +} + +// _read reads file list +func _read(c *Config, list *fileList) (*Config, error) { + // Pass through the list untill all files are read + for { + hasUnread := false + + // Go through the list and read files + for _, file := range *list { + if !file.Read { + if err := _readFile(file.Path, file.Required, c, list); err != nil { + return nil, err + } + + file.Read = true + hasUnread = true + } + } + + // Exit the loop because all files are read + if !hasUnread { + break + } + } + + return c, nil +} + +// _readFile is the base to read a file and get the configuration representation. // That representation can be queried with GetString, etc. -func _read(fname string, c *Config) (*Config, error) { +func _readFile(fname string, require bool, c *Config, list *fileList) error { file, err := os.Open(fname) if err != nil { - return nil, err + // Return the error in case the file required so the further loading + // will fail and teh error will be reported back. + if require { + return err + } + + // Otherwise, if the file is not required, just skip loading it. + return nil } - if err = c.read(bufio.NewReader(file)); err != nil { - return nil, err + // Defer closing the file so we can be sure the underlying file handle + // will be closed in any case. + defer file.Close() + + if err = c.read(bufio.NewReader(file), list); err != nil { + return err } if err = file.Close(); err != nil { - return nil, err + return err } - return c, nil + return nil } // Read reads a configuration file and returns its representation. // All arguments, except `fname`, are related to `New()` func Read(fname string, comment, separator string, preSpace, postSpace bool) (*Config, error) { - return _read(fname, New(comment, separator, preSpace, postSpace)) + list := &fileList{} + list.requireFile(fname) + + return _read(New(comment, separator, preSpace, postSpace), list) } // ReadDefault reads a configuration file and returns its representation. // It uses values by default. func ReadDefault(fname string) (*Config, error) { - return _read(fname, NewDefault()) + list := &fileList{} + list.requireFile(fname) + + return _read(NewDefault(), list) } // * * * -func (c *Config) read(buf *bufio.Reader) (err error) { +func (c *Config) read(buf *bufio.Reader, list *fileList) (err error) { var section, option string var scanner = bufio.NewScanner(buf) for scanner.Scan() { @@ -64,9 +182,20 @@ func (c *Config) read(buf *bufio.Reader) (err error) { // Switch written for readability (not performance) switch { // Empty line and comments - case len(l) == 0, l[0] == '#', l[0] == ';': + case len(l) == 0, l[0] == ';': continue + // Comments starting with ; + case l[0] == '#': + // Test for possible directives + if matches := reIncludeFile.FindStringSubmatch(l); matches != nil { + list.includeFile(matches[1]) + } else if matches := reRequireFile.FindStringSubmatch(l); matches != nil { + list.requireFile(matches[1]) + } else { + continue + } + // New section. The [ must be at the start of the line case l[0] == '[' && l[len(l)-1] == ']': option = "" // reset multi-line value From 228485b70d8091f983fd68ec0993f9e62dd82ec7 Mon Sep 17 00:00:00 2001 From: workanator Date: Fri, 17 Mar 2017 15:05:17 +0500 Subject: [PATCH 2/6] Add more tests --- all_test.go | 42 +++++++++++++++++++++++++++++---- testdata/failed_abs_require.cfg | 2 ++ testdata/failed_include.cfg | 5 ++++ testdata/failed_require.cfg | 5 ++++ testdata/target.cfg | 17 ++++--------- testdata/targets/X.cfg | 9 +++++++ testdata/targets/Y.cfg | 11 +++++++++ 7 files changed, 73 insertions(+), 18 deletions(-) create mode 100644 testdata/failed_abs_require.cfg create mode 100644 testdata/failed_include.cfg create mode 100644 testdata/failed_require.cfg create mode 100644 testdata/targets/X.cfg create mode 100644 testdata/targets/Y.cfg diff --git a/all_test.go b/all_test.go index 571f99e..3c3f25d 100644 --- a/all_test.go +++ b/all_test.go @@ -23,9 +23,12 @@ import ( ) const ( - tmpFilename = "testdata/__test.go" - sourceFilename = "testdata/source.cfg" - targetFilename = "testdata/target.cfg" + tmpFilename = "testdata/__test.go" + sourceFilename = "testdata/source.cfg" + targetFilename = "testdata/target.cfg" + failedRequireFilename = "testdata/failed_require.cfg" + failedAbsRequireFilename = "testdata/failed_abs_require.cfg" + failedIncludeFilename = "testdata/failed_include.cfg" ) func testGet(t *testing.T, c *Config, section string, option string, @@ -364,12 +367,12 @@ func TestSectionOptions(t *testing.T) { func TestMerge(t *testing.T) { target, error := ReadDefault(targetFilename) if error != nil { - t.Fatalf("Unable to read target config file '%s'", targetFilename) + t.Fatalf("Unable to read target config file '%s' because %s", targetFilename, error) } source, error := ReadDefault(sourceFilename) if error != nil { - t.Fatalf("Unable to read source config file '%s'", sourceFilename) + t.Fatalf("Unable to read source config file '%s' because %s", sourceFilename, error) } target.Merge(source) @@ -398,3 +401,32 @@ func TestMerge(t *testing.T) { t.Errorf("Expected '[X] x.four' to be 'x4' but instead it was '%s'", result) } } + +// TestFailedRequirement tests loading file with invalid #require +func TestFailedRequirement(t *testing.T) { + _, error := ReadDefault(failedRequireFilename) + if error != nil { + t.Logf("Unable to read config file '%s' because %s", failedRequireFilename, error) + } else { + t.Errorf("Load of config file '%s' must fail", failedRequireFilename) + } +} + +// TestFailedInclude tests loading file with invalid #include +func TestFailedInclude(t *testing.T) { + _, error := ReadDefault(failedIncludeFilename) + if error != nil { + t.Errorf("Unable to read config file '%s' because %s", failedIncludeFilename, error) + } +} + +// TestFailedAbsRequirement tests loading file with invalid #require with +// absolute path +func TestFailedAbsRequirement(t *testing.T) { + _, error := Read(failedAbsRequireFilename, DEFAULT_COMMENT, DEFAULT_SEPARATOR, false, false) + if error != nil { + t.Logf("Unable to read config file '%s' because %s", failedAbsRequireFilename, error) + } else { + t.Errorf("Load of config file '%s' must fail", failedAbsRequireFilename) + } +} diff --git a/testdata/failed_abs_require.cfg b/testdata/failed_abs_require.cfg new file mode 100644 index 0000000..7051ab6 --- /dev/null +++ b/testdata/failed_abs_require.cfg @@ -0,0 +1,2 @@ +; Just try to load file with invalid absolute path. +#require /targets/X.cfg diff --git a/testdata/failed_include.cfg b/testdata/failed_include.cfg new file mode 100644 index 0000000..6851a97 --- /dev/null +++ b/testdata/failed_include.cfg @@ -0,0 +1,5 @@ +[Some] +value1=1 +value2=TWO + +#include this_file_does_not_exists.cfg diff --git a/testdata/failed_require.cfg b/testdata/failed_require.cfg new file mode 100644 index 0000000..2a81000 --- /dev/null +++ b/testdata/failed_require.cfg @@ -0,0 +1,5 @@ +[Some] +value1=1 +value2=TWO + +#require this_file_does_not_exists.cfg diff --git a/testdata/target.cfg b/testdata/target.cfg index 1ecf025..de2662b 100644 --- a/testdata/target.cfg +++ b/testdata/target.cfg @@ -1,19 +1,10 @@ +; Require the file target_Y.cfg to included and the file on load will +; inform the loader to load the file targets/X.cfg +#require targets/Y.cfg + one=1 two=2 three=3 five=5 two_+_three=%(two)s + %(three)s - -[X] -x.one=x1 -x.two=x2 -x.three=x3 -x.four=x4 - -[Y] -y.one=y1 -y.two=y2 -y.three=y3 -y.four=y4 - diff --git a/testdata/targets/X.cfg b/testdata/targets/X.cfg new file mode 100644 index 0000000..ab0597c --- /dev/null +++ b/testdata/targets/X.cfg @@ -0,0 +1,9 @@ +; This is a circular reference. +; Remember relative paths are relative to the main file. +#require targets/Y.cfg + +[X] +x.one=x1 +x.two=x2 +x.three=x3 +x.four=x4 diff --git a/testdata/targets/Y.cfg b/testdata/targets/Y.cfg new file mode 100644 index 0000000..de300b5 --- /dev/null +++ b/testdata/targets/Y.cfg @@ -0,0 +1,11 @@ +; Remember relative paths are relative to the main file. +#require targets/X.cfg + +; Try to require self +#require targets/Y.cfg + +[Y] +y.one=y1 +y.two=y2 +y.three=y3 +y.four=y4 From 4091939bc88fd1e7f85cc9197d46da142aa4207b Mon Sep 17 00:00:00 2001 From: workanator Date: Fri, 17 Mar 2017 17:11:05 +0500 Subject: [PATCH 3/6] Add glob support --- Doc/NEWS.md | 2 ++ README.md | 3 ++- read.go | 35 +++++++++++++++++++++++++---------- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/Doc/NEWS.md b/Doc/NEWS.md index 2b1e649..07042d5 100644 --- a/Doc/NEWS.md +++ b/Doc/NEWS.md @@ -16,6 +16,8 @@ + Support for #include and #require directives. ++ #include and #require supports globs. + ### 2011-??-?? v0.9.6 + Changed to line comments. diff --git a/README.md b/README.md index a38d8bd..efb9e06 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,8 @@ directives tells the loader which file to load and how. exist loading of the configuration will fail. Here `` is the relative or absolute path to the file which should be -loaded, e.g. `#require db.cfg`, `#include /etc/my_tool/extra.cfg`. +loaded, e.g. `#require db.cfg`, `#include /etc/my_tool/extra.cfg`. The path +can contain globs (or wildcards), e.g. `#include user/*.cfg`. Please notice that all relative paths are relative to the main file path, this path you passed into `config.Read()` or `config.ReadDefault()`. diff --git a/read.go b/read.go index ede7e55..04d05a4 100644 --- a/read.go +++ b/read.go @@ -25,6 +25,8 @@ import ( ) var ( + // The regexp test if the path contains globs * and/or ? + reGlob = regexp.MustCompile(`[\*\?]`) // The regexp is for matching include file directive reIncludeFile = regexp.MustCompile(`^#include\s+(.+?)\s*$`) // The regexp is for matching require file directive @@ -69,19 +71,32 @@ func (list *fileList) pushFile(path string, required bool) error { absPath = path } - // Test the file with the absolute path exists in the list - for _, file := range *list { - if file.Path == absPath { - return nil + // Make the list of file candidates to include + var candidates []string + if reGlob.MatchString(absPath) { + candidates, err = filepath.Glob(absPath) + if err != nil { + return err } + } else { + candidates = []string{absPath} } - // Push the new file to the list - *list = append(*list, &configFile{ - Path: absPath, - Required: required, - Read: false, - }) + for _, candidate := range candidates { + // Test the file with the absolute path exists in the list + for _, file := range *list { + if file.Path == candidate { + return nil + } + } + + // Push the new file to the list + *list = append(*list, &configFile{ + Path: candidate, + Required: required, + Read: false, + }) + } return nil } From 8b602bd9962a5fe4f4725982053decc46b509c2e Mon Sep 17 00:00:00 2001 From: workanator Date: Fri, 17 Mar 2017 17:11:29 +0500 Subject: [PATCH 4/6] Use glob in #require --- testdata/target.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testdata/target.cfg b/testdata/target.cfg index de2662b..5f44c0c 100644 --- a/testdata/target.cfg +++ b/testdata/target.cfg @@ -1,6 +1,6 @@ ; Require the file target_Y.cfg to included and the file on load will -; inform the loader to load the file targets/X.cfg -#require targets/Y.cfg +; inform the loader to load all configurations files in targets subdirectory. +#require targets/*.cfg one=1 two=2 From 897a0c673ba9d318439adcad87d4424c14867bdd Mon Sep 17 00:00:00 2001 From: workanator Date: Mon, 20 Mar 2017 09:12:21 +0500 Subject: [PATCH 5/6] Leave only #include directive --- Doc/NEWS.md | 2 +- README.md | 19 +++++++++---------- read.go | 45 +++++++++++---------------------------------- 3 files changed, 21 insertions(+), 45 deletions(-) diff --git a/Doc/NEWS.md b/Doc/NEWS.md index 07042d5..1116f40 100644 --- a/Doc/NEWS.md +++ b/Doc/NEWS.md @@ -14,7 +14,7 @@ ### 2017-03-17 v0.10.0 -+ Support for #include and #require directives. ++ Support for #include directive. + #include and #require supports globs. diff --git a/README.md b/README.md index efb9e06..9cb68aa 100644 --- a/README.md +++ b/README.md @@ -93,19 +93,18 @@ directive and zero, one or many arguments. For example, ### Including files -The loader can be instructed to load other configuration file(s). Those -directives tells the loader which file to load and how. - -* `#include ` instructs the loader to load the file if it's found. -* `#require ` instructs the loader to load the file and if it does not -exist loading of the configuration will fail. - -Here `` is the relative or absolute path to the file which should be -loaded, e.g. `#require db.cfg`, `#include /etc/my_tool/extra.cfg`. The path +The loader can be instructed to load other configuration file(s) with +directive `#include`. The directive requires loading files to exist what +means if the loader fails loading one of including files it will fail +loading the whole configuration. + +The syntax of the directive is `#include ` where `` is the relative +or absolute path to the file which should be loaded, +e.g. `#include db.cfg`, `#include /etc/my_tool/extra.cfg`. The path can contain globs (or wildcards), e.g. `#include user/*.cfg`. Please notice that all relative paths are relative to the main file path, -this path you passed into `config.Read()` or `config.ReadDefault()`. +the path you passed into `config.Read()` or `config.ReadDefault()`. ## License diff --git a/read.go b/read.go index 04d05a4..99e4490 100644 --- a/read.go +++ b/read.go @@ -29,15 +29,12 @@ var ( reGlob = regexp.MustCompile(`[\*\?]`) // The regexp is for matching include file directive reIncludeFile = regexp.MustCompile(`^#include\s+(.+?)\s*$`) - // The regexp is for matching require file directive - reRequireFile = regexp.MustCompile(`^#require\s+(.+?)\s*$`) ) // configFile identifies a file which should be read. type configFile struct { - Path string - Required bool - Read bool + Path string + Read bool } // fileList is the list of files to read. @@ -47,7 +44,7 @@ type fileList []*configFile // into the list if it does not contain the same absolute path already. // All relative paths are relative to the main file which is the first // file in the list. -func (list *fileList) pushFile(path string, required bool) error { +func (list *fileList) pushFile(path string) error { var ( absPath string err error @@ -92,25 +89,14 @@ func (list *fileList) pushFile(path string, required bool) error { // Push the new file to the list *list = append(*list, &configFile{ - Path: candidate, - Required: required, - Read: false, + Path: candidate, + Read: false, }) } return nil } -// includeFile is the shorthand for pushFile(path, false) -func (list *fileList) includeFile(path string) error { - return list.pushFile(path, false) -} - -// requireFile is the shorthand for pushFile(path, true) -func (list *fileList) requireFile(path string) error { - return list.pushFile(path, true) -} - // _read reads file list func _read(c *Config, list *fileList) (*Config, error) { // Pass through the list untill all files are read @@ -120,7 +106,7 @@ func _read(c *Config, list *fileList) (*Config, error) { // Go through the list and read files for _, file := range *list { if !file.Read { - if err := _readFile(file.Path, file.Required, c, list); err != nil { + if err := _readFile(file.Path, c, list); err != nil { return nil, err } @@ -140,17 +126,10 @@ func _read(c *Config, list *fileList) (*Config, error) { // _readFile is the base to read a file and get the configuration representation. // That representation can be queried with GetString, etc. -func _readFile(fname string, require bool, c *Config, list *fileList) error { +func _readFile(fname string, c *Config, list *fileList) error { file, err := os.Open(fname) if err != nil { - // Return the error in case the file required so the further loading - // will fail and teh error will be reported back. - if require { - return err - } - - // Otherwise, if the file is not required, just skip loading it. - return nil + return err } // Defer closing the file so we can be sure the underlying file handle @@ -172,7 +151,7 @@ func _readFile(fname string, require bool, c *Config, list *fileList) error { // All arguments, except `fname`, are related to `New()` func Read(fname string, comment, separator string, preSpace, postSpace bool) (*Config, error) { list := &fileList{} - list.requireFile(fname) + list.pushFile(fname) return _read(New(comment, separator, preSpace, postSpace), list) } @@ -181,7 +160,7 @@ func Read(fname string, comment, separator string, preSpace, postSpace bool) (*C // It uses values by default. func ReadDefault(fname string) (*Config, error) { list := &fileList{} - list.requireFile(fname) + list.pushFile(fname) return _read(NewDefault(), list) } @@ -204,9 +183,7 @@ func (c *Config) read(buf *bufio.Reader, list *fileList) (err error) { case l[0] == '#': // Test for possible directives if matches := reIncludeFile.FindStringSubmatch(l); matches != nil { - list.includeFile(matches[1]) - } else if matches := reRequireFile.FindStringSubmatch(l); matches != nil { - list.requireFile(matches[1]) + list.pushFile(matches[1]) } else { continue } From fe92a66f9d8af4dca3e2f061c8fad67a1b85902d Mon Sep 17 00:00:00 2001 From: workanator Date: Mon, 20 Mar 2017 09:12:40 +0500 Subject: [PATCH 6/6] Remore #require from testing --- all_test.go | 36 ++++++++----------- ...abs_require.cfg => failed_abs_include.cfg} | 2 +- ...led_include.cfg => failed_rel_include.cfg} | 0 testdata/failed_require.cfg | 5 --- testdata/target.cfg | 4 +-- testdata/targets/X.cfg | 2 +- testdata/targets/Y.cfg | 4 +-- 7 files changed, 20 insertions(+), 33 deletions(-) rename testdata/{failed_abs_require.cfg => failed_abs_include.cfg} (68%) rename testdata/{failed_include.cfg => failed_rel_include.cfg} (100%) delete mode 100644 testdata/failed_require.cfg diff --git a/all_test.go b/all_test.go index 3c3f25d..c66c050 100644 --- a/all_test.go +++ b/all_test.go @@ -26,9 +26,8 @@ const ( tmpFilename = "testdata/__test.go" sourceFilename = "testdata/source.cfg" targetFilename = "testdata/target.cfg" - failedRequireFilename = "testdata/failed_require.cfg" - failedAbsRequireFilename = "testdata/failed_abs_require.cfg" - failedIncludeFilename = "testdata/failed_include.cfg" + failedAbsIncludeFilename = "testdata/failed_abs_include.cfg" + failedRelIncludeFilename = "testdata/failed_rel_include.cfg" ) func testGet(t *testing.T, c *Config, section string, option string, @@ -402,31 +401,24 @@ func TestMerge(t *testing.T) { } } -// TestFailedRequirement tests loading file with invalid #require -func TestFailedRequirement(t *testing.T) { - _, error := ReadDefault(failedRequireFilename) +// TestFailedAbsInclude tests loading file with invalid #include with +// absolute path +func TestFailedAbsInclude(t *testing.T) { + _, error := Read(failedAbsIncludeFilename, DEFAULT_COMMENT, DEFAULT_SEPARATOR, false, false) if error != nil { - t.Logf("Unable to read config file '%s' because %s", failedRequireFilename, error) + t.Logf("Unable to read config file '%s' because %s", failedAbsIncludeFilename, error) } else { - t.Errorf("Load of config file '%s' must fail", failedRequireFilename) - } -} - -// TestFailedInclude tests loading file with invalid #include -func TestFailedInclude(t *testing.T) { - _, error := ReadDefault(failedIncludeFilename) - if error != nil { - t.Errorf("Unable to read config file '%s' because %s", failedIncludeFilename, error) + t.Errorf("Load of config file '%s' must fail", failedAbsIncludeFilename) } } -// TestFailedAbsRequirement tests loading file with invalid #require with -// absolute path -func TestFailedAbsRequirement(t *testing.T) { - _, error := Read(failedAbsRequireFilename, DEFAULT_COMMENT, DEFAULT_SEPARATOR, false, false) +// TestFailedRelInclude tests loading file with invalid #include with +// relative path +func TestFailedRelInclude(t *testing.T) { + _, error := ReadDefault(failedRelIncludeFilename) if error != nil { - t.Logf("Unable to read config file '%s' because %s", failedAbsRequireFilename, error) + t.Logf("Unable to read config file '%s' because %s", failedRelIncludeFilename, error) } else { - t.Errorf("Load of config file '%s' must fail", failedAbsRequireFilename) + t.Errorf("Load of config file '%s' must fail", failedRelIncludeFilename) } } diff --git a/testdata/failed_abs_require.cfg b/testdata/failed_abs_include.cfg similarity index 68% rename from testdata/failed_abs_require.cfg rename to testdata/failed_abs_include.cfg index 7051ab6..37e7453 100644 --- a/testdata/failed_abs_require.cfg +++ b/testdata/failed_abs_include.cfg @@ -1,2 +1,2 @@ ; Just try to load file with invalid absolute path. -#require /targets/X.cfg +#include /targets/X.cfg diff --git a/testdata/failed_include.cfg b/testdata/failed_rel_include.cfg similarity index 100% rename from testdata/failed_include.cfg rename to testdata/failed_rel_include.cfg diff --git a/testdata/failed_require.cfg b/testdata/failed_require.cfg deleted file mode 100644 index 2a81000..0000000 --- a/testdata/failed_require.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[Some] -value1=1 -value2=TWO - -#require this_file_does_not_exists.cfg diff --git a/testdata/target.cfg b/testdata/target.cfg index 5f44c0c..c83360e 100644 --- a/testdata/target.cfg +++ b/testdata/target.cfg @@ -1,6 +1,6 @@ -; Require the file target_Y.cfg to included and the file on load will +; Include the file target_Y.cfg to included and the file on load will ; inform the loader to load all configurations files in targets subdirectory. -#require targets/*.cfg +#include targets/*.cfg one=1 two=2 diff --git a/testdata/targets/X.cfg b/testdata/targets/X.cfg index ab0597c..e3fc676 100644 --- a/testdata/targets/X.cfg +++ b/testdata/targets/X.cfg @@ -1,6 +1,6 @@ ; This is a circular reference. ; Remember relative paths are relative to the main file. -#require targets/Y.cfg +#include targets/Y.cfg [X] x.one=x1 diff --git a/testdata/targets/Y.cfg b/testdata/targets/Y.cfg index de300b5..c3117c1 100644 --- a/testdata/targets/Y.cfg +++ b/testdata/targets/Y.cfg @@ -1,8 +1,8 @@ ; Remember relative paths are relative to the main file. -#require targets/X.cfg +#include targets/X.cfg ; Try to require self -#require targets/Y.cfg +#include targets/Y.cfg [Y] y.one=y1