Fix Path.copyToRecursively when copying across file systems #KT-55935
Merge-request: KT-MR-8705 Merged-by: Abduqodiri Qurbonzoda <abduqodiri.qurbonzoda@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
1844869e8a
commit
80b48eed0b
@@ -161,11 +161,13 @@ public fun Path.copyToRecursively(
|
||||
// TODO: KT-38678
|
||||
// source and target files are the same entry, continue recursive copy operation
|
||||
} else {
|
||||
val realPath = this.toRealPath()
|
||||
val isSubdirectory = if (targetExistsAndNotSymlink) {
|
||||
target.toRealPath().startsWith(realPath)
|
||||
} else {
|
||||
target.parent?.let { it.exists() && it.toRealPath().startsWith(realPath) } ?: false
|
||||
val isSubdirectory = when {
|
||||
this.fileSystem != target.fileSystem ->
|
||||
false
|
||||
targetExistsAndNotSymlink ->
|
||||
target.toRealPath().startsWith(this.toRealPath())
|
||||
else ->
|
||||
target.parent?.let { it.exists() && it.toRealPath().startsWith(this.toRealPath()) } ?: false
|
||||
}
|
||||
if (isSubdirectory)
|
||||
throw FileSystemException(
|
||||
@@ -178,7 +180,7 @@ public fun Path.copyToRecursively(
|
||||
|
||||
fun destination(source: Path): Path {
|
||||
val relativePath = source.relativeTo(this@copyToRecursively)
|
||||
return target.resolve(relativePath)
|
||||
return target.resolve(relativePath.pathString)
|
||||
}
|
||||
|
||||
fun error(source: Path, exception: Exception): FileVisitResult {
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
|
||||
package kotlin.jdk7.test
|
||||
|
||||
import java.net.URI
|
||||
import java.nio.file.*
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
import kotlin.io.path.*
|
||||
import kotlin.jdk7.test.PathTreeWalkTest.Companion.createTestFiles
|
||||
import kotlin.jdk7.test.PathTreeWalkTest.Companion.referenceFilenames
|
||||
@@ -970,4 +973,50 @@ class PathRecursiveFunctionsTest : AbstractPathTest() {
|
||||
|
||||
src.copyToRecursively(dst, followLinks = false, overwrite = true)
|
||||
}
|
||||
|
||||
private fun createZipFile(parent: Path, name: String): Path {
|
||||
val zipRoot = parent.resolve(name)
|
||||
ZipOutputStream(zipRoot.outputStream()).use { out ->
|
||||
out.putNextEntry(ZipEntry("directory/file.txt"))
|
||||
out.write("hello".toByteArray())
|
||||
out.closeEntry()
|
||||
}
|
||||
return zipRoot
|
||||
}
|
||||
|
||||
@Test
|
||||
fun zipToDefaultPath() {
|
||||
val root = createTempDirectory().cleanupRecursively()
|
||||
val zipRoot = createZipFile(root, "src.zip")
|
||||
val dst = root.resolve("dst")
|
||||
|
||||
val classLoader: ClassLoader? = null
|
||||
FileSystems.newFileSystem(zipRoot, classLoader).use { zipFs ->
|
||||
val src = zipFs.getPath("/directory")
|
||||
|
||||
src.copyToRecursively(dst, followLinks = false)
|
||||
|
||||
val expected = listOf("", "file.txt")
|
||||
testVisitedFiles(expected, dst.walkIncludeDirectories(), dst)
|
||||
assertEquals("hello", dst.resolve("file.txt").readText())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun defaultPathToZip() {
|
||||
val root = createTestFiles().cleanupRecursively()
|
||||
val zipRoot = createZipFile(root, "dst.zip")
|
||||
val src = root.resolve("1").also { it.resolve("3/4.txt").writeText("hello") }
|
||||
|
||||
val classLoader: ClassLoader? = null
|
||||
FileSystems.newFileSystem(zipRoot, classLoader).use { zipFs ->
|
||||
val dst = zipFs.getPath("/directory")
|
||||
|
||||
src.copyToRecursively(dst, followLinks = false)
|
||||
|
||||
val expected = listOf("", "2", "3", "3/4.txt", "3/5.txt", "file.txt")
|
||||
testVisitedFiles(expected, dst.walkIncludeDirectories(), dst)
|
||||
assertEquals("hello", zipFs.getPath("/directory/3/4.txt").readText())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user