Skip to content

Commit 3fdb2e1

Browse files
committed
Switch to loose files
For #1306.
1 parent f76c809 commit 3fdb2e1

13 files changed

+136
-770
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
build
44
dist*
55
out*
6-
release
6+
release*
77
node_modules
88
binaries

ci/build.ts

-145
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,19 @@
1-
import { Binary } from "@coder/nbin"
21
import * as cp from "child_process"
32
import * as fs from "fs-extra"
4-
import * as os from "os"
53
import Bundler from "parcel-bundler"
64
import * as path from "path"
75
import * as util from "util"
86

97
enum Task {
10-
Binary = "binary",
11-
Package = "package",
128
Build = "build",
139
Watch = "watch",
1410
}
1511

1612
class Builder {
1713
private readonly rootPath = path.resolve(__dirname, "..")
1814
private readonly vscodeSourcePath = path.join(this.rootPath, "lib/vscode")
19-
private readonly binariesPath = path.join(this.rootPath, "binaries")
2015
private readonly buildPath = path.join(this.rootPath, "build")
2116
private readonly codeServerVersion: string
22-
private _target?: "darwin" | "alpine" | "linux"
2317
private currentTask?: Task
2418

2519
public constructor() {
@@ -66,47 +60,16 @@ class Builder {
6660
throw new Error("No task provided")
6761
}
6862

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-
7363
switch (task) {
7464
case Task.Watch:
7565
return this.watch()
76-
case Task.Binary:
77-
return this.binary(binaryName)
78-
case Task.Package:
79-
return this.package(binaryName)
8066
case Task.Build:
8167
return this.build()
8268
default:
8369
throw new Error(`No task matching "${task}"`)
8470
}
8571
}
8672

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-
11073
/**
11174
* Make sure the argument is set. Display the value if it is.
11275
*/
@@ -256,114 +219,6 @@ class Builder {
256219
}
257220
}
258221

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-
367222
private async watch(): Promise<void> {
368223
let server: cp.ChildProcess | undefined
369224
const restartServer = (): void => {

ci/code-server.sh

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env sh
2+
# code-server.sh -- Run code-server with the bundled Node binary.
3+
4+
cd "$(dirname "$0")" || exit 1
5+
6+
./node ./out/node/entry.js "$@"

ci/release-image/Dockerfile

+4-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ RUN apt-get install -y dumb-init sudo
1616
RUN apt-get install -y man procps vim nano htop ssh git
1717

1818
RUN adduser --gecos '' --disabled-password coder && \
19-
echo "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd
19+
echo "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd
2020

2121
RUN curl -SsL https://github.com/boxboat/fixuid/releases/download/v0.4/fixuid-0.4-linux-amd64.tar.gz | tar -C /usr/local/bin -xzf - && \
2222
chown root:root /usr/local/bin/fixuid && \
@@ -28,7 +28,9 @@ RUN rm -rf /var/lib/apt/lists/*
2828

2929
COPY release/code-server*.tar.gz /tmp
3030
RUN cd /tmp && tar -xzf code-server*.tar.gz && \
31-
cp code-server*/code-server /usr/local/bin/code-server
31+
cp code-server*/code-server /usr/local/bin/code-server && \
32+
cp -r code-server* /usr/lib/code-server && \
33+
sed 's/\$0/\/usr\/lib\/code-server/g' /usr/lib/code-server/code-server > /usr/bin/code-server
3234
RUN rm -rf /tmp/*
3335

3436
EXPOSE 8080

ci/release.sh

+58-38
Original file line numberDiff line numberDiff line change
@@ -3,52 +3,72 @@
33

44
set -euo pipefail
55

6-
# This script assumes that yarn has already ran.
7-
function main() {
8-
cd "$(dirname "${0}")/.."
9-
source ./ci/lib.sh
6+
function package() {
7+
local target
8+
target=$(uname | tr '[:upper:]' '[:lower:]')
9+
if [[ $target == "linux" ]]; then
10+
# Alpine's ldd doesn't have a version flag but if you use an invalid flag
11+
# (like --version) it outputs the version to stderr and exits with 1.
12+
local ldd_output
13+
ldd_output=$(ldd --version 2>&1 || true)
14+
if echo "$ldd_output" | grep -iq musl; then
15+
target="alpine"
16+
fi
17+
fi
1018

11-
set_version
19+
local arch
20+
arch="$(uname -m)"
21+
22+
echo -n "Creating release..."
1223

13-
# Always minify and package on CI since that's when releases are pushed.
24+
cp "$(command -v node)" ./build
25+
cp README.md ./build
26+
cp LICENSE.txt ./build
27+
cp ./lib/vscode/ThirdPartyNotices.txt ./build
28+
cp ./ci/code-server.sh ./build/code-server
29+
30+
local archive_name="code-server-$VERSION-$target-$arch"
31+
mkdir -p ./release
32+
33+
local ext
34+
if [[ $target == "linux" ]]; then
35+
ext=".tar.gz"
36+
tar -czf "release/$archive_name$ext" --transform "s/^\.\/build/$archive_name/" ./build
37+
else
38+
mv ./build "./$archive_name"
39+
ext=".zip"
40+
zip -r "release/$archive_name$ext" ./code-server
41+
mv "./$archive_name" ./build
42+
fi
43+
44+
echo "done (release/$archive_name)"
45+
46+
mkdir -p "./release-upload/$VERSION"
47+
cp "./release/$archive_name$ext" "./release-upload/$VERSION/$target-$arch.tar.gz"
48+
mkdir -p "./release-upload/latest"
49+
cp "./release/$archive_name$ext" "./release-upload/latest/$target-$arch.tar.gz"
50+
}
51+
52+
# This script assumes that yarn has already ran.
53+
function build() {
54+
# Always minify and package on CI.
1455
if [[ ${CI:-} ]]; then
1556
export MINIFY="true"
16-
export PACKAGE="true"
1757
fi
1858

1959
yarn build
20-
yarn binary
21-
if [[ -n ${PACKAGE:-} ]]; then
22-
yarn package
23-
fi
60+
}
61+
62+
function main() {
63+
cd "$(dirname "${0}")/.."
64+
source ./ci/lib.sh
65+
66+
set_version
67+
68+
build
2469

25-
cd binaries
26-
27-
if [[ -n ${STRIP_BIN_TARGET:-} ]]; then
28-
# In this case provide plainly named binaries.
29-
for binary in code-server*; do
30-
echo "Moving $binary to code-server"
31-
mv "$binary" code-server
32-
done
33-
elif [[ -n ${DRONE_TAG:-} || -n ${TRAVIS_TAG:-} ]]; then
34-
# Prepare directory for uploading binaries on release.
35-
for binary in code-server*; do
36-
mkdir -p "../binary-upload"
37-
38-
local prefix="code-server-$VERSION-"
39-
local target="${binary#$prefix}"
40-
if [[ $target == "linux-x86_64" ]]; then
41-
echo "Copying $binary to ../binary-upload/latest-linux"
42-
cp "$binary" "../binary-upload/latest-linux"
43-
fi
44-
45-
local gcp_dir
46-
gcp_dir="../binary-upload/releases/$VERSION/$target"
47-
mkdir -p "$gcp_dir"
48-
49-
echo "Copying $binary to $gcp_dir/code-server"
50-
cp "$binary" "$gcp_dir/code-server"
51-
done
70+
if [[ ${CI:-} ]]; then
71+
package
5272
fi
5373
}
5474

ci/vscode.patch

-16
Original file line numberDiff line numberDiff line change
@@ -179,22 +179,6 @@ index 5a631e0b39..4114bd9287 100644
179179
} else if (typeof process === 'object') {
180180
_isWindows = (process.platform === 'win32');
181181
_isMacintosh = (process.platform === 'darwin');
182-
diff --git a/src/vs/base/common/processes.ts b/src/vs/base/common/processes.ts
183-
index c52f7b3774..967943d27b 100644
184-
--- a/src/vs/base/common/processes.ts
185-
+++ b/src/vs/base/common/processes.ts
186-
@@ -110,7 +110,10 @@ export function sanitizeProcessEnvironment(env: IProcessEnvironment, ...preserve
187-
/^ELECTRON_.+$/,
188-
/^GOOGLE_API_KEY$/,
189-
/^VSCODE_.+$/,
190-
- /^SNAP(|_.*)$/
191-
+ /^SNAP(|_.*)$/,
192-
+ // NOTE@coder: Add our variables.
193-
+ /^NBIN_BYPASS$/,
194-
+ /^LAUNCH_VSCODE$/
195-
];
196-
const envKeys = Object.keys(env);
197-
envKeys
198182
diff --git a/src/vs/base/node/languagePacks.js b/src/vs/base/node/languagePacks.js
199183
index 2c64061da7..c0ef8faedd 100644
200184
--- a/src/vs/base/node/languagePacks.js

doc/CONTRIBUTING.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,5 @@ works internally.
2525
```shell
2626
yarn
2727
yarn build
28-
node build/out/entry.js # You can run the built JavaScript with Node.
29-
yarn binary # Or you can package it into a binary.
28+
node build/out/entry.js # Run the built JavaScript with Node.
3029
```

package.json

+1-4
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,9 @@
1212
"fmt": "ci/fmt.sh",
1313
"runner": "cd ./ci && NODE_OPTIONS=--max_old_space_size=32384 ts-node ./build.ts",
1414
"build": "yarn runner build",
15-
"watch": "yarn runner watch",
16-
"binary": "yarn runner binary",
17-
"package": "yarn runner package"
15+
"watch": "yarn runner watch"
1816
},
1917
"devDependencies": {
20-
"@coder/nbin": "^1.2.7",
2118
"@types/adm-zip": "^0.4.32",
2219
"@types/fs-extra": "^8.0.1",
2320
"@types/mocha": "^5.2.7",

0 commit comments

Comments
 (0)