diff --git a/.envrc b/.envrc index 3b11770..325666e 100644 --- a/.envrc +++ b/.envrc @@ -1,2 +1,2 @@ -use flake +use flake . --impure dotenv diff --git a/.gitignore b/.gitignore index d87e4f1..99f71b6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .direnv/ result .env +.devenv diff --git a/flake.lock b/flake.lock index 3680e4e..4214ec9 100644 --- a/flake.lock +++ b/flake.lock @@ -1,36 +1,138 @@ { "nodes": { + "advisory-db": { + "flake": false, + "locked": { + "lastModified": 1732819720, + "narHash": "sha256-6H7mKBKw3VErpGcCGEamBYJsopvqqdFmJhl8slfCtOQ=", + "owner": "rustsec", + "repo": "advisory-db", + "rev": "9dc4a0bb102451e3c71e1b639068aec5a3e1f5f3", + "type": "github" + }, + "original": { + "owner": "rustsec", + "repo": "advisory-db", + "type": "github" + } + }, + "cachix": { + "inputs": { + "devenv": [ + "devenv" + ], + "flake-compat": [ + "devenv" + ], + "git-hooks": [ + "devenv" + ], + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1728672398, + "narHash": "sha256-KxuGSoVUFnQLB2ZcYODW7AVPAh9JqRlD5BrfsC/Q4qs=", + "owner": "cachix", + "repo": "cachix", + "rev": "aac51f698309fd0f381149214b7eee213c66ef0a", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "latest", + "repo": "cachix", + "type": "github" + } + }, + "crane": { + "locked": { + "lastModified": 1733016477, + "narHash": "sha256-Hh0khbqBeCtiNS0SJgqdWrQDem9WlPEc2KF5pAY+st0=", + "owner": "ipetkov", + "repo": "crane", + "rev": "76d64e779e2fbaf172110038492343a8c4e29b55", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "devenv": { + "inputs": { + "cachix": "cachix", + "flake-compat": "flake-compat", + "git-hooks": "git-hooks", + "nix": "nix", + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1732896163, + "narHash": "sha256-eS0vSZT0ZUguR6Jf6CyupvDn4m+r/mgN6Vtg61ECYC0=", + "owner": "cachix", + "repo": "devenv", + "rev": "2c928a199d56191d7a53f29ccafa56238c8ce4e5", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, "fenix": { "inputs": { "nixpkgs": [ "nixpkgs" ], - "rust-analyzer-src": "rust-analyzer-src" + "rust-analyzer-src": [] }, "locked": { - "lastModified": 1730183653, - "narHash": "sha256-dcJGcoDgNBxTagW8kECwBKsRBA1ZITtQ+p3N6KHg5ps=", - "owner": "nix-community", + "lastModified": 1732981482, + "narHash": "sha256-mwxaSCU4NljZeMBOzDfjEev4Br7ZhGiHh77Cs/NrIEg=", + "owner": "Defelo", "repo": "fenix", - "rev": "dc19afc39af5f5e69fca78ebae59170e61017df8", + "rev": "cc65a4c69dd719ae5405bf7054674520262f748b", "type": "github" }, "original": { - "owner": "nix-community", + "owner": "Defelo", + "ref": "staging", "repo": "fenix", "type": "github" } }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, "flake-parts": { "inputs": { - "nixpkgs-lib": "nixpkgs-lib" + "nixpkgs-lib": [ + "devenv", + "nix", + "nixpkgs" + ] }, "locked": { - "lastModified": 1727826117, - "narHash": "sha256-K5ZLCyfO/Zj9mPFldf3iwS6oZStJcU4tSpiXTMYaaL0=", + "lastModified": 1712014858, + "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "3d04084d54bedc3d6b8b736c70ef449225c361b1", + "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", "type": "github" }, "original": { @@ -39,55 +141,130 @@ "type": "github" } }, - "naersk": { + "flake-parts_2": { "inputs": { - "nixpkgs": "nixpkgs" + "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1721727458, - "narHash": "sha256-r/xppY958gmZ4oTfLiHN0ZGuQ+RSTijDblVgVLFi1mw=", - "owner": "nix-community", - "repo": "naersk", - "rev": "3fb418eaf352498f6b6c30592e3beb63df42ef11", + "lastModified": 1730504689, + "narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "506278e768c2a08bec68eb62932193e341f55c90", "type": "github" }, "original": { - "owner": "nix-community", - "repo": "naersk", + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "git-hooks": { + "inputs": { + "flake-compat": [ + "devenv" + ], + "gitignore": "gitignore", + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-stable": [ + "devenv" + ] + }, + "locked": { + "lastModified": 1730302582, + "narHash": "sha256-W1MIJpADXQCgosJZT8qBYLRuZls2KSiKdpnTVdKBuvU=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "af8a16fe5c264f5e9e18bcee2859b40a656876cf", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "devenv", + "git-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "libgit2": { + "flake": false, + "locked": { + "lastModified": 1697646580, + "narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=", + "owner": "libgit2", + "repo": "libgit2", + "rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5", + "type": "github" + }, + "original": { + "owner": "libgit2", + "repo": "libgit2", + "type": "github" + } + }, + "nix": { + "inputs": { + "flake-compat": [ + "devenv" + ], + "flake-parts": "flake-parts", + "libgit2": "libgit2", + "nixpkgs": "nixpkgs_2", + "nixpkgs-23-11": [ + "devenv" + ], + "nixpkgs-regression": [ + "devenv" + ], + "pre-commit-hooks": [ + "devenv" + ] + }, + "locked": { + "lastModified": 1727438425, + "narHash": "sha256-X8ES7I1cfNhR9oKp06F6ir4Np70WGZU5sfCOuNBEwMg=", + "owner": "domenkozar", + "repo": "nix", + "rev": "f6c5ae4c1b2e411e6b1e6a8181cc84363d6a7546", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "devenv-2.24", + "repo": "nix", "type": "github" } }, "nixpkgs": { "locked": { - "lastModified": 0, - "narHash": "sha256-4spSNTZ6h8Xmvrr9oqfuxc9jarasGj1QOcsgw8BfNd8=", - "path": "/nix/store/93haqkb7bl8l90vpfqgkygrd5l13gafm-source", - "type": "path" - }, - "original": { - "id": "nixpkgs", - "type": "indirect" - } - }, - "nixpkgs-lib": { - "locked": { - "lastModified": 1727825735, - "narHash": "sha256-0xHYkMkeLVQAMa7gvkddbPqpxph+hDzdu1XdGPJR+Os=", - "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/fb192fec7cc7a4c26d51779e9bab07ce6fa5597a.tar.gz" - }, - "original": { - "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/fb192fec7cc7a4c26d51779e9bab07ce6fa5597a.tar.gz" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1729880355, - "narHash": "sha256-RP+OQ6koQQLX5nw0NmcDrzvGL8HDLnyXt/jHhL1jwjM=", + "lastModified": 1730531603, + "narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "18536bf04cd71abd345f9579158841376fdd0c5a", + "rev": "7ffd9ae656aec493492b44d0ddfb28e79a1ea25d", "type": "github" }, "original": { @@ -97,30 +274,75 @@ "type": "github" } }, - "root": { - "inputs": { - "fenix": "fenix", - "flake-parts": "flake-parts", - "naersk": "naersk", - "nixpkgs": "nixpkgs_2" + "nixpkgs-lib": { + "locked": { + "lastModified": 1730504152, + "narHash": "sha256-lXvH/vOfb4aGYyvFmZK/HlsNsr/0CVWlwYvo2rxJk3s=", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz" } }, - "rust-analyzer-src": { - "flake": false, + "nixpkgs_2": { "locked": { - "lastModified": 1730123801, - "narHash": "sha256-11FMcPraLSKuvfFF4OzmKWSKE5zXAzFqZOi3k/8/HFg=", - "owner": "rust-lang", - "repo": "rust-analyzer", - "rev": "cf8f950baab30f335917b177536d2d73e0aaa1ae", + "lastModified": 1717432640, + "narHash": "sha256-+f9c4/ZX5MWDOuB1rKoWj+lBNm0z0rs4CK47HBLxy1o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "88269ab3044128b7c2f4c7d68448b2fb50456870", "type": "github" }, "original": { - "owner": "rust-lang", - "ref": "nightly", - "repo": "rust-analyzer", + "owner": "NixOS", + "ref": "release-24.05", + "repo": "nixpkgs", "type": "github" } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1716977621, + "narHash": "sha256-Q1UQzYcMJH4RscmpTkjlgqQDX5yi1tZL0O345Ri6vXQ=", + "owner": "cachix", + "repo": "devenv-nixpkgs", + "rev": "4267e705586473d3e5c8d50299e71503f16a6fb6", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "rolling", + "repo": "devenv-nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1733064805, + "narHash": "sha256-7NbtSLfZO0q7MXPl5hzA0sbVJt6pWxxtGWbaVUDDmjs=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "31d66ae40417bb13765b0ad75dd200400e98de84", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "advisory-db": "advisory-db", + "crane": "crane", + "devenv": "devenv", + "fenix": "fenix", + "flake-parts": "flake-parts_2", + "nixpkgs": "nixpkgs_4" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index ff6c082..9b7595c 100644 --- a/flake.nix +++ b/flake.nix @@ -1,62 +1,184 @@ { - description = "A TUI for the Canvas LMS."; + description = "A TUI for the Canvas LMS"; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - flake-parts.url = "github:hercules-ci/flake-parts"; + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + + crane.url = "github:ipetkov/crane"; + fenix = { - url = "github:nix-community/fenix"; + # url = "github:nix-community/fenix"; + url = "github:Defelo/fenix/staging"; inputs.nixpkgs.follows = "nixpkgs"; + inputs.rust-analyzer-src.follows = ""; }; - naersk.url = "github:nix-community/naersk"; + + flake-parts.url = "github:hercules-ci/flake-parts"; + + advisory-db = { + url = "github:rustsec/advisory-db"; + flake = false; + }; + + devenv.url = "github:cachix/devenv"; }; outputs = inputs@{ flake-parts, + crane, fenix, - naersk, + advisory-db, ... }: flake-parts.lib.mkFlake { inherit inputs; } { + imports = [ + inputs.devenv.flakeModule + ]; systems = [ - "aarch64-linux" "x86_64-linux" - "aarch64-darwin" + "aarch64-linux" "x86_64-darwin" + "aarch64-darwin" ]; perSystem = - { system, pkgs, ... }: + { + config, + pkgs, + system, + ... + }: let - naersk' = pkgs.callPackage naersk { }; - defaultBuildOpts = { - cargo = fenix.packages.${system}.stable.cargo; - rustc = fenix.packages.${system}.stable.rustc; - src = ./.; + inherit (pkgs) lib; - nativeBuildInputs = with pkgs; [ pkg-config ]; - buildInputs = with pkgs; [ openssl ]; + craneLib = crane.mkLib pkgs; + src = craneLib.cleanCargoSource ./.; - mode = "build"; + # Common arguments can be set here to avoid repeating them later + commonArgs = { + inherit src; + strictDeps = true; + + nativeBuildInputs = with pkgs; [ + pkg-config + ]; + + buildInputs = with pkgs; [ + openssl + ]; + + # Additional environment variables can be set directly + # MY_CUSTOM_VAR = "some value"; }; + + craneLibLLvmTools = craneLib.overrideToolchain ( + fenix.packages.${system}.complete.withComponents [ + "cargo" + "llvm-tools" + "rustc" + ] + ); + + # Build *just* the cargo dependencies, so we can reuse + # all of that work (e.g. via cachix) when running in CI + cargoArtifacts = craneLib.buildDepsOnly commonArgs; + + # Build the actual crate itself, reusing the dependency + # artifacts from above. + cartographer = craneLib.buildPackage ( + commonArgs + // { + inherit cargoArtifacts; + } + ); in { - devShells.default = pkgs.mkShell { - buildInputs = with pkgs; [ - pkg-config - openssl - fenix.packages.${system}.stable.completeToolchain - cargo-audit - ]; - }; - packages = { - default = naersk'.buildPackage defaultBuildOpts; - test = naersk'.buildPackage ( - defaultBuildOpts + checks = { + # Build the crate as part of `nix flake check` for convenience + inherit cartographer; + + # Run clippy (and deny all warnings) on the crate source, + # again, reusing the dependency artifacts from above. + # + # Note that this is done as a separate derivation so that + # we can block the CI if there are issues here, but not + # prevent downstream consumers from building our crate by itself. + cartographer-clippy = craneLib.cargoClippy ( + commonArgs // { - mode = "test"; + inherit cargoArtifacts; + cargoClippyExtraArgs = "--all-targets -- --deny warnings"; } ); + + cartographer-doc = craneLib.cargoDoc ( + commonArgs + // { + inherit cargoArtifacts; + } + ); + + # Check formatting + cartographer-fmt = craneLib.cargoFmt { + inherit src; + }; + + cartographer-toml-fmt = craneLib.taploFmt { + src = pkgs.lib.sources.sourceFilesBySuffices src [ ".toml" ]; + # taplo arguments can be further customized below as needed + # taploExtraArgs = "--config ./taplo.toml"; + }; + + # Audit dependencies + cartographer-audit = craneLib.cargoAudit { + inherit src advisory-db; + }; + + # Audit licenses + cartographer-deny = craneLib.cargoDeny { + inherit src; + }; + + # Run tests with cargo-nextest + # Consider setting `doCheck = false` on `cartographer` if you do not want + # the tests to run twice + cartographer-nextest = craneLib.cargoNextest ( + commonArgs + // { + inherit cargoArtifacts; + partitions = 1; + partitionType = "count"; + } + ); + }; + + packages = + { + default = cartographer; + } + // lib.optionalAttrs (!pkgs.stdenv.isDarwin) { + cartographer-llvm-coverage = craneLibLLvmTools.cargoLlvmCov ( + commonArgs + // { + inherit cargoArtifacts; + } + ); + }; + + devenv.shells.default = { + enterShell = '' + export LD_LIBRARY_PATH=${pkgs.lib.makeLibraryPath [ pkgs.openssl ]}:$LD_LIBRARY_PATH + ''; + packages = [ + (fenix.packages.${system}.complete.withComponents [ + "cargo" + "llvm-tools" + "rustc" + "clippy" + "rustfmt" + "rust-analyzer" + ]) + ] ++ config.packages.default.nativeBuildInputs ++ config.packages.default.buildInputs; }; }; };