diff --git a/.claude/agents/pr-fix.md b/.claude/agents/pr-fix.md index a0c63ce..d5e63dd 100644 --- a/.claude/agents/pr-fix.md +++ b/.claude/agents/pr-fix.md @@ -58,7 +58,7 @@ Do not edit anything when returning this block. - Edit sources: `lib/*.js` (and keep `lib/index.d.ts` in sync when you change an option, a signature, or an export); tests in `test/`; config files at the repo root (`package.json`, `.eslintrc.js`, `.mega-linter.yml`, etc.); workflows in `.github/workflows/`. - Keep the existing code style (ESLint `eslint:recommended` + Prettier). Use the existing `debug("java-caller")` logging pattern. -- Run local validation that needs no network where possible: `npm run lint:fix`, then `npm run test` (set `DEBUG=java-caller` to mirror CI; the mocha timeout is 5 min because real JRE installs run). Coverage runs under `npm run test:coverage`. +- Run local validation that needs no network where possible: `npm run lint:fix`, then `npm run test` (set `NODE_DEBUG=java-caller` to mirror CI; the mocha timeout is 5 min because real JRE installs run). Coverage runs under `npm run test:coverage`. - Do NOT introduce defensive hacks (skip-on-fail, retries, `|| true`, weakened assertions, broad eslint ignores) to force green - fix the root cause. - **npm only**, never `yarn` (it would desync `package-lock.json`). diff --git a/.cspell.json b/.cspell.json index cad8ba9..456227c 100644 --- a/.cspell.json +++ b/.cspell.json @@ -20,6 +20,7 @@ "Gowans", "Inclusivity", "KICS", + "PATHEXT", "PROSELINT", "Perso", "SIGINT", @@ -34,6 +35,7 @@ "customarg", "cvfm", "danunafig", + "debuglog", "desync", "distrib", "djukxe", diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 92286e9..9253015 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,6 +11,24 @@ concurrency: cancel-in-progress: true jobs: + lint: + name: Lint + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Checkout Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Install node + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: "24" + - name: Install dependencies + run: npm ci + - name: Run lint + run: npm run lint + test: if: github.event_name != 'push' || github.ref_name == github.event.repository.default_branch strategy: @@ -50,7 +68,7 @@ jobs: run: npm ci - name: Run tests env: - DEBUG: java-caller,njre + NODE_DEBUG: java-caller run: npm run test test-no-java: @@ -73,5 +91,5 @@ jobs: run: npm ci - name: Run tests env: - DEBUG: "java-caller" + NODE_DEBUG: "java-caller" run: npm run test diff --git a/.mega-linter.yml b/.mega-linter.yml index cde84e0..a685c10 100644 --- a/.mega-linter.yml +++ b/.mega-linter.yml @@ -1,6 +1,8 @@ # Flavor & version used by mega-linter-runner and the MegaLinter agent skills MEGALINTER_FLAVOR: javascript MEGALINTER_VERSION: v10 +# The javascript flavor is a deliberate choice: skip the custom-flavor suggestions +FLAVOR_SUGGESTIONS: false DISABLE_LINTERS: - TYPESCRIPT_STANDARD - TYPESCRIPT_PRETTIER diff --git a/CHANGELOG.md b/CHANGELOG.md index 57904d4..8fb0da2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +## [6.0.0] 2026-08-09 + +- **Breaking**: Debug traces are now activated with `NODE_DEBUG=java-caller` instead of `DEBUG=java-caller`. The `debug` package has been replaced by Node's built-in `util.debuglog`, which only reads `NODE_DEBUG` from the environment the process is launched with (setting `process.env.NODE_DEBUG` at runtime no longer enables traces). The output format changes accordingly, from `java-caller +1ms` to `JAVA-CALLER : `. +- **Breaking**: Minimum supported Node.js version is now 18 (`engines` previously declared `>=12`, while `njre` v3 already required `>=18`) +- Reduce runtime dependencies from 17 packages to 10: remove `fs-extra` (replaced by `node:fs`) and `debug` (replaced by `node:util`), and upgrade `yauzl` so it no longer pulls `buffer-crc32`. Only `njre` and `semver` remain as direct dependencies. +- Remove the `which` dev dependency, whose `engines` excluded the Node versions tested in CI +- Fix `npm run lint`, broken since the ESLint v10 upgrade: `@eslint/js` and `globals` are required by `eslint.config.js` but were no longer installed transitively. They are now explicit dev dependencies, and CI runs `npm run lint` so the script cannot silently break again. + ## [5.0.0] 2026-06-30 - **Breaking**: Upgrade `njre` to v2.0.0: auto-installed JDK/JRE now comes from Eclipse Temurin (`api.adoptium.net`) instead of the deprecated AdoptOpenJDK endpoint (which hung under Node 24) diff --git a/CLAUDE.md b/CLAUDE.md index 3827e8b..5b3f58a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -9,8 +9,8 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Commands ```shell -npm run test # Run all mocha tests (timeout 300000ms; CI sets DEBUG=java-caller,njre) -npm run test:debug # Tests with DEBUG=java-caller enabled +npm run test # Run all mocha tests (timeout 300000ms; CI sets NODE_DEBUG=java-caller) +npm run test:debug # Tests with NODE_DEBUG=java-caller enabled npm run lint:fix # eslint --fix on **/*.js, then prettier on lib (tab-width 4, print-width 150) # Run a single test by name (mocha grep on the it()/describe() title): @@ -50,10 +50,12 @@ Three modules in `lib/`, re-exported from `index.js`: - **Java-version resolution is cached on `globalThis.JAVA_CALLER_VERSIONS_CACHE`** to avoid repeated lookups across instances in one process. Tests reset this in `test/helpers/init.js`; if you add caching state, reset it there too. - **Platform branching** lives in `getPlatformBinPath()` (darwin = `Contents/Home/bin`) and several `os.platform() === "win32"` checks. Windows also handles arg quoting (`windowsVerbatimArguments`), `javaw` for windowless, and `windowsHide`. Any new behavior must be validated on win32/darwin/linux. - **`classPath`** accepts a string (split on `:`, converted to the OS delimiter) or a string array; resolved against `rootPath` unless `useAbsoluteClassPaths` is set. +- **Runtime dependencies are deliberately minimal** (`njre` + `semver` only): prefer `node:` built-ins over adding a package. +- **Debug traces use `util.debuglog`**, activated with `NODE_DEBUG=java-caller` (not `DEBUG=`, which was the pre-v6 `debug` package contract). `debuglog` reads `NODE_DEBUG` only from the environment the process was launched with, so tests and helpers cannot turn traces on at runtime — `npm run test:debug` sets it on the command line. ## Testing notes - Tests are mocha + `node:assert`, with shared helpers in `test/helpers/common.js` (`checkStatus`, `checkStdOutIncludes`, etc.) and per-run init in `test/helpers/init.js` (loaded via the `mocha.require` config in `package.json`). - `test/java-install.test.js` exercises the real `njre` download/install path, which is why the mocha timeout is 5 minutes. -- CI (`.github/workflows/test.yml`) runs the matrix Node 18/20/24 × Java 8/11/17/21/25 × ubuntu/macos/windows, plus a no-Java job (`Test - No Java`) that runs the suite in a container without a system JDK. +- CI (`.github/workflows/test.yml`) runs the matrix Node 18/20/24 × Java 8/11/17/21/25 × ubuntu/macos/windows, plus a no-Java job (`Test - No Java`) that runs the suite in a container without a system JDK, plus a `Lint` job running `npm run lint`. - macOS defaults `minimumJavaVersion` to 11 (no Java 8 there); keep that branch intact. diff --git a/README.md b/README.md index b95f028..1323899 100644 --- a/README.md +++ b/README.md @@ -170,13 +170,15 @@ You can see **more examples in** [**test methods**](https://github.com/nvuillam/ ## TROUBLESHOOTING -Set environment variable `DEBUG=java-caller` before calling your code using java-caller module, and you will see the java commands executed. +Set environment variable `NODE_DEBUG=java-caller` before calling your code using java-caller module, and you will see the java commands executed. + +> Since v6.0.0 traces use Node's built-in [`util.debuglog`](https://nodejs.org/api/util.html#utildebuglogsection-callback) instead of the `debug` package, so the variable is `NODE_DEBUG` and not `DEBUG` anymore. It must be set in the environment the process is launched with: setting `process.env.NODE_DEBUG` at runtime has no effect. Example debug log: ```shell -java-caller Found Java version 1.80131 +1s -java-caller Java command: java -Xms256m -Xmx2048m -cp C:\Work\gitPerso\node-java-caller\test\java\dist com.nvuillam.javacaller.JavaCallerTester -customarg nico +1ms +JAVA-CALLER 12345: Found Java version 1.80131 +JAVA-CALLER 12345: Java command: java -Xms256m -Xmx2048m -cp C:\Work\gitPerso\node-java-caller\test\java\dist com.nvuillam.javacaller.JavaCallerTester -customarg nico ``` ## CONTRIBUTE diff --git a/examples/cli_app/package.json b/examples/cli_app/package.json index f51064e..56dd4c1 100644 --- a/examples/cli_app/package.json +++ b/examples/cli_app/package.json @@ -12,9 +12,9 @@ "scripts": { "install-local-cli": "npm install && npm link --force", "run:source": "node lib/index.js -a list --of arguments", - "run:source:verbose": "env DEBUG=java-caller node lib/index.js -a list --of arguments", + "run:source:verbose": "env NODE_DEBUG=java-caller node lib/index.js -a list --of arguments", "run:cli": "java-caller-example-cli -a list --of arguments", - "run:verbose": "env DEBUG=java-caller java-caller-example-cli -a list --of arguments" + "run:verbose": "env NODE_DEBUG=java-caller java-caller-example-cli -a list --of arguments" }, "keywords": [ "java-caller", diff --git a/examples/module_app/package.json b/examples/module_app/package.json index 780492b..dbb2352 100644 --- a/examples/module_app/package.json +++ b/examples/module_app/package.json @@ -12,9 +12,9 @@ "scripts": { "install-local-cli": "npm install && npm link --force", "run:source": "node lib/index.js", - "run:source:verbose": "env DEBUG=java-caller node lib/index.js", + "run:source:verbose": "env NODE_DEBUG=java-caller node lib/index.js", "run:cli": "java-caller-example-module", - "run:cli:verbose": "env DEBUG=java-caller java-caller-example-module", + "run:cli:verbose": "env NODE_DEBUG=java-caller java-caller-example-module", "test": "echo \"I strongly encourage you to implement test cases and code coverage, with mocha and nyc for example :)\"" }, "keywords": [ diff --git a/lib/cli.js b/lib/cli.js index 20c2aec..9bdca79 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -1,6 +1,6 @@ #! /usr/bin/env node const { JavaCaller } = require("./java-caller"); -const fse = require("fs-extra"); +const fs = require("fs"); const path = require("path"); class JavaCallerCli { @@ -11,7 +11,7 @@ class JavaCallerCli { constructor(baseDir) { // Use user-defined JSON file to read configuration const configFile = path.resolve(`${baseDir}/java-caller-config.json`); - const options = fse.readJSONSync(configFile); + const options = JSON.parse(fs.readFileSync(configFile, "utf8")); // Default output is console with CLI if (options.output == null) { options.output = "console"; diff --git a/lib/java-caller.js b/lib/java-caller.js index fbce75c..609ff9f 100644 --- a/lib/java-caller.js +++ b/lib/java-caller.js @@ -1,11 +1,15 @@ #! /usr/bin/env node -const debug = require("debug")("java-caller"); -const fse = require("fs-extra"); +const fs = require("fs"); const os = require("os"); const path = require("path"); +const { debuglog } = require("util"); const { spawn } = require("child_process"); const semver = require("semver"); +// NODE_DEBUG must be set in the environment the process is launched with: +// debuglog never re-reads it, so setting process.env.NODE_DEBUG at runtime has no effect. +const debug = debuglog("java-caller"); + class JavaCaller { "use strict"; minimumJavaVersion = os.platform() === "darwin" ? 11 : 8; // Mac starts at 11 @@ -334,15 +338,15 @@ class JavaCaller { console.log(`Installing Java ${javaTypeToInstall} ${javaVersionToInstall} in ${this.javaCallerSupportDir}...`); // Create a directory for installing Java and ensure it contains a dummy package.json - await fse.ensureDir(this.javaCallerSupportDir, { mode: "0777" }); + await fs.promises.mkdir(this.javaCallerSupportDir, { recursive: true, mode: "0777" }); const packageJson = `${this.javaCallerSupportDir + path.sep}package.json`; - if (!fse.existsSync(packageJson)) { + if (!fs.existsSync(packageJson)) { const packageJsonContent = { name: "java-caller-support", version: "1.0.0", description: "Java installations by java-caller (https://github.com/nvuillam/node-java-caller)", }; - await fse.writeFile(packageJson, JSON.stringify(packageJsonContent), "utf8"); + await fs.promises.writeFile(packageJson, JSON.stringify(packageJsonContent), "utf8"); } // Install appropriate java version using njre @@ -464,15 +468,15 @@ class JavaCaller { // check if one matches with javaType , minimumJavaVersion and maximumJavaVersion async findJavaVersionHome() { const javaInstallsTopDir = path.join(this.javaCallerSupportDir, "jre"); - if (!fse.existsSync(javaInstallsTopDir)) { + if (!fs.existsSync(javaInstallsTopDir)) { return {}; } - return await fse + return await fs.promises .readdir(javaInstallsTopDir) .then((items) => items - .filter((item) => fse.statSync(path.join(javaInstallsTopDir, item)).isDirectory()) + .filter((item) => fs.statSync(path.join(javaInstallsTopDir, item)).isDirectory()) .map((folder) => { const version = semver.coerce(folder); return { version, folder }; @@ -483,7 +487,7 @@ class JavaCaller { const bin = path.join(home, this.getPlatformBinPath()); return { version, folder, home, bin }; }) - .find(({ bin }) => fse.existsSync(bin)), + .find(({ bin }) => fs.existsSync(bin)), ) .then((match) => { if (!match) return {}; diff --git a/package-lock.json b/package-lock.json index b1e886e..1bc514a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,29 +1,28 @@ { "name": "java-caller", - "version": "5.0.0", + "version": "6.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "java-caller", - "version": "5.0.0", + "version": "6.0.0", "license": "MIT", "dependencies": { - "debug": "^4.3.4", - "fs-extra": "^11.1.1", "njre": "^3.0.0", "semver": "^7.5.4" }, "devDependencies": { + "@eslint/js": "^10.0.1", "@types/node": "^25.2.0", "eslint": "^10.0.0", + "globals": "^17.9.0", "mocha": "^11.0.0", "prettier": "^3.1.0", - "typescript": "^7.0.0", - "which": "^7.0.0" + "typescript": "^7.0.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=18.0.0" } }, "node_modules/@eslint-community/eslint-utils": { @@ -125,6 +124,27 @@ "node": "^20.19.0 || ^22.13.0 || >=24" } }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, "node_modules/@eslint/object-schema": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", @@ -719,15 +739,6 @@ "dev": true, "license": "ISC" }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -910,6 +921,7 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -1247,20 +1259,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/fs-extra": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.4.0.tgz", - "integrity": "sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1321,11 +1319,18 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" + "node_modules/globals": { + "version": "17.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.9.0.tgz", + "integrity": "sha512-m/MvAW61QVU5VDNF1Vj8axt016h8w7L5TU1e9zlab7XIttAT2YAlCwl75K1fOqvMM9apmD7lbCIRhpfkhmxhCg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/has-flag": { "version": "4.0.0", @@ -1433,16 +1438,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/isexe": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", - "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=20" - } - }, "node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", @@ -1503,18 +1498,6 @@ "dev": true, "license": "MIT" }, - "node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -1666,6 +1649,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, "node_modules/natural-compare": { @@ -2130,15 +2114,6 @@ "dev": true, "license": "MIT" }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -2149,22 +2124,6 @@ "punycode": "^2.1.0" } }, - "node_modules/which": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-7.0.0.tgz", - "integrity": "sha512-RancgH2dmbLdHl6LRhEqvklWMgl/Hdnun0Y90KhBOLkMefg8Qa7/Zel8Sm+8HEcP6DEjzsWzpkuBQEZok58isA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^4.0.0" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^22.22.2 || ^24.15.0 || >=26.0.0" - } - }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -2404,12 +2363,11 @@ } }, "node_modules/yauzl": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.1.tgz", - "integrity": "sha512-k1isifdbpNSFEHFJ1ZY4YDewv0IH9FR61lDetaRMD3j2ae3bIXGV+7c+LHCqtQGofSd8PIyV4X6+dHMAnSr60A==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.4.0.tgz", + "integrity": "sha512-jIH9yLR9wqr0wOS0TpBvo/g/2UgZH5qePVbjgRliiF0BYvOZyaBknKsF+x9Iht0O6sqgnB93rCICdOZFecJuDw==", "license": "MIT", "dependencies": { - "buffer-crc32": "~0.2.3", "pend": "~1.2.0" }, "engines": { diff --git a/package.json b/package.json index b07ef7b..d97502d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "java-caller", - "version": "5.0.0", + "version": "6.0.0", "description": "Library to easily call java from node sources. Automatically installs java if not present", "main": "./lib/index.js", "types": "./lib/index.d.ts", @@ -13,7 +13,7 @@ "java:compile": "javac -d test/java/dist --release 8 test/java/src/com/nvuillam/javacaller/JavaCallerTester.java", "java:jar": "cd test/java/dist && jar -cvfm ./../jar/JavaCallerTester.jar ./../jar/manifest/Manifest.txt com/nvuillam/javacaller/*.class && jar -cvfm ./../jar/JavaCallerTesterRunnable.jar ./../jar/manifest-runnable/Manifest.txt com/nvuillam/javacaller/*.class", "test": "mocha \"test/**/*.test.js\"", - "test:debug": "env DEBUG=java-caller mocha --reporter spec \"test/**/*.test.js\"" + "test:debug": "env NODE_DEBUG=java-caller mocha --reporter spec \"test/**/*.test.js\"" }, "repository": { "type": "git", @@ -37,29 +37,26 @@ }, "homepage": "https://github.com/nvuillam/node-java-caller#readme", "dependencies": { - "debug": "^4.3.4", - "fs-extra": "^11.1.1", "njre": "^3.0.0", "semver": "^7.5.4" }, "devDependencies": { + "@eslint/js": "^10.0.1", "@types/node": "^25.2.0", "eslint": "^10.0.0", + "globals": "^17.9.0", "mocha": "^11.0.0", "prettier": "^3.1.0", - "typescript": "^7.0.0", - "which": "^7.0.0" + "typescript": "^7.0.0" }, "overrides": { - "@babel/core": "^8.0.0", "brace-expansion": "^5.0.6", "diff": "^9.0.0", "js-yaml": "^5.0.0", - "serialize-javascript": "^7.0.5", - "uuid": "^14.0.0" + "serialize-javascript": "^7.0.5" }, "engines": { - "node": ">=12.0.0" + "node": ">=18.0.0" }, "mocha": { "require": [ diff --git a/test/helpers/common.js b/test/helpers/common.js index 2023010..69322ea 100644 --- a/test/helpers/common.js +++ b/test/helpers/common.js @@ -1,5 +1,22 @@ #! /usr/bin/env node const assert = require("assert"); +const fs = require("fs"); +const os = require("os"); +const path = require("path"); + +// Locate an executable in PATH, honoring PATHEXT on Windows. Returns null when not found. +function findInPath(command) { + const extensions = os.platform() === "win32" ? (process.env.PATHEXT || ".EXE").split(path.delimiter) : [""]; + for (const dir of (process.env.PATH || "").split(path.delimiter).filter(Boolean)) { + for (const extension of extensions) { + const candidate = path.join(dir, command + extension); + if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) { + return candidate; + } + } + } + return null; +} // Reset codeNarcCallsCounter before each test const beforeEachTestCase = function () { @@ -26,6 +43,7 @@ function checkStdErrIncludes(textToCheck, stdout, stderr) { module.exports = { beforeEachTestCase, + findInPath, checkStatus, checkStdOutIncludes, checkStdOutIncludesOneOf, diff --git a/test/helpers/init.js b/test/helpers/init.js index 8d863da..e6dcd77 100644 --- a/test/helpers/init.js +++ b/test/helpers/init.js @@ -2,11 +2,9 @@ "use strict"; console.log("npm run test initialized"); -// Activate debug log if we are in debug mode -const debug = typeof v8debug === "object" || /--debug|--inspect|--inspect-brk/.test(process.execArgv.join(" ")); -if (debug) { - require("debug").enable("java-caller"); -} +// Traces can no longer be enabled from here: util.debuglog only reads NODE_DEBUG from the +// environment the process was launched with. Run `npm run test:debug`, or launch your +// debugger with NODE_DEBUG=java-caller set. // Reinitialize cache globalThis.JAVA_CALLER_VERSIONS_CACHE = null; diff --git a/test/java-caller.test.js b/test/java-caller.test.js index 2c2c6d0..270f79d 100644 --- a/test/java-caller.test.js +++ b/test/java-caller.test.js @@ -2,11 +2,11 @@ "use strict"; const { JavaCaller } = require('../lib/index'); const os = require("os"); -const which = require("which"); const path = require('path'); const { beforeEachTestCase, + findInPath, checkStatus, checkStdOutIncludes, checkStdErrIncludes @@ -169,10 +169,8 @@ describe("Call with classes", () => { }); it("should call JavaCallerTester.class in JavaCallerTester.jar (override java)", async () => { - let javaPath; - try { - javaPath = which.sync("java"); - } catch { + const javaPath = findInPath("java"); + if (!javaPath) { console.log("Java not found: ignore test method"); } if (javaPath) {