2022-02-25 04:58:08 -06:00
|
|
|
import {spawn} from 'child_process';
|
|
|
|
import {readdir} from 'fs/promises';
|
|
|
|
import {tmpdir} from 'os';
|
|
|
|
import {join} from 'path';
|
|
|
|
|
2022-02-28 10:29:56 -06:00
|
|
|
import {D} from '@flecks/core';
|
2022-02-25 04:58:08 -06:00
|
|
|
import commandExists from 'command-exists';
|
|
|
|
|
|
|
|
const debug = D('@flecks/repl/commands');
|
|
|
|
|
|
|
|
export default (program, flecks) => {
|
|
|
|
const commands = {};
|
|
|
|
commands.repl = {
|
|
|
|
options: [
|
|
|
|
['-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');
|
2022-03-03 11:35:28 -06:00
|
|
|
const directory = join(tmpdir(), 'flecks', id, 'repl');
|
2022-02-25 04:58:08 -06:00
|
|
|
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;
|
|
|
|
};
|