Reputation: 5367
When creating a CLI I would like to test my function. For that I'm using the module child_process.
const path = require('path');
const { execFile } = require('child_process');
describe('cli test', () => {
test('thing', () => {
const myCli = execFile(
`${path.resolve(__dirname, '..')}/cli.js`, ['--foo', 'Bar'],
(err, stdout, stderr) => {
if (err) {
console.log('err: ', err);
}
});
});
But this produces the following error:
Attempted to log "err: { Error: spawn /projects/cli/src/cli.js EACCES
at Process.ChildProcess._handle.onexit (internal/child_process.js:240:19)
at onErrorNT (internal/child_process.js:415:16)
at process._tickCallback (internal/process/next_tick.js:63:19)
errno: 'EACCES',
code: 'EACCES',
Running this script directly in the terminal via the command: $ node cli.js --foo Bar
works perfectly.
Now a suggestion is to chmod +x <file>
that file (source). But the test should also work on CI, and on a different computer which pulls the Git repo.
Any idea?
Upvotes: 1
Views: 3285
Reputation: 1561
I was receiving an EACCESS -13 error from child_process.spawn when trying to run a the command line mysql command.
There was something wrong with my PATH and updating it to add /usr/local/mysql/bin/ resolved the problem.
The temporary fix is to run export PATH=$PATH:/usr/local/mysql/bin/
.
The permanent fix is to:
sudo nano /etc/paths
/usr/local/mysql/bin
at the endNOTE: I got the temporary fix from a site ... I don't know why it has a / on the end of the bin but all of the mysql executables appear to be available without it in the /etc/paths file
Upvotes: 0
Reputation: 78920
I'd suggest using fork
instead of execFile
.
The
child_process.fork()
method is a special case ofchild_process.spawn()
used specifically to spawn new Node.js processes.
This will allow you to execute JS files without needing them to be shell executable.
Upvotes: 2
Reputation: 333
To the best of my knowledge, git actually tracks the executable bit for files. There are some things to consider though as pointed out in this article: https://medium.com/@tahteche/how-git-treats-changes-in-file-permissions-f71874ca239d
Another solution would be to not rely on the ./
execution syntax (which requires the executable bit to be turned on for the respective file) but instead to explicitly use the shell command:
const path = require('path');
const { execFile } = require('child_process');
describe('cli test', () => {
test('thing', () => {
const myCli = execFile(
`sh ${path.resolve(__dirname, '..')}/cli.js`, ['--foo', 'Bar'],
(err, stdout, stderr) => {
if (err) {
console.log('err: ', err);
}
});
});
Notice the sh
prefix I added to your code, This way you thell the sh
command (which should be available in all of your environments e.g. the CI) to execute the contents of the file, regardless of whether the file itself can be executed or not!
Upvotes: 0