diff options
Diffstat (limited to 'editors/code')
-rw-r--r-- | editors/code/src/main.ts | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index ac3bb365e..0a234cb84 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import * as vscode from 'vscode'; | 1 | import * as vscode from 'vscode'; |
2 | import * as path from "path"; | 2 | import * as path from "path"; |
3 | import * as os from "os"; | 3 | import * as os from "os"; |
4 | import { promises as fs } from "fs"; | 4 | import { promises as fs, PathLike } from "fs"; |
5 | 5 | ||
6 | import * as commands from './commands'; | 6 | import * as commands from './commands'; |
7 | import { activateInlayHints } from './inlay_hints'; | 7 | import { activateInlayHints } from './inlay_hints'; |
@@ -12,6 +12,7 @@ import { log, assert, isValidExecutable } from './util'; | |||
12 | import { PersistentState } from './persistent_state'; | 12 | import { PersistentState } from './persistent_state'; |
13 | import { fetchRelease, download } from './net'; | 13 | import { fetchRelease, download } from './net'; |
14 | import { activateTaskProvider } from './tasks'; | 14 | import { activateTaskProvider } from './tasks'; |
15 | import { exec } from 'child_process'; | ||
15 | 16 | ||
16 | let ctx: Ctx | undefined; | 17 | let ctx: Ctx | undefined; |
17 | 18 | ||
@@ -188,6 +189,46 @@ async function bootstrapServer(config: Config, state: PersistentState): Promise< | |||
188 | return path; | 189 | return path; |
189 | } | 190 | } |
190 | 191 | ||
192 | async function patchelf(dest: PathLike): Promise<void> { | ||
193 | await vscode.window.withProgress( | ||
194 | { | ||
195 | location: vscode.ProgressLocation.Notification, | ||
196 | title: "Patching rust-analysis for NixOS" | ||
197 | }, | ||
198 | async (progress, _) => { | ||
199 | let patch_path = path.join(os.tmpdir(), "patch-ra.nix") | ||
200 | progress.report({message: "Writing nix file", increment: 5}) | ||
201 | await fs.writeFile(patch_path, ` | ||
202 | {src, pkgs ? import <nixpkgs> {}}: | ||
203 | pkgs.stdenv.mkDerivation { | ||
204 | name = "rust-analyzer"; | ||
205 | inherit src; | ||
206 | phases = [ "installPhase" "fixupPhase" ]; | ||
207 | installPhase = "cp $src $out"; | ||
208 | fixupPhase = '' | ||
209 | chmod 755 $out | ||
210 | patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out | ||
211 | ''; | ||
212 | } | ||
213 | `) | ||
214 | let orig_file = dest + "-orig" | ||
215 | await fs.rename(dest, orig_file) | ||
216 | progress.report({message: "Patching executable", increment: 20}) | ||
217 | await new Promise((resolve, reject) => { | ||
218 | exec(`nix-build ${patch_path} --arg src '${orig_file}' -o ${dest}`, | ||
219 | (err, stdout, stderr) => { | ||
220 | if (err != null) { | ||
221 | reject(Error(stderr)) | ||
222 | } else { | ||
223 | resolve(stdout) | ||
224 | } | ||
225 | }) | ||
226 | }) | ||
227 | // await fs.unlink(orig_file) | ||
228 | } | ||
229 | ) | ||
230 | } | ||
231 | |||
191 | async function getServer(config: Config, state: PersistentState): Promise<string | undefined> { | 232 | async function getServer(config: Config, state: PersistentState): Promise<string | undefined> { |
192 | const explicitPath = process.env.__RA_LSP_SERVER_DEBUG ?? config.serverPath; | 233 | const explicitPath = process.env.__RA_LSP_SERVER_DEBUG ?? config.serverPath; |
193 | if (explicitPath) { | 234 | if (explicitPath) { |
@@ -237,6 +278,12 @@ async function getServer(config: Config, state: PersistentState): Promise<string | |||
237 | assert(!!artifact, `Bad release: ${JSON.stringify(release)}`); | 278 | assert(!!artifact, `Bad release: ${JSON.stringify(release)}`); |
238 | 279 | ||
239 | await download(artifact.browser_download_url, dest, "Downloading rust-analyzer server", { mode: 0o755 }); | 280 | await download(artifact.browser_download_url, dest, "Downloading rust-analyzer server", { mode: 0o755 }); |
281 | |||
282 | // Patching executable if that's NixOS. | ||
283 | if (fs.stat("/etc/nixos").then(_ => true).catch(_ => false)) { | ||
284 | await patchelf(dest) | ||
285 | } | ||
286 | |||
240 | await state.updateServerVersion(config.package.version); | 287 | await state.updateServerVersion(config.package.version); |
241 | return dest; | 288 | return dest; |
242 | } | 289 | } |