Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.ossuminc.riddl.commands.PrettifyCommand.scala Maven / Gradle / Ivy
/*
* Copyright 2019 Ossum, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
package com.ossuminc.riddl.commands
import com.ossuminc.riddl.language.{At, CommonOptions, Messages}
import com.ossuminc.riddl.language.Messages.Messages
import com.ossuminc.riddl.passes.Pass.standardPasses
import com.ossuminc.riddl.passes.{PassInput, PassOptions, PassesCreator, PassesOutput, PassesResult}
import com.ossuminc.riddl.utils.{ExceptionUtils, Logger}
import com.ossuminc.riddl.command.{CommandOptions, PassCommandOptions, TranslationCommand}
import com.ossuminc.riddl.command.CommandOptions.optional
import com.ossuminc.riddl.passes.prettify.{PrettifyOutput, PrettifyPass, RiddlFileEmitter}
import pureconfig.ConfigCursor
import pureconfig.ConfigReader
import scopt.OParser
import java.nio.charset.Charset
import java.nio.file.{Files, Path, StandardOpenOption}
object PrettifyCommand {
val cmdName = "prettify"
case class Options(
inputFile: Option[Path] = None,
outputDir: Option[Path] = Some(Path.of(System.getProperty("java.io.tmpdir"))),
projectName: Option[String] = None,
singleFile: Boolean = true
) extends TranslationCommand.Options
with PassOptions
with PassCommandOptions:
def command: String = cmdName
}
/** A command to Prettify RIDDL Source */
class PrettifyCommand extends TranslationCommand[PrettifyCommand.Options](PrettifyCommand.cmdName) {
import PrettifyCommand.Options
def overrideOptions(options: PrettifyCommand.Options, newOutputDir: Path): PrettifyCommand.Options = {
options.copy(outputDir = Some(newOutputDir))
}
override def getOptionsParser: (OParser[Unit, PrettifyCommand.Options], PrettifyCommand.Options) = {
val builder = OParser.builder[PrettifyCommand.Options]
import builder.*
cmd(PrettifyCommand.cmdName)
.children(
inputFile((v, c) => c.copy(inputFile = Option(v.toPath))),
outputDir((v, c) => c.copy(outputDir = Option(v.toPath))),
opt[String]("project-name")
.action((v, c) => c.copy(projectName = Option(v)))
.text("The name of the project to prettify"),
opt[Boolean]('s', name = "single-file")
.action((v, c) => c.copy(singleFile = v))
.text(
"""Resolve all includes and imports and write a single file with the
|same file name as the input placed in the out-dir""".stripMargin
)
)
.text("""Parse and validate the input-file and then reformat it to a
|standard layout written to the output-dir. """.stripMargin) ->
PrettifyCommand.Options()
}
override def getConfigReader: ConfigReader[PrettifyCommand.Options] = { (cur: ConfigCursor) =>
for
topCur <- cur.asObjectCursor
cmdCur <- topCur.atKey(PrettifyCommand.cmdName)
objCur <- cmdCur.asObjectCursor
content <- cmdCur.asObjectCursor
inputPathRes <- content.atKey("input-file")
inputPath <- inputPathRes.asString
outputPathRes <- content.atKey("output-dir")
outputPath <- outputPathRes.asString
projectName <- optional(content, "project-name", "No Project Name Specified") { cur => cur.asString }
singleFileRes <- objCur.atKey("single-file")
singleFile <- singleFileRes.asBoolean
yield PrettifyCommand.Options(
Option(Path.of(inputPath)),
Option(Path.of(outputPath)),
Option(projectName),
singleFile
)
}
override def getPasses(
log: Logger,
commonOptions: CommonOptions,
options: PrettifyCommand.Options
): PassesCreator = {
standardPasses ++ Seq(
{ (input: PassInput, outputs: PassesOutput) =>
PrettifyPass(input, outputs, PrettifyPass.Options(flatten = options.singleFile))
}
)
}
override def run(
originalOptions: PrettifyCommand.Options,
commonOptions: CommonOptions,
log: Logger,
outputDirOverride: Option[Path]
): Either[Messages, PassesResult] =
super.run(originalOptions, commonOptions, log, outputDirOverride) match
case Left(messages) => Left(messages)
case result @ Right(passesResult: PassesResult) =>
passesResult.outputOf[PrettifyOutput](PrettifyPass.name) match
case Some(output: PrettifyOutput) =>
writeOutput(output, originalOptions, outputDirOverride, log)
result
case None =>
// shouldn't happen
Left(List(Messages.error("No output from Prettify Pass", At.empty)))
end match
end match
end run
private def writeOutput(
output: PrettifyOutput,
originalOptions: Options,
dirOverrides: Option[Path],
logger: Logger
): Unit =
try {
val dir = originalOptions.outputDir
.getOrElse(dirOverrides
.getOrElse(Path.of(Option(System.getProperty("user.dir")).getOrElse("."))))
Files.createDirectories(dir)
if output.state.flatten then
val path = dir.resolve("prettify-output.riddl")
Files.writeString(
path,
output.state.filesAsString,
Charset.forName("UTF-8"),
StandardOpenOption.CREATE,
StandardOpenOption.WRITE
)
else
val base = dirOverrides.getOrElse(Path.of("."))
output.state.withFiles { (file: RiddlFileEmitter) =>
val content = file.toString
val path = base.resolve(file.url.path)
Files.writeString(path, content,
Charset.forName("UTF-8"),
StandardOpenOption.CREATE_NEW,
StandardOpenOption.WRITE
)
}
end if
} catch {
case e: java.io.IOException =>
logger.info(s"Exception while writing: ${e.getClass.getName}: ${e.getMessage}")
val stackTrace = ExceptionUtils.getRootCauseStackTrace(e).mkString("\n")
logger.info(stackTrace)
}
end writeOutput
}