sbt 0.13.x迁移至1.1.4:Play应用Git拉取前端Shell任务适配
Hey there, let's get your Play Framework frontend task running reliably in sbt 1.1.4. There are a few key adjustments needed to account for sbt 1.x's stricter task failure handling and fix cross-platform compatibility gaps that were likely overlooked in the original 0.13.x code.
Key Changes & Fixes
1. Enforce Task Failure on Shell Command Errors
In sbt 1.x, it’s critical to ensure failed shell commands stop the task (instead of silently proceeding). Your original code runs commands but doesn’t check their exit status—we’ll fix this with the ! operator from Scala’s sys.process library, which returns the command’s exit code and lets us fail the task if anything goes wrong.
2. Fix Cross-Platform Delete Commands
Your original code uses rm -rf for Windows via cmd /c, which won’t work—Windows Command Prompt doesn’t recognize the Unix rm command. We’ll replace this with native Windows delete commands (rmdir /s /q) to keep the task working across operating systems.
3. Explicit Logging for Task Progress
While streams.value still works in sbt 1.x, we’ll use s.log.info() and s.log.error() to make task progress and issues clearer in the sbt output.
Full Adapted Code
import scala.sys.process._ lazy val frontend = taskKey[Unit]("Downloads and sets up frontend assets") frontend := { val s = streams.value val isWindows = sys.props("os.name").toLowerCase.contains("windows") // Base shell command structure for cross-platform execution val shell: Seq[String] = if (isWindows) Seq("cmd", "/c") else Seq("bash", "-c") s.log.info("Starting frontend setup: cloning repository...") val cloneCommand = shell :+ "git clone git@bitbucket.org:user/frontend.git" // Execute clone and fail task if it fails val cloneExitCode = cloneCommand.! if (cloneExitCode != 0) { s.log.error("Failed to clone the frontend repository") throw new RuntimeException(s"Git clone failed with exit code $cloneExitCode") } s.log.info("Cleaning up old frontend assets...") // Cross-platform delete and directory creation commands val cleanupCommands = if (isWindows) { Seq( shell :+ "rmdir /s /q frontend\\dist\\js", shell :+ "rmdir /s /q public\\design", shell :+ "mkdir public\\design" ) } else { Seq( shell :+ "rm -rf frontend/dist/js && rm -rf public/design && mkdir public/design" ) } // Run each cleanup command and validate success cleanupCommands.foreach { cmd => val exitCode = cmd.! if (exitCode != 0) { s.log.error(s"Failed to run command: ${cmd.mkString(" ")}") throw new RuntimeException(s"Command failed with exit code $exitCode") } } s.log.info("Frontend setup completed successfully!") }
Additional Tips
- SSH Authentication: Make sure the user running sbt has valid SSH keys set up for Bitbucket—this is unrelated to sbt version but a common pitfall for git clone tasks.
- Working Directory Control: If you need to run commands in a specific subdirectory (not the project root), use
Process(cmd, new File("path/to/target/dir")).!instead of justcmd.!. - Simpler Multi-Command Execution: For Unix systems, combining commands with
&&works as expected, but Windows requires separatecmd /ccalls for each operation (since&&behaves differently in Command Prompt).
内容的提问来源于stack exchange,提问作者cutoffurmind

