diff --git a/Cargo.lock b/Cargo.lock index 3c46e71..f4e0f0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,30 +19,31 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", "getrandom", "once_cell", "version_check", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] [[package]] name = "anstream" -version = "0.6.1" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6cd65a4b849ace0b7f6daeebcc1a1d111282227ca745458c61dbf670e52a597" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", @@ -54,15 +55,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" dependencies = [ "utf8parse", ] @@ -78,9 +79,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0238ca56c96dfa37bdf7c373c8886dd591322500aceeeccdb2216fe06dc2f796" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", "windows-sys", @@ -109,9 +110,9 @@ dependencies = [ [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "camino" @@ -124,7 +125,7 @@ dependencies = [ [[package]] name = "cargo-featalign" -version = "0.6.1" +version = "0.6.2" dependencies = [ "anyhow", "cargo_metadata", @@ -143,9 +144,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" +checksum = "e34637b3140142bdf929fb439e8aa4ebad7651ebf7b1080b3930aa16ac1459ff" dependencies = [ "serde", ] @@ -236,9 +237,9 @@ dependencies = [ [[package]] name = "color-spantrace" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" dependencies = [ "once_cell", "owo-colors", @@ -254,9 +255,12 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "deranged" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", +] [[package]] name = "equivalent" @@ -266,9 +270,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "eyre" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +checksum = "80f656be11ddf91bd709454d15d5bd896fbaf4cc3314e69349e4d1569f5b46cd" dependencies = [ "indenter", "once_cell", @@ -285,9 +289,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", @@ -308,9 +312,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "heck" @@ -320,9 +324,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "imara-diff" @@ -342,12 +346,12 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.2", ] [[package]] @@ -364,15 +368,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "memchr" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "miniz_oxide" @@ -429,11 +433,17 @@ version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -496,9 +506,9 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "semver" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" dependencies = [ "serde", ] @@ -536,9 +546,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -551,9 +561,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.32" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -562,18 +572,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", @@ -592,14 +602,15 @@ dependencies = [ [[package]] name = "time" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" dependencies = [ "deranged", "itoa", "libc", "num_threads", + "powerfmt", "serde", "time-core", "time-macros", @@ -607,15 +618,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" dependencies = [ "time-core", ] @@ -639,20 +650,19 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "pin-project-lite", "tracing-core", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -670,9 +680,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "sharded-slab", "thread_local", @@ -788,9 +798,29 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.15" +version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" dependencies = [ "memchr", ] + +[[package]] +name = "zerocopy" +version = "0.7.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 5715dc2..a65970e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ license = "GPL-3.0" name = "cargo-featalign" readme = "README.md" repository = "https://github.com/hack-ink/cargo-featalign" -version = "0.6.1" +version = "0.6.2" [profile.ci-dev] incremental = false diff --git a/mock/Cargo.lock b/mock/Cargo.lock index 60b3194..6dc5565 100644 --- a/mock/Cargo.lock +++ b/mock/Cargo.lock @@ -22,6 +22,10 @@ version = "0.0.0" name = "general-e" version = "0.0.0" +[[package]] +name = "general-f" +version = "0.0.0" + [[package]] name = "mock-runtime" version = "0.0.0" @@ -31,6 +35,8 @@ dependencies = [ "general-c", "general-d", "general-e", + "general-f", + "optional-a", "pallet-a", "pallet-b", "pallet-c", @@ -38,7 +44,6 @@ dependencies = [ "primitive-a", "primitive-b", "primitive-c", - "primitive-d", ] [[package]] @@ -64,6 +69,13 @@ version = "0.0.0" name = "nested-d" version = "0.0.0" +[[package]] +name = "optional-a" +version = "0.0.0" +dependencies = [ + "primitive-a", +] + [[package]] name = "pallet-a" version = "0.0.0" @@ -94,7 +106,3 @@ version = "0.0.0" [[package]] name = "primitive-c" version = "0.0.0" - -[[package]] -name = "primitive-d" -version = "0.0.0" diff --git a/mock/Cargo.toml b/mock/Cargo.toml index 04cecf1..3f7781b 100644 --- a/mock/Cargo.toml +++ b/mock/Cargo.toml @@ -18,8 +18,10 @@ b = { package = "general-b", default-features = false, path = "general/b" } general-c = { default-features = true, path = "general/c" } # Test no default features. general-d = { path = "general/d" } -# Test development dependencies. +# Test development dependency. general-e = { path = "general/e" } +# Test optional dependency with default std. +general-f = { path = "general/f", optional = true } # Test missing `pallet-a/std`. pallet-a = { default-features = false, path = "pallet/a" } # Test missing `pallet-a/runtime-benchmarks`. @@ -32,8 +34,12 @@ pallet-d = { default-features = false, path = "pallet/d" } primitive-a = { default-features = false, path = "primitive/a" } # Test empty feature format. primitive-b = { path = "primitive/b" } +# Test `std` isn't a part of default features. primitive-c = { path = "primitive/c" } -primitive-d = { path = "primitive/d" } +# Test `std` is enabled by default in an optional dependency. +# +# Cargo Featalign should not raise any complaints when the default `std` is enabled. +optional-a = { path = "optional/a", optional = true } [dev-dependencies] general-e = { path = "general/e" } @@ -67,6 +73,10 @@ try-runtime = [ empty = [] +other = [ + "general-f", +] + [workspace] resolver = "2" @@ -74,6 +84,7 @@ exclude = [] members = [ "general/*", "nested/*", + "optional/*", "pallet/*", "primitive/*", ] diff --git a/mock/Cargo.toml.expect b/mock/Cargo.toml.expect index 8c41e0f..f03f519 100644 --- a/mock/Cargo.toml.expect +++ b/mock/Cargo.toml.expect @@ -18,8 +18,10 @@ b = { package = "general-b", default-features = false, path = "general/b" } general-c = { default-features = true, path = "general/c" } # Test no default features. general-d = { path = "general/d" } -# Test development dependencies. +# Test development dependency. general-e = { path = "general/e" } +# Test optional dependency with default std. +general-f = { path = "general/f", optional = true } # Test missing `pallet-a/std`. pallet-a = { default-features = false, path = "pallet/a" } # Test missing `pallet-a/runtime-benchmarks`. @@ -32,8 +34,12 @@ pallet-d = { default-features = false, path = "pallet/d" } primitive-a = { default-features = false, path = "primitive/a" } # Test empty feature format. primitive-b = { path = "primitive/b" } +# Test `std` isn't a part of default features. primitive-c = { path = "primitive/c" } -primitive-d = { path = "primitive/d" } +# Test `std` is enabled by default in an optional dependency. +# +# Cargo Featalign should not raise any complaints when the default `std` is enabled. +optional-a = { path = "optional/a", optional = true } [dev-dependencies] general-e = { path = "general/e" } @@ -51,6 +57,7 @@ std = [ "pallet-a/std", "pallet-d/std", "primitive-a/std", + "primitive-c/std", ] runtime-benchmarks = [ @@ -73,8 +80,10 @@ try-runtime = [ empty = [ "primitive-b/empty", - "primitive-c/empty", - "primitive-d/empty", +] + +other = [ + "general-f", ] [workspace] @@ -84,6 +93,7 @@ exclude = [] members = [ "general/*", "nested/*", + "optional/*", "pallet/*", "primitive/*", ] diff --git a/mock/primitive/d/Cargo.toml b/mock/general/f/Cargo.toml similarity index 76% rename from mock/primitive/d/Cargo.toml rename to mock/general/f/Cargo.toml index 3741991..0205e08 100644 --- a/mock/primitive/d/Cargo.toml +++ b/mock/general/f/Cargo.toml @@ -1,13 +1,14 @@ [package] authors = ["Xavier Lau "] -description = "primitive-d" +description = "general-f" edition = "2021" homepage = "https://hack.ink/cargo-featalign" license = "GPL-3.0" -name = "primitive-d" +name = "general-f" readme = "README.md" repository = "https://github.com/hack-ink/cargo-featalign" version = "0.0.0" [features] -empty = [] +default = ["std"] +std = [] diff --git a/mock/primitive/d/src/lib.rs b/mock/general/f/src/lib.rs similarity index 100% rename from mock/primitive/d/src/lib.rs rename to mock/general/f/src/lib.rs diff --git a/mock/optional/a/Cargo.toml b/mock/optional/a/Cargo.toml new file mode 100644 index 0000000..d83b58a --- /dev/null +++ b/mock/optional/a/Cargo.toml @@ -0,0 +1,13 @@ +[package] +authors = ["Xavier Lau "] +description = "optional-a" +edition = "2021" +homepage = "https://hack.ink/cargo-featalign" +license = "GPL-3.0" +name = "optional-a" +readme = "README.md" +repository = "https://github.com/hack-ink/cargo-featalign" +version = "0.0.0" + +[dependencies] +primitive-a = { path = "../../primitive/a" } diff --git a/mock/optional/a/src/lib.rs b/mock/optional/a/src/lib.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/mock/optional/a/src/lib.rs @@ -0,0 +1 @@ + diff --git a/mock/primitive/c/Cargo.toml b/mock/primitive/c/Cargo.toml index b57eeea..3e3d103 100644 --- a/mock/primitive/c/Cargo.toml +++ b/mock/primitive/c/Cargo.toml @@ -10,4 +10,5 @@ repository = "https://github.com/hack-ink/cargo-featalign" version = "0.0.0" [features] -empty = [] +default = [] +std = [] diff --git a/src/analyzer.rs b/src/analyzer.rs index b38c014..be93d86 100644 --- a/src/analyzer.rs +++ b/src/analyzer.rs @@ -33,7 +33,9 @@ pub fn append_problems(id: PackageId, problems: Vec) { } static WORKSPACE_ONLY: OnceCell = OnceCell::new(); +static IGNORE: OnceCell> = OnceCell::new(); static DEFAULT_STD: OnceCell = OnceCell::new(); +static NON_DEFAULT_STD: OnceCell> = OnceCell::new(); #[derive(Debug, Clone)] pub struct Analyzer { @@ -47,7 +49,9 @@ impl Analyzer { let manifest_path = util::manifest_path_of(&initiator.manifest_path); WORKSPACE_ONLY.set(initiator.workspace_only).unwrap(); + IGNORE.set(initiator.ignore).unwrap(); DEFAULT_STD.set(initiator.default_std).unwrap(); + NON_DEFAULT_STD.set(initiator.non_default_std).unwrap(); let mut metadata = MetadataCommand::new() .manifest_path(&*manifest_path) @@ -76,23 +80,21 @@ impl Analyzer { } fn analyze_crate(self, node: Node, package: Package, depth: i16, mut dependency_path: String) { - if *WORKSPACE_ONLY.get().unwrap() && !self.is_workspace_member(&package.id) { + if *WORKSPACE_ONLY.get().unwrap() && !self.is_workspace_member(&package.id) + || IGNORE.get().unwrap().contains(&package.name) + { return; } dependency_path.push_str(&format!("/{}", package.name.clone())); - if *DEFAULT_STD.get().unwrap() { - self.analyze_default_features(&node, &package, &dependency_path); - } - self.analyze_features(&node, &package, &dependency_path); if in_depth(depth) { let mut ts = Vec::new(); for d in &node.deps { - if ignore(d) { + if is_dev(d) { continue; } @@ -114,49 +116,24 @@ impl Analyzer { } } - fn analyze_default_features(&self, node: &Node, package: &Package, dependency_path: &str) { - let mut problem_cs = Vec::new(); - - // The items we require are separated between two vectors: `node.deps` and - // `package.dependencies`. - for d in &node.deps { - if ignore(d) { - continue; - } - - let p = self.metadata.get_by_id(&d.pkg).unwrap(); - - if package.dependencies.iter().any(|d| { - d.name == p.name - && d.uses_default_features - && p.features - .get("default") - .map(|dfs| dfs.iter().any(|f| f == "std")) - .unwrap_or_default() - }) { - problem_cs.push(ProblemCrate { - id: p.id.clone(), - alias: String::new(), - dependency_path: dependency_path.to_owned(), - problem: Problem::DefaultFeaturesEnabled, - }); - } - } - - append_problems(node.id.clone(), problem_cs); - } - fn analyze_features(&self, node: &Node, package: &Package, dependency_path: &str) { let rs = package .dependencies .iter() .filter_map(|d| d.rename.as_ref().map(|rn| (d.name.as_str(), rn.as_str()))) .collect::>(); - + let has_std_feat = package.features.get("std").is_some(); + let non_optional_deps = if *DEFAULT_STD.get().unwrap() && has_std_feat { + package.dependencies.iter().filter(|d| !d.optional).collect::>() + } else { + Vec::new() + }; + let fs = FEATURES.get().unwrap(); + let fs = package.features.iter().filter(|(f, _)| fs.contains(f)).collect::>(); let mut problem_cs = Vec::new(); for d in &node.deps { - if ignore(d) { + if is_dev(d) { continue; } @@ -165,28 +142,51 @@ impl Analyzer { let p_name = p.name.as_str(); let p_alias = rs.get_by_id(p_name).unwrap_or(p_name); let n = self.resolve.get_by_id(p_id).unwrap(); - let fs = FEATURES.get().unwrap(); let mut missing_fs = Vec::new(); - for (f, required_fs) in package.features.iter().filter(|(f, _)| fs.contains(f)) { + if !non_optional_deps.is_empty() + && !is_non_default_std(&d.name) + // Package's dependencies have `std` feature enabled. + && non_optional_deps.iter().any(|d| { + d.name == p.name + && d.uses_default_features + && p.features + .get("default") + .map(|dfs| dfs.iter().any(|f| f == "std")) + .unwrap_or_default() + }) { + problem_cs.push(ProblemCrate { + id: p_id.to_owned(), + alias: p_alias.to_owned(), + dependency_path: dependency_path.to_owned(), + problem: Problem::DefaultFeaturesEnabled, + }); + } + + 'out: for (f, required_fs) in &fs { // If the dependency has the feature specified by the user for analyzing. if n.features.contains(f) { - let mut problematic = true; + if package.dependencies.iter().any(|d| { + d.name == p_name + && d.uses_default_features && p + .features + .get("default") + .map(|dfs| dfs.iter().any(|f_| f_ == *f)) + .unwrap_or_default() + }) { + continue; + } // `assert!("general-a/std".contains("general-a"));` - for f in required_fs { + for f in *required_fs { // TODO: handle the full name here // e.g. this could be `general-a/std` or `general-a?/std` if f.contains(p_alias) { - problematic = false; - - break; + continue 'out; } } - if problematic { - missing_fs.push(f.to_owned()); - } + missing_fs.push((*f).to_owned()); } } @@ -229,11 +229,15 @@ pub enum Problem { MissingFeatures(Vec), } -// Ignore `[dev-dependencies]`. -fn ignore(node_dep: &NodeDep) -> bool { +// Check if the this package is under the `[dev-dependencies]`. +fn is_dev(node_dep: &NodeDep) -> bool { node_dep.dep_kinds.iter().any(|k| matches!(k.kind, DependencyKind::Development)) } +fn is_non_default_std(name: &str) -> bool { + NON_DEFAULT_STD.get().unwrap().iter().any(|n| n == name) +} + fn in_depth(depth: i16) -> bool { depth != 0 || depth == -1 } diff --git a/src/cli.rs b/src/cli.rs index f3d2625..bfaf8e2 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -76,6 +76,9 @@ pub struct AnalyzerInitiator { /// Determines whether to process only workspace members. #[arg(long)] pub workspace_only: bool, + /// Disregard the analysis of the specified crates. + #[arg(long, value_delimiter = ',')] + pub ignore: Vec, /// Determines whether to check default features. /// /// This option is useful when working in a no-std environment. @@ -83,6 +86,11 @@ pub struct AnalyzerInitiator { /// ["x/std"]` part to control it separately. #[arg(long)] pub default_std: bool, + // Specify the crates here that do not use the default to control their `std` feature. This + // will prevent the check from being applied to them, which is only useful when enabling the + // `default-std`. + #[arg(long, value_delimiter = ',')] + pub non_default_std: Vec, } #[derive(Debug, Parser)] diff --git a/src/test.rs b/src/test.rs index ca36ee9..a29a06f 100644 --- a/src/test.rs +++ b/src/test.rs @@ -26,9 +26,10 @@ fn cargo_featalign_should_work() { }); Analyzer::initialize(AnalyzerInitiator { manifest_path: "mock".into(), - workspace_only: true, default_std: true, + ignore: Vec::new(), + non_default_std: Vec::new(), }) .analyze(-1); Resolver::initialize(ResolverInitiator { sort: true }).resolve().unwrap();