eolang 0.33.0 → 0.33.2

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 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.32.1.tar.gz"
11
- version "0.32.1"
12
- sha256 "6770b4eb3068b5675e2f8c1cce580693f2ad844c6f9472fd2e236f81ba356ab2"
10
+ url "https://github.com/objectionary/eoc/archive/refs/tags/0.33.1.tar.gz"
11
+ version "0.33.1"
12
+ sha256 "ba76c6b5e63db422777583bcf09020683ebfbe59b28bc949df5e178c1756a1f4"
13
13
  license "MIT"
14
14
 
15
15
  depends_on "node"
@@ -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.32.1.tar.gz"
10
+ url "https://github.com/objectionary/eoc/archive/refs/tags/0.33.1.tar.gz"
11
11
  version "0.32.0"
12
- sha256 "6770b4eb3068b5675e2f8c1cce580693f2ad844c6f9472fd2e236f81ba356ab2"
12
+ sha256 "ba76c6b5e63db422777583bcf09020683ebfbe59b28bc949df5e178c1756a1f4"
13
13
  license "MIT"
14
14
 
15
15
  depends_on "node"
@@ -0,0 +1,25 @@
1
+ #
2
+ # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Objectionary.com
3
+ # SPDX-License-Identifier: MIT
4
+ #
5
+
6
+ require "language/node"
7
+ class Eolang < 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.33.1.tar.gz"
11
+ version "0.32.1"
12
+ sha256 "ba76c6b5e63db422777583bcf09020683ebfbe59b28bc949df5e178c1756a1f4"
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-2025 Objectionary.com
3
+ # SPDX-License-Identifier: MIT
4
+ #
5
+
6
+ require "language/node"
7
+ class Eolang < 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.33.1.tar.gz"
11
+ version "0.33.0"
12
+ sha256 "ba76c6b5e63db422777583bcf09020683ebfbe59b28bc949df5e178c1756a1f4"
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
@@ -18,14 +18,14 @@ First, you install [npm][npm-install] and [Java SE][java-se].
18
18
  Then, you install [eolang][npm] package, using [npm][npm-install]:
19
19
 
20
20
  ```bash
21
- npm install -g eolang@0.32.1
21
+ npm install -g eolang@0.33.1
22
22
  ```
23
23
 
24
24
  You can also use [Homebrew] (on macOS):
25
25
 
26
26
  ```bash
27
27
  brew tap objectionary/eoc https://github.com/objectionary/eoc
28
- brew install objectionary/eoc/eolang@0.32.1
28
+ brew install objectionary/eoc/eolang@0.33.1
29
29
  ```
30
30
 
31
31
  Then, you write a simple [EO](https://www.eolang.org) program in `hello.eo` file
package/eslint.config.js CHANGED
@@ -60,16 +60,7 @@ module.exports = [
60
60
  'require-unicode-regexp': 'off',
61
61
  'sort-keys': 'off',
62
62
  'sort-vars': 'off',
63
- "promise/prefer-await-to-then": "off"
63
+ "promise/prefer-await-to-then": "error"
64
64
  }
65
65
  },
66
- {
67
- files: [
68
- 'src/commands/js/transpile.js',
69
- 'src/commands/js/link.js',
70
- ],
71
- rules: {
72
- 'promise/prefer-await-to-then': 'warn',
73
- },
74
- }
75
66
  ];
@@ -121,6 +121,6 @@
121
121
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
122
122
  <heap-size>undefined</heap-size>
123
123
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
124
- <jeo.version>0.14.0</jeo.version>
124
+ <jeo.version>0.14.12</jeo.version>
125
125
  </properties>
126
126
  </project>
package/mvnw/mvnw CHANGED
@@ -23,7 +23,7 @@
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
25
  # ----------------------------------------------------------------------------
26
- # Apache Maven Wrapper startup batch script, version 3.3.0
26
+ # Apache Maven Wrapper startup batch script, version 3.3.4
27
27
  #
28
28
  # Optional ENV vars
29
29
  # -----------------
package/mvnw/mvnw.cmd CHANGED
@@ -23,7 +23,7 @@
23
23
  @REM ----------------------------------------------------------------------------
24
24
 
25
25
  @REM ----------------------------------------------------------------------------
26
- @REM Apache Maven Wrapper startup batch script, version 3.3.0
26
+ @REM Apache Maven Wrapper startup batch script, version 3.3.4
27
27
  @REM
28
28
  @REM Optional ENV vars
29
29
  @REM MVNW_REPOURL - repo url base for downloading maven distribution
package/mvnw/pom.xml CHANGED
@@ -10,7 +10,7 @@
10
10
  <version>0.0.0</version>
11
11
  <packaging>jar</packaging>
12
12
  <properties>
13
- <jeo.version>0.14.0</jeo.version>
13
+ <jeo.version>0.14.12</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>
@@ -26,13 +26,13 @@
26
26
  <dependency>
27
27
  <groupId>org.junit.jupiter</groupId>
28
28
  <artifactId>junit-jupiter-api</artifactId>
29
- <version>5.13.4</version>
29
+ <version>6.0.0</version>
30
30
  <scope>compile</scope>
31
31
  </dependency>
32
32
  <dependency>
33
33
  <groupId>org.junit.jupiter</groupId>
34
34
  <artifactId>junit-jupiter-engine</artifactId>
35
- <version>5.13.4</version>
35
+ <version>6.0.0</version>
36
36
  <scope>compile</scope>
37
37
  </dependency>
38
38
  </dependencies>
package/package.json CHANGED
@@ -24,9 +24,9 @@
24
24
  "eslint-plugin-promise": "^7.2.1",
25
25
  "grunt": "^1.6.1",
26
26
  "grunt-contrib-clean": "^2.0.1",
27
- "grunt-eslint": "^25.0.0",
27
+ "grunt-eslint": "^26.0.0",
28
28
  "grunt-mocha-cli": "^7.0.0",
29
- "mocha": "^11.7.2",
29
+ "mocha": "^11.7.4",
30
30
  "patch-package": "^8.0.0"
31
31
  },
32
32
  "engines": {
@@ -57,5 +57,5 @@
57
57
  "postinstall": "node scripts/postinstall.js",
58
58
  "test": "mocha --timeout 1200000"
59
59
  },
60
- "version": "0.33.0"
60
+ "version": "0.33.2"
61
61
  }
@@ -15,8 +15,9 @@ const {elapsed} = require('../elapsed');
15
15
  */
16
16
  module.exports = function(opts) {
17
17
  const target = path.resolve(opts.target);
18
- return elapsed((tracked) => mvnw(['eo:assemble'].concat(flags(opts)), opts.target, opts.batch).then((r) => {
18
+ return elapsed(async (tracked) => {
19
+ const r = await mvnw(['eo:assemble'].concat(flags(opts)), opts.target, opts.batch);
19
20
  tracked.print(`EO program assembled in ${rel(target)}`);
20
21
  return r;
21
- }));
22
+ });
22
23
  };
@@ -5,6 +5,7 @@
5
5
 
6
6
  const fs = require('fs');
7
7
  const path = require('path');
8
+ const SaxonJS = require('saxon-js');
8
9
 
9
10
  /**
10
11
  * Recursively reads all .xmir files from a directory.
@@ -25,27 +26,127 @@ function readXmirsRecursively(dir) {
25
26
  return files;
26
27
  }
27
28
 
29
+ /**
30
+ * Applies XSLT to XMIR
31
+ * @param {String} xmir - Text of XMIR file
32
+ * @param {String} xsl - Text of XSL file
33
+ * @return {String} HTML document
34
+ */
35
+ function transformDocument(xmir, xsl) {
36
+ const html = SaxonJS.XPath.evaluate(
37
+ `transform(
38
+ map {
39
+ 'source-node' : parse-xml($xml),
40
+ 'stylesheet-text' : $xslt,
41
+ 'delivery-format' : 'serialized'
42
+ }
43
+ )?output`,
44
+ null,
45
+ {
46
+ params : {
47
+ 'xml' : xmir,
48
+ 'xslt' : xsl
49
+ }
50
+ }
51
+ );
52
+ return html;
53
+ }
54
+
55
+ /**
56
+ * Creates documentation block from given XMIR
57
+ * @param {String} xmir_path - path of XMIR
58
+ * @return {String} HTML block
59
+ */
60
+ function createXmirHtmlBlock(xmir_path) {
61
+ try {
62
+ const xmir = fs.readFileSync(xmir_path).toString();
63
+ const xsl = fs.readFileSync(path.join(__dirname, '..', 'resources', 'xmir-transformer.xsl')).toString();
64
+ return transformDocument(xmir, xsl);
65
+ } catch(error) {
66
+ throw new Error(`Error while applying XSL to XMIR: ${error.message}`, error);
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Generates Package HTML
72
+ * @param {String} name - Package name
73
+ * @param {String[]} xmir_htmls - Array of xmirs htmls
74
+ * @param {String} css_path - CSS file path
75
+ * @return {String} HTML of the package
76
+ */
77
+ function generatePackageHtml(name, xmir_htmls, css_path) {
78
+ const title = `<h1 class="package-title">Package ${name} documentation</h1>`;
79
+ return `<!DOCTYPE html>
80
+ <html>
81
+ <head>
82
+ <link href="${css_path}" rel="stylesheet" type="text/css">
83
+ ${title}
84
+ </head>
85
+ <body>
86
+ ${xmir_htmls.join('\n')}
87
+ </body>
88
+ </html>`;
89
+ }
90
+
91
+ /**
92
+ * Wraps given html body
93
+ * @param {String} html - HTML body
94
+ * @param {String} css_path - CSS file path
95
+ * @return {String} Ready HTML
96
+ */
97
+ function wrapHtml(html, css_path) {
98
+ return `
99
+ <!DOCTYPE html>
100
+ <html>
101
+ <head>
102
+ <link href="${css_path}" rel="stylesheet" type="text/css">
103
+ </head>
104
+ <body>
105
+ ${html}
106
+ </body>
107
+ </html>
108
+ `;
109
+ }
110
+
28
111
  /**
29
112
  * Command to generate documentation.
30
113
  * @param {Hash} opts - All options
31
114
  */
32
- module.exports = function(opts) {
115
+ module.exports = async function(opts) {
33
116
  try {
34
- const input = path.resolve(opts.target, '.eoc', '1-parse');
117
+ const input = path.resolve(opts.target, '1-parse');
35
118
  const output = path.resolve(opts.target, 'docs');
36
119
  fs.mkdirSync(output, {recursive: true});
120
+ const css = path.join(output, 'styles.css');
121
+ fs.writeFileSync(css, '');
122
+ const packages_info = {};
123
+ const all_xmir_htmls = [];
37
124
  const xmirs = readXmirsRecursively(input);
38
125
  for (const xmir of xmirs) {
39
126
  const relative = path.relative(input, xmir);
127
+ const name = path.parse(xmir).name;
128
+ const xmir_html = createXmirHtmlBlock(xmir);
129
+ const html_app = path.join(output, path.dirname(relative),`${name}.html`);
130
+ fs.mkdirSync(path.dirname(html_app), {recursive: true});
131
+ fs.writeFileSync(html_app, wrapHtml(xmir_html, css));
40
132
  const packages = path.dirname(relative).split(path.sep).join('.');
41
- const html = path.join(output, `package_${packages}.html`);
42
- fs.mkdirSync(path.dirname(html), {recursive: true});
43
- fs.writeFileSync(html, '');
133
+ const html_package = path.join(output, `package_${packages}.html`);
134
+ if (!(packages in packages_info)) {
135
+ packages_info[packages] = {
136
+ xmir_htmls : [],
137
+ path: html_package
138
+ };
139
+ }
140
+ packages_info[packages].xmir_htmls.push(xmir_html);
141
+ all_xmir_htmls.push(xmir_html);
142
+ }
143
+ for (const package_name of Object.keys(packages_info)) {
144
+ fs.mkdirSync(path.dirname(packages_info[package_name].path), {recursive: true});
145
+ fs.writeFileSync(packages_info[package_name].path,
146
+ generatePackageHtml(package_name, packages_info[package_name].xmir_htmls, css));
44
147
  }
45
148
  const packages = path.join(output, 'packages.html');
46
- fs.writeFileSync(packages, '');
47
- const css = path.join(output, 'styles.css');
48
- fs.writeFileSync(css, '');
149
+ fs.writeFileSync(packages, generatePackageHtml('', all_xmir_htmls, css));
49
150
  console.info('Documentation generation completed in the %s directory', output);
50
151
  } catch (error) {
51
152
  console.error('Error generating documentation:', error);
@@ -12,14 +12,13 @@ const path = require('path');
12
12
  * @param {Object} opts - All options
13
13
  * @return {Promise} of compile task
14
14
  */
15
- module.exports = function(opts) {
15
+ module.exports = async function(opts) {
16
16
  const target = path.resolve(opts.target);
17
17
  /**
18
18
  * @todo #368:30min Wrap logs in 'elapsed'
19
19
  * It is necessary to use 'elapsed' in all logging cases that require output of elapsed time
20
20
  */
21
- return mvnw(['test-compile'].concat(flags(opts)), opts.target, opts.batch).then((r) => {
22
- console.info('Java .class files compiled in %s', rel(target));
23
- return r;
24
- });
21
+ const r = await mvnw(['test-compile'].concat(flags(opts)), opts.target, opts.batch);
22
+ console.info('Java .class files compiled in %s', rel(target));
23
+ return r;
25
24
  };
@@ -12,10 +12,9 @@ const path = require('path');
12
12
  * @param {Object} opts - All options
13
13
  * @return {Promise} of link task
14
14
  */
15
- module.exports = function(opts) {
15
+ module.exports = async function(opts) {
16
16
  const jar = path.resolve(opts.target, 'eoc.jar');
17
- return mvnw(['jar:jar', 'shade:shade'].concat(flags(opts)), opts.target, opts.batch).then((r) => {
18
- console.info('Executable JAR created at %s', rel(jar));
19
- return r;
20
- });
17
+ const r = await mvnw(['jar:jar', 'shade:shade'].concat(flags(opts)), opts.target, opts.batch);
18
+ console.info('Executable JAR created at %s', rel(jar));
19
+ return r;
21
20
  };
@@ -12,15 +12,12 @@ const path = require('path');
12
12
  * @param {Object} opts - All options
13
13
  * @return {Promise} of resolve task
14
14
  */
15
- module.exports = function(opts) {
16
- return mvnw(['eo:resolve'].concat(flags(opts)), opts.target, opts.batch)
17
- .then((r) => {
18
- const sources = path.resolve(opts.target, 'eo/6-resolve');
19
- console.info('Dependencies resolved in %s', rel(sources));
20
- return mvnw(['eo:place'].concat(flags(opts)), opts.target, opts.batch);
21
- }).then((r) => {
22
- const classes = path.resolve(opts.target, 'classes');
23
- console.info('Dependencies placed in %s', rel(classes));
24
- return r;
25
- });
15
+ module.exports = async function(opts) {
16
+ await mvnw(['eo:resolve'].concat(flags(opts)), opts.target, opts.batch);
17
+ const sources = path.resolve(opts.target, 'eo/6-resolve');
18
+ console.info('Dependencies resolved in %s', rel(sources));
19
+ const r = await mvnw(['eo:place'].concat(flags(opts)), opts.target, opts.batch);
20
+ const classes = path.resolve(opts.target, 'classes');
21
+ console.info('Dependencies placed in %s', rel(classes));
22
+ return r;
26
23
  };
@@ -12,10 +12,9 @@ const path = require('path');
12
12
  * @param {Object} opts - All options
13
13
  * @return {Promise} of transpile task
14
14
  */
15
- module.exports = function(opts) {
15
+ module.exports = async function(opts) {
16
16
  const sources = path.resolve(opts.target, 'generated-sources');
17
- return mvnw(['eo:transpile'].concat(flags(opts)), opts.target, opts.batch).then((r) => {
18
- console.info('Java sources generated in %s', rel(sources));
19
- return r;
20
- });
17
+ const r = await mvnw(['eo:transpile'].concat(flags(opts)), opts.target, opts.batch);
18
+ console.info('Java sources generated in %s', rel(sources));
19
+ return r;
21
20
  };
@@ -12,8 +12,8 @@ const path = require('path');
12
12
  * @param {Object} opts - All options
13
13
  * @return {Promise} of assemble task
14
14
  */
15
- module.exports = function(opts) {
16
- return mvnw(
15
+ module.exports = async function(opts) {
16
+ const r = await mvnw(
17
17
  ['jeo:assemble']
18
18
  .concat(flags(opts))
19
19
  .concat(
@@ -24,11 +24,10 @@ module.exports = function(opts) {
24
24
  ]
25
25
  ),
26
26
  opts.target, opts.batch
27
- ).then((r) => {
28
- console.info(
29
- 'EO .xmir files from %s assembled to .class files in %s',
30
- rel(opts.xmirs), rel(opts.classes)
31
- );
32
- return r;
33
- });
27
+ );
28
+ console.info(
29
+ 'EO .xmir files from %s assembled to .class files in %s',
30
+ rel(opts.xmirs), rel(opts.classes)
31
+ );
32
+ return r;
34
33
  };
@@ -12,8 +12,8 @@ const path = require('path');
12
12
  * @param {Object} opts - All options
13
13
  * @return {Promise} of disassemble task
14
14
  */
15
- module.exports = function(opts) {
16
- return mvnw(
15
+ module.exports = async function(opts) {
16
+ const r = await mvnw(
17
17
  ['jeo:disassemble']
18
18
  .concat(flags(opts))
19
19
  .concat(
@@ -24,11 +24,10 @@ module.exports = function(opts) {
24
24
  ]
25
25
  ),
26
26
  opts.target, opts.batch
27
- ).then((r) => {
28
- console.info(
29
- 'Bytecode .class files from %s disassembled to .xmir files in %s',
30
- rel(opts.classes), rel(opts.xmirs)
31
- );
32
- return r;
33
- });
27
+ );
28
+ console.info(
29
+ 'Bytecode .class files from %s disassembled to .xmir files in %s',
30
+ rel(opts.classes), rel(opts.xmirs)
31
+ );
32
+ return r;
34
33
  };
@@ -13,10 +13,9 @@ const fs = require('fs');
13
13
  * @param {Object} opts - All options
14
14
  * @return {Promise} of latex generation task
15
15
  */
16
- module.exports = function(opts) {
16
+ module.exports = async function(opts) {
17
17
  const latex = path.resolve(opts.target, 'latex');
18
- return mvnw(['eo:latex'].concat(flags(opts)), opts.target, opts.batch).then((r) => {
19
- console.info('LaTeX files generated in %s', rel(latex));
20
- return r;
21
- });
18
+ const r = await mvnw(['eo:latex'].concat(flags(opts)), opts.target, opts.batch);
19
+ console.info('LaTeX files generated in %s', rel(latex));
20
+ return r;
22
21
  };
@@ -13,32 +13,38 @@ const semver = require('semver');
13
13
  * @param {Hash} opts - All options
14
14
  * @return {Promise} of assemble task
15
15
  */
16
- module.exports = function(opts) {
16
+ module.exports = async function(opts) {
17
17
  const extra = [
18
18
  `-Deo.failOnWarning=${opts.easy ? 'false' : 'true'}`,
19
19
  `-Deo.skipLinting=${opts.blind ? 'true' : 'false'}`,
20
20
  ];
21
21
  if (opts.parser.endsWith('-SNAPSHOT') || semver.gte(opts.parser, '0.45.0')) {
22
- return mvnw(
23
- ['eo:lint'].concat(flags(opts)).concat(extra),
24
- opts.target, opts.batch
25
- ).then((r) => {
22
+ try {
23
+ const r = await mvnw(
24
+ ['eo:lint'].concat(flags(opts)).concat(extra),
25
+ opts.target, opts.batch
26
+ );
26
27
  console.info('EO program linted in %s', rel(path.resolve(opts.target)));
27
28
  return r;
28
- }).catch((error) => {
29
+ } catch (error) {
29
30
  throw new Error(
30
- 'There are errors and/or warnings; you may disable warnings via the --easy option'
31
+ 'There are errors and/or warnings; you may disable warnings via the --easy option',
32
+ { cause: error }
31
33
  );
32
- });
34
+ }
33
35
  }
34
- return mvnw(
35
- ['eo:verify'].concat(flags(opts)).concat(extra),
36
- opts.target, opts.batch
37
- ).then((r) => {
36
+ try {
37
+ const r = await mvnw(
38
+ ['eo:verify'].concat(flags(opts)).concat(extra),
39
+ opts.target, opts.batch
40
+ );
38
41
  console.info('EO program verified in %s', rel(path.resolve(opts.target)));
39
42
  return r;
40
- }).catch((error) => {
41
- throw new Error('You may disable warnings via the --easy option');
42
- });
43
+ } catch (error) {
44
+ throw new Error(
45
+ 'You may disable warnings via the --easy option',
46
+ { cause: error }
47
+ );
48
+ }
43
49
 
44
50
  };
@@ -12,10 +12,9 @@ const {mvnw, flags} = require('../mvnw');
12
12
  * @param {Hash} opts - All options
13
13
  * @return {Promise} of assemble task
14
14
  */
15
- module.exports = function(opts) {
15
+ module.exports = async function(opts) {
16
16
  const target = path.resolve(opts.target);
17
- return mvnw(['eo:parse'].concat(flags(opts)), opts.target, opts.batch).then((r) => {
18
- console.info('EO sources parsed in %s', rel(target));
19
- return r;
20
- });
17
+ const r = await mvnw(['eo:parse'].concat(flags(opts)), opts.target, opts.batch);
18
+ console.info('EO sources parsed in %s', rel(target));
19
+ return r;
21
20
  };
@@ -12,12 +12,12 @@ const {mvnw, flags} = require('../mvnw');
12
12
  * @param {Object} opts - All options
13
13
  * @return {Promise} of assemble task
14
14
  */
15
- module.exports = function(opts) {
15
+ module.exports = async function(opts) {
16
16
  const input = path.resolve(opts.target, opts.printInput);
17
17
  console.debug('Reading from %s', rel(input));
18
18
  const output = path.resolve(opts.target, opts.printOutput);
19
19
  console.debug('Writing to %s', rel(output));
20
- return mvnw(
20
+ const r = await mvnw(
21
21
  ['eo:print']
22
22
  .concat(flags(opts))
23
23
  .concat(
@@ -27,8 +27,7 @@ module.exports = function(opts) {
27
27
  ]
28
28
  ),
29
29
  opts.target, opts.batch
30
- ).then((r) => {
31
- console.info('XMIR files converted to EO files at %s', rel(output));
32
- return r;
33
- });
30
+ );
31
+ console.info('XMIR files converted to EO files at %s', rel(output));
32
+ return r;
34
33
  };
@@ -12,10 +12,9 @@ const path = require('path');
12
12
  * @param {Hash} opts - All options
13
13
  * @return {Promise} of register task
14
14
  */
15
- module.exports = function(opts) {
15
+ module.exports = async function(opts) {
16
16
  const foreign = path.resolve(opts.target, 'eo-foreign.json');
17
- return mvnw(['eo:register'].concat(flags(opts)), opts.target, opts.batch).then((r) => {
18
- console.info('EO objects registered in %s', rel(foreign));
19
- return r;
20
- });
17
+ const r = await mvnw(['eo:register'].concat(flags(opts)), opts.target, opts.batch);
18
+ console.info('EO objects registered in %s', rel(foreign));
19
+ return r;
21
20
  };
@@ -12,7 +12,7 @@ const {mvnw, flags} = require('../mvnw');
12
12
  * @param {Hash} opts - All options
13
13
  * @return {Promise} of sodg task
14
14
  */
15
- module.exports = function(opts) {
15
+ module.exports = async function(opts) {
16
16
  const argv = ['eo:sodg'].concat(flags(opts));
17
17
  argv.push(`-Deo.sodgIncludes=${opts.include}`);
18
18
  if (opts.exclude) {
@@ -36,8 +36,7 @@ module.exports = function(opts) {
36
36
  argv.push('-Deo.generateGraphFiles');
37
37
  argv.push('-Deo.generateDotFiles');
38
38
  }
39
- return mvnw(argv, opts.target, opts.batch).then((r) => {
40
- console.info('SODG files generated in %s', rel(path.resolve(opts.target)));
41
- return r;
42
- });
39
+ const r = await mvnw(argv, opts.target, opts.batch);
40
+ console.info('SODG files generated in %s', rel(path.resolve(opts.target)));
41
+ return r;
43
42
  };
package/src/mvnw.js CHANGED
@@ -7,7 +7,7 @@ const path = require('path');
7
7
  const fs = require('fs');
8
8
  const rel = require('relative');
9
9
  const readline = require('readline');
10
- const {spawn} = require('child_process');
10
+ const { spawn } = require('child_process');
11
11
  const colors = require('colors');
12
12
 
13
13
  /**
@@ -30,7 +30,7 @@ let beginning,
30
30
  * @param {Object} opts - Opts provided to the "eoc"
31
31
  * @return {Array} of Maven options
32
32
  */
33
- module.exports.flags = function(opts) {
33
+ module.exports.flags = function (opts) {
34
34
  const sources = path.resolve(opts.sources);
35
35
  console.debug('Sources in %s', rel(sources));
36
36
  const target = path.resolve(opts.target);
@@ -58,20 +58,24 @@ module.exports.flags = function(opts) {
58
58
  * @param {Boolean} [batch] - Is it batch mode (TRUE) or interactive (FALSE)?
59
59
  * @return {Promise} of maven execution task
60
60
  */
61
- module.exports.mvnw = function(args, tgt, batch) {
61
+ module.exports.mvnw = function (args, tgt, batch) {
62
62
  return new Promise((resolve, reject) => {
63
63
  target = tgt;
64
64
  phase = args[0];
65
- const home = path.resolve(__dirname, '../mvnw'),
66
- bin = path.resolve(home, 'mvnw') + (process.platform === 'win32' ? '.cmd' : ''),
67
- params = args.filter((t) => t !== '').concat([
68
- '--batch-mode',
69
- '--color=never',
70
- '--update-snapshots',
71
- '--fail-fast',
72
- '--strict-checksums',
73
- ]),
74
- cmd = `${bin } ${ params.join(' ')}`;
65
+ const home = path.resolve(__dirname, '../mvnw');
66
+ let bin = path.resolve(home, 'mvnw') + (process.platform === 'win32' ? '.cmd' : '');
67
+ if (!fs.existsSync(bin)) {
68
+ console.warn(colors.yellow(`Warning: mvnw not found at ${bin}, falling back to system "mvn"`));
69
+ bin = 'mvn';
70
+ }
71
+ const params = args.filter((t) => t !== '').concat([
72
+ '--batch-mode',
73
+ '--color=never',
74
+ '--update-snapshots',
75
+ '--fail-fast',
76
+ '--strict-checksums',
77
+ ]);
78
+ const cmd = `${bin} ${params.join(' ')}`;
75
79
  console.debug('+ %s', cmd);
76
80
  const result = spawn(
77
81
  bin,
@@ -114,7 +118,7 @@ module.exports.mvnw = function(args, tgt, batch) {
114
118
  function start() {
115
119
  running = true;
116
120
  beginning = Date.now();
117
- const check = function() {
121
+ const check = function () {
118
122
  if (running) {
119
123
  print();
120
124
  setTimeout(check, 1000);
@@ -143,18 +147,36 @@ function print() {
143
147
  * @return {Integer} Total number files.
144
148
  */
145
149
  function count(dir, curr) {
146
- if (fs.existsSync(dir)) {
147
- for (const f of fs.readdirSync(dir)) {
148
- const next = path.join(dir, f);
149
- if (fs.statSync(next).isDirectory()) {
150
- curr = count(next, curr);
151
- } else {
152
- curr++;
153
- }
150
+ if (!fs.existsSync(dir)) {
151
+ return curr;
152
+ }
153
+ try {
154
+ const files = fs.readdirSync(dir);
155
+ for (const f of files) {
156
+ curr = processFile(path.join(dir, f), curr);
157
+ }
158
+ } catch (error) {
159
+ if (error.code === 'ENOENT') {
160
+ return curr;
154
161
  }
162
+ throw error;
155
163
  }
156
164
  return curr;
157
165
  }
166
+ function processFile(filePath, curr) {
167
+ try {
168
+ const stat = fs.statSync(filePath);
169
+ if (stat.isDirectory()) {
170
+ return count(filePath, curr);
171
+ }
172
+ return curr + 1;
173
+ } catch (error) {
174
+ if (error.code === 'ENOENT') {
175
+ return curr;
176
+ }
177
+ throw error;
178
+ }
179
+ }
158
180
  let elapsed;
159
181
  if (duration < 1000) {
160
182
  elapsed = `${duration}ms`;
@@ -0,0 +1,56 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ * SPDX-FileCopyrightText: Copyright (c) 2022-2025 Objectionary.com
4
+ * SPDX-License-Identifier: MIT
5
+ -->
6
+ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
7
+ <xsl:template match="/">
8
+ <div class="app-block">
9
+ <xsl:for-each select="//o[(@name and @name != 'φ') and (not(@base) or (@base != '∅' and @base != 'ξ'))]">
10
+ <xsl:if test="//comments/comment[@line = current()/@line]">
11
+ <div class="object-block">
12
+ <xsl:variable name="fullname">
13
+ <xsl:for-each select="ancestor-or-self::o[@name and @name != 'φ']">
14
+ <xsl:value-of select="@name"/>
15
+ <xsl:choose>
16
+ <xsl:when test="position() != last()">.</xsl:when>
17
+ </xsl:choose>
18
+ </xsl:for-each>
19
+ </xsl:variable>
20
+ <h2 class="object-title"><xsl:value-of select="$fullname"/></h2>
21
+ <p class="object-sign">
22
+ <xsl:value-of select="$fullname"/>(<xsl:for-each select="current()/o[@base and @base = '∅']">
23
+ <xsl:value-of select="@name"/>
24
+ <xsl:choose>
25
+ <xsl:when test="position() != last()">, </xsl:when>
26
+ </xsl:choose>
27
+ </xsl:for-each>)</p>
28
+ <p class="object-desc">
29
+ <xsl:call-template name="break">
30
+ <xsl:with-param name="text" select="//comments/comment[@line = current()/@line]"/>
31
+ </xsl:call-template>
32
+ </p>
33
+ </div>
34
+ </xsl:if>
35
+ </xsl:for-each>
36
+ </div>
37
+ </xsl:template>
38
+ <xsl:template name="break">
39
+ <xsl:param name="text" select="string(.)"/>
40
+ <xsl:choose>
41
+ <xsl:when test="contains($text, '\n')">
42
+ <xsl:value-of select="substring-before($text, '\n')"/>
43
+ <br/>
44
+ <xsl:call-template name="break">
45
+ <xsl:with-param
46
+ name="text"
47
+ select="substring-after($text, '\n')"
48
+ />
49
+ </xsl:call-template>
50
+ </xsl:when>
51
+ <xsl:otherwise>
52
+ <xsl:value-of select="$text"/>
53
+ </xsl:otherwise>
54
+ </xsl:choose>
55
+ </xsl:template>
56
+ </xsl:stylesheet>
package/src/version.js CHANGED
@@ -6,6 +6,6 @@
6
6
  // The values here are replaced automatically by the .rultor.yml script,
7
7
  // at the "release" pipeline:
8
8
  module.exports = {
9
- what: '0.33.0',
10
- when: '2025-09-16'
9
+ what: '0.33.2',
10
+ when: '2025-10-07'
11
11
  };