Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Usage of a published version of reactor-ts #1426

Merged
merged 23 commits into from
Oct 28, 2022
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ jobs:

# Run the TypeScript integration tests.
ts-tests:
uses: lf-lang/lingua-franca/.github/workflows/ts-tests.yml@master
uses: lf-lang/lingua-franca/.github/workflows/ts-tests.yml@ts-use-published-runtime
needs: cancel

# Run the serialization tests
Expand Down
15 changes: 10 additions & 5 deletions .github/workflows/ts-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,29 @@ jobs:
- name: Install pnpm
run: npm i -g pnpm
- name: Cache .pnpm-store
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ~/.pnpm-store
key: ${{ runner.os }}-node${{ matrix.node-version }}-${{ hashFiles('org.lflang/src/lib/ts/package.json') }}
key: ${{ runner.os }}-node${{ matrix.node-version }}
- name: Install Dependencies OS X
run: |
brew install coreutils
if: ${{ runner.os == 'macOS' }}
- name: Check out specific ref of reactor-ts
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: lf-lang/reactor-ts
path: org.lflang/src/lib/ts/reactor-ts
path: ./reactor-ts
ref: ${{ inputs.runtime-ref }}
if: ${{ inputs.runtime-ref }}
- name: Perform TypeScript tests
- name: Perform TypeScript tests with default runtime
run: |
./gradlew test --tests org.lflang.tests.runtime.TypeScriptTest.*
if: ${{ inputs.runtime-ref == ''}}
- name: Perform TypeScript tests with alternative runtime
run: |
./gradlew test --tests org.lflang.tests.runtime.TypeScriptTest.* -Druntime="${{ github.workspace }}/reactor-ts"
if: ${{ inputs.runtime-ref }}
- name: Report to CodeCov
uses: codecov/codecov-action@v2.1.0
with:
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[submodule "org.lflang/src/lib/ts/reactor-ts"]
path = org.lflang/src/lib/ts/reactor-ts
url = https://github.com/lf-lang/reactor-ts.git
[submodule "org.lflang/src/lib/c/reactor-c"]
path = org.lflang/src/lib/c/reactor-c
url = https://github.com/lf-lang/reactor-c.git
Expand Down
51 changes: 25 additions & 26 deletions org.lflang.cli/src/org/lflang/cli/Lfc.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.lflang.LFStandaloneSetup;
import org.lflang.LocalStrings;
import org.lflang.generator.LFGeneratorContext;
import org.lflang.generator.LFGeneratorContext.BuildParm;
import org.lflang.generator.MainContext;

import com.google.inject.Inject;
Expand Down Expand Up @@ -65,22 +66,22 @@ public class Lfc extends CliBase {
* @author Marten Lohstroh <marten@berkeley.edu>
*/
enum CLIOption {
CLEAN("c", "clean", false, false, "Clean before building.", true),
COMPILER(null, "target-compiler", true, false, "Target compiler to invoke.", true),
EXTERNAL_RUNTIME_PATH(null, "external-runtime-path", true, false, "Specify an external runtime library to be used by the compiled binary.", true),
FEDERATED("f", "federated", false, false, "Treat main reactor as federated.", false),
HELP("h", "help", false, false, "Display this information.", true),
LOGGING(null, "logging", true, false, "The logging level to use by the generated binary", true),
LINT("l", "lint", false, false, "Enable or disable linting of generated code.", true),
NO_COMPILE("n", "no-compile", false, false, "Do not invoke target compiler.", true),
OUTPUT_PATH("o", "output-path", true, false, "Specify the root output directory.", false),
QUIET("q", "quiet", false, false, "Suppress output of the target compiler and other commands", true),
RTI("r", "rti", true, false, "Specify the location of the RTI.", true),
RUNTIME_VERSION(null, "runtime-version", true, false, "Specify the version of the runtime library used for compiling LF programs.", true),
SCHEDULER("s", "scheduler", true, false, "Specify the runtime scheduler (if supported).", true),
THREADING("t", "threading", true, false, "Specify whether the runtime should use multi-threading (true/false).", true),
VERSION(null, "version", false, false, "Print version information.", false),
WORKERS("w", "workers", true, false, "Specify the default number of worker threads.", true);
CLEAN(BuildParm.CLEAN, "c", false, false, true),
TARGET_COMPILER(BuildParm.TARGET_COMPILER, null, true, false, true),
EXTERNAL_RUNTIME_PATH(BuildParm.EXTERNAL_RUNTIME_PATH, null, true, false, true),
FEDERATED(BuildParm.FEDERATED, "f", false, false, false),
HELP(BuildParm.HELP, "h", false, false, true),
LOGGING(BuildParm.LOGGING, null, true, false, true),
LINT(BuildParm.LINT, "l",false, false, true),
NO_COMPILE(BuildParm.NO_COMPILE, "n", false, false, true),
OUTPUT_PATH(BuildParm.OUTPUT_PATH, "o", true, false, false),
QUIET(BuildParm.QUIET, "q", false, false, true),
RTI(BuildParm.RTI, "r", true, false, true),
RUNTIME_VERSION(BuildParm.RUNTIME_VERSION, null, true, false, true),
SCHEDULER(BuildParm.SCHEDULER, "s", true, false, true),
THREADING(BuildParm.THREADING, "t", true, false, true),
VERSION(BuildParm.VERSION, "version", false, false, false),
WORKERS(BuildParm.WORKERS, "w", true, false, true);

/**
* The corresponding Apache CLI Option object.
Expand All @@ -95,20 +96,18 @@ enum CLIOption {
/**
* Construct a new CLIOption.
*
* @param opt The short option name. E.g.: "f" denotes a flag
* "-f".
* @param longOpt The long option name. E.g.: "foo" denotes a flag
* "--foo".
* @param hasArg Whether or not this option has an argument. E.g.:
* @param parameter The build parameter that this CLI parameter corresponds to.
* @param shorthand The single-character switch to use for this option. E.g.:
* "-c" for "--clean".
* @param hasArg Whether this option has an argument. E.g.:
* "--foo bar" where "bar" is the argument value.
* @param isReq Whether or not this option is required. If it is
* @param isReq Whether this option is required. If it is
* required but not specified a menu is shown.
* @param description The description used in the menu.
* @param passOn Whether or not to pass this option as a property
* @param passOn Whether to pass this option as a property
* to the code generator.
*/
CLIOption(String opt, String longOpt, boolean hasArg, boolean isReq, String description, boolean passOn) {
this.option = new Option(opt, longOpt, hasArg, description);
CLIOption(BuildParm parameter, String shorthand, boolean hasArg, boolean isReq, boolean passOn) {
this.option = new Option(shorthand, parameter.getKey(), hasArg, parameter.description);
option.setRequired(isReq);
this.passOn = passOn;
}
Expand Down
1 change: 1 addition & 0 deletions org.lflang.tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ test {
}
// Pass the scheduler property on to the Java VM
systemProperty 'scheduler', System.getProperty('scheduler')
systemProperty 'runtime', System.getProperty('runtime')
// Suggested by Gradle documentation: https://guides.gradle.org/performance/#parallel_test_execution
maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
useJUnitPlatform()
Expand Down
16 changes: 15 additions & 1 deletion org.lflang.tests/src/org/lflang/tests/TestBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.lflang.generator.DockerGeneratorBase;
import org.lflang.generator.LFGenerator;
import org.lflang.generator.LFGeneratorContext;
import org.lflang.generator.LFGeneratorContext.BuildParm;
import org.lflang.generator.MainContext;
import org.lflang.tests.Configurators.Configurator;
import org.lflang.tests.LFTest.Result;
Expand Down Expand Up @@ -384,8 +385,21 @@ private static void checkAndReportFailures(Set<LFTest> tests) {
* @throws IOException if there is any file access problem
*/
private LFGeneratorContext configure(LFTest test, Configurator configurator, TestLevel level) throws IOException {
var props = new Properties();
var sysProps = System.getProperties();
// Set the external-runtime-path property if it was specified.
if (sysProps.containsKey("runtime")) {
var rt = sysProps.get("runtime").toString();
if (!rt.isEmpty()) {
props.setProperty(BuildParm.EXTERNAL_RUNTIME_PATH.getKey(), rt);
System.out.println("Using runtime: " + sysProps.get("runtime").toString());
}
} else {
System.out.println("Using default runtime.");
}

var context = new MainContext(
LFGeneratorContext.Mode.STANDALONE, CancelIndicator.NullImpl, (m, p) -> {}, new Properties(), true,
LFGeneratorContext.Mode.STANDALONE, CancelIndicator.NullImpl, (m, p) -> {}, props, true,
fileConfig -> new DefaultErrorReporter()
);

Expand Down
10 changes: 1 addition & 9 deletions org.lflang/src/lib/ts/package.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
{
"name": "LinguaFrancaDefault",
"version": "0.0.1",
"description": "A default Lingua Franca project for the TypeScript target",
"type": "commonjs",
"repository": {
"type": "git",
"url": "https://github.com/icyphy/lingua-franca"
},
"license": "BSD-2-Clause",
"dependencies": {
"reactor-ts": "file:./reactor-ts",
"@types/reactor-ts": "file:./reactor-ts",
"@lf-lang/reactor-ts": "^0.1.0",
"@babel/cli": "^7.8.4",
"@babel/core": "^7.8.7",
"@babel/node": "^7.8.7",
Expand Down
1 change: 0 additions & 1 deletion org.lflang/src/lib/ts/reactor-ts
Submodule reactor-ts deleted from aeb813
4 changes: 2 additions & 2 deletions org.lflang/src/lib/ts/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"allowJs": true,
"noEmit": true,
"target": "esnext",
"types": ["node", "reactor-ts", "ulog", "microtime", "command-line-args", "command-line-usage"],
"types": ["node", "@lf-lang/reactor-ts", "ulog", "microtime", "command-line-args", "command-line-usage"],
"esModuleInterop": true,
"isolatedModules": true,
"lib": ["esnext", "dom"],
Expand All @@ -13,7 +13,7 @@
"strictBindCallApply": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"typeRoots": ["./node_modules/@types/", "./node_modules/reactor-ts/src/core/@types/"]
"typeRoots": ["./node_modules/@types/", "./node_modules/@lf-lang/reactor-ts/src/core/@types/"]
lhstrh marked this conversation as resolved.
Show resolved Hide resolved
},
"include": [
"src/**/*"
Expand Down
44 changes: 44 additions & 0 deletions org.lflang/src/org/lflang/generator/LFGeneratorContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,50 @@
*/
public interface LFGeneratorContext extends IGeneratorContext {

/**
* Enumeration of keys used to parameterize the build process.
*/
public enum BuildParm {
CLEAN("Clean before building."),
EXTERNAL_RUNTIME_PATH("Specify an external runtime library to be used by the compiled binary."),
FEDERATED("Treat main reactor as federated."),
HELP("Display this information."),
LOGGING("The logging level to use by the generated binary"),
LINT("Enable or disable linting of generated code."),
NO_COMPILE("Do not invoke target compiler."),
OUTPUT_PATH("Specify the root output directory."),
QUIET("Suppress output of the target compiler and other commands"),
RTI("Specify the location of the RTI."),
RUNTIME_VERSION("Specify the version of the runtime library used for compiling LF programs."),
SCHEDULER("Specify the runtime scheduler (if supported)."),
TARGET_COMPILER("Target compiler to invoke."),
THREADING("Specify whether the runtime should use multi-threading (true/false)."),
VERSION("Print version information."),
WORKERS("Specify the default number of worker threads.");

public final String description;

BuildParm(String description) {
this.description = description;
}

/**
* Return the string to use as the key to store a value relating to this parameter.
*/
public String getKey() {
return this.name().toLowerCase().replace('_', '-');
}

/**
* Return the value corresponding to this parameter or `null` if there is none.
* @param context The context passed to the code generator.
*/
public String getValue(LFGeneratorContext context) {
return context.getArgs().getProperty(this.getKey());
}
}


enum Mode {
STANDALONE,
EPOCH,
Expand Down
46 changes: 25 additions & 21 deletions org.lflang/src/org/lflang/generator/ts/TSGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ class TSGenerator(
*/
val CONFIG_FILES = arrayOf("package.json", "tsconfig.json", "babel.config.js", ".eslintrc.json")

val RT_CONFIG_FILES = arrayOf("package.json", "package-lock.json", "tsconfig.json", ".babelrc")

private val VG =
ExpressionGenerator(::timeInTargetLanguage) { param -> "this.${param.name}.get()" }

Expand Down Expand Up @@ -147,9 +145,8 @@ class TSGenerator(
createMainReactorInstance()

clean(context)
copyRuntime()
collectDependencies(resource, context, tsFileConfig.reactorTsPath(), true)
copyConfigFiles()
updatePackageConfig(context)

val codeMaps = HashMap<Path, CodeMap>()
val dockerGenerator = TSDockerGenerator(isFederated)
Expand Down Expand Up @@ -193,6 +190,30 @@ class TSGenerator(
}
}

/**
* Update package.json according to given build parameters.
*/
private fun updatePackageConfig(context: LFGeneratorContext) {
var rtPath = LFGeneratorContext.BuildParm.EXTERNAL_RUNTIME_PATH.getValue(context)
val rtVersion = LFGeneratorContext.BuildParm.RUNTIME_VERSION.getValue(context)
val sb = StringBuffer("");
val manifest = fileConfig.srcGenPath.resolve("package.json");
val rtRegex = Regex("(\"@lf-lang/reactor-ts\")(.+)")
if (rtPath != null && !rtPath.startsWith("file:")) rtPath = "file:$rtPath"
// FIXME: do better CLI arg validation upstream
// https://github.com/lf-lang/lingua-franca/issues/1429
manifest.toFile().forEachLine {
var line = it.replace("\"LinguaFrancaDefault\"", "\"${fileConfig.name}\"");
if (rtPath != null) {
line = line.replace(rtRegex, "$1: \"$rtPath\",")
} else if (rtVersion != null) {
line = line.replace(rtRegex, "$1: \"git://github.com/lf-lang/reactor-ts.git#$rtVersion\",")
}
sb.appendLine(line)
}
manifest.toFile().writeText(sb.toString());
}

/**
* Clean up the src-gen directory as needed to prepare for code generation.
*/
Expand All @@ -203,23 +224,6 @@ class TSGenerator(
)
}

/**
* Copy the TypeScript runtime so that it is accessible to the generated code.
*/
private fun copyRuntime() {
FileUtil.copyDirectoryFromClassPath(
"$LIB_PATH/reactor-ts/src/core",
tsFileConfig.reactorTsPath().resolve("src").resolve("core"),
true
)
for (configFile in RT_CONFIG_FILES) {
FileUtil.copyFileFromClassPath(
"$LIB_PATH/reactor-ts/$configFile",
tsFileConfig.reactorTsPath().resolve(configFile)
)
}
}

/**
* For each configuration file that is not present in the same directory
* as the source file, copy a default version from $LIB_PATH/.
Expand Down
26 changes: 13 additions & 13 deletions org.lflang/src/org/lflang/generator/ts/TSImportPreambleGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,18 @@ class TSImportPreambleGenerator(
const val DEFAULT_IMPORTS = """
|import commandLineArgs from 'command-line-args'
|import commandLineUsage from 'command-line-usage'
|import {Parameter as __Parameter, Timer as __Timer, Reactor as __Reactor, App as __App} from 'reactor-ts'
|import {Action as __Action, Startup as __Startup, FederatePortAction as __FederatePortAction} from 'reactor-ts'
|import {Bank as __Bank} from 'reactor-ts'
|import {FederatedApp as __FederatedApp} from 'reactor-ts'
|import {InPort as __InPort, OutPort as __OutPort, Port as __Port, WritablePort as __WritablePort, WritableMultiPort as __WritableMultiPort} from 'reactor-ts'
|import {InMultiPort as __InMultiPort, OutMultiPort as __OutMultiPort} from 'reactor-ts'
|import {Reaction as __Reaction} from 'reactor-ts'
|import {State as __State} from 'reactor-ts'
|import {TimeUnit, TimeValue, Tag as __Tag, Origin as __Origin} from 'reactor-ts'
|import {Args as __Args, Variable as __Variable, Triggers as __Triggers, Present, Read, Write, ReadWrite, MultiReadWrite, Sched} from 'reactor-ts'
|import {Log} from 'reactor-ts'
|import {ProcessedCommandLineArgs as __ProcessedCommandLineArgs, CommandLineOptionDefs as __CommandLineOptionDefs, CommandLineUsageDefs as __CommandLineUsageDefs, CommandLineOptionSpec as __CommandLineOptionSpec, unitBasedTimeValueCLAType as __unitBasedTimeValueCLAType, booleanCLAType as __booleanCLAType} from 'reactor-ts'
|import {Parameter as __Parameter, Timer as __Timer, Reactor as __Reactor, App as __App} from '@lf-lang/reactor-ts'
|import {Action as __Action, Startup as __Startup, FederatePortAction as __FederatePortAction} from '@lf-lang/reactor-ts'
|import {Bank as __Bank} from '@lf-lang/reactor-ts'
|import {FederatedApp as __FederatedApp} from '@lf-lang/reactor-ts'
|import {InPort as __InPort, OutPort as __OutPort, Port as __Port, WritablePort as __WritablePort, WritableMultiPort as __WritableMultiPort} from '@lf-lang/reactor-ts'
|import {InMultiPort as __InMultiPort, OutMultiPort as __OutMultiPort} from '@lf-lang/reactor-ts'
|import {Reaction as __Reaction} from '@lf-lang/reactor-ts'
|import {State as __State} from '@lf-lang/reactor-ts'
|import {TimeUnit, TimeValue, Tag as __Tag, Origin as __Origin} from '@lf-lang/reactor-ts'
|import {Args as __Args, Variable as __Variable, Triggers as __Triggers, Present, Read, Write, ReadWrite, MultiReadWrite, Sched} from '@lf-lang/reactor-ts'
|import {Log} from '@lf-lang/reactor-ts'
|import {ProcessedCommandLineArgs as __ProcessedCommandLineArgs, CommandLineOptionDefs as __CommandLineOptionDefs, CommandLineUsageDefs as __CommandLineUsageDefs, CommandLineOptionSpec as __CommandLineOptionSpec, unitBasedTimeValueCLAType as __unitBasedTimeValueCLAType, booleanCLAType as __booleanCLAType} from '@lf-lang/reactor-ts'
|"""
}

Expand Down Expand Up @@ -102,4 +102,4 @@ class TSImportPreambleGenerator(
fun generatePreamble(): String {
return generateDefaultImports() + generateProtoPreamble()
}
}
}
17 changes: 17 additions & 0 deletions test/TypeScript/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,19 @@
# Library of TypeScript tests
To run the entire test suite, execute `./gradlew test --tests org.lflang.tests.runtime.TypeScriptTest.*`.

## Using an alternative runtime
To run the tests with an alternative runtime, use the `-Druntime` flag to specify where to find it.

### Examples
- To use a local checkout of `reactor-ts` located in the local file system in the directory `~/lf-lang/reactor-ts`:
```
./gradlew test --tests org.lflang.tests.runtime.TypeScriptTest.* -Druntime="~/lf-lang/reactor-ts"
```
- Note that `lfc` can be pointed to an alternative runtime as well, using the `external-runtime-path` switch:
```
lfc test/TypeScript/src/Minimal.lf --external-runtime-path ~/lf-lang/reactor-ts
lhstrh marked this conversation as resolved.
Show resolved Hide resolved
```
- To point `lfc` to a particular ref (e.g. `main`, `v0.1.0` or `f8c6d2379f278e22ad48410bf06cf0909405ecc3`) in the `lf-lang/reactor-ts` repo:
```
lfc test/TypeScript/src/Minimal.lf --runtime-version <ref>
```