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

Initコマンドを実装する #23

Merged
merged 11 commits into from
Dec 22, 2022
56 changes: 56 additions & 0 deletions src/main/scala/com/github/windymelt/zmm/Cli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,62 @@ final class Cli
} yield ()
}

/**
* 現在のディレクトリをZMMプロジェクトとして初期化する。
*
* 現在のディレクトリに原稿XMLファイルや生成物配置用のディレクトリを作成する。
* 既にディレクトリやファイルが存在している場合は何もしない。
*
* @return Unitを返す。
*/
def initializeProject(): IO[Unit] = {
val agreed = for {
cwd <- IO.pure(os.pwd.toString())
_ <- IO.print(s"$cwd を ZMMプロジェクトとして初期化しますか? [y/N]?>")
ynString <- IO.readLine
} yield ynString == "y"

val placeXml: IO[Unit] = IO {
os.exists(os.pwd / "script.xml") match {
case true => IO.println("script.xml は既に存在するのでスキップされました")
case false => IO(os.write(os.pwd / "script.xml", xml.script().body))
}
}.flatten

val digArtifacts: IO[Unit] = IO {
os.exists(os.pwd / "artifacts") match {
case true => IO.println("artifacts/ は既に存在するのでスキップされました")
case false => IO(os.makeDir(os.pwd / "artifacts"))
}
}.flatten

val digArtifactsHtml: IO[Unit] = IO {
os.exists(os.pwd / "artifacts" / "html") match {
case true => IO.println("artifacts/html/ は既に存在するのでスキップされました")
case false => IO(os.makeDir(os.pwd / "artifacts" / "html"))
}
}.flatten

val digAssets: IO[Unit] = IO {
os.exists(os.pwd / "assets") match {
case true => IO.println("assets/ は既に存在するのでスキップされました")
case false => IO(os.makeDir(os.pwd / "assets"))
}
}.flatten

val init = for {
_ <- placeXml
_ <- digArtifacts >> digArtifactsHtml
_ <- digAssets
} yield ()

// ZMMプロジェクトを構成するいくつかのファイル/ディレクトリについて、存在しなかったらテンプレートをもとに作成する、を繰り返す
agreed flatMap {
case true => init
case false => IO.println("中断します")
}
}

def generate(filePath: String): IO[Unit] = {
val content = IO.delay(scala.xml.XML.loadFile(filePath))

Expand Down
16 changes: 16 additions & 0 deletions src/main/scala/com/github/windymelt/zmm/CliOptions.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.github.windymelt.zmm

import com.monovore.decline._
import com.monovore.decline.effect._

sealed trait ZmmOption
final case class ShowCommand(target: String) extends ZmmOption // 今のところvoicevoxしか入らない
final case class TargetFile(target: java.nio.file.Path) extends ZmmOption
final case class InitializeCommand() extends ZmmOption

object CliOptions {
private val showCommand = Opts.subcommand(name = "show", help = "Prints information.")(Opts.argument[String]("voicevox").map(ShowCommand.apply))
private val targetFile = Opts.argument[java.nio.file.Path](metavar = "XMLFile").map(TargetFile.apply)
private val initCommand = Opts.subcommand(name = "init", help = "Initializes current directory as ZMM project.")(Opts.unit.map(_ => InitializeCommand()))
val opts: Opts[ZmmOption] = targetFile orElse showCommand orElse initCommand
}
23 changes: 8 additions & 15 deletions src/main/scala/com/github/windymelt/zmm/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,25 @@ import cats.effect.IOApp
import cats.effect.ExitCode
import java.io.OutputStream
import org.http4s.syntax.header

import com.monovore.decline._
import com.monovore.decline.effect._

sealed trait ZmmOption
final case class ShowCommand(target: String) extends ZmmOption // 今のところvoicevoxしか入らない
final case class TargetFile(target: java.nio.file.Path) extends ZmmOption
import com.monovore.decline.Opts
import com.monovore.decline.effect.CommandIOApp

object Main extends CommandIOApp(
name = "zmm",
header = "Zunda Movie Maker",
header = "Zunda Movie Maker -- see https://www.3qe.us/zmm/doc/ for more documentation",
version = BuildInfo.version,
) {
val showCommand = Opts.subcommand(name = "show", help = "Prints information.")(Opts.argument[String]("voicevox").map(ShowCommand.apply))
val targetFile = Opts.argument[java.nio.file.Path](metavar = "XMLFile").map(TargetFile.apply)
val opts: Opts[ZmmOption] = targetFile orElse showCommand
override def main: Opts[IO[ExitCode]] = opts map { o =>
override def main: Opts[IO[ExitCode]] = CliOptions.opts map { o =>
val cli = new Cli()
o match {
case ShowCommand(target) => target match {
case "voicevox" => cli.showVoiceVoxSpeakers() >> IO.pure(cats.effect.ExitCode.Success)
case _ => IO.println("subcommand [show] only accepts 'voicevox'. try `show voicevox`") >> IO.pure(cats.effect.ExitCode.Error)
case "voicevox" => cli.showVoiceVoxSpeakers() >> IO.pure(ExitCode.Success)
case _ => IO.println("subcommand [show] only accepts 'voicevox'. try `show voicevox`") >> IO.pure(ExitCode.Error)
}
case TargetFile(file) =>
cli.generate(file.toString) >>
IO.pure(cats.effect.ExitCode.Success)
IO.pure(ExitCode.Success)
case InitializeCommand() => cli.initializeProject() >> IO.pure(ExitCode.Success)
}
}
}
26 changes: 26 additions & 0 deletions src/main/twirl/script.scala.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8" ?>
<content version="0.0">
<meta>
<voiceconfig id="metan" backend="voicevox">
<voicevoxconfig id="2" />
</voiceconfig>
<voiceconfig id="zundamon" backend="voicevox">
<voicevoxconfig id="3" />
</voiceconfig>
<characterconfig name="metan" voice-id="metan" serif-color="#E14D2A"
tachie-url="../../assets/めたんの立ち絵を設定してください" />
<characterconfig name="zunda" voice-id="zundamon" serif-color="#379237"
tachie-url="../../assets/ずんだもんの立ち絵を設定してください" />
<dict pronounce="ゼットエムエ_ム">zmm</dict>
</meta>
<predef>
</predef>
<dialogue backgroundImage="../../assets/ここに背景画像を設定してください" bgm="assets/ここにBGMファイルを設定してください">
<scene>
<say by="metan">こんにちは、四国めたんです</say>
<say by="zunda">こんにちは、ずんだもんなのだ</say>
<say by="metan">この原稿ファイルはzmmのサンプル原稿です</say>
<say by="zunda">よろしくなのだ</say>
</scene>
</dialogue>
</content>