nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{ stdenv, fetchFromGitHub, makeWrapper, runCommand
2, moreutils, jq, git, zip, rsync, pkgconfig, yarn, python2
3, nodejs-12_x, libsecret, xorg, ripgrep, nettools }:
4
5let
6 system = stdenv.hostPlatform.system;
7
8 nodejs = nodejs-12_x;
9 python = python2;
10 yarn' = yarn.override { inherit nodejs; };
11 defaultYarnOpts = [ "frozen-lockfile" "non-interactive" "no-progress"];
12
13in stdenv.mkDerivation rec {
14 pname = "code-server";
15 version = "3.4.1";
16 commit = "d3773c11f147bdd7a4f5acfefdee23c26f069e76";
17
18 src = fetchFromGitHub {
19 owner = "cdr";
20 repo = "code-server";
21 rev = version;
22 sha256 = "PfDD0waloppGZ09zCQ9ggBeVL/Dhfv6QmEs/fs7QLtA=";
23 fetchSubmodules = true;
24 };
25
26 yarnCache = stdenv.mkDerivation {
27 name = "${pname}-${version}-${system}-yarn-cache";
28 inherit src;
29 phases = ["unpackPhase" "buildPhase"];
30 nativeBuildInputs = [ yarn' git ];
31 buildPhase = ''
32 export HOME=$PWD
33
34 patchShebangs ./ci
35
36 # apply code-server patches as code-server has patched vscode yarn.lock
37 yarn vscode:patch
38
39 yarn config set yarn-offline-mirror $out
40 find "$PWD" -name "yarn.lock" -printf "%h\n" | \
41 xargs -I {} yarn --cwd {} \
42 --frozen-lockfile --ignore-scripts --ignore-platform \
43 --ignore-engines --no-progress --non-interactive
44 '';
45 outputHashMode = "recursive";
46 outputHashAlgo = "sha256";
47
48 # to get hash values use nix-build -A code-server.yarnPrefetchCache
49 outputHash = {
50 x86_64-linux = "Zze2hEm2Np+SyQ0KXy5CZr5wilZbHBYXNYcRJBUUkQo=";
51 aarch64-linux = "LiIvGuBismWSL2yV2DuKUWDjIzuIQU/VVxtiD4xJ+6Q=";
52 }.${system} or (throw "Unsupported system ${system}");
53 };
54
55 # Extract the Node.js source code which is used to compile packages with
56 # native bindings
57 nodeSources = runCommand "node-sources" {} ''
58 tar --no-same-owner --no-same-permissions -xf ${nodejs.src}
59 mv node-* $out
60 '';
61
62 nativeBuildInputs = [
63 nodejs yarn' python pkgconfig zip makeWrapper git rsync jq moreutils
64 ];
65 buildInputs = [ libsecret xorg.libX11 xorg.libxkbfile ];
66
67 patchPhase = ''
68 export HOME=$PWD
69
70 patchShebangs ./ci
71
72 # apply code-server vscode patches
73 yarn vscode:patch
74
75 # allow offline install for vscode
76 substituteInPlace lib/vscode/build/npm/postinstall.js \
77 --replace '--ignore-optional' '--offline'
78
79 # fix path to ifconfig, so vscode can get mac address
80 substituteInPlace lib/vscode/src/vs/base/node/macAddress.ts \
81 --replace '/sbin/ifconfig' '${nettools}/bin/ifconfig'
82
83 # disable automatic updates
84 sed -i '/update.mode/,/\}/{s/default:.*/default: "none",/g}' \
85 lib/vscode/src/vs/platform/update/common/update.config.contribution.ts
86
87 # inject git commit
88 substituteInPlace ci/build/build-release.sh \
89 --replace '$(git rev-parse HEAD)' "$commit"
90
91 # remove all built-in extensions, as these are 3rd party extensions that
92 # gets downloaded from vscode marketplace
93 jq --slurp '.[0] * .[1]' "lib/vscode/product.json" <(
94 cat << EOF
95 {
96 "builtInExtensions": []
97 }
98 EOF
99 ) | sponge lib/vscode/product.json
100 '';
101
102 configurePhase = ''
103 # set default yarn opts
104 ${stdenv.lib.concatMapStrings (option: ''
105 yarn --offline config set ${option}
106 '') defaultYarnOpts}
107
108 # set offline mirror to yarn cache we created in previous steps
109 yarn --offline config set yarn-offline-mirror "${yarnCache}"
110
111 # set nodedir, so we can build binaries later
112 npm config set nodedir "${nodeSources}"
113
114 # skip browser downloads for playwright
115 export PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD="true"
116 '';
117
118 buildPhase = ''
119 # install code-server dependencies
120 yarn --offline
121
122 # install vscode dependencies without running script for all vscode packages
123 # that require patching for postinstall scripts to succeed
124 for d in lib/vscode lib/vscode/build; do
125 yarn --offline --cwd $d --offline --ignore-scripts
126 done
127
128 # put ripgrep binary into bin, so postinstall does not try to download it
129 find -name vscode-ripgrep -type d \
130 -execdir mkdir -p {}/bin \; \
131 -execdir ln -s ${ripgrep}/bin/rg {}/bin/rg \;
132
133 # patch shebangs of everything, also cached files, as otherwise postinstall
134 # will not be able to find /usr/bin/env, as it does not exists in sandbox
135 patchShebangs .
136
137 # rebuild binaries, we use npm here, as yarn does not provider alternative
138 # that would not atempt to try to reinstall everything and break out
139 # patching attempts
140 npm rebuild --prefix lib/vscode --update-binary
141
142 # run postinstall scripts, which eventually do yarn install on all
143 # additional requirements
144 yarn --cwd lib/vscode postinstall --frozen-lockfile --offline
145
146 # build code-server
147 yarn build
148
149 # build vscode
150 yarn build:vscode
151
152 # create release
153 yarn release
154 '';
155
156 installPhase = ''
157 mkdir -p $out/libexec/code-server $out/bin
158
159 # copy release to libexec path
160 cp -R -T release "$out/libexec/code-server"
161
162 # install only production dependencies
163 yarn --offline --cwd "$out/libexec/code-server" --production
164
165 # create wrapper
166 makeWrapper "${nodejs-12_x}/bin/node" "$out/bin/code-server" \
167 --add-flags "$out/libexec/code-server/out/node/entry.js"
168 '';
169
170 passthru = {
171 prefetchYarnCache = stdenv.lib.overrideDerivation yarnCache (d: {
172 outputHash = stdenv.lib.fakeSha256;
173 });
174 };
175
176 meta = with stdenv.lib; {
177 description = "Run VS Code on a remote server.";
178 longDescription = ''
179 code-server is VS Code running on a remote server, accessible through the
180 browser.
181 '';
182 homepage = "https://github.com/cdr/code-server";
183 license = licenses.mit;
184 maintainers = with maintainers; [ offline ];
185 platforms = ["x86_64-linux"];
186 };
187}