From 88e0a29085ff04c1a7dc0c561372b5675249dc65 Mon Sep 17 00:00:00 2001 From: Stefano Lottini Date: Mon, 8 May 2023 22:49:12 +0200 Subject: [PATCH] scenario detection to prevent unwanted extension activation --- package.json | 2 +- src/configuration.ts | 8 +----- src/configuration_constants.ts | 9 ++++++ src/extension.ts | 33 +++++++++++++-------- src/filesystem.ts | 52 ++++++++++++++++++++++++++++++++++ src/rendering.ts | 2 +- 6 files changed, 85 insertions(+), 21 deletions(-) create mode 100644 src/configuration_constants.ts diff --git a/package.json b/package.json index 078ccd1..92b3a6d 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "url": "https://github.com/DataStax-Academy/katapod" }, "description": "", - "version": "1.2.1", + "version": "1.3.0", "license": "Apache-2.0", "engines": { "vscode": "^1.64.0" diff --git a/src/configuration.ts b/src/configuration.ts index df10e52..d0f1cf4 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -8,13 +8,7 @@ import {buildFullFileUri, checkFileExists} from "./filesystem"; import {log} from "./logging"; import {ConfigCommand} from "./runCommands"; - -const kpConfigFileName = ".katapod_config.json"; -// const kpConfigFileName = ".katapod_config.json"; -const kpDefaultStartupScript = "wait.sh"; -const kpDefaultTerminalName = "cqlsh-editor"; -const kpDefaultTerminalID = "cqlsh"; -const kpDefaultIntroStepName = "intro"; +import {kpConfigFileName, kpDefaultStartupScript, kpDefaultTerminalName, kpDefaultTerminalID, kpDefaultIntroStepName} from "./configuration_constants"; // Structure of the config object diff --git a/src/configuration_constants.ts b/src/configuration_constants.ts new file mode 100644 index 0000000..f009718 --- /dev/null +++ b/src/configuration_constants.ts @@ -0,0 +1,9 @@ +/* +Constants about configuration (file names, defaults, ...) +*/ + +export const kpConfigFileName = ".katapod_config.json"; +export const kpDefaultStartupScript = "wait.sh"; +export const kpDefaultTerminalName = "cqlsh-editor"; +export const kpDefaultTerminalID = "cqlsh"; +export const kpDefaultIntroStepName = "intro"; diff --git a/src/extension.ts b/src/extension.ts index f4de866..9854861 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -8,6 +8,7 @@ import {runCommand, FullCommand} from "./runCommands"; import {loadPage, reloadPage, TargetStep} from "./rendering"; import {setupLayout} from "./layout"; import {KatapodEnvironment} from "./state"; +import {isKatapodScenario} from "./filesystem"; let katapodEnvironment: KatapodEnvironment; @@ -28,18 +29,26 @@ export async function activate(context: vscode.ExtensionContext) { (which helps fighting nondeterminism in these calls while avoiding chains of ".then(...)" with all await's). See https://stackoverflow.com/questions/64640967/can-a-vscode-extension-activate-method-be-async. */ - context.subscriptions.push(vscode.commands.registerCommand("katapod.sendText", sendTextClosure)); - context.subscriptions.push(vscode.commands.registerCommand("katapod.reloadPage", reloadPageClosure)); - context.subscriptions.push(vscode.commands.registerCommand("katapod.loadPage", loadPageClosure)); - context.subscriptions.push(vscode.commands.registerCommand("katapod.start", start)); - - await vscode.commands.executeCommand("notifications.clearAll"); - await vscode.commands.executeCommand("workbench.action.closeSidebar"); - await vscode.commands.executeCommand("workbench.action.closeAuxiliaryBar"); - await vscode.commands.executeCommand("workbench.action.closePanel"); - await vscode.commands.executeCommand("workbench.action.closeAllEditors"); - start(); - await vscode.commands.executeCommand("notifications.clearAll"); + + isKatapodScenario().then( async (isScen) => { + if(isScen){ + log('debug', 'Katapod scenario detected. Activating extension.'); + context.subscriptions.push(vscode.commands.registerCommand("katapod.sendText", sendTextClosure)); + context.subscriptions.push(vscode.commands.registerCommand("katapod.reloadPage", reloadPageClosure)); + context.subscriptions.push(vscode.commands.registerCommand("katapod.loadPage", loadPageClosure)); + context.subscriptions.push(vscode.commands.registerCommand("katapod.start", start)); + + await vscode.commands.executeCommand("notifications.clearAll"); + await vscode.commands.executeCommand("workbench.action.closeSidebar"); + await vscode.commands.executeCommand("workbench.action.closeAuxiliaryBar"); + await vscode.commands.executeCommand("workbench.action.closePanel"); + await vscode.commands.executeCommand("workbench.action.closeAllEditors"); + start(); + await vscode.commands.executeCommand("notifications.clearAll"); + } else { + log('debug', 'Katapod scenario not detected. Extension not activated.'); + } + } ); } export function deactivate() {} diff --git a/src/filesystem.ts b/src/filesystem.ts index 5c6516e..170d64d 100644 --- a/src/filesystem.ts +++ b/src/filesystem.ts @@ -2,8 +2,17 @@ Filesystem and I/O facilities. */ +const fs = require("fs"); import * as vscode from "vscode"; const path = require("path"); +import {log} from "./logging"; + +import {kpConfigFileName} from "./configuration_constants"; + + +const gitpodYamlFileName = '.gitpod.yml'; +const katapodExtensionMatchFragment1 = '.vsix'; +const katapodExtensionMatchFragment2 = 'katapod'; export function getWorkingDir(): string | undefined { @@ -21,3 +30,46 @@ export function buildFullFileUri(fileName: string): vscode.Uri { export function checkFileExists(fileUri: vscode.Uri): Thenable { return vscode.workspace.fs.stat(fileUri); } + +export function isKatapodScenario(): Promise { + /* + We want to check if this is a Katapod scenario or just any other Gitpod project. + The decision flow (dictated by the requirement of back-compatibility with scenarios lacking a .katapod_config.json) is: + 1. if there is a ".katapod_config.json" => is scenario + 2. else: + 2a. if there is a ".gitpod.yml": + 2a.I if it contains a string of the kind used to load a(ny) katapod extension => is scenario + 2a.II else => is not scenario + 2b. => is not scenario + */ + const configFileUri: vscode.Uri = buildFullFileUri(kpConfigFileName); + const isScenario = new Promise((resolve) => { + checkFileExists(configFileUri).then( + function () { + // 1 + resolve(true); + }, + function () { + // 2 + const gYamlFileUri = buildFullFileUri(gitpodYamlFileName); + checkFileExists(gYamlFileUri).then( + function() { + // 2a. We look for a line containing both 'vsix' and 'katapod' and call it a day (a hack...) + var linesRead = fs.readFileSync(gYamlFileUri.fsPath, 'utf-8').split('\n'); + var katapoddyLines = linesRead + .map( (l: string) => l.toLowerCase() ) + .filter( (l: string) => l.indexOf(katapodExtensionMatchFragment1) > -1 ) + .filter( (l: string) => l.indexOf(katapodExtensionMatchFragment2) > -1); + // 2a.I vs 2a.II + resolve(katapoddyLines.length > 0); + }, + function() { + // 2b + resolve(false); + } + ); + } + ); + }); + return isScenario; +} diff --git a/src/rendering.ts b/src/rendering.ts index 9d8729a..b43c70b 100644 --- a/src/rendering.ts +++ b/src/rendering.ts @@ -3,7 +3,7 @@ Parsing/rendering markdown, code blocks and other elements. */ import * as vscode from "vscode"; -import * as path from "path"; +// import * as path from "path"; const fs = require("fs"); const markdownIt = require("markdown-it"); const markdownItAttrs = require("markdown-it-attrs");