From bc2fe5848d446e38533412d56077445d5966b96c Mon Sep 17 00:00:00 2001 From: Sam Estep Date: Wed, 8 Jul 2026 09:26:21 -0400 Subject: [PATCH 1/2] Build Ruff VS Code extension from source to drop binary-lookup modal The prebuilt `charliermarsh.ruff` extension pops a modal error whenever its interpreter probe throws. That happens in non-Python projects where direnv has leaked the Nix SDK's `DEVELOPER_DIR`, which shadows Apple's `/usr/bin/python3` shim (`error: tool 'python3' not found`). The extension already falls back to the bundled ruff and works fine, so the modal is pure noise. nixpkgs ships the prebuilt Marketplace VSIX, so patch cleanly by building from source instead: fetch astral-sh/ruff-vscode, apply a 10-line patch removing the `showErrorMessage` modal (keeping the log line), run the webpack build, and ship only `dist/` plus the ruff binary at `bundled/libs/bin/ruff`. The deprecated `ruff-lsp` Python stack under `bundled/libs` is dropped -- it's only used by `nativeServer: off`, and we run the native server. Co-Authored-By: Claude Opus 4.8 (1M context) --- modules/vscode.nix | 4 ++- vscode/ruff/default.nix | 66 ++++++++++++++++++++++++++++++++++++++ vscode/ruff/no-popup.patch | 21 ++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 vscode/ruff/default.nix create mode 100644 vscode/ruff/no-popup.patch diff --git a/modules/vscode.nix b/modules/vscode.nix index ec50c2c..6d07965 100644 --- a/modules/vscode.nix +++ b/modules/vscode.nix @@ -7,7 +7,9 @@ vscode = pkgs.vscode-extensions; in [ - vscode.charliermarsh.ruff + # Built from source (see vscode/ruff) to drop the spurious binary-lookup + # modal; nixpkgs' prebuilt `vscode.charliermarsh.ruff` shows it. + (pkgs.callPackage ../vscode/ruff { }) vscode.esbenp.prettier-vscode vscode.github.vscode-github-actions vscode.gplane.wasm-language-tools diff --git a/vscode/ruff/default.nix b/vscode/ruff/default.nix new file mode 100644 index 0000000..b1e159e --- /dev/null +++ b/vscode/ruff/default.nix @@ -0,0 +1,66 @@ +# The Ruff VS Code extension, built from source (nixpkgs ships the prebuilt +# Marketplace VSIX) so we can patch its TypeScript rather than minified JS. +# +# The patch drops the modal error the extension pops when its interpreter probe +# throws -- which happens in non-Python projects where direnv has leaked the Nix +# SDK's DEVELOPER_DIR and thereby broken Apple's /usr/bin/python3 shim. The +# extension already falls back to the bundled ruff and works, so we keep only +# the log line. +# +# To bump `version`, refresh both hashes: +# nix flake prefetch github:astral-sh/ruff-vscode/ # -> hash +# nix run nixpkgs#prefetch-npm-deps -- /package-lock.json # -> npmDepsHash +# and re-check that no-popup.patch still applies (it fails loudly if not). +{ + lib, + buildNpmPackage, + fetchFromGitHub, + ruff, +}: + +buildNpmPackage rec { + pname = "vscode-extension-charliermarsh-ruff"; + version = "2026.56.0"; + + src = fetchFromGitHub { + owner = "astral-sh"; + repo = "ruff-vscode"; + rev = version; + hash = "sha256-96aITdErMnwJmhMmu2MUSVDu1kOavizUZWYQKFuIR6g="; + }; + + npmDepsHash = "sha256-sHv1J1O1q64161ImBOja8m6xzH+vmk3gsYkQc3YYNk8="; + + patches = [ ./no-popup.patch ]; + + # Match upstream's `npm ci --ignore-scripts`; the deps are pure JS. + npmFlags = [ "--ignore-scripts" ]; + + # `npm run package` == webpack --mode production -> dist/extension.js + npmBuildScript = "package"; + + installPhase = '' + runHook preInstall + + ext="$out/share/vscode/extensions/charliermarsh.ruff" + mkdir -p "$ext/bundled" + + cp package.json icon.png README.md CHANGELOG.md LICENSE "$ext/" + cp -r dist "$ext/dist" + cp -r bundled/tool "$ext/bundled/tool" + + # The native server (ruff.nativeServer, the default) runs this ruff binary + # directly. We skip the rest of bundled/libs -- the deprecated ruff-lsp + # Python stack, only used when ruff.nativeServer = "off". + mkdir -p "$ext/bundled/libs/bin" + ln -s ${lib.getExe ruff} "$ext/bundled/libs/bin/ruff" + + runHook postInstall + ''; + + meta = { + description = "Ruff VS Code extension, from source, with the spurious binary-lookup modal removed"; + homepage = "https://github.com/astral-sh/ruff-vscode"; + license = lib.licenses.mit; + }; +} diff --git a/vscode/ruff/no-popup.patch b/vscode/ruff/no-popup.patch new file mode 100644 index 0000000..26bfe6b --- /dev/null +++ b/vscode/ruff/no-popup.patch @@ -0,0 +1,21 @@ +diff --git a/src/common/server.ts b/src/common/server.ts +index aba6275..9d02aae 100644 +--- a/src/common/server.ts ++++ b/src/common/server.ts +@@ -203,16 +203,6 @@ export async function findRuffBinaryPath( + ]); + ruffBinaryPath = stdout.trim(); + } catch (err) { +- vscode.window +- .showErrorMessage( +- "Unexpected error while trying to find the Ruff binary. See the logs for more details.", +- "Show Logs", +- ) +- .then((selection) => { +- if (selection) { +- logger.channel.show(); +- } +- }); + logger.error(`Error while trying to find the Ruff binary: ${err}`); + } + } else { From f6d993d747ec7b5c35dc820bfbbbe271a7600863 Mon Sep 17 00:00:00 2001 From: Sam Estep Date: Mon, 13 Jul 2026 02:33:10 -0400 Subject: [PATCH 2/2] Add vscodeExt* passthru so home-manager can build extensions.json home-manager's vscode module reads vscodeExtUniqueId/vscodeExtPublisher/ vscodeExtName off every extension (via nixpkgs vscode-utils toExtensionJsonEntry) when generating .vscode/extensions/extensions.json. nixpkgs' Marketplace builder attaches those; a bare buildNpmPackage does not, so `nix build .#homeConfigurations.{sam,samueles}.activationPackage` failed at eval with `attribute 'vscodeExtUniqueId' missing`. Verified: samueles.activationPackage now builds (the hm-macos CI command). Co-Authored-By: Claude Opus 4.8 (1M context) --- vscode/ruff/default.nix | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vscode/ruff/default.nix b/vscode/ruff/default.nix index b1e159e..1b64521 100644 --- a/vscode/ruff/default.nix +++ b/vscode/ruff/default.nix @@ -39,6 +39,15 @@ buildNpmPackage rec { # `npm run package` == webpack --mode production -> dist/extension.js npmBuildScript = "package"; + # home-manager's vscode module reads these off each extension (unconditionally, + # via nixpkgs' vscode-utils `toExtensionJsonEntry`) to write extensions.json. + # nixpkgs' marketplace builder attaches them; a bare buildNpmPackage does not. + passthru = { + vscodeExtPublisher = "charliermarsh"; + vscodeExtName = "ruff"; + vscodeExtUniqueId = "charliermarsh.ruff"; + }; + installPhase = '' runHook preInstall