Respect custom VS Code SSH config paths
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / macos-client (macos-aarch64, macos-14) (push) Canceled after 0s
ci / macos-client (macos-x86_64, macos-13) (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / macos-client (macos-aarch64, macos-14) (push) Canceled after 0s
ci / macos-client (macos-x86_64, macos-13) (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s
This commit is contained in:
@@ -86,7 +86,7 @@ async function configureHost() {
|
|||||||
fs.mkdirSync(sshDir, { recursive: true });
|
fs.mkdirSync(sshDir, { recursive: true });
|
||||||
const generatedPath = config.get('generatedSshConfig') || path.join(sshDir, 'config.dosh');
|
const generatedPath = config.get('generatedSshConfig') || path.join(sshDir, 'config.dosh');
|
||||||
const mainConfig = path.join(sshDir, 'config');
|
const mainConfig = path.join(sshDir, 'config');
|
||||||
ensureInclude(mainConfig, path.basename(generatedPath));
|
ensureInclude(mainConfig, sshIncludeTarget(mainConfig, generatedPath, process.platform));
|
||||||
upsertBlock(generatedPath, alias, block);
|
upsertBlock(generatedPath, alias, block);
|
||||||
return { alias, generatedPath };
|
return { alias, generatedPath };
|
||||||
}
|
}
|
||||||
@@ -123,6 +123,18 @@ function ensureInclude(configPath, includeFile) {
|
|||||||
fs.writeFileSync(configPath, `Include ${includeFile}\n${raw ? `\n${raw}` : ''}`);
|
fs.writeFileSync(configPath, `Include ${includeFile}\n${raw ? `\n${raw}` : ''}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sshIncludeTarget(mainConfigPath, generatedPath, platform = process.platform) {
|
||||||
|
const pathApi = platform === 'win32' ? path.win32 : path;
|
||||||
|
const mainDir = pathApi.resolve(pathApi.dirname(mainConfigPath));
|
||||||
|
const generatedAbsolute = pathApi.resolve(mainDir, generatedPath);
|
||||||
|
const generatedDir = pathApi.resolve(pathApi.dirname(generatedAbsolute));
|
||||||
|
const includePath =
|
||||||
|
normalizeCase(generatedDir, platform) === normalizeCase(mainDir, platform)
|
||||||
|
? pathApi.basename(generatedAbsolute)
|
||||||
|
: generatedAbsolute;
|
||||||
|
return sshConfigPathWord(includePath, platform);
|
||||||
|
}
|
||||||
|
|
||||||
function upsertBlock(configPath, alias, block) {
|
function upsertBlock(configPath, alias, block) {
|
||||||
const raw = fs.existsSync(configPath) ? fs.readFileSync(configPath, 'utf8') : '';
|
const raw = fs.existsSync(configPath) ? fs.readFileSync(configPath, 'utf8') : '';
|
||||||
const begin = `# BEGIN DOSH ${alias}`;
|
const begin = `# BEGIN DOSH ${alias}`;
|
||||||
@@ -189,6 +201,18 @@ function sshConfigWord(value, platform = process.platform) {
|
|||||||
return shellQuote(value);
|
return shellQuote(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sshConfigPathWord(value, platform = process.platform) {
|
||||||
|
const normalized = platform === 'win32' ? value.replace(/\\/g, '/') : value;
|
||||||
|
if (/^[a-zA-Z0-9_./:@%+=,-]+$/.test(normalized)) {
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
return `"${normalized.replace(/["\\]/g, '\\$&')}"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeCase(value, platform) {
|
||||||
|
return platform === 'win32' ? value.toLowerCase() : value;
|
||||||
|
}
|
||||||
|
|
||||||
function windowsCommandWord(value) {
|
function windowsCommandWord(value) {
|
||||||
let out = '"';
|
let out = '"';
|
||||||
let backslashes = 0;
|
let backslashes = 0;
|
||||||
@@ -218,7 +242,9 @@ module.exports = {
|
|||||||
activate,
|
activate,
|
||||||
deactivate,
|
deactivate,
|
||||||
sshBlock,
|
sshBlock,
|
||||||
|
sshConfigPathWord,
|
||||||
shellQuote,
|
shellQuote,
|
||||||
|
sshIncludeTarget,
|
||||||
sshConfigWord,
|
sshConfigWord,
|
||||||
windowsCommandWord
|
windowsCommandWord
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ const assert = require('node:assert/strict');
|
|||||||
const {
|
const {
|
||||||
shellQuote,
|
shellQuote,
|
||||||
sshBlock,
|
sshBlock,
|
||||||
|
sshConfigPathWord,
|
||||||
|
sshIncludeTarget,
|
||||||
sshConfigWord,
|
sshConfigWord,
|
||||||
windowsCommandWord
|
windowsCommandWord
|
||||||
} = require('./extension');
|
} = require('./extension');
|
||||||
@@ -48,3 +50,36 @@ test('ssh block quotes proxy command for the target platform', () => {
|
|||||||
);
|
);
|
||||||
assert.doesNotMatch(block, /'C:\\Program Files\\Dosh\\dosh\.exe'/);
|
assert.doesNotMatch(block, /'C:\\Program Files\\Dosh\\dosh\.exe'/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('ssh include target stays relative for generated config beside main config', () => {
|
||||||
|
assert.equal(
|
||||||
|
sshIncludeTarget('/Users/palav/.ssh/config', '/Users/palav/.ssh/config.dosh', 'darwin'),
|
||||||
|
'config.dosh'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ssh include target uses absolute path for custom generated config location', () => {
|
||||||
|
assert.equal(
|
||||||
|
sshIncludeTarget(
|
||||||
|
'/Users/palav/.ssh/config',
|
||||||
|
'/Users/palav/Library/Application Support/Dosh/config.dosh',
|
||||||
|
'darwin'
|
||||||
|
),
|
||||||
|
'"/Users/palav/Library/Application Support/Dosh/config.dosh"'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ssh include target handles Windows custom generated config paths', () => {
|
||||||
|
assert.equal(
|
||||||
|
sshIncludeTarget(
|
||||||
|
'C:\\Users\\palav\\.ssh\\config',
|
||||||
|
'C:\\Users\\palav\\AppData\\Roaming\\Dosh Remote\\config.dosh',
|
||||||
|
'win32'
|
||||||
|
),
|
||||||
|
'"C:/Users/palav/AppData/Roaming/Dosh Remote/config.dosh"'
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
sshConfigPathWord('C:\\Users\\palav\\.ssh\\config.dosh', 'win32'),
|
||||||
|
'C:/Users/palav/.ssh/config.dosh'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user