From 0a416a41f400a0b0d033038676d2ce4638c1b158 Mon Sep 17 00:00:00 2001 From: Ahmad Ansori Palembani Date: Thu, 1 May 2025 16:24:29 +0700 Subject: [PATCH] refactor(nix/brew): Code refactor Co-authored-by: isabel --- nix/overlays/darwin/brew.nix | 193 +++++++++++++++++++---------------- 1 file changed, 105 insertions(+), 88 deletions(-) diff --git a/nix/overlays/darwin/brew.nix b/nix/overlays/darwin/brew.nix index e8384c8..00a5a52 100644 --- a/nix/overlays/darwin/brew.nix +++ b/nix/overlays/darwin/brew.nix @@ -1,105 +1,122 @@ -# Modified version of brew-nix/casks.nix +# Modified version of brew-nix/casks.nix to support macOS version variations # -# REF: https://github.com/BatteredBunny/brew-nix/blob/9dfab294afea5029922bbc59a10ae487c7318d59/casks.nix -{ system, mac-version ? "ventura", nixpkgs, brew-api, ... }: +# REF: https://github.com/BatteredBunny/brew-nix/blob/928e5382d927727666bcbbd27240e73eeb269b4a/casks.nix +{ + system, + mac-version ? "ventura", + nixpkgs, + brew-api, + ... +}: let pkgs = import nixpkgs { inherit system; }; - - hasBinary = cask: pkgs.lib.hasAttr "binary" (getArtifacts cask); - hasApp = cask: pkgs.lib.hasAttr "app" (getArtifacts cask); - hasPkg = cask: pkgs.lib.hasAttr "pkg" (getArtifacts cask); + lib = pkgs.lib; getName = cask: builtins.elemAt cask.name 0; + getBinary = artifacts: builtins.elemAt artifacts.binary 0; + getApp = artifacts: builtins.elemAt artifacts.app 0; - getBinary = cask: builtins.elemAt (getArtifacts cask).binary 0; - getApp = cask: builtins.elemAt (getArtifacts cask).app 0; - getArtifacts = cask: pkgs.lib.mergeAttrsList cask.artifacts; + caskToDerivation = + cask: + let + artifacts = lib.mergeAttrsList cask.artifacts; + isBinary = lib.hasAttr "binary" artifacts; + isApp = lib.hasAttr "app" artifacts; + isPkg = lib.hasAttr "pkg" artifacts; + url = (cask.variations.${mac-version} or cask).url; + hash = (cask.variations.${mac-version} or cask).sha256; + in + pkgs.stdenv.mkDerivation rec { + pname = cask.token; + inherit (cask) version; - getUrl = cask: (cask.variations.${mac-version} or cask).url; - getHash = cask: (cask.variations.${mac-version} or cask).sha256; # TODO: convert it to SRI + src = pkgs.fetchurl { + inherit url; + sha256 = pkgs.lib.optionalString (hash != "no_check") hash; + }; - caskToDerivation = cask: pkgs.stdenv.mkDerivation rec { - pname = cask.token; - version = cask.version; + nativeBuildInputs = + with pkgs; + [ + undmg + unzip + gzip + _7zz + makeWrapper + ] + ++ pkgs.lib.optional isPkg ( + with pkgs; + [ + xar + cpio + ] + ); - src = pkgs.fetchurl { - url = (getUrl cask); - sha256 = pkgs.lib.optionalString ((getHash cask) != "no_check") (getHash cask); + unpackPhase = + if isPkg then '' + xar -xf $src + for pkg in $(cat Distribution | grep -oE "#.+\.pkg" | sed -e "s/^#//" -e "s/$/\/Payload/"); do + zcat $pkg | cpio -i + done + '' else if isApp then '' + undmg $src || 7zz x -snld $src + '' else if isBinary then '' + if [ "$(file --mime-type -b "$src")" == "application/gzip" ]; then + gunzip $src -c > ${getBinary artifacts} + elif [ "$(file --mime-type -b "$src")" == "application/x-mach-binary" ]; then + cp $src ${getBinary artifacts} + fi + '' else ""; + + sourceRoot = pkgs.lib.optionalString isApp (getApp artifacts); + + # Patching shebangs invalidates code signing + dontPatchShebangs = true; + + installPhase = + if isPkg then '' + mkdir -p $out/Applications + cp -R Applications/* $out/Applications/ + + if [ -d "Resources" ]; then + mkdir -p $out/Resources + cp -R Resources/* $out/Resources/ + fi + + if [ -d "Library" ]; then + mkdir -p $out/Library + cp -R Library/* $out/Library/ + fi + '' else if isApp then '' + mkdir -p "$out/Applications/${sourceRoot}" + cp -R . "$out/Applications/${sourceRoot}" + + if [[ -e "$out/Applications/${sourceRoot}/Contents/MacOS/${getName cask}" ]]; then + makeWrapper "$out/Applications/${sourceRoot}/Contents/MacOS/${getName cask}" $out/bin/${cask.token} + elif [[ -e "$out/Applications/${sourceRoot}/Contents/MacOS/${pkgs.lib.removeSuffix ".app" sourceRoot}" ]]; then + makeWrapper "$out/Applications/${sourceRoot}/Contents/MacOS/${pkgs.lib.removeSuffix ".app" sourceRoot}" $out/bin/${cask.token} + fi + '' else if (isBinary && !isApp) then '' + mkdir -p $out/bin + cp -R ./* $out/bin + '' else ""; + + meta = { + inherit (cask) homepage; + description = cask.desc; + platforms = pkgs.lib.platforms.darwin; + mainProgram = if (isBinary && !isApp) then (getBinary artifacts) else (cask.token); + }; }; - nativeBuildInputs = with pkgs; [ - undmg - unzip - gzip - _7zz - makeWrapper - ] ++ pkgs.lib.optional (hasPkg cask) (with pkgs; [ - xar - cpio - ]); - - unpackPhase = - if (hasPkg cask) then '' - xar -xf $src - for pkg in $(cat Distribution | grep -oE "#.+\.pkg" | sed -e "s/^#//" -e "s/$/\/Payload/"); do - zcat $pkg | cpio -i - done - '' else if (hasApp cask) then '' - undmg $src || 7zz x -snld $src - '' else if (hasBinary cask) then '' - if [ "$(file --mime-type -b "$src")" == "application/gzip" ]; then - gunzip $src -c > ${getBinary cask} - elif [ "$(file --mime-type -b "$src")" == "application/x-mach-binary" ]; then - cp $src ${getBinary cask} - fi - '' else ""; - - sourceRoot = pkgs.lib.optionalString (hasApp cask) (getApp cask); - - installPhase = - if (hasPkg cask) then '' - mkdir -p $out/Applications - cp -R Applications/* $out/Applications/ - - if [ -d "Resources" ]; then - mkdir -p $out/Resources - cp -R Resources/* $out/Resources/ - fi - - if [ -d "Library" ]; then - mkdir -p $out/Library - cp -R Library/* $out/Library/ - fi - '' else if (hasApp cask) then '' - mkdir -p "$out/Applications/${sourceRoot}" - cp -R . "$out/Applications/${sourceRoot}" - - if [[ -e "$out/Applications/${sourceRoot}/Contents/MacOS/${getName cask}" ]]; then - makeWrapper "$out/Applications/${sourceRoot}/Contents/MacOS/${getName cask}" $out/bin/${cask.token} - elif [[ -e "$out/Applications/${sourceRoot}/Contents/MacOS/${pkgs.lib.removeSuffix ".app" sourceRoot}" ]]; then - makeWrapper "$out/Applications/${sourceRoot}/Contents/MacOS/${pkgs.lib.removeSuffix ".app" sourceRoot}" $out/bin/${cask.token} - fi - '' else if (hasBinary cask && !hasApp cask) then '' - mkdir -p $out/bin - cp -R ./* $out/bin - '' else ""; - - meta = { - homepage = cask.homepage; - description = cask.desc; - platforms = pkgs.lib.platforms.darwin; - mainProgram = if (hasBinary cask && !hasApp cask) then (getBinary cask) else (cask.token); - }; - }; - - casks = builtins.fromJSON (builtins.readFile (brew-api + "/cask.json")); + casks = lib.importJSON (brew-api + "/cask.json"); in final: prev: { - casks = builtins.listToAttrs (builtins.map - (cask: { + casks = lib.listToAttrs ( + builtins.map (cask: { name = cask.token; value = caskToDerivation cask; - }) - casks); + }) casks + ); }