From 0432f5e6f3f446ee1cdd38eee728f8681be98068 Mon Sep 17 00:00:00 2001 From: Philip Munksgaard Date: Tue, 2 Jun 2026 09:33:36 +0200 Subject: [PATCH] graphite-cli: 1.7.20 -> 1.8.6 Since 1.8, graphite has started relying on binary packages prebuilt per host platform, kind of like obsidian. Therefore, to support newer versions of graphite, I've altered the package definition to download those binary packages directly (one for each platform). On Linux we need a FHS environment wrapper, which makes the code a bit more complex. I've taken the liberty of also adding a version check to the package. --- .../by-name/gr/graphite-cli/package-lock.json | 36 ----- pkgs/by-name/gr/graphite-cli/package.nix | 135 ++++++++++++++---- pkgs/by-name/gr/graphite-cli/update.sh | 30 ++-- 3 files changed, 122 insertions(+), 79 deletions(-) delete mode 100644 pkgs/by-name/gr/graphite-cli/package-lock.json diff --git a/pkgs/by-name/gr/graphite-cli/package-lock.json b/pkgs/by-name/gr/graphite-cli/package-lock.json deleted file mode 100644 index 35da6f75584d..000000000000 --- a/pkgs/by-name/gr/graphite-cli/package-lock.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "@withgraphite/graphite-cli", - "version": "1.7.20", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@withgraphite/graphite-cli", - "version": "1.7.20", - "hasInstallScript": true, - "license": "None", - "dependencies": { - "semver": "^7.5.4" - }, - "bin": { - "graphite": "graphite.js", - "gt": "graphite.js" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - } - } -} diff --git a/pkgs/by-name/gr/graphite-cli/package.nix b/pkgs/by-name/gr/graphite-cli/package.nix index d8e487c11a11..c9fe9e7f899d 100644 --- a/pkgs/by-name/gr/graphite-cli/package.nix +++ b/pkgs/by-name/gr/graphite-cli/package.nix @@ -1,42 +1,26 @@ { lib, stdenv, - buildNpmPackage, fetchurl, + buildFHSEnv, git, installShellFiles, + testers, + graphite-cli, }: -buildNpmPackage rec { - pname = "graphite-cli"; - version = "1.7.20"; - - src = fetchurl { - url = "https://registry.npmjs.org/@withgraphite/graphite-cli/-/graphite-cli-${version}.tgz"; - hash = "sha256-Xzq6+fsWRPoiPxtk1zNARCkIPBu64ipAKqPVU2dnV9E="; +let + selectSystem = + attrs: + attrs.${stdenv.hostPlatform.system} or (throw "Unsupported system: ${stdenv.hostPlatform.system}"); + suffix = selectSystem { + x86_64-linux = "linux-x64"; + aarch64-linux = "linux-arm64"; + x86_64-darwin = "darwin-x64"; + aarch64-darwin = "darwin-arm64"; }; - npmDepsHash = "sha256-6JzVDgrV5kUKES7/z+0aU+Rs6VabdKhcfru38j3Jmcw="; - - postPatch = '' - ln -s ${./package-lock.json} package-lock.json - ''; - - nativeBuildInputs = [ - git - installShellFiles - ]; - - dontNpmBuild = true; - - postInstall = lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) '' - installShellCompletion --cmd gt \ - --bash <($out/bin/gt completion) \ - --fish <(GT_PAGER= $out/bin/gt fish) \ - --zsh <(ZSH_NAME=zsh $out/bin/gt completion) - ''; - - passthru.updateScript = ./update.sh; + version = "1.8.6"; meta = { changelog = "https://graphite.dev/docs/cli-changelog"; @@ -46,5 +30,96 @@ buildNpmPackage rec { license = lib.licenses.unfree; # no license specified mainProgram = "gt"; maintainers = with lib.maintainers; [ joshheinrichs-shopify ]; + platforms = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + sourceProvenance = [ lib.sourceTypes.binaryNativeCode ]; }; -} + + passthru = { + updateScript = ./update.sh; + tests.version = testers.testVersion { + package = graphite-cli; + command = "gt --version"; + }; + }; + + shellCompletions = '' + installShellCompletion --cmd gt \ + --bash <($out/bin/gt completion) \ + --zsh <(ZSH_NAME=zsh $out/bin/gt completion) \ + --fish <($out/bin/gt fish) + ''; + + unwrapped = stdenv.mkDerivation { + pname = "graphite-cli-unwrapped"; + inherit version meta passthru; + strictDeps = true; + + src = fetchurl { + url = "https://registry.npmjs.org/@withgraphite/graphite-cli-${suffix}/-/graphite-cli-${suffix}-${version}.tgz"; + hash = selectSystem { + x86_64-linux = "sha256-YnG3iw35ZEyGbB9vGdcnj0qkvUfyLuaIEB5l09hkRck="; + aarch64-linux = "sha256-Z4yY26hXf8++TX5tJcqufsAULTn9oUL90d9tDZj5d/k="; + x86_64-darwin = "sha256-oV0tanuk2dzB62uChni9CJtSw3eFECQi3aMBc+ZV7Do="; + aarch64-darwin = "sha256-6eogi8fMOD5IgRyEdPRxdDa17WytB1JwTpKRzyyhQ2Q="; + }; + }; + + nativeBuildInputs = lib.optionals stdenv.hostPlatform.isDarwin [ + git + installShellFiles + ]; + + dontConfigure = true; + dontBuild = true; + # On Linux the binary is wrapped with buildFHSEnv; completions are + # generated there. Here we only need to skip fixup to avoid patchelf/strip. + dontFixup = stdenv.hostPlatform.isLinux; + + installPhase = '' + runHook preInstall + install -Dm755 bin/gt $out/bin/gt + runHook postInstall + ''; + + postInstall = lib.optionalString stdenv.hostPlatform.isDarwin shellCompletions; + }; +in +# The binary is built with vercel/pkg, which appends a virtual filesystem to +# the executable at fixed byte offsets. patchelf and strip shift those offsets, +# corrupting the embedded data, so the binary must remain completely unmodified. +# On Linux we use buildFHSEnv to provide /lib64/ld-linux-*.so.* and shared +# libraries without touching the binary. On Darwin this isn't needed. +if stdenv.hostPlatform.isLinux then + (buildFHSEnv { + pname = "graphite-cli"; + inherit version passthru; + + targetPkgs = pkgs: [ + unwrapped + pkgs.stdenv.cc.cc.lib + git + ]; + + runScript = "gt"; + + extraInstallCommands = '' + ln -s $out/bin/graphite-cli $out/bin/gt + source ${installShellFiles}/nix-support/setup-hook + ${shellCompletions} + ''; + + meta = meta // { + platforms = [ + "x86_64-linux" + "aarch64-linux" + ]; + }; + }).overrideAttrs + { strictDeps = true; } +else + unwrapped diff --git a/pkgs/by-name/gr/graphite-cli/update.sh b/pkgs/by-name/gr/graphite-cli/update.sh index 2f89e6fcd18b..e60ea11060b1 100755 --- a/pkgs/by-name/gr/graphite-cli/update.sh +++ b/pkgs/by-name/gr/graphite-cli/update.sh @@ -1,12 +1,10 @@ #! /usr/bin/env nix-shell -#! nix-shell -i bash -p gnused nix nodejs prefetch-npm-deps wget +#! nix-shell -i bash -p gnused nix nodejs set -euo pipefail pushd "$(dirname "${BASH_SOURCE[0]}")" version=$(npm view @withgraphite/graphite-cli version) -tarball="graphite-cli-$version.tgz" -url="https://registry.npmjs.org/@withgraphite/graphite-cli/-/$tarball" if [[ "$UPDATE_NIX_OLD_VERSION" == "$version" ]]; then echo "Already up to date!" @@ -15,16 +13,22 @@ fi sed -i 's#version = "[^"]*"#version = "'"$version"'"#' package.nix -sha256=$(nix-prefetch-url "$url") -src_hash=$(nix-hash --to-sri --type sha256 "$sha256") -sed -i 's#hash = "[^"]*"#hash = "'"$src_hash"'"#' package.nix +tmpdir=$(mktemp -d) +trap 'rm -rf "$tmpdir"' EXIT -rm -f package-lock.json package.json *.tgz -wget "$url" -tar xf "$tarball" --strip-components=1 package/package.json -npm i --package-lock-only --ignore-scripts -npm_hash=$(prefetch-npm-deps package-lock.json) -sed -i 's#npmDepsHash = "[^"]*"#npmDepsHash = "'"$npm_hash"'"#' package.nix -rm -f package.json *.tgz +for platform in linux-x64 linux-arm64 darwin-x64 darwin-arm64; do + ( + url="https://registry.npmjs.org/@withgraphite/graphite-cli-${platform}/-/graphite-cli-${platform}-${version}.tgz" + sha256=$(nix-prefetch-url "$url") + nix-hash --to-sri --type sha256 "$sha256" > "$tmpdir/$platform" + ) & +done +wait + +for platform in linux-x64 linux-arm64 darwin-x64 darwin-arm64; do + hash=$(cat "$tmpdir/$platform") + # Each platform hash appears only once in the file + sed -i "/${platform}/s#\"sha256-[^\"]*\"#\"${hash}\"#" package.nix +done popd