{ stdenv, lib, symlinkJoin }: let homepage = "https://colorfulstage.com/media/download/"; mkCursor = { name, src }: stdenv.mkDerivation rec { inherit name src; version = "1.0.0"; installPhase = '' runHook preInstall install -dm 0755 $out/share/icons/${name} cp -rf . $out/share/icons/${name} runHook postInstall ''; meta = { description = "Project Sekai cursor theme - ${name}"; inherit homepage; }; }; groups = { leoneed = [ "honami" "ichika" "miku" "saki" "shiho" ]; mmj = [ "airi" "haruka" "miku" "minori" "shizuku" ]; n25 = [ "ena" "kanade" "mafuyu" "miku" "mizuki" ]; vbs = [ "akito" "an" "kohane" "miku" "toya" ]; virtualsinger = [ "kaito" "len" "luka" "meiko" "miku" "rin" ]; wxs = [ "emu" "miku" "nene" "rui" "tsukasa" ]; }; # Individual cursors organized hierarchically pjsk-cursor-tree = lib.recurseIntoAttrs (lib.genAttrs [ "ani" "cur" ] (variant: lib.recurseIntoAttrs (lib.mapAttrs (group: characters: lib.recurseIntoAttrs (lib.genAttrs characters (character: mkCursor { name = "pjsk-cursor-${variant}-${group}-${character}"; src = ../../assets/${group}-${character}-${variant}.tar.gz; } )) ) groups) )); # Helper to collect all derivations under a tree for symlinkJoin collectDerivations = v: if lib.isDerivation v then [ v ] else lib.concatLists (map collectDerivations (lib.attrValues (builtins.removeAttrs v [ "recurseForDerivations" ]))); # Joined cursors organized hierarchically pjsk-cursors-tree = let allJoined = symlinkJoin { name = "pjsk-cursors"; paths = collectDerivations pjsk-cursor-tree; meta = { description = "Project Sekai cursor theme - All cursors"; inherit homepage; }; }; variants = lib.genAttrs [ "ani" "cur" ] (variant: let vPaths = collectDerivations pjsk-cursor-tree.${variant}; vJoined = symlinkJoin { name = "pjsk-cursors-${variant}"; paths = vPaths; meta = { description = "Project Sekai cursor theme - All ${variant} cursors"; inherit homepage; }; }; vGroups = lib.mapAttrs (group: _: symlinkJoin { name = "pjsk-cursors-${variant}-${group}"; paths = collectDerivations pjsk-cursor-tree.${variant}.${group}; meta = { description = "Project Sekai cursor theme - ${group} group ${variant} cursors"; inherit homepage; }; } ) groups; in vJoined // lib.recurseIntoAttrs vGroups ); in allJoined // lib.recurseIntoAttrs variants; # Flatten everything for CI visibility in 'packages' flattenTree = prefix: tree: let recurse = p: t: if lib.isDerivation t then { "${p}" = t; } else if builtins.isAttrs t then lib.concatMapAttrs (n: v: if n == "recurseForDerivations" then { } else recurse (if p == "" then n else "${p}-${n}") v) t else { }; in recurse prefix tree; in { # Hierarchical access pjsk-cursor = pjsk-cursor-tree; pjsk-cursors = pjsk-cursors-tree; # Flat access for CI flat = (flattenTree "pjsk-cursor" pjsk-cursor-tree) // (flattenTree "pjsk-cursors" pjsk-cursors-tree); }