From 0448b7364666ba59b39bbd5564fe8a34b67b8f01 Mon Sep 17 00:00:00 2001 From: wxb1ank Date: Sun, 23 May 2021 22:37:10 -0400 Subject: migrate from `fs` to `vscode.FileSystem` API --- editors/code/src/main.ts | 30 ++++++++++++++---------------- editors/code/src/net.ts | 30 +++++++++++++++--------------- editors/code/src/toolchain.ts | 19 ++++++------------- 3 files changed, 35 insertions(+), 44 deletions(-) diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index fb9d38a14..f58d26215 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -1,7 +1,5 @@ import * as vscode from 'vscode'; -import * as path from "path"; import * as os from "os"; -import { promises as fs, PathLike } from "fs"; import * as commands from './commands'; import { activateInlayHints } from './inlay_hints'; @@ -222,7 +220,7 @@ async function bootstrapExtension(config: Config, state: PersistentState): Promi const artifact = latestNightlyRelease.assets.find(artifact => artifact.name === "rust-analyzer.vsix"); assert(!!artifact, `Bad release: ${JSON.stringify(latestNightlyRelease)}`); - const dest = path.join(config.globalStorageUri.path, "rust-analyzer.vsix"); + const dest = vscode.Uri.joinPath(config.globalStorageUri, "rust-analyzer.vsix"); await downloadWithRetryDialog(state, async () => { await download({ @@ -233,8 +231,8 @@ async function bootstrapExtension(config: Config, state: PersistentState): Promi }); }); - await vscode.commands.executeCommand("workbench.extensions.installExtension", vscode.Uri.file(dest)); - await fs.unlink(dest); + await vscode.commands.executeCommand("workbench.extensions.installExtension", dest); + await vscode.workspace.fs.delete(dest); await state.updateNightlyReleaseId(latestNightlyRelease.id); await state.updateLastCheck(now); @@ -259,7 +257,7 @@ async function bootstrapServer(config: Config, state: PersistentState): Promise< return path; } -async function patchelf(dest: PathLike): Promise { +async function patchelf(dest: vscode.Uri): Promise { await vscode.window.withProgress( { location: vscode.ProgressLocation.Notification, @@ -279,11 +277,11 @@ async function patchelf(dest: PathLike): Promise { ''; } `; - const origFile = dest + "-orig"; - await fs.rename(dest, origFile); + const origFile = vscode.Uri.file(dest.path + "-orig"); + await vscode.workspace.fs.rename(dest, origFile); progress.report({ message: "Patching executable", increment: 20 }); await new Promise((resolve, reject) => { - const handle = exec(`nix-build -E - --argstr srcStr '${origFile}' -o '${dest}'`, + const handle = exec(`nix-build -E - --argstr srcStr '${origFile.path}' -o '${dest.path}'`, (err, stdout, stderr) => { if (err != null) { reject(Error(stderr)); @@ -294,7 +292,7 @@ async function patchelf(dest: PathLike): Promise { handle.stdin?.write(expression); handle.stdin?.end(); }); - await fs.unlink(origFile); + await vscode.workspace.fs.delete(origFile); } ); } @@ -334,20 +332,20 @@ async function getServer(config: Config, state: PersistentState): Promise true, () => false); + const dest = vscode.Uri.joinPath(config.globalStorageUri, `rust-analyzer-${platform}${ext}`); + const exists = await vscode.workspace.fs.stat(dest).then(() => true, () => false); if (!exists) { await state.updateServerVersion(undefined); } - if (state.serverVersion === config.package.version) return dest; + if (state.serverVersion === config.package.version) return dest.path; if (config.askBeforeDownload) { const userResponse = await vscode.window.showInformationMessage( `Language server version ${config.package.version} for rust-analyzer is not installed.`, "Download now" ); - if (userResponse !== "Download now") return dest; + if (userResponse !== "Download now") return dest.path; } const releaseTag = config.package.releaseTag; @@ -374,7 +372,7 @@ async function getServer(config: Config, state: PersistentState): Promise { try { - const contents = await fs.readFile("/etc/os-release"); + const contents = (await vscode.workspace.fs.readFile(vscode.Uri.file("/etc/os-release"))).toString(); return contents.indexOf("ID=nixos") !== -1; } catch (e) { return false; diff --git a/editors/code/src/net.ts b/editors/code/src/net.ts index 07ebc615c..747c02db9 100644 --- a/editors/code/src/net.ts +++ b/editors/code/src/net.ts @@ -73,14 +73,14 @@ export interface GithubRelease { assets: Array<{ name: string; // eslint-disable-next-line camelcase - browser_download_url: string; + browser_download_url: vscode.Uri; }>; } interface DownloadOpts { progressTitle: string; - url: string; - dest: string; + url: vscode.Uri; + dest: vscode.Uri; mode?: number; gunzip?: boolean; httpProxy?: string; @@ -90,9 +90,9 @@ export async function download(opts: DownloadOpts) { // Put artifact into a temporary file (in the same dir for simplicity) // to prevent partially downloaded files when user kills vscode // This also avoids overwriting running executables - const dest = path.parse(opts.dest); const randomHex = crypto.randomBytes(5).toString("hex"); - const tempFile = path.join(dest.dir, `${dest.name}${randomHex}`); + const rawDest = path.parse(opts.dest.path); + const tempFilePath = vscode.Uri.joinPath(vscode.Uri.file(rawDest.dir), `${rawDest.name}${randomHex}`); await vscode.window.withProgress( { @@ -102,7 +102,7 @@ export async function download(opts: DownloadOpts) { }, async (progress, _cancellationToken) => { let lastPercentage = 0; - await downloadFile(opts.url, tempFile, opts.mode, !!opts.gunzip, opts.httpProxy, (readBytes, totalBytes) => { + await downloadFile(opts.url, tempFilePath, opts.mode, !!opts.gunzip, opts.httpProxy, (readBytes, totalBytes) => { const newPercentage = Math.round((readBytes / totalBytes) * 100); if (newPercentage !== lastPercentage) { progress.report({ @@ -116,12 +116,12 @@ export async function download(opts: DownloadOpts) { } ); - await fs.promises.rename(tempFile, opts.dest); + await vscode.workspace.fs.rename(tempFilePath, opts.dest); } async function downloadFile( - url: string, - destFilePath: fs.PathLike, + url: vscode.Uri, + destFilePath: vscode.Uri, mode: number | undefined, gunzip: boolean, httpProxy: string | null | undefined, @@ -129,15 +129,15 @@ async function downloadFile( ): Promise { const res = await (() => { if (httpProxy) { - log.debug(`Downloading ${url} via proxy: ${httpProxy}`); - return fetch(url, { agent: new HttpsProxyAgent(httpProxy) }); + log.debug(`Downloading ${url.path} via proxy: ${httpProxy}`); + return fetch(url.path, { agent: new HttpsProxyAgent(httpProxy) }); } - return fetch(url); + return fetch(url.path); })(); if (!res.ok) { - log.error("Error", res.status, "while downloading file from", url); + log.error("Error", res.status, "while downloading file from", url.path); log.error({ body: await res.text(), headers: res.headers }); throw new Error(`Got response ${res.status} when trying to download a file.`); @@ -146,7 +146,7 @@ async function downloadFile( const totalBytes = Number(res.headers.get('content-length')); assert(!Number.isNaN(totalBytes), "Sanity check of content-length protocol"); - log.debug("Downloading file of", totalBytes, "bytes size from", url, "to", destFilePath); + log.debug("Downloading file of", totalBytes, "bytes size from", url.path, "to", destFilePath.path); let readBytes = 0; res.body.on("data", (chunk: Buffer) => { @@ -154,7 +154,7 @@ async function downloadFile( onProgress(readBytes, totalBytes); }); - const destFileStream = fs.createWriteStream(destFilePath, { mode }); + const destFileStream = fs.createWriteStream(destFilePath.path, { mode }); const srcStream = gunzip ? res.body.pipe(zlib.createGunzip()) : res.body; await pipeline(srcStream, destFileStream); diff --git a/editors/code/src/toolchain.ts b/editors/code/src/toolchain.ts index 68826c478..ba1b8617a 100644 --- a/editors/code/src/toolchain.ts +++ b/editors/code/src/toolchain.ts @@ -1,9 +1,8 @@ import * as cp from 'child_process'; import * as os from 'os'; import * as path from 'path'; -import * as fs from 'fs'; import * as readline from 'readline'; -import { OutputChannel } from 'vscode'; +import * as vscode from 'vscode'; import { execute, log, memoize } from './util'; interface CompilationArtifact { @@ -19,7 +18,7 @@ export interface ArtifactSpec { } export class Cargo { - constructor(readonly rootFolder: string, readonly output: OutputChannel) { } + constructor(readonly rootFolder: string, readonly output: vscode.OutputChannel) { } // Made public for testing purposes static artifactSpec(args: readonly string[]): ArtifactSpec { @@ -158,9 +157,9 @@ export const getPathForExecutable = memoize( try { // hmm, `os.homedir()` seems to be infallible // it is not mentioned in docs and cannot be infered by the type signature... - const standardPath = path.join(os.homedir(), ".cargo", "bin", executableName); + const standardPath = vscode.Uri.joinPath(vscode.Uri.file(os.homedir()), ".cargo", "bin", executableName); - if (isFile(standardPath)) return standardPath; + if (isFile(standardPath.path)) return standardPath.path; } catch (err) { log.error("Failed to read the fs info", err); } @@ -181,12 +180,6 @@ function lookupInPath(exec: string): boolean { return candidates.some(isFile); } -function isFile(suspectPath: string): boolean { - // It is not mentionned in docs, but `statSync()` throws an error when - // the path doesn't exist - try { - return fs.statSync(suspectPath).isFile(); - } catch { - return false; - } +async function isFile(path: string): Promise { + return ((await vscode.workspace.fs.stat(vscode.Uri.file(path))).type & vscode.FileType.File) != 0; } -- cgit v1.2.3