diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index e683c00b..0caa6792 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -8,9 +8,16 @@ "uses": "actions/checkout@v4" }, { - "uses": "cachix/install-nix-action@v31", + "uses": "nixbuild/nix-quick-install-action@master", "with": { - "github_access_token": "${{ secrets.GITHUB_TOKEN }}" + "github_access_token": "${{ secrets.GITHUB_TOKEN }}", + "nix_conf": "keep-env-derivations = true\nkeep-outputs = true\n" + } + }, + { + "uses": "nix-community/cache-nix-action@main", + "with": { + "primary-key": "nix-${{ runner.os }}" } }, { @@ -33,9 +40,16 @@ "uses": "actions/checkout@v4" }, { - "uses": "cachix/install-nix-action@v31", + "uses": "nixbuild/nix-quick-install-action@master", + "with": { + "github_access_token": "${{ secrets.GITHUB_TOKEN }}", + "nix_conf": "keep-env-derivations = true\nkeep-outputs = true\n" + } + }, + { + "uses": "nix-community/cache-nix-action@main", "with": { - "github_access_token": "${{ secrets.GITHUB_TOKEN }}" + "primary-key": "nix-${{ runner.os }}" } }, { @@ -52,9 +66,16 @@ "uses": "actions/checkout@v4" }, { - "uses": "cachix/install-nix-action@v31", + "uses": "nixbuild/nix-quick-install-action@master", + "with": { + "github_access_token": "${{ secrets.GITHUB_TOKEN }}", + "nix_conf": "keep-env-derivations = true\nkeep-outputs = true\n" + } + }, + { + "uses": "nix-community/cache-nix-action@main", "with": { - "github_access_token": "${{ secrets.GITHUB_TOKEN }}" + "primary-key": "nix-${{ runner.os }}" } }, { diff --git a/.github/workflows/update-flake-inputs.yaml b/.github/workflows/update-flake-inputs.yaml new file mode 100644 index 00000000..214dcf71 --- /dev/null +++ b/.github/workflows/update-flake-inputs.yaml @@ -0,0 +1,56 @@ +{ + "jobs": { + "nix-flake-update": { + "permissions": { + "contents": "write", + "pull-requests": "write" + }, + "runs-on": "ubuntu-latest", + "steps": [ + { + "id": "app-token", + "uses": "actions/create-github-app-token@v1", + "with": { + "app-id": "${{ secrets.APP_ID }}", + "private-key": "${{ secrets.APP_PRIVATE_KEY }}" + } + }, + { + "uses": "actions/checkout@v4", + "with": { + "token": "${{ steps.app-token.outputs.token }}" + } + }, + { + "uses": "nixbuild/nix-quick-install-action@master", + "with": { + "github_access_token": "${{ secrets.GITHUB_TOKEN }}", + "nix_conf": "keep-env-derivations = true\nkeep-outputs = true\n" + } + }, + { + "uses": "nix-community/cache-nix-action@main", + "with": { + "primary-key": "nix-${{ runner.os }}" + } + }, + { + "uses": "mic92/update-flake-inputs@main", + "with": { + "commit-message": "chore(flake): update {{input}}{{in}}", + "github-token": "${{ steps.app-token.outputs.token }}" + } + } + ] + } + }, + "name": "Update flake inputs", + "on": { + "schedule": [ + { + "cron": "0 0/6 * * *" + } + ], + "workflow_dispatch": {} + } +} diff --git a/.github/workflows/update-flake-lock.yaml b/.github/workflows/update-flake-lock.yaml deleted file mode 100644 index 50d21a4c..00000000 --- a/.github/workflows/update-flake-lock.yaml +++ /dev/null @@ -1,40 +0,0 @@ -{ - "jobs": { - "nix-flake-update": { - "permissions": { - "contents": "write", - "id-token": "write", - "issues": "write", - "pull-requests": "write" - }, - "runs-on": "ubuntu-latest", - "steps": [ - { - "uses": "actions/checkout@v4" - }, - { - "uses": "cachix/install-nix-action@v31", - "with": { - "github_access_token": "${{ secrets.GITHUB_TOKEN }}" - } - }, - { - "uses": "DeterminateSystems/update-flake-lock@main", - "with": { - "commit-msg": "chore(flake): bump inputs", - "pr-title": "chore(flake): bump inputs" - } - } - ] - } - }, - "name": "Update flake.lock", - "on": { - "schedule": [ - { - "cron": "0 0 * * 5" - } - ], - "workflow_dispatch": {} - } -} diff --git a/Cargo.lock b/Cargo.lock index fec1f7a1..59f04155 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,56 @@ dependencies = [ "memchr", ] +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + [[package]] name = "anyhow" version = "1.0.100" @@ -32,29 +82,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.9.4" @@ -87,35 +120,50 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.0.0-beta.5" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feff3878564edb93745d58cf63e17b63f24142506e7a20c87a5521ed7bfb1d63" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ - "atty", - "bitflags 1.3.2", + "clap_builder", "clap_derive", - "indexmap", - "lazy_static", - "os_str_bytes", +] + +[[package]] +name = "clap_builder" +version = "4.5.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", "strsim", - "termcolor", - "textwrap", - "unicase", ] [[package]] name = "clap_derive" -version = "3.0.0-beta.5" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b15c6b4f786ffb6192ffe65a36855bc1fc2444bcd0945ae16748dcd6ed7d0d3" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.106", ] +[[package]] +name = "clap_lex" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + [[package]] name = "console" version = "0.15.11" @@ -125,7 +173,7 @@ dependencies = [ "encode_unicode", "libc", "once_cell", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -226,7 +274,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -290,12 +338,9 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" -version = "0.3.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -358,6 +403,12 @@ dependencies = [ "similar", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + [[package]] name = "itoa" version = "0.4.8" @@ -455,13 +506,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "os_str_bytes" -version = "4.2.0" +name = "once_cell_polyfill" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addaa943333a514159c80c97ff4a93306530d965d27e139188283cd13e06a799" -dependencies = [ - "memchr", -] +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "paste" @@ -469,30 +517,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" version = "1.0.101" @@ -593,11 +617,11 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.4", + "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -671,7 +695,7 @@ checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3" [[package]] name = "statix" -version = "0.5.8" +version = "0.6.0" dependencies = [ "anyhow", "ariadne", @@ -706,9 +730,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" @@ -742,16 +766,7 @@ dependencies = [ "getrandom", "once_cell", "rustix", - "windows-sys", -] - -[[package]] -name = "termcolor" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" -dependencies = [ - "winapi-util", + "windows-sys 0.59.0", ] [[package]] @@ -760,15 +775,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "288cb548dbe72b652243ea797201f3d481a0609a967980fcc5b2315ea811560a" -[[package]] -name = "textwrap" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" -dependencies = [ - "unicode-width", -] - [[package]] name = "thiserror" version = "1.0.30" @@ -813,38 +819,17 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-ident" version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" -[[package]] -name = "unicode-segmentation" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" - -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - [[package]] name = "utf8parse" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "version_check" @@ -941,6 +926,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-sys" version = "0.59.0" @@ -950,6 +941,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-targets" version = "0.52.6" diff --git a/Cargo.toml b/Cargo.toml index 07e43308..1cb5baf3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,32 +8,32 @@ edition = "2024" license = "MIT" [workspace.dependencies] -anyhow = "1.0.100" -ariadne = "0.1.3" -clap = "3.0.0-beta.4" -hex = "0.4.3" -ignore = "0.4.18" -indexmap = "1.6.2" -indoc = "2.0.6" -insta = { features = ["filters"], version = "1.43.2" } -lazy_static = "1.0" +anyhow = "*" +ariadne = "*" +clap = { features = ["derive"], version = "*" } +hex = "*" +ignore = "*" +indexmap = "*" +indoc = "*" +insta = { features = ["filters"], version = "*" } +lazy_static = "*" lib.path = "./lib" macros.path = "./macros" -paste = "1.0.15" -proc-macro2 = "1.0.27" -quote = "1.0" -rayon = "1.5.1" -rnix = "0.12.0" -rowan = "0.15.17" -serde = { features = ["derive"], version = "1.0.68" } -serde_json = { version = "1.0.68" } -sha2 = "0.10.9" -similar = "2.1.0" -strip-ansi-escapes = "0.1.1" -syn = { features = ["full"], version = "2.0" } -tempfile = "3.23.0" -thiserror = "1.0.30" -toml = "0.5.8" +paste = "*" +proc-macro2 = "*" +quote = "*" +rayon = "*" +rnix = "*" +rowan = "*" +serde = { features = ["derive"], version = "*" } +serde_json = "*" +sha2 = "*" +similar = "*" +strip-ansi-escapes = "*" +syn = { features = ["full"], version = "*" } +tempfile = "*" +thiserror = "*" +toml = "*" vfs.path = "./vfs" [workspace.lints.clippy] diff --git a/bin/Cargo.toml b/bin/Cargo.toml index 0f6ad73a..d9acabd9 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -4,7 +4,7 @@ description = "Lints and suggestions for the Nix programming language" edition.workspace = true license.workspace = true name = "statix" -version = "0.5.8" +version = "0.6.0" [lib] name = "statix" diff --git a/bin/src/config.rs b/bin/src/config.rs index 7764d603..678e216a 100644 --- a/bin/src/config.rs +++ b/bin/src/config.rs @@ -13,7 +13,7 @@ use serde::{Deserialize, Serialize}; use vfs::ReadOnlyVfs; #[derive(Parser, Debug)] -#[clap(version, author, about)] +#[clap(author, about)] pub struct Opts { #[clap(subcommand)] pub cmd: SubCommand, @@ -38,7 +38,7 @@ pub enum SubCommand { #[derive(Parser, Debug)] pub struct Check { /// File or directory to run check on - #[clap(default_value = ".", parse(from_os_str))] + #[clap(default_value = ".")] target: PathBuf, /// Globs of file patterns to skip @@ -52,7 +52,7 @@ pub struct Check { /// Output format. #[cfg_attr(feature = "json", doc = "Supported values: stderr, errfmt, json")] #[cfg_attr(not(feature = "json"), doc = "Supported values: stderr, errfmt")] - #[clap(short = 'o', long, default_value_t, parse(try_from_str))] + #[clap(short = 'o', long, default_value_t)] pub format: OutFormat, /// Path to statix.toml or its parent directory @@ -87,7 +87,7 @@ impl Check { #[derive(Parser, Debug)] pub struct Fix { /// File or directory to run fix on - #[clap(default_value = ".", parse(from_os_str))] + #[clap(default_value = ".")] target: PathBuf, /// Globs of file patterns to skip @@ -153,12 +153,11 @@ impl Fix { #[derive(Parser, Debug)] pub struct Single { /// File to run single-fix on - #[clap(parse(from_os_str))] pub target: Option, /// Position to attempt a fix at - #[clap(short, long, parse(try_from_str = parse_line_col))] - pub position: (usize, usize), + #[clap(short, long)] + pub position: Position, /// Do not fix files in place, display a diff instead #[clap(short, long = "dry-run")] @@ -205,8 +204,7 @@ impl Single { #[derive(Parser, Debug)] pub struct Explain { /// Warning code to explain - #[clap(parse(try_from_str = parse_warning_code))] - pub target: u32, + pub target: WarningCode, } #[derive(Parser, Debug)] @@ -306,34 +304,52 @@ impl ConfFile { } } -fn parse_line_col(src: &str) -> Result<(usize, usize), ConfigErr> { - let parts = src.split(','); - match parts.collect::>().as_slice() { - [line, col] => { - let do_parse = |val: &str| { - val.parse::() - .map_err(|_| ConfigErr::InvalidPosition(src.to_owned())) - }; - let l = do_parse(line)?; - let c = do_parse(col)?; - Ok((l, c)) +#[derive(Debug, Clone, Copy)] +pub struct Position { + pub line: usize, + pub col: usize, +} + +impl FromStr for Position { + type Err = ConfigErr; + + fn from_str(src: &str) -> Result { + let parts = src.split(','); + match parts.collect::>().as_slice() { + [line, col] => { + let do_parse = |val: &str| { + val.parse::() + .map_err(|_| ConfigErr::InvalidPosition(src.to_owned())) + }; + let l = do_parse(line)?; + let c = do_parse(col)?; + Ok(Self { line: l, col: c }) + } + _ => Err(ConfigErr::InvalidPosition(src.to_owned())), } - _ => Err(ConfigErr::InvalidPosition(src.to_owned())), } } -fn parse_warning_code(src: &str) -> Result { - let mut char_stream = src.chars(); - let severity = char_stream - .next() - .ok_or_else(|| ConfigErr::InvalidWarningCode(src.to_owned()))? - .to_ascii_lowercase(); - match severity { - 'w' => char_stream - .collect::() - .parse::() - .map_err(|_| ConfigErr::InvalidWarningCode(src.to_owned())), - _ => Ok(0), +#[derive(Debug, Clone, Copy)] +pub struct WarningCode(pub u32); + +impl FromStr for WarningCode { + type Err = ConfigErr; + + fn from_str(src: &str) -> Result { + let mut char_stream = src.chars(); + let severity = char_stream + .next() + .ok_or_else(|| ConfigErr::InvalidWarningCode(src.to_owned()))? + .to_ascii_lowercase(); + match severity { + 'w' => char_stream + .collect::() + .parse::() + .map(Self) + .map_err(|_| ConfigErr::InvalidWarningCode(src.to_owned())), + _ => Ok(Self(0)), + } } } diff --git a/bin/src/explain.rs b/bin/src/explain.rs index 6a452da8..60df7ed6 100644 --- a/bin/src/explain.rs +++ b/bin/src/explain.rs @@ -1,15 +1,15 @@ -use crate::{err::ExplainErr, utils}; +use crate::{config::WarningCode, err::ExplainErr, utils}; -pub fn explain(code: u32) -> Result<&'static str, ExplainErr> { +pub fn explain(code: WarningCode) -> Result<&'static str, ExplainErr> { let lints = utils::lint_map(); - match code { + match code.0 { 0 => Ok("syntax error"), _ => lints .values() .flatten() - .find(|l| l.code() == code) + .find(|l| l.code() == code.0) .map(|l| l.explanation()) - .ok_or(ExplainErr::LintNotFound(code)), + .ok_or(ExplainErr::LintNotFound(code.0)), } } diff --git a/bin/src/fix.rs b/bin/src/fix.rs index d14c806d..faaabb6b 100644 --- a/bin/src/fix.rs +++ b/bin/src/fix.rs @@ -90,9 +90,11 @@ pub mod main { let entry = vfs.iter().next().unwrap(); let path = entry.file_path.display().to_string(); let original_src = entry.contents; - let (line, col) = single_config.position; - match (single_config.out(), super::single(line, col, original_src)) { + match ( + single_config.out(), + super::single(single_config.position, original_src), + ) { (FixOut::Diff, single_result) => { let fixed_src = single_result .map(|r| r.src) diff --git a/bin/src/fix/single.rs b/bin/src/fix/single.rs index 5b8762d7..de21124f 100644 --- a/bin/src/fix/single.rs +++ b/bin/src/fix/single.rs @@ -3,27 +3,29 @@ use std::{borrow::Cow, convert::TryFrom}; use lib::Report; use rnix::{Root, TextSize, WalkEvent}; -use crate::{err::SingleFixErr, fix::Source, utils}; +use crate::{config::Position, err::SingleFixErr, fix::Source, utils}; pub struct SingleFixResult<'δ> { pub src: Source<'δ>, } -fn pos_to_byte(line: usize, col: usize, src: &str) -> Result { - let mut byte: TextSize = TextSize::of(""); - for (l, _) in src - .split_inclusive('\n') - .zip(1..) - .take_while(|(_, i)| *i < line) - { - byte += TextSize::of(l); - } - byte += TextSize::try_from(col).map_err(|_| SingleFixErr::Conversion(col))?; - - if usize::from(byte) >= src.len() { - Err(SingleFixErr::OutOfBounds(line, col)) - } else { - Ok(byte) +impl Position { + pub(crate) fn to_byte(self, src: &str) -> Result { + let mut byte: TextSize = TextSize::of(""); + for (l, _) in src + .split_inclusive('\n') + .zip(1..) + .take_while(|(_, i)| *i < self.line) + { + byte += TextSize::of(l); + } + byte += TextSize::try_from(self.col).map_err(|_| SingleFixErr::Conversion(self.col))?; + + if usize::from(byte) >= src.len() { + Err(SingleFixErr::OutOfBounds(self.line, self.col)) + } else { + Ok(byte) + } } } @@ -49,9 +51,9 @@ fn find(offset: TextSize, src: &str) -> Result { .ok_or(SingleFixErr::NoOp) } -pub fn single(line: usize, col: usize, src: &str) -> Result, SingleFixErr> { +pub fn single(position: Position, src: &str) -> Result, SingleFixErr> { let mut src = Cow::from(src); - let offset = pos_to_byte(line, col, &src)?; + let offset = position.to_byte(&src)?; let report = find(offset, &src)?; report.apply(src.to_mut()); diff --git a/bin/src/traits.rs b/bin/src/traits.rs index 284adf4b..aebebd1e 100644 --- a/bin/src/traits.rs +++ b/bin/src/traits.rs @@ -1,4 +1,5 @@ use std::{ + env, io::{self, Write}, str, }; @@ -46,6 +47,7 @@ fn write_stderr( lint_result: &LintResult, vfs: &ReadOnlyVfs, ) -> io::Result<()> { + let no_color = env::var("NO_COLOR").is_ok(); let file_id = lint_result.file_id; let src = str::from_utf8(vfs.get(file_id)).unwrap(); let path = vfs.file_path(file_id); @@ -70,6 +72,7 @@ fn write_stderr( CliReport::build(report_kind, src_id, offset) .with_config( CliConfig::default() + .with_color(!no_color) .with_cross_gap(true) .with_multiline_arrows(false) .with_label_attach(LabelAttach::Middle) @@ -78,11 +81,16 @@ fn write_stderr( .with_message(report.note) .with_code(report.code), |cli_report, diagnostic| { - cli_report.with_label( - Label::new((src_id, range(diagnostic.at))) + let mut label = Label::new((src_id, range(diagnostic.at))); + if no_color { + label = + label.with_message(diagnostic.message.split('`').collect::()); + } else { + label = label .with_message(colorize(&diagnostic.message)) - .with_color(Color::Magenta), - ) + .with_color(Color::Magenta); + } + cli_report.with_label(label) }, ) .finish() diff --git a/bin/tests/bool_comparison.rs b/bin/tests/bool_comparison.rs index a2c889fc..7265b13b 100644 --- a/bin/tests/bool_comparison.rs +++ b/bin/tests/bool_comparison.rs @@ -5,26 +5,22 @@ use macros::generate_tests; generate_tests! { rule: bool_comparison, expressions: [ - // trivial - "a == true", - "b == true", - "true == c", - "true == d", - // not equals - "e != true", - "f != false", - "true != g", - "false != h", // non-matches "i == j", "k != l", - // both sides bool + "a == false", + "b == true", + "false != c", + "true == d", + + // matches + "false != false", + "false != true", + "true != false", + "true != true", "false == false", "false == true", "true == false", "true == true", - // has attr - "false == m ? n", - "true == o ? p", ], } diff --git a/bin/tests/manual_inherit_from.rs b/bin/tests/manual_inherit_from.rs index 3d6dd99c..db146396 100644 --- a/bin/tests/manual_inherit_from.rs +++ b/bin/tests/manual_inherit_from.rs @@ -8,5 +8,7 @@ generate_tests! { "let a.b = 2; in { b = a.b; }", "let a.b = 2; in { c = a.c; }", "let a.b = 2; in { b = a.c; }", + // don't lint if the rhs expr is more than just an access + "let foo = { }; in { x = foo.x or false; }", ], } diff --git a/bin/tests/snapshots/bool_comparison__fix_01765d342111cdd7f2f68ac70b4a9451e5380adb64ed4d60c851c6ab437bc0ed.snap b/bin/tests/snapshots/bool_comparison__fix_01765d342111cdd7f2f68ac70b4a9451e5380adb64ed4d60c851c6ab437bc0ed.snap new file mode 100644 index 00000000..8ebe24e2 --- /dev/null +++ b/bin/tests/snapshots/bool_comparison__fix_01765d342111cdd7f2f68ac70b4a9451e5380adb64ed4d60c851c6ab437bc0ed.snap @@ -0,0 +1,5 @@ +--- +source: bin/tests/bool_comparison.rs +expression: "\"true != false\"" +--- + diff --git a/bin/tests/snapshots/bool_comparison__fix_101b3f071d9ef6e1c6cddd4b3d4d2a4f7d4cf2764ff5811ee2d532b3ccb45690.snap b/bin/tests/snapshots/bool_comparison__fix_101b3f071d9ef6e1c6cddd4b3d4d2a4f7d4cf2764ff5811ee2d532b3ccb45690.snap deleted file mode 100644 index cc8620ab..00000000 --- a/bin/tests/snapshots/bool_comparison__fix_101b3f071d9ef6e1c6cddd4b3d4d2a4f7d4cf2764ff5811ee2d532b3ccb45690.snap +++ /dev/null @@ -1,9 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"f != false\"" ---- ---- -+++ [fixed] -@@ -1 +1 @@ --f != false -+f diff --git a/bin/tests/snapshots/bool_comparison__fix_3fce60992c69dd4f86be49b4f2898f9ecd8fce2117de78ba9dee164f01ff445b.snap b/bin/tests/snapshots/bool_comparison__fix_3fce60992c69dd4f86be49b4f2898f9ecd8fce2117de78ba9dee164f01ff445b.snap new file mode 100644 index 00000000..255d5192 --- /dev/null +++ b/bin/tests/snapshots/bool_comparison__fix_3fce60992c69dd4f86be49b4f2898f9ecd8fce2117de78ba9dee164f01ff445b.snap @@ -0,0 +1,5 @@ +--- +source: bin/tests/bool_comparison.rs +expression: "\"false != true\"" +--- + diff --git a/bin/tests/snapshots/bool_comparison__fix_43a857afe823ef70b47d4e0fbf00af8951e09a9a9891d29b3ba9e762a2978adb.snap b/bin/tests/snapshots/bool_comparison__fix_43a857afe823ef70b47d4e0fbf00af8951e09a9a9891d29b3ba9e762a2978adb.snap index 211d2458..80460946 100644 --- a/bin/tests/snapshots/bool_comparison__fix_43a857afe823ef70b47d4e0fbf00af8951e09a9a9891d29b3ba9e762a2978adb.snap +++ b/bin/tests/snapshots/bool_comparison__fix_43a857afe823ef70b47d4e0fbf00af8951e09a9a9891d29b3ba9e762a2978adb.snap @@ -2,8 +2,4 @@ source: bin/tests/bool_comparison.rs expression: "\"true == d\"" --- ---- -+++ [fixed] -@@ -1 +1 @@ --true == d -+d + diff --git a/bin/tests/snapshots/bool_comparison__fix_55dfc255fdce66acbcebd803bdc0a33666717f07ceb798a97e29b4fdf1505560.snap b/bin/tests/snapshots/bool_comparison__fix_55dfc255fdce66acbcebd803bdc0a33666717f07ceb798a97e29b4fdf1505560.snap new file mode 100644 index 00000000..f4c55a33 --- /dev/null +++ b/bin/tests/snapshots/bool_comparison__fix_55dfc255fdce66acbcebd803bdc0a33666717f07ceb798a97e29b4fdf1505560.snap @@ -0,0 +1,5 @@ +--- +source: bin/tests/bool_comparison.rs +expression: "\"a == false\"" +--- + diff --git a/bin/tests/snapshots/bool_comparison__fix_5d2c71eef69cc07e519dc3646f786ba7a32f5546c3a2194d2636a2684391e3f1.snap b/bin/tests/snapshots/bool_comparison__fix_5d2c71eef69cc07e519dc3646f786ba7a32f5546c3a2194d2636a2684391e3f1.snap index cb1c9f70..4eaad332 100644 --- a/bin/tests/snapshots/bool_comparison__fix_5d2c71eef69cc07e519dc3646f786ba7a32f5546c3a2194d2636a2684391e3f1.snap +++ b/bin/tests/snapshots/bool_comparison__fix_5d2c71eef69cc07e519dc3646f786ba7a32f5546c3a2194d2636a2684391e3f1.snap @@ -2,8 +2,4 @@ source: bin/tests/bool_comparison.rs expression: "\"false == false\"" --- ---- -+++ [fixed] -@@ -1 +1 @@ --false == false -+!false + diff --git a/bin/tests/snapshots/bool_comparison__fix_630b66ca8810d52f4e68ed1c8d68db36bce21a1cb65b60ec15b901e87b62c13a.snap b/bin/tests/snapshots/bool_comparison__fix_630b66ca8810d52f4e68ed1c8d68db36bce21a1cb65b60ec15b901e87b62c13a.snap deleted file mode 100644 index f27140be..00000000 --- a/bin/tests/snapshots/bool_comparison__fix_630b66ca8810d52f4e68ed1c8d68db36bce21a1cb65b60ec15b901e87b62c13a.snap +++ /dev/null @@ -1,9 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"false != h\"" ---- ---- -+++ [fixed] -@@ -1 +1 @@ --false != h -+h diff --git a/bin/tests/snapshots/bool_comparison__fix_82b623ef0ecd1e0e70c1dbe39f02832657a82dd5a58392f23345b22467a89b1a.snap b/bin/tests/snapshots/bool_comparison__fix_82b623ef0ecd1e0e70c1dbe39f02832657a82dd5a58392f23345b22467a89b1a.snap index 745004ae..1e760c87 100644 --- a/bin/tests/snapshots/bool_comparison__fix_82b623ef0ecd1e0e70c1dbe39f02832657a82dd5a58392f23345b22467a89b1a.snap +++ b/bin/tests/snapshots/bool_comparison__fix_82b623ef0ecd1e0e70c1dbe39f02832657a82dd5a58392f23345b22467a89b1a.snap @@ -2,8 +2,4 @@ source: bin/tests/bool_comparison.rs expression: "\"true == true\"" --- ---- -+++ [fixed] -@@ -1 +1 @@ --true == true -+true + diff --git a/bin/tests/snapshots/bool_comparison__fix_852249844e4f5e03707d323181ca8645f39f390d9a91490dd6926c3df73f1912.snap b/bin/tests/snapshots/bool_comparison__fix_852249844e4f5e03707d323181ca8645f39f390d9a91490dd6926c3df73f1912.snap new file mode 100644 index 00000000..ef641d5d --- /dev/null +++ b/bin/tests/snapshots/bool_comparison__fix_852249844e4f5e03707d323181ca8645f39f390d9a91490dd6926c3df73f1912.snap @@ -0,0 +1,5 @@ +--- +source: bin/tests/bool_comparison.rs +expression: "\"true != true\"" +--- + diff --git a/bin/tests/snapshots/bool_comparison__fix_953514e1d8b3ed9ecc2a23a82ab52f3b71eb218061d8a678afbbdb09b717cd0f.snap b/bin/tests/snapshots/bool_comparison__fix_953514e1d8b3ed9ecc2a23a82ab52f3b71eb218061d8a678afbbdb09b717cd0f.snap new file mode 100644 index 00000000..fa8ce5ab --- /dev/null +++ b/bin/tests/snapshots/bool_comparison__fix_953514e1d8b3ed9ecc2a23a82ab52f3b71eb218061d8a678afbbdb09b717cd0f.snap @@ -0,0 +1,5 @@ +--- +source: bin/tests/bool_comparison.rs +expression: "\"false != c\"" +--- + diff --git a/bin/tests/snapshots/bool_comparison__fix_9f48ebd94e1733d7ccda130d62830499b7344b794644163af528b0c834c5cca4.snap b/bin/tests/snapshots/bool_comparison__fix_9f48ebd94e1733d7ccda130d62830499b7344b794644163af528b0c834c5cca4.snap deleted file mode 100644 index 672e1780..00000000 --- a/bin/tests/snapshots/bool_comparison__fix_9f48ebd94e1733d7ccda130d62830499b7344b794644163af528b0c834c5cca4.snap +++ /dev/null @@ -1,9 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"true == c\"" ---- ---- -+++ [fixed] -@@ -1 +1 @@ --true == c -+c diff --git a/bin/tests/snapshots/bool_comparison__fix_a09de9082d480f3e54de569de2789ebfee65a1ecbd31dcbdfc543b8b13e4bda4.snap b/bin/tests/snapshots/bool_comparison__fix_a09de9082d480f3e54de569de2789ebfee65a1ecbd31dcbdfc543b8b13e4bda4.snap deleted file mode 100644 index b9e508b9..00000000 --- a/bin/tests/snapshots/bool_comparison__fix_a09de9082d480f3e54de569de2789ebfee65a1ecbd31dcbdfc543b8b13e4bda4.snap +++ /dev/null @@ -1,9 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"true != g\"" ---- ---- -+++ [fixed] -@@ -1 +1 @@ --true != g -+!g diff --git a/bin/tests/snapshots/bool_comparison__fix_a11a365119d2c64750d4253426c99db3e016d21e6183a706845dfed17d803393.snap b/bin/tests/snapshots/bool_comparison__fix_a11a365119d2c64750d4253426c99db3e016d21e6183a706845dfed17d803393.snap index 4a9c9830..0c3d35ee 100644 --- a/bin/tests/snapshots/bool_comparison__fix_a11a365119d2c64750d4253426c99db3e016d21e6183a706845dfed17d803393.snap +++ b/bin/tests/snapshots/bool_comparison__fix_a11a365119d2c64750d4253426c99db3e016d21e6183a706845dfed17d803393.snap @@ -2,8 +2,4 @@ source: bin/tests/bool_comparison.rs expression: "\"b == true\"" --- ---- -+++ [fixed] -@@ -1 +1 @@ --b == true -+b + diff --git a/bin/tests/snapshots/bool_comparison__fix_a14c6695accf2da707eaeb76ded232840736b9034ef1b55d1c8c92b9f5098a14.snap b/bin/tests/snapshots/bool_comparison__fix_a14c6695accf2da707eaeb76ded232840736b9034ef1b55d1c8c92b9f5098a14.snap deleted file mode 100644 index 59830241..00000000 --- a/bin/tests/snapshots/bool_comparison__fix_a14c6695accf2da707eaeb76ded232840736b9034ef1b55d1c8c92b9f5098a14.snap +++ /dev/null @@ -1,9 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"false == m ? n\"" ---- ---- -+++ [fixed] -@@ -1 +1 @@ --false == m ? n -+!m ? n diff --git a/bin/tests/snapshots/bool_comparison__fix_a30c834e61da781cbcbc0c95b79ab0a51a81f1fdc5a5d885d778f43d268ed2b3.snap b/bin/tests/snapshots/bool_comparison__fix_a30c834e61da781cbcbc0c95b79ab0a51a81f1fdc5a5d885d778f43d268ed2b3.snap deleted file mode 100644 index bcf6e72c..00000000 --- a/bin/tests/snapshots/bool_comparison__fix_a30c834e61da781cbcbc0c95b79ab0a51a81f1fdc5a5d885d778f43d268ed2b3.snap +++ /dev/null @@ -1,9 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"a == true\"" ---- ---- -+++ [fixed] -@@ -1 +1 @@ --a == true -+a diff --git a/bin/tests/snapshots/bool_comparison__fix_a83e7884e4c039d6517795734c6cab32d5e69473f7a6b6fe660eec020d70993d.snap b/bin/tests/snapshots/bool_comparison__fix_a83e7884e4c039d6517795734c6cab32d5e69473f7a6b6fe660eec020d70993d.snap deleted file mode 100644 index 9ceb9645..00000000 --- a/bin/tests/snapshots/bool_comparison__fix_a83e7884e4c039d6517795734c6cab32d5e69473f7a6b6fe660eec020d70993d.snap +++ /dev/null @@ -1,9 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"true == o ? p\"" ---- ---- -+++ [fixed] -@@ -1 +1 @@ --true == o ? p -+o ? p diff --git a/bin/tests/snapshots/bool_comparison__fix_ba56854c55bd3954b56d4e0c3d32b65cd144d55b060637c5ff8085d81bef6c49.snap b/bin/tests/snapshots/bool_comparison__fix_ba56854c55bd3954b56d4e0c3d32b65cd144d55b060637c5ff8085d81bef6c49.snap index d5e0a1e4..f0726958 100644 --- a/bin/tests/snapshots/bool_comparison__fix_ba56854c55bd3954b56d4e0c3d32b65cd144d55b060637c5ff8085d81bef6c49.snap +++ b/bin/tests/snapshots/bool_comparison__fix_ba56854c55bd3954b56d4e0c3d32b65cd144d55b060637c5ff8085d81bef6c49.snap @@ -2,8 +2,4 @@ source: bin/tests/bool_comparison.rs expression: "\"false == true\"" --- ---- -+++ [fixed] -@@ -1 +1 @@ --false == true -+!true + diff --git a/bin/tests/snapshots/bool_comparison__fix_c031ce4a7d754ef42071e72da7d6bf4b645ebdaf948399be54f775686a58347b.snap b/bin/tests/snapshots/bool_comparison__fix_c031ce4a7d754ef42071e72da7d6bf4b645ebdaf948399be54f775686a58347b.snap deleted file mode 100644 index 87f4adba..00000000 --- a/bin/tests/snapshots/bool_comparison__fix_c031ce4a7d754ef42071e72da7d6bf4b645ebdaf948399be54f775686a58347b.snap +++ /dev/null @@ -1,9 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"e != true\"" ---- ---- -+++ [fixed] -@@ -1 +1 @@ --e != true -+!e diff --git a/bin/tests/snapshots/bool_comparison__fix_e242c6e0c4298e00ab2cae2f89de63cc77e833cf6ad2c8eb1047a38df7f25564.snap b/bin/tests/snapshots/bool_comparison__fix_e242c6e0c4298e00ab2cae2f89de63cc77e833cf6ad2c8eb1047a38df7f25564.snap new file mode 100644 index 00000000..8a10b0ed --- /dev/null +++ b/bin/tests/snapshots/bool_comparison__fix_e242c6e0c4298e00ab2cae2f89de63cc77e833cf6ad2c8eb1047a38df7f25564.snap @@ -0,0 +1,5 @@ +--- +source: bin/tests/bool_comparison.rs +expression: "\"false != false\"" +--- + diff --git a/bin/tests/snapshots/bool_comparison__fix_eb450df0fb6d76e9df94f175a6b87a7c1a667495e18432ed8f38540fd051cec1.snap b/bin/tests/snapshots/bool_comparison__fix_eb450df0fb6d76e9df94f175a6b87a7c1a667495e18432ed8f38540fd051cec1.snap index 5e06117c..8b570f8a 100644 --- a/bin/tests/snapshots/bool_comparison__fix_eb450df0fb6d76e9df94f175a6b87a7c1a667495e18432ed8f38540fd051cec1.snap +++ b/bin/tests/snapshots/bool_comparison__fix_eb450df0fb6d76e9df94f175a6b87a7c1a667495e18432ed8f38540fd051cec1.snap @@ -2,8 +2,4 @@ source: bin/tests/bool_comparison.rs expression: "\"true == false\"" --- ---- -+++ [fixed] -@@ -1 +1 @@ --true == false -+false + diff --git a/bin/tests/snapshots/bool_comparison__lint_01765d342111cdd7f2f68ac70b4a9451e5380adb64ed4d60c851c6ab437bc0ed.snap b/bin/tests/snapshots/bool_comparison__lint_01765d342111cdd7f2f68ac70b4a9451e5380adb64ed4d60c851c6ab437bc0ed.snap new file mode 100644 index 00000000..ee33b785 --- /dev/null +++ b/bin/tests/snapshots/bool_comparison__lint_01765d342111cdd7f2f68ac70b4a9451e5380adb64ed4d60c851c6ab437bc0ed.snap @@ -0,0 +1,11 @@ +--- +source: bin/tests/bool_comparison.rs +expression: "\"true != false\"" +--- +[W01] Warning: Equality comparison between boolean literals + ╭─[:1:1] + │ + 1 │ true != false + · ──────┬────── + · ╰──────── Equality comparison between boolean literals +───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_101b3f071d9ef6e1c6cddd4b3d4d2a4f7d4cf2764ff5811ee2d532b3ccb45690.snap b/bin/tests/snapshots/bool_comparison__lint_101b3f071d9ef6e1c6cddd4b3d4d2a4f7d4cf2764ff5811ee2d532b3ccb45690.snap deleted file mode 100644 index e3f5206f..00000000 --- a/bin/tests/snapshots/bool_comparison__lint_101b3f071d9ef6e1c6cddd4b3d4d2a4f7d4cf2764ff5811ee2d532b3ccb45690.snap +++ /dev/null @@ -1,11 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"f != false\"" ---- -[W01] Warning: Unnecessary comparison with boolean - ╭─[:1:1] - │ - 1 │ f != false - · ─────┬──── - · ╰────── Comparing f with boolean literal false -───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_3fce60992c69dd4f86be49b4f2898f9ecd8fce2117de78ba9dee164f01ff445b.snap b/bin/tests/snapshots/bool_comparison__lint_3fce60992c69dd4f86be49b4f2898f9ecd8fce2117de78ba9dee164f01ff445b.snap new file mode 100644 index 00000000..c530e857 --- /dev/null +++ b/bin/tests/snapshots/bool_comparison__lint_3fce60992c69dd4f86be49b4f2898f9ecd8fce2117de78ba9dee164f01ff445b.snap @@ -0,0 +1,11 @@ +--- +source: bin/tests/bool_comparison.rs +expression: "\"false != true\"" +--- +[W01] Warning: Equality comparison between boolean literals + ╭─[:1:1] + │ + 1 │ false != true + · ──────┬────── + · ╰──────── Equality comparison between boolean literals +───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_43a857afe823ef70b47d4e0fbf00af8951e09a9a9891d29b3ba9e762a2978adb.snap b/bin/tests/snapshots/bool_comparison__lint_43a857afe823ef70b47d4e0fbf00af8951e09a9a9891d29b3ba9e762a2978adb.snap index f2923f30..80460946 100644 --- a/bin/tests/snapshots/bool_comparison__lint_43a857afe823ef70b47d4e0fbf00af8951e09a9a9891d29b3ba9e762a2978adb.snap +++ b/bin/tests/snapshots/bool_comparison__lint_43a857afe823ef70b47d4e0fbf00af8951e09a9a9891d29b3ba9e762a2978adb.snap @@ -2,10 +2,4 @@ source: bin/tests/bool_comparison.rs expression: "\"true == d\"" --- -[W01] Warning: Unnecessary comparison with boolean - ╭─[:1:1] - │ - 1 │ true == d - · ────┬──── - · ╰────── Comparing d with boolean literal true -───╯ + diff --git a/bin/tests/snapshots/bool_comparison__lint_55dfc255fdce66acbcebd803bdc0a33666717f07ceb798a97e29b4fdf1505560.snap b/bin/tests/snapshots/bool_comparison__lint_55dfc255fdce66acbcebd803bdc0a33666717f07ceb798a97e29b4fdf1505560.snap new file mode 100644 index 00000000..f4c55a33 --- /dev/null +++ b/bin/tests/snapshots/bool_comparison__lint_55dfc255fdce66acbcebd803bdc0a33666717f07ceb798a97e29b4fdf1505560.snap @@ -0,0 +1,5 @@ +--- +source: bin/tests/bool_comparison.rs +expression: "\"a == false\"" +--- + diff --git a/bin/tests/snapshots/bool_comparison__lint_5d2c71eef69cc07e519dc3646f786ba7a32f5546c3a2194d2636a2684391e3f1.snap b/bin/tests/snapshots/bool_comparison__lint_5d2c71eef69cc07e519dc3646f786ba7a32f5546c3a2194d2636a2684391e3f1.snap index bd0f41a5..ab4d42be 100644 --- a/bin/tests/snapshots/bool_comparison__lint_5d2c71eef69cc07e519dc3646f786ba7a32f5546c3a2194d2636a2684391e3f1.snap +++ b/bin/tests/snapshots/bool_comparison__lint_5d2c71eef69cc07e519dc3646f786ba7a32f5546c3a2194d2636a2684391e3f1.snap @@ -2,10 +2,10 @@ source: bin/tests/bool_comparison.rs expression: "\"false == false\"" --- -[W01] Warning: Unnecessary comparison with boolean +[W01] Warning: Equality comparison between boolean literals ╭─[:1:1] │ 1 │ false == false · ───────┬────── - · ╰──────── Comparing false with boolean literal false + · ╰──────── Equality comparison between boolean literals ───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_630b66ca8810d52f4e68ed1c8d68db36bce21a1cb65b60ec15b901e87b62c13a.snap b/bin/tests/snapshots/bool_comparison__lint_630b66ca8810d52f4e68ed1c8d68db36bce21a1cb65b60ec15b901e87b62c13a.snap deleted file mode 100644 index 76e69512..00000000 --- a/bin/tests/snapshots/bool_comparison__lint_630b66ca8810d52f4e68ed1c8d68db36bce21a1cb65b60ec15b901e87b62c13a.snap +++ /dev/null @@ -1,11 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"false != h\"" ---- -[W01] Warning: Unnecessary comparison with boolean - ╭─[:1:1] - │ - 1 │ false != h - · ─────┬──── - · ╰────── Comparing h with boolean literal false -───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_82b623ef0ecd1e0e70c1dbe39f02832657a82dd5a58392f23345b22467a89b1a.snap b/bin/tests/snapshots/bool_comparison__lint_82b623ef0ecd1e0e70c1dbe39f02832657a82dd5a58392f23345b22467a89b1a.snap index cd7a4249..ce2d6529 100644 --- a/bin/tests/snapshots/bool_comparison__lint_82b623ef0ecd1e0e70c1dbe39f02832657a82dd5a58392f23345b22467a89b1a.snap +++ b/bin/tests/snapshots/bool_comparison__lint_82b623ef0ecd1e0e70c1dbe39f02832657a82dd5a58392f23345b22467a89b1a.snap @@ -2,10 +2,10 @@ source: bin/tests/bool_comparison.rs expression: "\"true == true\"" --- -[W01] Warning: Unnecessary comparison with boolean +[W01] Warning: Equality comparison between boolean literals ╭─[:1:1] │ 1 │ true == true · ──────┬───── - · ╰─────── Comparing true with boolean literal true + · ╰─────── Equality comparison between boolean literals ───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_852249844e4f5e03707d323181ca8645f39f390d9a91490dd6926c3df73f1912.snap b/bin/tests/snapshots/bool_comparison__lint_852249844e4f5e03707d323181ca8645f39f390d9a91490dd6926c3df73f1912.snap new file mode 100644 index 00000000..fe48751f --- /dev/null +++ b/bin/tests/snapshots/bool_comparison__lint_852249844e4f5e03707d323181ca8645f39f390d9a91490dd6926c3df73f1912.snap @@ -0,0 +1,11 @@ +--- +source: bin/tests/bool_comparison.rs +expression: "\"true != true\"" +--- +[W01] Warning: Equality comparison between boolean literals + ╭─[:1:1] + │ + 1 │ true != true + · ──────┬───── + · ╰─────── Equality comparison between boolean literals +───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_953514e1d8b3ed9ecc2a23a82ab52f3b71eb218061d8a678afbbdb09b717cd0f.snap b/bin/tests/snapshots/bool_comparison__lint_953514e1d8b3ed9ecc2a23a82ab52f3b71eb218061d8a678afbbdb09b717cd0f.snap new file mode 100644 index 00000000..fa8ce5ab --- /dev/null +++ b/bin/tests/snapshots/bool_comparison__lint_953514e1d8b3ed9ecc2a23a82ab52f3b71eb218061d8a678afbbdb09b717cd0f.snap @@ -0,0 +1,5 @@ +--- +source: bin/tests/bool_comparison.rs +expression: "\"false != c\"" +--- + diff --git a/bin/tests/snapshots/bool_comparison__lint_9f48ebd94e1733d7ccda130d62830499b7344b794644163af528b0c834c5cca4.snap b/bin/tests/snapshots/bool_comparison__lint_9f48ebd94e1733d7ccda130d62830499b7344b794644163af528b0c834c5cca4.snap deleted file mode 100644 index cf663e7f..00000000 --- a/bin/tests/snapshots/bool_comparison__lint_9f48ebd94e1733d7ccda130d62830499b7344b794644163af528b0c834c5cca4.snap +++ /dev/null @@ -1,11 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"true == c\"" ---- -[W01] Warning: Unnecessary comparison with boolean - ╭─[:1:1] - │ - 1 │ true == c - · ────┬──── - · ╰────── Comparing c with boolean literal true -───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_a09de9082d480f3e54de569de2789ebfee65a1ecbd31dcbdfc543b8b13e4bda4.snap b/bin/tests/snapshots/bool_comparison__lint_a09de9082d480f3e54de569de2789ebfee65a1ecbd31dcbdfc543b8b13e4bda4.snap deleted file mode 100644 index 9251f714..00000000 --- a/bin/tests/snapshots/bool_comparison__lint_a09de9082d480f3e54de569de2789ebfee65a1ecbd31dcbdfc543b8b13e4bda4.snap +++ /dev/null @@ -1,11 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"true != g\"" ---- -[W01] Warning: Unnecessary comparison with boolean - ╭─[:1:1] - │ - 1 │ true != g - · ────┬──── - · ╰────── Comparing g with boolean literal true -───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_a11a365119d2c64750d4253426c99db3e016d21e6183a706845dfed17d803393.snap b/bin/tests/snapshots/bool_comparison__lint_a11a365119d2c64750d4253426c99db3e016d21e6183a706845dfed17d803393.snap index 9ae1c7be..0c3d35ee 100644 --- a/bin/tests/snapshots/bool_comparison__lint_a11a365119d2c64750d4253426c99db3e016d21e6183a706845dfed17d803393.snap +++ b/bin/tests/snapshots/bool_comparison__lint_a11a365119d2c64750d4253426c99db3e016d21e6183a706845dfed17d803393.snap @@ -2,10 +2,4 @@ source: bin/tests/bool_comparison.rs expression: "\"b == true\"" --- -[W01] Warning: Unnecessary comparison with boolean - ╭─[:1:1] - │ - 1 │ b == true - · ────┬──── - · ╰────── Comparing b with boolean literal true -───╯ + diff --git a/bin/tests/snapshots/bool_comparison__lint_a14c6695accf2da707eaeb76ded232840736b9034ef1b55d1c8c92b9f5098a14.snap b/bin/tests/snapshots/bool_comparison__lint_a14c6695accf2da707eaeb76ded232840736b9034ef1b55d1c8c92b9f5098a14.snap deleted file mode 100644 index b3408305..00000000 --- a/bin/tests/snapshots/bool_comparison__lint_a14c6695accf2da707eaeb76ded232840736b9034ef1b55d1c8c92b9f5098a14.snap +++ /dev/null @@ -1,11 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"false == m ? n\"" ---- -[W01] Warning: Unnecessary comparison with boolean - ╭─[:1:1] - │ - 1 │ false == m ? n - · ───────┬────── - · ╰──────── Comparing m ? n with boolean literal false -───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_a30c834e61da781cbcbc0c95b79ab0a51a81f1fdc5a5d885d778f43d268ed2b3.snap b/bin/tests/snapshots/bool_comparison__lint_a30c834e61da781cbcbc0c95b79ab0a51a81f1fdc5a5d885d778f43d268ed2b3.snap deleted file mode 100644 index 8dba507a..00000000 --- a/bin/tests/snapshots/bool_comparison__lint_a30c834e61da781cbcbc0c95b79ab0a51a81f1fdc5a5d885d778f43d268ed2b3.snap +++ /dev/null @@ -1,11 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"a == true\"" ---- -[W01] Warning: Unnecessary comparison with boolean - ╭─[:1:1] - │ - 1 │ a == true - · ────┬──── - · ╰────── Comparing a with boolean literal true -───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_a83e7884e4c039d6517795734c6cab32d5e69473f7a6b6fe660eec020d70993d.snap b/bin/tests/snapshots/bool_comparison__lint_a83e7884e4c039d6517795734c6cab32d5e69473f7a6b6fe660eec020d70993d.snap deleted file mode 100644 index 1100232c..00000000 --- a/bin/tests/snapshots/bool_comparison__lint_a83e7884e4c039d6517795734c6cab32d5e69473f7a6b6fe660eec020d70993d.snap +++ /dev/null @@ -1,11 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"true == o ? p\"" ---- -[W01] Warning: Unnecessary comparison with boolean - ╭─[:1:1] - │ - 1 │ true == o ? p - · ──────┬────── - · ╰──────── Comparing o ? p with boolean literal true -───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_ba56854c55bd3954b56d4e0c3d32b65cd144d55b060637c5ff8085d81bef6c49.snap b/bin/tests/snapshots/bool_comparison__lint_ba56854c55bd3954b56d4e0c3d32b65cd144d55b060637c5ff8085d81bef6c49.snap index a75666af..aca796da 100644 --- a/bin/tests/snapshots/bool_comparison__lint_ba56854c55bd3954b56d4e0c3d32b65cd144d55b060637c5ff8085d81bef6c49.snap +++ b/bin/tests/snapshots/bool_comparison__lint_ba56854c55bd3954b56d4e0c3d32b65cd144d55b060637c5ff8085d81bef6c49.snap @@ -2,10 +2,10 @@ source: bin/tests/bool_comparison.rs expression: "\"false == true\"" --- -[W01] Warning: Unnecessary comparison with boolean +[W01] Warning: Equality comparison between boolean literals ╭─[:1:1] │ 1 │ false == true · ──────┬────── - · ╰──────── Comparing true with boolean literal false + · ╰──────── Equality comparison between boolean literals ───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_c031ce4a7d754ef42071e72da7d6bf4b645ebdaf948399be54f775686a58347b.snap b/bin/tests/snapshots/bool_comparison__lint_c031ce4a7d754ef42071e72da7d6bf4b645ebdaf948399be54f775686a58347b.snap deleted file mode 100644 index 223e6657..00000000 --- a/bin/tests/snapshots/bool_comparison__lint_c031ce4a7d754ef42071e72da7d6bf4b645ebdaf948399be54f775686a58347b.snap +++ /dev/null @@ -1,11 +0,0 @@ ---- -source: bin/tests/bool_comparison.rs -expression: "\"e != true\"" ---- -[W01] Warning: Unnecessary comparison with boolean - ╭─[:1:1] - │ - 1 │ e != true - · ────┬──── - · ╰────── Comparing e with boolean literal true -───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_e242c6e0c4298e00ab2cae2f89de63cc77e833cf6ad2c8eb1047a38df7f25564.snap b/bin/tests/snapshots/bool_comparison__lint_e242c6e0c4298e00ab2cae2f89de63cc77e833cf6ad2c8eb1047a38df7f25564.snap new file mode 100644 index 00000000..0dae084d --- /dev/null +++ b/bin/tests/snapshots/bool_comparison__lint_e242c6e0c4298e00ab2cae2f89de63cc77e833cf6ad2c8eb1047a38df7f25564.snap @@ -0,0 +1,11 @@ +--- +source: bin/tests/bool_comparison.rs +expression: "\"false != false\"" +--- +[W01] Warning: Equality comparison between boolean literals + ╭─[:1:1] + │ + 1 │ false != false + · ───────┬────── + · ╰──────── Equality comparison between boolean literals +───╯ diff --git a/bin/tests/snapshots/bool_comparison__lint_eb450df0fb6d76e9df94f175a6b87a7c1a667495e18432ed8f38540fd051cec1.snap b/bin/tests/snapshots/bool_comparison__lint_eb450df0fb6d76e9df94f175a6b87a7c1a667495e18432ed8f38540fd051cec1.snap index 9d3b3d90..e2294751 100644 --- a/bin/tests/snapshots/bool_comparison__lint_eb450df0fb6d76e9df94f175a6b87a7c1a667495e18432ed8f38540fd051cec1.snap +++ b/bin/tests/snapshots/bool_comparison__lint_eb450df0fb6d76e9df94f175a6b87a7c1a667495e18432ed8f38540fd051cec1.snap @@ -2,10 +2,10 @@ source: bin/tests/bool_comparison.rs expression: "\"true == false\"" --- -[W01] Warning: Unnecessary comparison with boolean +[W01] Warning: Equality comparison between boolean literals ╭─[:1:1] │ 1 │ true == false · ──────┬────── - · ╰──────── Comparing false with boolean literal true + · ╰──────── Equality comparison between boolean literals ───╯ diff --git a/bin/tests/snapshots/manual_inherit_from__fix_b169f7b47a1e5a5efcfc052399cd20e9c361b5dcdaeca5c91d7719a2b9561712.snap b/bin/tests/snapshots/manual_inherit_from__fix_b169f7b47a1e5a5efcfc052399cd20e9c361b5dcdaeca5c91d7719a2b9561712.snap new file mode 100644 index 00000000..aebc7f73 --- /dev/null +++ b/bin/tests/snapshots/manual_inherit_from__fix_b169f7b47a1e5a5efcfc052399cd20e9c361b5dcdaeca5c91d7719a2b9561712.snap @@ -0,0 +1,5 @@ +--- +source: bin/tests/manual_inherit_from.rs +expression: "\"let foo = { }; in { x = foo.x or false; }\"" +--- + diff --git a/bin/tests/snapshots/manual_inherit_from__lint_b169f7b47a1e5a5efcfc052399cd20e9c361b5dcdaeca5c91d7719a2b9561712.snap b/bin/tests/snapshots/manual_inherit_from__lint_b169f7b47a1e5a5efcfc052399cd20e9c361b5dcdaeca5c91d7719a2b9561712.snap new file mode 100644 index 00000000..aebc7f73 --- /dev/null +++ b/bin/tests/snapshots/manual_inherit_from__lint_b169f7b47a1e5a5efcfc052399cd20e9c361b5dcdaeca5c91d7719a2b9561712.snap @@ -0,0 +1,5 @@ +--- +source: bin/tests/manual_inherit_from.rs +expression: "\"let foo = { }; in { x = foo.x or false; }\"" +--- + diff --git a/dev-flake/flake.lock b/dev-flake/flake.lock index 5809e505..e33afd40 100644 --- a/dev-flake/flake.lock +++ b/dev-flake/flake.lock @@ -2,11 +2,11 @@ "nodes": { "files": { "locked": { - "lastModified": 1750263550, - "narHash": "sha256-EW/QJ8i/13GgiynBb6zOMxhLU1uEkRqmzbIDEP23yVA=", + "lastModified": 1762767848, + "narHash": "sha256-trF2WXzH57uSkA1zeI8FTz8tU6vPYrklkTjh/7DZy/M=", "owner": "mightyiam", "repo": "files", - "rev": "5f4ef1fd1f9012354a9748be093e277675d10f07", + "rev": "2d9d4937e94006ad8f165dfab9dff87cfab7eb2b", "type": "github" }, "original": { @@ -17,11 +17,11 @@ }, "flake-compat_dedupe": { "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "lastModified": 1767039857, + "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", "owner": "edolstra", "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", "type": "github" }, "original": { @@ -43,11 +43,11 @@ ] }, "locked": { - "lastModified": 1750779888, - "narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=", + "lastModified": 1772024342, + "narHash": "sha256-+eXlIc4/7dE6EcPs9a2DaSY3fTA9AE526hGqkNID3Wg=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d", + "rev": "6e34e97ed9788b17796ee43ccdbaf871a5c2b476", "type": "github" }, "original": { @@ -63,11 +63,11 @@ ] }, "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "lastModified": 1762808025, + "narHash": "sha256-XmjITeZNMTQXGhhww6ed/Wacy2KzD6svioyCX7pkUu4=", "owner": "hercules-ci", "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "rev": "cb5e3fdca1de58ccbc3ef53de65bd372b48f567c", "type": "github" }, "original": { @@ -98,18 +98,15 @@ }, "nixpkgs_dedupe": { "locked": { - "lastModified": 1751949589, - "narHash": "sha256-mgFxAPLWw0Kq+C8P3dRrZrOYEQXOtKuYVlo9xvPntt8=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "9b008d60392981ad674e04016d25619281550a9d", - "type": "github" + "lastModified": 1772479524, + "narHash": "sha256-U+hMRvavBzJYhdWCWGRHCK3bpcKjqTJAnyii3y09uT8=", + "rev": "4215e62dc2cd3bc705b0a423b9719ff6be378a43", + "type": "tarball", + "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre957146.4215e62dc2cd/nixexprs.tar.xz" }, "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" + "type": "tarball", + "url": "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz" } }, "root": { @@ -130,11 +127,11 @@ ] }, "locked": { - "lastModified": 1750931469, - "narHash": "sha256-0IEdQB1nS+uViQw4k3VGUXntjkDp7aAlqcxdewb/hAc=", + "lastModified": 1770228511, + "narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "ac8e6f32e11e9c7f153823abc3ab007f2a65d3e1", + "rev": "337a4fe074be1042a35086f15481d763b8ddc0e7", "type": "github" }, "original": { diff --git a/dev-flake/flake.nix b/dev-flake/flake.nix index f363843e..a43e4244 100644 --- a/dev-flake/flake.nix +++ b/dev-flake/flake.nix @@ -12,7 +12,7 @@ url = "github:nicknovitski/make-shell"; inputs.flake-compat.follows = "flake-compat_dedupe"; }; - nixpkgs_dedupe.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + nixpkgs_dedupe.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"; files.url = "github:mightyiam/files"; flake-compat_dedupe.url = "github:edolstra/flake-compat"; gitignore_dedupe = { diff --git a/docs/release.txt b/docs/release.txt deleted file mode 100644 index 8cc56ef3..00000000 --- a/docs/release.txt +++ /dev/null @@ -1,7 +0,0 @@ -Release checklist: - -- bump version in Cargo.toml -- run `cargo build --release` to bump Cargo.lock -- run nix-build and update cachix cache -- tag commit with latest version -- push tag and commit to all remotes diff --git a/flake-parts/ci.nix b/flake-parts/ci.nix index 998467b1..f46d9d7e 100644 --- a/flake-parts/ci.nix +++ b/flake-parts/ci.nix @@ -2,7 +2,7 @@ let filePaths = { check = ".github/workflows/check.yaml"; - updateFlakeLock = ".github/workflows/update-flake-lock.yaml"; + updateFlakeInputs = ".github/workflows/update-flake-inputs.yaml"; }; ids = { @@ -10,7 +10,10 @@ let getCheckNames = "get-check-names"; check = "check"; }; - steps.getCheckNames = "get-check-names"; + steps = { + getCheckNames = "get-check-names"; + appToken = "app-token"; + }; outputs = { jobs.getCheckNames = "checks"; steps.getCheckNames = "checks"; @@ -28,9 +31,19 @@ let steps = { checkout.uses = "actions/checkout@v4"; - cachixInstallNix = { - uses = "cachix/install-nix-action@v31"; - "with".github_access_token = "\${{ secrets.GITHUB_TOKEN }}"; + installNix = { + uses = "nixbuild/nix-quick-install-action@master"; + "with" = { + nix_conf = '' + keep-env-derivations = true + keep-outputs = true + ''; + github_access_token = "\${{ secrets.GITHUB_TOKEN }}"; + }; + }; + cacheNix = { + uses = "nix-community/cache-nix-action@main"; + "with".primary-key = "nix-\${{ runner.os }}"; }; }; in @@ -56,7 +69,8 @@ in "\${{ steps.${ids.steps.getCheckNames}.outputs.${ids.outputs.steps.getCheckNames} }}"; steps = [ steps.checkout - steps.cachixInstallNix + steps.installNix + steps.cacheNix { id = ids.steps.getCheckNames; run = '' @@ -74,7 +88,8 @@ in "\${{ fromJson(needs.${ids.jobs.getCheckNames}.outputs.${ids.outputs.jobs.getCheckNames}) }}"; steps = [ steps.checkout - steps.cachixInstallNix + steps.installNix + steps.cacheNix { run = '' nix ${nixArgs} build '.#checks.${runner.system}."''${{ matrix.${matrixParam} }}"' @@ -88,7 +103,8 @@ in runs-on = runner.name; steps = [ steps.checkout - steps.cachixInstallNix + steps.installNix + steps.cacheNix { run = "nix-env --install --file default.nix"; } ]; }; @@ -96,29 +112,41 @@ in }; } { - path_ = filePaths.updateFlakeLock; - drv = pkgs.writers.writeJSON "update-flake-lock.yaml" { - name = "Update flake.lock"; + path_ = filePaths.updateFlakeInputs; + drv = pkgs.writers.writeJSON "update-flake-inputs.yaml" { + name = "Update flake inputs"; on = { workflow_dispatch = { }; - schedule = [ { cron = "0 0 * * 5"; } ]; + schedule = [ { cron = "0 0/6 * * *"; } ]; }; jobs.nix-flake-update = { permissions = { contents = "write"; - id-token = "write"; - issues = "write"; pull-requests = "write"; }; runs-on = runner.name; steps = [ - steps.checkout - steps.cachixInstallNix { - uses = "DeterminateSystems/update-flake-lock@main"; + id = ids.steps.appToken; + uses = "actions/create-github-app-token@v1"; + "with" = { + app-id = "\${{ secrets.APP_ID }}"; + private-key = "\${{ secrets.APP_PRIVATE_KEY }}"; + }; + } + ( + steps.checkout + // { + "with".token = "\${{ steps.${ids.steps.appToken}.outputs.token }}"; + } + ) + steps.installNix + steps.cacheNix + { + uses = "mic92/update-flake-inputs@main"; "with" = { - commit-msg = "chore(flake): bump inputs"; - pr-title = "chore(flake): bump inputs"; + github-token = "\${{ steps.${ids.steps.appToken}.outputs.token }}"; + commit-message = "chore(flake): update {{input}}{{in}}"; }; } ]; diff --git a/flake-parts/fmt.nix b/flake-parts/fmt.nix index cb141d93..6624447d 100644 --- a/flake-parts/fmt.nix +++ b/flake-parts/fmt.nix @@ -3,26 +3,31 @@ partitions.dev.module = devPartition: { imports = [ devPartition.inputs.treefmt.flakeModule ]; - perSystem = psArgs: { - pre-commit.settings.hooks.treefmt.enable = true; + perSystem = + psArgs@{ pkgs, ... }: + { + pre-commit.settings.hooks.treefmt.enable = true; - treefmt = { - projectRootFile = "flake.nix"; - programs = { - nixfmt.enable = true; - prettier.enable = true; - taplo = { - enable = true; - settings.formatting = { - reorder_keys = true; - reorder_arrays = true; - reorder_inline_tables = true; - allowed_blank_lines = 1; + treefmt = { + projectRootFile = "flake.nix"; + programs = { + nixfmt = { + enable = true; + package = pkgs.nixfmt; + }; + prettier.enable = true; + taplo = { + enable = true; + settings.formatting = { + reorder_keys = true; + reorder_arrays = true; + reorder_inline_tables = true; + allowed_blank_lines = 1; + }; }; }; + settings.on-unmatched = "fatal"; }; - settings.on-unmatched = "fatal"; }; - }; }; } diff --git a/flake-parts/statix.nix b/flake-parts/statix.nix index 624476fa..5eb80f57 100644 --- a/flake-parts/statix.nix +++ b/flake-parts/statix.nix @@ -1,6 +1,7 @@ { lib, root, + self, ... }: { @@ -10,7 +11,7 @@ packages = { statix = pkgs.rustPlatform.buildRustPackage { pname = "statix"; - inherit ((lib.importTOML (root + "/bin/Cargo.toml")).package) version; + version = self.lastModifiedDate; src = lib.fileset.toSource { inherit root; diff --git a/flake-parts/systems.nix b/flake-parts/systems.nix new file mode 100644 index 00000000..4c0c40c2 --- /dev/null +++ b/flake-parts/systems.nix @@ -0,0 +1,7 @@ +{ + systems = [ + "x86_64-linux" + "aarch64-linux" + "aarch64-darwin" + ]; +} diff --git a/flake.lock b/flake.lock index 3625b0a7..abb2d16e 100644 --- a/flake.lock +++ b/flake.lock @@ -7,11 +7,11 @@ ] }, "locked": { - "lastModified": 1754487366, - "narHash": "sha256-pHYj8gUBapuUzKV/kN/tR3Zvqc7o6gdFB9XKXIp1SQ8=", + "lastModified": 1772408722, + "narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "af66ad14b28a127c5c0f3bbb298218fc63528a18", + "rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3", "type": "github" }, "original": { @@ -22,41 +22,21 @@ }, "nixpkgs": { "locked": { - "lastModified": 1755268003, - "narHash": "sha256-nNaeJjo861wFR0tjHDyCnHs1rbRtrMgxAKMoig9Sj/w=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "32f313e49e42f715491e1ea7b306a87c16fe0388", - "type": "github" + "lastModified": 1772479524, + "narHash": "sha256-U+hMRvavBzJYhdWCWGRHCK3bpcKjqTJAnyii3y09uT8=", + "rev": "4215e62dc2cd3bc705b0a423b9719ff6be378a43", + "type": "tarball", + "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre957146.4215e62dc2cd/nixexprs.tar.xz" }, "original": { - "owner": "nixos", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" + "type": "tarball", + "url": "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz" } }, "root": { "inputs": { "flake-parts": "flake-parts", - "nixpkgs": "nixpkgs", - "systems": "systems" - } - }, - "systems": { - "flake": false, - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" + "nixpkgs": "nixpkgs" } } }, diff --git a/flake.nix b/flake.nix index a2aac82a..0a0a399c 100644 --- a/flake.nix +++ b/flake.nix @@ -10,12 +10,7 @@ inputs.nixpkgs-lib.follows = "nixpkgs"; }; - nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; - - systems = { - url = "github:nix-systems/default"; - flake = false; - }; + nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"; }; outputs = inputs: @@ -23,7 +18,6 @@ { lib, ... }: { _module.args.root = ./.; - systems = import inputs.systems; imports = [ inputs.flake-parts.flakeModules.partitions @@ -41,6 +35,7 @@ ./flake-parts/overlay.nix ./flake-parts/rust.nix ./flake-parts/statix.nix + ./flake-parts/systems.nix ./vim-plugin/flake-part.nix ]; diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 35a87217..abf67d96 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -105,10 +105,12 @@ impl Report { | ParseError::UnexpectedWanted(_, at, _) | ParseError::UnexpectedDoubleBind(at) | ParseError::DuplicatedArgs(at, _) => at, - ParseError::UnexpectedEOF | ParseError::UnexpectedEOFWanted(_) => { - &TextRange::empty(0u32.into()) - } - _ => panic!("report a bug, pepper forgot to handle a parse error"), + ParseError::UnexpectedEOF + | ParseError::UnexpectedEOFWanted(_) + | ParseError::RecursionLimitExceeded => &TextRange::empty(0u32.into()), + _ => panic!( + "if this happened to you, please report an issue titled \"wild ParseError variant appeared\"" + ), }; let mut message = err.to_string(); message diff --git a/lib/src/lints/bool_comparison.rs b/lib/src/lints/bool_comparison.rs index ef95c60a..46510e14 100644 --- a/lib/src/lints/bool_comparison.rs +++ b/lib/src/lints/bool_comparison.rs @@ -1,34 +1,23 @@ -use crate::{Metadata, Report, Rule, Suggestion, make}; +use crate::{Metadata, Report, Rule}; use macros::lint; use rnix::{ NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, - ast::{BinOp, BinOpKind, Ident}, + ast::{BinOp, Ident}, }; use rowan::ast::AstNode as _; /// ## What it does -/// Checks for expressions of the form `x == true`, `x != true` and -/// suggests using the variable directly. -/// -/// ## Why is this bad? -/// Unnecessary code. +/// Checks for equality comparison between two boolean literals. /// /// ## Example -/// Instead of checking the value of `x`: /// /// ```nix -/// if x == true then 0 else 1 -/// ``` -/// -/// Use `x` directly: -/// -/// ```nix -/// if x then 0 else 1 +/// false == false /// ``` #[lint( name = "bool_comparison", - note = "Unnecessary comparison with boolean", + note = "Equality comparison between boolean literals", code = 1, match_with = SyntaxKind::NODE_BIN_OP )] @@ -41,46 +30,16 @@ impl Rule for BoolComparison { }; let bin_expr = BinOp::cast(node.clone())?; let (lhs, rhs) = (bin_expr.lhs()?, bin_expr.rhs()?); - let (lhs, rhs) = (lhs.syntax(), rhs.syntax()); - let op = EqualityBinOpKind::try_from(bin_expr.operator()?)?; - let (bool_side, non_bool_side): (NixBoolean, &SyntaxNode) = - match (boolean_ident(lhs), boolean_ident(rhs)) { - (None, None) => return None, - (None, Some(bool)) => (bool, lhs), - (Some(bool), _) => (bool, rhs), - }; + if boolean_ident(lhs.syntax()).is_none() || boolean_ident(rhs.syntax()).is_none() { + return None; + } - let replacement = match (&bool_side, op) { - (NixBoolean::True, EqualityBinOpKind::Equal) - | (NixBoolean::False, EqualityBinOpKind::NotEqual) => { - // `a == true`, `a != false` replace with just `a` - non_bool_side.clone() - } - (NixBoolean::True, EqualityBinOpKind::NotEqual) - | (NixBoolean::False, EqualityBinOpKind::Equal) => { - // `a != true`, `a == false` replace with `!a` - match non_bool_side.kind() { - SyntaxKind::NODE_APPLY - | SyntaxKind::NODE_PAREN - | SyntaxKind::NODE_IDENT - | SyntaxKind::NODE_HAS_ATTR => { - // do not parenthsize the replacement - make::unary_not(non_bool_side).syntax().clone() - } - _ => { - let parens = make::parenthesize(non_bool_side); - make::unary_not(parens.syntax()).syntax().clone() - } - } - } - }; let at = node.text_range(); - Some(self.report().suggest( - at, - format!("Comparing `{non_bool_side}` with boolean literal `{bool_side}`"), - Suggestion::with_replacement(at, replacement), - )) + Some( + self.report() + .diagnostic(at, "Equality comparison between boolean literals"), + ) } } @@ -89,25 +48,6 @@ enum NixBoolean { False, } -#[derive(Debug)] -enum EqualityBinOpKind { - NotEqual, - Equal, -} - -impl EqualityBinOpKind { - /// Try to create from a `BinOpKind` - /// - /// Returns an option, not a Result - fn try_from(bin_op_kind: BinOpKind) -> Option { - match bin_op_kind { - BinOpKind::Equal => Some(Self::Equal), - BinOpKind::NotEqual => Some(Self::NotEqual), - _ => None, - } - } -} - impl std::fmt::Display for NixBoolean { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let s = match self { diff --git a/lib/src/lints/manual_inherit_from.rs b/lib/src/lints/manual_inherit_from.rs index 83d10751..9397bf66 100644 --- a/lib/src/lints/manual_inherit_from.rs +++ b/lib/src/lints/manual_inherit_from.rs @@ -61,6 +61,9 @@ impl Rule for ManualInherit { let Some(Expr::Select(value)) = key_value_stmt.value() else { return None; }; + if value.or_token().is_some() { + return None; + } let select_attrpath = value.attrpath()?; let mut select_attrpath_attrs = select_attrpath.attrs(); let first_attr = select_attrpath_attrs.next()?; diff --git a/lib/src/make.rs b/lib/src/make.rs index b0a62449..cbdc807b 100644 --- a/lib/src/make.rs +++ b/lib/src/make.rs @@ -32,10 +32,6 @@ pub fn quote(node: &SyntaxNode) -> ast::Str { ast_from_text(&format!("\"{node}\"")) } -pub fn unary_not(node: &SyntaxNode) -> ast::UnaryOp { - ast_from_text(&format!("!{node}")) -} - pub fn inherit_stmt<'a>(nodes: impl IntoIterator) -> ast::Inherit { let inherited_idents = nodes .into_iter() diff --git a/readme.md b/readme.md index b58e9e8c..1a31a76e 100644 --- a/readme.md +++ b/readme.md @@ -2,6 +2,8 @@ > Lints and suggestions for the Nix programming language. +Forked from [oppiliappan/statix](https://github.com/oppiliappan/statix) + `statix check` highlights antipatterns in Nix code. `statix fix` can fix several such occurrences. @@ -60,6 +62,12 @@ Install with [brew/linuxbrew](https://brew.sh) brew install statix ``` +## No releases + +Even though some releases were made, +no more are intended. +Instead, this project is meant to be used from HEAD. + ## Usage Basic usage is as simple as: @@ -144,3 +152,8 @@ useless_has_attr All lints are enabled by default. Generate a minimal config with `statix dump > statix.toml`. + +#### Color + +Reports contain ANSI color escape codes unless the +[`NO_COLOR`](https://no-color.org/) environment variable is present.