Skip to content

Commit ce647d6

Browse files
committed
multi-mapping serializer
1 parent 325eaa3 commit ce647d6

2 files changed

Lines changed: 51 additions & 6 deletions

File tree

os/src/Path.scala

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -452,9 +452,15 @@ object Path extends PathMacros {
452452
val maybeBase = Option(System.getenv("OS_LIB_PATH_RELATIVIZER_BASE")).filter(_.nonEmpty)
453453
maybeBase match {
454454
case Some(base0) if base0.contains(",") =>
455-
val parts = base0.split(",", 2).map(_.trim)
456-
if (parts.length == 2 && parts(0).nonEmpty && parts(1).nonEmpty) {
457-
pathRemapSerializer(pathFromRawString(parts(0)), pathFromRawString(parts(1)))
455+
val tupleSpecs = base0.split(";").iterator.map(_.trim).filter(_.nonEmpty).toSeq
456+
val mappings = tupleSpecs.map { tuple =>
457+
val parts = tuple.split(",", 2).map(_.trim)
458+
if (parts.length == 2 && parts(0).nonEmpty && parts(1).nonEmpty) {
459+
(pathFromRawString(parts(0)), pathFromRawString(parts(1)))
460+
} else null
461+
}
462+
if (mappings.nonEmpty && mappings.forall(_ != null)) {
463+
pathRemapSerializer(mappings)
458464
} else rawPathSerializer
459465
case Some(base0) =>
460466
pathRelativizerSerializer(pathFromRawString(base0.trim))
@@ -506,15 +512,28 @@ object Path extends PathMacros {
506512
}
507513
}
508514

509-
@experimental def pathRemapSerializer(from: os.Path, to: os.Path): Serializer = new Serializer {
515+
@experimental def pathRemapSerializer(from: os.Path, to: os.Path): Serializer =
516+
pathRemapSerializer(Seq((from, to)))
517+
518+
@experimental def pathRemapSerializer(mappings: Seq[(os.Path, os.Path)]): Serializer = new Serializer {
510519
private def replacePrefix(p: java.nio.file.Path, src: os.Path, dest: os.Path): java.nio.file.Path = {
511520
if (p.getFileSystem == src.fileSystem && p.startsWith(src.wrapped)) {
512521
val rel = src.wrapped.relativize(p)
513522
dest.wrapped.resolve(rel.toString).normalize()
514523
} else p
515524
}
516-
private def serializeRemap(p: java.nio.file.Path): java.nio.file.Path = replacePrefix(p, from, to)
517-
private def deserializeRemap(p: java.nio.file.Path): java.nio.file.Path = replacePrefix(p, to, from)
525+
private def serializeRemap(p: java.nio.file.Path): java.nio.file.Path = {
526+
mappings.iterator
527+
.map { case (from, to) => replacePrefix(p, from, to) }
528+
.find(_ != p)
529+
.getOrElse(p)
530+
}
531+
private def deserializeRemap(p: java.nio.file.Path): java.nio.file.Path = {
532+
mappings.iterator
533+
.map { case (from, to) => replacePrefix(p, to, from) }
534+
.find(_ != p)
535+
.getOrElse(p)
536+
}
518537

519538
def serializeString(p: os.Path): String = serializeRemap(p.wrapped).toString
520539
def serializeFile(p: os.Path): java.io.File = new java.io.File(serializeString(p))

os/test/src/PathTests.scala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,32 @@ object PathTests extends TestSuite {
617617
assert(outside.toNIO == outside.wrapped)
618618
}
619619
}
620+
test("pathRemapSerializerMultipleMappings") {
621+
val from1 = os.pwd / "from1"
622+
val to1 = os.pwd / "to1"
623+
val from2 = os.pwd / "from2"
624+
val to2 = os.pwd / "to2"
625+
val serializer = os.Path.pathRemapSerializer(Seq((from1, to1), (from2, to2)))
626+
os.Path.pathSerializer.withValue(serializer) {
627+
val inFrom1 = from1 / "a"
628+
val inFrom2 = from2 / "b"
629+
val inTo1 = to1 / "a"
630+
val inTo2 = to2 / "b"
631+
632+
assert(inFrom1.toString == inTo1.wrapped.toString)
633+
assert(inFrom2.toString == inTo2.wrapped.toString)
634+
assert(os.Path(inTo1.wrapped.toString) == inFrom1)
635+
assert(os.Path(inTo2.wrapped.toString) == inFrom2)
636+
637+
// First matching mapping is applied, without chaining remaps.
638+
val chainSrc = from1 / "x"
639+
val chainSerializer =
640+
os.Path.pathRemapSerializer(Seq((from1, to1), (to1, to2)))
641+
os.Path.pathSerializer.withValue(chainSerializer) {
642+
assert(chainSrc.toString == to1.wrapped.resolve("x").toString)
643+
}
644+
}
645+
}
620646
}
621647
// compare absolute paths
622648
def sameFile(a: java.nio.file.Path, b: java.nio.file.Path): Boolean = {

0 commit comments

Comments
 (0)