···42 description = mdDoc ''
43 Group policies to install.
4445- See [Mozilla's documentation](https://github.com/mozilla/policy-templates/blob/master/README.md")
46 for a list of available options.
4748 This can be used to install extensions declaratively! Check out the
···79 '';
80 };
8100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082 autoConfig = mkOption {
83 type = types.lines;
84 default = "";
···136 };
137138 # Preferences are converted into a policy
139- programs.firefox.policies = mkIf (cfg.preferences != { }) {
140 Preferences = (mapAttrs
141 (_: value: { Value = value; Status = cfg.preferencesStatus; })
142 cfg.preferences);
000000000143 };
144 };
145
···4 * node fixup_bin.js <bin_dir> <modules_dir> [<bin_pkg_1>, <bin_pkg_2> ... ]
5 */
67-const fs = require('fs')
8-const path = require('path')
910-const derivationBinPath = process.argv[2]
11-const nodeModules = process.argv[3]
12-const packagesToPublishBin = process.argv.slice(4)
1314function processPackage(name) {
15- console.log('fixup_bin: Processing ', name)
1617- const packagePath = `${nodeModules}/${name}`
18- const packageJsonPath = `${packagePath}/package.json`
19- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath))
2021 if (!packageJson.bin) {
22- console.log('fixup_bin: No binaries provided')
23- return
24 }
2526 // There are two alternative syntaxes for `bin`
27 // a) just a plain string, in which case the name of the package is the name of the binary.
28 // b) an object, where key is the name of the eventual binary, and the value the path to that binary.
29- if (typeof packageJson.bin === 'string') {
30- const binName = packageJson.bin
31- packageJson.bin = {}
32- packageJson.bin[packageJson.name] = binName
33 }
3435 // eslint-disable-next-line no-restricted-syntax, guard-for-in
36 for (const binName in packageJson.bin) {
37- const binPath = packageJson.bin[binName]
38- const normalizedBinName = binName.replace('@', '').replace('/', '-')
3940- const targetPath = path.normalize(`${packagePath}/${binPath}`)
41- const createdPath = `${derivationBinPath}/${normalizedBinName}`
4243 console.log(
44- `fixup_bin: creating link ${createdPath} that points to ${targetPath}`,
45- )
4647- fs.symlinkSync(targetPath, createdPath)
48 }
49}
5051packagesToPublishBin.forEach(pkg => {
52- processPackage(pkg)
53-})
···4 * node fixup_bin.js <bin_dir> <modules_dir> [<bin_pkg_1>, <bin_pkg_2> ... ]
5 */
67+const fs = require("fs");
8+const path = require("path");
910+const derivationBinPath = process.argv[2];
11+const nodeModules = process.argv[3];
12+const packagesToPublishBin = process.argv.slice(4);
1314function processPackage(name) {
15+ console.log("fixup_bin: Processing ", name);
1617+ const packagePath = `${nodeModules}/${name}`;
18+ const packageJsonPath = `${packagePath}/package.json`;
19+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
2021 if (!packageJson.bin) {
22+ console.log("fixup_bin: No binaries provided");
23+ return;
24 }
2526 // There are two alternative syntaxes for `bin`
27 // a) just a plain string, in which case the name of the package is the name of the binary.
28 // b) an object, where key is the name of the eventual binary, and the value the path to that binary.
29+ if (typeof packageJson.bin === "string") {
30+ const binName = packageJson.bin;
31+ packageJson.bin = {};
32+ packageJson.bin[packageJson.name] = binName;
33 }
3435 // eslint-disable-next-line no-restricted-syntax, guard-for-in
36 for (const binName in packageJson.bin) {
37+ const binPath = packageJson.bin[binName];
38+ const normalizedBinName = binName.replace("@", "").replace("/", "-");
3940+ const targetPath = path.normalize(`${packagePath}/${binPath}`);
41+ const createdPath = `${derivationBinPath}/${normalizedBinName}`;
4243 console.log(
44+ `fixup_bin: creating link ${createdPath} that points to ${targetPath}`
45+ );
4647+ fs.symlinkSync(targetPath, createdPath);
48 }
49}
5051packagesToPublishBin.forEach(pkg => {
52+ processPackage(pkg);
53+});
···1-const https = require('https')
2-const crypto = require('crypto')
34// TODO:
5// make test case where getSha1 function is used, i.e. the case when resolved is without sha1?
···8function getSha1(url) {
9 return new Promise((resolve, reject) => {
10 https.get(url, res => {
11- const { statusCode } = res
12- const hash = crypto.createHash('sha1')
1314 if (statusCode !== 200) {
15- const err = new Error(`Request Failed.\nStatus Code: ${statusCode}`)
1617 // consume response data to free up memory
18- res.resume()
1920- reject(err)
21 }
2223- res.on('data', chunk => {
24- hash.update(chunk)
25- })
2627- res.on('end', () => {
28- resolve(hash.digest('hex'))
29- })
3031- res.on('error', reject)
32- })
33- })
34}
3536// Object -> Object
···3940 if (!pkg.resolved) {
41 console.error(
42- `yarn2nix: can't find "resolved" field for package ${
43- pkg.nameWithVersion
44- }, you probably required it using "file:...", this feature is not supported, ignoring`,
45- )
46- return pkg
47 }
4849- const [url, sha1] = pkg.resolved.split('#', 2)
5051- if (sha1 || url.startsWith('https://codeload.github.com')) {
52- return pkg
53 }
5455 // if there is no sha1 in resolved url
56 // (this could happen if yarn.lock was generated by older version of yarn)
57 // - request it from registry by https and add it to pkg
58- const newSha1 = await getSha1(url)
5960 return {
61 ...pkg,
62- resolved: `${url}#${newSha1}`,
63- }
64}
6566-module.exports = fixPkgAddMissingSha1
···1+const https = require("https");
2+const crypto = require("crypto");
34// TODO:
5// make test case where getSha1 function is used, i.e. the case when resolved is without sha1?
···8function getSha1(url) {
9 return new Promise((resolve, reject) => {
10 https.get(url, res => {
11+ const { statusCode } = res;
12+ const hash = crypto.createHash("sha1");
1314 if (statusCode !== 200) {
15+ const err = new Error(`Request Failed.\nStatus Code: ${statusCode}`);
1617 // consume response data to free up memory
18+ res.resume();
1920+ reject(err);
21 }
2223+ res.on("data", chunk => {
24+ hash.update(chunk);
25+ });
2627+ res.on("end", () => {
28+ resolve(hash.digest("hex"));
29+ });
3031+ res.on("error", reject);
32+ });
33+ });
34}
3536// Object -> Object
···3940 if (!pkg.resolved) {
41 console.error(
42+ `yarn2nix: can't find "resolved" field for package ${pkg.nameWithVersion}, you probably required it using "file:...", this feature is not supported, ignoring`
43+ );
44+ return pkg;
0045 }
4647+ const [url, sha1] = pkg.resolved.split("#", 2);
4849+ if (sha1 || url.startsWith("https://codeload.github.com")) {
50+ return pkg;
51 }
5253 // if there is no sha1 in resolved url
54 // (this could happen if yarn.lock was generated by older version of yarn)
55 // - request it from registry by https and add it to pkg
56+ const newSha1 = await getSha1(url);
5758 return {
59 ...pkg,
60+ resolved: `${url}#${newSha1}`
61+ };
62}
6364+module.exports = fixPkgAddMissingSha1;
···1+--- ./ci/build/build-vscode.sh
2++++ ./ci/build/build-vscode.sh
3+@@ -45,14 +45,12 @@
4+ # Set the commit Code will embed into the product.json. We need to do this
5+ # since Code tries to get the commit from the `.git` directory which will fail
6+ # as it is a submodule.
7+- export VSCODE_DISTRO_COMMIT
8+- VSCODE_DISTRO_COMMIT=$(git rev-parse HEAD)
9++ export VSCODE_DISTRO_COMMIT=none
10+11+ # Add the date, our name, links, and enable telemetry (this just makes
12+ # telemetry available; telemetry can still be disabled by flag or setting).
13+ # This needs to be done before building as Code will read this file and embed
14+ # it into the client-side code.
15+- git checkout product.json # Reset in case the script exited early.
16+ cp product.json product.original.json # Since jq has no inline edit.
17+ jq --slurp '.[0] * .[1]' product.original.json <(
18+ cat << EOF
19+@@ -99,7 +97,6 @@
20+ # Reset so if you develop after building you will not be stuck with the wrong
21+ # commit (the dev client will use `oss-dev` but the dev server will still use
22+ # product.json which will have `stable-$commit`).
23+- git checkout product.json
24+25+ popd
26+
+47-52
pkgs/servers/code-server/default.nix
···1{ lib, stdenv, fetchFromGitHub, buildGoModule, makeWrapper, runCommand
2, cacert, moreutils, jq, git, rsync, pkg-config, yarn, python3
3-, esbuild, nodejs-14_x, node-gyp, libsecret, xorg, ripgrep
4-, AppKit, Cocoa, CoreServices, Security, cctools, xcbuild }:
56let
7 system = stdenv.hostPlatform.system;
89- nodejs = nodejs-14_x;
10 python = python3;
11 yarn' = yarn.override { inherit nodejs; };
12- defaultYarnOpts = [ "frozen-lockfile" "non-interactive" "no-progress"];
1314 # replaces esbuild's download script with a binary from nixpkgs
15 patchEsbuild = path : version : ''
···2122in stdenv.mkDerivation rec {
23 pname = "code-server";
24- version = "4.0.1";
25- commit = "7fe23daf009e5234eaa54a1ea5ff26df384c47ac";
2627 src = fetchFromGitHub {
28- owner = "cdr";
29 repo = "code-server";
30 rev = "v${version}";
31- sha256 = "1s3dcmzlkyh7qfs3ai1p7dlp45iys0ax1fbxxz17p395pw9anrrl";
032 };
3334 cloudAgent = buildGoModule rec {
35 pname = "cloud-agent";
36- version = "0.2.3";
3738 src = fetchFromGitHub {
39- owner = "cdr";
40 repo = "cloud-agent";
41 rev = "v${version}";
42- sha256 = "14i1qq273f0yn5v52ryiqwj7izkd1yd212di4gh4bqypmmzhw3jj";
43 };
4445- vendorSha256 = "0k9v10wkzx53r5syf6bmm81gr4s5dalyaa07y9zvx6vv5r2h0661";
4647 postPatch = ''
48 # the cloud-agent release tag has an empty version string, so add it back in
···66 xargs -I {} yarn --cwd {} \
67 --frozen-lockfile --ignore-scripts --ignore-platform \
68 --ignore-engines --no-progress --non-interactive
000069 '';
70 outputHashMode = "recursive";
71 outputHashAlgo = "sha256";
7273 # to get hash values use nix-build -A code-server.prefetchYarnCache
74- outputHash = "0qmfsirld1qfl2s26rxbpmvxsyj2pvzkgk8w89zlrgbhgc5fj8p9";
75 };
7677 nativeBuildInputs = [
78- nodejs yarn' python pkg-config makeWrapper git rsync jq moreutils
79 ];
80 buildInputs = lib.optionals (!stdenv.isDarwin) [ libsecret ]
81 ++ (with xorg; [ libX11 libxkbfile ])
···86 patches = [
87 # remove download of coder-cloud agent
88 ./remove-cloud-agent-download.patch
0089 ];
9091 postPatch = ''
···133 # install code-server dependencies
134 yarn --offline --ignore-scripts
135000136 # patch shebangs of everything to allow binary packages to build
137 patchShebangs .
138139- # Skip shellcheck download
140- jq "del(.scripts.preinstall)" node_modules/shellcheck/package.json | sponge node_modules/shellcheck/package.json
0141142 # rebuild binary packages now that scripts have been patched
143- npm rebuild
0144145 # Replicate ci/dev/postinstall.sh
146 echo "----- Replicate ci/dev/postinstall.sh"
147 yarn --cwd "./vendor" install --modules-folder modules --offline --ignore-scripts --frozen-lockfile
148149- # Replicate vendor/postinstall.sh
150- echo " ----- Replicate vendor/postinstall.sh"
151- yarn --cwd "./vendor/modules/code-oss-dev" --offline --frozen-lockfile --ignore-scripts install
152-153 # remove all built-in extensions, as these are 3rd party extensions that
154 # get downloaded from vscode marketplace
155- jq --slurp '.[0] * .[1]' "vendor/modules/code-oss-dev/product.json" <(
156 cat << EOF
157 {
158 "builtInExtensions": []
159 }
160 EOF
161- ) | sponge vendor/modules/code-oss-dev/product.json
162163 # disable automatic updates
164 sed -i '/update.mode/,/\}/{s/default:.*/default: "none",/g}' \
165- vendor/modules/code-oss-dev/src/vs/platform/update/common/update.config.contribution.ts
166-167- # put ripgrep binary into bin, so postinstall does not try to download it
168- find -name vscode-ripgrep -type d \
169- -execdir mkdir -p {}/bin \; \
170- -execdir ln -s ${ripgrep}/bin/rg {}/bin/rg \;
171-172- # Playwright is only needed for tests, we can disable it for builds.
173- # There's an environment variable to disable downloads, but the package makes a breaking call to
174- # sw_vers before that variable is checked.
175- patch -p1 -i ${./playwright.patch}
176177 # Patch out remote download of nodejs from build script
178 patch -p1 -i ${./remove-node-download.patch}
179180- # Replicate install vscode dependencies without running script for all vscode packages
181- # that require patching for postinstall scripts to succeed
182- find ./vendor/modules/code-oss-dev -path "*node_modules" -prune -o \
183- -path "./*/*/*/*/*" -name "yarn.lock" -printf "%h\n" | \
184 xargs -I {} yarn --cwd {} \
185- --frozen-lockfile --offline --ignore-scripts --ignore-engines
186-187188 # patch shebangs of everything to allow binary packages to build
189 patchShebangs .
190191- ${patchEsbuild "./vendor/modules/code-oss-dev/build" "0.12.6"}
192- ${patchEsbuild "./vendor/modules/code-oss-dev/extensions" "0.11.23"}
193- '' + lib.optionalString stdenv.isDarwin ''
194 # use prebuilt binary for @parcel/watcher, which requires macOS SDK 10.13+
195 # (see issue #101229)
196- pushd ./vendor/modules/code-oss-dev/remote/node_modules/@parcel/watcher
197 mkdir -p ./build/Release
198 mv ./prebuilds/darwin-x64/node.napi.glibc.node ./build/Release/watcher.node
199 jq "del(.scripts) | .gypfile = false" ./package.json | sponge ./package.json
200 popd
201 '' + ''
202- # rebuild binaries, we use npm here, as yarn does not provide an alternative
203- # that would not attempt to try to reinstall everything and break our
204- # patching attempts
205- npm rebuild --prefix vendor/modules/code-oss-dev --update-binary
0206207 # run postinstall scripts after patching
208- find ./vendor/modules/code-oss-dev -path "*node_modules" -prune -o \
209 -path "./*/*/*/*/*" -name "yarn.lock" -printf "%h\n" | \
210 xargs -I {} sh -c 'jq -e ".scripts.postinstall" {}/package.json >/dev/null && yarn --cwd {} postinstall --frozen-lockfile --offline || true'
211···233 ln -s "${cloudAgent}/bin/cloud-agent" $out/libexec/code-server/lib/coder-cloud-agent
234235 # create wrapper
236- makeWrapper "${nodejs-14_x}/bin/node" "$out/bin/code-server" \
237 --add-flags "$out/libexec/code-server/out/node/entry.js"
238 '';
239···249 code-server is VS Code running on a remote server, accessible through the
250 browser.
251 '';
252- homepage = "https://github.com/cdr/code-server";
253 license = licenses.mit;
254- maintainers = with maintainers; [ offline ];
255 platforms = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" ];
256 };
257}
···1--- ./ci/build/npm-postinstall.sh
2+++ ./ci/build/npm-postinstall.sh
3-@@ -58,14 +58,6 @@
4-5- OS="$(uname | tr '[:upper:]' '[:lower:]')"
6-7- mkdir -p ./lib
8-
9-- if curl -fsSL "https://github.com/cdr/cloud-agent/releases/latest/download/cloud-agent-$OS-$ARCH" -o ./lib/coder-cloud-agent; then
10- chmod +x ./lib/coder-cloud-agent
11- else
12- echo "Failed to download cloud agent; --link will not work"
13- fi
14-
15- if ! vscode_yarn; then
16 echo "You may not have the required dependencies to build the native modules."
17- echo "Please see https://github.com/cdr/code-server/blob/master/docs/npm.md"
···1--- ./ci/build/npm-postinstall.sh
2+++ ./ci/build/npm-postinstall.sh
3+@@ -102,14 +102,6 @@
4+ ;;
5+ esac
6+7- mkdir -p ./lib
8-
9+- if curl -fsSL "https://github.com/coder/cloud-agent/releases/latest/download/cloud-agent-$OS-$ARCH" -o ./lib/coder-cloud-agent; then
10- chmod +x ./lib/coder-cloud-agent
11- else
12- echo "Failed to download cloud agent; --link will not work"
13- fi
14-
15+ if ! vscode_install; then
16 echo "You may not have the required dependencies to build the native modules."
17+ echo "Please see https://github.com/coder/code-server/blob/main/docs/npm.md"