From 6c66438fa40b1fd48a65bd09c399dcba26b90210 Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Mon, 13 Jun 2022 23:04:20 +0200 Subject: [PATCH] Revert "feat: show Metals' release notes if server version was updated (#1009)" This reverts commit 3ebbea7b53f0c7f0e3a9897992813cdf0a59adc0. --- .eslintrc.js | 5 +- media/styles.css | 8 -- package.json | 16 +-- src/extension.ts | 26 +--- src/releaseNotesProvider.ts | 254 ------------------------------------ src/types.ts | 11 -- src/util.ts | 16 --- yarn.lock | 55 -------- 8 files changed, 6 insertions(+), 385 deletions(-) delete mode 100644 media/styles.css delete mode 100644 src/releaseNotesProvider.ts delete mode 100644 src/types.ts diff --git a/.eslintrc.js b/.eslintrc.js index cbd5bb85f..2dffd1f23 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -17,10 +17,7 @@ module.exports = { { ignoreRestArgs: true }, ], "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": [ - "error", - { varsIgnorePattern: "_" }, - ], + "@typescript-eslint/no-unused-vars": ["error"], "@typescript-eslint/no-non-null-assertion": "error", "guard-for-in": "error", "no-var": "error", diff --git a/media/styles.css b/media/styles.css deleted file mode 100644 index fd1ac6829..000000000 --- a/media/styles.css +++ /dev/null @@ -1,8 +0,0 @@ -h2, -h3, -h4, -h5, -h6 { - margin-top: 2em; - margin-bottom: 0em; -} diff --git a/package.json b/package.json index cc773215f..0878795ea 100644 --- a/package.json +++ b/package.json @@ -415,11 +415,6 @@ "category": "Metals", "title": "Run doctor" }, - { - "command": "metals.show-release-notes", - "category": "Metals", - "title": "Show release notes" - }, { "command": "metals.scalafix-run", "category": "Metals", @@ -665,10 +660,6 @@ "command": "metals.doctor-run", "when": "metals:enabled" }, - { - "command": "metals.show-release-notes", - "when": "metals:enabled" - }, { "command": "metals.scalafix-run", "when": "metals:enabled" @@ -908,11 +899,10 @@ "scripts": { "vscode:prepublish": "yarn compile", "compile": "tsc -p ./", - "clean": "rimraf out/", "watch": "tsc -watch -p ./", "test": "ts-mocha src/test/unit/*.test.ts", "test-extension": "rimraf out/ && tsc -p ./ && node out/test/extension/runTest.js", - "build": "yarn clean && vsce package --yarn", + "build": "vsce package --yarn", "vscode:publish": "vsce publish --yarn", "ovsx:publish": "ovsx publish", "lint": "eslint . --ext .ts --fix && yarn format", @@ -923,8 +913,6 @@ "@types/glob": "^7.2.0", "@types/mocha": "^9.1.1", "@types/node": "17.0.27", - "@types/remarkable": "^2.0.3", - "@types/semver": "^7.3.9", "@types/vscode": "1.59.0", "@typescript-eslint/eslint-plugin": "^5.27.1", "@typescript-eslint/parser": "^5.27.1", @@ -946,8 +934,6 @@ "ansicolor": "^1.1.100", "metals-languageclient": "0.5.15", "promisify-child-process": "4.1.1", - "remarkable": "^2.0.1", - "semver": "^7.3.7", "vscode-languageclient": "7.0.0" }, "extensionPack": [ diff --git a/src/extension.ts b/src/extension.ts index 22fac7a47..e5eb3b889 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -90,7 +90,6 @@ import * as workbenchCommands from "./workbenchCommands"; import { getServerVersion } from "./getServerVersion"; import { getCoursierMirrorPath } from "./mirrors"; import { DoctorProvider } from "./doctor"; -import { showReleaseNotes } from "./releaseNotesProvider"; const outputChannel = window.createOutputChannel("Metals"); const openSettingsAction = "Open settings"; @@ -131,13 +130,7 @@ export async function activate(context: ExtensionContext): Promise { commands.executeCommand("setContext", "metals:enabled", true); try { const javaHome = await getJavaHome(getJavaHomeFromConfig()); - await fetchAndLaunchMetals(context, javaHome, serverVersion); - await showReleaseNotes( - "onExtensionStart", - context, - serverVersion, - outputChannel - ); + return fetchAndLaunchMetals(context, javaHome, serverVersion); } catch (err) { outputChannel.appendLine(`${err}`); showMissingJavaMessage(); @@ -269,8 +262,7 @@ function fetchAndLaunchMetals( context, classpath, serverProperties, - javaConfig, - serverVersion + javaConfig ); }, (reason) => { @@ -328,8 +320,7 @@ function launchMetals( context: ExtensionContext, metalsClasspath: string, serverProperties: string[], - javaConfig: JavaConfig, - serverVersion: string + javaConfig: JavaConfig ) { // Make editing Scala docstrings slightly nicer. enableScaladocIndentation(); @@ -516,16 +507,7 @@ function launchMetals( ) ); - registerCommand( - "metals.show-release-notes", - async () => - await showReleaseNotes( - "onUserDemand", - context, - serverVersion, - outputChannel - ) - ); + context.subscriptions.push(client.start()); return client.onReady().then( () => { diff --git a/src/releaseNotesProvider.ts b/src/releaseNotesProvider.ts deleted file mode 100644 index f24875e31..000000000 --- a/src/releaseNotesProvider.ts +++ /dev/null @@ -1,254 +0,0 @@ -import { env, ExtensionContext } from "vscode"; -import * as vscode from "vscode"; -import * as semver from "semver"; -import { Remarkable } from "remarkable"; -import { fetchFrom } from "./util"; -import { Either, makeLeft, makeRight } from "./types"; - -const versionKey = "metals-server-version"; -type CalledOn = "onExtensionStart" | "onUserDemand"; - -/** - * Show release notes if possible, swallow errors since its not a crucial feature. - * Treats snapshot versions like 0.11.6+67-926ec9a3-SNAPSHOT as a 0.11.6. - * - * @param calledOn determines when this function was called. - * For 'onExtensionStart' case show release notes only once (first time). - * For 'onUserDemand' show extension notes no matter if it's another time. - */ -export async function showReleaseNotes( - calledOn: CalledOn, - context: ExtensionContext, - serverVersion: string, - outputChannel: vscode.OutputChannel -) { - try { - const result = await showReleaseNotesImpl(calledOn, context, serverVersion); - if (result.kind === "left") { - const msg = `Release notes was not shown: ${result.value}`; - outputChannel.appendLine(msg); - } - } catch (error) { - outputChannel.appendLine( - `Error, couldn't show release notes for Metals ${serverVersion}` - ); - outputChannel.appendLine(`${error}`); - } -} - -async function showReleaseNotesImpl( - calledOn: CalledOn, - context: ExtensionContext, - currentVersion: string -): Promise> { - const state = context.globalState; - - const remote = isRemote(); - if (remote.kind === "left") { - return remote; - } - - const version = getVersion(calledOn); - if (version.kind === "left") { - return version; - } - - const releaseNotesUrl = await getMarkdownLink(version.value); - if (releaseNotesUrl.kind === "left") { - return releaseNotesUrl; - } - - // actual logic starts here - await showPanel(version.value, releaseNotesUrl.value); - return makeRight(undefined); - - // below are helper functions - - async function showPanel(version: string, releaseNotesUrl: string) { - const panel = vscode.window.createWebviewPanel( - `scalameta.metals.whatsNew`, - `Metals ${version} release notes`, - vscode.ViewColumn.One - ); - - const releaseNotes = await getReleaseNotesMarkdown( - releaseNotesUrl, - context, - (uri) => panel.webview.asWebviewUri(uri) - ); - - panel.webview.html = releaseNotes; - panel.reveal(); - - // Update current device's latest server version when there's no value or it was a older one. - // Then sync this value across other devices. - state.update(versionKey, version); - state.setKeysForSync([versionKey]); - - context.subscriptions.push(panel); - } - - /** - * Don't show panel for remote environment because it installs extension on every time. - * TODO: what about wsl? - */ - function isRemote(): Either { - return env.remoteName == null || env.remoteName === "wsl" - ? makeRight(undefined) - : makeLeft(`is a remote environment ${env.remoteName}`); - } - - /** - * Return version for which release notes should be displayed - */ - function getVersion(calledOn: CalledOn): Either { - const previousVersion: string | undefined = state.get(versionKey); - // strip version to - // in theory semver.clean can return null, but we're almost sure that currentVersion is well defined - const cleanVersion = semver.clean(currentVersion); - - if (cleanVersion == null) { - const msg = `can't transform ${currentVersion} to 'major.minor.patch'`; - return makeLeft(msg); - } - - // if there was no previous version or user explicitly wants to read release notes - // show release notes for current cleaned version - if (!previousVersion || calledOn === "onUserDemand") { - return makeRight(currentVersion); - } - - const compare = semver.compare(cleanVersion, previousVersion); - const diff = semver.diff(cleanVersion, previousVersion); - - // take into account only major, minor and patch, ignore snapshot releases - const isNewerVersion = - compare === 1 && - (diff === "major" || diff === "minor" || diff === "patch"); - - return isNewerVersion - ? makeRight(cleanVersion) - : makeLeft("do not show release notes for an older version"); - } -} - -/** - * Translate server version to link to the markdown file with release notes. - * @param version clean version in major.minor.patch form - * If version has release notes return link to them, if not return nothing. - * Sample link to which we're doing request https://api.github.com/repos/scalameta/metals/releases/tags/v0.11.6. - * From such JSON obtain body property which contains link to the blogpost, but what's more important, - * contains can be converted to name of markdown file with release notes. - */ -async function getMarkdownLink( - version: string -): Promise> { - const releaseInfoUrl = `https://api.github.com/repos/scalameta/metals/releases/tags/v${version}`; - const options = { - headers: { - "User-Agent": "metals", - }, - }; - const stringifiedContent = await fetchFrom(releaseInfoUrl, options); - const body = JSON.parse(stringifiedContent)["body"] as string; - - if (!body) { - const msg = `can't obtain content of ${releaseInfoUrl}`; - return makeLeft(msg); - } - - // matches (2022)/(06)/(03)/(aluminium) via capture groups - const matchResult = body.match( - new RegExp("(\\d\\d\\d\\d)/(\\d\\d)/(\\d\\d)/(\\w+)") - ); - // whole expression + 4 capture groups = 5 entries - if (matchResult?.length === 5) { - // omit first entry - const [_, ...tail] = matchResult; - const name = tail.join("-"); - const url = `https://raw.githubusercontent.com/scalameta/metals/main/website/blog/${name}.md`; - return makeRight(url); - } else { - const msg = `can't obtain markdown file name for ${version} from ${body}`; - return makeLeft(msg); - } -} - -/** - * - * @param releaseNotesUrl Url which server markdown with release notes - * @param context Extension context - * @param asWebviewUri - * Webviews cannot directly load resources from the workspace or local - * file system using file: uris. The asWebviewUri function takes a local - * file: uri and converts it into a uri that can be used inside of a webview - * to load the same resource. - * proxy to webview.asWebviewUri - */ -async function getReleaseNotesMarkdown( - releaseNotesUrl: string, - context: ExtensionContext, - asWebviewUri: (_: vscode.Uri) => vscode.Uri -): Promise { - const text = await fetchFrom(releaseNotesUrl); - // every release notes starts with that - const beginning = "We're happy to announce the release of"; - const notesStartIdx = text.indexOf(beginning); - const releaseNotes = text.substring(notesStartIdx); - - // cut metadata yaml from release notes, it start with --- and ends with --- - const metadata = text - .substring(0, notesStartIdx - 1) - .replace("---", "") - .replace("---", "") - .trim() - .split("\n"); - const author = metadata[0].slice("author: ".length); - const title = metadata[1].slice("title: ".length); - const authorUrl = metadata[2].slice("authorURL: ".length); - - const md = new Remarkable({ html: true }); - const renderedNotes = md.render(releaseNotes); - - // Uri with additional styles for webview - const stylesPathMainPath = vscode.Uri.joinPath( - context.extensionUri, - "media", - "styles.css" - ); - // need to transform Uri - const stylesUri = asWebviewUri(stylesPathMainPath); - - return ` - - - - - - - - -

${title}

-
-

- Showing Metals' release notes embedded in vscode is an experimental feature, in case of any issues report them at - https://github.com/scalameta/metals-vscode. -
-
- Original blogpost can be viewed at - . -

-
-

- -

-
- ${renderedNotes} - - -`; -} diff --git a/src/types.ts b/src/types.ts deleted file mode 100644 index ff4a72b76..000000000 --- a/src/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -export type Either = - | { kind: "left"; value: Left } - | { kind: "right"; value: Right }; - -export function makeLeft(t: T): Either { - return { kind: "left", value: t }; -} - -export function makeRight(t: T): Either { - return { kind: "right", value: t }; -} diff --git a/src/util.ts b/src/util.ts index 0a7bc2e93..8358d73d9 100644 --- a/src/util.ts +++ b/src/util.ts @@ -11,7 +11,6 @@ import { TextDocumentPositionParams, } from "vscode-languageclient"; import { LanguageClient } from "vscode-languageclient/node"; -import http from "https"; declare const sym: unique symbol; /** @@ -104,18 +103,3 @@ export function getJavaHomeFromConfig(): string | undefined { return javaHomePath; } } - -export async function fetchFrom( - url: string, - options?: http.RequestOptions -): Promise { - const promise = new Promise((resolve, reject) => { - http.get(url, options || {}, (resp) => { - let body = ""; - resp.on("data", (chunk) => (body += chunk)); - resp.on("end", () => resolve(body)); - resp.on("error", (e) => reject(e)); - }); - }); - return await promise; -} diff --git a/yarn.lock b/yarn.lock index 877f9615e..9e312d86a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -65,11 +65,6 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/highlight.js@^9.7.0": - version "9.12.4" - resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-9.12.4.tgz#8c3496bd1b50cc04aeefd691140aa571d4dbfa34" - integrity sha512-t2szdkwmg2JJyuCM20e8kR2X59WCE5Zkl4bzm1u1Oukjm79zpbiAv+QjnwLnuuV0WHEcX2NgUItu0pAMKuOPww== - "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" @@ -95,19 +90,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.27.tgz#f4df3981ae8268c066e8f49995639f855469081e" integrity sha512-4/Ke7bbWOasuT3kceBZFGakP1dYN2XFd8v2l9bqF2LNWrmeU07JLpp56aEeG6+Q3olqO5TvXpW0yaiYnZJ5CXg== -"@types/remarkable@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/remarkable/-/remarkable-2.0.3.tgz#ba2e5edada8f0fe64c658beb2127e06ac0b9c1c8" - integrity sha512-QQUBeYApuHCNl9Br6ZoI3PlKmwZ69JHrlJktJXnjxobia9liZgsI70fm8PnCqVFAcefYK+9PGzR5L/hzCslNYQ== - dependencies: - "@types/highlight.js" "^9.7.0" - highlight.js "^9.7.0" - -"@types/semver@^7.3.9": - version "7.3.9" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc" - integrity sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ== - "@types/vscode@1.59.0": version "1.59.0" resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.59.0.tgz#11c93f5016926126bf30b47b9ece3bd617eeef31" @@ -298,13 +280,6 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" -argparse@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - argparse@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" @@ -325,13 +300,6 @@ async@^3.2.2: resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9" integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g== -autolinker@^3.11.0: - version "3.15.0" - resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-3.15.0.tgz#03956088648f236642a5783612f9ca16adbbed38" - integrity sha512-N/5Dk5AZnqL9k6kkHdFIGLm/0/rRuSnJwqYYhLCJjU7ZtiaJwCBzNTvjzy1zzJADngv/wvtHYcrPHytPnASeFA== - dependencies: - tslib "^2.3.0" - azure-devops-node-api@^11.0.1: version "11.1.0" resolved "https://registry.yarnpkg.com/azure-devops-node-api/-/azure-devops-node-api-11.1.0.tgz#ea3ca49de8583b0366d000f3c3f8a75b8104055f" @@ -1134,11 +1102,6 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -highlight.js@^9.7.0: - version "9.18.5" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.5.tgz#d18a359867f378c138d6819edfc2a8acd5f29825" - integrity sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA== - hosted-git-info@^4.0.2: version "4.1.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" @@ -1795,14 +1758,6 @@ regexpp@^3.2.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -remarkable@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/remarkable/-/remarkable-2.0.1.tgz#280ae6627384dfb13d98ee3995627ca550a12f31" - integrity sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA== - dependencies: - argparse "^1.0.10" - autolinker "^3.11.0" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -1946,11 +1901,6 @@ source-map@^0.6.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -2121,11 +2071,6 @@ tslib@^2.2.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== -tslib@^2.3.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== - tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"