|
1 |
| -import { Binary } from "@coder/nbin" |
2 | 1 | import * as cp from "child_process"
|
3 | 2 | import * as fs from "fs-extra"
|
4 |
| -import * as os from "os" |
5 | 3 | import Bundler from "parcel-bundler"
|
6 | 4 | import * as path from "path"
|
7 | 5 | import * as util from "util"
|
8 | 6 |
|
9 | 7 | enum Task {
|
10 |
| - Binary = "binary", |
11 |
| - Package = "package", |
12 | 8 | Build = "build",
|
13 | 9 | Watch = "watch",
|
14 | 10 | }
|
15 | 11 |
|
16 | 12 | class Builder {
|
17 | 13 | private readonly rootPath = path.resolve(__dirname, "..")
|
18 | 14 | private readonly vscodeSourcePath = path.join(this.rootPath, "lib/vscode")
|
19 |
| - private readonly binariesPath = path.join(this.rootPath, "binaries") |
20 | 15 | private readonly buildPath = path.join(this.rootPath, "build")
|
21 | 16 | private readonly codeServerVersion: string
|
22 |
| - private _target?: "darwin" | "alpine" | "linux" |
23 | 17 | private currentTask?: Task
|
24 | 18 |
|
25 | 19 | public constructor() {
|
@@ -66,47 +60,16 @@ class Builder {
|
66 | 60 | throw new Error("No task provided")
|
67 | 61 | }
|
68 | 62 |
|
69 |
| - const arch = this.ensureArgument("arch", os.arch().replace(/^x/, "x86_")) |
70 |
| - const target = this.ensureArgument("target", await this.target()) |
71 |
| - const binaryName = `code-server-${this.codeServerVersion}-${target}-${arch}` |
72 |
| - |
73 | 63 | switch (task) {
|
74 | 64 | case Task.Watch:
|
75 | 65 | return this.watch()
|
76 |
| - case Task.Binary: |
77 |
| - return this.binary(binaryName) |
78 |
| - case Task.Package: |
79 |
| - return this.package(binaryName) |
80 | 66 | case Task.Build:
|
81 | 67 | return this.build()
|
82 | 68 | default:
|
83 | 69 | throw new Error(`No task matching "${task}"`)
|
84 | 70 | }
|
85 | 71 | }
|
86 | 72 |
|
87 |
| - /** |
88 |
| - * Get the target of the system. |
89 |
| - */ |
90 |
| - private async target(): Promise<"darwin" | "alpine" | "linux"> { |
91 |
| - if (!this._target) { |
92 |
| - if (os.platform() === "darwin" || (process.env.OSTYPE && /^darwin/.test(process.env.OSTYPE))) { |
93 |
| - this._target = "darwin" |
94 |
| - } else { |
95 |
| - // Alpine's ldd doesn't have a version flag but if you use an invalid flag |
96 |
| - // (like --version) it outputs the version to stderr and exits with 1. |
97 |
| - const result = await util |
98 |
| - .promisify(cp.exec)("ldd --version") |
99 |
| - .catch((error) => ({ stderr: error.message, stdout: "" })) |
100 |
| - if (/musl/.test(result.stderr) || /musl/.test(result.stdout)) { |
101 |
| - this._target = "alpine" |
102 |
| - } else { |
103 |
| - this._target = "linux" |
104 |
| - } |
105 |
| - } |
106 |
| - } |
107 |
| - return this._target |
108 |
| - } |
109 |
| - |
110 | 73 | /**
|
111 | 74 | * Make sure the argument is set. Display the value if it is.
|
112 | 75 | */
|
@@ -256,114 +219,6 @@ class Builder {
|
256 | 219 | }
|
257 | 220 | }
|
258 | 221 |
|
259 |
| - /** |
260 |
| - * Bundles the built code into a binary. |
261 |
| - */ |
262 |
| - private async binary(binaryName: string): Promise<void> { |
263 |
| - const prependCode = async (code: string, relativeFilePath: string): Promise<void> => { |
264 |
| - const filePath = path.join(this.buildPath, relativeFilePath) |
265 |
| - const content = await fs.readFile(filePath, "utf8") |
266 |
| - if (!content.startsWith(code)) { |
267 |
| - await fs.writeFile(filePath, code + content) |
268 |
| - } |
269 |
| - } |
270 |
| - |
271 |
| - // Unpack binaries since we can't run them within the binary. |
272 |
| - const unpack = ` |
273 |
| - if (global.NBIN_LOADED) { |
274 |
| - try { |
275 |
| - const fs = require("fs-extra") |
276 |
| - const rg = require("vscode-ripgrep") |
277 |
| - const path = require("path") |
278 |
| - const { logger, field } = require("@coder/logger") |
279 |
| -
|
280 |
| - const unpackExecutables = async (filePath, destination) => { |
281 |
| - logger.debug("unpacking executable", field("src", filePath), field("dest", destination)) |
282 |
| - await fs.mkdirp(path.dirname(destination)) |
283 |
| - if (filePath && !(await fs.pathExists(destination))) { |
284 |
| - await fs.writeFile(destination, await fs.readFile(filePath)) |
285 |
| - await fs.chmod(destination, "755") |
286 |
| - } |
287 |
| - } |
288 |
| -
|
289 |
| - unpackExecutables(rg.binaryRgPath, rg.rgPath).catch((error) => console.warn(error)) |
290 |
| - } catch (error) { |
291 |
| - console.warn(error) |
292 |
| - } |
293 |
| - } |
294 |
| - ` |
295 |
| - |
296 |
| - // Enable finding files within the binary. |
297 |
| - const loader = ` |
298 |
| - if (!global.NBIN_LOADED) { |
299 |
| - try { |
300 |
| - const nbin = require("nbin") |
301 |
| - nbin.shimNativeFs("${this.buildPath}") |
302 |
| - global.NBIN_LOADED = true |
303 |
| - require("@coder/logger").logger.debug("shimmed file system at ${this.buildPath}") |
304 |
| - const path = require("path") |
305 |
| - const rg = require("vscode-ripgrep") |
306 |
| - rg.binaryRgPath = rg.rgPath |
307 |
| - rg.rgPath = path.join(require("os").tmpdir(), "code-server/binaries", path.basename(rg.binaryRgPath)) |
308 |
| - } catch (error) { |
309 |
| - // Most likely not in the binary. |
310 |
| - } |
311 |
| - } |
312 |
| - ` |
313 |
| - |
314 |
| - await this.task("Prepending nbin loader", () => { |
315 |
| - return Promise.all([ |
316 |
| - prependCode(loader, "out/node/entry.js"), |
317 |
| - prependCode(loader, "lib/vscode/out/vs/server/entry.js"), |
318 |
| - prependCode(loader + unpack, "lib/vscode/out/vs/server/fork.js"), |
319 |
| - prependCode(loader, "lib/vscode/out/bootstrap-fork.js"), |
320 |
| - prependCode(loader, "lib/vscode/extensions/node_modules/typescript/lib/tsserver.js"), |
321 |
| - ]) |
322 |
| - }) |
323 |
| - |
324 |
| - const bin = new Binary({ |
325 |
| - mainFile: path.join(this.buildPath, "out/node/entry.js"), |
326 |
| - target: await this.target(), |
327 |
| - }) |
328 |
| - |
329 |
| - bin.writeFiles(path.join(this.buildPath, "**")) |
330 |
| - |
331 |
| - await fs.mkdirp(this.binariesPath) |
332 |
| - |
333 |
| - const binaryPath = path.join(this.binariesPath, binaryName) |
334 |
| - await fs.writeFile(binaryPath, await bin.build()) |
335 |
| - await fs.chmod(binaryPath, "755") |
336 |
| - |
337 |
| - this.log(`binary: ${binaryPath}`) |
338 |
| - } |
339 |
| - |
340 |
| - /** |
341 |
| - * Package the binary into a release archive. |
342 |
| - */ |
343 |
| - private async package(binaryName: string): Promise<void> { |
344 |
| - const releasePath = path.join(this.rootPath, "release") |
345 |
| - const archivePath = path.join(releasePath, binaryName) |
346 |
| - |
347 |
| - await fs.remove(archivePath) |
348 |
| - await fs.mkdirp(archivePath) |
349 |
| - |
350 |
| - await fs.copyFile(path.join(this.binariesPath, binaryName), path.join(archivePath, "code-server")) |
351 |
| - await fs.copyFile(path.join(this.rootPath, "README.md"), path.join(archivePath, "README.md")) |
352 |
| - await fs.copyFile(path.join(this.vscodeSourcePath, "LICENSE.txt"), path.join(archivePath, "LICENSE.txt")) |
353 |
| - await fs.copyFile( |
354 |
| - path.join(this.vscodeSourcePath, "ThirdPartyNotices.txt"), |
355 |
| - path.join(archivePath, "ThirdPartyNotices.txt"), |
356 |
| - ) |
357 |
| - |
358 |
| - if ((await this.target()) === "darwin") { |
359 |
| - await util.promisify(cp.exec)(`zip -r "${binaryName}.zip" "${binaryName}"`, { cwd: releasePath }) |
360 |
| - this.log(`archive: ${archivePath}.zip`) |
361 |
| - } else { |
362 |
| - await util.promisify(cp.exec)(`tar -czf "${binaryName}.tar.gz" "${binaryName}"`, { cwd: releasePath }) |
363 |
| - this.log(`archive: ${archivePath}.tar.gz`) |
364 |
| - } |
365 |
| - } |
366 |
| - |
367 | 222 | private async watch(): Promise<void> {
|
368 | 223 | let server: cp.ChildProcess | undefined
|
369 | 224 | const restartServer = (): void => {
|
|
0 commit comments