eolang 0.35.1 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Formula/eolang.rb +3 -3
- package/Formula/eolang@0.34.1.rb +25 -0
- package/Formula/eolang@0.35.1.rb +25 -0
- package/README.md +25 -37
- package/eo-version.txt +1 -1
- package/eslint.config.js +3 -0
- package/home-tag.txt +1 -1
- package/mvnw/.mvn/wrapper/maven-wrapper.properties +1 -1
- package/mvnw/dependency-reduced-pom.xml +7 -7
- package/mvnw/pom.xml +5 -5
- package/package.json +6 -7
- package/scripts/readme_automation.js +50 -0
- package/src/commands/docs.js +31 -0
- package/src/commands/foreign.js +44 -2
- package/src/commands/java/compile.js +2 -0
- package/src/commands/java/link.js +2 -0
- package/src/commands/java/pipeline.js +13 -0
- package/src/commands/java/test.js +18 -8
- package/src/commands/lint.js +3 -3
- package/src/commands/normalize.js +4 -3
- package/src/elapsed.js +1 -1
- package/src/eo2jsw.js +10 -10
- package/src/eoc.js +96 -67
- package/src/jdk.js +65 -0
- package/src/mvnw.js +22 -9
- package/src/parser-version.js +22 -11
- package/src/version.js +2 -2
- package/patches/grunt-mocha-cli+7.0.0.patch +0 -25
- package/scripts/postinstall.js +0 -53
package/Formula/eolang.rb
CHANGED
|
@@ -7,9 +7,9 @@ require "language/node"
|
|
|
7
7
|
class Eolang < Formula
|
|
8
8
|
desc "Command-line Tool-Kit"
|
|
9
9
|
homepage "https://github.com/objectionary/eoc"
|
|
10
|
-
url "https://github.com/objectionary/eoc/archive/refs/tags/0.
|
|
11
|
-
version "0.
|
|
12
|
-
sha256 "
|
|
10
|
+
url "https://github.com/objectionary/eoc/archive/refs/tags/0.35.2.tar.gz"
|
|
11
|
+
version "0.35.2"
|
|
12
|
+
sha256 "436b27218fb5acc48bbc56ecd8d6c5c9b4592fa19735e75515e21297938dc7de"
|
|
13
13
|
license "MIT"
|
|
14
14
|
|
|
15
15
|
depends_on "node"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#
|
|
2
|
+
# SPDX-FileCopyrightText: Copyright (c) 2022-2026 Objectionary.com
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
#
|
|
5
|
+
|
|
6
|
+
require "language/node"
|
|
7
|
+
class EolangAT0351 < Formula
|
|
8
|
+
desc "Command-line Tool-Kit"
|
|
9
|
+
homepage "https://github.com/objectionary/eoc"
|
|
10
|
+
url "https://github.com/objectionary/eoc/archive/refs/tags/0.34.1.tar.gz"
|
|
11
|
+
version "0.34.1"
|
|
12
|
+
sha256 "ecf7f19115086fadbe1785b789378928d81dc8f0e3aa154b268f3a747c80fd01"
|
|
13
|
+
license "MIT"
|
|
14
|
+
|
|
15
|
+
depends_on "node"
|
|
16
|
+
|
|
17
|
+
def install
|
|
18
|
+
system "npm", "install", *std_npm_args
|
|
19
|
+
bin.install_symlink Dir["#{libexec}/bin/*"]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
test do
|
|
23
|
+
system "#{bin}/eoc", "--version"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#
|
|
2
|
+
# SPDX-FileCopyrightText: Copyright (c) 2022-2026 Objectionary.com
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
#
|
|
5
|
+
|
|
6
|
+
require "language/node"
|
|
7
|
+
class EolangAT0352 < Formula
|
|
8
|
+
desc "Command-line Tool-Kit"
|
|
9
|
+
homepage "https://github.com/objectionary/eoc"
|
|
10
|
+
url "https://github.com/objectionary/eoc/archive/refs/tags/0.35.1.tar.gz"
|
|
11
|
+
version "0.35.1"
|
|
12
|
+
sha256 "694218ea2ab13179be731ab7d671ba5f7ebe9a8aa9fc6b5d695d699180879466"
|
|
13
|
+
license "MIT"
|
|
14
|
+
|
|
15
|
+
depends_on "node"
|
|
16
|
+
|
|
17
|
+
def install
|
|
18
|
+
system "npm", "install", *std_npm_args
|
|
19
|
+
bin.install_symlink Dir["#{libexec}/bin/*"]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
test do
|
|
23
|
+
system "#{bin}/eoc", "--version"
|
|
24
|
+
end
|
|
25
|
+
end
|
package/README.md
CHANGED
|
@@ -20,14 +20,14 @@ First, you install [npm][npm-install] and [Java SE][java-se].
|
|
|
20
20
|
Then, you install [eolang][npm] package, using [npm][npm-install]:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
npm install -g eolang@0.35.
|
|
23
|
+
npm install -g eolang@0.35.2
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
You can also use [Homebrew] (on macOS):
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
29
|
brew tap objectionary/eoc https://github.com/objectionary/eoc
|
|
30
|
-
brew install objectionary/eoc/eolang@0.35.
|
|
30
|
+
brew install objectionary/eoc/eolang@0.35.2
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
Or install it via [Nix flakes](https://nixos.wiki/wiki/Flakes):
|
|
@@ -115,41 +115,29 @@ That's it.
|
|
|
115
115
|
You can also do many other things with `eoc` commands
|
|
116
116
|
(the flow is explained in [this blog post][blog]):
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
* `
|
|
120
|
-
|
|
121
|
-
* `
|
|
122
|
-
|
|
123
|
-
* `
|
|
124
|
-
|
|
125
|
-
* `
|
|
126
|
-
* `
|
|
127
|
-
* `
|
|
128
|
-
* `
|
|
129
|
-
* `
|
|
130
|
-
|
|
131
|
-
* `
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
* `
|
|
138
|
-
* `
|
|
139
|
-
* `
|
|
140
|
-
|
|
141
|
-
documentation for `.eo` structures
|
|
142
|
-
* `docs` generates HTML documentation from `.xmir` files
|
|
143
|
-
* `latex` generates `.tex` files from `.eo` sources
|
|
144
|
-
* `fmt` formats `.eo` files in the source directory
|
|
145
|
-
* `normalize` normalizes `.eo` files via phi-calculus rewriting using
|
|
146
|
-
[phino](https://github.com/objectionary/phino) (must be installed separately);
|
|
147
|
-
original files are saved to `.eoc/before-normalize/` for debugging
|
|
148
|
-
* ~~`translate` converts Java/C++/Python/etc. program to EO program~~
|
|
149
|
-
* ~~`demu` removes `cage` and `memory` objects~~
|
|
150
|
-
* ~~`dejump` removes `goto` objects~~
|
|
151
|
-
* ~~`infer` suggests object names where it's possible to infer them~~
|
|
152
|
-
* ~~`flatten` moves inner objects to upper level~~
|
|
118
|
+
<!-- BEGIN COMMANDS SECTION -->
|
|
119
|
+
* `audit` Inspect all packages and report their status
|
|
120
|
+
* `foreign` Inspect and print the list of foreign objects
|
|
121
|
+
* `clean` Delete all temporary files
|
|
122
|
+
* `register` Register all visible EO source files
|
|
123
|
+
* `parse` Parse EO files into XMIR
|
|
124
|
+
* `assemble` Parse EO files into XMIR and join them with required dependencies
|
|
125
|
+
* `print` Generate EO files from XMIR files
|
|
126
|
+
* `lint` Lint XMIR files and fail if any issues inside
|
|
127
|
+
* `resolve` Resolve all the dependencies required for compilation
|
|
128
|
+
* `transpile` Convert EO files into target language
|
|
129
|
+
* `compile` Compile target language sources into binaries
|
|
130
|
+
* `link` Link together all binaries into a single executable binary
|
|
131
|
+
* `dataize` Run the single executable binary and dataize an object
|
|
132
|
+
* `test` Run all visible unit tests
|
|
133
|
+
* `docs` Generate documentation from XMIR files
|
|
134
|
+
* `generate_comments` Generate documentation with LLM
|
|
135
|
+
* `jeo:disassemble` Disassemble .class files to .xmir files
|
|
136
|
+
* `jeo:assemble` Assemble .xmir files to .class files
|
|
137
|
+
* `latex` Generate LaTeX files from EO sources
|
|
138
|
+
* `normalize` Normalize EO files using phi-calculus normalization via phino
|
|
139
|
+
* `fmt` Format EO files in the source directory
|
|
140
|
+
<!-- END COMMANDS SECTION -->
|
|
153
141
|
|
|
154
142
|
This command line toolkit simply integrates other tools available in
|
|
155
143
|
the [@objectionary](https://github.com/objectionary) GitHub organization.
|
package/eo-version.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.61.
|
|
1
|
+
0.61.3
|
package/eslint.config.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const { configs } = require('@eslint/js');
|
|
7
7
|
const promise = require('eslint-plugin-promise');
|
|
8
|
+
const jsdoc = require('eslint-plugin-jsdoc');
|
|
8
9
|
const noEmptyLinesInMethod = require('./eslintPlugin/rules/noEmptyLinesInMethod');
|
|
9
10
|
|
|
10
11
|
const localPlugin = {
|
|
@@ -25,6 +26,7 @@ module.exports = [
|
|
|
25
26
|
},
|
|
26
27
|
plugins: {
|
|
27
28
|
promise,
|
|
29
|
+
jsdoc,
|
|
28
30
|
local: localPlugin
|
|
29
31
|
},
|
|
30
32
|
rules: {
|
|
@@ -68,6 +70,7 @@ module.exports = [
|
|
|
68
70
|
'sort-keys': 'off',
|
|
69
71
|
'sort-vars': 'off',
|
|
70
72
|
'promise/prefer-await-to-then': 'error',
|
|
73
|
+
'jsdoc/check-alignment': 'error',
|
|
71
74
|
'local/no-empty-lines-in-method': 'error'
|
|
72
75
|
}
|
|
73
76
|
},
|
package/home-tag.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.61.3
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
# SPDX-FileCopyrightText: Copyright (c) 2022-2026 Objectionary.com
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
|
-
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.
|
|
4
|
+
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.16/apache-maven-3.9.16-bin.zip
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<plugins>
|
|
14
14
|
<plugin>
|
|
15
15
|
<artifactId>maven-enforcer-plugin</artifactId>
|
|
16
|
-
<version>3.6.
|
|
16
|
+
<version>3.6.3</version>
|
|
17
17
|
<executions>
|
|
18
18
|
<execution>
|
|
19
19
|
<goals>
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
</plugin>
|
|
78
78
|
<plugin>
|
|
79
79
|
<artifactId>maven-surefire-plugin</artifactId>
|
|
80
|
-
<version>3.5.
|
|
80
|
+
<version>3.5.6</version>
|
|
81
81
|
<configuration>
|
|
82
82
|
<skipTests>true</skipTests>
|
|
83
83
|
</configuration>
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
</plugin>
|
|
121
121
|
<plugin>
|
|
122
122
|
<artifactId>maven-surefire-plugin</artifactId>
|
|
123
|
-
<version>3.5.
|
|
123
|
+
<version>3.5.6</version>
|
|
124
124
|
<configuration>
|
|
125
125
|
<skipTests>false</skipTests>
|
|
126
126
|
<failIfNoTests>true</failIfNoTests>
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
<dependency>
|
|
159
159
|
<groupId>org.junit.jupiter</groupId>
|
|
160
160
|
<artifactId>junit-jupiter-api</artifactId>
|
|
161
|
-
<version>6.0
|
|
161
|
+
<version>6.1.0</version>
|
|
162
162
|
<scope>test</scope>
|
|
163
163
|
<exclusions>
|
|
164
164
|
<exclusion>
|
|
@@ -182,7 +182,7 @@
|
|
|
182
182
|
<dependency>
|
|
183
183
|
<groupId>org.junit.jupiter</groupId>
|
|
184
184
|
<artifactId>junit-jupiter-engine</artifactId>
|
|
185
|
-
<version>6.0
|
|
185
|
+
<version>6.1.0</version>
|
|
186
186
|
<scope>test</scope>
|
|
187
187
|
<exclusions>
|
|
188
188
|
<exclusion>
|
|
@@ -206,7 +206,7 @@
|
|
|
206
206
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
|
207
207
|
<heap-size>undefined</heap-size>
|
|
208
208
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
209
|
-
<junit.version>6.0
|
|
210
|
-
<jeo.version>0.15.
|
|
209
|
+
<junit.version>6.1.0</junit.version>
|
|
210
|
+
<jeo.version>0.15.3</jeo.version>
|
|
211
211
|
</properties>
|
|
212
212
|
</project>
|
package/mvnw/pom.xml
CHANGED
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
<version>0.0.0</version>
|
|
11
11
|
<packaging>jar</packaging>
|
|
12
12
|
<properties>
|
|
13
|
-
<jeo.version>0.15.
|
|
13
|
+
<jeo.version>0.15.3</jeo.version>
|
|
14
14
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
15
15
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
|
16
16
|
<eo.version>undefined</eo.version>
|
|
17
17
|
<heap-size>undefined</heap-size>
|
|
18
18
|
<stack-size>undefined</stack-size>
|
|
19
|
-
<junit.version>6.0
|
|
19
|
+
<junit.version>6.1.0</junit.version>
|
|
20
20
|
</properties>
|
|
21
21
|
<dependencies>
|
|
22
22
|
<dependency>
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
<plugins>
|
|
35
35
|
<plugin>
|
|
36
36
|
<artifactId>maven-enforcer-plugin</artifactId>
|
|
37
|
-
<version>3.6.
|
|
37
|
+
<version>3.6.3</version>
|
|
38
38
|
<executions>
|
|
39
39
|
<execution>
|
|
40
40
|
<goals>
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
</plugin>
|
|
99
99
|
<plugin>
|
|
100
100
|
<artifactId>maven-surefire-plugin</artifactId>
|
|
101
|
-
<version>3.5.
|
|
101
|
+
<version>3.5.6</version>
|
|
102
102
|
<configuration>
|
|
103
103
|
<skipTests>true</skipTests>
|
|
104
104
|
</configuration>
|
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
</plugin>
|
|
161
161
|
<plugin>
|
|
162
162
|
<artifactId>maven-surefire-plugin</artifactId>
|
|
163
|
-
<version>3.5.
|
|
163
|
+
<version>3.5.6</version>
|
|
164
164
|
<configuration>
|
|
165
165
|
<skipTests>false</skipTests>
|
|
166
166
|
<failIfNoTests>true</failIfNoTests>
|
package/package.json
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
"eoc": "./src/eoc.js"
|
|
5
5
|
},
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@langchain/core": "^0.
|
|
8
|
-
"@langchain/openai": "^0.
|
|
7
|
+
"@langchain/core": "^1.0.0",
|
|
8
|
+
"@langchain/openai": "^1.0.0",
|
|
9
9
|
"colors": "^1.4.0",
|
|
10
10
|
"commander": "^12.1.0",
|
|
11
11
|
"eo2js": "^0.0.8",
|
|
@@ -21,15 +21,15 @@
|
|
|
21
21
|
"@eslint/js": "^9.27.0",
|
|
22
22
|
"eslint": "^9.28.0",
|
|
23
23
|
"eslint-config-google": "^0.14.0",
|
|
24
|
+
"eslint-plugin-jsdoc": "^63.0.12",
|
|
24
25
|
"eslint-plugin-promise": "^7.2.1",
|
|
25
26
|
"grunt": "^1.6.1",
|
|
26
27
|
"grunt-contrib-clean": "^2.0.1",
|
|
27
28
|
"grunt-eslint": "^26.0.0",
|
|
28
29
|
"grunt-mocha-test": "^0.13.3",
|
|
29
30
|
"istanbul": "^0.4.5",
|
|
30
|
-
"mocha": "^11.7.
|
|
31
|
-
"nyc": "^18.0.0"
|
|
32
|
-
"patch-package": "^8.0.0"
|
|
31
|
+
"mocha": "^11.7.6",
|
|
32
|
+
"nyc": "^18.0.0"
|
|
33
33
|
},
|
|
34
34
|
"engines": {
|
|
35
35
|
"node": ">6.0",
|
|
@@ -71,8 +71,7 @@
|
|
|
71
71
|
"repository": "objectionary/eoc",
|
|
72
72
|
"scripts": {
|
|
73
73
|
"coverage": "nyc --reporter=lcov --reporter=text-summary mocha test/**/*.js --timeout 1200000",
|
|
74
|
-
"postinstall": "node scripts/postinstall.js",
|
|
75
74
|
"test": "mocha 'test/**/*.js' --timeout 1200000"
|
|
76
75
|
},
|
|
77
|
-
"version": "0.
|
|
76
|
+
"version": "0.36.0"
|
|
78
77
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*
|
|
3
|
+
* SPDX-FileCopyrightText: Copyright (c) 2022-2026 Objectionary.com
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const assert = require('assert');
|
|
8
|
+
const { commandsDescription } = require("../src/eoc");
|
|
9
|
+
|
|
10
|
+
function escapeRegex(str) {
|
|
11
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function updateSection(sectionName, newContent, readMeContent) {
|
|
15
|
+
const start = `<!-- BEGIN ${sectionName.toUpperCase()} SECTION -->`;
|
|
16
|
+
const end = `<!-- END ${sectionName.toUpperCase()} SECTION -->`;
|
|
17
|
+
const regex = new RegExp(
|
|
18
|
+
`(${escapeRegex(start)})([\\s\\S]*?)(${escapeRegex(end)})`,
|
|
19
|
+
"g"
|
|
20
|
+
);
|
|
21
|
+
return readMeContent.replace(regex, `$1\n${newContent}$3`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function bulletListTemplate(rows) {
|
|
25
|
+
return `${rows.map(([cmd, desc]) => `* \`${cmd}\` ${desc}`).join("\n") }\n`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function modifyReadme(commands,fs) {
|
|
29
|
+
assert.ok(commands.length > 0,'Commands should have rows')
|
|
30
|
+
const commandsMarkdown = bulletListTemplate(commands);
|
|
31
|
+
assert.ok(commandsMarkdown.length > 0,"commandsMarkdown result should have text")
|
|
32
|
+
let readMeContent = fs.readFileSync('README.md', "utf8");
|
|
33
|
+
assert.ok(readMeContent.length > 0,"readMeContent should have text")
|
|
34
|
+
readMeContent = updateSection('commands', commandsMarkdown, readMeContent);
|
|
35
|
+
assert.ok(readMeContent.length > 0,"readMeContent should sill have text after modification")
|
|
36
|
+
fs.writeFileSync('README.md',readMeContent);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function syncCommandsToReadme(fs)
|
|
40
|
+
{
|
|
41
|
+
modifyReadme(commandsDescription(),fs);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = {
|
|
45
|
+
bulletListTemplate, updateSection, modifyReadme, syncCommandsToReadme
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
if (require.main === module) {
|
|
49
|
+
syncCommandsToReadme(require("fs"));
|
|
50
|
+
};
|
package/src/commands/docs.js
CHANGED
|
@@ -10,6 +10,17 @@ const { marked } = require('marked');
|
|
|
10
10
|
const {elapsed} = require('../elapsed');
|
|
11
11
|
const {findFiles} = require('../files');
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Escape special XML characters.
|
|
15
|
+
* @param {String} str - Raw string
|
|
16
|
+
* @return {String} XML-safe string
|
|
17
|
+
*/
|
|
18
|
+
function xmlEscape(str) {
|
|
19
|
+
return str.replace(/&/g, '&')
|
|
20
|
+
.replace(/</g, '<')
|
|
21
|
+
.replace(/>/g, '>')
|
|
22
|
+
.replace(/"/g, '"');
|
|
23
|
+
}
|
|
13
24
|
|
|
14
25
|
/**
|
|
15
26
|
* Applies XSLT to XMIR
|
|
@@ -108,6 +119,7 @@ function wrapHtml(name, html, css) {
|
|
|
108
119
|
/**
|
|
109
120
|
* Command to generate documentation.
|
|
110
121
|
* @param {Hash} opts - All options
|
|
122
|
+
* @return {Promise<String>} Resolves to the message reporting the summary path
|
|
111
123
|
*/
|
|
112
124
|
module.exports = function(opts) {
|
|
113
125
|
return elapsed(async (tracked) => {
|
|
@@ -132,10 +144,12 @@ module.exports = function(opts) {
|
|
|
132
144
|
if (!(packages in packages_info)) {
|
|
133
145
|
packages_info[packages] = {
|
|
134
146
|
xmir_htmls : [],
|
|
147
|
+
names: [],
|
|
135
148
|
path: html_package
|
|
136
149
|
};
|
|
137
150
|
}
|
|
138
151
|
packages_info[packages].xmir_htmls.push(xmir_html);
|
|
152
|
+
packages_info[packages].names.push(name);
|
|
139
153
|
all_xmir_htmls.push(xmir_html);
|
|
140
154
|
}
|
|
141
155
|
for (const package_name of Object.keys(packages_info)) {
|
|
@@ -145,7 +159,24 @@ module.exports = function(opts) {
|
|
|
145
159
|
}
|
|
146
160
|
const packages = path.join(output, 'packages.html');
|
|
147
161
|
fs.writeFileSync(packages, generatePackageHtml('overall package', all_xmir_htmls, css));
|
|
162
|
+
const summary = path.join(output, 'summary.xml');
|
|
163
|
+
const pkgNames = Object.keys(packages_info);
|
|
164
|
+
const lines = [
|
|
165
|
+
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
166
|
+
`<eodoc packages="${pkgNames.length}" objects="${xmirs.length}">`
|
|
167
|
+
];
|
|
168
|
+
for (const pkg of pkgNames) {
|
|
169
|
+
lines.push(` <package name="${xmlEscape(pkg)}">`);
|
|
170
|
+
for (const obj of packages_info[pkg].names) {
|
|
171
|
+
lines.push(` <object name="${xmlEscape(obj)}"/>`);
|
|
172
|
+
}
|
|
173
|
+
lines.push(' </package>');
|
|
174
|
+
}
|
|
175
|
+
lines.push('</eodoc>');
|
|
176
|
+
fs.writeFileSync(summary, lines.join('\n'));
|
|
177
|
+
const located = tracked.print(`Summary XML generated at ${path.relative(process.cwd(), summary)}`);
|
|
148
178
|
tracked.print(`Documentation generation completed in the ${output} directory`);
|
|
179
|
+
return located;
|
|
149
180
|
} catch (error) {
|
|
150
181
|
console.error('Error generating documentation:', error);
|
|
151
182
|
throw error;
|
package/src/commands/foreign.js
CHANGED
|
@@ -7,15 +7,57 @@ const rel = require('relative');
|
|
|
7
7
|
const path = require('path');
|
|
8
8
|
const fs = require('fs');
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Extract the first balanced JSON array from a string, ignoring any trailing
|
|
12
|
+
* bytes that may have been left over by a non-atomic writer (observed on
|
|
13
|
+
* Windows CI, see issue #782).
|
|
14
|
+
* @param {String} text - Raw file contents
|
|
15
|
+
* @return {String} Substring spanning the first complete `[...]` array
|
|
16
|
+
*/
|
|
17
|
+
function firstJsonArray(text) {
|
|
18
|
+
const body = text.charCodeAt(0) === 0xFEFF ? text.slice(1) : text;
|
|
19
|
+
let depth = 0;
|
|
20
|
+
let start = -1;
|
|
21
|
+
let inString = false;
|
|
22
|
+
let escape = false;
|
|
23
|
+
for (let i = 0; i < body.length; i += 1) {
|
|
24
|
+
const ch = body[i];
|
|
25
|
+
if (inString) {
|
|
26
|
+
if (escape) {
|
|
27
|
+
escape = false;
|
|
28
|
+
} else if (ch === '\\') {
|
|
29
|
+
escape = true;
|
|
30
|
+
} else if (ch === '"') {
|
|
31
|
+
inString = false;
|
|
32
|
+
}
|
|
33
|
+
} else if (ch === '"') {
|
|
34
|
+
inString = true;
|
|
35
|
+
} else if (ch === '[') {
|
|
36
|
+
if (depth === 0) {
|
|
37
|
+
start = i;
|
|
38
|
+
}
|
|
39
|
+
depth += 1;
|
|
40
|
+
} else if (ch === ']') {
|
|
41
|
+
depth -= 1;
|
|
42
|
+
if (depth === 0 && start >= 0) {
|
|
43
|
+
return body.slice(start, i + 1);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
throw new SyntaxError('No complete JSON array found in foreign catalog');
|
|
48
|
+
}
|
|
49
|
+
|
|
10
50
|
/**
|
|
11
51
|
* Inspects and prints the list of foreign objects.
|
|
12
52
|
* @param {Hash} opts - All options
|
|
13
53
|
*/
|
|
14
54
|
module.exports = function(opts) {
|
|
15
|
-
const file = path.resolve(opts.target, 'eo-foreign.json')
|
|
16
|
-
|
|
55
|
+
const file = path.resolve(opts.target, 'eo-foreign.json');
|
|
56
|
+
const all = JSON.parse(firstJsonArray(fs.readFileSync(file, 'utf8')));
|
|
17
57
|
console.info('There are %d objects in %s:', all.length, rel(file));
|
|
18
58
|
all.forEach((obj) => {
|
|
19
59
|
console.info(' %s', obj.id);
|
|
20
60
|
});
|
|
21
61
|
};
|
|
62
|
+
|
|
63
|
+
module.exports.firstJsonArray = firstJsonArray;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
const rel = require('relative');
|
|
6
6
|
const {mvnw, flags} = require('../../mvnw');
|
|
7
7
|
const {elapsed} = require('../../elapsed');
|
|
8
|
+
const {verifyJavac} = require('../../jdk');
|
|
8
9
|
const path = require('path');
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -13,6 +14,7 @@ const path = require('path');
|
|
|
13
14
|
* @return {Promise} of compile task
|
|
14
15
|
*/
|
|
15
16
|
module.exports = function(opts) {
|
|
17
|
+
verifyJavac();
|
|
16
18
|
const target = path.resolve(opts.target);
|
|
17
19
|
return elapsed(async (tracked) => {
|
|
18
20
|
const r = await mvnw(goals().concat(flags(opts)), opts.target, opts.batch);
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
const rel = require('relative');
|
|
7
7
|
const {mvnw, flags} = require('../../mvnw');
|
|
8
8
|
const {elapsed} = require('../../elapsed');
|
|
9
|
+
const {verifyJavac} = require('../../jdk');
|
|
9
10
|
const path = require('path');
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -14,6 +15,7 @@ const path = require('path');
|
|
|
14
15
|
* @return {Promise} of link task
|
|
15
16
|
*/
|
|
16
17
|
module.exports = function(opts) {
|
|
18
|
+
verifyJavac();
|
|
17
19
|
const jar = path.resolve(opts.target, 'eoc.jar');
|
|
18
20
|
return elapsed(async (tracked) => {
|
|
19
21
|
const r = await mvnw(goals().concat(flags(opts)), opts.target, opts.batch);
|
|
@@ -5,6 +5,16 @@
|
|
|
5
5
|
|
|
6
6
|
const {mvnw, flags} = require('../../mvnw');
|
|
7
7
|
const {elapsed} = require('../../elapsed');
|
|
8
|
+
const {verifyJavac} = require('../../jdk');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Commands whose Maven goals require `javac` to be on the PATH.
|
|
12
|
+
* Anything that triggers the maven-compiler-plugin (or surefire test
|
|
13
|
+
* compilation) must be listed here so we can fail fast with a clear
|
|
14
|
+
* diagnostic instead of letting Maven die with `release version 11
|
|
15
|
+
* not supported`.
|
|
16
|
+
*/
|
|
17
|
+
const JAVAC_COMMANDS = ['compile', 'link', 'test'];
|
|
8
18
|
|
|
9
19
|
/**
|
|
10
20
|
* Runs multiple Maven goals in a single Maven invocation.
|
|
@@ -14,6 +24,9 @@ const {elapsed} = require('../../elapsed');
|
|
|
14
24
|
* @return {Promise} of pipeline task
|
|
15
25
|
*/
|
|
16
26
|
module.exports = function(coms, commands, opts, maven = mvnw) {
|
|
27
|
+
if (commands.some((cmd) => JAVAC_COMMANDS.includes(cmd))) {
|
|
28
|
+
verifyJavac();
|
|
29
|
+
}
|
|
17
30
|
return elapsed(async (tracked) => {
|
|
18
31
|
const {goals, extras} = collect(coms, commands, opts);
|
|
19
32
|
const result = await maven(goals.concat(flags(opts)).concat(extras), opts.target, opts.batch);
|
|
@@ -4,18 +4,28 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
const {mvnw, flags} = require('../../mvnw');
|
|
7
|
+
const {verifyJavac} = require('../../jdk');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Command to run all available unit tests.
|
|
10
11
|
* @param {Object} opts - All options
|
|
12
|
+
* @param {Function} maven - Maven runner, defaults to mvnw
|
|
11
13
|
* @return {Promise} of compile task
|
|
12
14
|
*/
|
|
13
|
-
module.exports = function(opts) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
)
|
|
15
|
+
module.exports = function(opts, maven = mvnw) {
|
|
16
|
+
verifyJavac();
|
|
17
|
+
const args = [
|
|
18
|
+
'surefire:test',
|
|
19
|
+
`-Dstack-size=${opts.stack}`,
|
|
20
|
+
`-Dheap-size=${opts.heap}`,
|
|
21
|
+
];
|
|
22
|
+
if (opts.object) {
|
|
23
|
+
const parts = opts.object.split('.');
|
|
24
|
+
const method = parts.pop().replace(/-/g, '_');
|
|
25
|
+
const obj = parts.pop().replace(/-/g, '_');
|
|
26
|
+
const pkg = parts.map((p) => `EO${p.replace(/-/g, '_')}`).join('.');
|
|
27
|
+
const cls = `EO${obj}*Test`;
|
|
28
|
+
args.push(`-Dtest=${pkg ? `org.eolang.${pkg}.${cls}` : `org.eolang.${cls}`}#${method}`);
|
|
29
|
+
}
|
|
30
|
+
return maven(args.concat(flags(opts)));
|
|
21
31
|
};
|
package/src/commands/lint.js
CHANGED
|
@@ -55,9 +55,9 @@ module.exports = function(opts) {
|
|
|
55
55
|
module.exports.goals = goals;
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
|
-
* Command to get extra Maven flags for lint command.
|
|
59
|
-
* @return {Array.<String>} of extra Maven flags to run for lint command
|
|
60
|
-
*/
|
|
58
|
+
* Command to get extra Maven flags for lint command.
|
|
59
|
+
* @return {Array.<String>} of extra Maven flags to run for lint command
|
|
60
|
+
*/
|
|
61
61
|
module.exports.extras = extras;
|
|
62
62
|
|
|
63
63
|
function goals(opts) {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
const path = require('path');
|
|
7
|
-
const {execSync} = require('child_process');
|
|
7
|
+
const {execSync, execFileSync} = require('child_process');
|
|
8
8
|
const {mvnw, flags} = require('../mvnw');
|
|
9
9
|
const {elapsed} = require('../elapsed');
|
|
10
10
|
const {findFiles, saveFile, copyDir} = require('../files');
|
|
@@ -42,8 +42,9 @@ module.exports = function(opts) {
|
|
|
42
42
|
const rel = path.relative(parsed, xmir);
|
|
43
43
|
console.debug('Normalizing %s', rel);
|
|
44
44
|
const ts = Date.now();
|
|
45
|
-
const out =
|
|
46
|
-
|
|
45
|
+
const out = execFileSync(
|
|
46
|
+
'phino',
|
|
47
|
+
['rewrite', '--input=xmir', '--output=xmir', '--normalize', xmir],
|
|
47
48
|
{stdio: ['pipe', 'pipe', 'pipe']}
|
|
48
49
|
);
|
|
49
50
|
console.debug('Normalized in %dms', Date.now() - ts);
|
package/src/elapsed.js
CHANGED
|
@@ -29,7 +29,7 @@ module.exports.elapsed = function elapsed(task) {
|
|
|
29
29
|
} else if (duration < 60 * 1000) {
|
|
30
30
|
extended = `${Math.ceil(duration / 1000)}s`;
|
|
31
31
|
} else {
|
|
32
|
-
extended = `${Math.ceil(duration /
|
|
32
|
+
extended = `${Math.ceil(duration / (60 * 1000))}min`;
|
|
33
33
|
}
|
|
34
34
|
const msg = `${message} in ${extended}`;
|
|
35
35
|
console.info(msg);
|
package/src/eo2jsw.js
CHANGED
|
@@ -7,11 +7,11 @@ const path = require('path');
|
|
|
7
7
|
const {execSync} = require('child_process'),
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
* Convert eoc arguments to appropriate eo2js flags
|
|
11
|
+
* @param {Object} args - eoc arguments
|
|
12
|
+
* @param {String} lib - Path to eo2js lib
|
|
13
|
+
* @return {Array.<String>} - Flags for eo2js
|
|
14
|
+
*/
|
|
15
15
|
flags = function(args, lib) {
|
|
16
16
|
return [
|
|
17
17
|
'--target', args.target,
|
|
@@ -24,11 +24,11 @@ const {execSync} = require('child_process'),
|
|
|
24
24
|
},
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
* Wrapper for eo2js.
|
|
28
|
+
* @param {String} command - Command to execute
|
|
29
|
+
* @param {Object} args - Command arguments
|
|
30
|
+
* @return {Promise<Array.<String>>}
|
|
31
|
+
*/
|
|
32
32
|
eo2jsw = function(command, args) {
|
|
33
33
|
const lib = path.resolve(__dirname, '../node_modules/eo2js/src'),
|
|
34
34
|
bin = path.resolve(lib, 'eo2js.js');
|
package/src/eoc.js
CHANGED
|
@@ -5,63 +5,79 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const tinted = require('./tinted-console');
|
|
8
|
-
const {program} = require('commander')
|
|
8
|
+
const {program} = require('commander');
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
11
|
* Target language option.
|
|
12
12
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const language = {
|
|
14
|
+
java: 'Java',
|
|
15
|
+
js: 'JavaScript',
|
|
16
|
+
};
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
19
|
* Platform dependent commands.
|
|
20
20
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
},
|
|
49
|
-
[language.js]: {
|
|
50
|
-
...common,
|
|
51
|
-
...{
|
|
52
|
-
resolve: require('./commands/js/resolve'),
|
|
53
|
-
transpile: require('./commands/js/transpile'),
|
|
54
|
-
link: require('./commands/js/link'),
|
|
55
|
-
compile: require('./commands/js/compile'),
|
|
56
|
-
dataize: require('./commands/js/dataize'),
|
|
57
|
-
test: require('./commands/js/test'),
|
|
58
|
-
}
|
|
21
|
+
const common = {
|
|
22
|
+
assemble: require('./commands/assemble'),
|
|
23
|
+
audit: require('./commands/audit'),
|
|
24
|
+
clean: require('./commands/clean'),
|
|
25
|
+
foreign: require('./commands/foreign'),
|
|
26
|
+
parse: require('./commands/parse'),
|
|
27
|
+
print: require('./commands/print'),
|
|
28
|
+
register: require('./commands/register'),
|
|
29
|
+
lint: require('./commands/lint'),
|
|
30
|
+
docs: require('./commands/docs'),
|
|
31
|
+
generate_comments: require('./commands/generate_comments'),
|
|
32
|
+
jeo_disassemble: require('./commands/jeo/disassemble'),
|
|
33
|
+
jeo_assemble: require('./commands/jeo/assemble'),
|
|
34
|
+
latex: require('./commands/latex'),
|
|
35
|
+
normalize: require('./commands/normalize'),
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const commands = {
|
|
39
|
+
[language.java]: {
|
|
40
|
+
...common,
|
|
41
|
+
...{
|
|
42
|
+
resolve: require('./commands/java/resolve'),
|
|
43
|
+
transpile: require('./commands/java/transpile'),
|
|
44
|
+
link: require('./commands/java/link'),
|
|
45
|
+
compile: require('./commands/java/compile'),
|
|
46
|
+
dataize: require('./commands/java/dataize'),
|
|
47
|
+
test: require('./commands/java/test'),
|
|
59
48
|
}
|
|
60
49
|
},
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
50
|
+
[language.js]: {
|
|
51
|
+
...common,
|
|
52
|
+
...{
|
|
53
|
+
resolve: require('./commands/js/resolve'),
|
|
54
|
+
transpile: require('./commands/js/transpile'),
|
|
55
|
+
link: require('./commands/js/link'),
|
|
56
|
+
compile: require('./commands/js/compile'),
|
|
57
|
+
dataize: require('./commands/js/dataize'),
|
|
58
|
+
test: require('./commands/js/test'),
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const pipelines = {
|
|
64
|
+
[language.java]: require('./commands/java/pipeline'),
|
|
65
|
+
[language.js]: require('./commands/js/pipeline'),
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Every language name a user may type, mapped (in lower case) to its
|
|
70
|
+
* canonical platform key. Derived from `language` so the accepted names
|
|
71
|
+
* and the platforms can never drift apart. For each `[alias, canonical]`
|
|
72
|
+
* pair we accept the short alias (e.g. `js`) and the canonical name
|
|
73
|
+
* lower-cased (e.g. `javascript`); `select()` lower-cases the input, so
|
|
74
|
+
* mixed-case spellings such as `JavaScript` are matched too.
|
|
75
|
+
*/
|
|
76
|
+
const platforms = {};
|
|
77
|
+
for (const [alias, canonical] of Object.entries(language)) {
|
|
78
|
+
platforms[alias] = canonical;
|
|
79
|
+
platforms[canonical.toLowerCase()] = canonical;
|
|
80
|
+
}
|
|
65
81
|
|
|
66
82
|
if (process.argv.includes('--verbose')) {
|
|
67
83
|
tinted.enable('debug');
|
|
@@ -103,7 +119,7 @@ program
|
|
|
103
119
|
.option('--parser <version>', 'Set the version of EO parser to use', parser)
|
|
104
120
|
.option('--latest', 'Use the latest parser version from Maven Central')
|
|
105
121
|
.option('--alone', 'Just run a single command without dependencies')
|
|
106
|
-
.option('-l, --language <name>', 'Language of target execution platform', language.java)
|
|
122
|
+
.option('-l, --language <name>', 'Language of target execution platform (Java or JavaScript, case-insensitive)', language.java)
|
|
107
123
|
.option('-b, --batch', 'Run in batch mode, suppress interactive messages')
|
|
108
124
|
.option('--no-color', 'Disable colorization of console messages')
|
|
109
125
|
.option('--track-transformation-steps', 'Save intermediate XMIR files')
|
|
@@ -234,6 +250,7 @@ program.command('compile')
|
|
|
234
250
|
program.command('link')
|
|
235
251
|
.description('Link together all binaries into a single executable binary')
|
|
236
252
|
.action(async (str, opts) => {
|
|
253
|
+
pin(program.opts());
|
|
237
254
|
clear(str);
|
|
238
255
|
if (program.opts().alone === undefined) {
|
|
239
256
|
await pipe()(coms(), ['register', 'assemble', 'lint', 'resolve', 'transpile', 'compile', 'link'], program.opts());
|
|
@@ -265,6 +282,7 @@ program.command('test')
|
|
|
265
282
|
.description('Run all visible unit tests')
|
|
266
283
|
.option('--stack <size>', 'Set stack size for the virtual machine', '64M')
|
|
267
284
|
.option('--heap <size>', 'Set the heap size for the VM', '256M')
|
|
285
|
+
.option('--object <name>', 'Run a single test object by its full EO name, e.g. foo.app.works-fine')
|
|
268
286
|
.action(async (str, opts) => {
|
|
269
287
|
pin(program.opts());
|
|
270
288
|
clear(str);
|
|
@@ -340,6 +358,7 @@ program.command('jeo:assemble')
|
|
|
340
358
|
'classes'
|
|
341
359
|
)
|
|
342
360
|
.action((str, opts) => {
|
|
361
|
+
pin(program.opts());
|
|
343
362
|
coms().jeo_assemble({...program.opts(), ...str});
|
|
344
363
|
});
|
|
345
364
|
|
|
@@ -369,17 +388,18 @@ program.command('fmt')
|
|
|
369
388
|
await pipe()(coms(), ['register', 'parse'], program.opts());
|
|
370
389
|
await coms().print({
|
|
371
390
|
printInput: '1-parse',
|
|
372
|
-
printOutput: program.opts().sources,
|
|
391
|
+
printOutput: path.resolve(program.opts().sources),
|
|
373
392
|
...program.opts()
|
|
374
393
|
});
|
|
375
394
|
});
|
|
376
395
|
|
|
377
|
-
|
|
378
|
-
program.
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
396
|
+
if (require.main === module) {
|
|
397
|
+
program.parseAsync(process.argv);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
module.exports.commandsDescription = function commandsDescription() {
|
|
401
|
+
return program.commands
|
|
402
|
+
.map(c => [c.name(),c.description()]);
|
|
383
403
|
}
|
|
384
404
|
|
|
385
405
|
/**
|
|
@@ -408,12 +428,7 @@ function pin(opts) {
|
|
|
408
428
|
* @return {Object} - commands
|
|
409
429
|
*/
|
|
410
430
|
function coms() {
|
|
411
|
-
|
|
412
|
-
hash = commands[lang];
|
|
413
|
-
if (hash === undefined) {
|
|
414
|
-
throw new Error(`Unknown platform ${lang}`);
|
|
415
|
-
}
|
|
416
|
-
return hash;
|
|
431
|
+
return select(commands, program.opts().language);
|
|
417
432
|
}
|
|
418
433
|
|
|
419
434
|
/**
|
|
@@ -421,10 +436,24 @@ function coms() {
|
|
|
421
436
|
* @return {Function} - pipeline function
|
|
422
437
|
*/
|
|
423
438
|
function pipe() {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
439
|
+
return select(pipelines, program.opts().language);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Resolve the entry registered for the requested language, matching the
|
|
444
|
+
* name case-insensitively and accepting aliases (e.g. `js`, `java`). The
|
|
445
|
+
* lookup and its validation live here, so callers never repeat the
|
|
446
|
+
* "unknown platform" check.
|
|
447
|
+
*
|
|
448
|
+
* @param {Object} registry - Map keyed by canonical platform name
|
|
449
|
+
* @param {String} lang - Language name as provided on the command line
|
|
450
|
+
* @return {*} The entry registered for the resolved platform
|
|
451
|
+
* @throws {Error} If the language does not resolve to a known platform
|
|
452
|
+
*/
|
|
453
|
+
function select(registry, lang) {
|
|
454
|
+
const found = registry[platforms[String(lang).toLowerCase()]];
|
|
455
|
+
if (found === undefined) {
|
|
427
456
|
throw new Error(`Unknown platform ${lang}`);
|
|
428
457
|
}
|
|
429
|
-
return
|
|
458
|
+
return found;
|
|
430
459
|
}
|
package/src/jdk.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-FileCopyrightText: Copyright (c) 2022-2026 Objectionary.com
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const {execSync} = require('child_process');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Default executor used when no override is supplied. Runs the command
|
|
10
|
+
* synchronously, captures its output, and returns it as a Buffer.
|
|
11
|
+
* Stderr is captured (javac prints its version to stderr) so we can
|
|
12
|
+
* surface it back if anything goes wrong.
|
|
13
|
+
*
|
|
14
|
+
* @param {String} cmd - The command to execute.
|
|
15
|
+
* @return {Buffer} The combined stdout/stderr output.
|
|
16
|
+
*/
|
|
17
|
+
function defaultExec(cmd) {
|
|
18
|
+
return execSync(cmd, {stdio: ['ignore', 'pipe', 'pipe']});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Build the user-facing error message that we want to print when
|
|
23
|
+
* `javac` cannot be located or executed. The message lists the
|
|
24
|
+
* common ways to install a full JDK on each platform, since the
|
|
25
|
+
* most common cause of this error is that the user has installed
|
|
26
|
+
* a JRE (or none at all) instead of a JDK.
|
|
27
|
+
*
|
|
28
|
+
* @param {Error} cause - The underlying error from the exec attempt.
|
|
29
|
+
* @return {String} The user-facing diagnostic.
|
|
30
|
+
*/
|
|
31
|
+
function missingJavacMessage(cause) {
|
|
32
|
+
const lines = [
|
|
33
|
+
'`javac` was not found on your PATH.',
|
|
34
|
+
'EO needs a full JDK (not just a JRE) to compile Java sources.',
|
|
35
|
+
'Please install OpenJDK 11 or newer and make sure `javac` is on your PATH.',
|
|
36
|
+
' Debian/Ubuntu: sudo apt-get install openjdk-21-jdk',
|
|
37
|
+
' macOS: brew install --cask temurin',
|
|
38
|
+
' Windows: https://adoptium.net/'
|
|
39
|
+
];
|
|
40
|
+
if (cause && cause.message) {
|
|
41
|
+
lines.push(`Underlying error: ${cause.message.toString().trim()}`);
|
|
42
|
+
}
|
|
43
|
+
return lines.join('\n');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Verify that `javac` is available on the current PATH. Throws an
|
|
48
|
+
* Error with a clear, actionable message when it is not, and is a
|
|
49
|
+
* no-op otherwise. The actual command runner is injectable so that
|
|
50
|
+
* tests can stub it out without spawning a real subprocess.
|
|
51
|
+
*
|
|
52
|
+
* @param {Function} [exec] - Optional command runner (mainly for tests).
|
|
53
|
+
* Should accept a single string command and
|
|
54
|
+
* either return the captured output or throw
|
|
55
|
+
* on non-zero exit.
|
|
56
|
+
* @return {void}
|
|
57
|
+
*/
|
|
58
|
+
module.exports.verifyJavac = function(exec) {
|
|
59
|
+
const run = exec || defaultExec;
|
|
60
|
+
try {
|
|
61
|
+
run('javac -version');
|
|
62
|
+
} catch (cause) {
|
|
63
|
+
throw new Error(missingJavacMessage(cause), {cause});
|
|
64
|
+
}
|
|
65
|
+
};
|
package/src/mvnw.js
CHANGED
|
@@ -11,6 +11,17 @@ const {spawn} = require('child_process');
|
|
|
11
11
|
const colors = require('colors');
|
|
12
12
|
const parserVersion = require('./parser-version');
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Short label for the Maven goals being executed, collapsing a list
|
|
16
|
+
* into a count and leaving a lone goal under its own name.
|
|
17
|
+
* @param {Array} args The arguments passed to Maven
|
|
18
|
+
* @return {String} Either the single goal or a count like "5 steps"
|
|
19
|
+
*/
|
|
20
|
+
module.exports.summary = function(args) {
|
|
21
|
+
const steps = args.filter((a) => !a.startsWith('-'));
|
|
22
|
+
return steps.length > 1 ? `${steps.length} steps` : steps.join('');
|
|
23
|
+
};
|
|
24
|
+
|
|
14
25
|
/**
|
|
15
26
|
* The shell to use (depending on operating system).
|
|
16
27
|
* @return {String} Path to shell or "undefined" if default one should be used
|
|
@@ -42,7 +53,7 @@ module.exports.flags = function(opts) {
|
|
|
42
53
|
console.debug('Sources in %s', rel(sources));
|
|
43
54
|
const target = path.resolve(opts.target);
|
|
44
55
|
console.debug('Target in %s', rel(target));
|
|
45
|
-
if (opts.parser && !parserVersion.exists(opts.parser)) {
|
|
56
|
+
if (opts.parser && !opts.parser.endsWith('-SNAPSHOT') && !parserVersion.exists(opts.parser)) {
|
|
46
57
|
console.error(colors.red(
|
|
47
58
|
`Parser version ${opts.parser} is not available in Maven Central.\n` +
|
|
48
59
|
`Please check available versions at: https://repo.maven.apache.org/maven2/org/eolang/eo-maven-plugin/\n` +
|
|
@@ -65,6 +76,8 @@ module.exports.flags = function(opts) {
|
|
|
65
76
|
`-Deo.placedFormat=csv`,
|
|
66
77
|
`-Deo.skipLinting=${opts.blind ? 'true' : 'false'}`,
|
|
67
78
|
opts.trackTransformationSteps ? '-Deo.trackTransformationSteps' : '',
|
|
79
|
+
'-Dorg.slf4j.simpleLogger.showDateTime=true',
|
|
80
|
+
'-Dorg.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss',
|
|
68
81
|
].filter(flag => flag !== '');
|
|
69
82
|
};
|
|
70
83
|
|
|
@@ -79,7 +92,7 @@ module.exports.mvnw = function(args, tgt, batch) {
|
|
|
79
92
|
return new Promise((resolve, reject) => {
|
|
80
93
|
console.debug(`Running mvnw with arguments: ${args.join(' ')}`);
|
|
81
94
|
target = tgt;
|
|
82
|
-
phase =
|
|
95
|
+
phase = module.exports.summary(args);
|
|
83
96
|
const home = path.resolve(__dirname, '../mvnw');
|
|
84
97
|
let bin = path.resolve(home, 'mvnw') + (process.platform === 'win32' ? '.cmd' : '');
|
|
85
98
|
if (!fs.existsSync(bin)) {
|
|
@@ -108,20 +121,20 @@ module.exports.mvnw = function(args, tgt, batch) {
|
|
|
108
121
|
start();
|
|
109
122
|
}
|
|
110
123
|
result.on('close', (code) => {
|
|
111
|
-
if (code !== 0) {
|
|
112
|
-
console.error(`The command "${cmd}" exited with #${code} code`);
|
|
113
|
-
process.exit(1);
|
|
114
|
-
}
|
|
115
124
|
if (!batch) {
|
|
116
125
|
stop();
|
|
117
126
|
}
|
|
127
|
+
if (code !== 0) {
|
|
128
|
+
reject(new Error(`The command "${cmd}" exited with #${code} code`));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
118
131
|
resolve(args);
|
|
119
132
|
});
|
|
120
133
|
} else {
|
|
121
134
|
result.on('close', (code) => {
|
|
122
135
|
if (code !== 0) {
|
|
123
|
-
|
|
124
|
-
|
|
136
|
+
reject(new Error(`The command "${cmd}" exited with #${code} code`));
|
|
137
|
+
return;
|
|
125
138
|
}
|
|
126
139
|
resolve(args);
|
|
127
140
|
});
|
|
@@ -200,7 +213,7 @@ function print() {
|
|
|
200
213
|
} else if (duration < 60 * 1000) {
|
|
201
214
|
elapsed = `${Math.ceil(duration / 1000)}s`;
|
|
202
215
|
} else {
|
|
203
|
-
elapsed = `${Math.ceil(duration /
|
|
216
|
+
elapsed = `${Math.ceil(duration / (60 * 1000))}min`;
|
|
204
217
|
}
|
|
205
218
|
process.stdout.write(
|
|
206
219
|
colors.yellow(`[${phase}] ${elapsed}; ${count(target, 0)} files generated so far...`)
|
package/src/parser-version.js
CHANGED
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
const {XMLParser} = require('fast-xml-parser');
|
|
7
|
+
const colors = require('colors');
|
|
7
8
|
const request = require('sync-request'),
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
* Load the latest version from GitHub releases.
|
|
12
|
+
* @return {String} Latest version, for example '0.23.1'
|
|
13
|
+
*/
|
|
13
14
|
version = module.exports = {
|
|
14
15
|
value: '',
|
|
15
16
|
get() {
|
|
@@ -26,23 +27,33 @@ const request = require('sync-request'),
|
|
|
26
27
|
}
|
|
27
28
|
return version.value;
|
|
28
29
|
},
|
|
30
|
+
/**
|
|
31
|
+
* Build the Maven Central URL of a parser version POM.
|
|
32
|
+
* @param {String} ver - Version to locate, for example '0.23.1'
|
|
33
|
+
* @return {String} Full URL of the eo-maven-plugin POM
|
|
34
|
+
*/
|
|
35
|
+
url(ver) {
|
|
36
|
+
const repo = 'org/eolang/eo-maven-plugin',
|
|
37
|
+
artifactId = 'eo-maven-plugin';
|
|
38
|
+
return `https://repo.maven.apache.org/maven2/${repo}/${ver}/${artifactId}-${ver}.pom`;
|
|
39
|
+
},
|
|
29
40
|
/**
|
|
30
41
|
* Check if a specific parser version exists in Maven Central.
|
|
31
42
|
* @param {String} ver - Version to check, for example '0.23.1'
|
|
32
|
-
* @
|
|
43
|
+
* @param {function} fetch - HTTP call, defaults to sync-request
|
|
44
|
+
* @return {Boolean} True if version exists or cannot be verified, false if confirmed absent
|
|
33
45
|
*/
|
|
34
|
-
exists(ver) {
|
|
46
|
+
exists(ver, fetch = request) {
|
|
35
47
|
let result;
|
|
36
48
|
if (ver && ver !== 'undefined') {
|
|
37
49
|
try {
|
|
38
|
-
const
|
|
39
|
-
artifactId = 'eo-maven-plugin',
|
|
40
|
-
url = `https://repo.maven.apache.org/maven2/${repo}/${ver}/${artifactId}-${ver}.pom`,
|
|
41
|
-
res = request('GET', url, {timeout: 10000, socketTimeout: 10000});
|
|
50
|
+
const res = fetch('GET', version.url(ver), {timeout: 10000, socketTimeout: 10000});
|
|
42
51
|
result = res.statusCode === 200;
|
|
43
52
|
} catch (e) {
|
|
44
|
-
console.
|
|
45
|
-
|
|
53
|
+
console.warn(colors.yellow(
|
|
54
|
+
`Cannot verify parser version ${ver} in Maven Central (${e.message}), proceeding anyway`
|
|
55
|
+
));
|
|
56
|
+
result = true;
|
|
46
57
|
}
|
|
47
58
|
} else {
|
|
48
59
|
result = false;
|
package/src/version.js
CHANGED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
diff --git a/node_modules/grunt-mocha-cli/lib/index.js b/node_modules/grunt-mocha-cli/lib/index.js
|
|
4
|
-
index 59f7a07..4cc7182 100644
|
|
5
|
-
--- a/node_modules/grunt-mocha-cli/lib/index.js
|
|
6
|
-
+++ b/node_modules/grunt-mocha-cli/lib/index.js
|
|
7
|
-
@@ -2,6 +2,7 @@
|
|
8
|
-
const fs = require('fs')
|
|
9
|
-
const path = require('path')
|
|
10
|
-
const grunt = require('grunt')
|
|
11
|
-
+const os = require('os')
|
|
12
|
-
|
|
13
|
-
const BOOL_OPTIONS = [
|
|
14
|
-
'allow-uncaught',
|
|
15
|
-
@@ -55,6 +56,10 @@ module.exports = function(options) {
|
|
16
|
-
spawnOptions.cmd = path.dirname(spawnOptions.cmd)
|
|
17
|
-
spawnOptions.cmd += '/../.bin/mocha'
|
|
18
|
-
|
|
19
|
-
+ if (os.platform() === 'win32') {
|
|
20
|
-
+ spawnOptions.opts.shell = true
|
|
21
|
-
+ }
|
|
22
|
-
+
|
|
23
|
-
if (process.platform === 'win32') {
|
|
24
|
-
spawnOptions.cmd += '.cmd'
|
|
25
|
-
}
|
package/scripts/postinstall.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/*
|
|
4
|
-
* SPDX-FileCopyrightText: Copyright (c) 2022-2026 Objectionary.com
|
|
5
|
-
* SPDX-License-Identifier: MIT
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Conditional postinstall script that only runs patch-package in development.
|
|
10
|
-
* This prevents patch-package from running during production installs where
|
|
11
|
-
* devDependencies (like grunt-mocha-cli) are not available.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
const fs = require('fs');
|
|
15
|
-
const path = require('path');
|
|
16
|
-
const { spawn } = require('child_process');
|
|
17
|
-
|
|
18
|
-
const gruntMochaCli = path.join(__dirname, '..', 'node_modules', 'grunt-mocha-cli');
|
|
19
|
-
|
|
20
|
-
function findPatchPackage() {
|
|
21
|
-
const binDir = path.join(__dirname, '..', 'node_modules', '.bin');
|
|
22
|
-
if (process.platform === 'win32') {
|
|
23
|
-
const cmdFile = path.join(binDir, 'patch-package.cmd');
|
|
24
|
-
if (fs.existsSync(cmdFile)) {
|
|
25
|
-
return cmdFile;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
const binFile = path.join(binDir, 'patch-package');
|
|
29
|
-
if (fs.existsSync(binFile)) {
|
|
30
|
-
return binFile;
|
|
31
|
-
}
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const patchPackageBin = findPatchPackage();
|
|
36
|
-
|
|
37
|
-
if (fs.existsSync(gruntMochaCli) && patchPackageBin) {
|
|
38
|
-
console.log('Development environment detected, running patch-package...');
|
|
39
|
-
const spawnOptions = {
|
|
40
|
-
stdio: 'inherit',
|
|
41
|
-
shell: process.platform === 'win32'
|
|
42
|
-
};
|
|
43
|
-
const child = spawn(patchPackageBin, [], spawnOptions);
|
|
44
|
-
child.on('exit', (code) => {
|
|
45
|
-
process.exit(code);
|
|
46
|
-
});
|
|
47
|
-
child.on('error', (err) => {
|
|
48
|
-
console.error('Failed to execute patch-package:', err);
|
|
49
|
-
process.exit(1);
|
|
50
|
-
});
|
|
51
|
-
} else {
|
|
52
|
-
console.log('Production environment detected, skipping patch-package.');
|
|
53
|
-
}
|