eolang 0.35.2 → 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 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.35.1.tar.gz"
11
- version "0.35.1"
12
- sha256 "694218ea2ab13179be731ab7d671ba5f7ebe9a8aa9fc6b5d695d699180879466"
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 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.1
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.1
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):
package/eo-version.txt CHANGED
@@ -1 +1 @@
1
- 0.61.1
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.59.7
1
+ 0.61.3
@@ -207,6 +207,6 @@
207
207
  <heap-size>undefined</heap-size>
208
208
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
209
209
  <junit.version>6.1.0</junit.version>
210
- <jeo.version>0.15.2</jeo.version>
210
+ <jeo.version>0.15.3</jeo.version>
211
211
  </properties>
212
212
  </project>
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.15.2</jeo.version>
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>
package/package.json CHANGED
@@ -21,6 +21,7 @@
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",
@@ -72,5 +73,5 @@
72
73
  "coverage": "nyc --reporter=lcov --reporter=text-summary mocha test/**/*.js --timeout 1200000",
73
74
  "test": "mocha 'test/**/*.js' --timeout 1200000"
74
75
  },
75
- "version": "0.35.2"
76
+ "version": "0.36.0"
76
77
  }
File without changes
@@ -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, '&amp;')
20
+ .replace(/</g, '&lt;')
21
+ .replace(/>/g, '&gt;')
22
+ .replace(/"/g, '&quot;');
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;
@@ -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 = execSync(
46
- `phino rewrite --input=xmir --output=xmir --normalize ${xmir}`,
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/eo2jsw.js CHANGED
@@ -7,11 +7,11 @@ const path = require('path');
7
7
  const {execSync} = require('child_process'),
8
8
 
9
9
  /**
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
- */
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
- * Wrapper for eo2js.
28
- * @param {String} command - Command to execute
29
- * @param {Object} args - Command arguments
30
- * @return {Promise<Array.<String>>}
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
- language = {
14
- java: 'Java',
15
- js: 'JavaScript',
16
- },
13
+ const language = {
14
+ java: 'Java',
15
+ js: 'JavaScript',
16
+ };
17
17
 
18
- /**
18
+ /**
19
19
  * Platform dependent commands.
20
20
  */
21
- 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
- commands = {
38
- [language.java]: {
39
- ...common,
40
- ...{
41
- resolve: require('./commands/java/resolve'),
42
- transpile: require('./commands/java/transpile'),
43
- link: require('./commands/java/link'),
44
- compile: require('./commands/java/compile'),
45
- dataize: require('./commands/java/dataize'),
46
- test: require('./commands/java/test'),
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
- pipelines = {
62
- [language.java]: require('./commands/java/pipeline'),
63
- [language.js]: require('./commands/js/pipeline'),
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')
@@ -378,13 +394,7 @@ program.command('fmt')
378
394
  });
379
395
 
380
396
  if (require.main === module) {
381
- try {
382
- program.parse(process.argv);
383
- } catch (e) {
384
- console.error(e.message);
385
- console.debug(e.stack);
386
- process.exit(1);
387
- }
397
+ program.parseAsync(process.argv);
388
398
  }
389
399
 
390
400
  module.exports.commandsDescription = function commandsDescription() {
@@ -418,12 +428,7 @@ function pin(opts) {
418
428
  * @return {Object} - commands
419
429
  */
420
430
  function coms() {
421
- const lang = program.opts().language,
422
- hash = commands[lang];
423
- if (hash === undefined) {
424
- throw new Error(`Unknown platform ${lang}`);
425
- }
426
- return hash;
431
+ return select(commands, program.opts().language);
427
432
  }
428
433
 
429
434
  /**
@@ -431,10 +436,24 @@ function coms() {
431
436
  * @return {Function} - pipeline function
432
437
  */
433
438
  function pipe() {
434
- const lang = program.opts().language;
435
- const pipeline = pipelines[lang];
436
- if (pipeline === undefined) {
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) {
437
456
  throw new Error(`Unknown platform ${lang}`);
438
457
  }
439
- return pipeline;
458
+ return found;
440
459
  }
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
@@ -81,7 +92,7 @@ module.exports.mvnw = function(args, tgt, batch) {
81
92
  return new Promise((resolve, reject) => {
82
93
  console.debug(`Running mvnw with arguments: ${args.join(' ')}`);
83
94
  target = tgt;
84
- phase = args.filter((a) => !a.startsWith('-')).join(' + ');
95
+ phase = module.exports.summary(args);
85
96
  const home = path.resolve(__dirname, '../mvnw');
86
97
  let bin = path.resolve(home, 'mvnw') + (process.platform === 'win32' ? '.cmd' : '');
87
98
  if (!fs.existsSync(bin)) {
@@ -110,20 +121,20 @@ module.exports.mvnw = function(args, tgt, batch) {
110
121
  start();
111
122
  }
112
123
  result.on('close', (code) => {
113
- if (code !== 0) {
114
- console.error(`The command "${cmd}" exited with #${code} code`);
115
- process.exit(1);
116
- }
117
124
  if (!batch) {
118
125
  stop();
119
126
  }
127
+ if (code !== 0) {
128
+ reject(new Error(`The command "${cmd}" exited with #${code} code`));
129
+ return;
130
+ }
120
131
  resolve(args);
121
132
  });
122
133
  } else {
123
134
  result.on('close', (code) => {
124
135
  if (code !== 0) {
125
- console.error(`The command "${cmd}" exited with #${code} code`);
126
- process.exit(1);
136
+ reject(new Error(`The command "${cmd}" exited with #${code} code`));
137
+ return;
127
138
  }
128
139
  resolve(args);
129
140
  });
@@ -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
- * Load the latest version from GitHub releases.
11
- * @return {String} Latest version, for example '0.23.1'
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() {
@@ -40,7 +41,7 @@ const request = require('sync-request'),
40
41
  * Check if a specific parser version exists in Maven Central.
41
42
  * @param {String} ver - Version to check, for example '0.23.1'
42
43
  * @param {function} fetch - HTTP call, defaults to sync-request
43
- * @return {Boolean} True if version exists, false otherwise
44
+ * @return {Boolean} True if version exists or cannot be verified, false if confirmed absent
44
45
  */
45
46
  exists(ver, fetch = request) {
46
47
  let result;
@@ -49,8 +50,10 @@ const request = require('sync-request'),
49
50
  const res = fetch('GET', version.url(ver), {timeout: 10000, socketTimeout: 10000});
50
51
  result = res.statusCode === 200;
51
52
  } catch (e) {
52
- console.debug('Unable to validate parser version (network error): %s', e.message);
53
- result = false;
53
+ console.warn(colors.yellow(
54
+ `Cannot verify parser version ${ver} in Maven Central (${e.message}), proceeding anyway`
55
+ ));
56
+ result = true;
54
57
  }
55
58
  } else {
56
59
  result = false;
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.35.2',
10
- when: '2026-06-23'
9
+ what: '0.36.0',
10
+ when: '2026-07-09'
11
11
  };