Guest User

Untitled

a guest
Apr 28th, 2026
52
0
Never
5
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.20 KB | None | 0 0
  1. Да, можно — через **fixed-output derivation (FOD)**, в которой разрешена сеть. Идея: одна FOD генерирует `package-lock.json` (с сетью, фиксированный хэш), вторая (обычный `buildNpmPackage`) использует результат первой.
  2.  
  3. ```nix
  4. { buildNpmPackage, fetchurl, lib, stdenvNoCC, nodejs, cacert }:
  5.  
  6. let
  7. pname = "vot-cli";
  8. version = "1.4.3";
  9.  
  10. src = fetchurl {
  11. url = "https://registry.npmjs.org/${pname}/-/${pname}-${version}.tgz";
  12. hash = "sha256-eOUfy6l48MD9IcWiFlC142vXvo5XobKTJ2uC6xzDGS4=";
  13. };
  14.  
  15. # FOD: имеет доступ в сеть, выход фиксируется по хэшу
  16. packageLock = stdenvNoCC.mkDerivation {
  17. name = "${pname}-${version}-package-lock.json";
  18. inherit src;
  19.  
  20. nativeBuildInputs = [ nodejs cacert ];
  21.  
  22. buildPhase = ''
  23. export HOME=$TMPDIR
  24. npm install --package-lock-only --ignore-scripts --no-audit --no-fund
  25. '';
  26.  
  27. installPhase = ''
  28. cp package-lock.json $out
  29. '';
  30.  
  31. outputHashMode = "flat";
  32. outputHashAlgo = "sha256";
  33. outputHash = lib.fakeHash; # заменишь после первого билда
  34. };
  35. in
  36. buildNpmPackage {
  37. inherit pname version src;
  38.  
  39. postPatch = ''
  40. cp ${packageLock} package-lock.json
  41. '';
  42.  
  43. npmDepsHash = lib.fakeHash; # заменишь после второго билда
  44.  
  45. dontNpmBuild = true;
  46.  
  47. meta = with lib; {
  48. description = "Voice Over Translation CLI tool";
  49. homepage = "https://github.com/ilyhalight/voice-over-translation";
  50. license = licenses.mit;
  51. platforms = platforms.all;
  52. mainProgram = "vot-cli";
  53. };
  54. }
  55. ```
  56.  
  57. ## Как заполнить хэши
  58.  
  59. Запускаешь `nix-build` — он упадёт два раза подряд с понятными сообщениями вида:
  60.  
  61. ```
  62. hash mismatch in fixed-output derivation '/nix/store/...-vot-cli-1.4.3-package-lock.json':
  63. specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
  64. got: sha256-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
  65. ```
  66.  
  67. Подставляешь полученный `got:` в соответствующее поле, перезапускаешь. Всего две итерации:
  68.  
  69. 1. первый `nix-build` → получаешь хэш для `packageLock.outputHash`
  70. 2. второй `nix-build` → получаешь хэш для `npmDepsHash`
  71. 3. третий `nix-build` → собирается
  72.  
  73. ## Подводные камни
  74.  
  75. **Нечистота резолвинга.** `npm install --package-lock-only` резолвит semver-диапазоны (`^1.2.3`) в конкретные версии **на момент запуска**. Если завтра в реестр зальют `1.2.4`, лок-файл получится другим, хэш FOD не совпадёт, билд сломается. На практике это означает: периодически (раз в несколько месяцев или при апдейте `vot-cli`) хэш нужно будет обновить. Воспроизводимость в пределах одной «эпохи» сохраняется — Nix закэширует результат FOD и не будет ходить в сеть, пока хэш совпадает.
  76.  
  77. **Можно прибить semver лагом времени:**
  78.  
  79. ```nix
  80. buildPhase = ''
  81. export HOME=$TMPDIR
  82. npm config set before "2025-01-01"
  83. npm install --package-lock-only --ignore-scripts --no-audit --no-fund
  84. '';
  85. ```
  86.  
  87. `npm config set before` заставляет резолвер игнорировать версии, опубликованные после указанной даты. Это сильно повышает шансы что лок-файл будет одинаковый месяцами.
  88.  
  89. **Альтернатива — IFD.** Можно прочитать сгенерированный лок-файл прямо в evaluation через `builtins.readFile`, но это даёт мало пользы и Nix flakes по умолчанию запрещают IFD. Двухступенчатый FOD проще и работает везде.
Advertisement
Comments
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
Add Comment
Please, Sign In to add comment