From 8203828bb081faae4cd9d39c8abe6bc073138176 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 9 Mar 2020 19:54:40 +0200 Subject: vscode-prerefactor: merge two files into downloads.ts --- editors/code/src/installation/download_artifact.ts | 50 ----------- editors/code/src/installation/download_file.ts | 51 ------------ editors/code/src/installation/downloads.ts | 97 ++++++++++++++++++++++ 3 files changed, 97 insertions(+), 101 deletions(-) delete mode 100644 editors/code/src/installation/download_artifact.ts delete mode 100644 editors/code/src/installation/download_file.ts create mode 100644 editors/code/src/installation/downloads.ts (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/download_artifact.ts b/editors/code/src/installation/download_artifact.ts deleted file mode 100644 index 97e4d67c2..000000000 --- a/editors/code/src/installation/download_artifact.ts +++ /dev/null @@ -1,50 +0,0 @@ -import * as vscode from "vscode"; -import * as path from "path"; -import { promises as fs } from "fs"; - -import { ArtifactReleaseInfo } from "./interfaces"; -import { downloadFile } from "./download_file"; -import { assert } from "../util"; - -/** - * Downloads artifact from given `downloadUrl`. - * Creates `installationDir` if it is not yet created and put the artifact under - * `artifactFileName`. - * Displays info about the download progress in an info message printing the name - * of the artifact as `displayName`. - */ -export async function downloadArtifact( - { downloadUrl, releaseName }: ArtifactReleaseInfo, - artifactFileName: string, - installationDir: string, - displayName: string, -) { - await fs.mkdir(installationDir).catch(err => assert( - err?.code === "EEXIST", - `Couldn't create directory "${installationDir}" to download ` + - `${artifactFileName} artifact: ${err?.message}` - )); - - const installationPath = path.join(installationDir, artifactFileName); - - await vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - cancellable: false, // FIXME: add support for canceling download? - title: `Downloading ${displayName} (${releaseName})` - }, - async (progress, _cancellationToken) => { - let lastPrecentage = 0; - const filePermissions = 0o755; // (rwx, r_x, r_x) - await downloadFile(downloadUrl, installationPath, filePermissions, (readBytes, totalBytes) => { - const newPercentage = (readBytes / totalBytes) * 100; - progress.report({ - message: newPercentage.toFixed(0) + "%", - increment: newPercentage - lastPrecentage - }); - - lastPrecentage = newPercentage; - }); - } - ); -} diff --git a/editors/code/src/installation/download_file.ts b/editors/code/src/installation/download_file.ts deleted file mode 100644 index ee8949d61..000000000 --- a/editors/code/src/installation/download_file.ts +++ /dev/null @@ -1,51 +0,0 @@ -import fetch from "node-fetch"; -import * as fs from "fs"; -import * as stream from "stream"; -import * as util from "util"; -import { log, assert } from "../util"; - -const pipeline = util.promisify(stream.pipeline); - -/** - * Downloads file from `url` and stores it at `destFilePath` with `destFilePermissions`. - * `onProgress` callback is called on recieveing each chunk of bytes - * to track the progress of downloading, it gets the already read and total - * amount of bytes to read as its parameters. - */ -export async function downloadFile( - url: string, - destFilePath: fs.PathLike, - destFilePermissions: number, - onProgress: (readBytes: number, totalBytes: number) => void -): Promise { - const res = await fetch(url); - - if (!res.ok) { - log.error("Error", res.status, "while downloading file from", url); - log.error({ body: await res.text(), headers: res.headers }); - - throw new Error(`Got response ${res.status} when trying to download a file.`); - } - - 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); - - let readBytes = 0; - res.body.on("data", (chunk: Buffer) => { - readBytes += chunk.length; - onProgress(readBytes, totalBytes); - }); - - const destFileStream = fs.createWriteStream(destFilePath, { mode: destFilePermissions }); - - await pipeline(res.body, destFileStream); - return new Promise(resolve => { - destFileStream.on("close", resolve); - destFileStream.destroy(); - - // Details on workaround: https://github.com/rust-analyzer/rust-analyzer/pull/3092#discussion_r378191131 - // Issue at nodejs repo: https://github.com/nodejs/node/issues/31776 - }); -} diff --git a/editors/code/src/installation/downloads.ts b/editors/code/src/installation/downloads.ts new file mode 100644 index 000000000..7ce2e2960 --- /dev/null +++ b/editors/code/src/installation/downloads.ts @@ -0,0 +1,97 @@ +import fetch from "node-fetch"; +import * as vscode from "vscode"; +import * as path from "path"; +import * as fs from "fs"; +import * as stream from "stream"; +import * as util from "util"; +import { log, assert } from "../util"; +import { ArtifactReleaseInfo } from "./interfaces"; + +const pipeline = util.promisify(stream.pipeline); + +/** + * Downloads file from `url` and stores it at `destFilePath` with `destFilePermissions`. + * `onProgress` callback is called on recieveing each chunk of bytes + * to track the progress of downloading, it gets the already read and total + * amount of bytes to read as its parameters. + */ +export async function downloadFile( + url: string, + destFilePath: fs.PathLike, + destFilePermissions: number, + onProgress: (readBytes: number, totalBytes: number) => void +): Promise { + const res = await fetch(url); + + if (!res.ok) { + log.error("Error", res.status, "while downloading file from", url); + log.error({ body: await res.text(), headers: res.headers }); + + throw new Error(`Got response ${res.status} when trying to download a file.`); + } + + 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); + + let readBytes = 0; + res.body.on("data", (chunk: Buffer) => { + readBytes += chunk.length; + onProgress(readBytes, totalBytes); + }); + + const destFileStream = fs.createWriteStream(destFilePath, { mode: destFilePermissions }); + + await pipeline(res.body, destFileStream); + return new Promise(resolve => { + destFileStream.on("close", resolve); + destFileStream.destroy(); + + // Details on workaround: https://github.com/rust-analyzer/rust-analyzer/pull/3092#discussion_r378191131 + // Issue at nodejs repo: https://github.com/nodejs/node/issues/31776 + }); +} + +/** + * Downloads artifact from given `downloadUrl`. + * Creates `installationDir` if it is not yet created and puts the artifact under + * `artifactFileName`. + * Displays info about the download progress in an info message printing the name + * of the artifact as `displayName`. + */ +export async function downloadArtifactWithProgressUi( + { downloadUrl, releaseName }: ArtifactReleaseInfo, + artifactFileName: string, + installationDir: string, + displayName: string, +) { + await fs.promises.mkdir(installationDir).catch(err => assert( + err?.code === "EEXIST", + `Couldn't create directory "${installationDir}" to download ` + + `${artifactFileName} artifact: ${err?.message}` + )); + + const installationPath = path.join(installationDir, artifactFileName); + + await vscode.window.withProgress( + { + location: vscode.ProgressLocation.Notification, + cancellable: false, // FIXME: add support for canceling download? + title: `Downloading rust-analyzer ${displayName} (${releaseName})` + }, + async (progress, _cancellationToken) => { + let lastPrecentage = 0; + const filePermissions = 0o755; // (rwx, r_x, r_x) + await downloadFile(downloadUrl, installationPath, filePermissions, (readBytes, totalBytes) => { + const newPercentage = (readBytes / totalBytes) * 100; + progress.report({ + message: newPercentage.toFixed(0) + "%", + increment: newPercentage - lastPrecentage + }); + + lastPrecentage = newPercentage; + }); + } + ); +} -- cgit v1.2.3 From 0f826aec8280cf1593e1b1e265cced6f7e5d84d7 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 9 Mar 2020 19:55:26 +0200 Subject: vscode: get release date from release info --- .../src/installation/fetch_artifact_release_info.ts | 3 +++ editors/code/src/installation/interfaces.ts | 18 ++++-------------- 2 files changed, 7 insertions(+), 14 deletions(-) (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/fetch_artifact_release_info.ts b/editors/code/src/installation/fetch_artifact_release_info.ts index b1b5a3485..1ad3b8338 100644 --- a/editors/code/src/installation/fetch_artifact_release_info.ts +++ b/editors/code/src/installation/fetch_artifact_release_info.ts @@ -59,12 +59,15 @@ export async function fetchArtifactReleaseInfo( return { releaseName: release.name, + releaseDate: new Date(release.published_at), downloadUrl: artifact.browser_download_url }; // We omit declaration of tremendous amount of fields that we are not using here interface GithubRelease { name: string; + // eslint-disable-next-line camelcase + published_at: string; assets: Array<{ name: string; // eslint-disable-next-line camelcase diff --git a/editors/code/src/installation/interfaces.ts b/editors/code/src/installation/interfaces.ts index 50b635921..1a8ea0884 100644 --- a/editors/code/src/installation/interfaces.ts +++ b/editors/code/src/installation/interfaces.ts @@ -1,5 +1,3 @@ -import * as vscode from "vscode"; - export interface GithubRepo { name: string; owner: string; @@ -9,6 +7,7 @@ export interface GithubRepo { * Metadata about particular artifact retrieved from GitHub releases. */ export interface ArtifactReleaseInfo { + releaseDate: Date; releaseName: string; downloadUrl: string; } @@ -42,6 +41,9 @@ export namespace ArtifactSource { */ repo: GithubRepo; + + // FIXME: add installationPath: string; + /** * Directory on the filesystem where the bundled binary is stored. */ @@ -57,17 +59,5 @@ export namespace ArtifactSource { * Tag of github release that denotes a version required by this extension. */ tag: string; - - /** - * Object that provides `get()/update()` operations to store metadata - * about the actual binary, e.g. its actual version. - */ - storage: vscode.Memento; - - /** - * Ask for the user permission before downloading the artifact. - */ - askBeforeDownload: boolean; } - } -- cgit v1.2.3 From 601fc9d1abf52c16356d49b6c540b31718e62b88 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 9 Mar 2020 19:57:34 +0200 Subject: vscode: add nightly extension installation logic --- editors/code/src/installation/extension.ts | 131 +++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 editors/code/src/installation/extension.ts (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/extension.ts b/editors/code/src/installation/extension.ts new file mode 100644 index 000000000..7709cd3cd --- /dev/null +++ b/editors/code/src/installation/extension.ts @@ -0,0 +1,131 @@ +import * as vscode from "vscode"; +import * as path from "path"; +import { promises as fs } from 'fs'; + +import { vscodeReinstallExtension, vscodeReloadWindow, log, vscodeInstallExtensionFromVsix, assert, notReentrant } from "../util"; +import { Config, UpdatesChannel } from "../config"; +import { ArtifactReleaseInfo } from "./interfaces"; +import { downloadArtifactWithProgressUi } from "./downloads"; +import { fetchArtifactReleaseInfo } from "./fetch_artifact_release_info"; + +const HEURISTIC_NIGHTLY_RELEASE_PERIOD_IN_HOURS = 25; + +/** + * Installs `stable` or latest `nightly` version or does nothing if the current + * extension version is what's needed according to `desiredUpdateChannel`. + */ +export async function ensureProperExtensionVersion(config: Config): Promise { + const currentUpdChannel = config.installedExtensionUpdateChannel; + const desiredUpdChannel = config.updatesChannel; + + if (currentUpdChannel === UpdatesChannel.Stable) { + // Release date is present only when we are on nightly + config.installedNightlyExtensionReleaseDate.set(null); + } + + // User has built lsp server from sources, she should manage updates manually + if (currentUpdChannel === null) return; + + if (desiredUpdChannel === UpdatesChannel.Stable) { + // VSCode should handle updates for stable channel + if (currentUpdChannel === UpdatesChannel.Stable) return; + + if (!await askToDownloadProperExtensionVersion(config)) return; + + await vscodeReinstallExtension(config.extensionId); + await vscodeReloadWindow(); // never returns + } + + if (currentUpdChannel === UpdatesChannel.Stable) { + if (!await askToDownloadProperExtensionVersion(config)) return; + + return await tryDownloadNightlyExtension(config); + } + + const currentExtReleaseDate = config.installedNightlyExtensionReleaseDate.get(); + + assert(currentExtReleaseDate !== null, "nightly release date must've been set during installation"); + + const hoursSinceLastUpdate = diffInHours(currentExtReleaseDate, new Date()); + log.debug(`Current rust-analyzer nightly was downloaded ${hoursSinceLastUpdate} hours ago`); + + if (hoursSinceLastUpdate < HEURISTIC_NIGHTLY_RELEASE_PERIOD_IN_HOURS) { + return; + } + if (!await askToDownloadProperExtensionVersion(config, "The installed nightly version is most likely outdated. ")) { + return; + } + + await tryDownloadNightlyExtension(config, releaseInfo => { + assert( + currentExtReleaseDate === config.installedNightlyExtensionReleaseDate.get(), + "Other active VSCode instance has reinstalled the extension" + ); + + if (releaseInfo.releaseDate === currentExtReleaseDate) { + vscode.window.showInformationMessage( + "Whoops, it appears that your nightly version is up-to-date. " + + "There might be some problems with the upcomming nightly release " + + "or you traveled too far into the future. Sorry for that 😅! " + ); + return false; + } + return true; + }); +} + +async function askToDownloadProperExtensionVersion(config: Config, reason = "") { + if (!config.askBeforeDownload) return true; + + const stableOrNightly = config.updatesChannel === UpdatesChannel.Stable ? "stable" : "latest nightly"; + + // In case of reentering this function and showing the same info message + // (e.g. after we had shown this message, the user changed the config) + // vscode will dismiss the already shown one (i.e. return undefined). + // This behaviour is what we want, but likely it is not documented + + const userResponse = await vscode.window.showInformationMessage( + reason + `Do you want to download the ${stableOrNightly} rust-analyzer extension ` + + `version and reload the window now?`, + "Download now", "Cancel" + ); + log.debug("Response: ", userResponse); + return userResponse === "Download now"; +} + +/** + * Shutdowns the process in case of success (i.e. reloads the window) or throws an error. + */ +const tryDownloadNightlyExtension = notReentrant(async function tryDownloadNightlyExtension( + config: Config, + shouldDownload: (releaseInfo: ArtifactReleaseInfo) => boolean = () => true +): Promise { + const vsixSource = config.nightlyVsixSource; + try { + const releaseInfo = await fetchArtifactReleaseInfo(vsixSource.repo, vsixSource.file, vsixSource.tag); + + if (!shouldDownload(releaseInfo)) return; + + await downloadArtifactWithProgressUi(releaseInfo, vsixSource.file, vsixSource.dir, "nightly extension"); + + const vsixPath = path.join(vsixSource.dir, vsixSource.file); + + await vscodeInstallExtensionFromVsix(vsixPath) + await config.installedNightlyExtensionReleaseDate.set(releaseInfo.releaseDate); + await fs.unlink(vsixPath); + + await vscodeReloadWindow(); // never returns + } catch (err) { + log.downloadError(err, "nightly extension", vsixSource.repo.name); + } +}); + +function diffInHours(a: Date, b: Date): number { + // Discard the time and time-zone information (to abstract from daylight saving time bugs) + // https://stackoverflow.com/a/15289883/9259330 + + const utcA = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate()); + const utcB = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate()); + + return (utcA - utcB) / (1000 * 60 * 60); +} -- cgit v1.2.3 From 1e73811fbe634efec90a3e009a84fd8dda9f5697 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 9 Mar 2020 19:57:55 +0200 Subject: vscode: amend server installation logic to account for nightlies --- editors/code/src/installation/server.ts | 97 ++++++++++++++++----------------- 1 file changed, 48 insertions(+), 49 deletions(-) (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/server.ts b/editors/code/src/installation/server.ts index ef1c45ff6..345f30d47 100644 --- a/editors/code/src/installation/server.ts +++ b/editors/code/src/installation/server.ts @@ -1,14 +1,16 @@ import * as vscode from "vscode"; import * as path from "path"; -import { promises as dns } from "dns"; import { spawnSync } from "child_process"; import { ArtifactSource } from "./interfaces"; import { fetchArtifactReleaseInfo } from "./fetch_artifact_release_info"; -import { downloadArtifact } from "./download_artifact"; +import { downloadArtifactWithProgressUi } from "./downloads"; import { log, assert } from "../util"; +import { Config, NIGHTLY_TAG } from "../config"; + +export async function ensureServerBinary(config: Config): Promise { + const source = config.serverSource; -export async function ensureServerBinary(source: null | ArtifactSource): Promise { if (!source) { vscode.window.showErrorMessage( "Unfortunately we don't ship binaries for your platform yet. " + @@ -35,18 +37,11 @@ export async function ensureServerBinary(source: null | ArtifactSource): Promise return null; } case ArtifactSource.Type.GithubRelease: { - const prebuiltBinaryPath = path.join(source.dir, source.file); - - const installedVersion: null | string = getServerVersion(source.storage); - const requiredVersion: string = source.tag; - - log.debug("Installed version:", installedVersion, "required:", requiredVersion); - - if (isBinaryAvailable(prebuiltBinaryPath) && installedVersion === requiredVersion) { - return prebuiltBinaryPath; + if (!shouldDownloadServer(source, config)) { + return path.join(source.dir, source.file); } - if (source.askBeforeDownload) { + if (config.askBeforeDownload) { const userResponse = await vscode.window.showInformationMessage( `Language server version ${source.tag} for rust-analyzer is not installed. ` + "Do you want to download it now?", @@ -55,38 +50,53 @@ export async function ensureServerBinary(source: null | ArtifactSource): Promise if (userResponse !== "Download now") return null; } - if (!await downloadServer(source)) return null; - - return prebuiltBinaryPath; + return await downloadServer(source, config); } } } -async function downloadServer(source: ArtifactSource.GithubRelease): Promise { +function shouldDownloadServer( + source: ArtifactSource.GithubRelease, + config: Config +): boolean { + if (!isBinaryAvailable(path.join(source.dir, source.file))) return true; + + const installed = { + tag: config.serverReleaseTag.get(), + date: config.serverReleaseDate.get() + }; + const required = { + tag: source.tag, + date: config.installedNightlyExtensionReleaseDate.get() + }; + + log.debug("Installed server:", installed, "required:", required); + + if (required.tag !== NIGHTLY_TAG || installed.tag !== NIGHTLY_TAG) { + return required.tag !== installed.tag; + } + + assert(required.date !== null, "Extension release date should have been saved during its installation"); + assert(installed.date !== null, "Server release date should have been saved during its installation"); + + return installed.date.getTime() !== required.date.getTime(); +} + +async function downloadServer( + source: ArtifactSource.GithubRelease, + config: Config, +): Promise { try { const releaseInfo = await fetchArtifactReleaseInfo(source.repo, source.file, source.tag); - await downloadArtifact(releaseInfo, source.file, source.dir, "language server"); - await setServerVersion(source.storage, releaseInfo.releaseName); + await downloadArtifactWithProgressUi(releaseInfo, source.file, source.dir, "language server"); + await Promise.all([ + config.serverReleaseTag.set(releaseInfo.releaseName), + config.serverReleaseDate.set(releaseInfo.releaseDate) + ]); } catch (err) { - vscode.window.showErrorMessage( - `Failed to download language server from ${source.repo.name} ` + - `GitHub repository: ${err.message}` - ); - - log.error(err); - - dns.resolve('example.com').then( - addrs => log.debug("DNS resolution for example.com was successful", addrs), - err => { - log.error( - "DNS resolution for example.com failed, " + - "there might be an issue with Internet availability" - ); - log.error(err); - } - ); - return false; + log.downloadError(err, "language server", source.repo.name); + return null; } const binaryPath = path.join(source.dir, source.file); @@ -101,7 +111,7 @@ async function downloadServer(source: ArtifactSource.GithubRelease): Promise("server-version", null); - log.debug("Get server-version:", version); - return version; -} - -async function setServerVersion(storage: vscode.Memento, version: string): Promise { - log.debug("Set server-version:", version); - await storage.update("server-version", version.toString()); -} -- cgit v1.2.3 From 7e6b1a60c3d7b20e1b4cee2ab210b617e359a002 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 9 Mar 2020 20:04:11 +0200 Subject: vscode: npm run fix --- editors/code/src/installation/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/extension.ts b/editors/code/src/installation/extension.ts index 7709cd3cd..7eab68852 100644 --- a/editors/code/src/installation/extension.ts +++ b/editors/code/src/installation/extension.ts @@ -110,7 +110,7 @@ const tryDownloadNightlyExtension = notReentrant(async function tryDownloadNight const vsixPath = path.join(vsixSource.dir, vsixSource.file); - await vscodeInstallExtensionFromVsix(vsixPath) + await vscodeInstallExtensionFromVsix(vsixPath); await config.installedNightlyExtensionReleaseDate.set(releaseInfo.releaseDate); await fs.unlink(vsixPath); -- cgit v1.2.3 From 4d17152b31b27a8c851b4b1abaff359044ee9d96 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 9 Mar 2020 20:14:55 +0200 Subject: vscode: make bailing out on custom serverPath more evident --- editors/code/src/installation/extension.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/extension.ts b/editors/code/src/installation/extension.ts index 7eab68852..a0925acaa 100644 --- a/editors/code/src/installation/extension.ts +++ b/editors/code/src/installation/extension.ts @@ -15,6 +15,9 @@ const HEURISTIC_NIGHTLY_RELEASE_PERIOD_IN_HOURS = 25; * extension version is what's needed according to `desiredUpdateChannel`. */ export async function ensureProperExtensionVersion(config: Config): Promise { + // User has built lsp server from sources, she should manage updates manually + if (config.serverPath !== null) return; + const currentUpdChannel = config.installedExtensionUpdateChannel; const desiredUpdChannel = config.updatesChannel; @@ -23,9 +26,6 @@ export async function ensureProperExtensionVersion(config: Config): Promise Date: Mon, 9 Mar 2020 20:35:21 +0200 Subject: vscode-postrefactor: eliminate my-mistake floating promise @matklad --- editors/code/src/installation/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/extension.ts b/editors/code/src/installation/extension.ts index a0925acaa..d0782ad13 100644 --- a/editors/code/src/installation/extension.ts +++ b/editors/code/src/installation/extension.ts @@ -23,7 +23,7 @@ export async function ensureProperExtensionVersion(config: Config): Promise Date: Mon, 9 Mar 2020 20:41:23 +0200 Subject: vscode-postrefactor: compare dates by value, not by reference --- editors/code/src/installation/extension.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/extension.ts b/editors/code/src/installation/extension.ts index d0782ad13..3a1481a89 100644 --- a/editors/code/src/installation/extension.ts +++ b/editors/code/src/installation/extension.ts @@ -58,11 +58,11 @@ export async function ensureProperExtensionVersion(config: Config): Promise { assert( - currentExtReleaseDate === config.installedNightlyExtensionReleaseDate.get(), + currentExtReleaseDate.getTime() === config.installedNightlyExtensionReleaseDate.get()?.getTime(), "Other active VSCode instance has reinstalled the extension" ); - if (releaseInfo.releaseDate === currentExtReleaseDate) { + if (releaseInfo.releaseDate.getTime() === currentExtReleaseDate.getTime()) { vscode.window.showInformationMessage( "Whoops, it appears that your nightly version is up-to-date. " + "There might be some problems with the upcomming nightly release " + -- cgit v1.2.3 From abee777b6ec842eef6609475b2bf623e9490fd7e Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 9 Mar 2020 20:57:20 +0200 Subject: vscode-postrefactor: remove remainders of debug logging --- editors/code/src/installation/extension.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/extension.ts b/editors/code/src/installation/extension.ts index 3a1481a89..eb6acc341 100644 --- a/editors/code/src/installation/extension.ts +++ b/editors/code/src/installation/extension.ts @@ -89,7 +89,6 @@ async function askToDownloadProperExtensionVersion(config: Config, reason = "") `version and reload the window now?`, "Download now", "Cancel" ); - log.debug("Response: ", userResponse); return userResponse === "Download now"; } -- cgit v1.2.3 From c2b0fffe3d08d4819ca073c5821869b38784328d Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 9 Mar 2020 21:02:19 +0200 Subject: vscode-postrefactor: add achtung comment --- editors/code/src/installation/extension.ts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/extension.ts b/editors/code/src/installation/extension.ts index eb6acc341..87a587403 100644 --- a/editors/code/src/installation/extension.ts +++ b/editors/code/src/installation/extension.ts @@ -94,6 +94,10 @@ async function askToDownloadProperExtensionVersion(config: Config, reason = "") /** * Shutdowns the process in case of success (i.e. reloads the window) or throws an error. + * + * ACHTUNG!: this function has a crazy amount of state transitions, handling errors during + * each of them would result in a ton of code (especially accounting for cross-process + * shared mutable `globalState` access). Enforcing reentrancy for this is best-effort. */ const tryDownloadNightlyExtension = notReentrant(async function tryDownloadNightlyExtension( config: Config, -- cgit v1.2.3 From 7f02d4657b796a438e441e107d4fb1906ec1ed7b Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sat, 14 Mar 2020 02:00:34 +0200 Subject: vscode-postrefactor: minor config refactorings --- editors/code/src/installation/extension.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/extension.ts b/editors/code/src/installation/extension.ts index 87a587403..2022d090d 100644 --- a/editors/code/src/installation/extension.ts +++ b/editors/code/src/installation/extension.ts @@ -4,7 +4,7 @@ import { promises as fs } from 'fs'; import { vscodeReinstallExtension, vscodeReloadWindow, log, vscodeInstallExtensionFromVsix, assert, notReentrant } from "../util"; import { Config, UpdatesChannel } from "../config"; -import { ArtifactReleaseInfo } from "./interfaces"; +import { ArtifactReleaseInfo, ArtifactSource } from "./interfaces"; import { downloadArtifactWithProgressUi } from "./downloads"; import { fetchArtifactReleaseInfo } from "./fetch_artifact_release_info"; @@ -16,7 +16,7 @@ const HEURISTIC_NIGHTLY_RELEASE_PERIOD_IN_HOURS = 25; */ export async function ensureProperExtensionVersion(config: Config): Promise { // User has built lsp server from sources, she should manage updates manually - if (config.serverPath !== null) return; + if (config.serverSource?.type === ArtifactSource.Type.ExplicitPath) return; const currentUpdChannel = config.installedExtensionUpdateChannel; const desiredUpdChannel = config.updatesChannel; -- cgit v1.2.3 From d7b46e0527cd7b52845f37cffc57cbae4ba0b945 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sat, 14 Mar 2020 02:01:28 +0200 Subject: vscode-postrefactor: enforcing more reentrancy --- editors/code/src/installation/extension.ts | 2 +- editors/code/src/installation/server.ts | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/extension.ts b/editors/code/src/installation/extension.ts index 2022d090d..f6dd20d82 100644 --- a/editors/code/src/installation/extension.ts +++ b/editors/code/src/installation/extension.ts @@ -97,7 +97,7 @@ async function askToDownloadProperExtensionVersion(config: Config, reason = "") * * ACHTUNG!: this function has a crazy amount of state transitions, handling errors during * each of them would result in a ton of code (especially accounting for cross-process - * shared mutable `globalState` access). Enforcing reentrancy for this is best-effort. + * shared mutable `globalState` access). Enforcing no reentrancy for this is best-effort. */ const tryDownloadNightlyExtension = notReentrant(async function tryDownloadNightlyExtension( config: Config, diff --git a/editors/code/src/installation/server.ts b/editors/code/src/installation/server.ts index 345f30d47..f35958474 100644 --- a/editors/code/src/installation/server.ts +++ b/editors/code/src/installation/server.ts @@ -5,7 +5,7 @@ import { spawnSync } from "child_process"; import { ArtifactSource } from "./interfaces"; import { fetchArtifactReleaseInfo } from "./fetch_artifact_release_info"; import { downloadArtifactWithProgressUi } from "./downloads"; -import { log, assert } from "../util"; +import { log, assert, notReentrant } from "../util"; import { Config, NIGHTLY_TAG } from "../config"; export async function ensureServerBinary(config: Config): Promise { @@ -82,7 +82,10 @@ function shouldDownloadServer( return installed.date.getTime() !== required.date.getTime(); } -async function downloadServer( +/** + * Enforcing no reentrancy for this is best-effort. + */ +const downloadServer = notReentrant(async function downloadServer( source: ArtifactSource.GithubRelease, config: Config, ): Promise { @@ -112,7 +115,7 @@ async function downloadServer( ); return binaryPath; -} +}); function isBinaryAvailable(binaryPath: string): boolean { const res = spawnSync(binaryPath, ["--version"]); -- cgit v1.2.3 From 5e32a67c83d46862db0166c263efc65b6ecd5b52 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sat, 14 Mar 2020 03:01:14 +0200 Subject: vscode-postrefactor: more logging and better error handling --- editors/code/src/installation/extension.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/extension.ts b/editors/code/src/installation/extension.ts index f6dd20d82..0d69b8d0c 100644 --- a/editors/code/src/installation/extension.ts +++ b/editors/code/src/installation/extension.ts @@ -44,10 +44,20 @@ export async function ensureProperExtensionVersion(config: Config): Promise Date: Mon, 16 Mar 2020 12:17:36 +0200 Subject: vscode-postrefactor: prefer arrow functions --- editors/code/src/installation/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/extension.ts b/editors/code/src/installation/extension.ts index 0d69b8d0c..e0aa5317d 100644 --- a/editors/code/src/installation/extension.ts +++ b/editors/code/src/installation/extension.ts @@ -109,7 +109,7 @@ async function askToDownloadProperExtensionVersion(config: Config, reason = "") * each of them would result in a ton of code (especially accounting for cross-process * shared mutable `globalState` access). Enforcing no reentrancy for this is best-effort. */ -const tryDownloadNightlyExtension = notReentrant(async function tryDownloadNightlyExtension( +const tryDownloadNightlyExtension = notReentrant(async ( config: Config, shouldDownload: (releaseInfo: ArtifactReleaseInfo) => boolean = () => true ): Promise { -- cgit v1.2.3 From fc47274541b5f4e9c8406c4dd401392129845396 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 16 Mar 2020 12:18:30 +0200 Subject: vscode-postrefactor: fix syntax error --- editors/code/src/installation/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/extension.ts b/editors/code/src/installation/extension.ts index e0aa5317d..eea6fded2 100644 --- a/editors/code/src/installation/extension.ts +++ b/editors/code/src/installation/extension.ts @@ -112,7 +112,7 @@ async function askToDownloadProperExtensionVersion(config: Config, reason = "") const tryDownloadNightlyExtension = notReentrant(async ( config: Config, shouldDownload: (releaseInfo: ArtifactReleaseInfo) => boolean = () => true -): Promise { +): Promise => { const vsixSource = config.nightlyVsixSource; try { const releaseInfo = await fetchArtifactReleaseInfo(vsixSource.repo, vsixSource.file, vsixSource.tag); -- cgit v1.2.3 From 5a0041c5aaeee49be84ce771fb0360ae55cbd8b2 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Mon, 16 Mar 2020 12:19:26 +0200 Subject: vscode-postrefactor: migrate to arrow functions --- editors/code/src/installation/server.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'editors/code/src/installation') diff --git a/editors/code/src/installation/server.ts b/editors/code/src/installation/server.ts index f35958474..05730a778 100644 --- a/editors/code/src/installation/server.ts +++ b/editors/code/src/installation/server.ts @@ -85,10 +85,10 @@ function shouldDownloadServer( /** * Enforcing no reentrancy for this is best-effort. */ -const downloadServer = notReentrant(async function downloadServer( +const downloadServer = notReentrant(async ( source: ArtifactSource.GithubRelease, config: Config, -): Promise { +): Promise => { try { const releaseInfo = await fetchArtifactReleaseInfo(source.repo, source.file, source.tag); -- cgit v1.2.3