forked from digital-asset/daml
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DAML assistant codegen command (digital-asset#2800)
* DAML assistant codegen command, codegen config reader and docs
- Loading branch information
Showing
15 changed files
with
524 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
.. Copyright (c) 2019 The DAML Authors. All rights reserved. | ||
.. SPDX-License-Identifier: Apache-2.0 | ||
DAML codegen | ||
############ | ||
|
||
Introduction | ||
============ | ||
|
||
You can use the DAML codegen to generate Java and Scala classes representing DAML contract templates. These classes incorporate all boilerplate code for constructing corresponding ledger :ref:`com.digitalasset.ledger.api.v1.CreateCommand` and :ref:`com.digitalasset.ledger.api.v1.ExerciseCommand`. | ||
|
||
Running the DAML codegen | ||
======================== | ||
|
||
The basic command to run the DAML codegen is:: | ||
|
||
$ daml codegen [java|scala] [options] | ||
|
||
There are two modes: | ||
|
||
- command line configuration, specifying **all** settings in the command line | ||
|
||
- project file configuration, specifying **all** settings in the ``daml.yaml`` | ||
|
||
Command line configuration | ||
-------------------------- | ||
|
||
Help for **DAML to Java** codegen:: | ||
|
||
$ daml codegen java --help | ||
|
||
Help for **DAML to Scala** codegen:: | ||
|
||
$ daml codegen scala --help | ||
|
||
Both **DAML to Java** and **DAML to Scala** take the same set of configuration settings:: | ||
|
||
Usage: codegen [options] <DAR-file[=package-prefix]>... | ||
|
||
Code generator for the DAML ledger bindings. | ||
|
||
<DAR-file[=package-prefix]>... | ||
DAR file to use as input of the codegen with an optional, but recommend, package prefix for the generated sources. | ||
-o, --output-directory <value> | ||
Output directory for the generated sources | ||
-d, --decoderClass <value> | ||
Fully Qualified Class Name of the optional Decoder utility | ||
-V, --verbosity <value> Verbosity between 0 (only show errors) and 4 (show all messages) -- defaults to 0 | ||
-r, --root <value> Regular expression for fully-qualified names of templates to generate -- defaults to .* | ||
--help This help text | ||
|
||
Project file configuration | ||
-------------------------- | ||
|
||
The above settings can be configured in the ``codegen`` element of the DAML project file ``daml.yaml``. Here is an example:: | ||
|
||
sdk-version: 0.0.0 | ||
name: quickstart | ||
source: daml | ||
scenario: Main:setup | ||
parties: | ||
- Alice | ||
- Bob | ||
- USD_Bank | ||
- EUR_Bank | ||
version: 0.0.1 | ||
exposed-modules: | ||
- Main | ||
dependencies: | ||
- daml-prim | ||
- daml-stdlib | ||
codegen: | ||
java: | ||
package-prefix: com.digitalasset.quickstart.iou | ||
output-directory: java-codegen/src/main/java | ||
verbosity: 2 | ||
scala: | ||
package-prefix: com.digitalasset.quickstart.iou | ||
output-directory: scala-codegen/src/main/scala | ||
verbosity: 2 | ||
|
||
You can run the above configuration to generate **Java** code:: | ||
|
||
$ daml codegen java | ||
|
||
and to generate **Scala** code:: | ||
|
||
$ daml codegen scala | ||
|
||
The equivalent **DAML to Java** command line configuration:: | ||
|
||
$ daml codegen java ./.daml/dist/quickstart-0.0.1.dar=com.digitalasset.quickstart.iou --output-directory=java-codegen/src/main/java --verbosity=2 | ||
|
||
and **DAML to Scala** command line configuration:: | ||
|
||
$ daml codegen scala ./.daml/dist/quickstart-0.0.1.dar=com.digitalasset.quickstart.iou --output-directory=scala-codegen/src/main/scala --verbosity=2 | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
151 changes: 151 additions & 0 deletions
151
...gen-common/src/main/scala/com/digitalasset/daml/lf/codegen/conf/CodegenConfigReader.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
// Copyright (c) 2019 The DAML Authors. All rights reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package com.digitalasset.daml.lf.codegen.conf | ||
|
||
import java.io.File | ||
import java.nio.file.Path | ||
|
||
import ch.qos.logback.classic.Level | ||
import com.digitalasset.assistant.config._ | ||
import io.circe.ACursor | ||
|
||
import scala.util.Try | ||
|
||
object CodegenConfigReader { | ||
|
||
sealed trait CodegenDest | ||
object Java extends CodegenDest | ||
object Scala extends CodegenDest | ||
|
||
type Result[A] = Either[ConfigLoadingError, A] | ||
|
||
def readFromEnv(dest: CodegenDest): Result[Conf] = | ||
for { | ||
sdkConf <- ProjectConfig.loadFromEnv() | ||
codegenConf <- codegenConf(sdkConf, dest) | ||
} yield codegenConf | ||
|
||
def codegenConf(sdkConf: ProjectConfig, dest: CodegenDest): Result[Conf] = | ||
for { | ||
dar <- darPath(sdkConf) | ||
packagePrefix <- packagePrefix(sdkConf, dest) | ||
outputDirectory <- outputDirectory(sdkConf, dest) | ||
decoderPkgAndClass <- decoderPkgAndClass(sdkConf, dest) | ||
verbosity <- verbosity(sdkConf, dest): Result[Option[Int]] | ||
logLevel <- logLevel(verbosity, Level.ERROR) | ||
root <- root(sdkConf, dest): Result[Option[List[String]]] | ||
} yield | ||
Conf( | ||
darFiles = Map(dar -> packagePrefix), | ||
outputDirectory = outputDirectory, | ||
decoderPkgAndClass = decoderPkgAndClass, | ||
verbosity = logLevel, | ||
roots = root.getOrElse(Nil) | ||
) | ||
|
||
private def darPath(sdkConf: ProjectConfig): Result[Path] = | ||
for { | ||
name <- name(sdkConf) | ||
version <- version(sdkConf) | ||
dar <- darPath(name, version) | ||
} yield dar | ||
|
||
private def name(sdkConf: ProjectConfig): Result[String] = | ||
sdkConf.name.flatMap { | ||
case Some(a) => Right(a) | ||
case None => Left(ConfigMissing("name")) | ||
} | ||
|
||
private def version(sdkConf: ProjectConfig): Result[String] = | ||
sdkConf.version.flatMap { | ||
case Some(a) => Right(a) | ||
case None => Left(ConfigMissing("version")) | ||
} | ||
|
||
private def darPath(name: String, version: String): Result[Path] = | ||
for { | ||
darFile <- result(new File(darDirectory, s"$name-$version.dar")) | ||
darPath <- result(darFile.toPath) | ||
} yield darPath | ||
|
||
private val darDirectory = new File(".daml/dist") | ||
|
||
private def packagePrefix(sdkConf: ProjectConfig, mode: CodegenDest): Result[Option[String]] = | ||
codegen(sdkConf, mode) | ||
.downField("package-prefix") | ||
.as[Option[String]] | ||
.left | ||
.map(configParseError) | ||
|
||
private def outputDirectory(sdkConf: ProjectConfig, mode: CodegenDest): Result[Path] = | ||
codegen(sdkConf, mode) | ||
.downField("output-directory") | ||
.as[String] | ||
.left | ||
.map(configParseError) | ||
.flatMap(path) | ||
|
||
private def decoderPkgAndClass( | ||
sdkConf: ProjectConfig, | ||
mode: CodegenDest): Result[Option[(String, String)]] = | ||
codegen(sdkConf, mode) | ||
.downField("decoderClass") | ||
.as[Option[String]] | ||
.left | ||
.map(configParseError) | ||
.flatMap(decoderClass) | ||
|
||
private def decoderClass(fa: Option[String]): Result[Option[(String, String)]] = | ||
fa match { | ||
case Some(a) => decoderClass(a).map(Some(_)) | ||
case None => resultR(None) | ||
} | ||
|
||
private def decoderClass(s: String): Result[(String, String)] = | ||
result(Conf.readClassName.reads(s)) | ||
|
||
private def verbosity(sdkConf: ProjectConfig, mode: CodegenDest): Result[Option[Int]] = | ||
codegen(sdkConf, mode) | ||
.downField("verbosity") | ||
.as[Option[Int]] | ||
.left | ||
.map(configParseError) | ||
|
||
private def logLevel(fa: Option[Int], default: Level): Result[Level] = | ||
fa.fold(resultR(default))(readVerbosity) | ||
|
||
private def readVerbosity(a: Int): Result[Level] = | ||
result(Conf.readVerbosity.reads(a.toString)) | ||
|
||
private def root(sdkConf: ProjectConfig, mode: CodegenDest): Result[Option[List[String]]] = | ||
codegen(sdkConf, mode) | ||
.downField("root") | ||
.as[Option[List[String]]] | ||
.left | ||
.map(configParseError) | ||
|
||
private def codegen(sdkConf: ProjectConfig, mode: CodegenDest): ACursor = | ||
sdkConf.content.hcursor | ||
.downField("codegen") | ||
.downField(dest(mode)) | ||
|
||
private def dest(a: CodegenDest): String = a match { | ||
case Java => "java" | ||
case Scala => "scala" | ||
} | ||
|
||
private def path(a: String): Result[Path] = | ||
result(new File(a).toPath) | ||
|
||
private def configParseError(e: Exception): ConfigParseError = ConfigParseError(e.getMessage) | ||
|
||
private def result[A](a: => A): Result[A] = | ||
result(Try(a)) | ||
|
||
private def result[A](fa: Try[A]): Result[A] = | ||
fa.toEither.left.map(e => ConfigLoadError(e.getMessage)) | ||
|
||
private def resultR[A](a: A): Result[A] = | ||
Right(a): Result[A] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.