#scala #sbt
#scala #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 в соответствующие места в /b в задаче sbt.
Ответ №1:
Вы можете создать задачу 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
Ответ №2:
В 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
}
}
}
Обратите внимание, что я использую глобус здесь, чтобы найти файлы:
https://www.scala-sbt.org/1.x/docs/Globs.html