From e46c6416ff5bce28b57d042470f20648082719d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Sep 2021 16:42:17 +0100 Subject: [PATCH 01/32] Bump syn from 1.0.75 to 1.0.76 (#821) Bumps [syn](https://github.com/dtolnay/syn) from 1.0.75 to 1.0.76. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/1.0.75...1.0.76) --- updated-dependencies: - dependency-name: syn dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e7d3d49066..3f6c511280 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -780,9 +780,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.75" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" dependencies = [ "proc-macro2", "quote", From 580881e84b2016471191f0f1a9959dfbb7edefb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Saparelli?= Date: Thu, 9 Sep 2021 09:17:46 +1200 Subject: [PATCH 02/32] Add support for binstall (#824) --- Cargo.toml | 5 +++++ README.md | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 1d853906ab..8f92b8c06b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,3 +57,8 @@ vendored-openssl = ["git2/vendored-openssl"] [build-dependencies] rustc_version = "0.4" + +[package.metadata.binstall] +pkg-url = "{ repo }/releases/download/{ version }/cargo-tarpaulin-{ version }-travis.tar.gz" +bin-dir = "cargo-tarpaulin" +pkg-fmt = "tgz" diff --git a/README.md b/README.md index 73b64dfcfb..65b1ccdc2e 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,12 @@ installation and massively reducing the install time on CI. When using the [Nix](https://nixos.org/nix) package manager, the `nixpkgs.cargo-tarpaulin` package can be used. This ensures that tarpaulin will be built with the same rust version as the rest of your packages. +You can also use [cargo-binstall](https://github.com/ryankurte/cargo-binstall): + +```text +cargo binstall cargo-tarpaulin +``` + ### Environment Variables When tarpaulin runs your tests it strives to run them in the same environment as if they were ran via cargo test. From d8be56b604e46f8b5f3a9f618d663e1099080366 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Sep 2021 09:33:46 +0100 Subject: [PATCH 03/32] Bump git2 from 0.13.21 to 0.13.22 (#825) Bumps [git2](https://github.com/rust-lang/git2-rs) from 0.13.21 to 0.13.22. - [Release notes](https://github.com/rust-lang/git2-rs/releases) - [Commits](https://github.com/rust-lang/git2-rs/compare/0.13.21...0.13.22) --- updated-dependencies: - dependency-name: git2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f6c511280..64f2b3dfaa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -290,9 +290,9 @@ dependencies = [ [[package]] name = "git2" -version = "0.13.21" +version = "0.13.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "659cd14835e75b64d9dba5b660463506763cf0aa6cb640aeeb0e98d841093490" +checksum = "9c1cbbfc9a1996c6af82c2b4caf828d2c653af4fcdbb0e5674cc966eee5a4197" dependencies = [ "bitflags", "libc", @@ -400,9 +400,9 @@ checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" [[package]] name = "libgit2-sys" -version = "0.12.22+1.1.0" +version = "0.12.23+1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89c53ac117c44f7042ad8d8f5681378dfbc6010e49ec2c0d1f11dfedc7a4a1c3" +checksum = "29730a445bae719db3107078b46808cc45a5b7a6bae3f31272923af969453356" dependencies = [ "cc", "libc", From a022b1710a7bb8716d8a97ef1e2926bfb050a815 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Sep 2021 07:28:14 +0100 Subject: [PATCH 04/32] Bump tracing-subscriber from 0.2.20 to 0.2.21 (#826) Bumps [tracing-subscriber](https://github.com/tokio-rs/tracing) from 0.2.20 to 0.2.21. - [Release notes](https://github.com/tokio-rs/tracing/releases) - [Commits](https://github.com/tokio-rs/tracing/compare/tracing-subscriber-0.2.20...tracing-subscriber-0.2.21) --- updated-dependencies: - dependency-name: tracing-subscriber dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 64f2b3dfaa..f712a69ccb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -855,9 +855,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.18" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052" +checksum = "46125608c26121c81b0c6d693eab5a420e416da7e43c426d2e8f7df8da8a3acf" dependencies = [ "lazy_static", ] @@ -875,9 +875,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cbe87a2fa7e35900ce5de20220a582a9483a7063811defce79d7cbd59d4cfe" +checksum = "f7d29c0f56bcd17117430bc60fd10624b419ab8a3b5c358796a31e9a37a83a65" dependencies = [ "ansi_term 0.12.1", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 8f92b8c06b..2541814a4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ humantime-serde = "1" indexmap = { version = "1.7.0", features = ["serde-1"] } lazy_static = "1.0" tracing = { version = "0.1", default-features = false } -tracing-subscriber = {version = "0.2.20", default-features = false, features = ["env-filter", "fmt", "chrono", "ansi", "smallvec", "tracing-log"]} +tracing-subscriber = {version = "0.2.21", default-features = false, features = ["env-filter", "fmt", "chrono", "ansi", "smallvec", "tracing-log"]} memmap = "0.7.0" object = "0.24" proc-macro2 = { version = "1.0", features = ["span-locations"] } From fbd16d3d71c008e6a56edd00a9cba85a84ee08d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Sep 2021 08:44:15 +0100 Subject: [PATCH 05/32] Bump tracing-subscriber from 0.2.21 to 0.2.22 (#828) Bumps [tracing-subscriber](https://github.com/tokio-rs/tracing) from 0.2.21 to 0.2.22. - [Release notes](https://github.com/tokio-rs/tracing/releases) - [Commits](https://github.com/tokio-rs/tracing/compare/tracing-subscriber-0.2.21...tracing-subscriber-0.2.22) --- updated-dependencies: - dependency-name: tracing-subscriber dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f712a69ccb..809f0915ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -875,9 +875,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.21" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d29c0f56bcd17117430bc60fd10624b419ab8a3b5c358796a31e9a37a83a65" +checksum = "62af966210b88ad5776ee3ba12d5f35b8d6a2b2a12168f3080cf02b814d7376b" dependencies = [ "ansi_term 0.12.1", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 2541814a4a..3d44b56c0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ humantime-serde = "1" indexmap = { version = "1.7.0", features = ["serde-1"] } lazy_static = "1.0" tracing = { version = "0.1", default-features = false } -tracing-subscriber = {version = "0.2.21", default-features = false, features = ["env-filter", "fmt", "chrono", "ansi", "smallvec", "tracing-log"]} +tracing-subscriber = {version = "0.2.22", default-features = false, features = ["env-filter", "fmt", "chrono", "ansi", "smallvec", "tracing-log"]} memmap = "0.7.0" object = "0.24" proc-macro2 = { version = "1.0", features = ["span-locations"] } From 9e0c468fc935713fd21888811cfb8435e081ab8f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Sep 2021 08:44:22 +0100 Subject: [PATCH 06/32] Bump tracing from 0.1.26 to 0.1.27 (#829) Bumps [tracing](https://github.com/tokio-rs/tracing) from 0.1.26 to 0.1.27. - [Release notes](https://github.com/tokio-rs/tracing/releases) - [Commits](https://github.com/tokio-rs/tracing/compare/tracing-0.1.26...tracing-0.1.27) --- updated-dependencies: - dependency-name: tracing dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 809f0915ee..ce61a33744 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -844,9 +844,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +checksum = "c2ba9ab62b7d6497a8638dfda5e5c4fb3b2d5a7fca4118f2b96151c8ef1a437e" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", From c284bd36fb57b0616faca612120a9ae90202e0d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Sep 2021 08:44:20 +0100 Subject: [PATCH 07/32] Bump serde_json from 1.0.67 to 1.0.68 (#831) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.67 to 1.0.68. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.67...v1.0.68) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce61a33744..d4a201aadf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -731,9 +731,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" +checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" dependencies = [ "itoa", "ryu", From a1bf1f741c277a058a0965865ffaee3f1cc3ad5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Sep 2021 09:38:36 +0100 Subject: [PATCH 08/32] Bump tracing-subscriber from 0.2.22 to 0.2.23 (#832) Bumps [tracing-subscriber](https://github.com/tokio-rs/tracing) from 0.2.22 to 0.2.23. - [Release notes](https://github.com/tokio-rs/tracing/releases) - [Commits](https://github.com/tokio-rs/tracing/compare/tracing-subscriber-0.2.22...tracing-subscriber-0.2.23) --- updated-dependencies: - dependency-name: tracing-subscriber dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4a201aadf..27971f7673 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -875,9 +875,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62af966210b88ad5776ee3ba12d5f35b8d6a2b2a12168f3080cf02b814d7376b" +checksum = "56c42e73a9d277d4d2b6a88389a137ccf3c58599660b17e8f5fc39305e490669" dependencies = [ "ansi_term 0.12.1", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 3d44b56c0e..9003b0edeb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ humantime-serde = "1" indexmap = { version = "1.7.0", features = ["serde-1"] } lazy_static = "1.0" tracing = { version = "0.1", default-features = false } -tracing-subscriber = {version = "0.2.22", default-features = false, features = ["env-filter", "fmt", "chrono", "ansi", "smallvec", "tracing-log"]} +tracing-subscriber = {version = "0.2.23", default-features = false, features = ["env-filter", "fmt", "chrono", "ansi", "smallvec", "tracing-log"]} memmap = "0.7.0" object = "0.24" proc-macro2 = { version = "1.0", features = ["span-locations"] } From 37fc7132496fe0b17ca0c27281ebe6eba9c7c9c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Sep 2021 10:24:43 +0100 Subject: [PATCH 09/32] Bump tracing from 0.1.27 to 0.1.28 (#835) Bumps [tracing](https://github.com/tokio-rs/tracing) from 0.1.27 to 0.1.28. - [Release notes](https://github.com/tokio-rs/tracing/releases) - [Commits](https://github.com/tokio-rs/tracing/compare/tracing-0.1.27...tracing-0.1.28) --- updated-dependencies: - dependency-name: tracing dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 27971f7673..bfff68c544 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -844,9 +844,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ba9ab62b7d6497a8638dfda5e5c4fb3b2d5a7fca4118f2b96151c8ef1a437e" +checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", From bf3f2811b2f45cc8da9af1dfa9f9b864c9cc7499 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Sep 2021 10:24:52 +0100 Subject: [PATCH 10/32] Bump tracing-subscriber from 0.2.23 to 0.2.24 (#836) Bumps [tracing-subscriber](https://github.com/tokio-rs/tracing) from 0.2.23 to 0.2.24. - [Release notes](https://github.com/tokio-rs/tracing/releases) - [Commits](https://github.com/tokio-rs/tracing/compare/tracing-subscriber-0.2.23...tracing-subscriber-0.2.24) --- updated-dependencies: - dependency-name: tracing-subscriber dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bfff68c544..620170687c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -875,9 +875,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c42e73a9d277d4d2b6a88389a137ccf3c58599660b17e8f5fc39305e490669" +checksum = "fdd0568dbfe3baf7048b7908d2b32bca0d81cd56bec6d2a8f894b01d74f86be3" dependencies = [ "ansi_term 0.12.1", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 9003b0edeb..d2baef952d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ humantime-serde = "1" indexmap = { version = "1.7.0", features = ["serde-1"] } lazy_static = "1.0" tracing = { version = "0.1", default-features = false } -tracing-subscriber = {version = "0.2.23", default-features = false, features = ["env-filter", "fmt", "chrono", "ansi", "smallvec", "tracing-log"]} +tracing-subscriber = {version = "0.2.24", default-features = false, features = ["env-filter", "fmt", "chrono", "ansi", "smallvec", "tracing-log"]} memmap = "0.7.0" object = "0.24" proc-macro2 = { version = "1.0", features = ["span-locations"] } From a11dc3a12924736f14dbbc5e7af331a03db1d571 Mon Sep 17 00:00:00 2001 From: xd009642 Date: Tue, 21 Sep 2021 13:28:09 +0100 Subject: [PATCH 11/32] Fix/unreachable analysis (fixes #833) (#834) * Add Definite reachabiliy for #833 Returns work but for some reason still a slight failure. Tracking that down now * Fix the function call filtering. Lesson to self don't try to be smart * Handle merging definite expressions + loops --- CHANGELOG.md | 2 + src/source_analysis/expressions.rs | 107 ++++++++++--------- src/source_analysis/items.rs | 11 +- src/source_analysis/mod.rs | 44 +++++++- src/source_analysis/statements.rs | 16 +-- src/source_analysis/tests.rs | 160 +++++++++++++++++++++++++++++ 6 files changed, 282 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6a5a42538..28af0e892a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ file. ### Changed - Fix #819 incorrect handling of test args caused by removing the executable path as first program arg in execve +- Now factor in try and return blocks in reachability calculation +- Remove erroneous filtering of function calls that take a single line with arguments present ### Removed diff --git a/src/source_analysis/expressions.rs b/src/source_analysis/expressions.rs index d1114724af..1533123714 100644 --- a/src/source_analysis/expressions.rs +++ b/src/source_analysis/expressions.rs @@ -27,12 +27,18 @@ impl SourceAnalysis { Expr::Group(ref g) => self.process_expr(&g.expr, ctx), Expr::Await(ref a) => self.process_expr(&a.base, ctx), Expr::Async(ref a) => self.visit_block(&a.block, ctx), - Expr::Try(ref t) => self.process_expr(&t.expr, ctx), - Expr::TryBlock(ref t) => self.visit_block(&t.block, ctx), + Expr::Try(ref t) => { + self.process_expr(&t.expr, ctx); + SubResult::Definite + } + Expr::TryBlock(ref t) => { + self.visit_block(&t.block, ctx); + SubResult::Definite + } // don't try to compute unreachability on other things _ => SubResult::Ok, }; - if let SubResult::Unreachable = res { + if res.is_unreachable() { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(expr); } @@ -42,6 +48,7 @@ impl SourceAnalysis { fn visit_let(&mut self, let_expr: &ExprLet, ctx: &Context) -> SubResult { let check_cover = self.check_attr_list(&let_expr.attrs, ctx); let analysis = self.get_line_analysis(ctx.file.to_path_buf()); + let mut res = SubResult::Ok; if check_cover { for a in &let_expr.attrs { analysis.ignore_tokens(a); @@ -63,12 +70,12 @@ impl SourceAnalysis { .logical_lines .insert(let_expr.expr.span().start().line, base_line); } - self.process_expr(&let_expr.expr, ctx); + res += self.process_expr(&let_expr.expr, ctx); } } else { analysis.ignore_tokens(let_expr); } - SubResult::Ok + res } fn visit_path(&mut self, path: &ExprPath, ctx: &Context) -> SubResult { @@ -96,7 +103,7 @@ impl SourceAnalysis { } else { analysis.ignore_tokens(ret); } - SubResult::Ok + SubResult::Definite } fn visit_expr_block(&mut self, block: &ExprBlock, ctx: &Context) -> SubResult { @@ -110,135 +117,137 @@ impl SourceAnalysis { } fn visit_block(&mut self, block: &Block, ctx: &Context) -> SubResult { - if let SubResult::Unreachable = self.process_statements(&block.stmts, ctx) { + let reachable = self.process_statements(&block.stmts, ctx); + if reachable.is_unreachable() { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(block); - SubResult::Unreachable - } else { - SubResult::Ok } + reachable } fn visit_closure(&mut self, closure: &ExprClosure, ctx: &Context) -> SubResult { - self.process_expr(&closure.body, ctx); + let res = self.process_expr(&closure.body, ctx); // Even if a closure is "unreachable" it might be part of a chained method // call and I don't want that propagating up. - SubResult::Ok + if res.is_unreachable() { + SubResult::Ok + } else { + res + } } fn visit_match(&mut self, mat: &ExprMatch, ctx: &Context) -> SubResult { // a match with some arms is unreachable iff all its arms are unreachable - let mut reachable_arm = false; + let mut result = None; for arm in &mat.arms { if self.check_attr_list(&arm.attrs, ctx) { - if let SubResult::Ok = self.process_expr(&arm.body, ctx) { + let reachable = self.process_expr(&arm.body, ctx); + if reachable.is_reachable() { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); let span = arm.pat.span(); for line in span.start().line..span.end().line { analysis.logical_lines.insert(line + 1, span.start().line); } - reachable_arm = true + result = result.map(|x| x + reachable).or_else(|| Some(reachable)); } } else { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(arm); } } - if !reachable_arm { + if let Some(result) = result { + result + } else { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(mat); SubResult::Unreachable - } else { - SubResult::Ok } } fn visit_if(&mut self, if_block: &ExprIf, ctx: &Context) -> SubResult { // an if expression is unreachable iff both its branches are unreachable - let mut reachable_arm = false; - - self.process_expr(&if_block.cond, ctx); - if let SubResult::Ok = self.visit_block(&if_block.then_branch, ctx) { - reachable_arm = true; - } + let mut reachable = self.process_expr(&if_block.cond, ctx); + reachable += self.visit_block(&if_block.then_branch, ctx); if let Some((_, ref else_block)) = if_block.else_branch { - if let SubResult::Ok = self.process_expr(&else_block, ctx) { - reachable_arm = true; - } + reachable += self.process_expr(&else_block, ctx); } else { // an empty else branch is reachable - reachable_arm = true; + reachable += SubResult::Ok; } - if !reachable_arm { + if reachable.is_unreachable() { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(if_block); SubResult::Unreachable } else { - SubResult::Ok + reachable } } fn visit_while(&mut self, whl: &ExprWhile, ctx: &Context) -> SubResult { if self.check_attr_list(&whl.attrs, ctx) { // a while block is unreachable iff its body is - if let SubResult::Unreachable = self.visit_block(&whl.body, ctx) { + if self.visit_block(&whl.body, ctx).is_unreachable() { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(whl); SubResult::Unreachable } else { - SubResult::Ok + SubResult::Definite } } else { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(whl); - SubResult::Ok + SubResult::Definite } } fn visit_for(&mut self, for_loop: &ExprForLoop, ctx: &Context) -> SubResult { if self.check_attr_list(&for_loop.attrs, ctx) { // a for block is unreachable iff its body is - if let SubResult::Unreachable = self.visit_block(&for_loop.body, ctx) { + if self.visit_block(&for_loop.body, ctx).is_unreachable() { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(for_loop); SubResult::Unreachable } else { - SubResult::Ok + SubResult::Definite } } else { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(for_loop); - SubResult::Ok + SubResult::Definite } } fn visit_loop(&mut self, loopex: &ExprLoop, ctx: &Context) -> SubResult { if self.check_attr_list(&loopex.attrs, ctx) { // a loop block is unreachable iff its body is - if let SubResult::Unreachable = self.visit_block(&loopex.body, ctx) { + // given we can't reason if a loop terminates we should make it as definite as + // it may last forever + if self.visit_block(&loopex.body, ctx).is_unreachable() { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(loopex); SubResult::Unreachable } else { - SubResult::Ok + SubResult::Definite } } else { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(loopex); - SubResult::Ok + SubResult::Definite } } fn visit_callable(&mut self, call: &ExprCall, ctx: &Context) -> SubResult { if self.check_attr_list(&call.attrs, ctx) { if !call.args.is_empty() { - let lines = get_coverable_args(&call.args); - let lines = get_line_range(call) - .filter(|x| !lines.contains(&x)) - .collect::>(); - let analysis = self.get_line_analysis(ctx.file.to_path_buf()); - analysis.add_to_ignore(&lines); + if call.span().start().line != call.span().end().line { + let lines = get_coverable_args(&call.args); + let lines = get_line_range(call) + .filter(|x| !lines.contains(&x)) + .collect::>(); + let analysis = self.get_line_analysis(ctx.file.to_path_buf()); + analysis.add_to_ignore(&lines); + } } self.process_expr(&call.func, ctx); } else { @@ -270,7 +279,7 @@ impl SourceAnalysis { fn visit_unsafe_block(&mut self, unsafe_expr: &ExprUnsafe, ctx: &Context) -> SubResult { let u_line = unsafe_expr.unsafe_token.span().start().line; - + let mut res = SubResult::Ok; let blk = &unsafe_expr.block; if u_line != blk.brace_token.span.start().line || blk.stmts.is_empty() { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); @@ -286,17 +295,19 @@ impl SourceAnalysis { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(unsafe_expr.unsafe_token); } - if let SubResult::Unreachable = self.process_statements(&blk.stmts, ctx) { + let reachable = self.process_statements(&blk.stmts, ctx); + if reachable.is_unreachable() { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(unsafe_expr); return SubResult::Unreachable; } + res += reachable; } else { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(unsafe_expr.unsafe_token); analysis.ignore_span(blk.brace_token.span); } - SubResult::Ok + res } fn visit_struct_expr(&mut self, structure: &ExprStruct, ctx: &Context) -> SubResult { diff --git a/src/source_analysis/items.rs b/src/source_analysis/items.rs index 6cc3b1a592..cc687544a3 100644 --- a/src/source_analysis/items.rs +++ b/src/source_analysis/items.rs @@ -33,7 +33,7 @@ impl SourceAnalysis { Item::Trait(ref i) => self.visit_trait(&i, ctx), Item::Impl(ref i) => self.visit_impl(&i, ctx), Item::Macro(ref i) => { - if let SubResult::Unreachable = self.visit_macro_call(&i.mac, ctx) { + if self.visit_macro_call(&i.mac, ctx).is_unreachable() { res = SubResult::Unreachable; } } @@ -130,7 +130,10 @@ impl SourceAnalysis { // We need to force cover! analysis.cover_span(func.block.brace_token.span, Some(ctx.file_contents)); } - if let SubResult::Unreachable = self.process_statements(&func.block.stmts, ctx) { + if self + .process_statements(&func.block.stmts, ctx) + .is_unreachable() + { // if the whole body of the function is unreachable, that means the function itself // cannot be called, so is unreachable as a whole let analysis = self.get_line_analysis(ctx.file.to_path_buf()); @@ -201,7 +204,9 @@ impl SourceAnalysis { analysis .cover_token_stream(i.into_token_stream(), Some(ctx.file_contents)); } - if let SubResult::Unreachable = self.process_statements(&i.block.stmts, ctx) + if self + .process_statements(&i.block.stmts, ctx) + .is_unreachable() { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); // if the body of this method is unreachable, this means that the method diff --git a/src/source_analysis/mod.rs b/src/source_analysis/mod.rs index 263e6ebb85..8e9d56f413 100644 --- a/src/source_analysis/mod.rs +++ b/src/source_analysis/mod.rs @@ -66,12 +66,54 @@ pub trait SourceAnalysisQuery { fn normalise(&self, path: &Path, l: usize) -> (PathBuf, usize); } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] pub(crate) enum SubResult { + /// Expression should be a reachable one (or we don't care to check further) Ok, + /// Expression definitely reachable - reserved for early returns from functions to stop + /// unreachable expressions wiping them out + Definite, + /// Unreachable expression i.e. unreachable!() Unreachable, } +// Addition works for this by forcing anything + definite to definite, otherwise prioritising +// unreachable. +impl std::ops::AddAssign for SubResult { + fn add_assign(&mut self, other: Self) { + if *self == Self::Definite || other == Self::Definite { + *self = Self::Definite; + } else if *self == Self::Unreachable || other == Self::Unreachable { + *self = Self::Unreachable; + } else { + *self = Self::Ok; + } + } +} + +impl std::ops::Add for SubResult { + type Output = Self; + + fn add(mut self, rhs: Self) -> Self::Output { + self += rhs; + self + } +} + +impl SubResult { + pub fn is_reachable(&self) -> bool { + if *self == Self::Unreachable { + false + } else { + true + } + } + + pub fn is_unreachable(&self) -> bool { + !self.is_reachable() + } +} + impl SourceAnalysisQuery for HashMap { fn should_ignore(&self, path: &Path, l: &usize) -> bool { if self.contains_key(path) { diff --git a/src/source_analysis/statements.rs b/src/source_analysis/statements.rs index 0277dd6193..8d85216d9d 100644 --- a/src/source_analysis/statements.rs +++ b/src/source_analysis/statements.rs @@ -6,25 +6,30 @@ impl SourceAnalysis { // in a list of statements, if any of them is unreachable, the whole list is // unreachable let mut unreachable = false; + let mut definite = false; for stmt in stmts.iter() { let res = match *stmt { Stmt::Item(ref i) => self.process_items(&[i.clone()], ctx), Stmt::Expr(ref i) | Stmt::Semi(ref i, _) => self.process_expr(&i, ctx), Stmt::Local(ref i) => self.process_local(&i, ctx), }; - if let SubResult::Unreachable = res { - unreachable = true; + unreachable |= res.is_unreachable(); + if SubResult::Definite == res { + definite = true; } } // We must be in a block, the parent will handle marking the span as unreachable - if unreachable { + if unreachable && !definite { SubResult::Unreachable + } else if definite { + SubResult::Definite } else { SubResult::Ok } } fn process_local(&mut self, local: &Local, ctx: &Context) -> SubResult { + let mut result = SubResult::Ok; if let Some((eq, expr)) = &local.init { let check_cover = self.check_attr_list(&local.attrs, ctx); if check_cover { @@ -50,14 +55,13 @@ impl SourceAnalysis { .insert(expr.span().start().line, base_line); } std::mem::drop(analysis); - self.process_expr(&expr, ctx); + result += self.process_expr(&expr, ctx); } } else { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(local); } } - - SubResult::Ok + result } } diff --git a/src/source_analysis/tests.rs b/src/source_analysis/tests.rs index 468193da20..74972d9d74 100644 --- a/src/source_analysis/tests.rs +++ b/src/source_analysis/tests.rs @@ -1227,3 +1227,163 @@ fn unreachable_propagate() { assert!(lines.ignore.contains(&Lines::Line(6))); assert!(lines.ignore.contains(&Lines::Line(7))); } + +#[test] +fn unreachable_include_returns() { + let config = Config::default(); + let ctx = Context { + config: &config, + file_contents: "fn test_not_unreachable() -> Result<(), Box> { + let x: u32 = foo(); + if x > 5 { + bar(); + return true; + } + std::fs::remove_dir(\"I don't exist and will definitely fail/so yeahhhh...\")?; + unreachable!(); + }", + file: Path::new(""), + ignore_mods: RefCell::new(HashSet::new()), + }; + let parser = parse_file(ctx.file_contents).unwrap(); + let mut analysis = SourceAnalysis::new(); + analysis.process_items(&parser.items, &ctx); + let lines = analysis.get_line_analysis(ctx.file.to_path_buf()); + assert!(!lines.ignore.contains(&Lines::Line(1))); + assert!(!lines.ignore.contains(&Lines::Line(2))); + assert!(!lines.ignore.contains(&Lines::Line(3))); + assert!(!lines.ignore.contains(&Lines::Line(4))); + assert!(!lines.ignore.contains(&Lines::Line(5))); + assert!(!lines.ignore.contains(&Lines::Line(6))); + assert!(!lines.ignore.contains(&Lines::Line(7))); + assert!(lines.ignore.contains(&Lines::Line(8))); + + let ctx = Context { + config: &config, + file_contents: "fn excluded_from_coverage(option: bool) -> bool { + if option { + return true; + } + if !option { + return false; + } + unreachable!(); + } + ", + file: Path::new(""), + ignore_mods: RefCell::new(HashSet::new()), + }; + let parser = parse_file(ctx.file_contents).unwrap(); + let mut analysis = SourceAnalysis::new(); + analysis.process_items(&parser.items, &ctx); + let lines = analysis.get_line_analysis(ctx.file.to_path_buf()); + assert!(!lines.ignore.contains(&Lines::Line(1))); + assert!(!lines.ignore.contains(&Lines::Line(2))); + assert!(!lines.ignore.contains(&Lines::Line(3))); + assert!(!lines.ignore.contains(&Lines::Line(4))); + assert!(!lines.ignore.contains(&Lines::Line(5))); + assert!(!lines.ignore.contains(&Lines::Line(6))); + assert!(!lines.ignore.contains(&Lines::Line(7))); + assert!(lines.ignore.contains(&Lines::Line(8))); +} + +#[test] +fn unreachable_include_loops() { + let config = Config::default(); + let ctx = Context { + config: &config, + file_contents: "fn test_not_unreachable() { + loop { + bar(); + } + unreachable!(); + }", + file: Path::new(""), + ignore_mods: RefCell::new(HashSet::new()), + }; + let parser = parse_file(ctx.file_contents).unwrap(); + let mut analysis = SourceAnalysis::new(); + analysis.process_items(&parser.items, &ctx); + let lines = analysis.get_line_analysis(ctx.file.to_path_buf()); + assert!(!lines.ignore.contains(&Lines::Line(1))); + assert!(!lines.ignore.contains(&Lines::Line(2))); + assert!(!lines.ignore.contains(&Lines::Line(3))); + assert!(!lines.ignore.contains(&Lines::Line(4))); + assert!(lines.ignore.contains(&Lines::Line(5))); + + let ctx = Context { + config: &config, + file_contents: "fn test_not_unreachable() { + while true { + bar(); + } + unreachable!(); + }", + file: Path::new(""), + ignore_mods: RefCell::new(HashSet::new()), + }; + let parser = parse_file(ctx.file_contents).unwrap(); + let mut analysis = SourceAnalysis::new(); + analysis.process_items(&parser.items, &ctx); + let lines = analysis.get_line_analysis(ctx.file.to_path_buf()); + assert!(!lines.ignore.contains(&Lines::Line(1))); + assert!(!lines.ignore.contains(&Lines::Line(2))); + assert!(!lines.ignore.contains(&Lines::Line(3))); + assert!(!lines.ignore.contains(&Lines::Line(4))); + assert!(lines.ignore.contains(&Lines::Line(5))); + + let ctx = Context { + config: &config, + file_contents: "fn test_not_unreachable() -> usize { + for i in &[1,2,3,4] { + return *i; + } + unreachable!(); + }", + file: Path::new(""), + ignore_mods: RefCell::new(HashSet::new()), + }; + let parser = parse_file(ctx.file_contents).unwrap(); + let mut analysis = SourceAnalysis::new(); + analysis.process_items(&parser.items, &ctx); + let lines = analysis.get_line_analysis(ctx.file.to_path_buf()); + assert!(!lines.ignore.contains(&Lines::Line(1))); + assert!(!lines.ignore.contains(&Lines::Line(2))); + assert!(!lines.ignore.contains(&Lines::Line(3))); + assert!(!lines.ignore.contains(&Lines::Line(4))); + assert!(lines.ignore.contains(&Lines::Line(5))); +} + +#[test] +fn single_line_callables() { + let config = Config::default(); + let ctx = Context { + config: &config, + file_contents: "struct A; + impl A { + fn foo() {} + fn bar(i: i32) {} + } + + fn foo() {} + fn bar(i: i32) {} + + fn blah() { + foo(); + A::foo(); + bar(2); + A::bar(2); + } + ", + file: Path::new(""), + ignore_mods: RefCell::new(HashSet::new()), + }; + let parser = parse_file(ctx.file_contents).unwrap(); + let mut analysis = SourceAnalysis::new(); + analysis.process_items(&parser.items, &ctx); + let lines = analysis.get_line_analysis(ctx.file.to_path_buf()); + assert!(!lines.ignore.contains(&Lines::Line(11))); + assert!(!lines.ignore.contains(&Lines::Line(12))); + assert!(!lines.ignore.contains(&Lines::Line(13))); + assert!(!lines.ignore.contains(&Lines::Line(14))); +} From 0e5e52a63615e52b2865f0b8f60a5790a10ad421 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Sep 2021 09:50:51 +0100 Subject: [PATCH 12/32] Bump syn from 1.0.76 to 1.0.77 (#838) Bumps [syn](https://github.com/dtolnay/syn) from 1.0.76 to 1.0.77. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/1.0.76...1.0.77) --- updated-dependencies: - dependency-name: syn dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 620170687c..66157be974 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -780,9 +780,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.76" +version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" +checksum = "5239bc68e0fef57495900cfea4e8dc75596d9a319d7e16b1e0a440d24e6fe0a0" dependencies = [ "proc-macro2", "quote", From 41a391febf53043d17e9f90e46fd467082467739 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Sep 2021 08:32:47 +0100 Subject: [PATCH 13/32] Bump nix from 0.22.1 to 0.23.0 (#839) Bumps [nix](https://github.com/nix-rust/nix) from 0.22.1 to 0.23.0. - [Release notes](https://github.com/nix-rust/nix/releases) - [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md) - [Commits](https://github.com/nix-rust/nix/compare/v0.22.1...v0.23.0) --- updated-dependencies: - dependency-name: nix dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66157be974..f010677cc5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,9 +60,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "byteorder" @@ -394,9 +394,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.99" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" +checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" [[package]] name = "libgit2-sys" @@ -505,9 +505,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.22.1" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7555d6c7164cc913be1ce7f95cbecdabda61eb2ccd89008524af306fb7f5031" +checksum = "f305c2c2e4c39a82f7bf0bf65fb557f9070ce06781d4f2454295cc34b1c43188" dependencies = [ "bitflags", "cc", diff --git a/Cargo.toml b/Cargo.toml index d2baef952d..ddc7dc2538 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,7 @@ cfg-if = "1.0.0" [target.'cfg(target_os = "linux")'.dependencies] libc = "0.2.94" -nix = "0.22.1" +nix = "0.23.0" procfs = "0.10" [features] From 8a95211d0164db0293d90a09ea1d876910af392c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Oct 2021 09:05:58 +0100 Subject: [PATCH 14/32] Bump syn from 1.0.77 to 1.0.78 (#840) Bumps [syn](https://github.com/dtolnay/syn) from 1.0.77 to 1.0.78. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/1.0.77...1.0.78) --- updated-dependencies: - dependency-name: syn dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f010677cc5..54c861f10b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -780,9 +780,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.77" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5239bc68e0fef57495900cfea4e8dc75596d9a319d7e16b1e0a440d24e6fe0a0" +checksum = "a4eac2e6c19f5c3abc0c229bea31ff0b9b091c7b14990e8924b92902a303a0c0" dependencies = [ "proc-macro2", "quote", From f1632976cb631039510981825b5adad3a5c1e0ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Oct 2021 09:06:09 +0100 Subject: [PATCH 15/32] Bump git2 from 0.13.22 to 0.13.23 (#841) Bumps [git2](https://github.com/rust-lang/git2-rs) from 0.13.22 to 0.13.23. - [Release notes](https://github.com/rust-lang/git2-rs/releases) - [Commits](https://github.com/rust-lang/git2-rs/compare/0.13.22...0.13.23) --- updated-dependencies: - dependency-name: git2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54c861f10b..5743d9e3db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -290,9 +290,9 @@ dependencies = [ [[package]] name = "git2" -version = "0.13.22" +version = "0.13.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c1cbbfc9a1996c6af82c2b4caf828d2c653af4fcdbb0e5674cc966eee5a4197" +checksum = "2a8057932925d3a9d9e4434ea016570d37420ddb1ceed45a174d577f24ed6700" dependencies = [ "bitflags", "libc", @@ -400,9 +400,9 @@ checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" [[package]] name = "libgit2-sys" -version = "0.12.23+1.2.0" +version = "0.12.24+1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29730a445bae719db3107078b46808cc45a5b7a6bae3f31272923af969453356" +checksum = "ddbd6021eef06fb289a8f54b3c2acfdd85ff2a585dfbb24b8576325373d2152c" dependencies = [ "cc", "libc", From d223148b17f3e54137e01599ea8305265a241254 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Oct 2021 08:41:10 +0100 Subject: [PATCH 16/32] Bump syn from 1.0.78 to 1.0.79 (#842) Bumps [syn](https://github.com/dtolnay/syn) from 1.0.78 to 1.0.79. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/1.0.78...1.0.79) --- updated-dependencies: - dependency-name: syn dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5743d9e3db..217dd499be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -780,9 +780,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4eac2e6c19f5c3abc0c229bea31ff0b9b091c7b14990e8924b92902a303a0c0" +checksum = "9eb7253273c3b779fe08145f0b4774faf4453f41c5346aff3c7c958e2d6d4380" dependencies = [ "proc-macro2", "quote", From 274c34d2f66a65bb0fd4d6c1c486543682b8426a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Oct 2021 08:41:26 +0100 Subject: [PATCH 17/32] Bump quote from 1.0.9 to 1.0.10 (#843) Bumps [quote](https://github.com/dtolnay/quote) from 1.0.9 to 1.0.10. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.9...1.0.10) --- updated-dependencies: - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 217dd499be..5426fa3d16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -626,9 +626,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" dependencies = [ "proc-macro2", ] From c9a4634705d999235dd8c3901161592f9bcdf3e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Oct 2021 08:41:42 +0100 Subject: [PATCH 18/32] Bump tracing-subscriber from 0.2.24 to 0.2.25 (#844) Bumps [tracing-subscriber](https://github.com/tokio-rs/tracing) from 0.2.24 to 0.2.25. - [Release notes](https://github.com/tokio-rs/tracing/releases) - [Commits](https://github.com/tokio-rs/tracing/compare/tracing-subscriber-0.2.24...tracing-subscriber-0.2.25) --- updated-dependencies: - dependency-name: tracing-subscriber dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5426fa3d16..aa9f12e494 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -875,9 +875,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd0568dbfe3baf7048b7908d2b32bca0d81cd56bec6d2a8f894b01d74f86be3" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" dependencies = [ "ansi_term 0.12.1", "chrono", diff --git a/Cargo.toml b/Cargo.toml index ddc7dc2538..e664cda231 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ humantime-serde = "1" indexmap = { version = "1.7.0", features = ["serde-1"] } lazy_static = "1.0" tracing = { version = "0.1", default-features = false } -tracing-subscriber = {version = "0.2.24", default-features = false, features = ["env-filter", "fmt", "chrono", "ansi", "smallvec", "tracing-log"]} +tracing-subscriber = {version = "0.2.25", default-features = false, features = ["env-filter", "fmt", "chrono", "ansi", "smallvec", "tracing-log"]} memmap = "0.7.0" object = "0.24" proc-macro2 = { version = "1.0", features = ["span-locations"] } From a5a81d3e36b026bebd53986ccccac884b4069651 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Oct 2021 08:42:01 +0100 Subject: [PATCH 19/32] Bump tracing from 0.1.28 to 0.1.29 (#845) Bumps [tracing](https://github.com/tokio-rs/tracing) from 0.1.28 to 0.1.29. - [Release notes](https://github.com/tokio-rs/tracing/releases) - [Commits](https://github.com/tokio-rs/tracing/compare/tracing-0.1.28...tracing-0.1.29) --- updated-dependencies: - dependency-name: tracing dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa9f12e494..f3e167af71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -844,9 +844,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8" +checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", @@ -855,9 +855,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46125608c26121c81b0c6d693eab5a420e416da7e43c426d2e8f7df8da8a3acf" +checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" dependencies = [ "lazy_static", ] From 4a3376b46f04481be28291e6c2e5493f446e60c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Oct 2021 08:31:19 +0100 Subject: [PATCH 20/32] Bump syn from 1.0.79 to 1.0.80 (#847) Bumps [syn](https://github.com/dtolnay/syn) from 1.0.79 to 1.0.80. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/1.0.79...1.0.80) --- updated-dependencies: - dependency-name: syn dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f3e167af71..59b57485e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -780,9 +780,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.79" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eb7253273c3b779fe08145f0b4774faf4453f41c5346aff3c7c958e2d6d4380" +checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194" dependencies = [ "proc-macro2", "quote", From 6330128bbd1cbaf02c55257cb76e77369bdae7f7 Mon Sep 17 00:00:00 2001 From: xd009642 Date: Sat, 9 Oct 2021 13:38:41 +0100 Subject: [PATCH 21/32] Fixes #848 doc test attribute `no_run` (#849) This takes the existing should_panic code and makes it less specialised so it just works with an attribute passed into the function. Then uses this to get the prefixes for the no_run doctests and skips adding any tests marked as no_run --- CHANGELOG.md | 8 ++++++ src/cargo.rs | 41 ++++++++++++++++++----------- tests/data/doctest_norun/Cargo.lock | 7 +++++ tests/data/doctest_norun/Cargo.toml | 8 ++++++ tests/data/doctest_norun/src/lib.rs | 11 ++++++++ tests/doc_coverage.rs | 17 ++++++++++++ 6 files changed, 76 insertions(+), 16 deletions(-) create mode 100644 tests/data/doctest_norun/Cargo.lock create mode 100644 tests/data/doctest_norun/Cargo.toml create mode 100644 tests/data/doctest_norun/src/lib.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 28af0e892a..f23e246408 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,14 @@ From 2019 onwards, all notable changes to tarpaulin will be documented in this file. +## [Unreleased] +### Added +- Added support for doctest `no_run` attribute + +### Changed + +### Removed + ## [0.18.2] 2021-09-05 ### Added diff --git a/src/cargo.rs b/src/cargo.rs index e057ef119d..899f0bb475 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -290,9 +290,24 @@ fn run_cargo( .filter_map(|e| e.ok()) .filter(|e| matches!(e.metadata(), Ok(ref m) if m.is_file() && m.len() != 0)) .collect::>(); - let should_panics = get_panic_candidates(&dir_entries, config); + let should_panics = get_attribute_candidates(&dir_entries, config, "should_panic"); + let no_runs = get_attribute_candidates(&dir_entries, config, "no_run"); for dt in &dir_entries { let mut tb = TestBinary::new(dt.path().to_path_buf(), ty); + + if let Some(meta) = DocTestBinaryMeta::new(dt.path()) { + if no_runs + .get(&meta.prefix) + .map(|x| x.contains(&meta.line)) + .unwrap_or(false) + { + info!("Skipping no_run doctest: {}", dt.path().display()); + continue; + } + if let Some(lines) = should_panics.get(&meta.prefix) { + tb.should_panic |= lines.contains(&meta.line); + } + } let mut current_dir = dt.path(); loop { if current_dir.is_dir() && current_dir.join("Cargo.toml").exists() { @@ -306,12 +321,6 @@ fn run_cargo( None => break, } } - // Now to do my magic! - if let Some(meta) = DocTestBinaryMeta::new(dt.path()) { - if let Some(lines) = should_panics.get(&meta.prefix) { - tb.should_panic |= lines.contains(&meta.line); - } - } result.push(tb); } } @@ -356,10 +365,14 @@ fn is_prefix_match(prefix: &str, entry: &Path) -> bool { /// /// Currently all doctest files take the pattern of `{name}_{line}_{number}` where name is the /// path to the file with directory separators and dots replaced with underscores. Therefore -/// each name could potentially map to many files as `src_some_folder_foo_rs_0_1` could go to +/// each name could potentially map to many files as `src_some_folder_foo_rs_1_1` could go to /// `src/some/folder_foo.rs` or `src/some/folder/foo.rs` here we're going to work on a heuristic /// that any matching file is good because we can't do any better -fn get_panic_candidates(tests: &[DirEntry], config: &Config) -> HashMap> { +fn get_attribute_candidates( + tests: &[DirEntry], + config: &Config, + attribute: &str, +) -> HashMap> { let mut result = HashMap::new(); let mut checked_files = HashSet::new(); let root = config.root(); @@ -372,7 +385,7 @@ fn get_panic_candidates(tests: &[DirEntry], config: &Config) -> HashMap HashMap io::Result> { +fn find_str_in_file(file: &Path, value: &str) -> io::Result> { let f = File::open(file)?; let reader = BufReader::new(f); let lines = reader .lines() .enumerate() - .filter(|(_, l)| { - l.as_ref() - .map(|x| x.contains("should_panic")) - .unwrap_or(false) - }) + .filter(|(_, l)| l.as_ref().map(|x| x.contains(value)).unwrap_or(false)) .map(|(i, _)| i + 1) // Move from line index to line number .collect(); Ok(lines) diff --git a/tests/data/doctest_norun/Cargo.lock b/tests/data/doctest_norun/Cargo.lock new file mode 100644 index 0000000000..90942053d8 --- /dev/null +++ b/tests/data/doctest_norun/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "doctest_norun" +version = "0.1.0" diff --git a/tests/data/doctest_norun/Cargo.toml b/tests/data/doctest_norun/Cargo.toml new file mode 100644 index 0000000000..9790600c6b --- /dev/null +++ b/tests/data/doctest_norun/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "doctest_norun" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tests/data/doctest_norun/src/lib.rs b/tests/data/doctest_norun/src/lib.rs new file mode 100644 index 0000000000..3f71843f61 --- /dev/null +++ b/tests/data/doctest_norun/src/lib.rs @@ -0,0 +1,11 @@ + + + +/// This function doesn't do much +/// +/// ```no_run +/// panic!("Don't run me") +/// ``` +pub fn do_something() { + todo!() +} diff --git a/tests/doc_coverage.rs b/tests/doc_coverage.rs index f15ab2a53b..027177f2dc 100644 --- a/tests/doc_coverage.rs +++ b/tests/doc_coverage.rs @@ -119,3 +119,20 @@ fn doc_test_compile_fail() { assert!(launch_tarpaulin(&config, &None).is_err()); } + +#[test] +fn doc_test_no_run() { + let mut config = Config::default(); + config.verbose = true; + config.force_clean = false; + config.test_timeout = Duration::from_secs(60); + let test_dir = get_test_path("doctest_norun"); + env::set_current_dir(&test_dir).unwrap(); + config.manifest = test_dir; + config.manifest.push("Cargo.toml"); + + config.run_types = vec![RunType::Doctests]; + + let (_, ret) = launch_tarpaulin(&config, &None).unwrap(); + assert_eq!(ret, 0); +} From e857d7e1a645b34f43babd1dac65f38b93ff8507 Mon Sep 17 00:00:00 2001 From: xd009642 Date: Sun, 10 Oct 2021 16:36:14 +0100 Subject: [PATCH 22/32] Fixes #846 crate level attrs (#851) When an outer attribute is used on a file i.e. `#![cfg(not(tarpaulin_include))] to exclude it, if this file is a lib.rs, mod.rs or .rs all other files in that module should be excluded. Now when one of these attributes is picked up tarpaulin will check if any files covered by it have been processed and if so wipe all the analysis and set them to ignore all, then for future files that match the module path it will ignore them as well. --- CHANGELOG.md | 1 + src/source_analysis/mod.rs | 45 ++++++++++++++++--- src/statemachine/instrumented.rs | 1 + tests/data/crate_level_ignores/Cargo.lock | 14 ++++++ tests/data/crate_level_ignores/Cargo.toml | 6 +++ .../workspace_1/Cargo.lock | 7 +++ .../workspace_1/Cargo.toml | 8 ++++ .../workspace_1/src/bar.rs | 4 ++ .../workspace_1/src/bar/baz.rs | 9 ++++ .../workspace_1/src/foo/bar.rs | 5 +++ .../workspace_1/src/foo/mod.rs | 3 ++ .../workspace_1/src/lib.rs | 22 +++++++++ .../workspace_main/Cargo.toml | 9 ++++ .../workspace_main/src/lib.rs | 14 ++++++ .../workspace_main/src/something.rs | 10 +++++ tests/mod.rs | 5 +++ 16 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 tests/data/crate_level_ignores/Cargo.lock create mode 100644 tests/data/crate_level_ignores/Cargo.toml create mode 100644 tests/data/crate_level_ignores/workspace_1/Cargo.lock create mode 100644 tests/data/crate_level_ignores/workspace_1/Cargo.toml create mode 100644 tests/data/crate_level_ignores/workspace_1/src/bar.rs create mode 100644 tests/data/crate_level_ignores/workspace_1/src/bar/baz.rs create mode 100644 tests/data/crate_level_ignores/workspace_1/src/foo/bar.rs create mode 100644 tests/data/crate_level_ignores/workspace_1/src/foo/mod.rs create mode 100644 tests/data/crate_level_ignores/workspace_1/src/lib.rs create mode 100644 tests/data/crate_level_ignores/workspace_main/Cargo.toml create mode 100644 tests/data/crate_level_ignores/workspace_main/src/lib.rs create mode 100644 tests/data/crate_level_ignores/workspace_main/src/something.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index f23e246408..ec23e6caa4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ file. ## [Unreleased] ### Added - Added support for doctest `no_run` attribute +- Add support for source filter via inner attributes ### Changed diff --git a/src/source_analysis/mod.rs b/src/source_analysis/mod.rs index 8e9d56f413..7c062b4f80 100644 --- a/src/source_analysis/mod.rs +++ b/src/source_analysis/mod.rs @@ -235,17 +235,16 @@ impl LineAnalysis { } } +#[derive(Default)] pub struct SourceAnalysis { pub lines: HashMap, pub branches: HashMap, + ignored_modules: Vec, } impl SourceAnalysis { pub fn new() -> Self { - Self { - lines: HashMap::new(), - branches: HashMap::new(), - } + Default::default() } pub fn get_line_analysis(&mut self, path: PathBuf) -> &mut LineAnalysis { @@ -258,6 +257,10 @@ impl SourceAnalysis { .or_insert_with(BranchAnalysis::new) } + fn is_ignored_module(&self, path: &Path) -> bool { + self.ignored_modules.iter().any(|x| path.starts_with(&x)) + } + pub fn get_analysis(config: &Config) -> Self { let mut result = Self::new(); let mut ignored_files: HashSet = HashSet::new(); @@ -296,7 +299,11 @@ impl SourceAnalysis { let skip_cause_test = config.ignore_tests && path.starts_with(root.join("tests")); let skip_cause_example = path.starts_with(root.join("examples")) && !config.run_types.contains(&RunType::Examples); - if !(skip_cause_test || skip_cause_example) { + if self.is_ignored_module(path) { + let mut analysis = LineAnalysis::new(); + analysis.ignore_all(); + self.lines.insert(path.to_path_buf(), analysis); + } else if !(skip_cause_test || skip_cause_example) { let file = File::open(file); if let Ok(mut file) = file { let mut content = String::new(); @@ -335,6 +342,34 @@ impl SourceAnalysis { } maybe_ignore_first_line(path, &mut self.lines); } else { + // Now we need to ignore not only this file but if it is a lib.rs or + // mod.rs we need to get the others + let bad_module = match ( + path.parent(), + path.file_name().map(|x| x.to_string_lossy()), + ) { + (Some(p), Some(n)) => { + if n == "lib.rs" || n == "mod.rs" { + Some(p.to_path_buf()) + } else { + let ignore = p.join(n.trim_end_matches(".rs")); + if ignore.exists() && ignore.is_dir() { + Some(ignore) + } else { + None + } + } + } + _ => None, + }; + // Kill it with fire!` + if let Some(module) = bad_module { + self.lines + .iter_mut() + .filter(|(k, _)| k.starts_with(module.as_path())) + .for_each(|(_, v)| v.ignore_all()); + self.ignored_modules.push(module); + } let analysis = self.get_line_analysis(path.to_path_buf()); analysis.ignore_span(file.span()); } diff --git a/src/statemachine/instrumented.rs b/src/statemachine/instrumented.rs index 8db7949517..195a6ba182 100644 --- a/src/statemachine/instrumented.rs +++ b/src/statemachine/instrumented.rs @@ -1,3 +1,4 @@ +#![allow(dead_code)] use crate::config::Config; use crate::errors::RunError; use crate::process_handling::RunningProcessHandle; diff --git a/tests/data/crate_level_ignores/Cargo.lock b/tests/data/crate_level_ignores/Cargo.lock new file mode 100644 index 0000000000..cfa8b6e8d5 --- /dev/null +++ b/tests/data/crate_level_ignores/Cargo.lock @@ -0,0 +1,14 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "crate_level_ignores" +version = "0.1.0" +dependencies = [ + "workspace_1", +] + +[[package]] +name = "workspace_1" +version = "0.1.0" diff --git a/tests/data/crate_level_ignores/Cargo.toml b/tests/data/crate_level_ignores/Cargo.toml new file mode 100644 index 0000000000..d15c9845c1 --- /dev/null +++ b/tests/data/crate_level_ignores/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] +members = [ + "workspace_1", + "workspace_main", +] + diff --git a/tests/data/crate_level_ignores/workspace_1/Cargo.lock b/tests/data/crate_level_ignores/workspace_1/Cargo.lock new file mode 100644 index 0000000000..30303aa639 --- /dev/null +++ b/tests/data/crate_level_ignores/workspace_1/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "workspace_1" +version = "0.1.0" diff --git a/tests/data/crate_level_ignores/workspace_1/Cargo.toml b/tests/data/crate_level_ignores/workspace_1/Cargo.toml new file mode 100644 index 0000000000..7a5a8c54e5 --- /dev/null +++ b/tests/data/crate_level_ignores/workspace_1/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "workspace_1" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tests/data/crate_level_ignores/workspace_1/src/bar.rs b/tests/data/crate_level_ignores/workspace_1/src/bar.rs new file mode 100644 index 0000000000..9a4e18405a --- /dev/null +++ b/tests/data/crate_level_ignores/workspace_1/src/bar.rs @@ -0,0 +1,4 @@ + +#![cfg(not(tarpaulin_include))] + +pub mod baz; diff --git a/tests/data/crate_level_ignores/workspace_1/src/bar/baz.rs b/tests/data/crate_level_ignores/workspace_1/src/bar/baz.rs new file mode 100644 index 0000000000..b14adc426f --- /dev/null +++ b/tests/data/crate_level_ignores/workspace_1/src/bar/baz.rs @@ -0,0 +1,9 @@ + + +pub fn print_bye() { + println!("BYE"); +} + +pub fn divide(x: i32, y: i32) -> i32 { + x / y +} diff --git a/tests/data/crate_level_ignores/workspace_1/src/foo/bar.rs b/tests/data/crate_level_ignores/workspace_1/src/foo/bar.rs new file mode 100644 index 0000000000..d79ce7d83c --- /dev/null +++ b/tests/data/crate_level_ignores/workspace_1/src/foo/bar.rs @@ -0,0 +1,5 @@ + + +pub fn shout_name(x: &str) { + println!("OI {}", x.to_uppercase()); +} diff --git a/tests/data/crate_level_ignores/workspace_1/src/foo/mod.rs b/tests/data/crate_level_ignores/workspace_1/src/foo/mod.rs new file mode 100644 index 0000000000..2f895f56f8 --- /dev/null +++ b/tests/data/crate_level_ignores/workspace_1/src/foo/mod.rs @@ -0,0 +1,3 @@ +#![cfg(not(tarpaulin_include))] + +pub mod bar; diff --git a/tests/data/crate_level_ignores/workspace_1/src/lib.rs b/tests/data/crate_level_ignores/workspace_1/src/lib.rs new file mode 100644 index 0000000000..53dd182deb --- /dev/null +++ b/tests/data/crate_level_ignores/workspace_1/src/lib.rs @@ -0,0 +1,22 @@ + +pub mod foo; +pub mod bar; + +fn print_hello() { + println!("HellO"); +} + +fn multiply(x: i32, y: i32) -> i32 { + x * y +} + +#[cfg(test)] +mod tests { + pub use super::*; + + #[test] + fn it_works() { + print_hello(); + assert_eq!(6, multiply(2, 3)); + } +} diff --git a/tests/data/crate_level_ignores/workspace_main/Cargo.toml b/tests/data/crate_level_ignores/workspace_main/Cargo.toml new file mode 100644 index 0000000000..bd47cb1581 --- /dev/null +++ b/tests/data/crate_level_ignores/workspace_main/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "crate_level_ignores" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +workspace_1 = { path = "../workspace_1" } diff --git a/tests/data/crate_level_ignores/workspace_main/src/lib.rs b/tests/data/crate_level_ignores/workspace_main/src/lib.rs new file mode 100644 index 0000000000..3321d56f83 --- /dev/null +++ b/tests/data/crate_level_ignores/workspace_main/src/lib.rs @@ -0,0 +1,14 @@ +#![cfg(not(tarpaulin_include))] + +pub mod something; + +pub use workspace_1::*; + + +#[cfg(test)] +mod tests { + #[test] + fn it_also_works() { + assert_eq!(2 + 2, 4); + } +} diff --git a/tests/data/crate_level_ignores/workspace_main/src/something.rs b/tests/data/crate_level_ignores/workspace_main/src/something.rs new file mode 100644 index 0000000000..bb9655f58f --- /dev/null +++ b/tests/data/crate_level_ignores/workspace_main/src/something.rs @@ -0,0 +1,10 @@ + + +fn uncovered_function(len: usize, inc: i32) -> Vec { + let mut x = vec![]; + for i in 0..len { + let val = i as i32 * inc; + x.push(val) + } + x +} diff --git a/tests/mod.rs b/tests/mod.rs index aa17f0685c..601a04f486 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -325,3 +325,8 @@ fn follow_exes_down() { config.force_clean = false; check_percentage_with_config("follow_exe", 1.0f64, true, config); } + +#[test] +fn handle_module_level_exclude_attrs() { + check_percentage("crate_level_ignores", 1.0f64, true); +} From 36d7df4565101331d920ae55dba833ee8fdeec84 Mon Sep 17 00:00:00 2001 From: xd009642 Date: Sun, 10 Oct 2021 19:36:47 +0100 Subject: [PATCH 23/32] Fixes #837 Ci-build docker with actions (#852) Build and push out our docker images using github actions on every commit to develop and once a week via cron --- .github/workflows/docker.yml | 48 ++++++++++++++++++++++++++++++++++++ .github/workflows/rust.yml | 7 ------ 2 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000000..b817133d7f --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,48 @@ +name: docker +on: + push: + branches: + - develop + schedule: + - cron: '0 0 * * 0' +jobs: + build_images: + runs-on: ubuntu-latest + strategy: + matrix: + image: ['', '-slim', '-nightly', '-nightly-slim'] + branch: ['master', 'develop'] + steps: + - uses: actions/checkout@v2 + with: + ref: ${{ matrix.branch }} + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: build_image + run: | + if [[ "${{ matrix.branch }}" = "master" ]]; then + export NAME="latest" + else + export NAME="${{ matrix.branch }}" + fi \ + && docker build -t xd009642/tarpaulin:$NAME${{ matrix.image }} -f Dockerfile${{ matrix.image}} . \ + && docker push xd009642/tarpaulin:$NAME${{ matrix.image }} \ + - uses: oprypin/find-latest-tag@v1 + id: tarpaulin + with: + repository: xd009642/tarpaulin + releases-only: true + if: matrix.branch == 'master' + - name: checkout_last_release + uses: actions/checkout@v2 + with: + ref: ${{ steps.tarpaulin.outputs.tag }} + if: matrix.branch == 'master' + - name: build_last_release + run: | + docker build -t xd009642/tarpaulin:${{ steps.tarpaulin.outputs.tag }}${{ matrix.image }} -f Dockerfile${{ matrix.image}} . \ + && docker push xd009642/tarpaulin:${{ steps.tarpaulin.outputs.tag }}${{ matrix.image }} \ + if: matrix.branch == 'master' diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 02432916d5..9c60e6f610 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -43,13 +43,6 @@ jobs: if: matrix.version == 'nightly' - name: check formatting run: cargo fmt -- --check - - name: notify docker hub - run: | - curl --request POST \ - --header 'Content-Type: application/json' \ - --data '{"build": true}' \ - https://registry.hub.docker.com/u/xd009642/tarpaulin/trigger/${{ secrets.DOCKER_TOKEN }}/ - if: github.ref == 'ref/heads/master' || github.ref == 'refs/heads/develop' windows: runs-on: windows-latest strategy: From 0fc3af30771806f7e35999790901938bdfa614b8 Mon Sep 17 00:00:00 2001 From: xd009642 Date: Sun, 10 Oct 2021 23:21:59 +0100 Subject: [PATCH 24/32] Revert dead-code disabling. Spotted there was an issue with -Z instrument-coverage ignoring files which aren't used. So no dead-code is in instrumented builds that aren't on windows (where it's presence causes segfaults) --- CHANGELOG.md | 1 + src/cargo.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec23e6caa4..9ba10af193 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ file. - Add support for source filter via inner attributes ### Changed +- [INTERNAL] Made link-dead-code apply for non-windows llvm instrumentation builds ### Removed diff --git a/src/cargo.rs b/src/cargo.rs index 899f0bb475..7c196a3d04 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -569,7 +569,8 @@ fn clean_doctest_folder>(doctest_dir: P) { fn handle_llvm_flags(value: &mut String, config: &Config) { if config.engine() == TraceEngine::Llvm { value.push_str("-Z instrument-coverage "); - } else { + } + if cfg!(not(windows)) { value.push_str(" -C link-dead-code "); } } From 737df1c97a3d3e9a9565077225dc0d0f075d7f3d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Oct 2021 09:44:23 +0100 Subject: [PATCH 25/32] Bump proc-macro2 from 1.0.29 to 1.0.30 (#854) Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.29 to 1.0.30. - [Release notes](https://github.com/alexcrichton/proc-macro2/releases) - [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.29...1.0.30) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59b57485e7..b18ded731b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -593,9 +593,9 @@ checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" [[package]] name = "proc-macro2" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" +checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70" dependencies = [ "unicode-xid", ] From 7ede9c162550fc535486a5250a4679d357af9a0b Mon Sep 17 00:00:00 2001 From: Lyra Date: Wed, 13 Oct 2021 23:06:24 +0200 Subject: [PATCH 26/32] Unify the code for ImplItemMethod and ItemFn (#853) * Unify the code for ImplItemMethod and ItemFn * Use ItemFn for default methods in traits * Force coverage in trait default functions and in generic impls/generic functions --- src/source_analysis/items.rs | 79 ++++++++++++------------------------ 1 file changed, 27 insertions(+), 52 deletions(-) diff --git a/src/source_analysis/items.rs b/src/source_analysis/items.rs index cc687544a3..6ff937944b 100644 --- a/src/source_analysis/items.rs +++ b/src/source_analysis/items.rs @@ -1,5 +1,4 @@ use crate::source_analysis::prelude::*; -use quote::ToTokens; use std::path::PathBuf; use syn::{spanned::Spanned, *}; @@ -17,7 +16,7 @@ impl SourceAnalysis { analysis.ignore_tokens(i); } Item::Mod(ref i) => self.visit_mod(&i, ctx), - Item::Fn(ref i) => self.visit_fn(&i, ctx), + Item::Fn(ref i) => self.visit_fn(&i, ctx, false), Item::Struct(ref i) => { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(i); @@ -95,11 +94,12 @@ impl SourceAnalysis { } } - fn visit_fn(&mut self, func: &ItemFn, ctx: &Context) { + fn visit_fn(&mut self, func: &ItemFn, ctx: &Context, force_cover: bool) { let mut test_func = false; let mut ignored_attr = false; let mut is_inline = false; let mut ignore_span = false; + let is_generic = !func.sig.generics.params.is_empty(); for attr in &func.attrs { if let Ok(x) = attr.parse_meta() { let id = x.path(); @@ -125,7 +125,7 @@ impl SourceAnalysis { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); analysis.ignore_tokens(func); } else { - if is_inline { + if is_inline || is_generic || force_cover { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); // We need to force cover! analysis.cover_span(func.block.brace_token.span, Some(ctx.file_contents)); @@ -158,23 +158,20 @@ impl SourceAnalysis { for item in &trait_item.items { if let TraitItem::Method(ref i) = *item { if self.check_attr_list(&i.attrs, ctx) { - if let Some(ref block) = i.default { + let item = i.clone(); + if let Some(block) = item.default { + let item_fn = ItemFn { + attrs: item.attrs, + // Trait functions inherit visibility from the trait + vis: trait_item.vis.clone(), + sig: item.sig, + block: Box::new(block), + }; + // We visit the function and force cover it + self.visit_fn(&item_fn, ctx, true); + } else { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); - analysis.cover_token_stream( - item.into_token_stream(), - Some(ctx.file_contents), - ); - self.visit_generics(&i.sig.generics, ctx); - let analysis = self.get_line_analysis(ctx.file.to_path_buf()); - analysis - .ignore - .remove(&Lines::Line(i.sig.span().start().line)); - - // Ignore multiple lines of fn decl - let decl_start = i.sig.fn_token.span().start().line + 1; - let stmts_start = block.span().start().line; - let lines = (decl_start..(stmts_start + 1)).collect::>(); - analysis.add_to_ignore(&lines); + analysis.ignore_tokens(i); } } else { let analysis = self.get_line_analysis(ctx.file.to_path_buf()); @@ -198,40 +195,18 @@ impl SourceAnalysis { if check_cover { for item in &impl_blk.items { if let ImplItem::Method(ref i) = *item { - if self.check_attr_list(&i.attrs, ctx) { - { - let analysis = self.get_line_analysis(ctx.file.to_path_buf()); - analysis - .cover_token_stream(i.into_token_stream(), Some(ctx.file_contents)); - } - if self - .process_statements(&i.block.stmts, ctx) - .is_unreachable() - { - let analysis = self.get_line_analysis(ctx.file.to_path_buf()); - // if the body of this method is unreachable, this means that the method - // cannot be called, and is unreachable - analysis.ignore_tokens(i); - return; - } + let item = i.clone(); + let item_fn = ItemFn { + attrs: item.attrs, + vis: item.vis, + sig: item.sig, + block: Box::new(item.block), + }; - self.visit_generics(&i.sig.generics, ctx); - let analysis = self.get_line_analysis(ctx.file.to_path_buf()); - analysis.ignore.remove(&Lines::Line(i.span().start().line)); + // If the impl is on a generic, we need to force cover + let force_cover = !impl_blk.generics.params.is_empty(); - // Ignore multiple lines of fn decl - let decl_start = i.sig.fn_token.span().start().line + 1; - let stmts_start = i.block.span().start().line; - let lines = (decl_start..(stmts_start + 1)).collect::>(); - analysis.add_to_ignore(&lines); - } else { - let analysis = self.get_line_analysis(ctx.file.to_path_buf()); - analysis.ignore_tokens(item); - } - let analysis = self.get_line_analysis(ctx.file.to_path_buf()); - for a in &i.attrs { - analysis.ignore_tokens(a); - } + self.visit_fn(&item_fn, ctx, force_cover); } } self.visit_generics(&impl_blk.generics, ctx); From 5076245a55472129472cf9fc72a7455ee612625b Mon Sep 17 00:00:00 2001 From: xd009642 Date: Wed, 13 Oct 2021 22:10:21 +0100 Subject: [PATCH 27/32] Update changelog for #853 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ba10af193..8a4169e5f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ file. ### Changed - [INTERNAL] Made link-dead-code apply for non-windows llvm instrumentation builds +- Consolidate fn/impl-fn/trait-fn source analysis to use same implementation for consistency ### Removed From c54ad803241fa7298633fde89a723ecb12bca50f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Oct 2021 09:52:22 +0100 Subject: [PATCH 28/32] Bump procfs from 0.10.1 to 0.11.0 (#855) Bumps [procfs](https://github.com/eminence/procfs) from 0.10.1 to 0.11.0. - [Release notes](https://github.com/eminence/procfs/releases) - [Commits](https://github.com/eminence/procfs/compare/v0.10.1...v0.11.0) --- updated-dependencies: - dependency-name: procfs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b18ded731b..13287fb89d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -602,9 +602,9 @@ dependencies = [ [[package]] name = "procfs" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95e344cafeaeefe487300c361654bcfc85db3ac53619eeccced29f5ea18c4c70" +checksum = "3f2e7eea7c1d7beccbd5acc1e37ac844afccf176525674aad26ece3de1fc7733" dependencies = [ "bitflags", "byteorder", diff --git a/Cargo.toml b/Cargo.toml index e664cda231..46dbe4715b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ cfg-if = "1.0.0" [target.'cfg(target_os = "linux")'.dependencies] libc = "0.2.94" nix = "0.23.0" -procfs = "0.10" +procfs = "0.11" [features] default = [] From 187f5ac3b44954f0bd7fe594ea6ac003b46eba43 Mon Sep 17 00:00:00 2001 From: MPThLee Date: Fri, 22 Oct 2021 18:23:26 +0900 Subject: [PATCH 29/32] Update README as codecov action v1 is deprecated. (#856) See also: https://github.com/codecov/codecov-action#%EF%B8%8F--deprecration-of-v1 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 65b1ccdc2e..cc0d4d58da 100644 --- a/README.md +++ b/README.md @@ -425,7 +425,7 @@ jobs: cargo +nightly tarpaulin --verbose --all-features --workspace --timeout 120 --out Xml - name: Upload to codecov.io - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v2 with: # token: ${{secrets.CODECOV_TOKEN}} # not required for public repos fail_ci_if_error: true From f48445716cffe87576747cd8ab1d059bf9df2fab Mon Sep 17 00:00:00 2001 From: xd009642 Date: Sat, 23 Oct 2021 13:05:04 +0100 Subject: [PATCH 30/32] Fixes #857 (plus some other stuff) (#858) * Make some things public * Fixes #857 * update changelog --- CHANGELOG.md | 2 ++ src/lib.rs | 6 +++--- src/path_utils.rs | 2 +- tests/data/not_a_file.rs/Cargo.lock | 7 +++++++ tests/data/not_a_file.rs/Cargo.toml | 8 ++++++++ tests/data/not_a_file.rs/src/lib.rs | 7 +++++++ tests/mod.rs | 23 +++++++++++++++++++++++ 7 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 tests/data/not_a_file.rs/Cargo.lock create mode 100644 tests/data/not_a_file.rs/Cargo.toml create mode 100644 tests/data/not_a_file.rs/src/lib.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a4169e5f4..04655c0d76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ file. ### Changed - [INTERNAL] Made link-dead-code apply for non-windows llvm instrumentation builds - Consolidate fn/impl-fn/trait-fn source analysis to use same implementation for consistency +- Add check to make sure a `DirEntry` with a .rs extension is actually a file and not a directory fixes #857 +- Make `path_utils`, `source_analysis` and `statemachine` public modules ### Removed diff --git a/src/lib.rs b/src/lib.rs index e56c55b425..1be2c8f5d3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,11 +17,11 @@ pub mod cargo; pub mod config; pub mod errors; pub mod event_log; -mod path_utils; +pub mod path_utils; mod process_handling; pub mod report; -mod source_analysis; -mod statemachine; +pub mod source_analysis; +pub mod statemachine; pub mod test_loader; pub mod traces; diff --git a/src/path_utils.rs b/src/path_utils.rs index 14c59b9d61..c62a0a84a7 100644 --- a/src/path_utils.rs +++ b/src/path_utils.rs @@ -7,7 +7,7 @@ use walkdir::{DirEntry, WalkDir}; /// Returns true if the file is a rust source file pub fn is_source_file(entry: &DirEntry) -> bool { let p = entry.path(); - p.extension() == Some(OsStr::new("rs")) + p.is_file() && p.extension() == Some(OsStr::new("rs")) } /// Returns true if the folder is a target folder diff --git a/tests/data/not_a_file.rs/Cargo.lock b/tests/data/not_a_file.rs/Cargo.lock new file mode 100644 index 0000000000..b18c7eed2e --- /dev/null +++ b/tests/data/not_a_file.rs/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "not_a_file" +version = "0.1.0" diff --git a/tests/data/not_a_file.rs/Cargo.toml b/tests/data/not_a_file.rs/Cargo.toml new file mode 100644 index 0000000000..d71c7ad255 --- /dev/null +++ b/tests/data/not_a_file.rs/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "not_a_file" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tests/data/not_a_file.rs/src/lib.rs b/tests/data/not_a_file.rs/src/lib.rs new file mode 100644 index 0000000000..31e1bb209f --- /dev/null +++ b/tests/data/not_a_file.rs/src/lib.rs @@ -0,0 +1,7 @@ +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } +} diff --git a/tests/mod.rs b/tests/mod.rs index 601a04f486..b16c1dce84 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -1,6 +1,7 @@ use crate::utils::get_test_path; use cargo_tarpaulin::config::{Config, ConfigWrapper, Mode, RunType}; use cargo_tarpaulin::launch_tarpaulin; +use cargo_tarpaulin::path_utils::*; use cargo_tarpaulin::traces::TraceMap; use clap::App; use std::env; @@ -330,3 +331,25 @@ fn follow_exes_down() { fn handle_module_level_exclude_attrs() { check_percentage("crate_level_ignores", 1.0f64, true); } + +#[test] +fn dot_rs_in_dir_name() { + // issue #857 + let mut config = Config::default(); + config.force_clean = false; + + let restore_dir = env::current_dir().unwrap(); + let test_dir = get_test_path("not_a_file.rs"); + env::set_current_dir(&test_dir).unwrap(); + config.manifest = test_dir; + config.manifest.push("Cargo.toml"); + + let (res, _ret) = launch_tarpaulin(&config, &None).unwrap(); + env::set_current_dir(&restore_dir).unwrap(); + + assert_eq!(res.files().len(), 1); + + for dir in get_source_walker(&config) { + assert!(dir.path().is_file()); + } +} From ae514db309d556628a9560f20b9ea76b420cd63b Mon Sep 17 00:00:00 2001 From: xd009642 Date: Sat, 23 Oct 2021 15:51:50 +0100 Subject: [PATCH 31/32] Add fork child to pid_map fixes #790 (#859) * Add fork child to pid_map * Fix tests * Fix formating --- CHANGELOG.md | 1 + src/statemachine/linux.rs | 16 +++++++++++- tests/data/fork-test/Cargo.lock | 16 ++++++++++++ tests/data/fork-test/Cargo.toml | 9 +++++++ tests/data/fork-test/src/lib.rs | 45 +++++++++++++++++++++++++++++++++ tests/mod.rs | 6 +++++ 6 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 tests/data/fork-test/Cargo.lock create mode 100644 tests/data/fork-test/Cargo.toml create mode 100644 tests/data/fork-test/src/lib.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 04655c0d76..8fce5c7ac4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ file. - Consolidate fn/impl-fn/trait-fn source analysis to use same implementation for consistency - Add check to make sure a `DirEntry` with a .rs extension is actually a file and not a directory fixes #857 - Make `path_utils`, `source_analysis` and `statemachine` public modules +- Add fork child to PID map to fix #790 ### Removed diff --git a/src/statemachine/linux.rs b/src/statemachine/linux.rs index 3e6424d893..299621ca36 100644 --- a/src/statemachine/linux.rs +++ b/src/statemachine/linux.rs @@ -570,7 +570,21 @@ impl<'a> LinuxData<'a> { } }, PTRACE_EVENT_FORK | PTRACE_EVENT_VFORK => { - trace!("Caught fork event. Child {:?}", get_event_data(child)); + if let Ok(fork_child) = get_event_data(child) { + trace!("Caught fork event. Child {}", fork_child); + let parent = if let Some(process) = self.get_traced_process_mut(child) { + // Counting a fork as a new thread ? + process.thread_count += 1; + Some(process.parent) + } else { + None + }; + if let Some(parent) = parent { + self.pid_map.insert(Pid::from_raw(fork_child as _), parent); + } + } else { + trace!("No event data for child"); + } Ok(( TestState::wait_state(), TracerAction::Continue(child.into()), diff --git a/tests/data/fork-test/Cargo.lock b/tests/data/fork-test/Cargo.lock new file mode 100644 index 0000000000..892f9ca313 --- /dev/null +++ b/tests/data/fork-test/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "fork-test" +version = "0.1.0" +dependencies = [ + "libc", +] + +[[package]] +name = "libc" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce" diff --git a/tests/data/fork-test/Cargo.toml b/tests/data/fork-test/Cargo.toml new file mode 100644 index 0000000000..2493df7832 --- /dev/null +++ b/tests/data/fork-test/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "fork-test" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +libc = "0.2.103" diff --git a/tests/data/fork-test/src/lib.rs b/tests/data/fork-test/src/lib.rs new file mode 100644 index 0000000000..92e5f15c95 --- /dev/null +++ b/tests/data/fork-test/src/lib.rs @@ -0,0 +1,45 @@ +#[test] +pub fn test1() { + fn child(f: F) { + match unsafe { libc::fork() } { + 0 => { + f(); + unsafe { + libc::_exit(0); + } + }, + -1 => unreachable!(), + pid => unsafe { + libc::waitpid(pid, core::ptr::null_mut(), 0); + }, + } + } + + child(|| ()); +} + +#[test] +pub fn test2() { + match unsafe { libc::fork() } { + 0 => unsafe { libc::_exit(0); }, + -1 => unreachable!(), + pid => unsafe { + libc::waitpid(pid, core::ptr::null_mut(), 0); + }, + } +} + +#[test] +pub fn test3() { + match unsafe { libc::fork() } { + 0 => { + unsafe { + libc::_exit(0); + } + }, + -1 => unreachable!(), + pid => unsafe { + libc::waitpid(pid, core::ptr::null_mut(), 0); + }, + } +} diff --git a/tests/mod.rs b/tests/mod.rs index b16c1dce84..fbe8815bbb 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -332,6 +332,12 @@ fn handle_module_level_exclude_attrs() { check_percentage("crate_level_ignores", 1.0f64, true); } +#[test] +fn handle_forks() { + // Some false negatives on more recent compilers so lets just aim for >90% and 0 return code + check_percentage("fork-test", 0.9f64, true); +} + #[test] fn dot_rs_in_dir_name() { // issue #857 From c2b86b6e6e6ba8a497ebb399de2a56889598c06b Mon Sep 17 00:00:00 2001 From: xd009642 Date: Sun, 24 Oct 2021 15:00:56 +0100 Subject: [PATCH 32/32] Prepare for release --- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 8 ++++++-- travis-install.sh | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13287fb89d..5370ca28c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,7 +90,7 @@ dependencies = [ [[package]] name = "cargo-tarpaulin" -version = "0.18.2" +version = "0.18.3" dependencies = [ "cargo_metadata", "cfg-if 1.0.0", diff --git a/Cargo.toml b/Cargo.toml index 46dbe4715b..f3e1606b9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargo-tarpaulin" -version = "0.18.2" +version = "0.18.3" authors = ["Daniel McKenna "] description = "Cargo-Tarpaulin is a tool to determine code coverage achieved via tests" repository = "https://github.com/xd009642/tarpaulin" diff --git a/README.md b/README.md index cc0d4d58da..1987a9bd6e 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Below is the help-text for a thorough explanation of the flags and features available: ``` -cargo-tarpaulin version: 0.18.2 +cargo-tarpaulin version: 0.18.3 Tool to analyse test coverage of cargo projects USAGE: @@ -266,7 +266,11 @@ my crate [keygraph-rs](https://github.com/xd009642/keygraph-rs). Before tarpaulin 0.13.4 you could ignore code in blocks with `#[cfg_attr(tarpaulin, skip)]` this has changed with 0.13.4 and onwards -and the new instructions are described below. +and the new instructions are described below. If you get compiler errors +mentioning unknown attribute skip use the `--avoid-cfg-tarpaulin` flag, this +affects a small number of users as it wasn't a largely adopted feature so also +look to updating your code or seeing if any of your dependencies are out of +date. Tarpaulin allows you to ignore modules or functions using attributes. Below is an example of ignoring the main function in a project: diff --git a/travis-install.sh b/travis-install.sh index 1bd116b6d1..0c7c42bd73 100755 --- a/travis-install.sh +++ b/travis-install.sh @@ -1,2 +1,2 @@ #!/bin/bash -curl -sL https://github.com/xd009642/tarpaulin/releases/download/0.18.2/cargo-tarpaulin-0.18.2-travis.tar.gz | tar xvz -C $HOME/.cargo/bin +curl -sL https://github.com/xd009642/tarpaulin/releases/download/0.18.3/cargo-tarpaulin-0.18.3-travis.tar.gz | tar xvz -C $HOME/.cargo/bin