From 9bdccc2d24b7ad5ee324158ee26400a4e72f8aaa Mon Sep 17 00:00:00 2001 From: Julian Date: Sun, 19 Oct 2025 15:49:55 +0200 Subject: [PATCH 1/5] lay base for renaming --- package.json | 74 +++-- src/binary-finder-strategies.ts | 254 ++++++++++-------- src/binary-finder.ts | 32 ++- src/commands.ts | 18 +- src/config.ts | 41 ++- src/constants.ts | 66 ++++- src/downloader.ts | 80 ++++-- src/extension.ts | 47 +++- src/index.ts | 4 +- src/lifecycle.ts | 14 +- src/logger.ts | 9 +- src/project.ts | 32 ++- src/renaming.ts | 45 ++++ src/session.ts | 101 ++++--- src/status-bar.ts | 4 +- src/utils.ts | 4 +- .../.vscode/settings.json | 2 +- .../packages/service-b/test.sql | 2 +- .../project-1/test.sql | 2 +- .../project-2/test.sql | 2 +- test/fixtures/multi-root/project-1/test.sql | 2 +- test/fixtures/multi-root/project-2/test.sql | 2 +- .../multi-root/project-disabled/test.sql | 2 +- .../multi-root/project-no-jsonc/test.sql | 2 +- test/fixtures/node-modules-strat/src/test.sql | 2 +- .../simple-project-download/src/test.sql | 2 +- .../simple-project-global-bin/src/test.sql | 2 +- .../vscode-settings-strat/src/test.sql | 2 +- 28 files changed, 594 insertions(+), 255 deletions(-) create mode 100644 src/renaming.ts diff --git a/package.json b/package.json index 626058d..9d71239 100644 --- a/package.json +++ b/package.json @@ -33,36 +33,36 @@ "contributes": { "commands": [ { - "title": "PostgresTools: Start", - "command": "postgrestools.start" + "title": "Postgres Language Server: Start", + "command": "postgres-language-server.start" }, { - "title": "PostgresTools: Stop", - "command": "postgrestools.stop" + "title": "Postgres Language Server: Stop", + "command": "postgres-language-server.stop" }, { - "title": "PostgresTools: Restart", - "command": "postgrestools.restart" + "title": "Postgres Language Server: Restart", + "command": "postgres-language-server.restart" }, { - "title": "PostgresTools: Download Server", - "command": "postgrestools.download" + "title": "Postgres Language Server: Download Server", + "command": "postgres-language-server.download" }, { - "title": "PostgresTools: Hard Reset (Delete All Temp & Global Binaries)", - "command": "postgrestools.reset" + "title": "Postgres Language Server: Hard Reset (Delete All Temp & Global Binaries)", + "command": "postgres-language-server.reset" }, { - "title": "PostgresTools: Get Current Version", - "command": "postgrestools.currentVersion" + "title": "Postgres Language Server: Get Current Version", + "command": "postgres-language-server.currentVersion" }, { - "title": "PostgresTools: Copy Latest Server Logfile", - "command": "postgrestools.copyLatestLogfile" + "title": "Postgres Language Server: Copy Latest Server Logfile", + "command": "postgres-language-server.copyLatestLogfile" } ], "configuration": { - "title": "PostgresTools", + "title": "Postgres Language Server", "properties": { "postgrestools.enabled": { "type": "boolean", @@ -110,6 +110,50 @@ } ], "scope": "resource" + }, + "postgres-language-server.enabled": { + "type": "boolean", + "description": "Whether to enable the postgres-language-server extension.", + "scope": "resource" + }, + "postgres-language-server.allowDownloadPrereleases": { + "type": "boolean", + "description": "Allows selecting prereleases when downloading the binary via this extension", + "scope": "resource" + }, + "postgres-language-server.allowVersionChecks": { + "type": "boolean", + "description": "If set, the extension will check periodically whether a new version for postgres-language-server is available and if so notify the user.", + "scope": "resource" + }, + "postgres-language-server.configFile": { + "type": "string", + "description": "Path to the `postgres-language-server.jsonc` file. You don't need to set this if the file is on root level of your project.", + "scope": "resource" + }, + "postgres-language-server.bin": { + "oneOf": [ + { + "type": "string", + "description": "Path to the postgres-language-server Language Server binary", + "examples": [ + "/path/to/postgres-language-server", + "./path/to/postgres-language-server" + ] + }, + { + "type": "object", + "description": "Platform-specific paths to the postgres-language-server Language Server binary", + "examples": [ + { + "linux-x64": "/path/to/postgres-language-server", + "darwin-arm64": "./path/to/postgres-language-server", + "win32-x64": "/path/to/postgres-language-server.exe" + } + ] + } + ], + "scope": "resource" } } } diff --git a/src/binary-finder-strategies.ts b/src/binary-finder-strategies.ts index 15b89d1..76376b2 100644 --- a/src/binary-finder-strategies.ts +++ b/src/binary-finder-strategies.ts @@ -13,7 +13,7 @@ export interface BinaryFindStrategy { } /** - * The user can specify a PostgresTools binary in the VSCode settings. + * The user can specify a Postgres Language Server binary in the VSCode settings. * * This can be done in two ways: * @@ -25,17 +25,19 @@ export interface BinaryFindStrategy { * Config Example: * ```json * { - * "postgrestools.bin": { - * "linux-x64": "/path/to/postgrestools", - * "darwin-arm64": "/path/to/postgrestools", - * "win32-x64": "/path/to/postgrestools.exe" + * "postgreslanguageserver.bin": { + * "linux-x64": "/path/to/bin", + * "darwin-arm64": "/path/to/bin", + * "win32-x64": "/path/to/bin.exe" * } * } */ export const vsCodeSettingsStrategy: BinaryFindStrategy = { name: "VSCode Settings Strategy", async find(path?: Uri) { - logger.debug("Trying to find PostgresTools binary via VSCode Settings"); + logger.debug( + "Trying to find Postgres Language Server binary via VSCode Settings" + ); type BinSetting = string | Record | undefined; let binSetting: BinSetting = getConfig("bin", { @@ -74,7 +76,7 @@ export const vsCodeSettingsStrategy: BinaryFindStrategy = { if (binSetting.startsWith(".")) { if (CONSTANTS.operatingMode === OperatingMode.MultiRoot) { window.showErrorMessage( - "Relative paths for the postgrestools binary in a multi-root workspace setting are not supported. Please use an absolute path in your `*.code-workspace` file." + "Relative paths for the postgres language server binary in a multi-root workspace setting are not supported. Please use an absolute path in your `*.code-workspace` file." ); return null; } else if (path) { @@ -96,14 +98,16 @@ export const vsCodeSettingsStrategy: BinaryFindStrategy = { logger.debug("Looking for binary at path", { resolvedPath }); - const postgrestools = Uri.file(resolvedPath); + const bin = Uri.file(resolvedPath); - if (await fileExists(postgrestools)) { - return postgrestools; + if (await fileExists(bin)) { + return bin; } } - logger.debug("No PostgresTools binary found in VSCode settings."); + logger.debug( + "No Postgres Language Server binary found in VSCode settings." + ); return null; }, @@ -114,85 +118,99 @@ export const vsCodeSettingsStrategy: BinaryFindStrategy = { * Search the binary in node modules. * Search for the sub-packages that the binary tries to use with npm. * Use node's `createRequire` – what's that? - * Resolve the *main* package.json – the one used by @postgrestools/postgrestools. + * Resolve the *main* package.json – the one used by @postgres-language-server/cli or `@postgrestools/postgrestools`. * In those node_modules, you should see the installed optional dependency. */ export const nodeModulesStrategy: BinaryFindStrategy = { name: "Node Modules Strategy", async find(path?: Uri) { - logger.debug("Trying to find PostgresTools binary in Node Modules"); + logger.debug( + "Trying to find Postgres Language Server binary in Node Modules" + ); if (!path) { logger.debug("No local path, skipping."); return null; } - const postgrestoolsPackageNameJson = `${CONSTANTS.npmPackageName}/package.json`; + for (const [pkgname, nodePkgName, binaryName] of [ + [ + CONSTANTS.newPackageName, + CONSTANTS.newPlatformSpecificNodePackageName, + CONSTANTS.newPlatformSpecificBinaryName, + ], + [ + CONSTANTS.oldPackageName, + CONSTANTS.oldPlatformSpecificNodePackageName, + CONSTANTS.oldPlatformSpecificBinaryName, + ], + ] satisfies [string, string | undefined, string][]) { + const postgresLanguageServerPackageNameJson = `${pkgname}/package.json`; + + logger.info(`Searching for node_modules package`, { + postgresLanguageServerPackageNameJson, + }); + + let requirePgltPackage: NodeJS.Require; + try { + /** + * Create a scoped require function that can require modules from the + * package installed via npm. + * + * We're essentially searching for the installed package in the current dir, and requiring from its node_modules. + * `package.json` serves as a target to resolve the root of the package. + */ + requirePgltPackage = createRequire( + require.resolve(postgresLanguageServerPackageNameJson, { + paths: [path.fsPath], // note: global ~/.node_modules is always searched + }) + ); + } catch (err: unknown) { + if ( + err instanceof Error && + err.message.toLowerCase().includes("cannot find module") + ) { + logger.debug(`User does not use node_modules`); + return null; + } else { + throw err; + } + } - logger.info(`Searching for node_modules package`, { - postgrestoolsPackageNameJson, - }); + logger.debug("Created require function!"); - let requirePgltPackage: NodeJS.Require; - try { - /** - * Create a scoped require function that can require modules from the - * package installed via npm. - * - * We're essentially searching for the installed package in the current dir, and requiring from its node_modules. - * `package.json` serves as a target to resolve the root of the package. - */ - requirePgltPackage = createRequire( - require.resolve(postgrestoolsPackageNameJson, { - paths: [path.fsPath], // note: global ~/.node_modules is always searched - }) - ); - } catch (err: unknown) { - if ( - err instanceof Error && - err.message.toLowerCase().includes("cannot find module") - ) { - logger.debug(`User does not use node_modules`); + if (nodePkgName === undefined) { + logger.debug( + `No package for current platform available in node_modules`, + { + os: process.platform, + arch: process.arch, + } + ); return null; - } else { - throw err; } - } - - logger.debug("Created require function!"); - const packageName = CONSTANTS.platformSpecificNodePackageName; - if (packageName === undefined) { logger.debug( - `No package for current platform available in node_modules`, - { - os: process.platform, - arch: process.arch, - } + `Resolving bin package at nested ${nodePkgName}/package.json` ); - return null; - } - logger.debug(`Resolving bin package at nested ${packageName}/package.json`); - - const binPackage = dirname( - requirePgltPackage.resolve(`${packageName}/package.json`) - ); + const binPackage = dirname( + requirePgltPackage.resolve(`${nodePkgName}/package.json`) + ); - logger.debug(`Resolved binpackage`, { binPackage }); + logger.debug(`Resolved binpackage`, { binPackage }); - const postgrestoolsPath = join( - binPackage, - CONSTANTS.platformSpecificBinaryName - ); - const postgrestools = Uri.file(postgrestoolsPath); + const binPath = join(binPackage, binaryName); + const bin = Uri.file(binPath); - if (await fileExists(postgrestools)) { - return postgrestools; + if (await fileExists(bin)) { + return bin; + } + logger.debug( + `Unable to find Postgres Language Server in path ${binPath}` + ); } - logger.debug(`Unable to find PostgresTools in path ${postgrestoolsPath}`); - return null; }, }; @@ -200,7 +218,9 @@ export const nodeModulesStrategy: BinaryFindStrategy = { export const yarnPnpStrategy: BinaryFindStrategy = { name: "Yarn PnP Strategy", async find(path?: Uri) { - logger.debug("Trying to find PostgresTools binary in Yarn Plug'n'Play"); + logger.debug( + "Trying to find Postgres Language Server binary in Yarn Plug'n'Play" + ); if (!path) { logger.debug("No local path, skipping."); @@ -225,41 +245,59 @@ export const yarnPnpStrategy: BinaryFindStrategy = { const yarnPnpApi = require(pnpFile.fsPath); /** - * Issue a request to the PostgresTools package.json from the current dir. + * Issue a request to the Postgres Language Server package.json from the current dir. */ - const postgrestoolsPackage = yarnPnpApi.resolveRequest( - `${CONSTANTS.npmPackageName}/package.json`, - path.fsPath - ); + for (const [pkgname, nodePkgName, binaryName] of [ + [ + CONSTANTS.newPackageName, + CONSTANTS.newPlatformSpecificNodePackageName, + CONSTANTS.newPlatformSpecificBinaryName, + ], + [ + CONSTANTS.oldPackageName, + CONSTANTS.oldPlatformSpecificNodePackageName, + CONSTANTS.oldPlatformSpecificBinaryName, + ], + ]) { + if (nodePkgName === undefined) { + logger.debug( + `No node package for current platform available in yarn pnp`, + { + os: process.platform, + arch: process.arch, + } + ); + continue; + } - if (!postgrestoolsPackage) { - logger.debug( - "Unable to find PostgresTools package via Yarn Plug'n'Play API" - ); - continue; - } + // yarn api will throw if we require a pkg that is not listed in package.json + try { + const packageJson = yarnPnpApi.resolveRequest( + `${pkgname}/package.json`, + path.fsPath + ); - const packageName = CONSTANTS.platformSpecificNodePackageName; - if (packageName === undefined) { - logger.debug(`No package for current platform available in yarn pnp`, { - os: process.platform, - arch: process.arch, - }); - return null; + /** + * Return URI to the platform-specific binary that the found main package depends on. + */ + return Uri.file( + yarnPnpApi.resolveRequest( + `${nodePkgName}/${binaryName}`, + packageJson + ) + ); + } catch { + logger.debug( + `Unable to find package ${pkgname} via Yarn Plug'n'Play API` + ); + continue; + } } - - /** - * Return URI to the platform-specific binary that the found main package depends on. - */ - return Uri.file( - yarnPnpApi.resolveRequest( - `${packageName}/${CONSTANTS.platformSpecificBinaryName}`, - postgrestoolsPackage - ) - ); } - logger.debug("Couldn't find PostgresTools binary via Yarn Plug'n'Play"); + logger.debug( + "Couldn't find Postgres Language Server binary via Yarn Plug'n'Play" + ); return null; }, @@ -270,7 +308,9 @@ export const pathEnvironmentVariableStrategy: BinaryFindStrategy = { async find() { const pathEnv = process.env.PATH; - logger.debug("Trying to find PostgresTools binary in PATH env var"); + logger.debug( + "Trying to find Postgres Language Server binary in PATH env var" + ); if (!pathEnv) { logger.debug("Path env var not found"); @@ -280,13 +320,15 @@ export const pathEnvironmentVariableStrategy: BinaryFindStrategy = { for (const dir of pathEnv.split(delimiter)) { logger.debug(`Checking ${dir}`); - const postgrestools = Uri.joinPath( - Uri.file(dir), - CONSTANTS.platformSpecificBinaryName - ); + for (const bname of [ + CONSTANTS.newPlatformSpecificBinaryName, + CONSTANTS.oldPlatformSpecificBinaryName, + ]) { + const bin = Uri.joinPath(Uri.file(dir), bname); - if (await fileExists(postgrestools)) { - return postgrestools; + if (await fileExists(bin)) { + return bin; + } } } @@ -297,9 +339,9 @@ export const pathEnvironmentVariableStrategy: BinaryFindStrategy = { }; export const downloadPgltStrategy: BinaryFindStrategy = { - name: "Download PostgresTools Strategy", + name: "Download Postgres Language Server Strategy", async find() { - logger.debug(`Trying to find downloaded PostgresTools binary`); + logger.debug(`Trying to find downloaded Postgres Language Server binary`); const downloadedBinary = await getDownloadedBinary(); @@ -313,7 +355,7 @@ export const downloadPgltStrategy: BinaryFindStrategy = { const proceed = (await window.showInformationMessage( - "You've opened a supported file outside of a PostgresTools project, and no installed PostgresTools binary could be found on your system. Would you like to download and install PostgresTools?", + "You've opened a supported file outside of a Postgres Language Server project, and no installed Postgres Language Server binary could be found on your system. Would you like to download and install Postgres Language Server?", "Download and install", "No" )) === "Download and install"; diff --git a/src/binary-finder.ts b/src/binary-finder.ts index 555bb30..abadb78 100644 --- a/src/binary-finder.ts +++ b/src/binary-finder.ts @@ -11,22 +11,36 @@ import { logger } from "./logger"; type Strategy = { label: string; + kind: StrategyKind; strategy: BinaryFindStrategy; onSuccess: (u: Uri) => void; condition?: (path?: Uri) => Promise; }; +export enum StrategyKind { + NPM, + Yarn, + VsCodeSettings, + Path, + Download, +} + const LOCAL_STRATEGIES: Strategy[] = [ { label: "VSCode Settings", + kind: StrategyKind.VsCodeSettings, strategy: vsCodeSettingsStrategy, onSuccess: (uri) => - logger.debug(`Found Binary in VSCode Settings (postgrestools.bin)`, { - path: uri.fsPath, - }), + logger.debug( + `Found Binary in VSCode Settings (postgres-language-server.bin) or (postgrestools.bin)`, + { + path: uri.fsPath, + } + ), }, { label: "NPM node_modules", + kind: StrategyKind.NPM, strategy: nodeModulesStrategy, onSuccess: (uri) => logger.debug(`Found Binary in Node Modules`, { @@ -35,6 +49,7 @@ const LOCAL_STRATEGIES: Strategy[] = [ }, { label: "Yarn Plug'n'Play node_modules", + kind: StrategyKind.Yarn, strategy: yarnPnpStrategy, onSuccess: (uri) => logger.debug(`Found Binary in Yarn PnP`, { @@ -43,6 +58,7 @@ const LOCAL_STRATEGIES: Strategy[] = [ }, { label: "PATH Environment Variable", + kind: StrategyKind.Path, strategy: pathEnvironmentVariableStrategy, onSuccess: (uri) => logger.debug(`Found Binary in PATH Environment Variable`, { @@ -51,6 +67,7 @@ const LOCAL_STRATEGIES: Strategy[] = [ }, { label: "Downloaded Binary", + kind: StrategyKind.Download, strategy: downloadPgltStrategy, onSuccess: (uri) => logger.debug(`Found downloaded binary`, { @@ -61,14 +78,16 @@ const LOCAL_STRATEGIES: Strategy[] = [ const GLOBAL_STRATEGIES: Strategy[] = [ { label: "VSCode Settings", + kind: StrategyKind.VsCodeSettings, strategy: vsCodeSettingsStrategy, onSuccess: (uri) => - logger.debug(`Found Binary in VSCode Settings (postgrestools.bin)`, { + logger.debug(`Found Binary in VSCode Settings`, { path: uri.fsPath, }), }, { label: "PATH Environment Variable", + kind: StrategyKind.Path, strategy: pathEnvironmentVariableStrategy, onSuccess: (uri) => logger.debug(`Found Binary in PATH Environment Variable`, { @@ -77,6 +96,7 @@ const GLOBAL_STRATEGIES: Strategy[] = [ }, { label: "Downloaded Binary", + kind: StrategyKind.Download, strategy: downloadPgltStrategy, onSuccess: (uri) => logger.debug(`Found downloaded binary`, { @@ -109,7 +129,7 @@ export class BinaryFinder { } private static async attemptFind(strategies: Strategy[], path?: Uri) { - for (const { strategy, onSuccess, condition, label } of strategies) { + for (const { strategy, onSuccess, condition, label, kind } of strategies) { if (condition && !(await condition(path))) { continue; } @@ -118,7 +138,7 @@ export class BinaryFinder { const binary = await strategy.find(path); if (binary) { onSuccess(binary); - return { bin: binary, label }; + return { bin: binary, label, kind }; } else { logger.info(`Binary not found with strategy`, { strategy: strategy.name, diff --git a/src/commands.ts b/src/commands.ts index 5be11de..7e6f8d7 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -31,7 +31,7 @@ export class UserFacingCommands { /** * When calling this command, the user will be prompted to select a version of - * the PostgresTools CLI to install. The selected version will be downloaded and stored + * the Postgres Language Server CLI to install. The selected version will be downloaded and stored * in VS Code's global storage directory. */ static async download() { @@ -39,7 +39,7 @@ export class UserFacingCommands { } /** - * Stops and restarts the PostgresTools extension, resetting state and cleaning up temporary binaries. + * Stops and restarts the Postgres Language Server extension, resetting state and cleaning up temporary binaries. */ static async reset() { await stop(); @@ -52,7 +52,7 @@ export class UserFacingCommands { state.activeSession = undefined; state.activeProject = undefined; - logger.info("PostgresTools extension was reset"); + logger.info("Postgres Language Server extension was reset"); await start(); } @@ -61,17 +61,21 @@ export class UserFacingCommands { const session = state.activeSession; if (!session) { - window.showInformationMessage("No PostgresTools version installed."); + window.showInformationMessage( + "No Postgres Language Server version installed." + ); return; } const version = await getVersion(session.bin); if (!version) { - window.showInformationMessage("No PostgresTools version installed."); + window.showInformationMessage( + "No Postgres Language Server version installed." + ); } else { window.showInformationMessage( - `Currently installed PostgresTools version is ${version}.` + `Currently installed Postgres Language Server version is ${version}.` ); window.showInformationMessage( `Using binary from "${session.binaryStrategyLabel}".` @@ -124,7 +128,7 @@ export class UserFacingCommands { } default: { window.showErrorMessage( - `Unsupported Platform: ${process.platform}. PostgresTools only runs on linux, darwin and windows.` + `Unsupported Platform: ${process.platform}. Postgres Language Server only runs on linux, darwin and windows.` ); return; } diff --git a/src/config.ts b/src/config.ts index d5050c0..b57295f 100644 --- a/src/config.ts +++ b/src/config.ts @@ -4,10 +4,11 @@ import { type WorkspaceFolder, workspace, } from "vscode"; +import { logger } from "./logger"; /** * This function retrieves a setting from the workspace configuration. - * Settings are looked up under the "postgrestools" prefix. + * Settings are looked up first under the "postgreslanguageserver", then under the "postgrestools" prefix. * * @param key The key of the setting to retrieve */ @@ -15,13 +16,22 @@ export const getFullConfig = ( options: { scope?: ConfigurationScope; } = {} -): WorkspaceConfiguration | undefined => { - return workspace.getConfiguration("postgrestools", options.scope); +): { + postgrestools: WorkspaceConfiguration | undefined; + postgresLanguageServer: WorkspaceConfiguration | undefined; +} => { + return { + postgrestools: workspace.getConfiguration("postgrestools", options.scope), + postgresLanguageServer: workspace.getConfiguration( + "postgres-language-server", + options.scope + ), + }; }; /** * This function retrieves a setting from the workspace configuration. - * Settings are looked up under the "postgrestools" prefix. + * Settings are looked up first under the "postgres-language-server", then under the "postgrestools" prefix. * * @param key The key of the setting to retrieve */ @@ -31,7 +41,28 @@ export const getConfig = ( scope?: ConfigurationScope; } = {} ): T | undefined => { - return workspace.getConfiguration("postgrestools", options.scope).get(key); + const newValue = workspace + .getConfiguration("postgres-language-server", options.scope) + .get(key); + + logger.debug(`Setting '${key}' in new config: ${newValue}`); + + if ( + newValue !== undefined && + newValue !== "" && + newValue !== null && + typeof newValue !== "boolean" + ) { + return newValue; + } + + const oldValue = workspace + .getConfiguration("postgrestools", options.scope) + .get(key); + + logger.debug(`Setting '${key}' in old config: ${oldValue}`); + + return oldValue; }; export const isEnabledForFolder = (folder: WorkspaceFolder): boolean => { diff --git a/src/constants.ts b/src/constants.ts index 7250790..1366c99 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -7,13 +7,14 @@ export enum OperatingMode { MultiRoot = "multi_root", } -const npmPackageName = "@postgrestools/postgrestools"; +const newPackageName = "@postgres-language-server/cli"; +const oldPackageName = "@postgrestools/postgrestools"; /** * platform and arch are values injected into the node runtime. * We use the values documented on https://nodejs.org. */ -const PACKAGE_NAMES: Record> = { +const OLD_PACKAGE_NAMES: Record> = { win32: { x64: `@postgrestools/cli-x86_64-windows-msvc`, arm64: `@postgrestools/cli-aarch64-windows-msvc`, @@ -27,6 +28,20 @@ const PACKAGE_NAMES: Record> = { arm64: `@postgrestools/cli-aarch64-linux-gnu`, }, }; +const NEW_PACKAGE_NAMES: Record> = { + win32: { + x64: `@postgres-language-server/cli-x86_64-windows-msvc`, + arm64: `@postgres-language-server/cli-aarch64-windows-msvc`, + }, + darwin: { + x64: `@postgres-language-server/cli-x86_64-apple-darwin`, + arm64: `@postgres-language-server/cli-aarch64-apple-darwin`, + }, + linux: { + x64: `@postgres-language-server/cli-x86_64-linux-gnu`, + arm64: `@postgres-language-server/cli-aarch64-linux-gnu`, + }, +}; const platformMappings: Record = { darwin: "apple-darwin", @@ -44,26 +59,41 @@ const _CONSTANTS = { activationTimestamp: Date.now(), - platformSpecificBinaryName: (() => { + oldPlatformSpecificBinaryName: (() => { return `postgrestools${process.platform === "win32" ? ".exe" : ""}`; })(), + newPlatformSpecificBinaryName: (() => { + return `postgres-language-server${ + process.platform === "win32" ? ".exe" : "" + }`; + })(), /** - * The name under which PostgresTools is published on npm. + * The name under which Postgres Language Server is published on npm. */ - npmPackageName, + oldPackageName, + newPackageName, - platformSpecificNodePackageName: (() => { + oldPlatformSpecificNodePackageName: (() => { const platform: string = process.platform; const arch: string = process.arch; - const pkg = PACKAGE_NAMES[platform]?.[arch]; + const pkg = OLD_PACKAGE_NAMES[platform]?.[arch]; + + // TS won't pick up on the possibility of this being undefined + return pkg as string | undefined; + })(), + newPlatformSpecificNodePackageName: (() => { + const platform: string = process.platform; + const arch: string = process.arch; + + const pkg = NEW_PACKAGE_NAMES[platform]?.[arch]; // TS won't pick up on the possibility of this being undefined return pkg as string | undefined; })(), - platformSpecificReleasedAssetName: (() => { + oldPlatformSpecificReleasedAssetName: (() => { let assetName = "postgrestools"; for (const [nodeArch, rustArch] of Object.entries(archMappings)) { @@ -83,6 +113,26 @@ const _CONSTANTS = { return assetName; })(), + newPlatformSpecificReleasedAssetName: (() => { + let assetName = "postgres-language-server"; + + for (const [nodeArch, rustArch] of Object.entries(archMappings)) { + if (nodeArch === process.arch) { + assetName += `_${rustArch}`; + } + } + + for (const [nodePlatform, rustPlatform] of Object.entries( + platformMappings + )) { + if (nodePlatform === process.platform) { + assetName += `-${rustPlatform}`; + } + } + + return assetName; + })(), + currentMachineSupported: (() => { // In future release, we should also check whether the toolchain matches (Linux musl, GNU etc.) return !!(platformMappings[process.platform] && archMappings[process.arch]); diff --git a/src/downloader.ts b/src/downloader.ts index 849e93d..c9fb3a4 100644 --- a/src/downloader.ts +++ b/src/downloader.ts @@ -1,3 +1,4 @@ +import * as semver from "semver"; import { ProgressLocation, QuickPickItem, @@ -10,9 +11,10 @@ import { state } from "./state"; import { CONSTANTS } from "./constants"; import { fileExists, getVersion } from "./utils"; import { chmodSync } from "fs"; +import { EARLIEST_CROSS_PUBLISHING_RELEASE } from "./renaming"; export async function downloadPglt(): Promise { - logger.debug(`Downloading PostgresTools`); + logger.debug(`Downloading Postgres Language Server`); const versionToDownload = await promptVersionToDownload(); @@ -23,7 +25,7 @@ export async function downloadPglt(): Promise { await window.withProgress( { - title: `Downloading PostgresTools ${versionToDownload.label}`, + title: `Downloading Postgres Language Server ${versionToDownload.label}`, location: ProgressLocation.Notification, }, () => downloadPgltVersion(versionToDownload.label) @@ -35,7 +37,14 @@ export async function downloadPglt(): Promise { } async function downloadPgltVersion(version: string): Promise { - const url = `https://github.com/supabase-community/postgres_lsp/releases/download/${version}/${CONSTANTS.platformSpecificReleasedAssetName}`; + const newNameAvailable = semver.gte( + version, + EARLIEST_CROSS_PUBLISHING_RELEASE + ); + + const url = newNameAvailable + ? `https://github.com/supabase-community/postgres_lsp/releases/download/${version}/${CONSTANTS.newPlatformSpecificReleasedAssetName}` + : `https://github.com/supabase-community/postgres_lsp/releases/download/${version}/${CONSTANTS.oldPlatformSpecificReleasedAssetName}`; logger.debug(`Attempting to download binary asset from Github`, { url }); @@ -57,12 +66,14 @@ async function downloadPgltVersion(version: string): Promise { return; } - const binPath = getInstalledBinaryPath(); + const binPath = newNameAvailable + ? getNewInstalledBinaryPath() + : getOldInstalledBinaryPath(); try { await workspace.fs.writeFile(binPath, new Uint8Array(binary)); chmodSync(binPath.fsPath, 0o755); - const successMsg = `Downloaded PostgresTools ${version} to ${binPath.fsPath}`; + const successMsg = `Downloaded Postgres Language Server ${version} to ${binPath.fsPath}`; logger.info(successMsg); window.showInformationMessage(successMsg); } catch (error) { @@ -78,34 +89,37 @@ export async function getDownloadedBinary(): Promise<{ } | null> { logger.debug(`Getting downloaded version`); - const bin = getInstalledBinaryPath(); + for (const bin of [ + getNewInstalledBinaryPath(), + getOldInstalledBinaryPath(), + ]) { + if (await fileExists(bin)) { + const version = await getVersion(bin); + if (!version) { + throw new Error("Just verified file exists, but it doesn't anymore."); + } + + logger.debug(`Found downloaded version and binary`, { + path: bin.fsPath, + version, + }); - if (await fileExists(bin)) { - const version = await getVersion(bin); - if (!version) { - throw new Error("Just verified file exists, but it doesn't anymore."); + return { + binPath: bin, + version, + }; + } else { + logger.info(`Downloaded binary does not exist:`, { binPath: bin }); } - - logger.debug(`Found downloaded version and binary`, { - path: bin.fsPath, - version, - }); - - return { - binPath: bin, - version, - }; } - logger.info(`Downloaded binary does not exist.`, { - binPath: bin, - }); - return null; } async function promptVersionToDownload() { - logger.debug(`Prompting user to select PostgresTools version to download`); + logger.debug( + `Prompting user to select Postgres Language Server version to download` + ); const itemsPromise: Promise = new Promise( async (resolve) => { @@ -146,15 +160,23 @@ async function promptVersionToDownload() { ); return window.showQuickPick(itemsPromise, { - title: "Select PostgresTools version to download", - placeHolder: "Select PostgresTools version to download", + title: "Select Postgres Language Server version to download", + placeHolder: "Select Postgres Language Server version to download", }); } -function getInstalledBinaryPath() { +function getOldInstalledBinaryPath() { + return Uri.joinPath( + state.context.globalStorageUri, + CONSTANTS.globalStorageFolderForBinary, + CONSTANTS.oldPlatformSpecificBinaryName + ); +} + +function getNewInstalledBinaryPath() { return Uri.joinPath( state.context.globalStorageUri, CONSTANTS.globalStorageFolderForBinary, - CONSTANTS.platformSpecificBinaryName + CONSTANTS.newPlatformSpecificBinaryName ); } diff --git a/src/extension.ts b/src/extension.ts index f34b447..8ff4940 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -12,7 +12,7 @@ import { debounce } from "./utils"; import { updateHidden } from "./status-bar"; /** - * This function is responsible for booting the PostgresTools extension. It is called + * This function is responsible for booting the Postgres Language Server extension. It is called * when the extension is activated. */ export const createExtension = async () => { @@ -23,7 +23,7 @@ export const createExtension = async () => { }; /** - * This function is responsible for shutting down the PostgresTools extension. It is + * This function is responsible for shutting down the Postgres Language Server extension. It is * called when the extension is deactivated and will trigger a cleanup of the * extension's state and resources. */ @@ -32,6 +32,38 @@ export const destroyExtension = async () => { }; const registerUserFacingCommands = () => { + state.context.subscriptions.push( + commands.registerCommand( + "postgres-language-server.start", + UserFacingCommands.start + ), + commands.registerCommand( + "postgres-language-server.stop", + UserFacingCommands.stop + ), + commands.registerCommand( + "postgres-language-server.restart", + UserFacingCommands.restart + ), + commands.registerCommand( + "postgres-language-server.download", + UserFacingCommands.download + ), + commands.registerCommand( + "postgres-language-server.reset", + UserFacingCommands.reset + ), + commands.registerCommand( + "postgres-language-server.currentVersion", + UserFacingCommands.currentVersion + ), + commands.registerCommand( + "postgres-language-server.copyLatestLogfile", + UserFacingCommands.copyLatestLogfile + ) + ); + + // deprecated state.context.subscriptions.push( commands.registerCommand("postgrestools.start", UserFacingCommands.start), commands.registerCommand("postgrestools.stop", UserFacingCommands.stop), @@ -58,14 +90,19 @@ const registerUserFacingCommands = () => { }; /** - * This function sets up a listener for configuration changes in the `postgrestools` - * namespace. When a configuration change is detected, the extension is + * This function sets up a listener for configuration changes in the `postgres-language-server` + * or `postgrestools` namespace. When a configuration change is detected, the extension is * restarted to reflect the new configuration. */ const listenForConfigurationChanges = () => { const debouncedConfigurationChangeHandler = debounce( (event: ConfigurationChangeEvent) => { - if (event.affectsConfiguration("postgrestools")) { + if (event.affectsConfiguration("postgres-language-server")) { + logger.info("Configuration change detected."); + if (!["restarting", "stopping"].includes(state.state)) { + restart(); + } + } else if (event.affectsConfiguration("postgrestools")) { logger.info("Configuration change detected."); if (!["restarting", "stopping"].includes(state.state)) { restart(); diff --git a/src/index.ts b/src/index.ts index 3f43acf..37cd45d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,12 +12,14 @@ import { CONSTANTS } from "./constants"; export async function activate(context: vscode.ExtensionContext) { logger.clear(); logger.info( - `PostgresTools extension ${context.extension.packageJSON.version} activated` + `Postgres Language Server extension ${context.extension.packageJSON.version} activated` ); state.context = context; const config = getFullConfig(); + logger.info(`Default of a boolean is ${getConfig("testDefault")}`); + logger.info(`Starting with config…`, { config }); logger.info(`In mode…`, { mode: CONSTANTS.operatingMode }); diff --git a/src/lifecycle.ts b/src/lifecycle.ts index 60b142d..4b7ffce 100644 --- a/src/lifecycle.ts +++ b/src/lifecycle.ts @@ -4,23 +4,23 @@ import { createActiveSession, destroySession } from "./session"; import { state } from "./state"; /** - * Starts the PostgresTools extension + * Starts the Postgres Language Server extension */ export const start = async () => { state.state = "starting"; await doStart(); state.state = "started"; - logger.info("PostgresTools extension started"); + logger.info("Postgres Language Server extension started"); }; /** - * Stops the PostgresTools extension + * Stops the Postgres Language Server extension */ export const stop = async () => { state.state = "stopping"; await doStop(); state.state = "stopped"; - logger.info("PostgresTools extension stopped"); + logger.info("Postgres Language Server extension stopped"); }; export const restart = async () => { @@ -33,7 +33,7 @@ export const restart = async () => { await doStop(); await doStart(); state.state = "started"; - logger.info("PostgresTools extension restarted"); + logger.info("Postgres Language Server extension restarted"); }; const doStart = async () => { @@ -44,7 +44,9 @@ const doStart = async () => { if (e instanceof Error) { logger.error(e.message); } - logger.error("Failed to start PostgresTools extension", { error: e }); + logger.error("Failed to start Postgres Language Server extension", { + error: e, + }); state.state = "error"; } }; diff --git a/src/logger.ts b/src/logger.ts index 9705214..8232cf6 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -4,7 +4,7 @@ import { CONSTANTS } from "./constants"; type LogArguments = Record; /** - * Messages logged to this logger will be displayed in the `PostgresTools` output + * Messages logged to this logger will be displayed in the `Postgres Language Server` output * channel in the Output panel. This logger respects the user's settings for * logging verbosity, so only messages with the appropriate log level will be * displayed. @@ -24,7 +24,12 @@ class Logger { ) { if (args) { message += `\n\t${Object.entries(args) - .map(([key, value]) => `${key}=${JSON.stringify(value)}`) + .map( + ([key, value]) => + `${key}=${ + value instanceof Error ? value.message : JSON.stringify(value) + }` + ) .join("\n\t")}`; } diff --git a/src/project.ts b/src/project.ts index 28334f3..cc306f2 100644 --- a/src/project.ts +++ b/src/project.ts @@ -20,7 +20,7 @@ export async function getActiveProjectsForMultiRoot( if (globalConfigSetting && globalConfigSetting.startsWith(".")) { window.showErrorMessage( - "Relative paths to the `postgrestools.jsonc` file in a multi-root workspace are not supported. Please use an absolute path in your `*.code-workspace` file." + "Relative paths to the `postgres-language-server.jsonc` or `postgrestools.jsonc` file in a multi-root workspace are not supported. Please use an absolute path in your `*.code-workspace` file." ); return []; } @@ -41,17 +41,31 @@ export async function getActiveProjectsForMultiRoot( return await Promise.all( folders.map(async (folder) => { if (!isEnabledForFolder(folder)) { + logger.info( + `Postgres Language Server disabled for folder via settings`, + { + path: folder.uri, + } + ); + return null; } if (!globalConfig) { - const defaultConfigPath = Uri.joinPath( + const defaultConfigPathNew = Uri.joinPath( + folder.uri, + "postgres-language-server.jsonc" + ); + const defaultConfigPathOld = Uri.joinPath( folder.uri, "postgrestools.jsonc" ); - const exists = await fileExists(defaultConfigPath); - if (!exists) { + const hasDefaultConfig = + (await fileExists(defaultConfigPathNew)) || + (await fileExists(defaultConfigPathOld)); + + if (!hasDefaultConfig) { logger.info( `Project does not have a config file at default path and is therefore excluded from multi-root workspace.`, { @@ -84,7 +98,15 @@ export async function getActiveProjectForSingleRoot( configPath = Uri.joinPath(first.uri, userConfig); } else { logger.info("User did not specify path to config file. Using default."); - configPath = Uri.joinPath(first.uri, "postgrestools.jsonc"); + + const newDefault = Uri.joinPath( + first.uri, + "postgres-language-server.jsonc" + ); + + const oldDefault = Uri.joinPath(first.uri, "postgrestools.jsonc"); + + configPath = (await fileExists(newDefault)) ? newDefault : oldDefault; } if (!(await fileExists(configPath))) { diff --git a/src/renaming.ts b/src/renaming.ts new file mode 100644 index 0000000..29f277a --- /dev/null +++ b/src/renaming.ts @@ -0,0 +1,45 @@ +import semver from "semver"; +import { StrategyKind } from "./binary-finder"; + +export const EARLIEST_CROSS_PUBLISHING_RELEASE = "99.99.99"; +export const LATEST_CROSS_PUBLISHING_RELEASE = "99.99.99"; + +export function shouldInformRename( + installedVersion: string, + latestAvailableVersion: string +) { + return ( + semver.lte(installedVersion, LATEST_CROSS_PUBLISHING_RELEASE) && + semver.gte(latestAvailableVersion, EARLIEST_CROSS_PUBLISHING_RELEASE) + ); +} + +export function updateAndRenamingMessageForKind(kind: StrategyKind): string { + switch (kind) { + case StrategyKind.NPM: + case StrategyKind.Yarn: + return "A new version of the Postgres Language Server is available! Make sure to use the new `@postgres-language-server/cli` package, as the old `@postgrestools/postgrestools` is being phased out."; + case StrategyKind.Download: + case StrategyKind.Path: + case StrategyKind.VsCodeSettings: + return "A new version of the Postgres Language Server is available! Make sure to get the binary from the new `postgres-language-server` name, as the old `postgrestools` is being phased out."; + default: + kind satisfies never; + throw new Error("Unreachable"); + } +} + +export function renamingMessageForKind(kind: StrategyKind): string { + switch (kind) { + case StrategyKind.NPM: + case StrategyKind.Yarn: + return "Warning: Please make sure to use the new `@postgres-language-server/cli` package, as the old `@postgrestools/postgrestools` is being phased out. If you've already switched, you're all set!"; + case StrategyKind.Download: + case StrategyKind.Path: + case StrategyKind.VsCodeSettings: + return "Warning: Please make sure to use a binary from the new `postgres-language-server` package, as the old `postgrestools` is being phased out. If you've already switched, you're all set!"; + default: + kind satisfies never; + throw new Error("Unreachable"); + } +} diff --git a/src/session.ts b/src/session.ts index 0b42161..169f922 100644 --- a/src/session.ts +++ b/src/session.ts @@ -21,15 +21,16 @@ import { type Project, } from "./project"; import { state } from "./state"; -import { - daysToMs, - fileExists, - fileIsExecutable, - getVersion, - subtractURI, -} from "./utils"; +import { daysToMs, fileExists, fileIsExecutable, getVersion } from "./utils"; import { CONSTANTS, OperatingMode } from "./constants"; import { getConfig, isEnabledForFolder } from "./config"; +import { + EARLIEST_CROSS_PUBLISHING_RELEASE, + LATEST_CROSS_PUBLISHING_RELEASE, + renamingMessageForKind, + shouldInformRename, + updateAndRenamingMessageForKind, +} from "./renaming"; export type Session = { bin: Uri; @@ -51,9 +52,9 @@ export const createSession = async ( if (!findResult) { window.showErrorMessage( - `Unable to find a PostgresTools binary. Read the docs for more various strategies to install a binary.` + `Unable to find a Postgres Language Server binary. Read the docs for various strategies to install a binary.` ); - logger.error("Could not find the PostgresTools binary"); + logger.error("Could not find the Postgres Language Server binary"); return; } @@ -66,10 +67,6 @@ export const createSession = async ( return; } - logger.info("Copying binary to temp location", { - currentLocation: findResult.bin.fsPath, - }); - const version = await getVersion(findResult.bin); if (!version) { throw new Error( @@ -81,14 +78,23 @@ export const createSession = async ( state.context.globalState.get("lastNotifiedOfUpdate") || new Date(0).toISOString(); - if ( - state.releases.versionOutdated(version) && - state.releases.latestVersion() && - Date.now() - new Date(lastNotifiedOfUpdate).getTime() > daysToMs(3) - ) { - window.showInformationMessage( - `A new version of PostgresTools is available! your version ${version} is outdated, consider updating to latest version ${state.releases.latestVersion()}.` - ); + if (Date.now() - new Date(lastNotifiedOfUpdate).getTime() > daysToMs(3)) { + const latestVersion = state.releases.latestVersion() ?? "0.0.0"; + + if (state.releases.versionOutdated(version)) { + if (shouldInformRename(version, latestVersion)) { + window.showInformationMessage( + updateAndRenamingMessageForKind(findResult.kind) + ); + } else { + window.showInformationMessage( + `A new version of Postgres Language Server is available! Your version ${version} is outdated, consider updating to latest version ${state.releases.latestVersion()}.` + ); + } + } else if (shouldInformRename(version, latestVersion)) { + window.showInformationMessage(renamingMessageForKind(findResult.kind)); + } + await state.context.globalState.update( "lastNotifiedOfUpdate", new Date().toISOString() @@ -100,10 +106,14 @@ export const createSession = async ( !semver.gte(version, "0.8.0") ) { window.showInformationMessage( - `Your current PostgresTools version ${version} does not support multi-root workspaces. Consider upgrading to version >= 0.8.0.` + `Your current Postgres Language Server version ${version} does not support multi-root workspaces. Consider upgrading to version >= 0.8.0.` ); } + logger.info("Copying binary to temp location", { + currentLocation: findResult.bin.fsPath, + }); + // Copy the binary to a temporary location, and run it from there // so that the original binary can be updated without locking issues. // We'll keep track of that temporary location in the session and @@ -157,9 +167,9 @@ const copyBinaryToTemporaryLocation = async ( const location = Uri.joinPath( state.context.globalStorageUri, "tmp-bin", - CONSTANTS.platformSpecificBinaryName.replace( - "postgrestools", - `postgrestools-${version}` + CONSTANTS.newPlatformSpecificBinaryName.replace( + "postgres-language-server", + `postgres-language-server-${version}` ) ); @@ -175,7 +185,7 @@ const copyBinaryToTemporaryLocation = async ( }); copyFileSync(bin.fsPath, location.fsPath); logger.debug( - "Copied postgrestools binary binary to temporary location.", + "Copied postgres language server binary binary to temporary location.", { original: bin.fsPath, temporary: location.fsPath, @@ -183,7 +193,7 @@ const copyBinaryToTemporaryLocation = async ( ); } else { logger.debug( - `A postgrestools binary for the same version ${version} already exists in the temporary location.`, + `A postgres language server binary for the same version ${version} already exists in the temporary location.`, { original: bin.fsPath, temporary: location.fsPath, @@ -214,7 +224,7 @@ export const createActiveSession = async () => { if (CONSTANTS.operatingMode === OperatingMode.SingleFile) { logger.warn( - "Single file mode unsupported, because we need a `postgrestools.jsonc` file." + "Single file mode unsupported, because we need a configuration file." ); return; } @@ -230,10 +240,10 @@ export const createActiveSession = async () => { try { if (state.activeSession) { await state.activeSession?.client.start(); - logger.info("Created a postgrestools session"); + logger.info("Created a postgres language server session"); } } catch (e) { - logger.error("Failed to create postgrestools session", { + logger.error("Failed to create postgres language server session", { error: `${e}`, }); state.activeSession?.client.dispose(); @@ -287,7 +297,7 @@ async function createActiveSessionForMultiRoot(): Promise { } /** - * Creates a new PostgresTools LSP client + * Creates a new Postgres Language Server LSP client */ const createLanguageClient = (bin: Uri, projects: Project[]) => { const singleRootProject = projects.length === 1 ? projects[0] : undefined; @@ -326,9 +336,12 @@ const createLanguageClient = (bin: Uri, projects: Project[]) => { progressOnInitialization: true, initializationFailedHandler: (e): boolean => { - logger.error("Failed to initialize the PostgresTools language server", { - error: e.toString(), - }); + logger.error( + "Failed to initialize the Postgres Language Server language server", + { + error: e.toString(), + } + ); return false; }, @@ -338,7 +351,7 @@ const createLanguageClient = (bin: Uri, projects: Project[]) => { message, count ): ErrorHandlerResult | Promise => { - logger.error("PostgresTools language server error", { + logger.error("Postgres Language Server language server error", { error: error.toString(), stack: error.stack, errorMessage: error.message, @@ -348,14 +361,14 @@ const createLanguageClient = (bin: Uri, projects: Project[]) => { return { action: ErrorAction.Shutdown, - message: "PostgresTools language server error", + message: "Postgres Language Server language server error", }; }, closed: (): CloseHandlerResult | Promise => { - logger.error("PostgresTools language server closed"); + logger.error("Postgres Language Server language server closed"); return { action: CloseAction.DoNotRestart, - message: "PostgresTools language server closed", + message: "Postgres Language Server language server closed", }; }, }, @@ -366,16 +379,16 @@ const createLanguageClient = (bin: Uri, projects: Project[]) => { workspaceFolder: undefined, }; - return new PostgresToolsLanguageClient( - "postgrestools.lsp", - "postgrestools", + return new PostgresLanguageServerLanguageClient( + "postgres-language-server.lsp", + "postgres-language-server", serverOptions, clientOptions ); }; /** - * Creates a new PostgresTools LSP logger + * Creates a new Postgres Language Server LSP logger */ const createLspLogger = (): LogOutputChannel => { return window.createOutputChannel( @@ -387,7 +400,7 @@ const createLspLogger = (): LogOutputChannel => { }; /** - * Creates a new PostgresTools LSP logger + * Creates a new Postgres Language Server LSP logger */ const createLspTraceLogger = (): LogOutputChannel => { // If the project is missing, we're creating a logger for the global LSP @@ -415,7 +428,7 @@ const createDocumentSelector = (projects: Project[]): DocumentFilter[] => { }); }; -class PostgresToolsLanguageClient extends LanguageClient { +class PostgresLanguageServerLanguageClient extends LanguageClient { protected fillInitializeParams(params: InitializeParams): void { super.fillInitializeParams(params); diff --git a/src/status-bar.ts b/src/status-bar.ts index 97f4946..9a6bb79 100644 --- a/src/status-bar.ts +++ b/src/status-bar.ts @@ -13,7 +13,7 @@ export type StatusBar = { const createStatusBar = (): StatusBar => { const item = window.createStatusBarItem( - "postgrestools_vscode", + "postgres-language-server_vscode", StatusBarAlignment.Right, 1 ); @@ -58,7 +58,7 @@ const getLspVersion = () => { }; const getStateText = (): string => { - return "PostgresTools"; + return "Postgres Language Server"; }; const getStateTooltip = (): string => { diff --git a/src/utils.ts b/src/utils.ts index 647928c..48a1cd9 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -105,7 +105,7 @@ export function subtractURI(original: Uri, subtract: Uri): Uri | undefined { * This function checks if a file is executable using Node's `accessSync` function. * It returns true if the file is executable, otherwise it returns false. * - * This is used to ensure that downloaded PostgresTools binaries are executable. + * This is used to ensure that downloaded Postgres Language Server binaries are executable. */ export function fileIsExecutable(uri: Uri): boolean { try { @@ -117,7 +117,7 @@ export function fileIsExecutable(uri: Uri): boolean { } // Retrieve the version of the binary -// We call postgrestools with --version which outputs the version in the format +// We call postgres-language-server with --version which outputs the version in the format // of "Version: 1.0.0" export async function getVersion(bin: Uri): Promise { if (!(await fileExists(bin))) { diff --git a/test/fixtures/monorepo-nested-config/.vscode/settings.json b/test/fixtures/monorepo-nested-config/.vscode/settings.json index 46c1dfd..70fd551 100644 --- a/test/fixtures/monorepo-nested-config/.vscode/settings.json +++ b/test/fixtures/monorepo-nested-config/.vscode/settings.json @@ -1,4 +1,4 @@ { "postgrestools.configFile": "/packages/service-a/postgrestools.jsonc", - "postgrestools.allowDownloadPrereleases": true + "postgrestools.allowDownloadPrereleases": true, } diff --git a/test/fixtures/monorepo-nested-config/packages/service-b/test.sql b/test/fixtures/monorepo-nested-config/packages/service-b/test.sql index 8ebec27..519bda8 100644 --- a/test/fixtures/monorepo-nested-config/packages/service-b/test.sql +++ b/test/fixtures/monorepo-nested-config/packages/service-b/test.sql @@ -1 +1 @@ -select email from users; \ No newline at end of file +select nothing from users; \ No newline at end of file diff --git a/test/fixtures/multi-root-with-overwrites/project-1/test.sql b/test/fixtures/multi-root-with-overwrites/project-1/test.sql index bdd037f..d455a07 100644 --- a/test/fixtures/multi-root-with-overwrites/project-1/test.sql +++ b/test/fixtures/multi-root-with-overwrites/project-1/test.sql @@ -1 +1 @@ -select email from public.users; \ No newline at end of file +select emai from public.users; \ No newline at end of file diff --git a/test/fixtures/multi-root-with-overwrites/project-2/test.sql b/test/fixtures/multi-root-with-overwrites/project-2/test.sql index bdd037f..d455a07 100644 --- a/test/fixtures/multi-root-with-overwrites/project-2/test.sql +++ b/test/fixtures/multi-root-with-overwrites/project-2/test.sql @@ -1 +1 @@ -select email from public.users; \ No newline at end of file +select emai from public.users; \ No newline at end of file diff --git a/test/fixtures/multi-root/project-1/test.sql b/test/fixtures/multi-root/project-1/test.sql index bdd037f..d455a07 100644 --- a/test/fixtures/multi-root/project-1/test.sql +++ b/test/fixtures/multi-root/project-1/test.sql @@ -1 +1 @@ -select email from public.users; \ No newline at end of file +select emai from public.users; \ No newline at end of file diff --git a/test/fixtures/multi-root/project-2/test.sql b/test/fixtures/multi-root/project-2/test.sql index 3c0b132..809d845 100644 --- a/test/fixtures/multi-root/project-2/test.sql +++ b/test/fixtures/multi-root/project-2/test.sql @@ -1 +1 @@ -select aud from auth.users; \ No newline at end of file +select au from auth.users; \ No newline at end of file diff --git a/test/fixtures/multi-root/project-disabled/test.sql b/test/fixtures/multi-root/project-disabled/test.sql index bdd037f..d455a07 100644 --- a/test/fixtures/multi-root/project-disabled/test.sql +++ b/test/fixtures/multi-root/project-disabled/test.sql @@ -1 +1 @@ -select email from public.users; \ No newline at end of file +select emai from public.users; \ No newline at end of file diff --git a/test/fixtures/multi-root/project-no-jsonc/test.sql b/test/fixtures/multi-root/project-no-jsonc/test.sql index a1aff9c..c09f076 100644 --- a/test/fixtures/multi-root/project-no-jsonc/test.sql +++ b/test/fixtures/multi-root/project-no-jsonc/test.sql @@ -1 +1 @@ -select * from auth.users; \ No newline at end of file +select emai from auth.users; \ No newline at end of file diff --git a/test/fixtures/node-modules-strat/src/test.sql b/test/fixtures/node-modules-strat/src/test.sql index dd2de61..025fcb9 100644 --- a/test/fixtures/node-modules-strat/src/test.sql +++ b/test/fixtures/node-modules-strat/src/test.sql @@ -1 +1 @@ -select name from public.users; \ No newline at end of file +select nam from public.users; \ No newline at end of file diff --git a/test/fixtures/simple-project-download/src/test.sql b/test/fixtures/simple-project-download/src/test.sql index 8ebec27..ca93151 100644 --- a/test/fixtures/simple-project-download/src/test.sql +++ b/test/fixtures/simple-project-download/src/test.sql @@ -1 +1 @@ -select email from users; \ No newline at end of file +select emai from users; \ No newline at end of file diff --git a/test/fixtures/simple-project-global-bin/src/test.sql b/test/fixtures/simple-project-global-bin/src/test.sql index 8ebec27..ca93151 100644 --- a/test/fixtures/simple-project-global-bin/src/test.sql +++ b/test/fixtures/simple-project-global-bin/src/test.sql @@ -1 +1 @@ -select email from users; \ No newline at end of file +select emai from users; \ No newline at end of file diff --git a/test/fixtures/vscode-settings-strat/src/test.sql b/test/fixtures/vscode-settings-strat/src/test.sql index 8ebec27..ca93151 100644 --- a/test/fixtures/vscode-settings-strat/src/test.sql +++ b/test/fixtures/vscode-settings-strat/src/test.sql @@ -1 +1 @@ -select email from users; \ No newline at end of file +select emai from users; \ No newline at end of file From b0f282931d756d7c79a7cbad68863ac08c8f3ca0 Mon Sep 17 00:00:00 2001 From: Julian Domke <68325451+juleswritescode@users.noreply.github.com> Date: Sun, 19 Oct 2025 15:52:29 +0200 Subject: [PATCH 2/5] Update src/config.ts --- src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.ts b/src/config.ts index b57295f..7f4241a 100644 --- a/src/config.ts +++ b/src/config.ts @@ -8,7 +8,7 @@ import { logger } from "./logger"; /** * This function retrieves a setting from the workspace configuration. - * Settings are looked up first under the "postgreslanguageserver", then under the "postgrestools" prefix. + * Settings are looked up first under the "postgres-language-server", then under the "postgrestools" prefix. * * @param key The key of the setting to retrieve */ From e6bffd993de626dc294bd9a422c91535a09a04ff Mon Sep 17 00:00:00 2001 From: Julian Date: Sun, 19 Oct 2025 15:55:52 +0200 Subject: [PATCH 3/5] unused --- src/extension.ts | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 8ff4940..2435b13 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -63,29 +63,6 @@ const registerUserFacingCommands = () => { ) ); - // deprecated - state.context.subscriptions.push( - commands.registerCommand("postgrestools.start", UserFacingCommands.start), - commands.registerCommand("postgrestools.stop", UserFacingCommands.stop), - commands.registerCommand( - "postgrestools.restart", - UserFacingCommands.restart - ), - commands.registerCommand( - "postgrestools.download", - UserFacingCommands.download - ), - commands.registerCommand("postgrestools.reset", UserFacingCommands.reset), - commands.registerCommand( - "postgrestools.currentVersion", - UserFacingCommands.currentVersion - ), - commands.registerCommand( - "postgrestools.copyLatestLogfile", - UserFacingCommands.copyLatestLogfile - ) - ); - logger.info("User-facing commands registered"); }; From ce227fdb16218c30fb8b3d5813aaea0fd6d339f8 Mon Sep 17 00:00:00 2001 From: Julian Date: Thu, 23 Oct 2025 09:54:44 +0200 Subject: [PATCH 4/5] chang name --- src/downloader.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/downloader.ts b/src/downloader.ts index c9fb3a4..d802463 100644 --- a/src/downloader.ts +++ b/src/downloader.ts @@ -43,8 +43,8 @@ async function downloadPgltVersion(version: string): Promise { ); const url = newNameAvailable - ? `https://github.com/supabase-community/postgres_lsp/releases/download/${version}/${CONSTANTS.newPlatformSpecificReleasedAssetName}` - : `https://github.com/supabase-community/postgres_lsp/releases/download/${version}/${CONSTANTS.oldPlatformSpecificReleasedAssetName}`; + ? `https://github.com/supabase-community/postgres-language-server/releases/download/${version}/${CONSTANTS.newPlatformSpecificReleasedAssetName}` + : `https://github.com/supabase-community/postgres-language-server/releases/download/${version}/${CONSTANTS.oldPlatformSpecificReleasedAssetName}`; logger.debug(`Attempting to download binary asset from Github`, { url }); From 1e56f5f2ad8698af41df18c398381562a299ce8e Mon Sep 17 00:00:00 2001 From: Julian Date: Thu, 23 Oct 2025 10:14:41 +0200 Subject: [PATCH 5/5] fixie --- src/downloader.ts | 7 ++----- src/renaming.ts | 39 +++++++++++++-------------------------- src/session.ts | 26 ++++++-------------------- 3 files changed, 21 insertions(+), 51 deletions(-) diff --git a/src/downloader.ts b/src/downloader.ts index d802463..e2f0201 100644 --- a/src/downloader.ts +++ b/src/downloader.ts @@ -11,7 +11,7 @@ import { state } from "./state"; import { CONSTANTS } from "./constants"; import { fileExists, getVersion } from "./utils"; import { chmodSync } from "fs"; -import { EARLIEST_CROSS_PUBLISHING_RELEASE } from "./renaming"; +import { hasNewName } from "./renaming"; export async function downloadPglt(): Promise { logger.debug(`Downloading Postgres Language Server`); @@ -37,10 +37,7 @@ export async function downloadPglt(): Promise { } async function downloadPgltVersion(version: string): Promise { - const newNameAvailable = semver.gte( - version, - EARLIEST_CROSS_PUBLISHING_RELEASE - ); + const newNameAvailable = await hasNewName(); const url = newNameAvailable ? `https://github.com/supabase-community/postgres-language-server/releases/download/${version}/${CONSTANTS.newPlatformSpecificReleasedAssetName}` diff --git a/src/renaming.ts b/src/renaming.ts index 29f277a..0e2f7ae 100644 --- a/src/renaming.ts +++ b/src/renaming.ts @@ -1,17 +1,19 @@ import semver from "semver"; import { StrategyKind } from "./binary-finder"; +import { CONSTANTS } from "./constants"; -export const EARLIEST_CROSS_PUBLISHING_RELEASE = "99.99.99"; -export const LATEST_CROSS_PUBLISHING_RELEASE = "99.99.99"; - -export function shouldInformRename( - installedVersion: string, - latestAvailableVersion: string -) { - return ( - semver.lte(installedVersion, LATEST_CROSS_PUBLISHING_RELEASE) && - semver.gte(latestAvailableVersion, EARLIEST_CROSS_PUBLISHING_RELEASE) - ); +export async function hasNewName() { + try { + const response = await fetch( + `https://github.com/supabase-community/postgres-language-server/releases/latest/download/${CONSTANTS.newPlatformSpecificReleasedAssetName}`, + { + method: "HEAD", + } + ); + return response.ok; + } catch { + return false; + } } export function updateAndRenamingMessageForKind(kind: StrategyKind): string { @@ -28,18 +30,3 @@ export function updateAndRenamingMessageForKind(kind: StrategyKind): string { throw new Error("Unreachable"); } } - -export function renamingMessageForKind(kind: StrategyKind): string { - switch (kind) { - case StrategyKind.NPM: - case StrategyKind.Yarn: - return "Warning: Please make sure to use the new `@postgres-language-server/cli` package, as the old `@postgrestools/postgrestools` is being phased out. If you've already switched, you're all set!"; - case StrategyKind.Download: - case StrategyKind.Path: - case StrategyKind.VsCodeSettings: - return "Warning: Please make sure to use a binary from the new `postgres-language-server` package, as the old `postgrestools` is being phased out. If you've already switched, you're all set!"; - default: - kind satisfies never; - throw new Error("Unreachable"); - } -} diff --git a/src/session.ts b/src/session.ts index 169f922..27bacea 100644 --- a/src/session.ts +++ b/src/session.ts @@ -24,13 +24,7 @@ import { state } from "./state"; import { daysToMs, fileExists, fileIsExecutable, getVersion } from "./utils"; import { CONSTANTS, OperatingMode } from "./constants"; import { getConfig, isEnabledForFolder } from "./config"; -import { - EARLIEST_CROSS_PUBLISHING_RELEASE, - LATEST_CROSS_PUBLISHING_RELEASE, - renamingMessageForKind, - shouldInformRename, - updateAndRenamingMessageForKind, -} from "./renaming"; +import { hasNewName, updateAndRenamingMessageForKind } from "./renaming"; export type Session = { bin: Uri; @@ -79,20 +73,12 @@ export const createSession = async ( new Date(0).toISOString(); if (Date.now() - new Date(lastNotifiedOfUpdate).getTime() > daysToMs(3)) { - const latestVersion = state.releases.latestVersion() ?? "0.0.0"; - if (state.releases.versionOutdated(version)) { - if (shouldInformRename(version, latestVersion)) { - window.showInformationMessage( - updateAndRenamingMessageForKind(findResult.kind) - ); - } else { - window.showInformationMessage( - `A new version of Postgres Language Server is available! Your version ${version} is outdated, consider updating to latest version ${state.releases.latestVersion()}.` - ); - } - } else if (shouldInformRename(version, latestVersion)) { - window.showInformationMessage(renamingMessageForKind(findResult.kind)); + window.showInformationMessage( + (await hasNewName()) + ? updateAndRenamingMessageForKind(findResult.kind) + : `A new version of Postgres Language Server is available! Your version ${version} is outdated, consider updating to latest version ${state.releases.latestVersion()}.` + ); } await state.context.globalState.update(