Simplify build and development steps
This commit is contained in:
parent
88cef85f62
commit
4cd2f2cd52
23
README.md
23
README.md
@ -58,17 +58,13 @@ arguments when launching code-server with Docker. See
|
||||
|
||||
### Build
|
||||
|
||||
- If you also plan on developing, set the `OUT` environment variable. Otherwise
|
||||
it will build in this directory which will cause issues because `yarn watch`
|
||||
will try to compile the build directory as well.
|
||||
- Run `yarn build ${vscodeVersion} ${codeServerVersion}` in this directory (for
|
||||
example: `yarn build 1.36.0 development`).
|
||||
- If you target the same VS Code version our Travis builds do everything will
|
||||
work but if you target some other version it might not (we have to do some
|
||||
patching to VS Code so different versions aren't always compatible).
|
||||
- You can run the built code with `node path/to/build/out/vs/server/main.js` or run
|
||||
`yarn binary` with the same arguments in the previous step to package the
|
||||
code into a single binary.
|
||||
```shell
|
||||
export OUT=/path/to/output/build # Optional if only building. Required if also developing.
|
||||
yarn build ${vscodeVersion} ${codeServerVersion} # See travis.yml for the VS Code version to use.
|
||||
# The code-server version can be anything you want.
|
||||
node ~/path/to/output/build/out/vs/server/main.js # You can run the built JavaScript with Node.
|
||||
yarn binary ${vscodeVersion} ${codeServerVersion} # Or you can package it into a binary.
|
||||
```
|
||||
|
||||
## Known Issues
|
||||
|
||||
@ -109,11 +105,12 @@ data collected to improve code-server.
|
||||
```shell
|
||||
git clone https://github.com/microsoft/vscode
|
||||
cd vscode
|
||||
git checkout <see travis.yml for the VS Code version to use here>
|
||||
git checkout ${vscodeVersion} # See travis.yml for the version to use.
|
||||
yarn
|
||||
git clone https://github.com/cdr/code-server src/vs/server
|
||||
cd src/vs/server
|
||||
yarn patch:apply
|
||||
yarn
|
||||
yarn patch:apply
|
||||
yarn watch
|
||||
# Wait for the initial compilation to complete (it will say "Finished compilation").
|
||||
# Run the next command in another shell.
|
||||
|
12
package.json
12
package.json
@ -2,15 +2,13 @@
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"runner": "cd ./scripts && node --max-old-space-size=32384 -r ts-node/register ./build.ts",
|
||||
"preinstall": "yarn runner ensure-in-vscode && cd ../../../ && yarn || true",
|
||||
"postinstall": "rm -rf node_modules/@types/node",
|
||||
"start": "yarn runner ensure-in-vscode && nodemon --watch ../../../out --verbose ../../../out/vs/server/main.js",
|
||||
"watch": "yarn runner ensure-in-vscode && cd ../../../ && yarn watch",
|
||||
"build": "yarn --ignore-scripts && yarn runner build",
|
||||
"start": "nodemon --watch ../../../out --verbose ../../../out/vs/server/main.js",
|
||||
"watch": "cd ../../../ && yarn watch",
|
||||
"build": "yarn && yarn runner build",
|
||||
"package": "yarn runner package",
|
||||
"binary": "yarn runner binary",
|
||||
"patch:generate": "yarn runner ensure-in-vscode && cd ../../../ && git diff --staged > ./src/vs/server/scripts/vscode.patch",
|
||||
"patch:apply": "yarn runner ensure-in-vscode && cd ../../../ && git apply ./src/vs/server/scripts/vscode.patch"
|
||||
"patch:generate": "cd ../../../ && git diff --staged > ./src/vs/server/scripts/vscode.patch",
|
||||
"patch:apply": "cd ../../../ && git apply ./src/vs/server/scripts/vscode.patch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@coder/nbin": "^1.2.2",
|
||||
|
@ -20,21 +20,34 @@ class Builder {
|
||||
private readonly rootPath = path.resolve(__dirname, "..");
|
||||
private readonly outPath = process.env.OUT || this.rootPath;
|
||||
private _target?: "darwin" | "alpine" | "linux";
|
||||
private task?: Task;
|
||||
private currentTask?: Task;
|
||||
|
||||
public run(task: Task | undefined, args: string[]): void {
|
||||
this.task = task;
|
||||
this.currentTask = task;
|
||||
this.doRun(task, args).catch((error) => {
|
||||
console.error(error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
private async task<T>(message: string, fn: () => Promise<T>): Promise<T> {
|
||||
const time = Date.now();
|
||||
this.log(`${message}...`, true);
|
||||
try {
|
||||
const t = await fn();
|
||||
process.stdout.write(`took ${Date.now() - time}ms\n`);
|
||||
return t;
|
||||
} catch (error) {
|
||||
process.stdout.write("failed\n");
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes to stdout with an optional newline.
|
||||
*/
|
||||
private log(message: string, skipNewline: boolean = false): void {
|
||||
process.stdout.write(`[${this.task || "default"}] ${message}`);
|
||||
process.stdout.write(`[${this.currentTask || "default"}] ${message}`);
|
||||
if (!skipNewline) {
|
||||
process.stdout.write("\n");
|
||||
}
|
||||
@ -140,24 +153,9 @@ class Builder {
|
||||
* Build code-server within VS Code.
|
||||
*/
|
||||
private async build(vscodeSourcePath: string, vscodeVersion: string, codeServerVersion: string, finalBuildPath: string): Promise<void> {
|
||||
const task = async <T>(message: string, fn: () => Promise<T>): Promise<T> => {
|
||||
const time = Date.now();
|
||||
this.log(`${message}...`, true);
|
||||
try {
|
||||
const t = await fn();
|
||||
process.stdout.write(`took ${Date.now() - time}ms\n`);
|
||||
return t;
|
||||
} catch (error) {
|
||||
process.stdout.write("failed\n");
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Install dependencies (should be cached by CI).
|
||||
// Ignore scripts since we'll install VS Code dependencies separately.
|
||||
await task("Installing code-server dependencies", async () => {
|
||||
await util.promisify(cp.exec)("yarn --ignore-scripts", { cwd: this.rootPath });
|
||||
await util.promisify(cp.exec)("yarn postinstall", { cwd: this.rootPath });
|
||||
await this.task("Installing code-server dependencies", async () => {
|
||||
await util.promisify(cp.exec)("yarn", { cwd: this.rootPath });
|
||||
});
|
||||
|
||||
// Download and prepare VS Code if necessary (should be cached by CI).
|
||||
@ -165,18 +163,18 @@ class Builder {
|
||||
if (exists) {
|
||||
this.log("Using existing VS Code directory");
|
||||
} else {
|
||||
await task("Cloning VS Code", () => {
|
||||
await this.task("Cloning VS Code", () => {
|
||||
return util.promisify(cp.exec)(
|
||||
"git clone https://github.com/microsoft/vscode"
|
||||
+ ` --quiet --branch "${vscodeVersion}"`
|
||||
+ ` --single-branch --depth=1 "${vscodeSourcePath}"`);
|
||||
});
|
||||
|
||||
await task("Installing VS Code dependencies", () => {
|
||||
await this.task("Installing VS Code dependencies", () => {
|
||||
return util.promisify(cp.exec)("yarn", { cwd: vscodeSourcePath });
|
||||
});
|
||||
|
||||
await task("Building default extensions", () => {
|
||||
await this.task("Building default extensions", () => {
|
||||
return util.promisify(cp.exec)(
|
||||
"yarn gulp compile-extensions-build --max-old-space-size=32384",
|
||||
{ cwd: vscodeSourcePath },
|
||||
@ -185,14 +183,14 @@ class Builder {
|
||||
}
|
||||
|
||||
// Clean before patching or it could fail if already patched.
|
||||
await task("Patching VS Code", async () => {
|
||||
await this.task("Patching VS Code", async () => {
|
||||
await util.promisify(cp.exec)("git reset --hard", { cwd: vscodeSourcePath });
|
||||
await util.promisify(cp.exec)("git clean -fd", { cwd: vscodeSourcePath });
|
||||
await util.promisify(cp.exec)(`git apply ${this.rootPath}/scripts/vscode.patch`, { cwd: vscodeSourcePath });
|
||||
});
|
||||
|
||||
const serverPath = path.join(vscodeSourcePath, "src/vs/server");
|
||||
await task("Copying code-server into VS Code", async () => {
|
||||
await this.task("Copying code-server into VS Code", async () => {
|
||||
await fs.remove(serverPath);
|
||||
await fs.mkdirp(serverPath);
|
||||
await Promise.all(["main.js", "node_modules", "src", "typings"].map((fileName) => {
|
||||
@ -200,16 +198,16 @@ class Builder {
|
||||
}));
|
||||
});
|
||||
|
||||
await task("Building VS Code", () => {
|
||||
await this.task("Building VS Code", () => {
|
||||
return util.promisify(cp.exec)("yarn gulp compile-build --max-old-space-size=32384", { cwd: vscodeSourcePath });
|
||||
});
|
||||
|
||||
await task("Optimizing VS Code", async () => {
|
||||
await this.task("Optimizing VS Code", async () => {
|
||||
await fs.copyFile(path.join(this.rootPath, "scripts/optimize.js"), path.join(vscodeSourcePath, "coder.js"));
|
||||
await util.promisify(cp.exec)(`yarn gulp optimize --max-old-space-size=32384 --gulpfile ./coder.js`, { cwd: vscodeSourcePath });
|
||||
});
|
||||
|
||||
const { productJson, packageJson } = await task("Generating final package.json and product.json", async () => {
|
||||
const { productJson, packageJson } = await this.task("Generating final package.json and product.json", async () => {
|
||||
const merge = async (name: string, extraJson: { [key: string]: string } = {}): Promise<{ [key: string]: string }> => {
|
||||
const [aJson, bJson] = (await Promise.all([
|
||||
fs.readFile(path.join(vscodeSourcePath, `${name}.json`), "utf8"),
|
||||
@ -247,13 +245,13 @@ class Builder {
|
||||
});
|
||||
|
||||
if (process.env.MINIFY) {
|
||||
await task("Minifying VS Code", () => {
|
||||
await this.task("Minifying VS Code", () => {
|
||||
return util.promisify(cp.exec)("yarn gulp minify --max-old-space-size=32384 --gulpfile ./coder.js", { cwd: vscodeSourcePath });
|
||||
});
|
||||
}
|
||||
|
||||
const finalServerPath = path.join(finalBuildPath, "out/vs/server");
|
||||
await task("Copying into final build directory", async () => {
|
||||
await this.task("Copying into final build directory", async () => {
|
||||
await fs.remove(finalBuildPath);
|
||||
await fs.mkdirp(finalBuildPath);
|
||||
await Promise.all([
|
||||
@ -271,7 +269,7 @@ class Builder {
|
||||
});
|
||||
|
||||
if (process.env.MINIFY) {
|
||||
await task("Restricting to production dependencies", async () => {
|
||||
await this.task("Restricting to production dependencies", async () => {
|
||||
await Promise.all(["package.json", "yarn.lock"].map((fileName) => {
|
||||
Promise.all([
|
||||
fs.copy(path.join(this.rootPath, fileName), path.join(finalServerPath, fileName)),
|
||||
@ -279,10 +277,9 @@ class Builder {
|
||||
]);
|
||||
}));
|
||||
|
||||
await Promise.all([
|
||||
util.promisify(cp.exec)("yarn --production --ignore-scripts", { cwd: finalServerPath }),
|
||||
util.promisify(cp.exec)("yarn --production", { cwd: finalBuildPath }),
|
||||
]);
|
||||
await Promise.all([finalServerPath, finalBuildPath].map((cwd) => {
|
||||
return util.promisify(cp.exec)("yarn --production", { cwd });
|
||||
}));
|
||||
|
||||
await Promise.all(["package.json", "yarn.lock"].map((fileName) => {
|
||||
return Promise.all([
|
||||
@ -293,7 +290,7 @@ class Builder {
|
||||
});
|
||||
}
|
||||
|
||||
await task("Writing final package.json and product.json", () => {
|
||||
await this.task("Writing final package.json and product.json", () => {
|
||||
return Promise.all([
|
||||
fs.writeFile(path.join(finalBuildPath, "package.json"), JSON.stringify(packageJson, null, 2)),
|
||||
fs.writeFile(path.join(finalBuildPath, "product.json"), JSON.stringify(productJson, null, 2)),
|
||||
@ -301,7 +298,7 @@ class Builder {
|
||||
});
|
||||
|
||||
// This is so it doesn't get cached along with VS Code (no point).
|
||||
await task("Removing copied server", () => fs.remove(serverPath));
|
||||
await this.task("Removing copied server", () => fs.remove(serverPath));
|
||||
|
||||
// Prepend code to the target which enables finding files within the binary.
|
||||
const prependLoader = async (relativeFilePath: string): Promise<void> => {
|
||||
@ -322,7 +319,7 @@ class Builder {
|
||||
await fs.writeFile(filePath, shim + (await fs.readFile(filePath, "utf8")));
|
||||
};
|
||||
|
||||
await task("Prepending nbin loader", () => {
|
||||
await this.task("Prepending nbin loader", () => {
|
||||
return Promise.all([
|
||||
prependLoader("out/vs/server/main.js"),
|
||||
prependLoader("out/bootstrap-fork.js"),
|
||||
|
Loading…
Reference in New Issue
Block a user