diff --git a/.github/scripts/package_lfc.sh b/.github/scripts/package-cli.sh similarity index 71% rename from .github/scripts/package_lfc.sh rename to .github/scripts/package-cli.sh index f72f2c299f..4eb51afd70 100755 --- a/.github/scripts/package_lfc.sh +++ b/.github/scripts/package-cli.sh @@ -2,20 +2,20 @@ set -euo pipefail -# build lf compiler -./gradlew clean buildLfc +# build lf cli tools +./gradlew clean buildAll # find the version number -jar_path="org.lflang.cli/build/libs/org.lflang.cli-*-lfc.jar" -version="$(ls ${jar_path} | xargs -n 1 basename | sed 's/^org.lflang.cli-\(.*\)-lfc.jar$/\1/')" +jar_path="org.lflang/build/libs/org.lflang-*.jar" +version="$(ls ${jar_path} | xargs -n 1 basename | sed 's/^org.lflang-\(.*\).jar$/\1/')" # use a different naming convention for nightly build artifacts if [[ "$#" > 0 && "$1" = "nightly" ]]; then echo "Packaging Lingua Franca Nightly Build" - outname="lfc_nightly_$(date '+%Y%m%d-%H%M%S')" + outname="lf-cli-nightly-$(date '+%Y%m%d-%H%M%S')" else echo "Packaging Lingua Franca v${version}" - outname="lfc_${version}" + outname="lf-cli-${version}" fi # assemble the files in a separate directory @@ -24,13 +24,15 @@ mkdir -p "${outname}/lib/scripts" mkdir -p "${outname}/lib/jars" # move the jar -mv org.lflang.cli/build/libs/org.lflang.cli-*-lfc.jar "${outname}/lib/jars" +mv org.lflang/build/libs/org.lflang-*.jar "${outname}/lib/jars" # copy the Bash scripts cp -a lib/scripts "${outname}/lib/" ln -s "../lib/scripts/launch.sh" "${outname}/bin/lfc" +ln -s "../lib/scripts/launch.sh" "${outname}/bin/lff" # copy the PowerShell script cp bin/lfc.ps1 "${outname}/bin/lfc.ps1" +cp bin/lff.ps1 "${outname}/bin/lff.ps1" # zip/tar everything - the files will be put into the build_upload directory mkdir -p build_upload diff --git a/.github/scripts/test-build.sh b/.github/scripts/test-build.sh new file mode 100755 index 0000000000..36ba4011c1 --- /dev/null +++ b/.github/scripts/test-build.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# Exit 1 if any command returns with a non-zero exit code. +set -euo pipefail + +cd $GITHUB_WORKSPACE + +function test_with_links() { + rm -rf foo + mkdir -p foo/bar/baz + ln -s ../bin/${1} foo/link-foo + ln -s ../link-foo foo/bar/link-bar + ln -s ../link-bar foo/bar/baz/link-baz + foo/bar/baz/link-baz --help +} + +# Test the build-lf-cli executable and its flags. +bin/build-lf-cli +bin/build-lf-cli --help +bin/build-lf-cli -h +bin/build-lf-cli -c -o -s +bin/build-lf-cli --clean --offline --stacktrace + +# Ensure that build-lf-cli is robust to symbolic links. +test_with_links "build-lf-cli" diff --git a/.github/scripts/test-lfc.sh b/.github/scripts/test-lfc.sh index d61f708132..f29b49af65 100755 --- a/.github/scripts/test-lfc.sh +++ b/.github/scripts/test-lfc.sh @@ -10,23 +10,10 @@ function test_with_links() { mkdir -p foo/bar/baz ln -s ../bin/${1} foo/link-foo ln -s ../link-foo foo/bar/link-bar - ln -s ../link-bar foo/bar/baz/link-baz - foo/bar/baz/link-baz --help + ln -s ../link-bar foo/bar/baz/link-${1} + foo/bar/baz/link-${1} --help } -# Test the build-lfc executable and its flags. -bin/build-lfc -bin/build-lfc --help -bin/build-lfc -h -bin/build-lfc --run --help -bin/build-lfc -r --help -bin/build-lfc --run test/C/src/Minimal.lf -bin/build-lfc -c -o -s -bin/build-lfc --clean --offline --stacktrace - -# Ensure that build-lfc is robust to symbolic links. -test_with_links "build-lfc" - bin/lfc test/C/src/Minimal.lf # -c,--clean Clean before building. diff --git a/.github/scripts/test-lff.sh b/.github/scripts/test-lff.sh new file mode 100755 index 0000000000..b16a5ad46a --- /dev/null +++ b/.github/scripts/test-lff.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# Exit 1 if any command returns with a non-zero exit code. +set -euo pipefail + +cd $GITHUB_WORKSPACE + +function test_with_links() { + rm -rf foo + mkdir -p foo/bar/baz + ln -s ../bin/${1} foo/link-foo + ln -s ../link-foo foo/bar/link-bar + ln -s ../link-bar foo/bar/baz/link-${1} + foo/bar/baz/link-${1} --help +} + +# just a couple of smoke tests +bin/lff --help +bin/lff --version + +bin/lff -d test/C/src/Minimal.lf +bin/lff --dry-run test/Cpp/src/Minimal.lf + +bin/lff -d test/C/src/Minimal.lf +bin/lff --dry-run test/Cpp/src/Minimal.lf + +# Ensure that lff is robust to symbolic links. +test_with_links "lff" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6158844feb..8b70202d0c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,12 +23,12 @@ jobs: fetch-depth: 0 - name: Prepare build environment uses: ./.github/actions/prepare-build-env - - name: Build and package lfc (nightly build) - run: .github/scripts/package_lfc.sh nightly + - name: Build and package lf cli tools (nightly build) + run: .github/scripts/package-cli.sh nightly shell: bash if: ${{ inputs.nightly == true }} - - name: Build and package lfc (regular build) - run: .github/scripts/package_lfc.sh + - name: Build and package lf cli tools (regular build) + run: .github/scripts/package-cli.sh shell: bash if: ${{ inputs.nightly != true }} - name: Check Maven/Java configuration diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0413935fcb..895029f444 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,9 +20,9 @@ jobs: cancel: uses: lf-lang/lingua-franca/.github/workflows/cancel.yml@master - # Test the Maven build. + # Test the Gradle and Maven build. build: - uses: lf-lang/lingua-franca/.github/workflows/build.yml@master + uses: lf-lang/lingua-franca/.github/workflows/build.yml@refactor-cli needs: cancel # Run the unit tests. @@ -32,7 +32,7 @@ jobs: # Run tests for the standalone compiler. cli-tests: - uses: lf-lang/lingua-franca/.github/workflows/cli-tests.yml@master + uses: lf-lang/lingua-franca/.github/workflows/cli-tests.yml@refactor-cli needs: cancel # Run the C benchmark tests. diff --git a/.github/workflows/cli-tests.yml b/.github/workflows/cli-tests.yml index b8aeee8d10..9aaced4aba 100644 --- a/.github/workflows/cli-tests.yml +++ b/.github/workflows/cli-tests.yml @@ -16,15 +16,24 @@ jobs: fetch-depth: 0 - name: Prepare build environment uses: ./.github/actions/prepare-build-env - - name: Run standalone cli tests + # FIXME: reenable once the cli test is fixed + # - name: Run standalone cli tests + # run: | + # ./gradlew :org.lflang.cli:test --stacktrace + - name: Test build bash scripts (Linux and macOS only) run: | - ./gradlew :org.lflang.cli:test --stacktrace - - name: Test Bash scripts (Linux or macOS only) + .github/scripts/test-build.sh + if: ${{ runner.os == 'macOS' || runner.os == 'Linux' }} + - name: Test lfc bash scripts (Linux or macOS only) run: | .github/scripts/test-lfc.sh if: ${{ runner.os == 'macOS' || runner.os == 'Linux' }} + - name: Test lff bash scripts (Linux or macOS only) + run: | + .github/scripts/test-lff.sh + if: ${{ runner.os == 'macOS' || runner.os == 'Linux' }} - name: Test PowerShell script (Windows only) run: | - ./gradlew buildLfc + ./gradlew buildAll bin/lfc.ps1 --help if: ${{ runner.os == 'Windows' }} diff --git a/bin/build-lf-cli b/bin/build-lf-cli new file mode 120000 index 0000000000..55c54a4b7a --- /dev/null +++ b/bin/build-lf-cli @@ -0,0 +1 @@ +../lib/scripts/build.sh \ No newline at end of file diff --git a/bin/lfc.ps1 b/bin/lfc.ps1 index f4e5187152..a09c91759c 100644 --- a/bin/lfc.ps1 +++ b/bin/lfc.ps1 @@ -1,50 +1,9 @@ #========================================================== # Description: Run the lfc compiler. -# Authors: Christian Menard, Peter Donovan +# Authors: Ruomu Xu # Usage: Usage: lfc [options] files... #========================================================== -$base="$PSScriptRoot\.." -$java_home = "$Env:JAVA_HOME" -$java_cmd = "$java_home\bin\java.exe" -$jarpath_dev="$base\org.lflang.cli\build\libs\org.lflang.cli-*-lfc.jar" -$jarpath_release="$base\lib\jars\org.lflang.cli-*-lfc.jar" - -function Test-Dev { - Test-Path "$base\org.lflang.cli" -PathType container -} - -function Get-JarPath { - if (Test-Dev) { - if (Test-Path $jarpath_dev -PathType leaf) { - $jarpath=$(Get-ChildItem $jarpath_dev).toString() - } else { - throw "Failed to find a copy of the Lingua Franca compiler matching the pattern ""$jarpath_dev"". Did you remember to build?" - } - } else { - if (Test-Path $jarpath_release -PathType leaf) { - $jarpath=$(Get-ChildItem $jarpath_release).toString() - } else { - throw "Failed to find a copy of the Lingua Franca compiler matching the pattern ""$jarpath_release""." - } - } - $jarpath -} - -# check if we can find java executable in $java_home -if (-not (Test-Path $java_cmd)) { - # otherwise, try to run java directly - if (-not (Get-Command java -errorAction SilentlyContinue)) { - throw "JRE not found" - } - $java_cmd = "java" -} - -# check for correct java version -$java_version = (Get-Command java | Select-Object -ExpandProperty Version).toString() -if ([version]$java_version -lt [version]"17.0") { - throw "JRE $java_version found but 17.0 or greater is required." -} - -# invoke lfc -& $java_cmd -jar $(Get-JarPath) $args +$launchScript="$PSScriptRoot\..\lib\scripts\launch.ps1" +# PS requires spattling: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Splatting?view=powershell-7.2 +. $launchScript @args diff --git a/bin/lff b/bin/lff new file mode 120000 index 0000000000..c22080b02d --- /dev/null +++ b/bin/lff @@ -0,0 +1 @@ +../lib/scripts/launch.sh \ No newline at end of file diff --git a/bin/lff.ps1 b/bin/lff.ps1 new file mode 100644 index 0000000000..d73b7357eb --- /dev/null +++ b/bin/lff.ps1 @@ -0,0 +1,9 @@ +#========================================================== +# Description: Run the lff compiler. +# Authors: Ruomu Xu +# Usage: Usage: lff [options] files... +#========================================================== + +$launchScript="$PSScriptRoot\..\lib\scripts\launch.ps1" +# PS requires spattling: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Splatting?view=powershell-7.2 +. $launchScript @args diff --git a/build.gradle b/build.gradle index 6970c1724c..6155f298d7 100644 --- a/build.gradle +++ b/build.gradle @@ -65,16 +65,14 @@ subprojects { } } -gradle.projectsEvaluated { - // Our CI uses --tests filters, which fails if some - // subprojects have no matching test. - // - // https://stackoverflow.com/questions/26147480/how-to-make-gradle-not-to-mark-build-failed-if-no-tests-are-found - subprojects { - test { - filter { - setFailOnNoMatchingTests(false) - } +// Our CI uses --tests filters, which fails if some +// subprojects have no matching test. +// +// https://stackoverflow.com/questions/26147480/how-to-make-gradle-not-to-mark-build-failed-if-no-tests-are-found +subprojects { + test { + filter { + setFailOnNoMatchingTests(false) } } } @@ -112,4 +110,4 @@ spotless { formatAnnotations() } } -tasks.withType(SpotlessTask) { it.dependsOn(":org.lflang.cli:jarLff") } +tasks.withType(SpotlessTask) { it.dependsOn(":org.lflang:jarCliTools") } diff --git a/lib/scripts/build.sh b/lib/scripts/build.sh index 0191e98f39..d342aa45cd 100755 --- a/lib/scripts/build.sh +++ b/lib/scripts/build.sh @@ -17,6 +17,11 @@ # This solution, adapted from an example written by Geoff Nixon, ia POSIX- # compliant and robust to symbolic links. If a chain of more than 1000 links # is encountered, we return. + +if [[ "$0" == *build-lfc ]]; then + echo -e "\033[33mWarning; buid-lfc is deprecated! Please use build-lf-cli instead.\033[0m" +fi + find_dir() ( start_dir=$PWD cd "$(dirname "$1")" @@ -60,7 +65,7 @@ fi # Print message explaining the CLI args. function usage() { - echo "Usage: build-lfc [options] [[-r | --run] [lfc-args]]" + echo "Usage: build-lf-cli [options] [lfc-args]]" echo "Options:" echo " -c | --clean Build entirely from scratch." echo " -h | --help Display this information." @@ -87,15 +92,6 @@ while [[ "$#" -gt 0 ]]; do usage exit 0 ;; - -r | --run ) - run=true - shift - while [[ "$#" -gt 0 ]]; do - args+=("$1") - shift - done - break - ;; *) usage exit 1 @@ -121,22 +117,15 @@ jar_path="$(get_jar_path)" if [ ! -f "${jar_path}" ] || ! "${find_cmd}" "${base}" \ -path "${src_pkg_path}" \ - -path "${lfc_src_pkg_path}" \ -prune -o \ -type f \ -newer "${jar_path}" \ -exec false {} +; then # Rebuild. 1>&2 echo "Jar file is missing or out-of-date; starting rebuild..." - "${base}/gradlew" ${flags} -p "${base}" buildLfc + "${base}/gradlew" ${flags} -p "${base}" buildAll # Update the timestamp in case the jar was not touched by Gradle. touch -c -- "${jar_path}" else echo "Already up-to-date." fi - -# Run lfc with the provided arguments. -if [[ "${run}" == "true" ]]; then - echo "Running lfc..." - run_lfc_with_args "${args[@]}" -fi diff --git a/lib/scripts/include.sh b/lib/scripts/include.sh index 3163d029c3..aa0a6ef065 100644 --- a/lib/scripts/include.sh +++ b/lib/scripts/include.sh @@ -21,10 +21,8 @@ set -euo pipefail # Paths (relative to ${base}), which is assumed to have been set. src_pkg_name="org.lflang" src_pkg_path="${base}/${src_pkg_name}" -lfc_src_pkg_name="${src_pkg_name}.cli" -lfc_src_pkg_path="${base}/${lfc_src_pkg_name}" -lfc_jar_build_path_pattern="${lfc_src_pkg_name}/build/libs/${lfc_src_pkg_name}-*-lfc.jar" -lfc_jar_release_path_pattern="lib/jars/${lfc_src_pkg_name}-*-lfc.jar" +jar_build_path_pattern="${src_pkg_name}/build/libs/${src_pkg_name}-*.jar" +jar_release_path_pattern="lib/jars/${src_pkg_name}-*.jar" # Enter directory silently (without printing). pushd() { @@ -47,15 +45,15 @@ function is_dir() { # Check whether the source directory exists, and return it if true. function get_src_dir() { - echo `is_dir "${base}/${lfc_src_pkg_name}"` + echo `is_dir "${base}/${src_pkg_name}"` } # If it exists, return a path to the Lingua Franca jar. function get_jar_path() { if [ "$(get_src_dir)" ]; then - jar_path_pattern="${lfc_jar_build_path_pattern}" + jar_path_pattern="${jar_build_path_pattern}" else - jar_path_pattern="${lfc_jar_release_path_pattern}" + jar_path_pattern="${jar_release_path_pattern}" fi # echo Jar path pattern: "${base}"/${jar_path_pattern} # Is there a file that matches our pattern? If so, return it. @@ -110,7 +108,7 @@ function get_java_cmd { } # Find the jar and JRE, run the jar with the provided arguments, and exit. -function run_lfc_with_args { +function run_cli_tool_with_args { # Find the jar; report error if it was not found. jar_path="$(get_jar_path)" @@ -120,6 +118,6 @@ function run_lfc_with_args { # Launch the compiler. java_cmd="$(get_java_cmd)" - "${java_cmd}" -jar "${jar_path}" "$@"; + "${java_cmd}" -cp "${jar_path}" "${main_class}" "$@"; exit $? } diff --git a/lib/scripts/launch.ps1 b/lib/scripts/launch.ps1 new file mode 100644 index 0000000000..6864ef7c56 --- /dev/null +++ b/lib/scripts/launch.ps1 @@ -0,0 +1,71 @@ +#========================================================== +# Description: Launch lfc or lff depending on the invoking script. +# Authors: Christian Menard, Peter Donovan, Ruomu Xu +# Usage: Usage: launch args... +# with invoker with name same as the programme to be invoked. +#========================================================== + +# If the invoker is Z:\nkamihara\lf\bin\lfc.ps1, $invokerName will strip out "lfc.ps1" and then get "lfc". +# See https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables?view=powershell-7.2#myinvocation +$invokerPath = $MyInvocation.PSCommandPath +$invokerName = [System.IO.Path]::GetFileNameWithoutExtension("$(Split-Path -Path $invokerPath -Leaf -Resolve)") + +$mainClassTable = @{"lfc" = "org.lflang.cli.Lfc"; "lff" = "org.lflang.cli.Lff"} +$mainClassName = $null +foreach ($k in $mainClassTable.Keys) { + if ($invokerName.EndsWith($k)) { + $mainClassName = $mainClassTable[$k] + break + } +} +if ($null -eq $mainClassName) { + throw ("$invokerName is not a known lf command. Known commands are [$($mainClassTable.Keys)]. " + + "In case you use a symbolic or hard link to one of the Lingua Franca " + + "command line tools, make sure that the link's name ends with one of [$($mainClassTable.Keys)]") +} + +# This script is in $base\lib\scripts +$base="$PSScriptRoot\..\..\" +$java_home = "$Env:JAVA_HOME" +$java_cmd = "$java_home\bin\java.exe" +$jarpath_dev="$base\org.lflang\build\libs\org.lflang-*.jar" +$jarpath_release="$base\lib\jars\org.lflang-*.jar" + +function Test-Dev { + Test-Path "$base\org.lflang" -PathType container +} + +function Get-JarPath { + if (Test-Dev) { + if (Test-Path $jarpath_dev -PathType leaf) { + $jarpath=$(Get-ChildItem $jarpath_dev).toString() + } else { + throw "Failed to find a copy of the Lingua Franca compiler matching the pattern ""$jarpath_dev"". Did you remember to build?" + } + } else { + if (Test-Path $jarpath_release -PathType leaf) { + $jarpath=$(Get-ChildItem $jarpath_release).toString() + } else { + throw "Failed to find a copy of the Lingua Franca compiler matching the pattern ""$jarpath_release""." + } + } + $jarpath +} + +# check if we can find java executable in $java_home +if (-not (Test-Path $java_cmd)) { + # otherwise, try to run java directly + if (-not (Get-Command java -errorAction SilentlyContinue)) { + throw "JRE not found" + } + $java_cmd = "java" +} + +# check for correct java version +$java_version = (Get-Command java | Select-Object -ExpandProperty Version).toString() +if ([version]$java_version -lt [version]"17.0") { + throw "JRE $java_version found but 17.0 or greater is required." +} + +# invoke lff +& $java_cmd -classpath $(Get-JarPath) $mainClassName $args diff --git a/lib/scripts/launch.sh b/lib/scripts/launch.sh index 3208e5de54..82747c81ef 100755 --- a/lib/scripts/launch.sh +++ b/lib/scripts/launch.sh @@ -13,7 +13,7 @@ # Find the directory in which this script resides in a way that is compatible # with MacOS, which has a `readlink` implementation that does not support the -# necessary `-f` flag to canonicalize by following every symlink in every +# necessary `-f` flag to canonicalize by following every symlink in every # component of the given name recursively. # This solution, adapted from an example written by Geoff Nixon, is POSIX- # compliant and robust to symbolic links. If a chain of more than 1000 links @@ -47,12 +47,27 @@ rel_path="lib/scripts" abs_path="$(find_dir "$0")" if [[ "${abs_path}" ]]; then - base="$(dirname "$(dirname "${abs_path}")")" + base=`dirname $(dirname ${abs_path})` source "${base}/${rel_path}/include.sh" else fatal_error "Unable to determine absolute path to $0." fi #============================================================================ + +if [[ "$0" == *lfc ]]; then + main_class="org.lflang.cli.Lfc" +elif [[ "$0" == *lff ]]; then + main_class="org.lflang.cli.Lff" +else + known_commands="[lfc, lff]" + echo \ + "ERROR: $0 is not a known lf command! Known commands are ${known_commands}. + In case you use a symbolic or hard link to one of the Lingua Franca + command line tools, make sure that the link's name ends with one of + ${known_commands}." + exit 2 +fi + # Launch the compiler. -run_lfc_with_args "$@" +run_cli_tool_with_args "$@" diff --git a/org.lflang.cli/build.gradle b/org.lflang.cli/build.gradle deleted file mode 100644 index 84913c02c5..0000000000 --- a/org.lflang.cli/build.gradle +++ /dev/null @@ -1,116 +0,0 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar - -sourceSets { - test { - java.srcDirs = [] - kotlin.srcDirs = ['test/kotlin'] - resources.srcDir('test/resources') - resources.include '**/*' - } -} - -configurations { - cli_impl { - extendsFrom implementation - } -} - -compileTestKotlin { - destinationDir = compileTestJava.destinationDir - kotlinOptions { - jvmTarget = kotlinJvmTarget - } -} - - - -dependencies { - implementation project(':org.lflang') - implementation "org.eclipse.xtext:org.eclipse.xtext.ide:${xtextVersion}" - implementation "org.eclipse.xtext:org.eclipse.xtext.xbase.ide:${xtextVersion}" - - testImplementation "junit:junit:${jUnitVersion}" -} - -apply plugin: 'application' -apply plugin: 'com.github.johnrengelman.shadow' - -task buildLfc() { - apply plugin: 'application' - apply plugin: 'com.github.johnrengelman.shadow' - mainClassName = 'org.lflang.cli.Lfc' -} - -task jarLfc(type: ShadowJar) { - manifest { - attributes('Main-Class': 'org.lflang.cli.Lfc') - } - configurations = [project.configurations.cli_impl] - archiveClassifier.set('lfc') - exclude 'test/*' - exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA' - // We should use minimize() here to reduce the size of the JAR, but it causes problems - // with regard to our Kotlin classes. Since we don't use imports to load them but load - // the classes manually, minimize does not see the dependency. While we can add an exclude - // rule, this does not seem to work very well and causes problems when compiling for a - // second time. Also see https://github.com/lf-lang/lingua-franca/pull/1285 - transform(com.github.jengelman.gradle.plugins.shadow.transformers.AppendingTransformer){ - resource = 'plugin.properties' - } - from sourceSets.main.output -} - -buildLfc.finalizedBy jarLfc - -task runLfc(type: JavaExec) { - // builds and runs lfc - // The working directory will be the root directory of the lingua franca project - // CLI arguments can be passed to lfc by using --args. Note that you need - // to escape cli flags which start with --.For instance --args ' --help'. - // Otherwise they're parsed as arguments to the Gradle CLI, not lfc. - description = "Build and run lfc, use --args to pass arguments" - group = "application" - classpath = sourceSets.main.runtimeClasspath - mainClass = 'org.lflang.cli.Lfc' - workingDir = '..' -} - -task buildLff() { - apply plugin: 'application' - apply plugin: 'com.github.johnrengelman.shadow' - mainClassName = 'org.lflang.cli.Lff' -} - -task jarLff(type: ShadowJar) { - manifest { - attributes('Main-Class': 'org.lflang.cli.Lff') - } - configurations = [project.configurations.cli_impl] - archiveClassifier.set('lff') - exclude 'test/*' - exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA' - // We should use minimize() here to reduce the size of the JAR, but it causes problems - // with regard to our Kotlin classes. Since we don't use imports to load them but load - // the classes manually, minimize does not see the dependency. While we can add an exclude - // rule, this does not seem to work very well and causes problems when compiling for a - // second time. Also see https://github.com/lf-lang/lingua-franca/pull/1285 - transform(com.github.jengelman.gradle.plugins.shadow.transformers.AppendingTransformer){ - resource = 'plugin.properties' - } - from sourceSets.main.output -} - -buildLff.finalizedBy jarLff - -task runLff(type: JavaExec) { - // builds and runs lff - // The working directory will be the root directory of the lingua franca project - // CLI arguments can be passed to lff by using --args. Note that you need - // to escape cli flags which start with --.For instance --args ' --help'. - // Otherwise they're parsed as arguments to the Gradle CLI, not lfc. - description = "Build and run lff, use --args to pass arguments" - group = "application" - classpath = sourceSets.main.runtimeClasspath - mainClass = 'org.lflang.cli.Lff' - workingDir = '..' -} diff --git a/org.lflang.tests/build.gradle b/org.lflang.tests/build.gradle index 580337f2b6..ffe054ef24 100644 --- a/org.lflang.tests/build.gradle +++ b/org.lflang.tests/build.gradle @@ -53,6 +53,9 @@ test { useJUnitPlatform() finalizedBy jacocoTestReport workingDir = ".." + filter { + setFailOnNoMatchingTests(true) + } } test.dependsOn("compileKotlin") diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/colors.lf b/org.lflang.tests/resources/org/lflang/tests/cli/colors.lf similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/colors.lf rename to org.lflang.tests/resources/org/lflang/tests/cli/colors.lf diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/colors.stderr b/org.lflang.tests/resources/org/lflang/tests/cli/colors.stderr similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/colors.stderr rename to org.lflang.tests/resources/org/lflang/tests/cli/colors.stderr diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/emptyFile.lf b/org.lflang.tests/resources/org/lflang/tests/cli/emptyFile.lf similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/emptyFile.lf rename to org.lflang.tests/resources/org/lflang/tests/cli/emptyFile.lf diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/emptyFile.stderr b/org.lflang.tests/resources/org/lflang/tests/cli/emptyFile.stderr similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/emptyFile.stderr rename to org.lflang.tests/resources/org/lflang/tests/cli/emptyFile.stderr diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/issue490.lf b/org.lflang.tests/resources/org/lflang/tests/cli/issue490.lf similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/issue490.lf rename to org.lflang.tests/resources/org/lflang/tests/cli/issue490.lf diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/issue490.stderr b/org.lflang.tests/resources/org/lflang/tests/cli/issue490.stderr similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/issue490.stderr rename to org.lflang.tests/resources/org/lflang/tests/cli/issue490.stderr diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/multilineWarning.lf b/org.lflang.tests/resources/org/lflang/tests/cli/multilineWarning.lf similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/multilineWarning.lf rename to org.lflang.tests/resources/org/lflang/tests/cli/multilineWarning.lf diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/multilineWarning.stderr b/org.lflang.tests/resources/org/lflang/tests/cli/multilineWarning.stderr similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/multilineWarning.stderr rename to org.lflang.tests/resources/org/lflang/tests/cli/multilineWarning.stderr diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/multilineWarningTooBig.lf b/org.lflang.tests/resources/org/lflang/tests/cli/multilineWarningTooBig.lf similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/multilineWarningTooBig.lf rename to org.lflang.tests/resources/org/lflang/tests/cli/multilineWarningTooBig.lf diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/multilineWarningTooBig.stderr b/org.lflang.tests/resources/org/lflang/tests/cli/multilineWarningTooBig.stderr similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/multilineWarningTooBig.stderr rename to org.lflang.tests/resources/org/lflang/tests/cli/multilineWarningTooBig.stderr diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/simpleWarning.lf b/org.lflang.tests/resources/org/lflang/tests/cli/simpleWarning.lf similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/simpleWarning.lf rename to org.lflang.tests/resources/org/lflang/tests/cli/simpleWarning.lf diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/simpleWarning.stderr b/org.lflang.tests/resources/org/lflang/tests/cli/simpleWarning.stderr similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/simpleWarning.stderr rename to org.lflang.tests/resources/org/lflang/tests/cli/simpleWarning.stderr diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/tabs.lf b/org.lflang.tests/resources/org/lflang/tests/cli/tabs.lf similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/tabs.lf rename to org.lflang.tests/resources/org/lflang/tests/cli/tabs.lf diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/tabs.stderr b/org.lflang.tests/resources/org/lflang/tests/cli/tabs.stderr similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/tabs.stderr rename to org.lflang.tests/resources/org/lflang/tests/cli/tabs.stderr diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/twoLineWarning.lf b/org.lflang.tests/resources/org/lflang/tests/cli/twoLineWarning.lf similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/twoLineWarning.lf rename to org.lflang.tests/resources/org/lflang/tests/cli/twoLineWarning.lf diff --git a/org.lflang.cli/test/resources/org/lflang/cli/tests/twoLineWarning.stderr b/org.lflang.tests/resources/org/lflang/tests/cli/twoLineWarning.stderr similarity index 100% rename from org.lflang.cli/test/resources/org/lflang/cli/tests/twoLineWarning.stderr rename to org.lflang.tests/resources/org/lflang/tests/cli/twoLineWarning.stderr diff --git a/org.lflang.cli/test/kotlin/org/lflang/cli/tests/LfcIssueReportingTest.kt b/org.lflang.tests/src/org/lflang/tests/cli/LfcIssueReportingTest.kt similarity index 89% rename from org.lflang.cli/test/kotlin/org/lflang/cli/tests/LfcIssueReportingTest.kt rename to org.lflang.tests/src/org/lflang/tests/cli/LfcIssueReportingTest.kt index 12519a1ca0..8a079da068 100644 --- a/org.lflang.cli/test/kotlin/org/lflang/cli/tests/LfcIssueReportingTest.kt +++ b/org.lflang.tests/src/org/lflang/tests/cli/LfcIssueReportingTest.kt @@ -21,15 +21,20 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.lflang.cli.tests +package org.lflang.tests.cli -import junit.framework.Assert.assertEquals -import junit.framework.AssertionFailedError -import org.junit.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test import org.lflang.LFRuntimeModule import org.lflang.LFStandaloneSetup -import org.lflang.cli.* -import java.io.* +import org.lflang.cli.AnsiColors +import org.lflang.cli.Io +import org.lflang.cli.LFStandaloneModule +import org.lflang.cli.Lfc +import org.lflang.cli.ReportingBackend +import org.opentest4j.AssertionFailedError +import java.io.ByteArrayOutputStream +import java.io.PrintStream import java.nio.charset.StandardCharsets import java.nio.file.Files import java.nio.file.Path @@ -118,8 +123,9 @@ class LfcIssueReportingTest { val packageName = loader.packageName.replace('.', '/') // relative to root of gradle project - val lfFile = Paths.get("test/resources/$packageName/$fileBaseName.lf") - val expectedPath = Paths.get("test/resources/$packageName/$fileBaseName.stderr") + val basePath = "org.lflang.tests/resources/$packageName/" + val lfFile = Paths.get("$basePath/$fileBaseName.lf") + val expectedPath = Paths.get("$basePath/$fileBaseName.stderr") assert(Files.exists(lfFile)) { "Missing test file $lfFile" } diff --git a/org.lflang/build.gradle b/org.lflang/build.gradle index 5fd90294b5..a76e26f6fc 100644 --- a/org.lflang/build.gradle +++ b/org.lflang/build.gradle @@ -1,3 +1,5 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + dependencies { implementation "org.eclipse.xtext:org.eclipse.xtext:${xtextVersion}" implementation "org.eclipse.xtext:org.eclipse.xtext.xbase.lib:${xtextVersion}" @@ -67,3 +69,67 @@ generateXtext.dependsOn(generateXtextLanguage) clean.dependsOn(cleanGenerateXtextLanguage) eclipse.classpath.plusConfigurations += [configurations.mwe2] +configurations { + cli_impl { + extendsFrom implementation + } +} + +apply plugin: 'application' +apply plugin: 'com.github.johnrengelman.shadow' + +task buildAll() { + apply plugin: 'application' + apply plugin: 'com.github.johnrengelman.shadow' + mainClassName = 'org.lflang.cli.Lfc' +} + +// define buildLfc as an alias to buildAll +task buildLfc { + dependsOn buildAll + doFirst({{logger.warn("The buildLfc task is deprecated! Please use buildAll instead.")}}) +} + +task jarCliTools(type: ShadowJar) { + manifest { + attributes('Main-Class': 'org.lflang.cli.Lfc') + } + configurations = [project.configurations.cli_impl] + exclude 'test/*' + exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA' + // We should use minimize() here to reduce the size of the JAR, but it causes problems + // with regard to our Kotlin classes. Since we don't use imports to load them but load + // the classes manually, minimize does not see the dependency. While we can add an exclude + // rule, this does not seem to work very well and causes problems when compiling for a + // second time. Also see https://github.com/lf-lang/lingua-franca/pull/1285 + transform(com.github.jengelman.gradle.plugins.shadow.transformers.AppendingTransformer){ + resource = 'plugin.properties' + } + from sourceSets.main.output +} + +buildAll.finalizedBy jarCliTools + +// Tasks for running specific CLI tools. +// The working directory will be the root directory of the lingua franca project +// CLI arguments can be passed to lfc by using --args. Note that you need +// to escape cli flags which start with --.For instance --args ' --help'. +// Otherwise they're parsed as arguments to the Gradle CLI, not lfc. + +task runLfc(type: JavaExec) { + // builds and runs lfc + description = "Build and run lfc, use --args to pass arguments" + group = "application" + classpath = sourceSets.main.runtimeClasspath + mainClass = 'org.lflang.cli.Lfc' + workingDir = '..' +} + +task runLff(type: JavaExec) { + // builds and runs lff + description = "Build and run lff, use --args to pass arguments" + group = "application" + classpath = sourceSets.main.runtimeClasspath + mainClass = 'org.lflang.cli.Lff' + workingDir = '..' +} diff --git a/org.lflang.cli/src/org/lflang/cli/CliBase.java b/org.lflang/src/org/lflang/cli/CliBase.java similarity index 100% rename from org.lflang.cli/src/org/lflang/cli/CliBase.java rename to org.lflang/src/org/lflang/cli/CliBase.java diff --git a/org.lflang.cli/src/org/lflang/cli/LFStandaloneModule.java b/org.lflang/src/org/lflang/cli/LFStandaloneModule.java similarity index 100% rename from org.lflang.cli/src/org/lflang/cli/LFStandaloneModule.java rename to org.lflang/src/org/lflang/cli/LFStandaloneModule.java diff --git a/org.lflang.cli/src/org/lflang/cli/Lfc.java b/org.lflang/src/org/lflang/cli/Lfc.java similarity index 100% rename from org.lflang.cli/src/org/lflang/cli/Lfc.java rename to org.lflang/src/org/lflang/cli/Lfc.java diff --git a/org.lflang.cli/src/org/lflang/cli/Lff.java b/org.lflang/src/org/lflang/cli/Lff.java similarity index 100% rename from org.lflang.cli/src/org/lflang/cli/Lff.java rename to org.lflang/src/org/lflang/cli/Lff.java diff --git a/org.lflang.cli/src/org/lflang/cli/ReportingUtil.kt b/org.lflang/src/org/lflang/cli/ReportingUtil.kt similarity index 100% rename from org.lflang.cli/src/org/lflang/cli/ReportingUtil.kt rename to org.lflang/src/org/lflang/cli/ReportingUtil.kt diff --git a/org.lflang.cli/src/org/lflang/cli/StandaloneErrorReporter.java b/org.lflang/src/org/lflang/cli/StandaloneErrorReporter.java similarity index 100% rename from org.lflang.cli/src/org/lflang/cli/StandaloneErrorReporter.java rename to org.lflang/src/org/lflang/cli/StandaloneErrorReporter.java diff --git a/org.lflang.cli/src/org/lflang/cli/StandaloneIssueAcceptor.java b/org.lflang/src/org/lflang/cli/StandaloneIssueAcceptor.java similarity index 100% rename from org.lflang.cli/src/org/lflang/cli/StandaloneIssueAcceptor.java rename to org.lflang/src/org/lflang/cli/StandaloneIssueAcceptor.java