]> source.dussan.org Git - jgit.git/commitdiff
FileBasedConfig: support for relative includes 48/111848/5
authorMarc Strapetz <marc.strapetz@syntevo.com>
Sat, 18 Nov 2017 16:50:30 +0000 (17:50 +0100)
committerMatthias Sohn <matthias.sohn@sap.com>
Mon, 4 Dec 2017 22:38:24 +0000 (23:38 +0100)
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>
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/FileBasedConfigTest.java
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java

index 7902bb53032a02dba9b939ce7a8bec6e72680fe1..13d546f2b75ca55e9208ce230af29836a1a46d1e 100644 (file)
@@ -855,7 +855,7 @@ public class ConfigTest {
                assertEquals("bar", parsed.getString("other", null, "more"));
        }
 
-       private static String pathToString(File file) {
+       public static String pathToString(File file) {
                final String path = file.getPath();
                if (SystemReader.getInstance().isWindows()) {
                        return path.replace('\\', '/');
index ee845c5325787a06ffbed1fbc9e7a30207c76c53..2134e1b8dcd1a33d3b236eb65bc5b6038fcff14b 100644 (file)
@@ -52,6 +52,7 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 
 import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lib.ConfigTest;
 import org.eclipse.jgit.util.FS;
 import org.eclipse.jgit.util.FileUtils;
 import org.eclipse.jgit.util.IO;
@@ -157,9 +158,89 @@ public class FileBasedConfigTest {
                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 {
-               trash.mkdirs();
-               File f = File.createTempFile(getClass().getName(), null, trash);
+               return createFile(content, null);
+       }
+
+       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);
                try {
                        os.write(content);
index 6cfd352ec1cd544b3bdc1955135dfa533e60acd5..ba62418e1d28d425845b0d200e975f629c5369dc 100644 (file)
@@ -55,6 +55,7 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.text.MessageFormat;
 
+import org.eclipse.jgit.annotations.Nullable;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.errors.LockFailedException;
 import org.eclipse.jgit.internal.JGitText;
@@ -74,6 +75,8 @@ import org.eclipse.jgit.util.RawParseUtils;
 public class FileBasedConfig extends StoredConfig {
        private final File configFile;
 
+       private final FS fs;
+
        private boolean utf8Bom;
 
        private volatile FileSnapshot snapshot;
@@ -107,6 +110,7 @@ public class FileBasedConfig extends StoredConfig {
        public FileBasedConfig(Config base, File cfgLocation, FS fs) {
                super(base);
                configFile = cfgLocation;
+               this.fs = fs;
                this.snapshot = FileSnapshot.DIRTY;
                this.hash = ObjectId.zeroId();
        }
@@ -240,4 +244,30 @@ public class FileBasedConfig extends StoredConfig {
        public boolean isOutdated() {
                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);
+               }
+       }
 }