Skip to content

Commit

Permalink
Fixing quickstart-scala example and doc (digital-asset#2901)
Browse files Browse the repository at this point in the history
* Fixing quickstart-scala example

* Updating docs

* Adding Scala codegen config

* Minor cleanup

* Apply suggestions from code review

Applying doc changes, thanks @bame-da!

Co-Authored-By: Bernhard Elsner <40762178+bame-da@users.noreply.github.com>
  • Loading branch information
2 people authored and mergify[bot] committed Sep 16, 2019
1 parent 0f015e9 commit c982478
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 96 deletions.
47 changes: 20 additions & 27 deletions docs/source/app-dev/bindings-scala/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ In order to use the Scala bindings, you should be familiar with:
- `Akka Streams API <https://doc.akka.io/docs/akka/current/stream/index.html>`_
- `Scala programming language <https://www.scala-lang.org>`_
- :ref:`assistant-manual-building-dars`
- :doc:`DAML codegen </tools/codegen>`

Getting started
===============
Expand All @@ -40,56 +41,48 @@ To use the Scala bindings, set up the following dependencies in your project:
:start-after: // <doc-ref:dependencies>
:end-before: // </doc-ref:dependencies>

We recommend separating generated code and application code into different modules. There are two modules in the example below:
We recommend separating generated code and application code into different modules. There are two modules in the ``quickstart-scala`` example:

- ``scala-codegen``
This modules contains all generated Scala classes.
This module will contain only generated Scala classes.
- ``application``
This is the application code that makes use of the generated Scala classes.

.. literalinclude:: ./code-snippets/quickstart-scala/build.sbt
:start-after: // <doc-ref:modules>
:end-before: // </doc-ref:modules>

``scala-codegen`` module uses the following function to generate Scala classes from a DAR file.

.. literalinclude:: ./code-snippets/quickstart-scala/build.sbt
:start-after: // <doc-ref:generate-scala>
:end-before: // </doc-ref:generate-scala>

You can get the entire `build.sbt file <https://github.com/digital-asset/daml/blob/master/language-support/scala/examples/quickstart-scala/build.sbt>`__ from the ``daml`` repository on GitHub.

Generating Scala code from the command line
===========================================

The above example demonstrates how to use Scala codegen from **sbt**. You can also call Scala codegen directly
from a command line.

Generating Scala code
=====================

1) Install :doc:`the latest version of the DAML SDK </getting-started/installation>`.

2) Download `the latest version of the Scala codegen command line interface <https://bintray.com/api/v1/content/digitalassetsdk/DigitalAssetSDK/com/daml/codegen-main/$latest/codegen-main-$latest.jar?bt_package=sdk-components>`_.
2) Build a **DAR** file from a **DAML** model. Refer to :ref:`assistant-manual-building-dars` for more instructions.

3) Configure ``codegen`` in the ``daml.yaml`` (for more details see :doc:`DAML codegen </tools/codegen>` documentation).

3) Build a **DAR** file from a **DAML** model. Refer to :ref:`assistant-manual-building-dars` for more instructions.
.. literalinclude:: ./code-snippets/quickstart-scala/daml.yaml
:start-after: # <doc-ref:codegen-scala>
:end-before: # </doc-ref:codegen-scala>

4) Run Scala codegen::

$ java -jar <parth-to-codegen-main-jar> scala <path-to-DAR-file>=<package-name> \
--output-directory=<path-to-output-directory> --verbosity=<0|1|2|3|4>
$ daml codegen scala

Here is an example, assuming SDK Version: **0.12.17**, DAR file: **./quickstart-scala.dar**,
package name: **com.digitalasset.quickstart.iou.model**, codegen output directory: **./codegen-out** and
verbosity level: **2** (INFO)::
If the command is successful, it should print::

$ java -jar codegen-main-100.12.17.jar scala ./quickstart-scala.dar=com.digitalasset.quickstart.iou.model \
--output-directory=./codegen-out --verbosity=2
...
Scala codegen
Reading configuration from project configuration file
[INFO ] Scala Codegen verbosity: INFO
[INFO ] decoding archive with Package ID: 5c96aa21d5f38386833ff47fe1a7562afb5b3fe5be520f289c42892dfb0ef42b
[INFO ] decoding archive with Package ID: 748d55be531976e941076a44fe8c06ad4a7bdb36160711dd0204b5ab8dc77e44
[INFO ] decoding archive with Package ID: d841a5e45897aea965ab7699f3e51613c9d00b9fbd1bb09658d7fb00486f5b57
[INFO ] Scala Codegen result:
Number of generated templates: 3
Number of not generated templates: 0
Details:

The output above tells that codegen produced Scala classes for 3 templates without errors (empty ``Details:`` line).
The output above tells that Scala codegen read configuration from ``daml.yaml`` and produced Scala classes for 3 templates without errors (empty ``Details:`` line).

Example code
============
Expand Down
3 changes: 0 additions & 3 deletions language-support/scala/examples/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ genrule(
cmd = """
mkdir -p $@
cp -rL $(SRCS) $@
rm -rf $@/project/project/*
ln -s ../Artifactory.scala $@/project/project/Artifactory.scala
ln -s ../Versions.scala $@/project/project/Versions.scala
rm -rf $@/target
rm -rf $@/project/target
rm -rf $@/application/target
Expand Down
63 changes: 57 additions & 6 deletions language-support/scala/examples/quickstart-scala/README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,73 @@
# quickstart-scala example

This example demonstrates how to:
- set up and configure Scala codegen
- set up and configure Scala codegen (see `codegen` configuration in the `./daml.yaml`)
- instantiate a contract and send a corresponding create command to the ledger
- how to exercise a choice and send a corresponding exercise command
- subscribe to receive ledger events and decode them into generated Scala ADTs

This examples requires a running sandbox. To start a sandbox, run the following command from within a DAML Assistant project directory:
All instructions below assume that you have DAML SDK installed. If you have not installed it yet, please follow these instructions: https://docs.daml.com/getting-started/installation.html

## Create a quickstart-scala project
```
daml new ./quickstart-scala quickstart-scala
```
This should output:
```
Created a new project in "./quickstart-scala" based on the template "quickstart-scala".
```
Where:
- `./quickstart-scala` is a project directory name
- `quickstart-scala` is a project template name, to see the entire list of available templates, run: `daml new --list`

## Compile the DAML project
The DAML code for the IOU example is located in the `./daml` folder. Run the following command to build it:
```
$ cd ./quickstart-scala
$ daml buld
```
this should output:
```
Compiling quickstart to a DAR.
Created .daml/dist/quickstart-0.0.1.dar.
```
$ daml start

## Generate Scala classes representing DAML contract templates
```
$ daml codegen scala
```
This should generate scala classes in the `./scala-codegen/src/main/scala` directory. See `codegen` configuration in the `daml.yaml` file:
```
...
codegen:
scala:
package-prefix: com.digitalasset.quickstart.iou.model
output-directory: scala-codegen/src/main/scala
verbosity: 2
```

To run the quickstart-scala example as part of a DAML Assistant project:
## Start Sandbox
This examples requires a running sandbox. To start it, run the following command:
```
$ daml sandbox ./.daml/dist/quickstart-0.0.1.dar
```
where `./.daml/dist/quickstart-0.0.1.dar` is the DAR file created in the previous step.

## Compile and run Scala example
Run the following command from the `quickstart-scala` folder:
```
$ sbt "application/runMain com.digitalasset.quickstart.iou.IouMain localhost 6865"
```
If example completes successfully, the above process should terminate and the output should look like this:
```
<Sent and received messages>
...
11:54:03.865 [run-main-0] INFO - Shutting down...
...
[success] Total time: 7 s, completed Sep 12, 2019, 11:54:04 AM
```

To run the quickstart-scala as a standalone project, you have to specify `da.sdk.version` and `dar.file` JVM system properties:
To run the quickstart-scala as a standalone project (not part of the DAML project), or to override the default SDK version configured in the `./SDK_VERSION` file, you have to specify `da.sdk.version` JVM system properties:
```
$ sbt -Dda.sdk.version=<DA_SDK_VERSION> -Ddar.file=<DAR_FILE_PATH> "application/runMain com.digitalasset.quickstart.iou.IouMain localhost 6865"
$ sbt -Dda.sdk.version=<DA_SDK_VERSION> "application/runMain com.digitalasset.quickstart.iou.IouMain localhost 6865"
```
35 changes: 0 additions & 35 deletions language-support/scala/examples/quickstart-scala/build.sbt
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import sbt._

import com.digitalasset.codegen.CodeGen.Novel
import com.digitalasset.codegen.CodeGen

import Versions._
import Artifactory._

Expand All @@ -26,15 +23,6 @@ lazy val `scala-codegen` = project
name := "scala-codegen",
commonSettings,
libraryDependencies ++= codeGenDependencies,
sourceGenerators in Compile += (damlScala in Compile).taskValue,
damlScala in Compile := {
generateScalaFrom(
darFile = darFile,
packageName = "com.digitalasset.quickstart.iou.model",
outputDir = (sourceManaged in Compile).value,
cacheDir = streams.value.cacheDirectory / name.value
)
}
)

lazy val `application` = project
Expand Down Expand Up @@ -71,26 +59,3 @@ lazy val applicationDependencies = Seq(
"com.daml.scala" %% "bindings-akka" % daSdkVersion,
)
// </doc-ref:dependencies>

lazy val damlScala = taskKey[Seq[File]]("Generate Scala code.")
damlScala := Seq() // by default, do nothing

// <doc-ref:generate-scala>
def generateScalaFrom(
darFile: File,
packageName: String,
outputDir: File,
cacheDir: File): Seq[File] = {

require(
darFile.getPath.endsWith(".dar") && darFile.exists(),
s"DAR file doest not exist: ${darFile.getPath: String}")

val cache = FileFunction.cached(cacheDir, FileInfo.hash) { _ =>
if (outputDir.exists) IO.delete(outputDir.listFiles)
CodeGen.generateCode(List(darFile), packageName, outputDir, Novel)
(outputDir ** "*.scala").get.toSet
}
cache(Set(darFile)).toSeq
}
// </doc-ref:generate-scala>
22 changes: 22 additions & 0 deletions language-support/scala/examples/quickstart-scala/daml.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
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
# <doc-ref:codegen-scala>
codegen:
scala:
package-prefix: com.digitalasset.quickstart.iou.model
output-directory: scala-codegen/src/main/scala
verbosity: 2
# </doc-ref:codegen-scala>
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,6 @@ object Versions {
val daSdkVersion: String = sys.props.get(daSdkVersionKey).getOrElse(sdkVersionFromFile())
println(s"$daSdkVersionKey = ${daSdkVersion: String}")

private val darFileKey = "dar.file"

val darFile = sys.props
.get(darFileKey)
.map(s => new sbt.File(s))
.getOrElse(new sbt.File(s"./dist/${projectNameFromConfig(): String}.dar"))
println(s"$darFileKey = ${darFile.getAbsolutePath: String}")

private def sdkVersionFromFile(): String =
"10" + sbt.IO.read(new sbt.File("./SDK_VERSION").getAbsoluteFile).trim

private def projectNameFromConfig(): String =
sbt.IO
.readLines(new sbt.File("./daml.yaml").getAbsoluteFile)
.find(_.startsWith("name:"))
.map(_.replaceFirst("name:", "").trim)
.getOrElse(throw new IllegalStateException(s"Cannot read project name from a config file"))
}

This file was deleted.

This file was deleted.

This file was deleted.

5 changes: 5 additions & 0 deletions templates/quickstart-scala/daml.yaml.template
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ exposed-modules:
dependencies:
- daml-prim
- daml-stdlib
codegen:
scala:
package-prefix: com.digitalasset.quickstart.iou.model
output-directory: scala-codegen/src/main/scala
verbosity: 2

0 comments on commit c982478

Please sign in to comment.