flecks/packages/repl/build/commands.js
2024-02-04 00:07:54 -06:00

63 lines
1.7 KiB
JavaScript

const {spawn} = require('child_process');
const {readdir} = require('fs/promises');
const {tmpdir} = require('os');
const {join} = require('path');
const {D} = require('@flecks/core/src');
const commandExists = require('command-exists');
const debug = D('@flecks/repl/commands');
module.exports = (program, flecks) => {
const commands = {};
commands.repl = {
options: [
program.createOption('-r, --rlwrap', 'use rlwrap around socat'),
],
description: 'Connect to REPL.',
action: async (opts) => {
const {
rlwrap,
} = opts;
try {
await commandExists('socat');
}
catch (error) {
throw new Error('socat must be installed to use REPL');
}
if (rlwrap) {
try {
await commandExists('rlwrap');
}
catch (error) {
throw new Error('rlwrap must be installed to use --rlwrap');
}
}
const {id} = flecks.get('@flecks/core');
const directory = join(tmpdir(), 'flecks', id, 'repl');
const filenames = await readdir(directory);
const sockets = filenames.filter(
// eslint-disable-next-line no-useless-escape
(filename) => filename.match(new RegExp(`${id}-.*\.sock$`)),
);
const socket = join(
directory,
sockets
.sort((l, r) => (l > r ? -1 : 1))
.shift(),
);
const spawnOptions = {
stdio: 'inherit',
};
const [cmd, args] = (
rlwrap
? ['rlwrap', ['-C', 'qmp', 'socat', 'STDIO', `UNIX:${socket}`]]
: ['socat', ['-', `unix-client:${socket}`]]
);
debug('spawning:\n%s %s', cmd, args.join(' '));
return spawn(cmd, args, spawnOptions);
},
};
return commands;
};