1{ 2 lib, 3 stdenv, 4 rustPlatform, 5 fetchFromGitHub, 6 fetchNpmDeps, 7 fetchurl, 8 binaryen, 9 gzip, 10 nodejs, 11 npmHooks, 12 python3, 13 rustc, 14 versionCheckHook, 15 wasm-bindgen-cli_0_2_92, 16 wasm-pack, 17}: 18 19# TODO: package python bindings 20 21let 22 23 # the lindera-unidic v0.32.2 crate uses [1] an outdated unidic-mecab fork [2] and builds it in pure rust 24 # [1] https://github.com/lindera/lindera/blob/v0.32.2/lindera-unidic/build.rs#L5-L11 25 # [2] https://github.com/lindera/unidic-mecab 26 # To find these urls: 27 # rg -A5 download_urls $(nix-build . -A pagefind.cargoDeps --no-out-link)/lindera-*/build.rs 28 lindera-srcs = { 29 unidic-mecab = fetchurl { 30 passthru.vendorDir = "lindera-unidic-*"; 31 url = "https://Lindera.dev/unidic-mecab-2.1.2.tar.gz"; 32 hash = "sha256-JKx1/k5E2XO1XmWEfDX6Suwtt6QaB7ScoSUUbbn8EYk="; 33 }; 34 mecab-ko-dic = fetchurl { 35 passthru.vendorDir = "lindera-ko-dic-*"; 36 url = "https://Lindera.dev/mecab-ko-dic-2.1.1-20180720.tar.gz"; 37 hash = "sha256-cCztIcYWfp2a68Z0q17lSvWNREOXXylA030FZ8AgWRo="; 38 }; 39 ipadic = fetchurl { 40 passthru.vendorDir = "lindera-ipadic-0.*"; 41 url = "https://Lindera.dev/mecab-ipadic-2.7.0-20070801.tar.gz"; 42 hash = "sha256-CZ5G6A1V58DWkGeDr/cTdI4a6Q9Gxe+W7BU7vwm/VVA="; 43 }; 44 cc-cedict = fetchurl { 45 passthru.vendorDir = "lindera-cc-cedict-*"; 46 url = "https://lindera.dev/CC-CEDICT-MeCab-0.1.0-20200409.tar.gz"; 47 hash = "sha256-7Tz54+yKgGR/DseD3Ana1DuMytLplPXqtv8TpB0JFsg="; 48 }; 49 ipadic-neologd = fetchurl { 50 passthru.vendorDir = "lindera-ipadic-neologd-*"; 51 url = "https://lindera.dev/mecab-ipadic-neologd-0.0.7-20200820.tar.gz"; 52 hash = "sha256-1VwCwgSTKFixeQUFVCdqMzZKne/+FTgM56xT7etqjqI="; 53 }; 54 }; 55 56in 57 58rustPlatform.buildRustPackage (finalAttrs: { 59 pname = "pagefind"; 60 version = "1.4.0"; 61 62 src = fetchFromGitHub { 63 owner = "Pagefind"; 64 repo = "pagefind"; 65 tag = "v${finalAttrs.version}"; 66 hash = "sha256-+jArZueDqpJQKg3fKdJjeQQL+egyR6Zi6wqPMZoFgyk="; 67 }; 68 69 cargoPatches = [ ./cargo-lock.patch ]; 70 cargoHash = "sha256-zbo8NkB9umpNDvkhKXpOdt8hJn+d+nrTXMaUghmIPrg="; 71 72 env.cargoDeps_web = rustPlatform.fetchCargoVendor { 73 name = "cargo-deps-web-${finalAttrs.version}"; 74 inherit (finalAttrs) src; 75 sourceRoot = "${finalAttrs.src.name}/pagefind_web"; 76 hash = "sha256-DaipINtwePA03YdbSzh6EjH4Q13P3CB9lwcmTOR54dM="; 77 }; 78 env.npmDeps_web_js = fetchNpmDeps { 79 name = "pagefind-npm-deps-web-js-${finalAttrs.version}"; 80 inherit (finalAttrs) src; 81 sourceRoot = "${finalAttrs.src.name}/pagefind_web_js"; 82 hash = "sha256-whpmjNKdiMxNfg7fRIWUPdyRWqsEphhqvQfiM65GYDs="; 83 }; 84 env.npmDeps_ui_default = fetchNpmDeps { 85 name = "pagefind-npm-deps-ui-default-${finalAttrs.version}"; 86 inherit (finalAttrs) src; 87 sourceRoot = "${finalAttrs.src.name}/pagefind_ui/default"; 88 hash = "sha256-voCs49JneWYE1W9U7aB6G13ypH6JqathVDeF58V57U8="; 89 }; 90 env.npmDeps_ui_modular = fetchNpmDeps { 91 name = "pagefind-npm-deps-ui-modular-${finalAttrs.version}"; 92 inherit (finalAttrs) src; 93 sourceRoot = "${finalAttrs.src.name}/pagefind_ui/modular"; 94 hash = "sha256-4d85V2X1doq3G8okgYSXOMuQDoAXCgtAtegFEPr+Wno="; 95 }; 96 env.npmDeps_playground = fetchNpmDeps { 97 name = "pagefind-npm-deps-playground-${finalAttrs.version}"; 98 inherit (finalAttrs) src; 99 sourceRoot = "${finalAttrs.src.name}/pagefind_playground"; 100 hash = "sha256-npo8MV6AAuQ/mGC9iu3bR7pjGoI7NgxuIeh+H3oz7Y8="; 101 }; 102 103 env.GIT_VERSION = finalAttrs.version; 104 105 postPatch = '' 106 # Set the correct version, e.g. for `pagefind --version` 107 node .backstage/version.cjs 108 109 # Tricky way to run the cargo setup a second time 110 ( 111 cd pagefind_web 112 cargoDeps=$cargoDeps_web cargoSetupPostUnpackHook 113 cargoDeps=$cargoDeps_web cargoSetupPostPatchHook 114 ) 115 116 # Tricky way to run npmConfigHook multiple times 117 ( 118 local postPatchHooks=() # written to by npmConfigHook 119 source ${npmHooks.npmConfigHook}/nix-support/setup-hook 120 npmRoot=pagefind_web_js npmDeps=$npmDeps_web_js npmConfigHook 121 npmRoot=pagefind_ui/default npmDeps=$npmDeps_ui_default npmConfigHook 122 npmRoot=pagefind_ui/modular npmDeps=$npmDeps_ui_modular npmConfigHook 123 npmRoot=pagefind_playground npmDeps=$npmDeps_playground npmConfigHook 124 ) 125 126 # patch build-time dependency downloads 127 ( 128 # add support for file:// urls 129 patch -d $cargoDepsCopy/lindera-dictionary-*/ -p1 < ${./lindera-dictionary-support-file-paths.patch} 130 131 # patch urls 132 ${lib.pipe finalAttrs.passthru.lindera-srcs [ 133 (lib.mapAttrsToList ( 134 key: src: '' 135 # compgen is only in bashInteractive 136 declare -a expanded_glob=($cargoDepsCopy/${src.vendorDir}/build.rs) 137 if [[ "''${#expanded_glob[@]}" -eq 0 ]]; then 138 echo >&2 "ERROR: '$cargoDepsCopy/${src.vendorDir}/build.rs' not found! (pagefind.passthru.lindera-srcs.${key})" 139 false 140 elif [[ "''${#expanded_glob[@]}" -gt 1 ]]; then 141 echo >&2 "ERROR: '$cargoDepsCopy/${src.vendorDir}/build.rs' matches more than one file! (pagefind.passthru.lindera-srcs.${key})" 142 printf >&2 "match: %s\n" "''${expanded_glob[@]}" 143 false 144 fi 145 echo "patching $cargoDepsCopy/${src.vendorDir}/build.rs..." 146 substituteInPlace $cargoDepsCopy/${src.vendorDir}/build.rs --replace-fail "${src.url}" "file://${src}" 147 unset expanded_glob 148 '' 149 )) 150 lib.concatLines 151 ]} 152 ) 153 154 # nightly-only feature 155 substituteInPlace pagefind_web/local_build.sh \ 156 --replace-fail ' -Z build-std=panic_abort,std' "" \ 157 --replace-fail ' -Z build-std-features=panic_immediate_abort' "" 158 ''; 159 160 __darwinAllowLocalNetworking = true; 161 162 nativeBuildInputs = [ 163 binaryen 164 gzip 165 nodejs 166 rustc 167 rustc.llvmPackages.lld 168 wasm-bindgen-cli_0_2_92 169 wasm-pack 170 ] 171 ++ lib.optionals stdenv.buildPlatform.isDarwin [ 172 python3 173 ]; 174 175 # build wasm and js assets 176 # based on "test-and-build" in https://github.com/CloudCannon/pagefind/blob/main/.github/workflows/release.yml 177 preBuild = '' 178 export HOME=$(mktemp -d) 179 180 echo Entering ./pagefind_web_js 181 ( 182 cd pagefind_web_js 183 npm run build-coupled 184 ) 185 186 echo Entering ./pagefind_web 187 ( 188 cd pagefind_web 189 bash ./local_build.sh 190 ) 191 192 echo Entering ./pagefind_ui/default 193 ( 194 cd pagefind_ui/default 195 npm run build 196 ) 197 198 echo Entering ./pagefind_ui/modular 199 ( 200 cd pagefind_ui/modular 201 npm run build 202 ) 203 204 echo Entering ./pagefind_playground 205 ( 206 cd pagefind_playground 207 npm run build 208 ) 209 ''; 210 211 # always build extended 212 buildFeatures = [ "extended" ]; 213 214 doInstallCheck = true; 215 216 nativeInstallCheckInputs = [ 217 versionCheckHook 218 ]; 219 220 passthru = { 221 inherit lindera-srcs; 222 tests.non-extended = finalAttrs.finalPackage.overrideAttrs { 223 buildFeatures = [ ]; 224 }; 225 }; 226 227 meta = { 228 description = "Generate low-bandwidth search index for your static website"; 229 homepage = "https://pagefind.app/"; 230 changelog = "https://github.com/Pagefind/pagefind/releases/tag/v${finalAttrs.version}"; 231 license = lib.licenses.mit; 232 maintainers = with lib.maintainers; [ pbsds ]; 233 platforms = lib.platforms.unix; 234 mainProgram = "pagefind"; 235 }; 236})