|
21 | 21 | enableFHS ? false,
|
22 | 22 | nodejsPackage ? null,
|
23 | 23 | extraRuntimeDependencies ? [ ],
|
24 |
| - installPath ? "~/.vscode-server", |
| 24 | + installPath ? "$HOME/.vscode-server", |
25 | 25 | postPatch ? "",
|
26 | 26 | }: let
|
27 | 27 | inherit (lib) makeBinPath makeLibraryPath optionalString;
|
|
71 | 71 | name = "patchelf-vscode-server";
|
72 | 72 | runtimeInputs = [ coreutils findutils patchelf ];
|
73 | 73 | text = ''
|
74 |
| - bin=$1 |
75 |
| - bin_dir=${installPath}/bin/$bin |
76 |
| - patched_file=${installPath}/.$bin.patched |
77 |
| - orig_node=${installPath}/.$bin.node |
| 74 | + bin_dir="$1" |
| 75 | + patched_file="$bin_dir/.nixos-patched" |
78 | 76 |
|
79 | 77 | # NOTE: We don't log here because it won't show up in the output of the user service.
|
80 | 78 |
|
|
109 | 107 | patchelf --shrink-rpath "$elf"
|
110 | 108 | }
|
111 | 109 |
|
112 |
| - patch_elf "$orig_node" |
113 | 110 | while read -rd ''' elf; do
|
114 | 111 | patch_elf "$elf"
|
115 | 112 | done < <(find "$bin_dir" -type f -perm -100 -printf '%p\0')
|
|
126 | 123 | name = "auto-fix-vscode-server";
|
127 | 124 | runtimeInputs = [ coreutils findutils inotify-tools ];
|
128 | 125 | text = ''
|
129 |
| - bins_dir=${installPath}/bin |
| 126 | + bins_dir_1=${installPath}/bin |
| 127 | + bins_dir_2=${installPath}/cli/servers |
130 | 128 |
|
131 | 129 | patch_bin () {
|
132 |
| - local bin=$1 |
133 |
| - bin=''${bin:0:40} |
134 |
| - local actual_dir=$bins_dir/$1 |
135 |
| - local patched_file=${installPath}/.$bin.patched |
| 130 | + local actual_dir="$1" |
| 131 | + local patched_file="$actual_dir/.nixos-patched" |
136 | 132 |
|
137 | 133 | if [[ -e $patched_file ]]; then
|
138 | 134 | return 0
|
139 | 135 | fi
|
140 | 136 |
|
| 137 | + # Backwards compatibility with previous versions of nixos-vscode-server. |
| 138 | + local old_patched_file |
| 139 | + old_patched_file="$(basename "$actual_dir")" |
| 140 | + if [[ $old_patched_file == "server" ]]; then |
| 141 | + old_patched_file="$(basename "$(dirname "$actual_dir")")" |
| 142 | + old_patched_file="${installPath}/.''${old_patched_file%%.*}.patched" |
| 143 | + else |
| 144 | + old_patched_file="${installPath}/.''${old_patched_file%%-*}.patched" |
| 145 | + fi |
| 146 | + if [[ -e $old_patched_file ]]; then |
| 147 | + echo "Migrating old nixos-vscode-server patch marker file to new location in $actual_dir." >&2 |
| 148 | + cp "$old_patched_file" "$patched_file" |
| 149 | + return 0 |
| 150 | + fi |
| 151 | +
|
141 | 152 | echo "Patching Node.js of VS Code server installation in $actual_dir..." >&2
|
142 | 153 |
|
143 |
| - ${optionalString (nodejs != null) '' |
144 |
| - ln -sfT ${ |
145 |
| - if enableFHS |
146 |
| - then nodejsFHS |
147 |
| - else nodejs |
148 |
| - }/bin/node "$actual_dir/node" |
| 154 | + mv "$actual_dir/node" "$actual_dir/node.patched" |
| 155 | +
|
| 156 | + ${optionalString (enableFHS) '' |
| 157 | + ln -sfT ${nodejsFHS}/bin/node "$actual_dir/node" |
149 | 158 | ''}
|
150 | 159 |
|
151 | 160 | ${optionalString (!enableFHS || postPatch != "") ''
|
152 |
| - local orig_node=${installPath}/.$bin.node |
153 |
| - mv "$actual_dir/node" "$orig_node" |
154 | 161 | cat <<EOF > "$actual_dir/node"
|
155 | 162 | #!${runtimeShell}
|
156 | 163 |
|
|
159 | 166 |
|
160 | 167 | # We leave the rest up to the Bash script
|
161 | 168 | # to keep having to deal with 'sh' compatibility to a minimum.
|
162 |
| - ${patchELFScript}/bin/patchelf-vscode-server '$bin' |
| 169 | + ${patchELFScript}/bin/patchelf-vscode-server \$(dirname "\$0") |
163 | 170 |
|
164 | 171 | # Let Node.js take over as if this script never existed.
|
165 |
| - exec '$orig_node' "\$@" |
| 172 | + ${ |
| 173 | + let nodePath = (if (nodejs != null) |
| 174 | + then "${if enableFHS then nodejsFHS else nodejs}/bin/node" |
| 175 | + else ''\$(dirname "\$0")/node.patched''); |
| 176 | + in ''exec "${nodePath}" "\$@"'' |
| 177 | + } |
166 | 178 | EOF
|
167 | 179 | chmod +x "$actual_dir/node"
|
168 | 180 | ''}
|
|
171 | 183 | echo 0 > "$patched_file"
|
172 | 184 | }
|
173 | 185 |
|
174 |
| - # Fix any existing symlinks before we enter the inotify loop. |
175 |
| - if [[ -e $bins_dir ]]; then |
176 |
| - while read -rd ''' bin; do |
177 |
| - patch_bin "$bin" |
178 |
| - done < <(find "$bins_dir" -mindepth 1 -maxdepth 1 -type d -printf '%P\0') |
179 |
| - else |
180 |
| - mkdir -p "$bins_dir" |
181 |
| - fi |
182 |
| -
|
183 |
| - while IFS=: read -r bin event; do |
| 186 | + mkdir -p "$bins_dir_1" "$bins_dir_2" |
| 187 | + while read -rd ''' bin; do |
| 188 | + if [[ $bin == "$bins_dir_2"* ]]; then |
| 189 | + bin="$bin/server" |
| 190 | + fi |
| 191 | + patch_bin "$bin" |
| 192 | + done < <(find "$bins_dir_1" "$bins_dir_2" -mindepth 1 -maxdepth 1 -type d -printf '%p\0') |
| 193 | + |
| 194 | + while IFS=: read -r bins_dir bin event; do |
184 | 195 | # A new version of the VS Code Server is being created.
|
185 | 196 | if [[ $event == 'CREATE,ISDIR' ]]; then
|
186 |
| - actual_dir=$bins_dir/$bin |
| 197 | + actual_dir="$bins_dir$bin" |
| 198 | + if [[ "$bins_dir" == "$bins_dir_2/" ]]; then |
| 199 | + actual_dir="$actual_dir/server" |
| 200 | + # Hope that VSCode will not die if the directory exists when it tries to install, otherwise we'll need to |
| 201 | + # use a coproc to wait for the directory to be created without entering in a race, then watch for the node |
| 202 | + # file to be created (probably while also avoiding a race) |
| 203 | + # https://unix.stackexchange.com/a/185370 |
| 204 | + mkdir -p "$actual_dir" |
| 205 | + fi |
187 | 206 | echo "VS Code server is being installed in $actual_dir..." >&2
|
| 207 | + # Quickly create a node file, which will be removed when vscode installs its own version |
188 | 208 | touch "$actual_dir/node"
|
| 209 | + # Hope we don't race... |
189 | 210 | inotifywait -qq -e DELETE_SELF "$actual_dir/node"
|
190 |
| - patch_bin "$bin" |
| 211 | + patch_bin "$actual_dir" |
191 | 212 | # The monitored directory is deleted, e.g. when "Uninstall VS Code Server from Host" has been run.
|
192 | 213 | elif [[ $event == DELETE_SELF ]]; then
|
193 | 214 | # See the comments above Restart in the service config.
|
194 | 215 | exit 0
|
195 | 216 | fi
|
196 |
| - done < <(inotifywait -q -m -e CREATE,ISDIR -e DELETE_SELF --format '%f:%e' "$bins_dir") |
| 217 | + done < <(inotifywait -q -m -e CREATE,ISDIR -e DELETE_SELF --format '%w:%f:%e' "$bins_dir_1" "$bins_dir_2") |
197 | 218 | '';
|
198 | 219 | };
|
199 | 220 | in
|
200 |
| - autoFixScript |
| 221 | +autoFixScript |
0 commit comments