Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix os.copy and os.move directories to root #267

Merged
merged 12 commits into from
May 16, 2024
8 changes: 4 additions & 4 deletions os/src/FileOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ object move {
def isDefinedAt(x: Path) = partialFunction.isDefinedAt(x)
def apply(from: Path) = {
val dest = partialFunction(from)
makeDir.all(dest / up)
if (dest.segmentCount != 0) makeDir.all(dest / up)
os.move(from, dest, replaceExisting, atomicMove, createFolders)
}
}
Expand All @@ -84,7 +84,7 @@ object move {
atomicMove: Boolean = false,
createFolders: Boolean = false
): Unit = {
if (createFolders) makeDir.all(to / up)
if (createFolders && to.segmentCount != 0) makeDir.all(to / up)
val opts1 =
if (replaceExisting) Array[CopyOption](StandardCopyOption.REPLACE_EXISTING)
else Array[CopyOption]()
Expand Down Expand Up @@ -149,7 +149,7 @@ object copy {
def isDefinedAt(x: Path) = partialFunction.isDefinedAt(x)
def apply(from: Path) = {
val dest = partialFunction(from)
makeDir.all(dest / up)
if (dest.segmentCount != 0) makeDir.all(dest / up)
os.copy(
from,
dest,
Expand All @@ -176,7 +176,7 @@ object copy {
createFolders: Boolean = false,
mergeFolders: Boolean = false
): Unit = {
if (createFolders) makeDir.all(to / up)
if (createFolders && to.segmentCount != 0) makeDir.all(to / up)
val opts1 =
if (followLinks) Array[CopyOption]()
else Array[CopyOption](LinkOption.NOFOLLOW_LINKS)
Expand Down
52 changes: 48 additions & 4 deletions os/test/src-jvm/PathTestsCustomFilesystem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package test.os

import utest._
import os._

import java.util.HashMap
import java.nio.file.FileSystems
import java.nio.file.{FileAlreadyExistsException, FileSystem, FileSystems}
import java.net.URI
import java.nio.file.FileSystem
import java.nio.file.Paths
import scala.util.{Failure, Try}
import scala.util.control.NonFatal

object PathTestsCustomFilesystem extends TestSuite {

Expand All @@ -15,7 +16,7 @@ object PathTestsCustomFilesystem extends TestSuite {
path.toUri()
}

def withCustomFs(f: FileSystem => Unit, fsUri: URI = customFsUri()): Unit = {
def withCustomFs[T](f: FileSystem => T, fsUri: URI = customFsUri()): T = {
val uri = new URI("jar", fsUri.toString(), null);
val env = new HashMap[String, String]();
env.put("create", "true");
Expand Down Expand Up @@ -175,6 +176,49 @@ object PathTestsCustomFilesystem extends TestSuite {
assert(os.exists(p / "file.txt"))
}
}
test("copyAndMergeToRootDirectoryWithCreateFolders") {
withCustomFs { fileSystem =>
val root = os.root("/", fileSystem)
val file = root / "test" / "dir" / "file.txt"
os.write(file, "Hello World")
os.copy(root / "test" / "dir", root, createFolders = true, mergeFolders = true)
assert(os.read(root / "file.txt") == "Hello World")
assert(os.exists(root / "file.txt"))
}
}
test("failMoveToRootDirectoryWithCreateFolders") {
withCustomFs { fileSystem =>
val root = os.root("/", fileSystem)
// This should fail. Just test that it doesn't throw PathError.AbsolutePathOutsideRoot.
intercept[FileAlreadyExistsException] {
os.move(root / "test" / "dir", root, createFolders = true)
}
}
}
test("copyMatchingAndMergeToRootDirectory") {
withCustomFs { fileSystem =>
val root = os.root("/", fileSystem)
val file = root / "test" / "dir" / "file.txt"
os.write(file, "Hello World")
os.list(root / "test").collect(os.copy.matching(mergeFolders = true) {
case p / "test" / _ => p
})
assert(os.read(root / "file.txt") == "Hello World")
assert(os.exists(root / "file.txt"))
}
}
test("failMoveMatchingToRootDirectory") {
withCustomFs { fileSystem =>
// can't use a `intercept`, see https://github.com/com-lihaoyi/os-lib/pull/267#issuecomment-2116131445
Try {
os.list(os.root("/", fileSystem)).collect(os.move.matching { case p / "test" => p })
} match {
case Failure(e @ (_: IllegalArgumentException | _: FileAlreadyExistsException))
if !e.isInstanceOf[PathError.AbsolutePathOutsideRoot.type] =>
e.getMessage
}
}
}
test("remove") {
withCustomFs { fileSystem =>
val p = os.root("/", fileSystem) / "test" / "dir"
Expand Down