diff options
Diffstat (limited to 'nix')
| -rw-r--r-- | nix/bun-deps.nix | 49 | ||||
| -rw-r--r-- | nix/desktop.nix | 86 | ||||
| -rw-r--r-- | nix/web.nix | 64 |
3 files changed, 199 insertions, 0 deletions
diff --git a/nix/bun-deps.nix b/nix/bun-deps.nix new file mode 100644 index 00000000..646a91d7 --- /dev/null +++ b/nix/bun-deps.nix @@ -0,0 +1,49 @@ +# Fixed-output derivation: workspace node_modules from bun.lock. +# Only re-runs when the lockfile or manifests change; the hash covers the +# installed dependency tree, so it must be updated whenever bun.lock changes +# (set outputHash = lib.fakeHash, build once, paste the reported hash). +{ + lib, + runCommand, + bun, + cacert, +}: + +let + minimalSrc = runCommand "opencut-bun-src" { } '' + mkdir -p $out/apps/web $out/apps/desktop + cp ${../package.json} $out/package.json + cp ${../bun.lock} $out/bun.lock + cp ${../bunfig.toml} $out/bunfig.toml + cp ${../.npmrc} $out/.npmrc + cp ${../apps/web/package.json} $out/apps/web/package.json + cp ${../apps/desktop/package.json} $out/apps/desktop/package.json + ''; +in +runCommand "opencut-bun-deps" + { + nativeBuildInputs = [ + bun + cacert + ]; + outputHashMode = "recursive"; + outputHashAlgo = "sha256"; + outputHash = "sha256-+zRGGTHFoM9d4wjP999J3JdcRgNksTTVOb+nceyvNak="; + } + '' + cp -r ${minimalSrc} src + chmod -R u+w src + cd src + + export HOME=$TMPDIR + export BUN_INSTALL_CACHE_DIR=$TMPDIR/bun-cache + # The electron binary is unused; nixpkgs electron is used at runtime. + export ELECTRON_SKIP_BINARY_DOWNLOAD=1 + + bun install --frozen-lockfile + + mkdir -p $out/apps/web $out/apps/desktop + cp -r node_modules $out/node_modules + cp -r apps/web/node_modules $out/apps/web/node_modules + cp -r apps/desktop/node_modules $out/apps/desktop/node_modules + '' diff --git a/nix/desktop.nix b/nix/desktop.nix new file mode 100644 index 00000000..de2c8660 --- /dev/null +++ b/nix/desktop.nix @@ -0,0 +1,86 @@ +# Electron desktop app: tsc-compiled main process + the static web export, +# wrapped with nixpkgs electron (no electron-builder, no asar). +# ffmpeg-static is satisfied by nixpkgs ffmpeg. +{ + lib, + stdenvNoCC, + bun, + nodejs, + callPackage, + electron, + ffmpeg, + makeWrapper, + sources ? import ../npins, +}: + +let + bunDeps = callPackage ./bun-deps.nix { }; + web = callPackage ./web.nix { inherit sources; }; + desktopPkg = builtins.fromJSON (builtins.readFile ../apps/desktop/package.json); +in +stdenvNoCC.mkDerivation { + pname = "opencut-desktop"; + version = desktopPkg.version; + src = lib.cleanSource ../.; + + nativeBuildInputs = [ + bun + nodejs + makeWrapper + ]; + + configurePhase = '' + runHook preConfigure + cp -r ${bunDeps}/node_modules node_modules + cp -r ${bunDeps}/apps/desktop/node_modules apps/desktop/node_modules + chmod -R u+w node_modules apps/desktop/node_modules + patchShebangs node_modules apps/desktop/node_modules + runHook postConfigure + ''; + + buildPhase = '' + runHook preBuild + export HOME=$TMPDIR + cd apps/desktop + bun run build + cd $NIX_BUILD_TOP/source + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + appdir=$out/share/opencut + mkdir -p $appdir/node_modules/ffmpeg-static + cp apps/desktop/package.json $appdir/package.json + cp -r apps/desktop/dist $appdir/dist + cp -r ${web} $appdir/web + + # main.js resolves ffmpeg via require("ffmpeg-static"); point it at nixpkgs ffmpeg. + cp apps/desktop/node_modules/ffmpeg-static/index.js $appdir/node_modules/ffmpeg-static/index.js + cp apps/desktop/node_modules/ffmpeg-static/package.json $appdir/node_modules/ffmpeg-static/package.json + ln -s ${lib.getExe ffmpeg} $appdir/node_modules/ffmpeg-static/ffmpeg + + makeWrapper ${lib.getExe electron} $out/bin/opencut \ + --add-flags "$appdir" + + mkdir -p $out/share/applications + cat > $out/share/applications/opencut.desktop <<EOF + [Desktop Entry] + Type=Application + Name=OpenCut + Comment=Offline-first video editor + Exec=opencut + Categories=AudioVideo;Video; + EOF + + runHook postInstall + ''; + + meta = { + description = "OpenCut desktop (Electron)"; + license = lib.licenses.mit; + mainProgram = "opencut"; + platforms = lib.platforms.linux; + }; +} diff --git a/nix/web.nix b/nix/web.nix new file mode 100644 index 00000000..eb464a2a --- /dev/null +++ b/nix/web.nix @@ -0,0 +1,64 @@ +# Static export of the Next.js web app (apps/web/out). +# Deps come from the bun-deps FOD; the Google-font fetch in next/font is +# replaced by the npins-pinned Inter so the build runs offline. +{ + lib, + stdenvNoCC, + bun, + nodejs, + callPackage, + sources ? import ../npins, +}: + +let + bunDeps = callPackage ./bun-deps.nix { }; + webPkg = builtins.fromJSON (builtins.readFile ../apps/web/package.json); +in +stdenvNoCC.mkDerivation { + pname = "opencut-web"; + version = webPkg.version; + src = lib.cleanSource ../.; + + nativeBuildInputs = [ + bun + nodejs + ]; + + postPatch = '' + mkdir -p apps/web/public/fonts + cp ${sources.inter}/web/InterVariable.woff2 apps/web/public/fonts/InterVariable.woff2 + substituteInPlace apps/web/src/app/layout.tsx \ + --replace-fail 'import { Inter } from "next/font/google";' 'import localFont from "next/font/local";' \ + --replace-fail 'const siteFont = Inter({ subsets: ["latin"] });' 'const siteFont = localFont({ src: "../../public/fonts/InterVariable.woff2" });' + ''; + + configurePhase = '' + runHook preConfigure + cp -r ${bunDeps}/node_modules node_modules + cp -r ${bunDeps}/apps/web/node_modules apps/web/node_modules + chmod -R u+w node_modules apps/web/node_modules + patchShebangs node_modules apps/web/node_modules + runHook postConfigure + ''; + + buildPhase = '' + runHook preBuild + export HOME=$TMPDIR + export NEXT_TELEMETRY_DISABLED=1 + export NODE_ENV=production + cd apps/web + bun run build + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + cp -r out $out + runHook postInstall + ''; + + meta = { + description = "OpenCut web app (static export)"; + license = lib.licenses.mit; + }; +} |
