From 4d89213fc9427ab489024441d9133d601c06b9d5 Mon Sep 17 00:00:00 2001 From: Malte Tammena Date: Wed, 10 Apr 2024 11:19:47 +0200 Subject: [PATCH] redo packaging --- deny.toml | 5 ++ flake.lock | 134 +++++++++++++++++++++++++--- flake.nix | 213 +++++++++++++++++++++++++++++++++----------- rust-toolchain.toml | 2 + src/aba/prepared.rs | 17 ++-- 5 files changed, 301 insertions(+), 70 deletions(-) create mode 100644 deny.toml create mode 100644 rust-toolchain.toml diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..ece3624 --- /dev/null +++ b/deny.toml @@ -0,0 +1,5 @@ +[licenses] +allow = [ + "MIT", + "Unicode-DFS-2016" +] diff --git a/flake.lock b/flake.lock index 4360097..3a9cc8e 100644 --- a/flake.lock +++ b/flake.lock @@ -1,11 +1,47 @@ { "nodes": { + "advisory-db": { + "flake": false, + "locked": { + "lastModified": 1712168594, + "narHash": "sha256-1Yh+vafNq19JDfmpknkWq11AkcQLPmFZ8X6YJZT5r7o=", + "owner": "rustsec", + "repo": "advisory-db", + "rev": "0bc9a77248be5cb5f2b51fe6aba8ba451d74c6bb", + "type": "github" + }, + "original": { + "owner": "rustsec", + "repo": "advisory-db", + "type": "github" + } + }, + "crane": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1712681629, + "narHash": "sha256-bMDXn4AkTXLCpoZbII6pDGoSeSe9gI87jxPsHRXgu/E=", + "owner": "ipetkov", + "repo": "crane", + "rev": "220387ac8e99cbee0ca4c95b621c4bc782b6a235", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, "fenix": { "inputs": { "nixpkgs": [ "nixpkgs" ], - "rust-analyzer-src": "rust-analyzer-src" + "rust-analyzer-src": [] }, "locked": { "lastModified": 1701757414, @@ -39,6 +75,42 @@ "type": "github" } }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1699065553, @@ -75,25 +147,63 @@ }, "root": { "inputs": { + "advisory-db": "advisory-db", + "crane": "crane", "fenix": "fenix", "flake-parts": "flake-parts", - "nixpkgs": "nixpkgs" + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" } }, - "rust-analyzer-src": { - "flake": false, + "rust-overlay": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": [ + "nixpkgs" + ] + }, "locked": { - "lastModified": 1701721820, - "narHash": "sha256-fKcg/YWrCc2ZT4hUvx2bPd+xCTAnQYcd0oDI1cpN07U=", - "owner": "rust-lang", - "repo": "rust-analyzer", - "rev": "2d66f6df252896cfbd7bd24be6ee0c124369b1b7", + "lastModified": 1712715149, + "narHash": "sha256-uOx7GaLV+5hekAYtm/CBr627Pi7+d1Yh70hwKmVjYYo=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "9ef1eca23bee5fb8080863909af3802130b2ee57", "type": "github" }, "original": { - "owner": "rust-lang", - "ref": "nightly", - "repo": "rust-analyzer", + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", "type": "github" } } diff --git a/flake.nix b/flake.nix index a115ee2..776cf06 100644 --- a/flake.nix +++ b/flake.nix @@ -1,18 +1,37 @@ { - inputs.flake-parts.url = "github:hercules-ci/flake-parts"; - inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - inputs.fenix = { - url = "github:nix-community/fenix"; - inputs.nixpkgs.follows = "nixpkgs"; + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + + flake-parts.url = "github:hercules-ci/flake-parts"; + + crane = { + url = "github:ipetkov/crane"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + fenix = { + url = "github:nix-community/fenix"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.rust-analyzer-src.follows = ""; + }; + + flake-utils.url = "github:numtide/flake-utils"; + + advisory-db = { + url = "github:rustsec/advisory-db"; + flake = false; + }; + + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs = { + nixpkgs.follows = "nixpkgs"; + }; + }; }; - outputs = inputs @ { - self, - flake-parts, - fenix, - ... - }: - flake-parts.lib.mkFlake {inherit inputs self;} { + outputs = inputs @ { self, nixpkgs, flake-parts, crane, fenix, flake-utils, advisory-db, rust-overlay, }: + flake-parts.lib.mkFlake { inherit inputs self; } { imports = [ ]; @@ -24,50 +43,140 @@ flake.hydraJobs.devShells.x86_64-linux = self.devShells.x86_64-linux; flake.hydraJobs.checks.x86_64-linux = self.checks.x86_64-linux; - perSystem = { - self', - pkgs, - config, - system, - ... - }: let - rustToolchain = with fenix.packages.${system}; - combine [ - (complete.withComponents [ + perSystem = + { self' + , pkgs + , lib + , config + , system + , ... + }: + let + + rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; + + # NB: we don't need to overlay our custom toolchain for the *entire* + # pkgs (which would require rebuidling anything else which uses rust). + # Instead, we just want to update the scope that crane will use by appending + # our specific toolchain there. + craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchain; + + src = craneLib.cleanCargoSource (craneLib.path ./.); + + # Common arguments can be set here to avoid repeating them later + commonArgs = { + inherit src; + strictDeps = true; + + buildInputs = [ + # Add additional build inputs here + ] ++ lib.optionals pkgs.stdenv.isDarwin [ + # Additional darwin specific inputs can be set here + pkgs.libiconv + ]; + + # Additional environment variables can be set directly + # MY_CUSTOM_VAR = "some value"; + }; + + craneLibLLvmTools = craneLib.overrideToolchain + (fenix.packages.${system}.complete.withComponents [ "cargo" - "clippy" - "rust-src" + "llvm-tools" "rustc" - "rustfmt" - ]) - rust-analyzer - ]; + ]); - rustPlatform = pkgs.makeRustPlatform { - cargo = rustToolchain; - rustc = rustToolchain; - }; - in { - packages.aba2sat = pkgs.callPackage ./nix/packages/aba2sat.nix {inherit rustPlatform;}; - packages.aspforaba = pkgs.callPackage ./nix/packages/aspforaba.nix {}; - packages.clingo = pkgs.callPackage ./nix/packages/clingo.nix {}; - packages.default = self'.packages.aba2sat; + # 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; - devShells.default = pkgs.mkShell { - name = "aba2sat"; - nativeBuildInputs = [ - pkgs.alejandra - pkgs.cargo-workspaces - pkgs.nil - pkgs.nodejs - pkgs.pre-commit - pkgs.shellcheck - pkgs.shfmt - rustToolchain - self'.packages.aspforaba - ]; - RUST_LOG = "trace"; + # Build the actual crate itself, reusing the dependency + # artifacts from above. + aba2sat = craneLib.buildPackage (commonArgs // { + inherit cargoArtifacts; + }); + in + { + _module.args.pkgs = import nixpkgs { + inherit system; + overlays = [ + (import rust-overlay) + ]; + }; + + checks = { + # Build the crate as part of `nix flake check` for convenience + inherit aba2sat; + + # 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. + aba2sat-clippy = craneLib.cargoClippy (commonArgs // { + inherit cargoArtifacts; + cargoClippyExtraArgs = "--all-targets -- --deny warnings"; + }); + + aba2sat-doc = craneLib.cargoDoc (commonArgs // { + inherit cargoArtifacts; + }); + + # Check formatting + aba2sat-fmt = craneLib.cargoFmt { + inherit src; + }; + + # Audit dependencies + aba2sat-audit = craneLib.cargoAudit { + inherit src advisory-db; + }; + + # Audit licenses + aba2sat-deny = crane.lib.${system}.cargoDeny { + inherit src; + }; + + # Run tests with cargo-nextest + # Consider setting `doCheck = false` on `aba2sat` if you do not want + # the tests to run twice + aba2sat-nextest = craneLib.cargoNextest (commonArgs // { + inherit cargoArtifacts; + partitions = 1; + partitionType = "count"; + }); + }; + + packages = { + default = aba2sat; + aspforaba = pkgs.callPackage ./nix/packages/aspforaba.nix { inherit (self'.packages) clingo; }; + clingo = pkgs.callPackage ./nix/packages/clingo.nix { }; + } // lib.optionalAttrs (!pkgs.stdenv.isDarwin) { + aba2sat-llvm-coverage = craneLibLLvmTools.cargoLlvmCov (commonArgs // { + inherit cargoArtifacts; + }); + }; + + apps.default = flake-utils.lib.mkApp { + drv = aba2sat; + }; + + devShells.default = craneLib.devShell { + # Inherit inputs from checks. + checks = self.checks.${system}; + + RUST_LOG = "trace"; + + # Extra inputs can be added here; cargo and rustc are provided by default. + packages = [ + pkgs.nil + pkgs.pre-commit + pkgs.shellcheck + pkgs.shfmt + pkgs.nodejs + ]; + }; }; - }; }; } diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..5d56faf --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/src/aba/prepared.rs b/src/aba/prepared.rs index a7cdd89..18df57f 100644 --- a/src/aba/prepared.rs +++ b/src/aba/prepared.rs @@ -103,11 +103,15 @@ fn calculate_loops_and_their_support(aba: &Aba) -> Vec { let to = universe.get(&to).unwrap(); graph.update_edge(*from, *to, ()); }); - let mut file = File::create("./graph.gv").unwrap(); - let dot = Dot::with_config(&graph, &[Config::EdgeNoLabel]); - write!(file, "{dot:?}").unwrap(); - // TODO: Write on debug, simplify for production + #[cfg(debug_assertions)] + { + let mut file = File::create("./graph.gv").unwrap(); + let dot = Dot::with_config(&graph, &[Config::EdgeNoLabel]); + write!(file, "{dot:?}").unwrap(); + } let mut loops = vec![]; + const LOOP_SIZE_IN_MULT_UNIVERSE_SIZE: f32 = 0.2; + let mut output_printed = false; graph.visit_cycles(|graph, cycle| { let heads = cycle.iter().map(|idx| graph[*idx]).collect::>(); let loop_rules = aba @@ -121,9 +125,10 @@ fn calculate_loops_and_their_support(aba: &Aba) -> Vec { .cloned() .collect(); loops.push(r#Loop { heads, support }); - if loops.len() >= universe.len() { - if loops.len() == universe.len() { + if loops.len() >= (LOOP_SIZE_IN_MULT_UNIVERSE_SIZE * universe.len() as f32) as usize { + if ! output_printed { eprintln!("Too... many... cycles... Aborting cycle detection with {} cycles. Solver? You're on your own now", loops.len()); + output_printed = true; } std::ops::ControlFlow::Break(()) } else {