style: fix indents (#300)
CI - Master: Build & Lint / check (push) Has been cancelled

This commit is contained in:
Baptiste Augrain
2026-07-01 20:31:00 +02:00
committed by GitHub
parent d8d915b58f
commit 774bb95d55
14 changed files with 525 additions and 517 deletions
+9 -1
View File
@@ -1,7 +1,7 @@
root = true
[*]
indent_style = tab
indent_style = space
tab_width = 4
end_of_line = lf
charset = utf-8
@@ -12,6 +12,10 @@ insert_final_newline = true
indent_style = space
indent_size = 2
[{*.json,.fixpackrc}]
indent_style = tab
indent_size = 4
[*.md]
indent_style = space
indent_size = 4
@@ -20,3 +24,7 @@ indent_size = 4
indent_style = space
indent_size = 2
trim_trailing_whitespace = false
[{*.sh,*.ps1}]
indent_style = space
indent_size = 2
+17 -17
View File
@@ -5,26 +5,26 @@ const path = require('path');
const version = process.argv[2];
try {
const changelog = fs.readFileSync(path.join(process.cwd(), 'CHANGELOG.md'), 'utf8');
const changelog = fs.readFileSync(path.join(process.cwd(), 'CHANGELOG.md'), 'utf8');
// Regular expression to match a version section with the date
// Matches from "## 0.0.48" until the next ## or end of file
const versionRegex = new RegExp(`## ${version.slice(1)}([^#]|#(?!#))*(?=## |$)`, 's');
// Regular expression to match a version section with the date
// Matches from "## 0.0.48" until the next ## or end of file
const versionRegex = new RegExp(`## ${version.slice(1)}([^#]|#(?!#))*(?=## |$)`, 's');
const match = changelog.match(versionRegex);
const match = changelog.match(versionRegex);
if(match) {
// Remove the version header and trim whitespace
const notes = match[0].replace(/^## \d+\.\d+\.\d+\n/, '').trim();
console.log(notes);
process.exit(0);
}
else {
console.error(`No changelog entry found for version ${version}`);
process.exit(1);
}
if(match) {
// Remove the version header and trim whitespace
const notes = match[0].replace(/^## \d+\.\d+\.\d+\n/, '').trim();
console.log(notes);
process.exit(0);
}
else {
console.error(`No changelog entry found for version ${version}`);
process.exit(1);
}
}
catch(error) {
console.error('Error reading CHANGELOG.md:', error);
process.exit(1);
console.error('Error reading CHANGELOG.md:', error);
process.exit(1);
}
+12 -12
View File
@@ -56,21 +56,21 @@ Community Moderators take reports of violations seriously and will make every ef
If an investigation by the Community Moderators finds that this Code of Conduct has been violated, the following enforcement ladder may be used to determine how best to repair harm, based on the incident's impact on the individuals involved and the community as a whole. Depending on the severity of a violation, lower rungs on the ladder may be skipped.
1) Warning
1) Event: A violation involving a single incident or series of incidents.
2) Consequence: A private, written warning from the Community Moderators.
3) Repair: Examples of repair include a private written apology, acknowledgement of responsibility, and seeking clarification on expectations.
1) Event: A violation involving a single incident or series of incidents.
2) Consequence: A private, written warning from the Community Moderators.
3) Repair: Examples of repair include a private written apology, acknowledgement of responsibility, and seeking clarification on expectations.
2) Temporarily Limited Activities
1) Event: A repeated incidence of a violation that previously resulted in a warning, or the first incidence of a more serious violation.
2) Consequence: A private, written warning with a time-limited cooldown period designed to underscore the seriousness of the situation and give the community members involved time to process the incident. The cooldown period may be limited to particular communication channels or interactions with particular community members.
3) Repair: Examples of repair may include making an apology, using the cooldown period to reflect on actions and impact, and being thoughtful about re-entering community spaces after the period is over.
1) Event: A repeated incidence of a violation that previously resulted in a warning, or the first incidence of a more serious violation.
2) Consequence: A private, written warning with a time-limited cooldown period designed to underscore the seriousness of the situation and give the community members involved time to process the incident. The cooldown period may be limited to particular communication channels or interactions with particular community members.
3) Repair: Examples of repair may include making an apology, using the cooldown period to reflect on actions and impact, and being thoughtful about re-entering community spaces after the period is over.
3) Temporary Suspension
1) Event: A pattern of repeated violation which the Community Moderators have tried to address with warnings, or a single serious violation.
2) Consequence: A private written warning with conditions for return from suspension. In general, temporary suspensions give the person being suspended time to reflect upon their behavior and possible corrective actions.
3) Repair: Examples of repair include respecting the spirit of the suspension, meeting the specified conditions for return, and being thoughtful about how to reintegrate with the community when the suspension is lifted.
1) Event: A pattern of repeated violation which the Community Moderators have tried to address with warnings, or a single serious violation.
2) Consequence: A private written warning with conditions for return from suspension. In general, temporary suspensions give the person being suspended time to reflect upon their behavior and possible corrective actions.
3) Repair: Examples of repair include respecting the spirit of the suspension, meeting the specified conditions for return, and being thoughtful about how to reintegrate with the community when the suspension is lifted.
4) Permanent Ban
1) Event: A pattern of repeated code of conduct violations that other steps on the ladder have failed to resolve, or a violation so serious that the Community Moderators determine there is no way to keep the community safe with this person as a member.
2) Consequence: Access to all community spaces, tools, and communication channels is removed. In general, permanent bans should be rarely used, should have strong reasoning behind them, and should only be resorted to if working through other remedies has failed to change the behavior.
3) Repair: There is no possible repair in cases of this severity.
1) Event: A pattern of repeated code of conduct violations that other steps on the ladder have failed to resolve, or a violation so serious that the Community Moderators determine there is no way to keep the community safe with this person as a member.
2) Consequence: Access to all community spaces, tools, and communication channels is removed. In general, permanent bans should be rarely used, should have strong reasoning behind them, and should only be resorted to if working through other remedies has failed to change the behavior.
3) Repair: There is no possible repair in cases of this severity.
This enforcement ladder is intended as a guideline. It does not limit the ability of Community Managers to use their discretion and judgment, in keeping with the best interests of our community.
+2 -2
View File
@@ -434,7 +434,7 @@ export class RemoteSSHResolver implements vscode.RemoteAuthorityResolver, vscode
}
if (!await fileExists(identityKey.filename)) {
// Try next identity file
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return callback(null as any);
}
@@ -457,7 +457,7 @@ export class RemoteSSHResolver implements vscode.RemoteAuthorityResolver, vscode
}
if (!result || result instanceof Error) {
// Try next identity file
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return callback(null as any);
}
+26 -26
View File
@@ -1,37 +1,37 @@
import * as vscode from 'vscode';
export function disposeAll(disposables: vscode.Disposable[]): void {
while (disposables.length) {
const item = disposables.pop();
if (item) {
item.dispose();
}
}
while (disposables.length) {
const item = disposables.pop();
if (item) {
item.dispose();
}
}
}
export abstract class Disposable {
private _isDisposed = false;
private _isDisposed = false;
protected _disposables: vscode.Disposable[] = [];
protected _disposables: vscode.Disposable[] = [];
public dispose(): void {
if (this._isDisposed) {
return;
}
this._isDisposed = true;
disposeAll(this._disposables);
}
public dispose(): void {
if (this._isDisposed) {
return;
}
this._isDisposed = true;
disposeAll(this._disposables);
}
protected _register<T extends vscode.Disposable>(value: T): T {
if (this._isDisposed) {
value.dispose();
} else {
this._disposables.push(value);
}
return value;
}
protected _register<T extends vscode.Disposable>(value: T): T {
if (this._isDisposed) {
value.dispose();
} else {
this._disposables.push(value);
}
return value;
}
protected get isDisposed(): boolean {
return this._isDisposed;
}
protected get isDisposed(): boolean {
return this._isDisposed;
}
}
+1 -1
View File
@@ -13,7 +13,7 @@ export async function exists(path: string) {
}
export function untildify(path: string){
return path.replace(/^~(?=$|\/|\\)/, homeDir);
return path.replace(/^~(?=$|\/|\\)/, homeDir);
}
export function normalizeToSlash(path: string) {
+44 -44
View File
@@ -5,63 +5,63 @@ import { inspect } from 'node:util';
type LogLevel = 'Trace' | 'Info' | 'Error';
export default class Log {
private output: vscode.OutputChannel;
private output: vscode.OutputChannel;
constructor(name: string) {
this.output = vscode.window.createOutputChannel(name);
}
constructor(name: string) {
this.output = vscode.window.createOutputChannel(name);
}
public trace(message: string, data?: unknown): void {
this.logLevel('Trace', message, data);
}
public trace(message: string, data?: unknown): void {
this.logLevel('Trace', message, data);
}
public info(message: string, data?: unknown): void {
this.logLevel('Info', message, data);
}
public info(message: string, data?: unknown): void {
this.logLevel('Info', message, data);
}
public error(message: string, data?: unknown): void {
this.logLevel('Error', message, data);
}
public error(message: string, data?: unknown): void {
this.logLevel('Error', message, data);
}
public logLevel(level: LogLevel, message: string, data?: unknown): void {
this.output.appendLine(`[${level} - ${this.now()}] ${message}`);
if (data) {
this.output.appendLine(toString(data));
}
}
public logLevel(level: LogLevel, message: string, data?: unknown): void {
this.output.appendLine(`[${level} - ${this.now()}] ${message}`);
if (data) {
this.output.appendLine(toString(data));
}
}
private now(): string {
const now = new Date();
return padLeft(now.getUTCHours() + '', 2, '0')
+ ':' + padLeft(now.getMinutes() + '', 2, '0')
+ ':' + padLeft(now.getUTCSeconds() + '', 2, '0') + '.' + now.getMilliseconds();
}
private now(): string {
const now = new Date();
return padLeft(now.getUTCHours() + '', 2, '0')
+ ':' + padLeft(now.getMinutes() + '', 2, '0')
+ ':' + padLeft(now.getUTCSeconds() + '', 2, '0') + '.' + now.getMilliseconds();
}
public show() {
this.output.show();
}
public show() {
this.output.show();
}
public dispose() {
this.output.dispose();
}
public dispose() {
this.output.dispose();
}
}
function padLeft(s: string, n: number, pad = ' ') {
return pad.repeat(Math.max(0, n - s.length)) + s;
return pad.repeat(Math.max(0, n - s.length)) + s;
}
function toString(value: unknown): string {
if (isPrimitive(value)) {
return `${value}`;
}
else if (value instanceof Error) {
return value.stack || value.message;
}
else if (isRecord(value)) {
if (value.success === false && isString(value.message)) {
return value.message;
}
}
if (isPrimitive(value)) {
return `${value}`;
}
else if (value instanceof Error) {
return value.stack || value.message;
}
else if (isRecord(value)) {
if (value.success === false && isString(value.message)) {
return value.message;
}
}
return inspect(value, { depth: null, compact: true, breakLength: Infinity });
return inspect(value, { depth: null, compact: true, breakLength: Infinity });
}
+92 -92
View File
@@ -5,15 +5,15 @@ import * as net from 'net';
* Finds a random unused port assigned by the operating system. Will reject in case no free port can be found.
*/
export function findRandomPort(): Promise<number> {
return new Promise((resolve, reject) => {
const server = net.createServer({ pauseOnConnect: true });
server.on('error', reject);
server.on('listening', () => {
const port = (server.address() as net.AddressInfo).port;
server.close(() => resolve(port));
});
server.listen(0, '127.0.0.1');
});
return new Promise((resolve, reject) => {
const server = net.createServer({ pauseOnConnect: true });
server.on('error', reject);
server.on('listening', () => {
const port = (server.address() as net.AddressInfo).port;
server.close(() => resolve(port));
});
server.listen(0, '127.0.0.1');
});
}
/**
@@ -21,110 +21,110 @@ export function findRandomPort(): Promise<number> {
* is openable. Will return 0 in case no free port can be found.
*/
export function findFreePort(startPort: number, giveUpAfter: number, timeout: number, stride = 1): Promise<number> {
let done = false;
let done = false;
return new Promise(resolve => {
const timeoutHandle = setTimeout(() => {
if (!done) {
done = true;
return resolve(0);
}
}, timeout);
return new Promise(resolve => {
const timeoutHandle = setTimeout(() => {
if (!done) {
done = true;
return resolve(0);
}
}, timeout);
doFindFreePort(startPort, giveUpAfter, stride, (port) => {
if (!done) {
done = true;
clearTimeout(timeoutHandle);
return resolve(port);
}
});
});
doFindFreePort(startPort, giveUpAfter, stride, (port) => {
if (!done) {
done = true;
clearTimeout(timeoutHandle);
return resolve(port);
}
});
});
}
function doFindFreePort(startPort: number, giveUpAfter: number, stride: number, clb: (port: number) => void): void {
if (giveUpAfter === 0) {
return clb(0);
}
if (giveUpAfter === 0) {
return clb(0);
}
const client = new net.Socket();
const client = new net.Socket();
// If we can connect to the port it means the port is already taken so we continue searching
client.once('connect', () => {
dispose(client);
// If we can connect to the port it means the port is already taken so we continue searching
client.once('connect', () => {
dispose(client);
return doFindFreePort(startPort + stride, giveUpAfter - 1, stride, clb);
});
return doFindFreePort(startPort + stride, giveUpAfter - 1, stride, clb);
});
client.once('data', () => {
// this listener is required since node.js 8.x
});
client.once('data', () => {
// this listener is required since node.js 8.x
});
client.once('error', (err: Error & { code?: string }) => {
dispose(client);
client.once('error', (err: Error & { code?: string }) => {
dispose(client);
// If we receive any non ECONNREFUSED error, it means the port is used but we cannot connect
if (err.code !== 'ECONNREFUSED') {
return doFindFreePort(startPort + stride, giveUpAfter - 1, stride, clb);
}
// If we receive any non ECONNREFUSED error, it means the port is used but we cannot connect
if (err.code !== 'ECONNREFUSED') {
return doFindFreePort(startPort + stride, giveUpAfter - 1, stride, clb);
}
// Otherwise it means the port is free to use!
return clb(startPort);
});
// Otherwise it means the port is free to use!
return clb(startPort);
});
client.connect(startPort, '127.0.0.1');
client.connect(startPort, '127.0.0.1');
}
/**
* Uses listen instead of connect. Is faster, but if there is another listener on 0.0.0.0 then this will take 127.0.0.1 from that listener.
*/
export function findFreePortFaster(startPort: number, giveUpAfter: number, timeout: number): Promise<number> {
let resolved = false;
let timeoutHandle: NodeJS.Timeout | undefined = undefined;
let countTried = 1;
const server = net.createServer({ pauseOnConnect: true });
function doResolve(port: number, resolve: (port: number) => void) {
if (!resolved) {
resolved = true;
server.removeAllListeners();
server.close();
if (timeoutHandle) {
clearTimeout(timeoutHandle);
}
resolve(port);
}
}
return new Promise<number>(resolve => {
timeoutHandle = setTimeout(() => {
doResolve(0, resolve);
}, timeout);
let resolved = false;
let timeoutHandle: NodeJS.Timeout | undefined = undefined;
let countTried = 1;
const server = net.createServer({ pauseOnConnect: true });
function doResolve(port: number, resolve: (port: number) => void) {
if (!resolved) {
resolved = true;
server.removeAllListeners();
server.close();
if (timeoutHandle) {
clearTimeout(timeoutHandle);
}
resolve(port);
}
}
return new Promise<number>(resolve => {
timeoutHandle = setTimeout(() => {
doResolve(0, resolve);
}, timeout);
server.on('listening', () => {
doResolve(startPort, resolve);
});
server.on('error', err => {
if (isNodeError(err) && (err.code === 'EADDRINUSE' || err.code === 'EACCES') && (countTried < giveUpAfter)) {
startPort++;
countTried++;
server.listen(startPort, '127.0.0.1');
} else {
doResolve(0, resolve);
}
});
server.on('close', () => {
doResolve(0, resolve);
});
server.listen(startPort, '127.0.0.1');
});
server.on('listening', () => {
doResolve(startPort, resolve);
});
server.on('error', err => {
if (isNodeError(err) && (err.code === 'EADDRINUSE' || err.code === 'EACCES') && (countTried < giveUpAfter)) {
startPort++;
countTried++;
server.listen(startPort, '127.0.0.1');
} else {
doResolve(0, resolve);
}
});
server.on('close', () => {
doResolve(0, resolve);
});
server.listen(startPort, '127.0.0.1');
});
}
function dispose(socket: net.Socket): void {
try {
socket.removeAllListeners('connect');
socket.removeAllListeners('error');
socket.end();
socket.destroy();
socket.unref();
} catch (error) {
console.error(error); // otherwise this error would get lost in the callback chain
}
try {
socket.removeAllListeners('connect');
socket.removeAllListeners('error');
socket.end();
socket.destroy();
socket.unref();
} catch (error) {
console.error(error); // otherwise this error would get lost in the callback chain
}
}
+97 -97
View File
@@ -29,166 +29,166 @@ $ARCH=
$PLATFORM="win32"
function printInstallResults($code) {
"%%SCRIPT_ID%%: start"
"exitCode==$code=="
"listeningOn==$LISTENING_ON=="
"connectionToken==$SERVER_CONNECTION_TOKEN=="
"logFile==$SERVER_LOGFILE=="
"osReleaseId==$OS_RELEASE_ID=="
"arch==$ARCH=="
"platform==$PLATFORM=="
"tmpDir==$TMP_DIR=="
"%%SCRIPT_ID%%: start"
"exitCode==$code=="
"listeningOn==$LISTENING_ON=="
"connectionToken==$SERVER_CONNECTION_TOKEN=="
"logFile==$SERVER_LOGFILE=="
"osReleaseId==$OS_RELEASE_ID=="
"arch==$ARCH=="
"platform==$PLATFORM=="
"tmpDir==$TMP_DIR=="
%%ENV_VAR_LINES%%
"%%SCRIPT_ID%%: end"
"%%SCRIPT_ID%%: end"
}
# Check machine architecture
$ARCH=$env:PROCESSOR_ARCHITECTURE
# Use x64 version for ARM64, as it's not yet available.
if(($ARCH -eq "AMD64") -or ($ARCH -eq "IA64") -or ($ARCH -eq "ARM64")) {
$SERVER_ARCH="x64"
$SERVER_ARCH="x64"
}
else {
"Error architecture not supported: $ARCH"
printInstallResults 1
exit 0
"Error architecture not supported: $ARCH"
printInstallResults 1
exit 0
}
# Create installation folder
if(!(Test-Path $SERVER_DIR)) {
try {
ni -it d $SERVER_DIR -f -ea si
} catch {
"Error creating server install directory - $($_.ToString())"
exit 1
}
try {
ni -it d $SERVER_DIR -f -ea si
} catch {
"Error creating server install directory - $($_.ToString())"
exit 1
}
if(!(Test-Path $SERVER_DIR)) {
"Error creating server install directory"
exit 1
}
if(!(Test-Path $SERVER_DIR)) {
"Error creating server install directory"
exit 1
}
}
cd $SERVER_DIR
# Check if server script is already installed
if(!(Test-Path $SERVER_SCRIPT)) {
del vscode-server.tar.gz
$REQUEST_ARGUMENTS = @{
Uri="$SERVER_DOWNLOAD_URL"
TimeoutSec=20
OutFile="vscode-server.tar.gz"
UseBasicParsing=$True
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-RestMethod @REQUEST_ARGUMENTS
if(Test-Path "vscode-server.tar.gz") {
tar -xf vscode-server.tar.gz --strip-components 1
del vscode-server.tar.gz
}
$REQUEST_ARGUMENTS = @{
Uri="$SERVER_DOWNLOAD_URL"
TimeoutSec=20
OutFile="vscode-server.tar.gz"
UseBasicParsing=$True
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-RestMethod @REQUEST_ARGUMENTS
if(Test-Path "vscode-server.tar.gz") {
tar -xf vscode-server.tar.gz --strip-components 1
del vscode-server.tar.gz
}
if(!(Test-Path $SERVER_SCRIPT)) {
"Error while installing the server binary"
exit 1
}
if(!(Test-Path $SERVER_SCRIPT)) {
"Error while installing the server binary"
exit 1
}
}
else {
"Server script already installed in $SERVER_SCRIPT"
"Server script already installed in $SERVER_SCRIPT"
}
# Modify the commit in the remote server to match the local value
if(%%MODIFY_PRODUCT_JSON%%) {
echo "Will modify product.json on remote to match the commit value"
(Get-Content -Raw "$SERVER_DIR\product.json") -replace '"commit": "[0-9a-f]+",', ('"commit": "' + $DISTRO_COMMIT + '",') |
Set-Content -NoNewLine "$SERVER_DIR\product.json"
echo "Will modify product.json on remote to match the commit value"
(Get-Content -Raw "$SERVER_DIR\product.json") -replace '"commit": "[0-9a-f]+",', ('"commit": "' + $DISTRO_COMMIT + '",') |
Set-Content -NoNewLine "$SERVER_DIR\product.json"
}
# Try to find if server is already running
if(Get-Process node -ErrorAction SilentlyContinue | Where-Object Path -Like "$SERVER_DIR\*") {
echo "Server script is already running $SERVER_SCRIPT"
echo "Server script is already running $SERVER_SCRIPT"
}
else {
if(Test-Path $SERVER_LOGFILE) {
del $SERVER_LOGFILE
}
if(Test-Path $SERVER_PIDFILE) {
del $SERVER_PIDFILE
}
if(Test-Path $SERVER_TOKENFILE) {
del $SERVER_TOKENFILE
}
if(Test-Path $SERVER_LOGFILE) {
del $SERVER_LOGFILE
}
if(Test-Path $SERVER_PIDFILE) {
del $SERVER_PIDFILE
}
if(Test-Path $SERVER_TOKENFILE) {
del $SERVER_TOKENFILE
}
$SERVER_CONNECTION_TOKEN="%%SERVER_CONNECTION_TOKEN%%"
[System.IO.File]::WriteAllLines($SERVER_TOKENFILE, $SERVER_CONNECTION_TOKEN)
$SERVER_CONNECTION_TOKEN="%%SERVER_CONNECTION_TOKEN%%"
[System.IO.File]::WriteAllLines($SERVER_TOKENFILE, $SERVER_CONNECTION_TOKEN)
$SCRIPT_ARGUMENTS="--start-server --host=127.0.0.1 $SERVER_LISTEN_FLAG $SERVER_DATA_DIR_FLAG $SERVER_VALIDATION_FLAG $SERVER_INITIAL_EXTENSIONS --connection-token-file $SERVER_TOKENFILE --telemetry-level off --enable-remote-auto-shutdown --accept-server-license-terms *> '$SERVER_LOGFILE'"
$SCRIPT_ARGUMENTS="--start-server --host=127.0.0.1 $SERVER_LISTEN_FLAG $SERVER_DATA_DIR_FLAG $SERVER_VALIDATION_FLAG $SERVER_INITIAL_EXTENSIONS --connection-token-file $SERVER_TOKENFILE --telemetry-level off --enable-remote-auto-shutdown --accept-server-license-terms *> '$SERVER_LOGFILE'"
$START_ARGUMENTS = @{
FilePath = "powershell.exe"
WindowStyle = "hidden"
ArgumentList = @(
"-ExecutionPolicy", "Unrestricted", "-NoLogo", "-NoProfile", "-NonInteractive", "-c", "$SERVER_SCRIPT $SCRIPT_ARGUMENTS"
)
PassThru = $True
}
$START_ARGUMENTS = @{
FilePath = "powershell.exe"
WindowStyle = "hidden"
ArgumentList = @(
"-ExecutionPolicy", "Unrestricted", "-NoLogo", "-NoProfile", "-NonInteractive", "-c", "$SERVER_SCRIPT $SCRIPT_ARGUMENTS"
)
PassThru = $True
}
$SERVER_ID = (start @START_ARGUMENTS).ID
$SERVER_ID = (start @START_ARGUMENTS).ID
if($SERVER_ID) {
[System.IO.File]::WriteAllLines($SERVER_PIDFILE, $SERVER_ID)
}
if($SERVER_ID) {
[System.IO.File]::WriteAllLines($SERVER_PIDFILE, $SERVER_ID)
}
}
if(Test-Path $SERVER_TOKENFILE) {
$SERVER_CONNECTION_TOKEN="$(cat $SERVER_TOKENFILE)"
$SERVER_CONNECTION_TOKEN="$(cat $SERVER_TOKENFILE)"
}
else {
"Error server token file not found $SERVER_TOKENFILE"
printInstallResults 1
exit 0
"Error server token file not found $SERVER_TOKENFILE"
printInstallResults 1
exit 0
}
sleep -Milliseconds 500
$SELECT_ARGUMENTS = @{
Path = $SERVER_LOGFILE
Pattern = "Extension host agent listening on (\d+)"
Path = $SERVER_LOGFILE
Pattern = "Extension host agent listening on (\d+)"
}
for($I = 1; $I -le 5; $I++) {
if(Test-Path $SERVER_LOGFILE) {
$GROUPS = (Select-String @SELECT_ARGUMENTS).Matches.Groups
if(Test-Path $SERVER_LOGFILE) {
$GROUPS = (Select-String @SELECT_ARGUMENTS).Matches.Groups
if($GROUPS) {
$LISTENING_ON = $GROUPS[1].Value
break
}
if($GROUPS) {
$LISTENING_ON = $GROUPS[1].Value
break
}
}
sleep -Milliseconds 500
sleep -Milliseconds 500
}
if(!(Test-Path $SERVER_LOGFILE)) {
"Error server log file not found $SERVER_LOGFILE"
printInstallResults 1
exit 0
"Error server log file not found $SERVER_LOGFILE"
printInstallResults 1
exit 0
}
# Finish server setup
printInstallResults 0
if($SERVER_ID) {
while($True) {
if(!(gps -Id $SERVER_ID)) {
"server died, exit"
exit 0
}
sleep 30
while($True) {
if(!(gps -Id $SERVER_ID)) {
"server died, exit"
exit 0
}
sleep 30
}
}
+145 -145
View File
@@ -29,18 +29,18 @@ PLATFORM=
# Mimic output from logs of remote-ssh extension
print_install_results_and_exit() {
echo "%%SCRIPT_ID%%: start"
echo "exitCode==$1=="
echo "listeningOn==$LISTENING_ON=="
echo "connectionToken==$SERVER_CONNECTION_TOKEN=="
echo "logFile==$SERVER_LOGFILE=="
echo "osReleaseId==$OS_RELEASE_ID=="
echo "arch==$ARCH=="
echo "platform==$PLATFORM=="
echo "tmpDir==$TMP_DIR=="
echo "%%SCRIPT_ID%%: start"
echo "exitCode==$1=="
echo "listeningOn==$LISTENING_ON=="
echo "connectionToken==$SERVER_CONNECTION_TOKEN=="
echo "logFile==$SERVER_LOGFILE=="
echo "osReleaseId==$OS_RELEASE_ID=="
echo "arch==$ARCH=="
echo "platform==$PLATFORM=="
echo "tmpDir==$TMP_DIR=="
%%ENV_VAR_LINES%%
echo "%%SCRIPT_ID%%: end"
exit 0
echo "%%SCRIPT_ID%%: end"
exit 0
}
LOCKFILE="$TMP_DIR/server_install.lock"
@@ -51,204 +51,204 @@ if command -v flock >/dev/null 2>&1; then
flock -x -w 30 $FD || print_install_results_and_exit 1
trap "flock -u $FD; trap - EXIT INT HUP; exit" EXIT INT HUP
else
echo "Warning: flock not available, skipping install lock" >&2
echo "Warning: flock not available, skipping install lock" >&2
fi
# Check if platform is supported
if ! command -v uname; then
echo "Error 'uname' command not found, could not get platform/arch data."
print_install_results_and_exit 1
echo "Error 'uname' command not found, could not get platform/arch data."
print_install_results_and_exit 1
fi
KERNEL="$(uname -s)"
case $KERNEL in
Darwin)
PLATFORM="darwin"
;;
Linux)
PLATFORM="linux"
;;
FreeBSD)
PLATFORM="freebsd"
;;
DragonFly)
PLATFORM="dragonfly"
;;
"")
echo "Error uname -s yields empty result"
print_install_results_and_exit 1
;;
*)
echo "Error platform not supported: $KERNEL"
print_install_results_and_exit 1
;;
Darwin)
PLATFORM="darwin"
;;
Linux)
PLATFORM="linux"
;;
FreeBSD)
PLATFORM="freebsd"
;;
DragonFly)
PLATFORM="dragonfly"
;;
"")
echo "Error uname -s yields empty result"
print_install_results_and_exit 1
;;
*)
echo "Error platform not supported: $KERNEL"
print_install_results_and_exit 1
;;
esac
# Check machine architecture
ARCH="$(uname -m)"
case $ARCH in
x86_64 | amd64)
SERVER_ARCH="x64"
;;
armv7l | armv8l)
SERVER_ARCH="armhf"
;;
arm64 | aarch64)
SERVER_ARCH="arm64"
;;
ppc64le)
SERVER_ARCH="ppc64le"
;;
riscv64)
SERVER_ARCH="riscv64"
;;
loongarch64)
SERVER_ARCH="loong64"
;;
s390x)
SERVER_ARCH="s390x"
;;
*)
echo "Error architecture not supported: $ARCH"
print_install_results_and_exit 1
;;
x86_64 | amd64)
SERVER_ARCH="x64"
;;
armv7l | armv8l)
SERVER_ARCH="armhf"
;;
arm64 | aarch64)
SERVER_ARCH="arm64"
;;
ppc64le)
SERVER_ARCH="ppc64le"
;;
riscv64)
SERVER_ARCH="riscv64"
;;
loongarch64)
SERVER_ARCH="loong64"
;;
s390x)
SERVER_ARCH="s390x"
;;
*)
echo "Error architecture not supported: $ARCH"
print_install_results_and_exit 1
;;
esac
# https://www.freedesktop.org/software/systemd/man/os-release.html
OS_RELEASE_ID="$(grep -i '^ID=' /etc/os-release 2>/dev/null | sed 's/^ID=//gi' | sed 's/"//g')"
if [[ -z $OS_RELEASE_ID ]]; then
OS_RELEASE_ID="$(grep -i '^ID=' /usr/lib/os-release 2>/dev/null | sed 's/^ID=//gi' | sed 's/"//g')"
if [[ -z $OS_RELEASE_ID ]]; then
OS_RELEASE_ID="unknown"
fi
OS_RELEASE_ID="$(grep -i '^ID=' /usr/lib/os-release 2>/dev/null | sed 's/^ID=//gi' | sed 's/"//g')"
if [[ -z $OS_RELEASE_ID ]]; then
OS_RELEASE_ID="unknown"
fi
fi
# Create installation folder
if [[ ! -d $SERVER_DIR ]]; then
mkdir -p $SERVER_DIR
if (( $? > 0 )); then
echo "Error creating server install directory"
print_install_results_and_exit 1
fi
mkdir -p $SERVER_DIR
if (( $? > 0 )); then
echo "Error creating server install directory"
print_install_results_and_exit 1
fi
fi
# adjust platform for vscodium download, if needed
if [[ $OS_RELEASE_ID = alpine ]]; then
PLATFORM=$OS_RELEASE_ID
PLATFORM=$OS_RELEASE_ID
fi
SERVER_DOWNLOAD_URL="$(echo "%%SERVER_DOWNLOAD_URL_TEMPLATE%%" | sed "s/\${quality}/$DISTRO_QUALITY/g" | sed "s/\${version}/$DISTRO_VERSION/g" | sed "s/\${commit}/$DISTRO_COMMIT/g" | sed "s/\${os}/$PLATFORM/g" | sed "s/\${arch}/$SERVER_ARCH/g" | sed "s/\${release}/$DISTRO_VSCODIUM_RELEASE/g")"
# Check if server script is already installed
if [[ ! -f $SERVER_SCRIPT ]]; then
case "$PLATFORM" in
darwin | linux | alpine | freebsd )
;;
*)
echo "Error '$PLATFORM' needs manual installation of remote extension host"
print_install_results_and_exit 1
;;
esac
case "$PLATFORM" in
darwin | linux | alpine | freebsd )
;;
*)
echo "Error '$PLATFORM' needs manual installation of remote extension host"
print_install_results_and_exit 1
;;
esac
pushd $SERVER_DIR > /dev/null
pushd $SERVER_DIR > /dev/null
if command -v wget >/dev/null 2>&1; then
wget --tries=3 --timeout=10 --continue --no-verbose -O vscode-server.tar.gz $SERVER_DOWNLOAD_URL
elif command -v curl >/dev/null 2>&1; then
curl --retry 3 --connect-timeout 10 --location --show-error --silent --output vscode-server.tar.gz $SERVER_DOWNLOAD_URL
elif command -v fetch >/dev/null 2>&1; then
fetch --retry --timeout=10 --quiet --output=vscode-server.tar.gz $SERVER_DOWNLOAD_URL
else
echo "Error no tool to download server binary"
print_install_results_and_exit 1
fi
if command -v wget >/dev/null 2>&1; then
wget --tries=3 --timeout=10 --continue --no-verbose -O vscode-server.tar.gz $SERVER_DOWNLOAD_URL
elif command -v curl >/dev/null 2>&1; then
curl --retry 3 --connect-timeout 10 --location --show-error --silent --output vscode-server.tar.gz $SERVER_DOWNLOAD_URL
elif command -v fetch >/dev/null 2>&1; then
fetch --retry --timeout=10 --quiet --output=vscode-server.tar.gz $SERVER_DOWNLOAD_URL
else
echo "Error no tool to download server binary"
print_install_results_and_exit 1
fi
if (( $? > 0 )); then
echo "Error downloading server from $SERVER_DOWNLOAD_URL"
rm -rf vscode-server.tar.gz
print_install_results_and_exit 1
fi
if (( $? > 0 )); then
echo "Error downloading server from $SERVER_DOWNLOAD_URL"
rm -rf vscode-server.tar.gz
print_install_results_and_exit 1
fi
tar -xf vscode-server.tar.gz --strip-components 1
if (( $? > 0 )); then
echo "Error while extracting server contents"
rm -rf vscode-server.tar.gz
print_install_results_and_exit 1
fi
tar -xf vscode-server.tar.gz --strip-components 1
if (( $? > 0 )); then
echo "Error while extracting server contents"
rm -rf vscode-server.tar.gz
print_install_results_and_exit 1
fi
if [[ ! -f $SERVER_SCRIPT ]]; then
rm -rf $SERVER_DIR/*
echo "Error server contents are corrupted"
print_install_results_and_exit 1
fi
if [[ ! -f $SERVER_SCRIPT ]]; then
rm -rf $SERVER_DIR/*
echo "Error server contents are corrupted"
print_install_results_and_exit 1
fi
rm -f vscode-server.tar.gz
rm -f vscode-server.tar.gz
popd > /dev/null
popd > /dev/null
else
echo "Server script already installed in $SERVER_SCRIPT"
echo "Server script already installed in $SERVER_SCRIPT"
fi
# Modify the commit in the remote server to match the local value
if %%MODIFY_PRODUCT_JSON%%; then
if command -v sed >/dev/null 2>&1; then
echo "Will modify product.json on remote to match the commit value"
sed -i -E 's/"commit": "[0-9a-f]+",/"commit": "'"$DISTRO_COMMIT"'",/' "$SERVER_DIR/product.json";
else
echo "Cannot find the 'sed' command, make sure it is installed to modify product.json with the matching commit."
fi
if command -v sed >/dev/null 2>&1; then
echo "Will modify product.json on remote to match the commit value"
sed -i -E 's/"commit": "[0-9a-f]+",/"commit": "'"$DISTRO_COMMIT"'",/' "$SERVER_DIR/product.json";
else
echo "Cannot find the 'sed' command, make sure it is installed to modify product.json with the matching commit."
fi
fi
# Try to find if server is already running
if [[ -f $SERVER_PIDFILE ]]; then
SERVER_PID="$(cat $SERVER_PIDFILE)"
SERVER_RUNNING_PROCESS="$(ps -o pid,args -p $SERVER_PID | grep $SERVER_SCRIPT)"
SERVER_PID="$(cat $SERVER_PIDFILE)"
SERVER_RUNNING_PROCESS="$(ps -o pid,args -p $SERVER_PID | grep $SERVER_SCRIPT)"
else
SERVER_RUNNING_PROCESS="$(ps -o pid,args -A | grep $SERVER_SCRIPT | grep -v grep)"
SERVER_RUNNING_PROCESS="$(ps -o pid,args -A | grep $SERVER_SCRIPT | grep -v grep)"
fi
if [[ -z $SERVER_RUNNING_PROCESS ]]; then
if [[ -f $SERVER_LOGFILE ]]; then
rm $SERVER_LOGFILE
fi
if [[ -f $SERVER_TOKENFILE ]]; then
rm $SERVER_TOKENFILE
fi
if [[ -f $SERVER_LOGFILE ]]; then
rm $SERVER_LOGFILE
fi
if [[ -f $SERVER_TOKENFILE ]]; then
rm $SERVER_TOKENFILE
fi
touch $SERVER_TOKENFILE
chmod 600 $SERVER_TOKENFILE
SERVER_CONNECTION_TOKEN="%%SERVER_CONNECTION_TOKEN%%"
echo $SERVER_CONNECTION_TOKEN > $SERVER_TOKENFILE
touch $SERVER_TOKENFILE
chmod 600 $SERVER_TOKENFILE
SERVER_CONNECTION_TOKEN="%%SERVER_CONNECTION_TOKEN%%"
echo $SERVER_CONNECTION_TOKEN > $SERVER_TOKENFILE
$SERVER_SCRIPT --start-server --host=127.0.0.1 $SERVER_LISTEN_FLAG $SERVER_DATA_DIR_FLAG $SERVER_VALIDATION_FLAG $SERVER_INITIAL_EXTENSIONS --connection-token-file $SERVER_TOKENFILE --telemetry-level off --enable-remote-auto-shutdown --accept-server-license-terms &> $SERVER_LOGFILE &
echo $! > $SERVER_PIDFILE
$SERVER_SCRIPT --start-server --host=127.0.0.1 $SERVER_LISTEN_FLAG $SERVER_DATA_DIR_FLAG $SERVER_VALIDATION_FLAG $SERVER_INITIAL_EXTENSIONS --connection-token-file $SERVER_TOKENFILE --telemetry-level off --enable-remote-auto-shutdown --accept-server-license-terms &> $SERVER_LOGFILE &
echo $! > $SERVER_PIDFILE
else
echo "Server script is already running $SERVER_SCRIPT"
echo "Server script is already running $SERVER_SCRIPT"
fi
if [[ -f $SERVER_TOKENFILE ]]; then
SERVER_CONNECTION_TOKEN="$(cat $SERVER_TOKENFILE)"
SERVER_CONNECTION_TOKEN="$(cat $SERVER_TOKENFILE)"
else
echo "Error server token file not found $SERVER_TOKENFILE"
print_install_results_and_exit 1
echo "Error server token file not found $SERVER_TOKENFILE"
print_install_results_and_exit 1
fi
if [[ -f $SERVER_LOGFILE ]]; then
for i in {1..35}; do
LISTENING_ON="$(cat $SERVER_LOGFILE | grep -E 'Extension host agent listening on .+' | sed 's/Extension host agent listening on //')"
if [[ -n $LISTENING_ON ]]; then
break
fi
sleep 0.5
done
if [[ -z $LISTENING_ON ]]; then
echo "Error server did not start successfully"
print_install_results_and_exit 1
for i in {1..35}; do
LISTENING_ON="$(cat $SERVER_LOGFILE | grep -E 'Extension host agent listening on .+' | sed 's/Extension host agent listening on //')"
if [[ -n $LISTENING_ON ]]; then
break
fi
else
echo "Error server log file not found $SERVER_LOGFILE"
sleep 0.5
done
if [[ -z $LISTENING_ON ]]; then
echo "Error server did not start successfully"
print_install_results_and_exit 1
fi
else
echo "Error server log file not found $SERVER_LOGFILE"
print_install_results_and_exit 1
fi
# Finish server setup
+33 -33
View File
@@ -25,32 +25,32 @@ function compileTemplate(templateName: string, variables: Record<string, string>
* Returns -1 if no match.
*/
function matchHostnamePattern(hostname: string, pattern: string): number {
// Exact match has highest priority
if (hostname === pattern) {
return 1000;
}
// Exact match has highest priority
if (hostname === pattern) {
return 1000;
}
// Catch-all wildcard has lowest priority
if (pattern === '*') {
return 1;
}
// Catch-all wildcard has lowest priority
if (pattern === '*') {
return 1;
}
// Convert wildcard pattern to regex
// Escape special regex characters except *
const regexPattern = pattern
.replace(/[.+?^${}()|[\]\\]/g, '\\$&')
.replace(/\*/g, '.*');
// Convert wildcard pattern to regex
// Escape special regex characters except *
const regexPattern = pattern
.replace(/[.+?^${}()|[\]\\]/g, '\\$&')
.replace(/\*/g, '.*');
const regex = new RegExp(`^${regexPattern}$`);
const regex = new RegExp(`^${regexPattern}$`);
if (regex.test(hostname)) {
// Calculate specificity based on the number of non-wildcard characters
// More specific patterns (more characters) get higher scores
const nonWildcardChars = pattern.replace(/\*/g, '').length;
return 10 + nonWildcardChars;
}
if (regex.test(hostname)) {
// Calculate specificity based on the number of non-wildcard characters
// More specific patterns (more characters) get higher scores
const nonWildcardChars = pattern.replace(/\*/g, '').length;
return 10 + nonWildcardChars;
}
return -1;
return -1;
}
/**
@@ -58,19 +58,19 @@ function matchHostnamePattern(hostname: string, pattern: string): number {
* Supports wildcards with priority: exact match > specific wildcard > general wildcard.
*/
export function findServerInstallPath(hostname: string, pathMap: Record<string, string>): string | undefined {
let bestMatch: { pattern: string; path: string; score: number } | undefined;
let bestMatch: { pattern: string; path: string; score: number } | undefined;
for (const [pattern, path] of Object.entries(pathMap)) {
const score = matchHostnamePattern(hostname, pattern);
for (const [pattern, path] of Object.entries(pathMap)) {
const score = matchHostnamePattern(hostname, pattern);
if (score > 0) {
if (!bestMatch || score > bestMatch.score) {
bestMatch = { pattern, path, score };
}
}
}
if (score > 0) {
if (!bestMatch || score > bestMatch.score) {
bestMatch = { pattern, path, score };
}
}
}
return bestMatch?.path;
return bestMatch?.path;
}
export type ServerInstallOptions = {
@@ -186,7 +186,7 @@ export async function installCodeServer(
// investigate if it's possible to use `-EncodedCommand` flag
// https://devblogs.microsoft.com/powershell/invoking-powershell-with-complex-expressions-using-scriptblocks/
// eslint-disable-next-line no-useless-assignment
// eslint-disable-next-line no-useless-assignment
let command = '';
if (shell === 'powershell') {
@@ -300,7 +300,7 @@ function generateBashInstallScript({ id, quality, version, commit, release, exte
const listenFlag = useSocketPath
? `--socket-path="$TMP_DIR/vscode-server-sock-${crypto.randomUUID()}"`
: '--port=0';
const envVarLines = envVariables.map(envVar => ` echo "${envVar}==$${envVar}=="`).join('\n');
const envVarLines = envVariables.map(envVar => ` echo "${envVar}==$${envVar}=="`).join('\n');
return compileTemplate('server-setup.sh', {
DISTRO_VERSION: version,
+8 -8
View File
@@ -10,14 +10,14 @@ import { glob } from 'glob';
// Only a few directives might return an array
// https://github.com/cyjake/ssh-config/blob/master/src/ssh-config.ts#L10
export type HostConfiguration = {
CanonicalDomains?: string | string[];
GlobalKnownHostsFile?: string | string[];
Host?: string | string[];
IPQoS?: string | string[];
Match?: string | string[];
ProxyCommand?: string | string[];
SendEnv?: string | string[];
UserKnownHostsFile?: string | string[];
CanonicalDomains?: string | string[];
GlobalKnownHostsFile?: string | string[];
Host?: string | string[];
IPQoS?: string | string[];
Match?: string | string[];
ProxyCommand?: string | string[];
SendEnv?: string | string[];
UserKnownHostsFile?: string | string[];
} & Record<string, string>;
const systemSSHConfig = isWindows ? path.resolve(process.env.ALLUSERSPROFILE || 'C:\\ProgramData', 'ssh\\ssh_config') : '/etc/ssh/ssh_config';
+1 -1
View File
@@ -44,7 +44,7 @@ export default class SSHDestination {
const data = JSON.parse(Buffer.from(dest, 'hex').toString());
return new SSHDestination(data.hostName, data.user, data.port);
} catch {
// ignore
// ignore
}
return SSHDestination.parse(dest.replace(/\\x([0-9a-f]{2})/g, (_, charCode) => String.fromCharCode(parseInt(charCode, 16))));
+38 -38
View File
@@ -7,46 +7,46 @@ const webpack = require('webpack');
/**@type {import('webpack').Configuration}*/
const config = {
target: 'node',
entry: './src/extension.ts',
output: {
path: path.resolve(__dirname, 'lib'),
filename: 'extension.js',
libraryTarget: "commonjs2",
devtoolModuleFilenameTemplate: "../[resource-path]",
},
devtool: 'source-map',
externals: {
vscode: "commonjs vscode",
bufferutil: "bufferutil",
"utf-8-validate": "utf-8-validate",
},
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [{
test: /\.ts$/,
exclude: /node_modules/,
use: [{
loader: 'ts-loader'
}]
}]
},
plugins: [
new webpack.IgnorePlugin({
resourceRegExp: /crypto\/build\/Release\/sshcrypto\.node$/,
}),
new webpack.IgnorePlugin({
resourceRegExp: /cpu-features/,
})
]
target: 'node',
entry: './src/extension.ts',
output: {
path: path.resolve(__dirname, 'lib'),
filename: 'extension.js',
libraryTarget: "commonjs2",
devtoolModuleFilenameTemplate: "../[resource-path]",
},
devtool: 'source-map',
externals: {
vscode: "commonjs vscode",
bufferutil: "bufferutil",
"utf-8-validate": "utf-8-validate",
},
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [{
test: /\.ts$/,
exclude: /node_modules/,
use: [{
loader: 'ts-loader'
}]
}]
},
plugins: [
new webpack.IgnorePlugin({
resourceRegExp: /crypto\/build\/Release\/sshcrypto\.node$/,
}),
new webpack.IgnorePlugin({
resourceRegExp: /cpu-features/,
})
]
}
module.exports = (_env, argv) => {
if (argv.mode === 'production') {
config.devtool = false;
}
if (argv.mode === 'production') {
config.devtool = false;
}
return config;
return config;
};