summaryrefslogtreecommitdiff
path: root/libs/utils/src
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@spawned.biz>2024-11-09 16:17:44 +0100
committerJoel Klinghed <the_jk@spawned.biz>2024-11-09 16:17:44 +0100
commit882520f3baee410647c3b99d608cc8fe18b0f5d0 (patch)
treeeebb370a4977ea20ce3cfaf679aff387ab0896c9 /libs/utils/src
parent6ea5cef180db16523b2d629a44ee556507e3de78 (diff)
sftp: add single merge tests for both local <-> sftp and sftp <-> local
Had to fixup the symlink code in Sftp, most importantly add a PathUtils relativeTo to fixup relative links.
Diffstat (limited to 'libs/utils/src')
-rw-r--r--libs/utils/src/main/java/org/the_jk/cleversync/PathUtils.kt27
-rw-r--r--libs/utils/src/test/java/org/the_jk/cleversync/PathUtilsTest.kt11
2 files changed, 38 insertions, 0 deletions
diff --git a/libs/utils/src/main/java/org/the_jk/cleversync/PathUtils.kt b/libs/utils/src/main/java/org/the_jk/cleversync/PathUtils.kt
index 4202b24..77037cd 100644
--- a/libs/utils/src/main/java/org/the_jk/cleversync/PathUtils.kt
+++ b/libs/utils/src/main/java/org/the_jk/cleversync/PathUtils.kt
@@ -1,5 +1,7 @@
package org.the_jk.cleversync
+import kotlin.math.min
+
object PathUtils {
fun dirname(path: String): String {
if (path.isEmpty()) return "."
@@ -46,4 +48,29 @@ object PathUtils {
}
return parts.joinToString("/", prefix = if (prefixed) "/" else "")
}
+
+ // Return path relative to base. Returns path as-is if either path is not
+ // absolute.
+ fun relativeTo(base: String, path: String): String {
+ if (!base.startsWith('/') || !path.startsWith('/')) return path
+ val baseParts = base.split('/').filter { part ->
+ part.isNotEmpty() && part != "."
+ }
+ val pathParts = path.split('/').filter { part ->
+ part.isNotEmpty() && part != "."
+ }
+ var i = 0
+ while (i < min(baseParts.size, pathParts.size)) {
+ if (baseParts[i] != pathParts[i]) break
+ i++
+ }
+ if (i == baseParts.size) {
+ if (i == pathParts.size) return "."
+ return pathParts.subList(i, pathParts.size).joinToString("/")
+ }
+ return buildList {
+ repeat(baseParts.size - i) { add("..") }
+ addAll(pathParts.subList(i, pathParts.size))
+ }.joinToString("/")
+ }
}
diff --git a/libs/utils/src/test/java/org/the_jk/cleversync/PathUtilsTest.kt b/libs/utils/src/test/java/org/the_jk/cleversync/PathUtilsTest.kt
index eb1d63f..1d411ea 100644
--- a/libs/utils/src/test/java/org/the_jk/cleversync/PathUtilsTest.kt
+++ b/libs/utils/src/test/java/org/the_jk/cleversync/PathUtilsTest.kt
@@ -55,4 +55,15 @@ class PathUtilsTest {
assertThat(PathUtils.resolve("foo/../../../bar/")).isEqualTo("bar")
assertThat(PathUtils.resolve("/foo/../../../bar/")).isEqualTo("/bar")
}
+
+ @Test
+ fun relativeTo() {
+ assertThat(PathUtils.relativeTo("", "")).isEmpty()
+ assertThat(PathUtils.relativeTo("/", "/")).isEqualTo(".")
+ assertThat(PathUtils.relativeTo("/", "/foo")).isEqualTo("foo")
+ assertThat(PathUtils.relativeTo("/", "/foo/bar/")).isEqualTo("foo/bar")
+ assertThat(PathUtils.relativeTo("/foo", "/foo/bar/")).isEqualTo("bar")
+ assertThat(PathUtils.relativeTo("/foo", "/bar")).isEqualTo("../bar")
+ assertThat(PathUtils.relativeTo("/foo/bar", "/fum/bar")).isEqualTo("../../fum/bar")
+ }
}