Add flag to install an extension from the command line (#504)
This commit is contained in:
parent
c4c26058ef
commit
630ccfcacc
@ -1,6 +1,6 @@
|
|||||||
import { field, logger } from "@coder/logger";
|
import { field, logger } from "@coder/logger";
|
||||||
import { ServerMessage, SharedProcessActive } from "@coder/protocol/src/proto";
|
import { ServerMessage, SharedProcessActive } from "@coder/protocol/src/proto";
|
||||||
import { ChildProcess, fork, ForkOptions, spawn } from "child_process";
|
import { ChildProcess, fork, ForkOptions } from "child_process";
|
||||||
import { randomFillSync } from "crypto";
|
import { randomFillSync } from "crypto";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import * as fse from "fs-extra";
|
import * as fse from "fs-extra";
|
||||||
@ -29,6 +29,7 @@ commander.version(process.env.VERSION || "development")
|
|||||||
.option("-N, --no-auth", "Start without requiring authentication.", undefined)
|
.option("-N, --no-auth", "Start without requiring authentication.", undefined)
|
||||||
.option("-H, --allow-http", "Allow http connections.", false)
|
.option("-H, --allow-http", "Allow http connections.", false)
|
||||||
.option("-P, --password <value>", "Specify a password for authentication.")
|
.option("-P, --password <value>", "Specify a password for authentication.")
|
||||||
|
.option("--install-extension <value>", "Install an extension by its ID.")
|
||||||
.option("--bootstrap-fork <name>", "Used for development. Never set.")
|
.option("--bootstrap-fork <name>", "Used for development. Never set.")
|
||||||
.option("--extra-args <args>", "Used for development. Never set.")
|
.option("--extra-args <args>", "Used for development. Never set.")
|
||||||
.arguments("Specify working directory.")
|
.arguments("Specify working directory.")
|
||||||
@ -61,6 +62,8 @@ const bold = (text: string | number): string | number => {
|
|||||||
readonly cert?: string;
|
readonly cert?: string;
|
||||||
readonly certKey?: string;
|
readonly certKey?: string;
|
||||||
|
|
||||||
|
readonly installExtension?: string;
|
||||||
|
|
||||||
readonly bootstrapFork?: string;
|
readonly bootstrapFork?: string;
|
||||||
readonly extraArgs?: string;
|
readonly extraArgs?: string;
|
||||||
};
|
};
|
||||||
@ -112,11 +115,11 @@ const bold = (text: string | number): string | number => {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
((options.extraArgs ? JSON.parse(options.extraArgs) : []) as string[]).forEach((arg, i) => {
|
process.argv = [
|
||||||
// [0] contains the binary running the script (`node` for example) and
|
process.argv[0],
|
||||||
// [1] contains the script name, so the arguments come after that.
|
process.argv[1],
|
||||||
process.argv[i + 2] = arg;
|
...(options.extraArgs ? JSON.parse(options.extraArgs) : []),
|
||||||
});
|
];
|
||||||
|
|
||||||
return requireModule(modulePath, builtInExtensionsDir);
|
return requireModule(modulePath, builtInExtensionsDir);
|
||||||
}
|
}
|
||||||
@ -162,6 +165,26 @@ const bold = (text: string | number): string | number => {
|
|||||||
logger.warn('"--data-dir" is deprecated. Use "--user-data-dir" instead.');
|
logger.warn('"--data-dir" is deprecated. Use "--user-data-dir" instead.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.installExtension) {
|
||||||
|
const fork = forkModule("vs/code/node/cli", [
|
||||||
|
"--user-data-dir", dataDir,
|
||||||
|
"--builtin-extensions-dir", builtInExtensionsDir,
|
||||||
|
"--extensions-dir", extensionsDir,
|
||||||
|
"--install-extension", options.installExtension,
|
||||||
|
], {
|
||||||
|
env: {
|
||||||
|
VSCODE_ALLOW_IO: "true",
|
||||||
|
VSCODE_LOGS: process.env.VSCODE_LOGS,
|
||||||
|
},
|
||||||
|
}, dataDir);
|
||||||
|
|
||||||
|
fork.stdout.on("data", (d: Buffer) => d.toString().split("\n").forEach((l) => logger.info(l)));
|
||||||
|
fork.stderr.on("data", (d: Buffer) => d.toString().split("\n").forEach((l) => logger.error(l)));
|
||||||
|
fork.on("exit", () => process.exit());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: fill in appropriate doc url
|
// TODO: fill in appropriate doc url
|
||||||
logger.info("Additional documentation: http://github.com/codercom/code-server");
|
logger.info("Additional documentation: http://github.com/codercom/code-server");
|
||||||
logger.info("Initializing", field("data-dir", dataDir), field("extensions-dir", extensionsDir), field("working-dir", workingDir), field("log-dir", logDir));
|
logger.info("Initializing", field("data-dir", dataDir), field("extensions-dir", extensionsDir), field("working-dir", workingDir), field("log-dir", logDir));
|
||||||
|
@ -82,7 +82,6 @@ export const requireModule = (modulePath: string, builtInExtensionsDir: string):
|
|||||||
* @param modulePath Path of the VS Code module to load.
|
* @param modulePath Path of the VS Code module to load.
|
||||||
*/
|
*/
|
||||||
export const forkModule = (modulePath: string, args?: string[], options?: cp.ForkOptions, dataDir?: string): cp.ChildProcess => {
|
export const forkModule = (modulePath: string, args?: string[], options?: cp.ForkOptions, dataDir?: string): cp.ChildProcess => {
|
||||||
let proc: cp.ChildProcess;
|
|
||||||
const forkOptions: cp.ForkOptions = {
|
const forkOptions: cp.ForkOptions = {
|
||||||
stdio: [null, null, null, "ipc"],
|
stdio: [null, null, null, "ipc"],
|
||||||
};
|
};
|
||||||
@ -91,18 +90,27 @@ export const forkModule = (modulePath: string, args?: string[], options?: cp.For
|
|||||||
delete options.env.ELECTRON_RUN_AS_NODE;
|
delete options.env.ELECTRON_RUN_AS_NODE;
|
||||||
forkOptions.env = options.env;
|
forkOptions.env = options.env;
|
||||||
}
|
}
|
||||||
|
|
||||||
const forkArgs = ["--bootstrap-fork", modulePath];
|
const forkArgs = ["--bootstrap-fork", modulePath];
|
||||||
if (args) {
|
if (args) {
|
||||||
forkArgs.push("--extra-args", JSON.stringify(args));
|
forkArgs.push("--extra-args", JSON.stringify(args));
|
||||||
}
|
}
|
||||||
if (dataDir) {
|
if (dataDir) {
|
||||||
forkArgs.push("--data-dir", dataDir);
|
forkArgs.push("--user-data-dir", dataDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const nodeArgs = [];
|
||||||
if (isCli) {
|
if (isCli) {
|
||||||
proc = cp.spawn(process.execPath, [path.join(buildDir, "out", "cli.js"), ...forkArgs], forkOptions);
|
nodeArgs.push(path.join(buildDir, "out", "cli.js"));
|
||||||
} else {
|
} else {
|
||||||
proc = cp.spawn(process.execPath, ["--require", "ts-node/register", "--require", "tsconfig-paths/register", process.argv[1], ...forkArgs], forkOptions);
|
nodeArgs.push(
|
||||||
|
"--require", "ts-node/register",
|
||||||
|
"--require", "tsconfig-paths/register",
|
||||||
|
process.argv[1],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const proc = cp.spawn(process.execPath, [...nodeArgs, ...forkArgs], forkOptions);
|
||||||
if (args && args[0] === "--type=watcherService" && os.platform() === "linux") {
|
if (args && args[0] === "--type=watcherService" && os.platform() === "linux") {
|
||||||
cp.exec(`renice -n 19 -p ${proc.pid}`, (error) => {
|
cp.exec(`renice -n 19 -p ${proc.pid}`, (error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import * as path from "path";
|
|
||||||
import * as paths from "./paths";
|
import * as paths from "./paths";
|
||||||
import * as environment from "vs/platform/environment/node/environmentService";
|
import * as environment from "vs/platform/environment/node/environmentService";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Customize paths using data received from the initialization message.
|
||||||
|
*/
|
||||||
export class EnvironmentService extends environment.EnvironmentService {
|
export class EnvironmentService extends environment.EnvironmentService {
|
||||||
public get sharedIPCHandle(): string {
|
public get sharedIPCHandle(): string {
|
||||||
return paths.getSocketPath() || super.sharedIPCHandle;
|
return paths.getSocketPath() || super.sharedIPCHandle;
|
||||||
|
@ -60,7 +60,7 @@ module.exports = merge(
|
|||||||
"native-keymap": path.join(vsFills, "native-keymap.ts"),
|
"native-keymap": path.join(vsFills, "native-keymap.ts"),
|
||||||
"native-watchdog": path.join(vsFills, "native-watchdog.ts"),
|
"native-watchdog": path.join(vsFills, "native-watchdog.ts"),
|
||||||
"vs/base/common/amd": path.resolve(vsFills, "amd.ts"),
|
"vs/base/common/amd": path.resolve(vsFills, "amd.ts"),
|
||||||
"vs/base/node/paths": path.resolve(vsFills, "paths.ts"),
|
"vs/base/node/paths": path.join(vsFills, "paths.ts"),
|
||||||
"vs/platform/product/node/package": path.resolve(vsFills, "package.ts"),
|
"vs/platform/product/node/package": path.resolve(vsFills, "package.ts"),
|
||||||
"vs/platform/product/node/product": path.resolve(vsFills, "product.ts"),
|
"vs/platform/product/node/product": path.resolve(vsFills, "product.ts"),
|
||||||
"vs/base/node/zip": path.resolve(vsFills, "zip.ts"),
|
"vs/base/node/zip": path.resolve(vsFills, "zip.ts"),
|
||||||
|
@ -158,6 +158,14 @@ index 6fd8249..04c0933 100644
|
|||||||
+ backupMainService.initialize().catch(console.error);
|
+ backupMainService.initialize().catch(console.error);
|
||||||
@@ -223,0 +236 @@ async function handshake(configuration: ISharedProcessConfiguration): Promise<vo
|
@@ -223,0 +236 @@ async function handshake(configuration: ISharedProcessConfiguration): Promise<vo
|
||||||
+startup({ machineId: "1" });
|
+startup({ machineId: "1" });
|
||||||
|
diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts
|
||||||
|
index 1f8b17a..2a875f9 100644
|
||||||
|
--- a/src/vs/code/node/cli.ts
|
||||||
|
+++ b/src/vs/code/node/cli.ts
|
||||||
|
@@ -43,0 +44,3 @@ export async function main(argv: string[]): Promise<any> {
|
||||||
|
+ const cli = await new Promise<IMainCli>((c, e) => require(['vs/code/node/cliProcessMain'], c, e));
|
||||||
|
+ await cli.main(args);
|
||||||
|
+ return; // Always just do this for now.
|
||||||
diff --git a/src/vs/editor/browser/config/configuration.ts b/src/vs/editor/browser/config/configuration.ts
|
diff --git a/src/vs/editor/browser/config/configuration.ts b/src/vs/editor/browser/config/configuration.ts
|
||||||
index f97a692..0206957 100644
|
index f97a692..0206957 100644
|
||||||
--- a/src/vs/editor/browser/config/configuration.ts
|
--- a/src/vs/editor/browser/config/configuration.ts
|
||||||
|
Reference in New Issue
Block a user