lynceus 0.4.3

lynceus is a file watcher that reports file changes using a webhook.
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    utils.url = "github:numtide/flake-utils";
    treefmt-nix.url = "github:numtide/treefmt-nix";
    treefmt-nix.inputs.nixpkgs.follows = "nixpkgs";
    crane.url = "github:ipetkov/crane";
  };

  outputs =
    {
      self,
      nixpkgs,
      utils,
      treefmt-nix,
      crane,
      ...
    }:
    utils.lib.eachDefaultSystem (
      system:
      let
        pkgs = import nixpkgs { inherit system; };
        cargoToml = fromTOML (builtins.readFile ./Cargo.toml);
        craneLib = crane.mkLib pkgs;
        treefmtStack = treefmt-nix.lib.evalModule pkgs {
          projectRootFile = "flake.nix";
          programs.rustfmt = {
            enable = true;
            edition = "2024";
          };
          # Nix formatters
          programs.nixfmt.enable = true;
          programs.statix.enable = true;
          programs.deadnix.enable = true;
          settings.formatter = {
            deadnix.priority = 1;
            statix.priority = 2;
            nixfmt.priority = 3;
          };
        };

        src = craneLib.cleanCargoSource (craneLib.path ./.);

        commonArgs = {
          inherit src;
          strictDeps = true;
          SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
        };

        # Build only dependencies to cache them
        cargoArtifacts = craneLib.buildDepsOnly commonArgs;

        # Build the final binary using cached dependency artifacts
        lynceus = craneLib.buildPackage (
          commonArgs
          // {
            inherit cargoArtifacts;
          }
        );

        # Helper to compile the container image for Linux (either natively or cross-compiled)
        makeImage =
          targetConfig:
          let
            targetPkgs =
              if targetConfig == null then
                pkgs
              else
                import nixpkgs {
                  inherit system;
                  crossSystem = {
                    config = targetConfig;
                  };
                };

            targetCraneLib = crane.mkLib targetPkgs;
            isCross = targetPkgs.stdenv.hostPlatform != targetPkgs.stdenv.buildPlatform;

            crossArgs =
              commonArgs
              // (targetPkgs.lib.optionalAttrs isCross (
                let
                  rustHostTriple = targetPkgs.stdenv.buildPlatform.config;
                  rustHostTripleEnv = builtins.replaceStrings [ "-" ] [ "_" ] rustHostTriple;
                  nixHostSuffix =
                    if targetPkgs.stdenv.buildPlatform.isDarwin && targetPkgs.stdenv.buildPlatform.isAarch64 then
                      "arm64_apple_darwin"
                    else
                      rustHostTripleEnv;
                  cargoHostLinkerVar = "CARGO_TARGET_" + targetPkgs.lib.toUpper rustHostTripleEnv + "_LINKER";
                  isDarwin = targetPkgs.stdenv.buildPlatform.isDarwin;
                in
                {
                  HOST_CC = "${targetPkgs.buildPackages.stdenv.cc}/bin/cc";
                  HOST_CXX = "${targetPkgs.buildPackages.stdenv.cc}/bin/c++";
                  "${cargoHostLinkerVar}" = "${targetPkgs.buildPackages.stdenv.cc}/bin/cc";
                }
                // targetPkgs.lib.optionalAttrs isDarwin {
                  depsBuildBuild = [
                    targetPkgs.libiconv
                  ];
                  nativeBuildInputs = [
                    targetPkgs.buildPackages.libiconv
                  ];
                  "NIX_LDFLAGS_${nixHostSuffix}" = "-L${targetPkgs.buildPackages.libiconv}/lib";
                  "NIX_CFLAGS_COMPILE_${nixHostSuffix}" = "-I${targetPkgs.buildPackages.libiconv}/include";
                }
              ));

            cargoArtifactsCross = targetCraneLib.buildDepsOnly crossArgs;

            lynceusCross = targetCraneLib.buildPackage (
              crossArgs
              // {
                inherit cargoArtifactsCross;
              }
            );
          in
          with targetPkgs;
          dockerTools.buildImage {
            name = cargoToml.package.name;
            copyToRoot = with dockerTools; [
              usrBinEnv
              binSh
              coreutils
              caCertificates
              fakeNss
            ];
            config.Entrypoint = [ "${lynceusCross}/bin/lynceus" ];
            config.Labels = with cargoToml; {
              "org.opencontainers.image.title" = package.name;
              "org.opencontainers.image.source" = package.repository or "";
              "org.opencontainers.image.description" = package.description or "";
            };
          };

        push-multiarch = pkgs.writeShellApplication {
          name = "push-multiarch";
          runtimeInputs = with pkgs; [
            regctl
            gzip
            coreutils
          ];
          text = ''
            if [ "$#" -lt 3 ]; then
              echo "Usage: push-multiarch <registry-repo> <amd64-image-tar> <arm64-image-tar>"
              exit 1
            fi

            REPO=$(echo "$1" | tr '[:upper:]' '[:lower:]')
            AMD64_IMAGE="$2"
            ARM64_IMAGE="$3"

            if [ -z "''${TAGS:-}" ]; then
              echo "Error: TAGS environment variable is not set"
              exit 1
            fi


            # Import images into local OCI layout directories directly from Nix build outputs
            regctl image import ocidir://./local-oci-amd64 "$AMD64_IMAGE"
            regctl image import ocidir://./local-oci-arm64 "$ARM64_IMAGE"

            # Get the digests of the imported OCI layouts
            AMD64_DIGEST=$(regctl image digest ocidir://./local-oci-amd64)
            ARM64_DIGEST=$(regctl image digest ocidir://./local-oci-arm64)

            # Push single-architecture layers and manifests by digest
            echo "Pushing AMD64 digest: $AMD64_DIGEST to $REPO..."
            regctl image copy ocidir://./local-oci-amd64 "$REPO@$AMD64_DIGEST"

            echo "Pushing ARM64 digest: $ARM64_DIGEST to $REPO..."
            regctl image copy ocidir://./local-oci-arm64 "$REPO@$ARM64_DIGEST"

            # Create and push the multi-architecture manifest index for each tag
            # Since TAGS is multiline, we read it line by line
            echo "$TAGS" | while read -r tag || [ -n "$tag" ]; do
              if [ -n "$tag" ]; then
                echo "Creating and pushing multi-arch index for $tag..."
                regctl index create "$tag" \
                  --ref "$REPO@$AMD64_DIGEST" \
                  --platform linux/amd64 \
                  --ref "$REPO@$ARM64_DIGEST" \
                  --platform linux/arm64
              fi
            done

            # Cleanup local OCI layouts
            rm -rf ./local-oci-amd64 ./local-oci-arm64
          '';
        };
      in
      rec {
        packages = rec {
          inherit lynceus;
          bin = lynceus;
          default = lynceus;

          check = craneLib.buildPackage (
            commonArgs
            // {
              inherit cargoArtifacts;
              pname = "lynceus-check";
              cargoBuildCommand = "cargo check";
            }
          );

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

          test = craneLib.cargoTest (
            commonArgs
            // {
              inherit cargoArtifacts;
            }
          );

          image = makeImage null;
          image-amd64 = makeImage "x86_64-unknown-linux-gnu";
          image-arm64 = makeImage "aarch64-unknown-linux-gnu";

          inherit push-multiarch;
        };

        checks = {
          inherit (packages) check clippy test;
          formatting = treefmtStack.config.build.check self;
        };

        formatter = treefmtStack.config.build.wrapper;
        devShells.default =
          with pkgs;
          craneLib.devShell {
            checks = self.checks.${system};
            packages = [
              cargo-outdated
              cargo-release
              git-cliff
            ];

            # Extract the Rust standard library source dynamically from craneLib's toolchain
            RUST_SRC_PATH = craneLib.callPackage (
              { rustc, rustPlatform }:
              if builtins.pathExists "${rustc}/lib/rustlib/src/rust/library" then
                "${rustc}/lib/rustlib/src/rust/library"
              else
                rustPlatform.rustLibSrc
            ) { };
          };
      }
    );
}