Skip to content

Commit

Permalink
feat(clang-format-node): create new clangFormatPath and `getClangFo…
Browse files Browse the repository at this point in the history
…rmatPath` API (#72)

New features have arrived.

You can get `clang-format-node` native binary absolute path from `clangFormatPath` and `getClangFormatPath` API.

* wip: update root's `package-lock.json` and `clang-format-node`'s `packges.json`

* wip: rename and update `getClangFormatPath.js`

* chore: update test script for `lint-staged` in `package.json`

* test: rename and update test for `getClangFormatPath`

I've deleted mocha and replaced it with node.js's test runner.

So I renamed it from `spec.js` to `test.js`.

* wip: create `clangFormatPath.js`

* test: add test for `clangFormatPath`

* chore: delete test logic in `lint-staged` of `package.json`

* refactor: detach cli logic into `cli.js`

* refactor: update `index.js`

* test: add `cli.test.js`

* test: update `cli.test.js` to be included in test coverage

* chore: fix `pretest` script

* refactor: delete unworking try-catch block and replace it with `.on('close', ...)`

* test: create test for `index.js`

* test: fix wrong import statement in `index.test.js`
  • Loading branch information
lumirlumir authored Nov 4, 2024
1 parent b09baa5 commit 08b195a
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 67 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@
"npx editorconfig-checker -config .editorconfig-checker.json"
],
"*.js": "npx eslint",
"*.md": "npx markdownlint",
"packages/**/*.js": [
"npm run test"
]
"*.md": "npx markdownlint"
}
}
7 changes: 4 additions & 3 deletions packages/clang-format-node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"README.md"
],
"bin": {
"clang-format": "build/index.js"
"clang-format": "build/cli.js"
},
"keywords": [
"clang-format",
Expand Down Expand Up @@ -43,7 +43,8 @@
"scripts": {
"postinstall": "find ./build/bin -type f -exec chmod 755 {} + || true",
"prepublishOnly": "npm run build",
"build": "npx babel src -d build --no-comments --compact true --minified && cp -r src/bin build && cp ../../LICENSE ../../README.md .",
"test": "npx mocha ./tests --inline-diffs true"
"build": "npx babel src -d build --ignore **/*.test.js && cp -r src/bin build && cp ../../LICENSE ../../README.md .",
"pretest": "find ./src/bin -type f -exec chmod 755 {} + || true",
"test": "node --test"
}
}
18 changes: 18 additions & 0 deletions packages/clang-format-node/src/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env node
// The shebang line `#!/usr/bin/env node` ensures the script runs with the correct Node.js interpreter across different environments.

const { spawn } = require('child_process');

const { clangFormatPath } = require('./utils/clangFormatPath');

const spawned = spawn(clangFormatPath, process.argv.slice(2), {
stdio: 'inherit',
});

spawned.on('close', code => {
if (code !== 0) {
// eslint-disable-next-line no-console
console.error(`Process exited with code: ${code}`);
process.exit(code);
}
});
26 changes: 26 additions & 0 deletions packages/clang-format-node/src/cli.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const { doesNotThrow, throws } = require('node:assert');
const { execSync } = require('node:child_process');
const { resolve } = require('node:path');
const { describe, it } = require('node:test');

const cli = resolve(__dirname, 'cli.js');

describe('cli doesNotThrow and throws testing', () => {
// Correct
it('node cli.js --help', () => {
doesNotThrow(() => {
execSync(`node ${cli} --help`);
});
});
it('node cli.js --version', () => {
doesNotThrow(() => {
execSync(`node ${cli} --version`);
});
});
// Wrong
it('node cli.js --abcdefg', () => {
throws(() => {
execSync(`node ${cli} --abcdefg`);
});
});
});
27 changes: 0 additions & 27 deletions packages/clang-format-node/src/getClangFormatPath.js

This file was deleted.

31 changes: 6 additions & 25 deletions packages/clang-format-node/src/index.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,7 @@
#!/usr/bin/env node
// The shebang line `#!/usr/bin/env node` ensures the script runs with the correct Node.js interpreter across different environments.
const { clangFormatPath } = require('./utils/clangFormatPath');
const { getClangFormatPath } = require('./utils/getClangFormatPath');

const { platform, arch } = require('os');
const { spawn } = require('child_process');
const getClangFormatPath = require('./getClangFormatPath');

const OS_PLATFORM = platform();
const ARCHITECTURE = arch();

try {
const spawned = spawn(
getClangFormatPath(OS_PLATFORM, ARCHITECTURE),
process.argv.slice(2),
{
stdio: 'inherit',
},
);

// Terminate the parent process after the child process has completed.
spawned.on('close', process.exit);
} catch (error) {
// eslint-disable-next-line no-console
console.error(error.message);
process.exit(1);
}
module.exports = {
clangFormatPath,
getClangFormatPath,
};
13 changes: 13 additions & 0 deletions packages/clang-format-node/src/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const { ok } = require('node:assert');
const { describe, it } = require('node:test');

const { clangFormatPath, getClangFormatPath } = require('./index');

describe('index ok testing', () => {
it('clangFormatPath should be imported correctly', () => {
ok(clangFormatPath);
});
it('getClangFormatPath should be imported correctly', () => {
ok(getClangFormatPath);
});
});
12 changes: 12 additions & 0 deletions packages/clang-format-node/src/utils/clangFormatPath.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const { platform, arch } = require('os');

const { getClangFormatPath } = require('./getClangFormatPath');

/**
* The ABSOLUTE path to the `clang-format` executable binary based on the OS platform and architecture.
*/
const clangFormatPath = getClangFormatPath(platform(), arch());

module.exports = {
clangFormatPath,
};
12 changes: 12 additions & 0 deletions packages/clang-format-node/src/utils/clangFormatPath.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const { strictEqual } = require('node:assert');
const { platform, arch } = require('node:os');
const { describe, it } = require('node:test');

const { clangFormatPath } = require('./clangFormatPath');
const { getClangFormatPath } = require('./getClangFormatPath');

describe('clangFormatPath strictEqual testing', () => {
it('clangFormatPath === getClangFormatPath(platform(), arch())', () => {
strictEqual(clangFormatPath, getClangFormatPath(platform(), arch()));
});
});
35 changes: 35 additions & 0 deletions packages/clang-format-node/src/utils/getClangFormatPath.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const { existsSync } = require('fs');
const { resolve } = require('path');

/**
* Returns the ABSOLUTE path to the `clang-format` executable binary based on the OS platform and architecture.
*
* The possible combinations are `darwin-arm64`, `darwin-x64`, `linux-arm`, `linux-arm64`, `linux-ppc64`, `linux-s390x`, `linux-x64`, `win32-x64`.
*
* Throws an error if the executable is not found.
*
* @param {string} osPlatform The current operating system platform. (e.g., `darwin`, `linux`, `win32`)
* @param {string} architecture The current system architecture. (e.g., `arm`, `arm64`, `ppc64`, `s390x`, `x64`)
* @returns {string} The ABSOLUTE path to the `clang-format` executable binary.
* @throws `Error` Throws an error if the executable binary is not found for the specified OS platform and architecture.
*/
function getClangFormatPath(osPlatform, architecture) {
const clangFormatPath = resolve(
__dirname,
`..`,
`bin`,
`cfn-${osPlatform}-${architecture}`,
`clang-format${osPlatform === 'win32' ? '.exe' : ''}`,
);

if (!existsSync(clangFormatPath))
throw new Error(
`No executable found for '${osPlatform}(OS platform)-${architecture}(architecture)'\nThe possible combinations are 'darwin-arm64', 'darwin-x64', 'linux-arm', 'linux-arm64', 'linux-ppc64', 'linux-s390x', 'linux-x64', 'win32-x64'`,
);

return clangFormatPath;
}

module.exports = {
getClangFormatPath,
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
const { doesNotThrow, throws } = require('assert');
const getClangFormatPath = require('../src/getClangFormatPath');
const { doesNotThrow, throws } = require('node:assert');
const { describe, it } = require('node:test');

// See possible values in https://nodejs.org/api/os.html#osplatform
const { getClangFormatPath } = require('./getClangFormatPath');

/**
* See possible values in {@link https://nodejs.org/api/os.html#osplatform}.
*/
const osPlatforms = ['aix', 'darwin', 'freebsd', 'linux', 'openbsd', 'sunos', 'win32'];
// See possible values in https://nodejs.org/api/os.html#osarch

/**
* See possible values in {@link https://nodejs.org/api/os.html#osarch}.
*/
const architectures = [
'arm',
'arm64',
Expand All @@ -18,15 +25,18 @@ const architectures = [
's390x',
'x64',
];

/**
* The possible combinations are `darwin-arm64`, `darwin-x64`, `linux-arm`, `linux-arm64`, `linux-ppc64`, `linux-s390x`, `linux-x64`, `win32-x64`.
*
* See {@link getClangFormatPath}.
*/
const allowed = {
darwin: ['arm64', 'x64'],
linux: ['arm', 'arm64', 'ppc64', 's390x', 'x64'],
win32: ['x64'],
};

/**
* Tests for the `getClangFormatPath`
*/
describe('getClangFormatPath doesNotThrow and throws testing', () => {
osPlatforms.forEach(osPlatform => {
architectures.forEach(architecture => {
Expand Down

0 comments on commit 08b195a

Please sign in to comment.