From 6f2d954471d1293587299c6a3909706ea5bcb9ea Mon Sep 17 00:00:00 2001
From: Peter Donovan
Date: Fri, 14 Jan 2022 17:22:50 -0800
Subject: [PATCH 01/11] TS: Platform-independent remove directory.
---
org.lflang/src/lib/ts/package.json | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/org.lflang/src/lib/ts/package.json b/org.lflang/src/lib/ts/package.json
index 5c14cd6b77..8477a066f0 100644
--- a/org.lflang/src/lib/ts/package.json
+++ b/org.lflang/src/lib/ts/package.json
@@ -26,11 +26,12 @@
"@babel/preset-typescript": "^7.8.3",
"@types/google-protobuf": "^3.7.4",
"@types/node": "^13.9.2",
+ "rimraf": "^3.0.2",
"typescript": "^3.8.3",
"ts-protoc-gen": "^0.12.0"
},
"scripts": {
"check-types": "tsc",
- "build": "rm -rf dist && babel src --out-dir dist --extensions '.ts,.js'"
+ "build": "rimraf dist && babel src --out-dir dist --extensions '.ts,.js'"
}
}
From 3caa19aaadaea19497a9a2f6624775cd81d56a93 Mon Sep 17 00:00:00 2001
From: Peter Donovan
Date: Fri, 14 Jan 2022 17:32:31 -0800
Subject: [PATCH 02/11] LFCommand: Try more aggressively to execute.
The only fully general way that I have found to check if something is executable is to try to start the process and see if an `IOException` occurs. `File.canExecute()` is insufficient -- it can return `true` when the answer is really `false`. Furthermore, successful termination of the `where` command on Windows apparently does not guarantee that the right executable will be used.
---
org.lflang/src/org/lflang/util/LFCommand.java | 58 ++++++++++++++-----
1 file changed, 44 insertions(+), 14 deletions(-)
diff --git a/org.lflang/src/org/lflang/util/LFCommand.java b/org.lflang/src/org/lflang/util/LFCommand.java
index bfc1189d8c..b1f4c35637 100644
--- a/org.lflang/src/org/lflang/util/LFCommand.java
+++ b/org.lflang/src/org/lflang/util/LFCommand.java
@@ -33,12 +33,16 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
import java.io.PrintStream;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.ArrayDeque;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import java.util.Queue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
import org.eclipse.xtext.util.CancelIndicator;
@@ -174,13 +178,8 @@ public int run(CancelIndicator cancelIndicator) {
System.out.println("--- Current working directory: " + processBuilder.directory().toString());
System.out.println("--- Executing command: " + String.join(" ", processBuilder.command()));
- final Process process;
- try {
- process = processBuilder.start();
- } catch (IOException e) {
- e.printStackTrace();
- return -1;
- }
+ final Process process = startProcess();
+ if (process == null) return -1;
ScheduledExecutorService poller = Executors.newSingleThreadScheduledExecutor();
poller.scheduleAtFixedRate(
@@ -303,7 +302,7 @@ public static LFCommand get(final String cmd, final List args, Path dir)
final File cmdFile = dir.resolve(cmd).toFile();
if (cmdFile.exists() && cmdFile.canExecute()) {
builder = new ProcessBuilder(cmdList);
- } else if (checkIfCommandIsOnPath(cmd, dir)) {
+ } else if (findCommand(cmd) != null) {
builder = new ProcessBuilder(cmdList);
} else if (checkIfCommandIsExecutableWithBash(cmd, dir)) {
builder = new ProcessBuilder("bash", "--login", "-c", String.join(" ", cmdList));
@@ -318,23 +317,54 @@ public static LFCommand get(final String cmd, final List args, Path dir)
}
- private static boolean checkIfCommandIsOnPath(final String command, final Path dir) {
+ /**
+ * Search for matches to the given command by following the PATH environment variable.
+ * @param command A command for which to search.
+ * @return The file locations of matches to the given command.
+ */
+ private static List findCommand(final String command) {
final String whichCmd = System.getProperty("os.name").startsWith("Windows") ? "where" : "which";
final ProcessBuilder whichBuilder = new ProcessBuilder(List.of(whichCmd, command));
- whichBuilder.directory(dir.toFile());
try {
- int whichReturn = whichBuilder.start().waitFor();
- return whichReturn == 0;
+ Process p = whichBuilder.start();
+ if (p.waitFor() != 0) return null;
+ return Arrays.stream(new String(p.getInputStream().readAllBytes()).split("\n"))
+ .map(String::strip).map(File::new).filter(File::canExecute).collect(Collectors.toList());
} catch (InterruptedException | IOException e) {
e.printStackTrace();
- return false;
+ return null;
+ }
+ }
+
+ /**
+ * Attempt to start the execution of this command.
+ * @return The {@code Process} that is started by this command, or {@code null} in case of failure.
+ */
+ private Process startProcess() {
+ Queue> commands = new ArrayDeque<>();
+ commands.add(processBuilder.command());
+ findCommand(processBuilder.command().get(0)).stream().map(it -> {
+ List template = processBuilder.command();
+ template.set(0, it.toString());
+ return template;
+ }).forEach(commands::add);
+ while (true) {
+ processBuilder.command(commands.poll());
+ try {
+ return processBuilder.start();
+ } catch (IOException e) {
+ if (commands.isEmpty()) {
+ e.printStackTrace();
+ return null;
+ }
+ }
}
}
private static boolean checkIfCommandIsExecutableWithBash(final String command, final Path dir) {
// check first if bash is installed
- if (!checkIfCommandIsOnPath("bash", dir)) {
+ if (findCommand("bash") == null) {
return false;
}
From ae80e56d76b714ed12ad68a7299c353f450c343e Mon Sep 17 00:00:00 2001
From: Peter Donovan
Date: Fri, 14 Jan 2022 17:39:01 -0800
Subject: [PATCH 03/11] CI: Run TS tests for Windows.
---
.github/workflows/ts-tests.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/ts-tests.yml b/.github/workflows/ts-tests.yml
index 825818dbd2..8b2402687e 100644
--- a/.github/workflows/ts-tests.yml
+++ b/.github/workflows/ts-tests.yml
@@ -14,7 +14,7 @@ jobs:
run:
strategy:
matrix:
- platform: [ubuntu-latest, macos-latest]
+ platform: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.platform }}
steps:
- name: Setup Java JDK
From ea91b4b9f7f9aae5f79b1a9e83dc7018478c5be6 Mon Sep 17 00:00:00 2001
From: Peter Donovan
Date: Fri, 14 Jan 2022 18:07:52 -0800
Subject: [PATCH 04/11] Update ci.yml.
---
.github/workflows/ci.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 773c0baad4..3a0f6bc470 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -58,4 +58,4 @@ 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@windows-ts
From c7c175b6409e61e3212f8c5b7ea598fce85a8644 Mon Sep 17 00:00:00 2001
From: Peter Donovan
Date: Fri, 14 Jan 2022 18:15:17 -0800
Subject: [PATCH 05/11] CI: Remove possibly unnecessary sudo.
---
.github/workflows/ts-tests.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/ts-tests.yml b/.github/workflows/ts-tests.yml
index 8b2402687e..5d81c933ac 100644
--- a/.github/workflows/ts-tests.yml
+++ b/.github/workflows/ts-tests.yml
@@ -29,7 +29,7 @@ jobs:
path: ~/.pnpm-store
key: ${{ runner.os }}-node${{ matrix.node-version }}-${{ hashFiles('**/pnpm-lock.yaml') }}
- name: Install pnpm
- run: sudo npm i -g pnpm
+ run: npm i -g pnpm
- name: Install Dependencies Ubuntu
run: sudo apt-get install libprotobuf-dev protobuf-compiler
if: ${{ runner.os == 'Linux' }}
From d0a66937be4182b79b3bbaafe0b52f12dc6bb0d8 Mon Sep 17 00:00:00 2001
From: Peter Donovan
Date: Fri, 14 Jan 2022 19:12:56 -0800
Subject: [PATCH 06/11] TS: Windows does not like certain single quotes.
---
org.lflang/src/lib/ts/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/org.lflang/src/lib/ts/package.json b/org.lflang/src/lib/ts/package.json
index 8477a066f0..367a812ab7 100644
--- a/org.lflang/src/lib/ts/package.json
+++ b/org.lflang/src/lib/ts/package.json
@@ -32,6 +32,6 @@
},
"scripts": {
"check-types": "tsc",
- "build": "rimraf dist && babel src --out-dir dist --extensions '.ts,.js'"
+ "build": "rimraf dist && babel src --out-dir dist --extensions .ts,.js"
}
}
From f84578e62aee34260fcae3be56c2cb51e9db15d7 Mon Sep 17 00:00:00 2001
From: Peter Donovan
Date: Sat, 15 Jan 2022 21:47:51 -0800
Subject: [PATCH 07/11] LFCommand: Repair mistake in recent commit.
---
org.lflang/src/org/lflang/util/LFCommand.java | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/org.lflang/src/org/lflang/util/LFCommand.java b/org.lflang/src/org/lflang/util/LFCommand.java
index b1f4c35637..33afe44113 100644
--- a/org.lflang/src/org/lflang/util/LFCommand.java
+++ b/org.lflang/src/org/lflang/util/LFCommand.java
@@ -38,7 +38,6 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
import java.util.Arrays;
import java.util.List;
import java.util.Map;
-import java.util.Queue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@@ -341,15 +340,12 @@ private static List findCommand(final String command) {
* @return The {@code Process} that is started by this command, or {@code null} in case of failure.
*/
private Process startProcess() {
- Queue> commands = new ArrayDeque<>();
- commands.add(processBuilder.command());
- findCommand(processBuilder.command().get(0)).stream().map(it -> {
- List template = processBuilder.command();
- template.set(0, it.toString());
- return template;
- }).forEach(commands::add);
+ ArrayDeque commands = new ArrayDeque<>();
+ List matchesOnPath = findCommand(processBuilder.command().get(0));
+ if (matchesOnPath != null) {
+ matchesOnPath.stream().map(File::toString).forEach(commands::addLast);
+ }
while (true) {
- processBuilder.command(commands.poll());
try {
return processBuilder.start();
} catch (IOException e) {
@@ -358,6 +354,7 @@ private Process startProcess() {
return null;
}
}
+ processBuilder.command().set(0, commands.removeFirst());
}
}
From b245db4ae8721ea4a78e9643d0e99dddb3bc7be0 Mon Sep 17 00:00:00 2001
From: Peter Donovan
Date: Sat, 15 Jan 2022 22:56:41 -0800
Subject: [PATCH 08/11] TS: Do not run serialization tests on Windows.
---
.../src/org/lflang/tests/runtime/TypeScriptTest.java | 2 ++
test/TypeScript/src/{ => serialization}/Person.proto | 0
test/TypeScript/src/{ => serialization}/ProtoHelloWorld.proto | 0
test/TypeScript/src/{ => serialization}/ProtoNoPacking.lf | 0
4 files changed, 2 insertions(+)
rename test/TypeScript/src/{ => serialization}/Person.proto (100%)
rename test/TypeScript/src/{ => serialization}/ProtoHelloWorld.proto (100%)
rename test/TypeScript/src/{ => serialization}/ProtoNoPacking.lf (100%)
diff --git a/org.lflang.tests/src/org/lflang/tests/runtime/TypeScriptTest.java b/org.lflang.tests/src/org/lflang/tests/runtime/TypeScriptTest.java
index f626306504..108bf220e8 100644
--- a/org.lflang.tests/src/org/lflang/tests/runtime/TypeScriptTest.java
+++ b/org.lflang.tests/src/org/lflang/tests/runtime/TypeScriptTest.java
@@ -1,5 +1,6 @@
package org.lflang.tests.runtime;
+import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
import org.lflang.Target;
import org.lflang.tests.AbstractTest;
@@ -46,6 +47,7 @@ public void runMultiportTests() {
@Test
@Override
public void runSerializationTests() {
+ Assumptions.assumeFalse(isWindows(), Message.NO_WINDOWS_SUPPORT);
super.runSerializationTests();
}
diff --git a/test/TypeScript/src/Person.proto b/test/TypeScript/src/serialization/Person.proto
similarity index 100%
rename from test/TypeScript/src/Person.proto
rename to test/TypeScript/src/serialization/Person.proto
diff --git a/test/TypeScript/src/ProtoHelloWorld.proto b/test/TypeScript/src/serialization/ProtoHelloWorld.proto
similarity index 100%
rename from test/TypeScript/src/ProtoHelloWorld.proto
rename to test/TypeScript/src/serialization/ProtoHelloWorld.proto
diff --git a/test/TypeScript/src/ProtoNoPacking.lf b/test/TypeScript/src/serialization/ProtoNoPacking.lf
similarity index 100%
rename from test/TypeScript/src/ProtoNoPacking.lf
rename to test/TypeScript/src/serialization/ProtoNoPacking.lf
From 6e2e70673d3fadce6c9c70dfb098ce6158ac687e Mon Sep 17 00:00:00 2001
From: Peter Donovan
Date: Fri, 7 Jan 2022 16:11:55 -0800
Subject: [PATCH 09/11] TypeScript CI: Delete cache step.
This cache step may not be effective because the lock files that it attempts to hash do not exist when the hash is computed at the beginning of the workflow.
---
.github/workflows/ts-tests.yml | 5 -----
1 file changed, 5 deletions(-)
diff --git a/.github/workflows/ts-tests.yml b/.github/workflows/ts-tests.yml
index 5d81c933ac..f0bea1dffb 100644
--- a/.github/workflows/ts-tests.yml
+++ b/.github/workflows/ts-tests.yml
@@ -23,11 +23,6 @@ jobs:
java-version: 11
- name: Setup Node.js environment
uses: actions/setup-node@v2.1.2
- - name: Cache .pnpm-store
- uses: actions/cache@v1
- with:
- path: ~/.pnpm-store
- key: ${{ runner.os }}-node${{ matrix.node-version }}-${{ hashFiles('**/pnpm-lock.yaml') }}
- name: Install pnpm
run: npm i -g pnpm
- name: Install Dependencies Ubuntu
From 109ab5c92fd2f94dffad82040b03344eeb1614cd Mon Sep 17 00:00:00 2001
From: Peter Donovan <33707478+petervdonovan@users.noreply.github.com>
Date: Mon, 17 Jan 2022 20:41:13 -0800
Subject: [PATCH 10/11] Update org.lflang/src/org/lflang/util/LFCommand.java
Co-authored-by: Marten Lohstroh
---
org.lflang/src/org/lflang/util/LFCommand.java | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/org.lflang/src/org/lflang/util/LFCommand.java b/org.lflang/src/org/lflang/util/LFCommand.java
index 33afe44113..d0a6bfb634 100644
--- a/org.lflang/src/org/lflang/util/LFCommand.java
+++ b/org.lflang/src/org/lflang/util/LFCommand.java
@@ -337,6 +337,12 @@ private static List findCommand(final String command) {
/**
* Attempt to start the execution of this command.
+ *
+ * First collect a list of paths where the executable might be found,
+ * then select an executable that successfully executes from the
+ * list of paths. Return the {@code Process} instance that is the
+ * result of a successful execution, or {@code null} if no successful
+ * execution happened.
* @return The {@code Process} that is started by this command, or {@code null} in case of failure.
*/
private Process startProcess() {
From 0f8415d61becea0ae267d93b371f0cd6bcf02d52 Mon Sep 17 00:00:00 2001
From: Peter Donovan
Date: Mon, 17 Jan 2022 20:47:59 -0800
Subject: [PATCH 11/11] CI: Update workflow ref.
---
.github/workflows/ci.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3a0f6bc470..773c0baad4 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -58,4 +58,4 @@ jobs:
# Run the TypeScript integration tests.
ts-tests:
- uses: lf-lang/lingua-franca/.github/workflows/ts-tests.yml@windows-ts
+ uses: lf-lang/lingua-franca/.github/workflows/ts-tests.yml@master