From 882520f3baee410647c3b99d608cc8fe18b0f5d0 Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Sat, 9 Nov 2024 16:17:44 +0100 Subject: 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. --- .../main/java/org/the_jk/cleversync/PathUtils.kt | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'libs/utils/src/main') 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("/") + } } -- cgit v1.2.3-70-g09d2