Browse Source

FileBasedConfig: support for relative includes

Relative include.path are now resolved against the config's parent
directory. include.path starting with ~/ are resolved against the
user's home directory

Change-Id: I91911ef404126618b1ddd3589294824a0ad919e6
Signed-off-by: Marc Strapetz <marc.strapetz@syntevo.com>
stable-4.10
Marc Strapetz 7 years ago committed by Matthias Sohn
parent
commit
26d78902f8
  1. 2
      org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
  2. 85
      org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/FileBasedConfigTest.java
  3. 30
      org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java

2
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java

@ -855,7 +855,7 @@ public class ConfigTest {
assertEquals("bar", parsed.getString("other", null, "more")); assertEquals("bar", parsed.getString("other", null, "more"));
} }
private static String pathToString(File file) { public static String pathToString(File file) {
final String path = file.getPath(); final String path = file.getPath();
if (SystemReader.getInstance().isWindows()) { if (SystemReader.getInstance().isWindows()) {
return path.replace('\\', '/'); return path.replace('\\', '/');

85
org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/FileBasedConfigTest.java

@ -52,6 +52,7 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.ConfigTest;
import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils; import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.IO;
@ -157,9 +158,89 @@ public class FileBasedConfigTest {
assertArrayEquals(bos2.toByteArray(), IO.readFully(file)); assertArrayEquals(bos2.toByteArray(), IO.readFully(file));
} }
@Test
public void testIncludeAbsolute()
throws IOException, ConfigInvalidException {
final File includedFile = createFile(CONTENT1.getBytes());
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write("[include]\npath=".getBytes());
bos.write(ConfigTest.pathToString(includedFile).getBytes());
final File file = createFile(bos.toByteArray());
final FileBasedConfig config = new FileBasedConfig(file, FS.DETECTED);
config.load();
assertEquals(ALICE, config.getString(USER, null, NAME));
}
@Test
public void testIncludeRelativeDot()
throws IOException, ConfigInvalidException {
final File includedFile = createFile(CONTENT1.getBytes(), "dir1");
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write("[include]\npath=".getBytes());
bos.write(("./" + includedFile.getName()).getBytes());
final File file = createFile(bos.toByteArray(), "dir1");
final FileBasedConfig config = new FileBasedConfig(file, FS.DETECTED);
config.load();
assertEquals(ALICE, config.getString(USER, null, NAME));
}
@Test
public void testIncludeRelativeDotDot()
throws IOException, ConfigInvalidException {
final File includedFile = createFile(CONTENT1.getBytes(), "dir1");
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write("[include]\npath=".getBytes());
bos.write(("../" + includedFile.getParentFile().getName() + "/"
+ includedFile.getName()).getBytes());
final File file = createFile(bos.toByteArray(), "dir2");
final FileBasedConfig config = new FileBasedConfig(file, FS.DETECTED);
config.load();
assertEquals(ALICE, config.getString(USER, null, NAME));
}
@Test
public void testIncludeRelativeDotDotNotFound()
throws IOException, ConfigInvalidException {
final File includedFile = createFile(CONTENT1.getBytes());
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write("[include]\npath=".getBytes());
bos.write(("../" + includedFile.getName()).getBytes());
final File file = createFile(bos.toByteArray());
final FileBasedConfig config = new FileBasedConfig(file, FS.DETECTED);
config.load();
assertEquals(null, config.getString(USER, null, NAME));
}
@Test
public void testIncludeWithTilde()
throws IOException, ConfigInvalidException {
final File includedFile = createFile(CONTENT1.getBytes(), "home");
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write("[include]\npath=".getBytes());
bos.write(("~/" + includedFile.getName()).getBytes());
final File file = createFile(bos.toByteArray(), "repo");
final FS fs = FS.DETECTED.newInstance();
fs.setUserHome(includedFile.getParentFile());
final FileBasedConfig config = new FileBasedConfig(file, fs);
config.load();
assertEquals(ALICE, config.getString(USER, null, NAME));
}
private File createFile(byte[] content) throws IOException { private File createFile(byte[] content) throws IOException {
trash.mkdirs(); return createFile(content, null);
File f = File.createTempFile(getClass().getName(), null, trash); }
private File createFile(byte[] content, String subdir) throws IOException {
File dir = subdir != null ? new File(trash, subdir) : trash;
dir.mkdirs();
File f = File.createTempFile(getClass().getName(), null, dir);
FileOutputStream os = new FileOutputStream(f, true); FileOutputStream os = new FileOutputStream(f, true);
try { try {
os.write(content); os.write(content);

30
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java

@ -55,6 +55,7 @@ import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.text.MessageFormat; import java.text.MessageFormat;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.LockFailedException; import org.eclipse.jgit.errors.LockFailedException;
import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.JGitText;
@ -74,6 +75,8 @@ import org.eclipse.jgit.util.RawParseUtils;
public class FileBasedConfig extends StoredConfig { public class FileBasedConfig extends StoredConfig {
private final File configFile; private final File configFile;
private final FS fs;
private boolean utf8Bom; private boolean utf8Bom;
private volatile FileSnapshot snapshot; private volatile FileSnapshot snapshot;
@ -107,6 +110,7 @@ public class FileBasedConfig extends StoredConfig {
public FileBasedConfig(Config base, File cfgLocation, FS fs) { public FileBasedConfig(Config base, File cfgLocation, FS fs) {
super(base); super(base);
configFile = cfgLocation; configFile = cfgLocation;
this.fs = fs;
this.snapshot = FileSnapshot.DIRTY; this.snapshot = FileSnapshot.DIRTY;
this.hash = ObjectId.zeroId(); this.hash = ObjectId.zeroId();
} }
@ -240,4 +244,30 @@ public class FileBasedConfig extends StoredConfig {
public boolean isOutdated() { public boolean isOutdated() {
return snapshot.isModified(getFile()); return snapshot.isModified(getFile());
} }
/**
* @since 4.10
*/
@Override
@Nullable
protected byte[] readIncludedConfig(String relPath)
throws ConfigInvalidException {
final File file;
if (relPath.startsWith("~/")) { //$NON-NLS-1$
file = fs.resolve(fs.userHome(), relPath.substring(2));
} else {
file = fs.resolve(configFile.getParentFile(), relPath);
}
if (!file.exists()) {
return null;
}
try {
return IO.readFully(file);
} catch (IOException ioe) {
throw new ConfigInvalidException(MessageFormat
.format(JGitText.get().cannotReadFile, relPath), ioe);
}
}
} }

Loading…
Cancel
Save