diff --git a/.gitignore b/.gitignore index bbee93a..efdbcfb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ /.direnv -/rust-checks/target /result* /target diff --git a/Cargo.lock b/Cargo.lock index cadee28..edb0f7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "anstream" version = "0.6.14" @@ -51,6 +60,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + [[package]] name = "clap" version = "4.5.4" @@ -91,12 +106,43 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +[[package]] +name = "codespan" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3362992a0d9f1dd7c3d0e89e0ab2bb540b7a95fea8cd798090e758fda2899b5e" +dependencies = [ + "codespan-reporting", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + [[package]] name = "colorchoice" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +[[package]] +name = "countme" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "heck" version = "0.5.0" @@ -121,12 +167,28 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + [[package]] name = "nixpkgs-hammering" version = "0.1.0" dependencies = [ "clap", "indoc", + "rust-checks", "serde", "serde_json", ] @@ -149,6 +211,76 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "rnix" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb35cedbeb70e0ccabef2a31bcff0aebd114f19566086300b8f42c725fc2cb5f" +dependencies = [ + "rowan", +] + +[[package]] +name = "rowan" +version = "0.15.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a58fa8a7ccff2aec4f39cc45bf5f985cec7125ab271cf681c279fd00192b49" +dependencies = [ + "countme", + "hashbrown", + "memoffset", + "rustc-hash", + "serde", + "text-size", +] + +[[package]] +name = "rust-checks" +version = "0.0.0" +dependencies = [ + "codespan", + "regex", + "rnix", + "rowan", + "serde", + "serde_json", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "ryu" version = "1.0.18" @@ -203,18 +335,51 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "text-size" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233" +dependencies = [ + "serde", +] + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-width" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" + [[package]] name = "utf8parse" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys", +] + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index 92c9c8d..b389031 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,5 +11,13 @@ path = "src/main.rs" [dependencies] clap = { version = "4.5.4", features = ["derive"] } indoc = "2.0.5" +serde = { workspace = true } +serde_json = { workspace = true } +rust-checks = { path = "./rust-checks" } + +[workspace] +members = ["rust-checks"] + +[workspace.dependencies] serde = { version = "1.0.203", features = ["serde_derive"] } serde_json = "1.0.117" diff --git a/flake.nix b/flake.nix index d3b4b44..f78b000 100644 --- a/flake.nix +++ b/flake.nix @@ -20,53 +20,34 @@ { nixpkgs-hammering = - let - rust-checks = prev.rustPlatform.buildRustPackage { - pname = "rust-checks"; - version = (prev.lib.importTOML ./rust-checks/Cargo.toml).package.version; - src = ./rust-checks; - cargoLock.lockFile = ./rust-checks/Cargo.lock; - }; - - # Find all of the binaries installed by rust-checks. Note, if this changes - # in the future to use wrappers or something else that pollute the bin/ - # directory, this logic will have to grow. - rust-check-names = let - binContents = builtins.readDir "${rust-checks}/bin"; - in - prev.lib.mapAttrsToList (name: type: assert type == "regular"; name) binContents; - in - prev.rustPlatform.buildRustPackage { - pname = "nixpkgs-hammering"; - version = (prev.lib.importTOML ./Cargo.toml).package.version; - src = ./.; + prev.rustPlatform.buildRustPackage { + pname = "nixpkgs-hammering"; + version = (prev.lib.importTOML ./Cargo.toml).package.version; + src = ./.; - cargoLock.lockFile = ./Cargo.lock; + cargoLock.lockFile = ./Cargo.lock; - nativeBuildInputs = with prev; [ - makeWrapper - ]; + nativeBuildInputs = with prev; [ + makeWrapper + ]; - passthru = { - inherit rust-checks; - exePath = "/bin/nixpkgs-hammer"; - }; + passthru = { + exePath = "/bin/nixpkgs-hammer"; + }; - postInstall = '' - datadir="$out/share/nixpkgs-hammering" - mkdir -p "$datadir" + postInstall = '' + datadir="$out/share/nixpkgs-hammering" + mkdir -p "$datadir" - wrapProgram "$out/bin/nixpkgs-hammer" \ - --prefix PATH ":" ${prev.lib.makeBinPath [ - prev.nix - rust-checks - ]} \ - --set AST_CHECK_NAMES ${prev.lib.concatStringsSep ":" rust-check-names} \ - --set OVERLAYS_DIR "$datadir/overlays" - cp -r ${./overlays} "$datadir/overlays" - cp -r ${./lib} "$datadir/lib" - ''; - }; + wrapProgram "$out/bin/nixpkgs-hammer" \ + --prefix PATH ":" ${prev.lib.makeBinPath [ + prev.nix + ]} \ + --set OVERLAYS_DIR "$datadir/overlays" + cp -r ${./overlays} "$datadir/overlays" + cp -r ${./lib} "$datadir/lib" + ''; + }; }; }; } // utils.lib.eachDefaultSystem (system: let diff --git a/rust-checks/Cargo.lock b/rust-checks/Cargo.lock deleted file mode 100644 index ec034bc..0000000 --- a/rust-checks/Cargo.lock +++ /dev/null @@ -1,318 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "codespan" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3362992a0d9f1dd7c3d0e89e0ab2bb540b7a95fea8cd798090e758fda2899b5e" -dependencies = [ - "codespan-reporting", -] - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - -[[package]] -name = "countme" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "memchr" -version = "2.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" - -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "proc-macro2" -version = "1.0.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "regex" -version = "1.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" - -[[package]] -name = "rnix" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb35cedbeb70e0ccabef2a31bcff0aebd114f19566086300b8f42c725fc2cb5f" -dependencies = [ - "rowan", -] - -[[package]] -name = "rowan" -version = "0.15.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a58fa8a7ccff2aec4f39cc45bf5f985cec7125ab271cf681c279fd00192b49" -dependencies = [ - "countme", - "hashbrown", - "memoffset", - "rustc-hash", - "serde", - "text-size", -] - -[[package]] -name = "rust-checks" -version = "0.0.0" -dependencies = [ - "codespan", - "regex", - "rnix", - "rowan", - "serde", - "serde_json", -] - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "serde" -version = "1.0.203" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.203" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "syn" -version = "2.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "text-size" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233" -dependencies = [ - "serde", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-width" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" - -[[package]] -name = "winapi-util" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/rust-checks/Cargo.toml b/rust-checks/Cargo.toml index dfd8eb3..b9a6ebb 100644 --- a/rust-checks/Cargo.toml +++ b/rust-checks/Cargo.toml @@ -9,5 +9,5 @@ codespan = "0.11" regex = "1" rnix = "0.11" rowan = { version = "0.15", features = [ "serde1" ] } -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" +serde = { workspace = true } +serde_json = { workspace = true } diff --git a/rust-checks/src/checks/mod.rs b/rust-checks/src/checks/mod.rs index 03cbe85..0db651a 100644 --- a/rust-checks/src/checks/mod.rs +++ b/rust-checks/src/checks/mod.rs @@ -4,8 +4,22 @@ mod no_uri_literals; mod stale_substitute; mod unused_argument; +use std::error::Error; + pub use missing_patch_comment::run as missing_patch_comment; pub use no_python_tests::run as no_python_tests; pub use no_uri_literals::run as no_uri_literals; pub use stale_substitute::run as stale_substitute; pub use unused_argument::run as unused_argument; + +use crate::common_structs::CheckedAttr; + +pub type Check = fn(Vec) -> Result>; + +pub const ALL: [(&'static str, Check); 5] = [ + ("missing-patch-comment", missing_patch_comment), + ("no-python-tests", no_python_tests), + ("no-uri-literals", no_uri_literals), + ("stale-substitute", stale_substitute), + ("unused-argument", unused_argument), +]; diff --git a/rust-checks/src/common_structs.rs b/rust-checks/src/common_structs.rs index 80ed590..5bd06f0 100644 --- a/rust-checks/src/common_structs.rs +++ b/rust-checks/src/common_structs.rs @@ -2,7 +2,7 @@ use codespan::{ByteIndex, FileId, Files}; use serde::{Deserialize, Serialize}; use std::error::Error; -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct CheckedAttr { pub name: String, pub location: Option, diff --git a/src/lib.rs b/src/lib.rs index 6ad25bd..ef0a13c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ use indoc::formatdoc; use model::{CheckedAttr, Report, Severity, SourceLocation}; +use rust_checks::checks::{self, Check}; use serde::{Deserialize, Serialize}; use std::{ collections::{HashMap, HashSet}, @@ -35,22 +36,19 @@ fn get_overlays_dir() -> Result { Err("Either ‘OVERLAYS_DIR’ or ‘CARGO_MANIFEST_DIR’ environment variable expected.".to_owned()) } -fn get_check_programs() -> Result, String> { - // Each rule that is implemented as an external check program rather - // than an overlay is installed onto our PATH, and the names of the - // rules put into this environment variable. - Ok(optional_env("AST_CHECK_NAMES")?.map_or_else( - || HashSet::new(), - |ast_checks| HashSet::from_iter(ast_checks.split(":").map(ToOwned::to_owned)), - )) +fn get_check_programs(excluded_rules: &HashSet) -> HashMap { + checks::ALL + .into_iter() + .map(|(name, check)| (name.to_string(), check)) + .filter(|(name, _)| !excluded_rules.contains(name)) + .collect() } fn run_external_checks( attrs: &[CheckedAttr], excluded_rules: &HashSet, ) -> Result>, String> { - let check_programs = get_check_programs()?; - let rules = &check_programs - &excluded_rules; + let rules = get_check_programs(excluded_rules); if rules.is_empty() { return Ok(HashMap::new()); } @@ -81,24 +79,28 @@ fn run_external_checks( } } - for rule in rules { - let json_text = run_command_with_input(&rule, &[], &encoded_attrs).map_err(|err| { + let mut rc_attrs = Vec::with_capacity(attrs.len()); + for attr in attrs { + rc_attrs.push(attr.clone().try_into()?); + } + for (name, check) in rules { + let json_text = check(rc_attrs.clone()).map_err(|err| { eprintln!( "{}", red(&format!( - "Rule ‘{rule}’ failed with input ‘{encoded_attrs}’.\ + "Rule ‘{name}’ failed with input ‘{encoded_attrs}’.\ This is a bug. Please file a ticket on GitHub." )) ); - format!("Unable to execute rule ‘{rule}’: {}", err.to_string()) + format!("Unable to execute rule ‘{name}’: {}", err.to_string()) })?; if !json_text.is_empty() { let results: HashMap> = serde_json::from_str(&json_text).map_err(|err| { format!( - "Unable to parse result of rule ‘{rule}’: {}", + "Unable to parse result of rule ‘{name}’: {}", err.to_string() ) })?; diff --git a/src/model.rs b/src/model.rs index 79f88e2..e55668e 100644 --- a/src/model.rs +++ b/src/model.rs @@ -1,3 +1,4 @@ +use rust_checks::common_structs; use serde::{Deserialize, Serialize}; use std::{fmt::Display, path::PathBuf}; @@ -25,6 +26,26 @@ pub struct SourceLocation { pub column: Option, } +fn pb_to_string(buf: PathBuf) -> Result { + Ok(buf + .to_str() + .ok_or_else(|| format!("File path ‘{}’ not a valid UTF-8 string", buf.display()))? + .to_owned()) +} + +impl TryInto for SourceLocation { + type Error = String; + + fn try_into(self) -> Result { + let SourceLocation { file, line, column } = self; + Ok(common_structs::SourceLocation { + file: pb_to_string(file)?, + line, + column, + }) + } +} + fn default_link() -> bool { true } @@ -56,3 +77,27 @@ pub struct CheckedAttr { /// path the the output of the drv in the nix store, if exists pub output: Option, } + +impl TryInto for CheckedAttr { + type Error = String; + + fn try_into(self) -> Result { + let CheckedAttr { + name, + location, + drv, + output, + } = self; + + let location = location.map(|l| l.try_into()).transpose()?; + let drv = drv.map(pb_to_string).transpose()?; + let output = output.map(pb_to_string).transpose()?; + + Ok(common_structs::CheckedAttr { + name, + location, + drv, + output, + }) + } +}