mdfried 0.18.3

A markdown viewer for the terminal that renders images and big headers
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
    crane.url = "github:ipetkov/crane";
    flake-utils.url = "github:numtide/flake-utils";
    rust-overlay = {
      url = "github:oxalica/rust-overlay";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs =
    {
      self,
      nixpkgs,
      crane,
      flake-utils,
      rust-overlay,
      ...
    }:
    flake-utils.lib.eachDefaultSystem (
      system:
      let
        pkgs = import nixpkgs {
          inherit system;
          overlays = [ (import rust-overlay) ];
        };
        inherit (pkgs) lib;

        craneLib = (crane.mkLib pkgs).overrideToolchain (p: p.rust-bin.stable.latest.default);

        unfilteredRoot = ./.;
        src = lib.fileset.toSource {
          root = unfilteredRoot;
          fileset = lib.fileset.unions [
            (craneLib.fileset.commonCargoSources unfilteredRoot)
            (lib.fileset.maybeMissing ./assets)
            (lib.fileset.maybeMissing ./src/snapshots)
            (lib.fileset.maybeMissing ./src/worker/snapshots)
          ];
        };

        # Common args for default builds using chafa-dyn (dynamic linking)
        commonArgs = {
          inherit src;
          strictDeps = true;

          nativeBuildInputs = with pkgs; [
            makeWrapper
            pkg-config
          ];

          buildInputs = [
            pkgs.chafa
            pkgs.glib.dev # for glib-2.0.pc (chafa dependency)
          ]
          ++ lib.optionals pkgs.stdenv.isDarwin [
            pkgs.libiconv
          ];
        };

        cargoArtifacts = craneLib.buildDepsOnly commonArgs;

        mdfried = craneLib.buildPackage (
          commonArgs
          // {
            inherit cargoArtifacts;
          }
        );

        # Fully static musl build for portable Linux binaries
        mdfriedStatic =
          let
            craneLibMusl = (crane.mkLib pkgs).overrideToolchain (
              p:
              p.rust-bin.stable.latest.default.override {
                targets = [ "x86_64-unknown-linux-musl" ];
              }
            );
            muslPkgs = pkgs.pkgsCross.musl64.pkgsStatic;
            chafaMuslStatic =
              (muslPkgs.chafa.override {
                libavif = null;
                libjxl = null;
                librsvg = null;
              }).overrideAttrs
                (old: {
                  configureFlags = (old.configureFlags or [ ]) ++ [
                    "--enable-static"
                    "--disable-shared"
                    "--without-avif"
                    "--without-jxl"
                    "--without-svg"
                    "--without-tools"
                  ];
                });
            glibMuslStatic = muslPkgs.glib;
            staticArgs = {
              inherit src;
              strictDeps = true;
              doCheck = false;
              cargoExtraArgs = "--no-default-features --features chafa-static";
              CARGO_BUILD_TARGET = "x86_64-unknown-linux-musl";
              CARGO_BUILD_RUSTFLAGS = "-C target-feature=+crt-static -C link-arg=-lgcc";
              CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER = "${pkgs.pkgsCross.musl64.stdenv.cc}/bin/x86_64-unknown-linux-musl-cc";
              nativeBuildInputs = with pkgs; [
                pkgsCross.musl64.stdenv.cc
                pkg-config
                llvmPackages.libclang
              ];
              buildInputs = [
                chafaMuslStatic
                glibMuslStatic
                muslPkgs.pcre2
                muslPkgs.libffi
                muslPkgs.zlib
              ];
              PKG_CONFIG_PATH = lib.makeSearchPath "lib/pkgconfig" [
                chafaMuslStatic
                glibMuslStatic
                muslPkgs.pcre2
                muslPkgs.libffi
                muslPkgs.zlib
              ];
              LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
              BINDGEN_EXTRA_CLANG_ARGS = "-isystem ${pkgs.pkgsCross.musl64.musl.dev}/include";
              # Disable fortify source to avoid __snprintf_chk (glibc-specific) in tree-sitter
              CC_x86_64_unknown_linux_musl = "${pkgs.pkgsCross.musl64.stdenv.cc}/bin/x86_64-unknown-linux-musl-cc";
              CFLAGS_x86_64_unknown_linux_musl = "-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0";
            };
            cargoArtifactsStatic = craneLibMusl.buildDepsOnly staticArgs;
          in
          craneLibMusl.buildPackage (
            staticArgs
            // {
              cargoArtifacts = cargoArtifactsStatic;
            }
          );

        # Windows cross-compilation (only on Linux)
        mdfriedWindows =
          let
            pkgsWindows = import nixpkgs {
              overlays = [ (import rust-overlay) ];
              localSystem = system;
              crossSystem = {
                config = "x86_64-w64-mingw32";
              };
            };
            craneLibWindows = (crane.mkLib pkgsWindows).overrideToolchain (
              p:
              p.rust-bin.stable.latest.default.override {
                targets = [ "x86_64-pc-windows-gnu" ];
              }
            );
          in
          craneLibWindows.buildPackage {
            inherit src;
            strictDeps = true;
            doCheck = false;
            cargoExtraArgs = "--no-default-features";

            nativeBuildInputs = with pkgs; [
              makeWrapper
            ];
          };

        # LLVM coverage toolchain
        craneLibLLvmTools = (crane.mkLib pkgs).overrideToolchain (
          p:
          p.rust-bin.stable.latest.default.override {
            extensions = [ "llvm-tools" ];
          }
        );

        # Screenshot tests (only on Linux)
        screenshotTests = if pkgs.stdenv.isLinux then
          import ./screenshot-tests.nix {
            inherit pkgs src;
            mdfriedStatic = mdfriedStatic;
          }
        else {};
      in
      {
        checks = {
          inherit mdfried;

          mdfried-clippy = craneLib.cargoClippy (
            commonArgs
            // {
              inherit cargoArtifacts;
              cargoClippyExtraArgs = "--all-targets -- --deny warnings";
            }
          );

          mdfried-doc = craneLib.cargoDoc (
            commonArgs
            // {
              inherit cargoArtifacts;
            }
          );

          mdfried-fmt = craneLib.cargoFmt {
            inherit src;
          };

          mdfried-nextest = craneLib.cargoNextest (
            commonArgs
            // {
              inherit cargoArtifacts;
              partitions = 1;
              partitionType = "count";
            }
          );
        };

        packages = {
          default = mdfried;
        }
        // lib.optionalAttrs pkgs.stdenv.isLinux {
          static = mdfriedStatic;
          windows = mdfriedWindows;
          mdfried-llvm-coverage = craneLibLLvmTools.cargoLlvmCov (
            commonArgs
            // {
              inherit cargoArtifacts;
            }
          );
        }
        // screenshotTests;

        apps.default = flake-utils.lib.mkApp {
          drv = mdfried;
        };

        devShells.default = craneLib.devShell {
          checks = self.checks.${system};

          packages =
            let
              screenshotDiffsScript = pkgs.writeShellScriptBin "screenshotDiffs" ''
                set -e

                echo "Building current screenshots sequentially..."
                for terminal in foot kitty wezterm alacritty; do
                  echo "  Building screenshot-test-$terminal..."
                  nix build ".#screenshot-test-$terminal" --print-build-logs
                done

                echo "Building master screenshots..."
                REFERENCE=$(nix build "git+file://$PWD?ref=master#screenshots" --print-out-paths --impure)

                echo "Building diffs..."
                REFERENCE=$REFERENCE nix build .#screenshotDiffs --impure --print-build-logs

                URL="file://$(readlink -f result)/index.html"
                echo ""
                printf '\e]8;;%s\e\\%s\e]8;;\e\\\n' "$URL" "Click here to open in browser"
              '';
            in
            with pkgs;
            [
              nixfmt
              cargo-release
              cargo-flamegraph
              chafa
              glib.dev # for glib-2.0.pc (chafa dependency)
              cargo-insta
              screenshotDiffsScript
            ]
            ++ lib.optionals pkgs.stdenv.isLinux [
              perf
            ];
          LD_LIBRARY_PATH = lib.makeLibraryPath [ pkgs.chafa ];
        };
      }
    );
}