Test and document current behavior of file() includes

At present, we don't make a file() include relative to the
file doing the including. This is discussed in #202.
We should most likely change this behavior, but this
commit documents and tests it.
This commit is contained in:
Havoc Pennington 2015-03-05 17:10:40 -05:00
parent f2ce57af42
commit 8c310ef5e8
9 changed files with 40 additions and 0 deletions

View File

@ -1095,6 +1095,11 @@ Implementations need not support files, Java resources, or URLs;
and they need not support particular URL protocols. However, if and they need not support particular URL protocols. However, if
they do support them they should do so as described above. they do support them they should do so as described above.
Note that at present, if `url()`/`file()`/`classpath()` are
specified, the included items are NOT interpreted relative to the
including items. Relative-to-including-file paths only work with
the heuristic `include "foo.conf"`. This may change in the future.
### Conversion of numerically-indexed objects to arrays ### Conversion of numerically-indexed objects to arrays
In some file formats and contexts, such as Java properties files, In some file formats and contexts, such as Java properties files,

View File

@ -594,8 +594,10 @@ public abstract class Parseable implements ConfigParseable {
if (sibling == null) if (sibling == null)
return null; return null;
if (sibling.exists()) { if (sibling.exists()) {
trace(sibling + " exists, so loading it as a file");
return newFile(sibling, options().setOriginDescription(null)); return newFile(sibling, options().setOriginDescription(null));
} else { } else {
trace(sibling + " does not exist, so trying it as a classpath resource");
return super.relativeTo(filename); return super.relativeTo(filename);
} }
} }

View File

@ -24,6 +24,8 @@ class SimpleIncludeContext implements ConfigIncludeContext {
@Override @Override
public ConfigParseable relativeTo(String filename) { public ConfigParseable relativeTo(String filename) {
if (ConfigImpl.traceLoadsEnabled())
ConfigImpl.trace("Looking for '" + filename + "' relative to " + parseable);
if (parseable != null) if (parseable != null)
return parseable.relativeTo(filename); return parseable.relativeTo(filename);
else else

View File

@ -0,0 +1,5 @@
base=41
# included without file() in a subdir
include "subdir/foo.conf"
# included using file() in a subdir
include file("subdir/baz.conf")

View File

@ -0,0 +1 @@
bar-file=44

View File

@ -0,0 +1 @@
bar=43

View File

@ -0,0 +1 @@
baz=45

View File

@ -0,0 +1,5 @@
foo=42
# included without file()
include "bar.conf"
# included using file()
include file("bar-file.conf")

View File

@ -1039,4 +1039,22 @@ include "onclasspath"
assertEquals(42, conf.getInt("onclasspath")) assertEquals(42, conf.getInt("onclasspath"))
} }
} }
@Test
def fileIncludeStatements(): Unit = {
val file = resourceFile("file-include.conf")
val conf = ConfigFactory.parseFile(file)
assertEquals("got file-include.conf", 41, conf.getInt("base"))
assertEquals("got subdir/foo.conf", 42, conf.getInt("foo"))
assertEquals("got bar.conf", 43, conf.getInt("bar"))
// these two do not work right now, because we do not
// treat the filename as relative to the including file
// if file() is specified, so `include file("bar-file.conf")`
// fails.
//assertEquals("got bar-file.conf", 44, conf.getInt("bar-file"))
//assertEquals("got subdir/baz.conf", 45, conf.getInt("baz"))
assertFalse("did not get bar-file.conf", conf.hasPath("bar-file"))
assertFalse("did not get subdir/baz.conf", conf.hasPath("baz"))
}
} }