Add `DEBUG_REMOTE_COMMANDS` flag and improve `code` remote command

issue/311
Kelvin Schoofs 3 years ago
parent 30c213ab31
commit 518e246ea1

@ -10,6 +10,7 @@
### Changes
- Proxy hop field now actually lists all known configs to pick from, instead of "TO DO" (#290)
- Remote `code` command (#267) now prompts to create an empty file for non-existing path
- Remote `code` command (#267) now displays a help message when not providing arguments
### Development changes
- Webpack setup has been improved quite a bit, mostly to clean up long ugly paths and make builds deterministic:

@ -382,9 +382,11 @@ function parseFlagList(list: string[] | undefined, origin: string): Record<strin
REMOTE_COMMANDS (boolean) (default=false)
- Enables automatically launching a background command terminal during connection setup
- Enables attempting to inject a file to be sourced by the remote shells (which adds the `code` alias)
DEBUG_REMOTE_COMMANDS (boolean) (default=false)
- Enables debug logging for the remote command terminal (thus useless if REMOTE_COMMANDS isn't true)
*/
export type FlagValue = string | boolean | null;
export type FlagCombo = [value: FlagValue, origin: string];
export type FlagCombo<V extends FlagValue = FlagValue> = [value: V, origin: string];
export const DEFAULT_FLAGS: string[] = [];
let cachedFlags: Record<string, FlagCombo> = {};
function calculateFlags(): Record<string, FlagCombo> {
@ -456,12 +458,12 @@ export function getFlag(target: string, flags?: string[]): FlagCombo | undefined
* @param flags An optional array of flags to check before the global ones
* @returns The matching FlagCombo or `[missingValue, 'missing']` instead
*/
export function getFlagBoolean(target: string, missingValue: boolean, flags?: string[]): FlagCombo {
export function getFlagBoolean(target: string, missingValue: boolean, flags?: string[]): FlagCombo<boolean> {
const combo = getFlag(target, flags);
if (!combo) return [missingValue, 'missing'];
const [value, reason] = combo;
if (value == null) return [true, reason];
if (typeof value === 'boolean') return combo;
if (typeof value === 'boolean') return [value, reason];
const lower = value.toLowerCase();
if (lower === 'true' || lower === 't' || lower === 'yes' || lower === 'y') return [true, reason];
if (lower === 'false' || lower === 'f' || lower === 'no' || lower === 'n') return [false, reason];

@ -37,7 +37,12 @@ if type code > /dev/null 2> /dev/null; then
return 0;
fi
code() {
if [ ! -n "$KELVIN_SSHFS_CMD_PATH" ]; then
if [ "$#" -ne 1 ] || [ $1 = "help" ] || [ $1 = "--help" ] || [ $1 = "-h" ] || [ $1 = "-?" ]; then
echo "Usage:";
echo " code <path_to_existing_file> Will make VS Code open the file";
echo " code <path_to_existing_folder> Will make VS Code add the folder as an additional workspace folder";
echo " code <path_to_nonexisting_file> Will prompt VS Code to create an empty file, then open it afterwards";
elif [ ! -n "$KELVIN_SSHFS_CMD_PATH" ]; then
echo "Not running in a terminal spawned by SSH FS? Failed to sent!"
elif [ -c "$KELVIN_SSHFS_CMD_PATH" ]; then
echo "::sshfs:code:$(pwd):::$1" >> $KELVIN_SSHFS_CMD_PATH;
@ -74,7 +79,7 @@ export class ConnectionManager {
public getPendingConnections(): [string, FileSystemConfig | undefined][] {
return Object.keys(this.pendingConnections).map(name => [name, this.pendingConnections[name][1]]);
}
protected async _createCommandTerminal(client: Client, authority: string): Promise<string> {
protected async _createCommandTerminal(client: Client, authority: string, debugLogging: boolean): Promise<string> {
const logging = Logging.scope(`CmdTerm(${authority})`);
const shell = await toPromise<ClientChannel>(cb => client.shell({}, cb));
shell.write('echo ::sshfs:TTY:$(tty)\n');
@ -83,7 +88,7 @@ export class ConnectionManager {
shell.stdout.once('error', rejectPath);
shell.once('close', () => rejectPath());
rl.on('line', async line => {
// logging.debug('<< ' + line);
if (debugLogging) logging.debug('<< ' + line);
const [, prefix, cmd, args] = line.match(/(.*?)::sshfs:(\w+):(.*)$/) || [];
if (!cmd || prefix.endsWith('echo ')) return;
switch (cmd) {
@ -170,8 +175,10 @@ export class ConnectionManager {
// Set up stuff for receiving remote commands
const [flagRCV, flagRCR] = getFlagBoolean('REMOTE_COMMANDS', false, actualConfig.flags);
if (flagRCV) {
logging.info(`Flag REMOTE_COMMANDS provided in '${flagRCR}', setting up command terminal`);
const cmdPath = await this._createCommandTerminal(client, name);
const [flagRCDV, flagRCDR] = getFlagBoolean('DEBUG_REMOTE_COMMANDS', false, actualConfig.flags);
const withDebugStr = flagRCDV ? ` with debug logging enabled by '${flagRCDR}'` : '';
logging.info(`Flag REMOTE_COMMANDS provided in '${flagRCR}', setting up command terminal${withDebugStr}`);
const cmdPath = await this._createCommandTerminal(client, name, flagRCDV);
environment.push({ key: 'KELVIN_SSHFS_CMD_PATH', value: cmdPath });
const sftp = await toPromise<SFTPWrapper>(cb => client.sftp(cb));
await toPromise(cb => sftp.writeFile('/tmp/.Kelvin_sshfs', TMP_PROFILE_SCRIPT, { mode: 0o666 }, cb));

Loading…
Cancel
Save