Skip to content

Latest commit

 

History

History

examples

Scala 3 examples

Dotty project Directory examples\ contains Scala 3 code examples coming from various websites - mostly from the Dotty project.

We choose examples\enum-Planet to demonstrate the usage of the build tools we do support:

> cd
Y:\examples\enum-Planet

Build tools rely on one or more configuration files to achieve their tasks. In our case we provide the following configuration files for enum-Planet:

Build tool Build file(s) Parent file(s) Environment(s)
ant.bat build.xml build.xml, ivy.xml Any a)
bazel.exe BUILD, WORKSPACE n.a. Any
cmd.exe build.bat
(build.properties)
cpath.bat b) Windows only
sh.exe build.sh
(build.properties)
Cygwin/MSYS2/Unix only
gradle.exe build.gradle common.gradle Any
make.exe c) Makefile Makefile.inc Any
mill.bat build.sc common.sc Any
mvn.cmd pom.xml pom.xml Any
sbt.bat build.sbt n.a. Any
scala-cli.exe Any
a) Here "Any" means "tested on Windows, Cygwin, MSYS2 and Unix".
b) This utility batch file manages Maven dependencies and returns the associated Java class path (as environment variable).
c) Default shell is /bin/sh as described in the online document Choosing the Shell.
 
 

Ant build tool

The Ant build file enum-Planet\build.xml depends on the parent file examples\build.xml which provides the macro definition dotc to compile the Scala source files.

🔎 Command ant.bat ("Another Neat Tool") is a Java-based build tool maintained by the Apache Software Foundation (tool created in 2000). It works with XML-based configuration files.

Execution of Planet.scala produces the following output (Ivy support is enabled by default):

> ant clean run
Buildfile: Y:\examples\enum-Planet\build.xml

clean:
   [delete] Deleting directory Y:\examples\enum-Planet\target

init.local:

init.ivy:
[ivy:resolve] :: Apache Ivy 2.5.2- 20230817170011 :: https://ant.apache.org/ivy/ ::
[ivy:resolve] :: loading settings :: url = jar:file:/C:/opt/apache-ant/lib/ivy-2.5.2.jar!/org/apache/ivy/core/settings/ivysettings.xml

init:

compile:
    [mkdir] Created dir: Y:\examples\enum-Planet\target\classes
   [scalac] Compiling 1 source file to Y:\examples\enum-Planet/target/classes

run:
     [java] Your weight on MERCURY (0) is 0.37775761520093526
     [java] Your weight on VENUS (1) is 0.9049990998410455
     [java] Your weight on EARTH (2) is 0.9999999999999999
     [java] Your weight on MARS (3) is 0.37873718403712886
     [java] Your weight on JUPITER (4) is 2.5305575254957406
     [java] Your weight on SATURN (5) is 1.0660155388115666
     [java] Your weight on URANUS (6) is 0.9051271993894251
     [java] Your weight on NEPTUNE (7) is 1.1383280724696578

BUILD SUCCESSFUL
Total time: 19 seconds

Apache Ivy
We observe from task init.ivy that the Apache Ivy library has been added to the Ant installation directory. In our case we installed version 2.5.2 of the Apache Ivy library.

> curl -sL -o c:\Temp\apache-ivy-2.5.2.zip https://www-eu.apache.org/dist/ant/ivy/2.5.2/apache-ivy-2.5.2-bin.zip
> unzip c:\temp\apache-ivy-2.5.2.zip -d c:\opt
> copy c:\opt\apache-ivy-2.5.2\ivy-2.5.2.jar c:\opt\apache-ant-1.10.13\lib
> dir c:\opt\apache-ant\lib | findstr ivy
20.10.2019  09:44         1 402 646 ivy-2.5.2.jar

We can set property -Duse.local=true to use Scala 3 local installation (reminder: in our case environment variable SCALA3_HOME is set by command setenv):

> ant -Duse.local=true clean run
Buildfile: Y:\examples\enum-Planet\build.xml

clean:
   [delete] Deleting directory Y:\examples\enum-Planet\target

init.local:
     [echo] SCALA3_HOME=C:\opt\scala3-3.3.3

init.ivy:

init:

compile:
    [mkdir] Created dir: Y:\examples\enum-Planet\target\classes
    [scalac] Compiling 1 source file to Y:\examples\enum-Planet/target/classes

run:
     [java] Your weight on MERCURY (0) is 0.37775761520093526
     [java] Your weight on VENUS (1) is 0.9049990998410455
     [java] Your weight on EARTH (2) is 0.9999999999999999
     [java] Your weight on MARS (3) is 0.37873718403712886
     [java] Your weight on JUPITER (4) is 2.5305575254957406
     [java] Your weight on SATURN (5) is 1.0660155388115666
     [java] Your weight on URANUS (6) is 0.9051271993894251
     [java] Your weight on NEPTUNE (7) is 1.1383280724696578

BUILD SUCCESSFUL
Total time: 14 seconds

Batch command

Command build.bat is our basic build tool featuring subcommands clean, compile, decompile, doc, help, lint, run and test; the batch file consists of ~790 lines of batch/Powershell code 1.

Command build.bat clean run generates the following output:

> build clean run
Your weight on MERCURY (0) is 0.37775761520093526
Your weight on VENUS (1) is 0.9049990998410455
Your weight on EARTH (2) is 0.9999999999999999
Your weight on MARS (3) is 0.37873718403712886
Your weight on JUPITER (4) is 2.5305575254957406
Your weight on SATURN (5) is 1.0660155388115666
Your weight on URANUS (6) is 0.9051271993894251
Your weight on NEPTUNE (7) is 1.1383280724696578

🔎 Compilation of the Java/Scala source files is performed only if needed during the build process:

> build clean
 
> build compile
 
> build -verbose compile
No action required ("src\main\scala\*.scala")

Command build -verbose clean run also displays progress messages:

> build -verbose clean run
Delete directory "target"
Compile 1 Scala source file to directory "target\classes"
Execute Scala main class Planet
Your weight on MERCURY (0) is 0.37775761520093526
Your weight on VENUS (1) is 0.9049990998410455
Your weight on EARTH (2) is 0.9999999999999999
Your weight on MARS (3) is 0.37873718403712886
Your weight on JUPITER (4) is 2.5305575254957406
Your weight on SATURN (5) is 1.0660155388115666
Your weight on URANUS (6) is 0.9051271993894251
Your weight on NEPTUNE (7) is 1.1383280724696578

Command build -debug clean run also displays internal steps of the build process:

> build -debug clean run
[build] Properties : _PROJECT_NAME=enum-Planet _PROJECT_VERSION=1.0-SNAPSHOT
[build] Options    : _EXPLAIN=0 _PRINT=0 _SCALA_VERSION=3 _TASTY=0 _TIMER=0 _VERBOSE=0
[build] Subcommands:  clean compile run
[build] Variables  : "CFR_HOME=C:\opt\cfr-0.152"
[build] Variables  : "JAVA_HOME=C:\opt\jdk-temurin-17.0.9_9"
[build] Variables  : "SCALA3_HOME=C:\opt\scala3-3.3.3"
[build] Variables  : "SCALA_HOME=C:\opt\scala-2.13.12"
[build] Variables  : _MAIN_CLASS=Planet _MAIN_ARGS=1
[build] del /s /q Y:\dotty\examples\enum-Planet\target\classes\*.class Y:\dotty\examples\enum-Planet\target\classes\*.hasTasty Y:\dotty\examples\enum-Planet\target\classes\.latest-build
[build] 20180322224754 Y:\dotty\examples\enum-Planet\src\main\scala\Planet.scala
[build] 00000000000000 Y:\dotty\examples\enum-Planet\target\classes\.latest-build
[build] scalac "@Y:\examples\enum-Planet\target\scalac_opts.txt" "@Y:\examples\enum-Planet\target\scalac_sources.txt"
[build] scala -classpath [...];Y:\dotty\examples\enum-Planet\target\classes Planet 1
Your weight on MERCURY is 0.37775761520093526
Your weight on VENUS (1) is 0.9049990998410455
Your weight on EARTH (2) is 0.9999999999999999
Your weight on MARS (3) is 0.37873718403712886
Your weight on JUPITER (4) is 2.5305575254957406
Your weight on SATURN (5) is 1.0660155388115666
Your weight on URANUS (6) is 0.9051271993894251
Your weight on NEPTUNE (7) is 1.1383280724696578
[build] _EXITCODE=0

🔎 The above enum-Planet example expects 1 argument at execution time.
For simplicity the build command currently relies on the property main.args defined in file project\build.properties (part of the SBT configuration) to specify program arguments.

> type project\build.properties
sbt.version=1.9.8
 
main.class=Planet
main.args=1

🔎 The output generated with options -verbose and -debug are redirected to stderr and can be discarded by adding 2>NUL, e.g.:

> build clean run -debug 2>NUL
Your weight on MERCURY (0) is 0.37775761520093526
Your weight on SATURN (5) is 1.0660155388115666
Your weight on VENUS (1) is 0.9049990998410455
Your weight on URANUS (6) is 0.9051271993894251
Your weight on EARTH (2) is 0.9999999999999999
Your weight on NEPTUNE (7) is 1.1383280724696578
Your weight on MARS (3) is 0.37873718403712886
Your weight on JUPITER (4) is 2.5305575254957406

Finally, command build -verbose decompile decompiles the generated bytecode with CFR:

> build -verbose decompile
No action required ("src\main\scala\*.scala")
Decompile Java bytecode to directory "target\cfr-sources"
Processing Planet$
Processing Planet
Save decompiled Java source files to "target\cfr-sources_scala3_3.3.1.java"
 
> dir /b /s target\*.java
Y:\examples\enum-Planet\target\cfr-sources_scala3_3.3.1.java
Y:\examples\enum-Planet\target\cfr-sources\Planet$.java
Y:\examples\enum-Planet\target\cfr-sources\Planet.java

If the two Java source files src\build\cfr-sources_scala<n>_<version>.txt (check file) and target\cfr-sources_scala<n>_<version>.txt (output file) are present subcommand decompile also invokes the diff command to show differences between the check file and the output file:

> dir /b src\build
cfr-sources_scala3_3.1.0.java
cfr-sources_scala3_3.2.2.java
cfr-sources_scala3_3.3.0.java
cfr-sources_scala3_3.3.1.java
 
> build -verbose decompile
No action required ("src\main\scala\*.scala")
Decompile Java bytecode to directory "target\cfr-sources"
Save decompiled Java source files to "target\cfr-sources_scala3_3.3.1.java"
Compare output file with check file "src\build\cfr-sources_scala3_3.3.1.java"

Shell command

Bash script build.sh is our basic build tool for Unix environments like Cygwin, Linux or MSYS2; it features subcommands clean, compile, doc, help, lint and run; the Bash script consists of ~500 lines of Bash code.

Command sh build.sh clean run produces the following output:

> sh ./build.sh clean run
Mass of earth is 0.1020132025669991
Your weight on MERCURY (0) is 0.37775761520093526
Your weight on VENUS (1) is 0.9049990998410455
Your weight on EARTH (2) is 0.9999999999999999
Your weight on MARS (3) is 0.37873718403712886
Your weight on JUPITER (4) is 2.5305575254957406
Your weight on SATURN (5) is 1.0660155388115666
Your weight on URANUS (6) is 0.9051271993894251
Your weight on NEPTUNE (7) is 1.1383280724696578

Gradle build tool

The Gradle build file enum-Planet\build.gradle depends on the parent file examples\common.gradle which defines the task compileDotty and manages the task dependencies.

🔎 Command gradle is the official build tool for Android applications. Created in 2007 it replaces XML-based build scripts with a Groovy-based DSL.

Command gradle -q clean run produces the following output (Planet.scala):

> gradle -q clean run
Your weight on MERCURY (0) is 0.37775761520093526
Your weight on VENUS (1) is 0.9049990998410455
Your weight on EARTH (2) is 0.9999999999999999
Your weight on MARS (3) is 0.37873718403712886
Your weight on JUPITER (4) is 2.5305575254957406
Your weight on SATURN (5) is 1.0660155388115666
Your weight on URANUS (6) is 0.9051271993894251
Your weight on NEPTUNE (7) is 1.1383280724696578

Gradle Wrappers
We don't rely on them even if using Gradle Wrapper is the recommended way to execute a Gradle build.
Simply execute the gradle wrapper command to generate the wrapper files; you can then run gradlew instead of gradle.

Make build tool

The Make build file enum-Planet\Makefile depends on the parent file examples\Makefile.inc which defines common settings (i.e. tool and library paths).

🔎 Command make automatically builds executable programs and libraries from source code by reading files called Makefiles which specify how to derive the target program. Make was originally created by Stuart Feldman in April 1976 at Bell Labs.

Command make clean run produces the following output (Planet.scala):

> make clean run
rm -rf "target"
[ -d "target/classes" ] || mkdir -p "target/classes"
scalac.bat "@target/scalac_opts.txt" "@target/scalac_sources.txt"
scala.bat -classpath "target/classes" Planet 1
Your weight on MERCURY (0) is 0.37775761520093526
Your weight on VENUS (1) is 0.9049990998410455
Your weight on EARTH (2) is 0.9999999999999999
Your weight on MARS (3) is 0.37873718403712886
Your weight on JUPITER (4) is 2.5305575254957406
Your weight on SATURN (5) is 1.0660155388115666
Your weight on URANUS (6) is 0.9051271993894251
Your weight on NEPTUNE (7) is 1.1383280724696578

Command make test executes the test suite PlanetTest.scala for program Planet.scala.

> make test
[ -d "target/test-classes" ] || mkdir -p "target/test-classes"
scalac.bat "@target/scalac_test_opts.txt" "@target/scalac_test_sources.txt"
java.exe -classpath "%USERPROFILE%/.m2/repository/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar;%USERPROFILE%/.m2/repository/org.scala-lang/scala3-library_3/3.3.1/scala3-library_3-3.3.1.jar;%USERPROFILE%/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar;%USERPROFILE%/.m2/repository/junit/junit/4.13.2/junit-4.13.2.jar;%USERPROFILE%/.m2/repository/com/novocode/junit-interface/0.11/junit-interface-0.11.jar;target/classes;target/test-classes" org.junit.runner.JUnitCore PlanetTest
JUnit version 4.13.2
..
Time: 0.239

OK (2 tests)

Command make doc generates the HTML documentation for program enum-Planet.scala:

> make doc
[ -d "target/docs" ] || mkdir -p "target/docs"
dotd.bat "@target/scaladoc_opts.txt" "@target/scaladoc_sources.txt"
Compiling (1/1): Planet.scala
[doc info] Generating doc page for: 
[doc info] Generating doc page for: .Planet
[doc info] Generating doc page for: .Planet$
[doc info] Generating doc page for: .Planet
[doc info] Generating doc page for: .Planet$
[...]
public members with docstrings:    0
protected members with docstrings: 0
private members with docstrings:   0/3 (0%)

Maven build tool

The Maven build file enum-Planet\pom.xml depends on the parent file ../pom.xml which defines common properties 2 (eg. java.version, scala.version).

🔎 Command mvn is a Java-based build tool maintained by the Apache Software Foundation. Created in 2002 it works with XML-based configuration files and provides a way to share JARs across several projects.

Command mvn.cmd compile test with option -debug produces additional debug information, including the underlying command lines executed by our Maven plugin scala-maven-plugin:

> mvn -debug compile test | findstr /b /c:"[DEBUG]\ [execute]" 2>NUL
[DEBUG] [execute] C:\opt\jdk-temurin-17.0.9_9\bin\java.exe \
 -Xms64m -Xmx1024m -Dscala.home=C:\opt\scala3-3.3.3 \
 -cp C:\opt\scala3-3.3.3\lib\*.jar -Dscala.usejavacp=true  \
 dotty.tools.dotc.Main \
 -classpath Y:\examples\hello-scala\target\classes \
 -d Y:\examples\hello-scala\target\classes \
 Y:\examples\hello-scala\src\main\scala\hello.scala
[DEBUG] [execute] C:\opt\jdk-temurin-17.0.9_9\bin\java.exe \
 -Xms64m -Xmx1024m -Dscala.home=C:\opt\scala3-3.3.3 [...]
[DEBUG] [execute] C:\opt\jdk-temurin-17.0.9_9\bin\java.exe \
 -Xms64m -Xmx1024m -cp C:\opt\scala3-3.3.3\lib\*.jar;\
Y:\examples\hello-scala\target\classes hello

🔎 The following command outputs the classpath being used by mvn into the text file classpath.txt :

> mvn dependency:build-classpath -Dmdep.outputFile=classpath.txt

Command mvn.cmd --quiet clean test produces the following output:

> mvn --quiet clean test
Your weight on MERCURY (0) is 0.37775761520093526
Your weight on VENUS (1) is 0.9049990998410455
Your weight on EARTH (2) is 0.9999999999999999
Your weight on MARS (3) is 0.37873718403712886
Your weight on JUPITER (4) is 2.5305575254957406
Your weight on SATURN (5) is 1.0660155388115666
Your weight on URANUS (6) is 0.9051271993894251
Your weight on NEPTUNE (7) is 1.1383280724696578
> mvn clean compile package
...
[INFO]
[INFO] --- maven-jar-plugin:3.3.0:jar (default-jar) @ enum-Planet ---
[INFO] Building jar: Y:\examples\enum-Planet\target\enum-Planet-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  9.468 s
[INFO] Finished at: 2019-07-27T19:53:09+01:00
[INFO] ------------------------------------------------------------------------

> java -version 2>&1 | findstr version
openjdk version "11.0.19" 2023-04-18

> java -Xbootclasspath/a:"c:\opt\scala3-3.3.3\lib\scala3-library_3-3.3.3.jar;c:\opt\scala3-3.3.3\lib\scala-library-2.13.10.jar" -jar target\enum-Planet-1.0-SNAPSHOT.jar 1
Your weight on MERCURY (0) is 0.37775761520093526
Your weight on VENUS (1) is 0.9049990998410455
Your weight on EARTH (2) is 0.9999999999999999
Your weight on MARS (3) is 0.37873718403712886
Your weight on JUPITER (4) is 2.5305575254957406
Your weight on SATURN (5) is 1.0660155388115666
Your weight on URANUS (6) is 0.9051271993894251
Your weight on NEPTUNE (7) is 1.1383280724696578

Scala Maven Plugin
In the above Maven configuration file we note the presence of the Maven plugin scala-maven-plugin. In fact the parent file examples\pom.xml depends on scala-maven-plugin, a Maven plugin we developed specifically for this project (see document maven-plugins\README.md):

> more ..\pom.xml
<?xml version="1.0" encoding="UTF-8"?>
...
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
 
        <!-- Scala settings -->
        <scala.version>3.3.3</scala.version>
        <scala.local.install>true</scala.local.install>
 
        <!-- Maven plugins -->
        <scala.maven.version>1.0.0</scala.maven.version>
        ...
    </properties>
    <dependencies>
        <dependency>
            <groupId>ch.epfl.alumni</groupId>
            <artifactId>scala-maven-plugin</artifactId>
            <version>${scala.maven.version}</version>
        </dependency>
        ...
    </dependencies>

</project>

The plugin is available as Zip archive and its installation is deliberately very simple:

> unzip ..\bin\scala-maven-plugin-1.0.zip %USERPROFILE%\.m2\repository\
> tree /a /f %USERPROFILE%\.m2\repository\ch\epfl\alumni | findstr /v "^[A-Z]"
\---scala-maven-plugin
    |   maven-metadata.xml
    |   maven-metadata.xml.md5
    |   [..]
    |
    \---1.0.1
            scala-maven-plugin-1.0.1.jar
            scala-maven-plugin-1.0.1.jar.md5
            scala-maven-plugin-1.0.1.pom
            scala-maven-plugin-1.0.1.pom.md5
            [..]

Mill build tool

The Mill build file enum-Planet\build.sc depends on the parent file examples\common.sc which defines the common settings.

🔎 Command mill is a Scala-based build tool which aims for simplicity to build projects in a fast and predictable manner.

Command mill.bat -i app produces the following output:

> mill -i app.run 1
[38/38] app.run
Your weight on MERCURY (0) is 0.37775761520093526
Your weight on VENUS (1) is 0.9049990998410455
Your weight on EARTH (2) is 0.9999999999999999
Your weight on MARS (3) is 0.37873718403712886
Your weight on JUPITER (4) is 2.5305575254957406
Your weight on SATURN (5) is 1.0660155388115666
Your weight on URANUS (6) is 0.9051271993894251
Your weight on NEPTUNE (7) is 1.1383280724696578

🔎 The user has to execute two mill commands to perform a clean build and run the application :

> mill -i app.clean & mill -i app.run 1
[1/1] app.clean
[27/39] app.compile
[info] compiling 1 Scala source to Y:\examples\enum-Planet\out\app\compile\dest\classes ...
[info] done compiling
[39/39] app.run
Mass of earth is 0.1020132025669991
Your weight on MERCURY (0) is 0.37775761520093526
[...]

SBT build tool

The SBT build file build.sbt is written in Scala and obeys the sbt build definitions.

🔎 Lightbend provides commercial support for the sbt build tool.

Command sbt.bat -warn clean "run 1" produces the following output:

> sbt -warn clean "run 1"
Your weight on MERCURY (0) is 0.37775761520093526
Your weight on VENUS (1) is 0.9049990998410455
Your weight on EARTH (2) is 0.9999999999999999
Your weight on MARS (3) is 0.37873718403712886
Your weight on JUPITER (4) is 2.5305575254957406
Your weight on SATURN (5) is 1.0660155388115666
Your weight on URANUS (6) is 0.9051271993894251
Your weight on NEPTUNE (7) is 1.1383280724696578

scala-cli tool

Specifying option -cli in command build.bat does call scala-cli.exe with the appropriate options:

> build -cli -debug run
[build] Properties : _PROJECT_NAME=enum-Planet _PROJECT_VERSION=1.0-SNAPSHOT
[build] Options    : _EXPLAIN=0 _PRINT=0 _SCALA_VERSION=3 _TASTY=0 _TIMER=0 _VERBOSE=0
[build] Subcommands:  compile run
[build] Variables  : "CFR_HOME=C:\opt\cfr-0.152"
[build] Variables  : "JAVA_HOME=C:\opt\jdk-temurin-17.0.9_9"
[build] Variables  : "SCALA_CLI_HOME=c:\opt\scala-cli"
[build] Variables  : "SCALA_HOME=C:\opt\scala-2.13.12"
[build] Variables  : "SCALA3_HOME=C:\opt\scala3-3.3.3"
[build] Variables  : _MAIN_CLASS=Planet _MAIN_ARGS=1
[build] "c:\opt\scala-cli\scala-cli.exe" compile -v -O -deprecation --scala 3 "Y:\examples\enum-Planet\src\main\scala"
Compiling project (Scala 3.3.1, JVM)
Compiled project (Scala 3.3.1, JVM)
[build] "c:\opt\scala-cli\scala-cli.exe" run -v --scala 3 --main-class "Planet" "Y:\examples\enum-Planet\src\main\scala" -- 1
Compiling project (Scala 3.3.1, JVM)
Compiled project (Scala 3.3.1, JVM)
Running C:\opt\jdk-temurin-17.0.9_9\bin\java.exe -cp Y:\examples\enum-Planet\src\main\scala\.scala-build\project_909ac66893\classes\main;C:\Users\michelou\AppData\Local\Coursier\cache\v1\https\repo1.maven.org\maven2\org\scala-lang\scala3-library_3\3.3.1\scala3-library_3-3.3.1.jar;C:\Users\michelou\AppData\Local\Coursier\cache\v1\https\repo1.maven.org\maven2\org\scala-lang\scala-library\2.13.10\scala-library-2.13.10.jar Planet 1
Mass of earth is 0.1020132025669991
Your weight on MERCURY (0) is 0.37775761520093526
Your weight on VENUS (1) is 0.9049990998410455
Your weight on EARTH (2) is 0.9999999999999999
Your weight on MARS (3) is 0.37873718403712886
Your weight on JUPITER (4) is 2.5305575254957406
Your weight on SATURN (5) is 1.0660155388115666
Your weight on URANUS (6) is 0.9051271993894251
Your weight on NEPTUNE (7) is 1.1383280724696578
[build] _EXITCODE=0

Footnotes

[1] Batch files and coding conventions

We strive to obey the following coding conventions in our batch files (e.g. enum-Planet\build.bat) :
  • We use at most 80 characters per line. In general we would say that 80 characters fit well with 4:3 screens and 100 characters fit well with 16:9 screens (both Databricks and Google use the convention of 100 characters).
  • We organize our code in 4 sections: Environment setup, Main, Subroutines and Cleanups.
  • We write exactly one exit instruction (label end in section Cleanups).
  • We adopt the following naming conventions: global variables start with character _ (shell variables defined in the user environment start with a letter) and local variables (e.g. inside subroutines or if/for constructs) start with __ (two _ characters).
@echo off
setlocal enabledelayedexpansion
 
@rem ##########################################################################
@rem ## Environment setup
 
set _EXITCODE=0
 
call :env
if not %_EXITCODE%==0 goto end
 
call :props
if not %_EXITCODE%==0 goto end
 
call :args %*
if not %_EXITCODE%==0 goto end
 
@rem ##########################################################################
@rem ## Main
 
if %_CLEAN%==1 (
    call :clean
    if not !_EXITCODE!==0 goto end
)
if %_COMPILE%==1 (
    call :compile
    if not !_EXITCODE!==0 goto end
)
if %_LINT%==1 (
    call :lint
    if not !_EXITCODE!==0 goto end
)
if %_DOC%==1 (
    call :doc
    if not !_EXITCODE!==0 goto end
)
if %_RUN%==1 (
    call :run
    if not !_EXITCODE!==0 goto end
)
goto end
 
@rem ##########################################################################
@rem ## Subroutines
 
:env
...(variable initialization, eg. directory paths)...
goto :eof
:props
...(read file build.properties if present)...
goto :eof
:args
...(command line options/subcommands)...
goto :eof
:clean
...(delete generated files/directories)...
goto :eof
:compile
...
goto :eof
:lint
...
goto :eof
:doc
...
goto :eof
:run
...
goto :eof
 
@rem ##########################################################################
@rem ## Cleanups
 
:end
...
exit /b %_EXITCODE%

[2] Useful Maven commands

The following command performs all substitutions for user-defined properties and imports and displays the resulting POM file.
> mvn help:effective-pom
Source : Complete Maven Tutorial by Sai Upadhyayula, December 2020.

[3] Scala annotation @main

> type src\main\scala\Main.scala
@main
def main = 
  println("Hello")
 
> %JAVA_HOME%\bin\javap -cp target\classes main
Compiled from "Main.scala"
public final class main {
  public main();
  public static void main(java.lang.String[]);
}

mics/May 2024