我可以在 sbt 中相对复制文件吗?
Can I relative-copy files in sbt?
我有这样的目录结构:
a
/one
hey.class
hey.tasty
you.class
you.tasty
/two
foo.class
foo.tasty
/three
bar.class
bar.tasty
b
/one
/two
/three
我需要一种方法将所有 .tasty 文件从 /a 中各自的位置复制到 sbt 任务中 /b 中的相应位置。
您可以通过以下方式创建 sbt 任务并传递原始文件夹和目标文件夹:
val copyTasties = inputKey[Unit]("Copy .tasty files")
copyTasties := {
val userInput = Def.spaceDelimited().parsed
if (userInput.size != 2) {
throw new IllegalArgumentException("Original and target directories should be define!")
}
val from = Paths.get(userInput.head)
val to = Paths.get(userInput.last)
Files
.walk(from)
.filter(Files.isRegularFile(_))
.filter(path => path.toString.endsWith("tasty"))
.forEach { original =>
val relative = from.relativize(original)
val destination = to.resolve(relative)
IO.copyFile(original.toFile, destination.toFile)
}
}
然后你可以这样调用它:
copyTasties C:\Dev\sandbox\a C:\Dev\sandbox\b
如果原始和目标稳定(例如它们是项目内的目录),您可以重写任务:
import java.nio.file.{Files, Paths}
import sbt._
val copyTastiesHardcoded = taskKey[Unit]("Copy .tasty files")
copyTastiesHardcoded := {
val baseDir = baseDirectory.value.toPath
val from = baseDir.resolve("a")
val to = baseDir.resolve("b")
Files
.walk(from)
.filter(Files.isRegularFile(_))
.filter(path => path.toString.endsWith("tasty"))
.forEach { original =>
val relative = from.relativize(original)
val destination = to.resolve(relative)
IO.copyFile(original.toFile, destination.toFile)
}
}
并在没有参数的情况下调用它
copyTastiesHardcoded
sbt 中有一些有用的实用方法可以帮助您查找文件并复制它们。不幸的是,它混合使用了传统的 java.io.File
和更现代的 java.nio.file.Path
,因此您需要在它们之间进行转换:
val copyFiles = taskKey[Unit]("copy files")
copyFiles := {
val inputDir = baseDirectory.value.toPath / "a"
val files: Seq[(Path, FileAttributes)] =
FileTreeView.default.list(inputDir.toGlob / RecursiveGlob / "*.tasty")
val outputDir = baseDirectory.value.toPath / "b"
IO.copy {
files.map { case (p, _) =>
p.toFile -> outputDir.resolve(inputDir.relativize(p)).toFile
}
}
}
请注意,我在这里使用 glob 来查找文件:
https://www.scala-sbt.org/1.x/docs/Globs.html
我有这样的目录结构:
a
/one
hey.class
hey.tasty
you.class
you.tasty
/two
foo.class
foo.tasty
/three
bar.class
bar.tasty
b
/one
/two
/three
我需要一种方法将所有 .tasty 文件从 /a 中各自的位置复制到 sbt 任务中 /b 中的相应位置。
您可以通过以下方式创建 sbt 任务并传递原始文件夹和目标文件夹:
val copyTasties = inputKey[Unit]("Copy .tasty files")
copyTasties := {
val userInput = Def.spaceDelimited().parsed
if (userInput.size != 2) {
throw new IllegalArgumentException("Original and target directories should be define!")
}
val from = Paths.get(userInput.head)
val to = Paths.get(userInput.last)
Files
.walk(from)
.filter(Files.isRegularFile(_))
.filter(path => path.toString.endsWith("tasty"))
.forEach { original =>
val relative = from.relativize(original)
val destination = to.resolve(relative)
IO.copyFile(original.toFile, destination.toFile)
}
}
然后你可以这样调用它:
copyTasties C:\Dev\sandbox\a C:\Dev\sandbox\b
如果原始和目标稳定(例如它们是项目内的目录),您可以重写任务:
import java.nio.file.{Files, Paths}
import sbt._
val copyTastiesHardcoded = taskKey[Unit]("Copy .tasty files")
copyTastiesHardcoded := {
val baseDir = baseDirectory.value.toPath
val from = baseDir.resolve("a")
val to = baseDir.resolve("b")
Files
.walk(from)
.filter(Files.isRegularFile(_))
.filter(path => path.toString.endsWith("tasty"))
.forEach { original =>
val relative = from.relativize(original)
val destination = to.resolve(relative)
IO.copyFile(original.toFile, destination.toFile)
}
}
并在没有参数的情况下调用它
copyTastiesHardcoded
sbt 中有一些有用的实用方法可以帮助您查找文件并复制它们。不幸的是,它混合使用了传统的 java.io.File
和更现代的 java.nio.file.Path
,因此您需要在它们之间进行转换:
val copyFiles = taskKey[Unit]("copy files")
copyFiles := {
val inputDir = baseDirectory.value.toPath / "a"
val files: Seq[(Path, FileAttributes)] =
FileTreeView.default.list(inputDir.toGlob / RecursiveGlob / "*.tasty")
val outputDir = baseDirectory.value.toPath / "b"
IO.copy {
files.map { case (p, _) =>
p.toFile -> outputDir.resolve(inputDir.relativize(p)).toFile
}
}
}
请注意,我在这里使用 glob 来查找文件: https://www.scala-sbt.org/1.x/docs/Globs.html