From 046edd54ab71b242895c9dddecfe642dde0309d6 Mon Sep 17 00:00:00 2001 From: John DiSanti Date: Tue, 11 Oct 2022 12:46:13 -0700 Subject: [PATCH] Remove `cargo-check-external-types` (#1820) This tool now has its own repository: https://github.com/awslabs/cargo-check-external-types --- tools/Dockerfile | 5 +- tools/cargo-check-external-types/Cargo.lock | 630 ------------------ tools/cargo-check-external-types/Cargo.toml | 27 - tools/cargo-check-external-types/LICENSE | 175 ----- tools/cargo-check-external-types/README.md | 61 -- .../cargo-check-external-types/additional-ci | 10 - tools/cargo-check-external-types/src/cargo.rs | 121 ---- .../cargo-check-external-types/src/config.rs | 144 ---- tools/cargo-check-external-types/src/error.rs | 276 -------- tools/cargo-check-external-types/src/lib.rs | 22 - tools/cargo-check-external-types/src/main.rs | 232 ------- tools/cargo-check-external-types/src/path.rs | 93 --- .../cargo-check-external-types/src/visitor.rs | 579 ---------------- .../test-workspace/.gitignore | 1 - .../test-workspace/Cargo.toml | 2 - .../test-workspace/external-lib/Cargo.toml | 7 - .../test-workspace/external-lib/src/lib.rs | 42 -- .../test-workspace/test-crate/Cargo.toml | 8 - .../test-workspace/test-crate/src/lib.rs | 159 ----- .../test-crate/src/test_union.rs | 24 - .../test-reexports-crate/Cargo.toml | 8 - .../test-reexports-crate/src/lib.rs | 16 - .../allow-some-types-expected-output.txt | 39 -- .../tests/allow-some-types.toml | 6 - .../tests/default-config-expected-output.txt | 369 ---------- .../tests/integration_test.rs | 77 --- ...t-format-markdown-table-expected-output.md | 44 -- .../tests/test-reexports-expected-output.md | 57 -- tools/ci-build/scripts/check-tools | 1 - 29 files changed, 3 insertions(+), 3232 deletions(-) delete mode 100644 tools/cargo-check-external-types/Cargo.lock delete mode 100644 tools/cargo-check-external-types/Cargo.toml delete mode 100644 tools/cargo-check-external-types/LICENSE delete mode 100644 tools/cargo-check-external-types/README.md delete mode 100755 tools/cargo-check-external-types/additional-ci delete mode 100644 tools/cargo-check-external-types/src/cargo.rs delete mode 100644 tools/cargo-check-external-types/src/config.rs delete mode 100644 tools/cargo-check-external-types/src/error.rs delete mode 100644 tools/cargo-check-external-types/src/lib.rs delete mode 100644 tools/cargo-check-external-types/src/main.rs delete mode 100644 tools/cargo-check-external-types/src/path.rs delete mode 100644 tools/cargo-check-external-types/src/visitor.rs delete mode 100644 tools/cargo-check-external-types/test-workspace/.gitignore delete mode 100644 tools/cargo-check-external-types/test-workspace/Cargo.toml delete mode 100644 tools/cargo-check-external-types/test-workspace/external-lib/Cargo.toml delete mode 100644 tools/cargo-check-external-types/test-workspace/external-lib/src/lib.rs delete mode 100644 tools/cargo-check-external-types/test-workspace/test-crate/Cargo.toml delete mode 100644 tools/cargo-check-external-types/test-workspace/test-crate/src/lib.rs delete mode 100644 tools/cargo-check-external-types/test-workspace/test-crate/src/test_union.rs delete mode 100644 tools/cargo-check-external-types/test-workspace/test-reexports-crate/Cargo.toml delete mode 100644 tools/cargo-check-external-types/test-workspace/test-reexports-crate/src/lib.rs delete mode 100644 tools/cargo-check-external-types/tests/allow-some-types-expected-output.txt delete mode 100644 tools/cargo-check-external-types/tests/allow-some-types.toml delete mode 100644 tools/cargo-check-external-types/tests/default-config-expected-output.txt delete mode 100644 tools/cargo-check-external-types/tests/integration_test.rs delete mode 100644 tools/cargo-check-external-types/tests/output-format-markdown-table-expected-output.md delete mode 100644 tools/cargo-check-external-types/tests/test-reexports-expected-output.md diff --git a/tools/Dockerfile b/tools/Dockerfile index 1e61c92387..9d8c0b963b 100644 --- a/tools/Dockerfile +++ b/tools/Dockerfile @@ -51,6 +51,7 @@ ARG cargo_deny_version=0.12.2 ARG cargo_udeps_version=0.1.29 ARG cargo_hack_version=0.5.14 ARG cargo_minimal_versions_version=0.1.4 +ARG cargo_check_external_types_version=0.1.4 ENV RUSTUP_HOME=/opt/rustup \ CARGO_HOME=/opt/cargo \ PATH=/opt/cargo/bin/:${PATH} \ @@ -97,14 +98,14 @@ RUN set -eux; \ cargo install cargo-deny --locked --version ${cargo_deny_version}; \ cargo +${rust_nightly_version} install cargo-udeps --locked --version ${cargo_udeps_version}; \ cargo install cargo-hack --locked --version ${cargo_hack_version}; \ - cargo install cargo-minimal-versions --version ${cargo_minimal_versions_version}; \ + cargo install cargo-minimal-versions --locked --version ${cargo_minimal_versions_version}; \ + cargo install cargo-check-external-types --locked --version ${cargo_check_external_types_version}; \ if [[ "${checkout_smithy_rs_tools}" == "true" ]]; then \ git clone https://github.com/awslabs/smithy-rs.git; \ cd smithy-rs; \ git checkout ${smithy_rs_commit_hash}; \ fi; \ cargo install --locked --path tools/publisher; \ - cargo install --locked --path tools/cargo-check-external-types; \ cargo install --locked --path tools/changelogger; \ cargo install --locked --path tools/crate-hasher; \ cargo install --locked --path tools/sdk-lints; \ diff --git a/tools/cargo-check-external-types/Cargo.lock b/tools/cargo-check-external-types/Cargo.lock deleted file mode 100644 index b35e21c09d..0000000000 --- a/tools/cargo-check-external-types/Cargo.lock +++ /dev/null @@ -1,630 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - -[[package]] -name = "anyhow" -version = "1.0.62" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "camino" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo-check-external-types" -version = "0.1.3" -dependencies = [ - "anyhow", - "cargo_metadata", - "clap", - "owo-colors", - "pest", - "pretty_assertions", - "rustdoc-types", - "serde", - "serde_json", - "test_bin", - "toml", - "tracing", - "tracing-attributes", - "tracing-subscriber", - "wildmatch", -] - -[[package]] -name = "cargo-platform" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo_metadata" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "3.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" -dependencies = [ - "atty", - "bitflags", - "clap_derive", - "clap_lex", - "indexmap", - "lazy_static", - "strsim", - "termcolor", - "textwrap", -] - -[[package]] -name = "clap_derive" -version = "3.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - -[[package]] -name = "ctor" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdffe87e1d521a10f9696f833fe502293ea446d7f256c06128293a4119bdf4cb" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "indexmap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "is_ci" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb" - -[[package]] -name = "itoa" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.132" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "once_cell" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" - -[[package]] -name = "os_str_bytes" -version = "6.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" - -[[package]] -name = "output_vt100" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66" -dependencies = [ - "winapi", -] - -[[package]] -name = "owo-colors" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" -dependencies = [ - "supports-color", -] - -[[package]] -name = "pest" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0560d531d1febc25a3c9398a62a71256c0178f2e3443baedd9ad4bb8c9deb4" -dependencies = [ - "thiserror", - "ucd-trie", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pretty_assertions" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89f989ac94207d048d92db058e4f6ec7342b0971fc58d1271ca148b799b3563" -dependencies = [ - "ansi_term", - "ctor", - "diff", - "output_vt100", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "regex" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" - -[[package]] -name = "rustdoc-types" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a260c376ebec8b6fcd30f518b253772873c5dd8564b45e384aad8a79c62aa6" -dependencies = [ - "serde", -] - -[[package]] -name = "ryu" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" - -[[package]] -name = "semver" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711" -dependencies = [ - "serde", -] - -[[package]] -name = "serde" -version = "1.0.144" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.144" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sharded-slab" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "smallvec" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "supports-color" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4872ced36b91d47bae8a214a683fe54e7078875b399dfa251df346c9b547d1f9" -dependencies = [ - "atty", - "is_ci", -] - -[[package]] -name = "syn" -version = "1.0.99" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "test_bin" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e7a7de15468c6e65dd7db81cf3822c1ec94c71b2a3c1a976ea8e4696c91115c" - -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" - -[[package]] -name = "thiserror" -version = "1.0.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thread_local" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" -dependencies = [ - "once_cell", -] - -[[package]] -name = "toml" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" -dependencies = [ - "serde", -] - -[[package]] -name = "tracing" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" -dependencies = [ - "cfg-if", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" -dependencies = [ - "lazy_static", - "log", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b" -dependencies = [ - "ansi_term", - "matchers", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "ucd-trie" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89570599c4fe5585de2b388aab47e99f7fa4e9238a1399f707a02e356058141c" - -[[package]] -name = "unicode-ident" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wildmatch" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee583bdc5ff1cf9db20e9db5bb3ff4c3089a8f6b8b31aff265c9aba85812db86" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/tools/cargo-check-external-types/Cargo.toml b/tools/cargo-check-external-types/Cargo.toml deleted file mode 100644 index bc888d2592..0000000000 --- a/tools/cargo-check-external-types/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "cargo-check-external-types" -version = "0.1.3" -authors = ["AWS Rust SDK Team ", "John DiSanti "] -description = "Static analysis tool to detect external types exposed in a library's public API." -edition = "2021" -license = "Apache-2.0" -repository = "https://github.com/awslabs/smithy-rs" - -[dependencies] -anyhow = "1" -cargo_metadata = "0.14" -clap = { version = "~3.1.18", features = ["derive"] } -owo-colors = { version = "3", features = ["supports-colors"] } -pest = "2" # For pretty error formatting -rustdoc-types = "0.12" -serde = { version = "1", features = ["derive"] } -serde_json = "1" -toml = "0.5" -tracing = "0.1" -tracing-attributes = "0.1" -tracing-subscriber = { version = "0.3.15", features = ["env-filter"] } -wildmatch = "2" - -[dev-dependencies] -pretty_assertions = "1.1" -test_bin = "0.4" diff --git a/tools/cargo-check-external-types/LICENSE b/tools/cargo-check-external-types/LICENSE deleted file mode 100644 index 67db858821..0000000000 --- a/tools/cargo-check-external-types/LICENSE +++ /dev/null @@ -1,175 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. diff --git a/tools/cargo-check-external-types/README.md b/tools/cargo-check-external-types/README.md deleted file mode 100644 index 820d4c95c6..0000000000 --- a/tools/cargo-check-external-types/README.md +++ /dev/null @@ -1,61 +0,0 @@ -cargo-check-external-types -========================== - -Static analysis tool that detects external types used in a Rust library's public API. -Configuration can be provided to allow certain external types so that this tool can -be used in continuous integration so that types don't unintentionally make it into -the library's API. It can also output a Markdown table of the external types it found. - -Example Output --------------- - -The test suite has a Rust library that [relies on some external types](test-workspace/test-crate/src/lib.rs). -When the tool is run against this library without any configuration, -[it emits errors](tests/default-config-expected-output.txt) -for each occurrence of an external type in the public API. - -When [a config file](tests/allow-some-types.toml) is provided, -the allowed external types [no longer show up in the output](tests/allow-some-types-expected-output.txt). - -When the output format is set to `markdown-table`, then -a [table of external types](tests/output-format-markdown-table-expected-output.md) is output. - -How to Use ----------- - -_Important:_ This tool requires a nightly build of Rust to be installed since it relies on rustdoc JSON output. -It was last tested against nightly-2022-07-25. - -To install, run the following from this README path: - -```bash -cargo install --locked cargo-check-external-types -``` - -Then, in your library crate path, run: -```bash -cargo +nightly check-external-types -``` - -This will produce errors if any external types are used in a public API at all. That's not terribly useful -on its own, so the tool can be given a config file to allow certain types. For example, we can allow -any type in `bytes` with: - -```toml -allowed_external_types = [ - "bytes::*", -] -``` - -Save that file somewhere in your project (in this example, we choose the name `external-types.toml`), and then -run the command with: - -```bash -cargo +nightly check-external-types --config external-types.toml -``` - -License -------- - -This tool is distributed under the terms of Apache License Version 2.0. -See the [LICENSE](LICENSE) file for more information. diff --git a/tools/cargo-check-external-types/additional-ci b/tools/cargo-check-external-types/additional-ci deleted file mode 100755 index 66816d0d60..0000000000 --- a/tools/cargo-check-external-types/additional-ci +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -# -# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -# SPDX-License-Identifier: Apache-2.0 - -set -e -cd "$(dirname "$0")" - -cargo clippy -cargo "+${RUST_NIGHTLY_VERSION}" test diff --git a/tools/cargo-check-external-types/src/cargo.rs b/tools/cargo-check-external-types/src/cargo.rs deleted file mode 100644 index 4cc7b144a3..0000000000 --- a/tools/cargo-check-external-types/src/cargo.rs +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -use crate::here; -use anyhow::{bail, Context, Result}; -use rustdoc_types::{Crate, FORMAT_VERSION}; -use serde::Deserialize; -use std::fs; -use std::path::PathBuf; -use std::process::{Command, Output}; - -#[derive(Deserialize)] -struct CrateFormatVersion { - format_version: u32, -} - -/// Runs the `cargo rustdoc` command required to produce Rustdoc's JSON output with a nightly compiler. -pub struct CargoRustDocJson { - /// Name of the crate (as specified in the Cargo.toml file) - crate_name: String, - /// Path of the crate to examine - crate_path: PathBuf, - /// Expected `target/` directory where the output will be - target_path: PathBuf, - /// Features to enable - features: Vec, -} - -impl CargoRustDocJson { - pub fn new( - crate_name: impl Into, - crate_path: impl Into, - target_path: impl Into, - features: Vec, - ) -> Self { - CargoRustDocJson { - crate_name: crate_name.into(), - crate_path: crate_path.into(), - target_path: target_path.into(), - features, - } - } - - pub fn run(&self) -> Result { - let cargo = std::env::var("CARGO") - .ok() - .unwrap_or_else(|| "cargo".to_string()); - - let mut command = Command::new(&cargo); - command.current_dir(&self.crate_path).arg("rustdoc"); - if !self.features.is_empty() { - command.arg("--no-default-features").arg("--features"); - command.arg(&self.features.join(",")); - } - command - .arg("--") - .arg("--document-private-items") - .arg("-Z") - .arg("unstable-options") - .arg("--output-format") - .arg("json"); - let output = command - .output() - .context(here!("failed to run nightly rustdoc"))?; - handle_failure("rustdoc", &output)?; - - let output_file_name = self - .target_path - .canonicalize() - .context(here!())? - .join(format!("doc/{}.json", self.crate_name.replace('-', "_"))); - - let json = fs::read_to_string(output_file_name).context(here!())?; - let format_version: CrateFormatVersion = serde_json::from_str(&json) - .context("Failed to find `format_version` in rustdoc JSON output.") - .context(here!())?; - if format_version.format_version != FORMAT_VERSION { - bail!( - "The version of rustdoc being used produces JSON format version {0}, but \ - this tool requires format version {1}. This can happen if the locally \ - installed version of rustdoc doesn't match the rustdoc JSON types from \ - the `rustdoc-types` crate.\n\n\ - If this occurs with the latest Rust nightly and the latest version of this \ - tool, then this is a bug, and the tool needs to be upgraded to the latest \ - format version.\n\n\ - Otherwise, you'll need to determine a Rust nightly version that matches \ - this tool's supported format version (or vice versa).", - format_version.format_version, - FORMAT_VERSION - ); - } - let package: Crate = serde_json::from_str(&json) - .context("Failed to parse rustdoc output.") - .context(here!())?; - Ok(package) - } -} - -pub fn handle_failure(operation_name: &str, output: &Output) -> Result<(), anyhow::Error> { - if !output.status.success() { - return Err(capture_error(operation_name, output)); - } - Ok(()) -} - -pub fn capture_error(operation_name: &str, output: &Output) -> anyhow::Error { - let message = format!( - "Failed to {name}:\nStatus: {status}\nStdout: {stdout}\nStderr: {stderr}\n", - name = operation_name, - status = if let Some(code) = output.status.code() { - format!("{}", code) - } else { - "Killed by signal".to_string() - }, - stdout = String::from_utf8_lossy(&output.stdout), - stderr = String::from_utf8_lossy(&output.stderr) - ); - anyhow::Error::msg(message) -} diff --git a/tools/cargo-check-external-types/src/config.rs b/tools/cargo-check-external-types/src/config.rs deleted file mode 100644 index fa74e3c076..0000000000 --- a/tools/cargo-check-external-types/src/config.rs +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -use serde::de::{SeqAccess, Visitor}; -use serde::{Deserialize, Deserializer}; -use std::fmt; -use wildmatch::WildMatch; - -/// Struct reprepsentation of the TOML config files that specify which external types are allowed. -#[derive(Debug, Deserialize)] -pub struct Config { - /// Whether or not to allow types from `alloc`. Defaults to true. - #[serde(default = "default_allow_std")] - pub allow_alloc: bool, - - /// Whether or not to allow types from `core`. Defaults to true. - #[serde(default = "default_allow_std")] - pub allow_core: bool, - - /// Whether or not to allow types from `std`. Defaults to true. - #[serde(default = "default_allow_std")] - pub allow_std: bool, - - /// List of globs for allowed external types - /// - /// For example, to allow every type in a crate: - /// ```toml - /// allowed_external_types = [ - /// "crate_name::*" - /// ] - /// ``` - /// - /// Or, to selectively allow just a module of that crate - /// ```toml - /// allowed_external_types = [ - /// "crate_name::path::to_module::*" - /// ] - /// ``` - #[serde(deserialize_with = "deserialize_vec_wild_match")] - pub allowed_external_types: Vec, -} - -impl Config { - /// Returns true if the given `type_name` is allowed by this config for the given `root_crate_name`. - pub fn allows_type(&self, root_crate_name: &str, type_name: &str) -> bool { - let type_crate_name = &type_name[0..type_name.find("::").unwrap_or(type_name.len())]; - match type_crate_name { - _ if type_crate_name == root_crate_name => true, - "alloc" => self.allow_alloc, - "core" => self.allow_core, - "std" => self.allow_std, - _ => self - .allowed_external_types - .iter() - .any(|glob| glob.matches(type_name)), - } - } -} - -impl Default for Config { - fn default() -> Self { - Self { - allow_alloc: default_allow_std(), - allow_core: default_allow_std(), - allow_std: default_allow_std(), - allowed_external_types: Default::default(), - } - } -} - -const fn default_allow_std() -> bool { - true -} - -struct VecWildMatchDeserializer; - -impl<'de> Visitor<'de> for VecWildMatchDeserializer { - type Value = Vec; - - fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("list of glob strings") - } - - fn visit_seq(self, mut seq: A) -> Result - where - A: SeqAccess<'de>, - { - let mut result = Vec::new(); - while let Some(value) = seq.next_element::<&str>()? { - result.push(WildMatch::new(value)); - } - Ok(result) - } -} - -fn deserialize_vec_wild_match<'de, D>(de: D) -> Result, D::Error> -where - D: Deserializer<'de>, -{ - de.deserialize_any(VecWildMatchDeserializer) -} - -#[cfg(test)] -mod tests { - use super::Config; - use wildmatch::WildMatch; - - #[test] - fn deserialize_config() { - let config = r#" - allow_std = false - allowed_external_types = [ - "test::*", - "another_test::something::*::something", - ] - "#; - let config: Config = toml::from_str(config).unwrap(); - assert!(config.allow_alloc); - assert!(config.allow_core); - assert!(!config.allow_std); - assert!(config.allowed_external_types[0].matches("test::something")); - assert!(!config.allowed_external_types[0].matches("other::something")); - assert!(config.allowed_external_types[1].matches("another_test::something::foo::something")); - assert!(!config.allowed_external_types[1].matches("another_test::other::foo::something")); - } - - #[test] - fn test_allows_type() { - let config = Config { - allowed_external_types: vec![WildMatch::new("one::*"), WildMatch::new("two::*")], - ..Default::default() - }; - assert!(config.allows_type("root", "alloc::System")); - assert!(config.allows_type("root", "std::vec::Vec")); - assert!(config.allows_type("root", "std::path::Path")); - - assert!(config.allows_type("root", "root::thing")); - assert!(config.allows_type("root", "one::thing")); - assert!(config.allows_type("root", "two::thing")); - assert!(!config.allows_type("root", "three::thing")); - } -} diff --git a/tools/cargo-check-external-types/src/error.rs b/tools/cargo-check-external-types/src/error.rs deleted file mode 100644 index fed669eb36..0000000000 --- a/tools/cargo-check-external-types/src/error.rs +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -use anyhow::{Context, Result}; -use owo_colors::{OwoColorize, Stream}; -use pest::Position; -use rustdoc_types::Span; -use std::cmp::Ordering; -use std::collections::HashMap; -use std::fmt; -use std::path::{Path, PathBuf}; - -/// Where the error occurred relative to the [`Path`](crate::path::Path). -/// -/// For example, if the path is a path to a function, then this could point to something -/// specific about that function, such as a specific function argument that is in error. -/// -/// There is overlap in this enum with [`ComponentType`](crate::path::ComponentType) since -/// some paths are specific enough to locate the external type. -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ErrorLocation { - AssocType, - ArgumentNamed(String), - ClosureInput, - ClosureOutput, - ConstGeneric, - Constant, - EnumTupleEntry, - GenericArg, - GenericDefaultBinding, - ImplementedTrait, - QualifiedSelfType, - QualifiedSelfTypeAsTrait, - ReExport, - ReturnValue, - Static, - StructField, - TraitBound, - TypeDef, - WhereBound, -} - -impl fmt::Display for ErrorLocation { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let s = match self { - Self::AssocType => "associated type", - Self::ArgumentNamed(name) => return write!(f, "argument named `{}` of", name), - Self::ClosureInput => "closure input of", - Self::ClosureOutput => "closure output of", - Self::ConstGeneric => "const generic of", - Self::Constant => "constant", - Self::EnumTupleEntry => "enum tuple entry of", - Self::GenericArg => "generic arg of", - Self::GenericDefaultBinding => "generic default binding of", - Self::ImplementedTrait => "implemented trait of", - Self::QualifiedSelfType => "qualified self type", - Self::QualifiedSelfTypeAsTrait => "qualified type `as` trait", - Self::ReExport => "re-export named", - Self::ReturnValue => "return value of", - Self::Static => "static value", - Self::StructField => "struct field of", - Self::TraitBound => "trait bound of", - Self::TypeDef => "typedef type of", - Self::WhereBound => "where bound of", - }; - write!(f, "{}", s) - } -} - -/// Error type for validation errors that get displayed to the user on the CLI. -#[derive(Debug)] -pub enum ValidationError { - UnapprovedExternalTypeRef { - type_name: String, - what: ErrorLocation, - in_what_type: String, - location: Option, - sort_key: String, - }, -} - -impl ValidationError { - pub fn unapproved_external_type_ref( - type_name: impl Into, - what: &ErrorLocation, - in_what_type: impl Into, - location: Option<&Span>, - ) -> Self { - let type_name = type_name.into(); - let in_what_type = in_what_type.into(); - let sort_key = format!( - "{}:{}:{}:{}", - location_sort_key(location), - type_name, - what, - in_what_type - ); - Self::UnapprovedExternalTypeRef { - type_name, - what: what.clone(), - in_what_type, - location: location.cloned(), - sort_key, - } - } - - pub fn type_name(&self) -> &str { - match self { - Self::UnapprovedExternalTypeRef { type_name, .. } => type_name, - } - } - - pub fn location(&self) -> Option<&Span> { - match self { - Self::UnapprovedExternalTypeRef { location, .. } => location.as_ref(), - } - } - - fn sort_key(&self) -> &str { - match self { - Self::UnapprovedExternalTypeRef { sort_key, .. } => sort_key.as_ref(), - } - } - - pub fn fmt_headline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::UnapprovedExternalTypeRef { type_name, .. } => { - let inner = format!( - "Unapproved external type `{}` referenced in public API", - type_name - ); - write!( - f, - "{} {}", - "error:" - .if_supports_color(Stream::Stdout, |text| text.red()) - .if_supports_color(Stream::Stdout, |text| text.bold()), - inner.if_supports_color(Stream::Stdout, |text| text.bold()) - ) - } - } - } - - pub fn subtext(&self) -> String { - match self { - Self::UnapprovedExternalTypeRef { - what, in_what_type, .. - } => format!("in {} `{}`", what, in_what_type), - } - } -} - -fn location_sort_key(location: Option<&Span>) -> String { - if let Some(location) = location { - format!( - "{}:{:07}:{:07}", - location.filename.to_string_lossy(), - location.begin.0, - location.begin.1 - ) - } else { - "none".into() - } -} - -impl Ord for ValidationError { - fn cmp(&self, other: &Self) -> Ordering { - self.partial_cmp(other).unwrap() - } -} - -impl PartialOrd for ValidationError { - fn partial_cmp(&self, other: &Self) -> Option { - self.sort_key().partial_cmp(other.sort_key()) - } -} - -impl Eq for ValidationError {} - -impl PartialEq for ValidationError { - fn eq(&self, other: &Self) -> bool { - self.sort_key() == other.sort_key() - } -} - -impl fmt::Display for ValidationError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.fmt_headline(f) - } -} - -/// Pretty printer for error context. -/// -/// This makes validation errors look similar to the compiler errors from rustc. -pub struct ErrorPrinter { - workspace_root: PathBuf, - file_cache: HashMap, -} - -impl ErrorPrinter { - pub fn new(workspace_root: impl Into) -> Self { - Self { - workspace_root: workspace_root.into(), - file_cache: HashMap::new(), - } - } - - fn get_file_contents(&mut self, path: &Path) -> Result<&str> { - if !self.file_cache.contains_key(path) { - let full_file_name = self.workspace_root.join(path).canonicalize()?; - let contents = std::fs::read_to_string(&full_file_name) - .context("failed to load source file for error context") - .context(full_file_name.to_string_lossy().to_string())?; - self.file_cache.insert(path.to_path_buf(), contents); - } - Ok(self.file_cache.get(path).unwrap()) - } - - pub fn pretty_print_error_context(&mut self, location: &Span, subtext: String) { - match self.get_file_contents(&location.filename) { - Ok(file_contents) => { - let begin = Self::position_from_line_col(file_contents, location.begin); - let end = Self::position_from_line_col(file_contents, location.end); - - // HACK: Using Pest to do the pretty error context formatting for lack of - // knowledge of a smaller library tailored to this use-case - let variant = pest::error::ErrorVariant::<()>::CustomError { message: subtext }; - let err_context = match (begin, end) { - (Some(b), Some(e)) => { - Some(pest::error::Error::new_from_span(variant, b.span(&e))) - } - (Some(b), None) => Some(pest::error::Error::new_from_pos(variant, b)), - _ => None, - }; - if let Some(err_context) = err_context { - println!( - "{}\n", - err_context.with_path(&location.filename.to_string_lossy()) - ); - } - } - Err(err) => { - println!("error: {subtext}"); - println!( - " --> {}:{}:{}", - location.filename.to_string_lossy(), - location.begin.0, - location.begin.1 + 1 - ); - println!(" | Failed to load {:?}", location.filename); - println!(" | relative to {:?}", self.workspace_root); - println!(" | to provide error message context."); - println!(" | Cause: {err:?}"); - } - } - } - - fn position_from_line_col(contents: &str, (line, col): (usize, usize)) -> Option { - let (mut cl, mut cc) = (1, 1); - let content_bytes = contents.as_bytes(); - for (index, &byte) in content_bytes.iter().enumerate() { - if cl == line && cc == col { - return Position::new(contents, index); - } - - cc += 1; - if byte == b'\n' { - cl += 1; - cc = 0; - } - } - None - } -} diff --git a/tools/cargo-check-external-types/src/lib.rs b/tools/cargo-check-external-types/src/lib.rs deleted file mode 100644 index 88b90ef35b..0000000000 --- a/tools/cargo-check-external-types/src/lib.rs +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -pub mod cargo; -pub mod config; -pub mod error; -pub mod path; -pub mod visitor; - -/// A macro for attaching info to error messages pointing to the line of code responsible for the error. -/// [Thanks to dtolnay for this macro](https://github.com/dtolnay/anyhow/issues/22#issuecomment-542309452) -#[macro_export] -macro_rules! here { - () => { - concat!("error at ", file!(), ":", line!(), ":", column!()) - }; - ($message:tt) => { - concat!($message, " (", here!(), ")") - }; -} diff --git a/tools/cargo-check-external-types/src/main.rs b/tools/cargo-check-external-types/src/main.rs deleted file mode 100644 index acb59961d0..0000000000 --- a/tools/cargo-check-external-types/src/main.rs +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -use anyhow::{anyhow, bail}; -use anyhow::{Context, Result}; -use cargo_check_external_types::cargo::CargoRustDocJson; -use cargo_check_external_types::error::ErrorPrinter; -use cargo_check_external_types::here; -use cargo_check_external_types::visitor::Visitor; -use cargo_metadata::{CargoOpt, Metadata}; -use clap::Parser; -use owo_colors::{OwoColorize, Stream}; -use std::borrow::Cow; -use std::fmt; -use std::fs; -use std::path::PathBuf; -use std::process; -use std::str::FromStr; -use tracing_subscriber::prelude::*; -use tracing_subscriber::EnvFilter; - -#[derive(Debug)] -enum OutputFormat { - Errors, - MarkdownTable, -} - -impl fmt::Display for OutputFormat { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(match self { - Self::Errors => "errors", - Self::MarkdownTable => "markdown-table", - }) - } -} - -impl FromStr for OutputFormat { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - match s { - "errors" => Ok(OutputFormat::Errors), - "markdown-table" => Ok(OutputFormat::MarkdownTable), - _ => Err(anyhow!( - "invalid output format: {}. Expected `errors` or `markdown-table`.", - s - )), - } - } -} - -#[derive(clap::Args, Debug)] -struct CheckExternalTypesArgs { - /// Enables all crate features - #[clap(long)] - all_features: bool, - /// Disables default features - #[clap(long)] - no_default_features: bool, - /// Comma delimited list of features to enable in the crate - #[clap(long, use_value_delimiter = true)] - features: Option>, - /// Path to the Cargo manifest - manifest_path: Option, - - /// Path to config toml to read - #[clap(long)] - config: Option, - /// Enable verbose output for debugging - #[clap(short, long)] - verbose: bool, - /// Format to output results in - #[clap(long, default_value_t = OutputFormat::Errors)] - output_format: OutputFormat, -} - -#[derive(Parser, Debug)] -#[clap(author, version, about, bin_name = "cargo")] -enum Args { - CheckExternalTypes(CheckExternalTypesArgs), -} - -enum Error { - ValidationErrors, - Failure(anyhow::Error), -} - -impl From for Error { - fn from(err: anyhow::Error) -> Self { - Error::Failure(err) - } -} - -fn main() { - process::exit(match run_main() { - Ok(_) => 0, - Err(Error::ValidationErrors) => 1, - Err(Error::Failure(err)) => { - println!("{:#}", dbg!(err)); - 2 - } - }) -} - -fn run_main() -> Result<(), Error> { - let Args::CheckExternalTypes(args) = Args::parse(); - if args.verbose { - let filter_layer = EnvFilter::try_from_default_env() - .or_else(|_| EnvFilter::try_new("debug")) - .unwrap(); - let fmt_layer = tracing_subscriber::fmt::layer() - .without_time() - .with_ansi(true) - .with_level(true) - .with_target(false) - .pretty(); - tracing_subscriber::registry() - .with(filter_layer) - .with(fmt_layer) - .init(); - } - - let config = if let Some(config_path) = &args.config { - let contents = fs::read_to_string(config_path).context("failed to read config file")?; - toml::from_str(&contents).context("failed to parse config file")? - } else { - Default::default() - }; - - let mut cargo_metadata_cmd = cargo_metadata::MetadataCommand::new(); - if args.all_features { - cargo_metadata_cmd.features(CargoOpt::AllFeatures); - } - if args.no_default_features { - cargo_metadata_cmd.features(CargoOpt::NoDefaultFeatures); - } - if let Some(features) = args.features { - cargo_metadata_cmd.features(CargoOpt::SomeFeatures(features)); - } - let crate_path = if let Some(manifest_path) = args.manifest_path { - cargo_metadata_cmd.manifest_path(&manifest_path); - manifest_path - .canonicalize() - .context(here!())? - .parent() - .expect("parent path") - .to_path_buf() - } else { - std::env::current_dir() - .context(here!())? - .canonicalize() - .context(here!())? - }; - let cargo_metadata = cargo_metadata_cmd.exec().context(here!())?; - let cargo_features = resolve_features(&cargo_metadata)?; - - eprintln!("Running rustdoc to produce json doc output..."); - let package = CargoRustDocJson::new( - &*cargo_metadata - .root_package() - .as_ref() - .map(|package| Cow::Borrowed(package.name.as_str())) - .unwrap_or_else(|| crate_path.file_name().expect("file name").to_string_lossy()), - &crate_path, - &cargo_metadata.target_directory, - cargo_features, - ) - .run() - .context(here!())?; - - eprintln!("Examining all public types..."); - let errors = Visitor::new(config, package)?.visit_all()?; - match args.output_format { - OutputFormat::Errors => { - let mut error_printer = ErrorPrinter::new(&cargo_metadata.workspace_root); - for error in &errors { - println!("{}", error); - if let Some(location) = error.location() { - error_printer.pretty_print_error_context(location, error.subtext()) - } - } - if !errors.is_empty() { - println!( - "{} {} emitted", - errors.len(), - "errors".if_supports_color(Stream::Stdout, |text| text.red()) - ); - return Err(Error::ValidationErrors); - } - } - OutputFormat::MarkdownTable => { - println!("| Crate | Type | Used In |"); - println!("| --- | --- | --- |"); - let mut rows = Vec::new(); - for error in &errors { - let type_name = error.type_name(); - let crate_name = &type_name[0..type_name.find("::").unwrap_or(type_name.len())]; - let location = error.location().unwrap(); - rows.push(format!( - "| {} | {} | {}:{}:{} |", - crate_name, - type_name, - location.filename.to_string_lossy(), - location.begin.0, - location.begin.1 - )); - } - rows.sort(); - rows.into_iter().for_each(|row| println!("{}", row)); - } - } - - Ok(()) -} - -fn resolve_features(metadata: &Metadata) -> Result> { - let root_package = metadata - .root_package() - .ok_or_else(|| anyhow!("No root package found"))?; - if let Some(resolve) = &metadata.resolve { - let root_node = resolve - .nodes - .iter() - .find(|&n| n.id == root_package.id) - .ok_or_else(|| anyhow!("Failed to find node for root package"))?; - Ok(root_node.features.clone()) - } else { - bail!("Cargo metadata didn't have resolved nodes"); - } -} diff --git a/tools/cargo-check-external-types/src/path.rs b/tools/cargo-check-external-types/src/path.rs deleted file mode 100644 index 29123e63c6..0000000000 --- a/tools/cargo-check-external-types/src/path.rs +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -use rustdoc_types::{Item, Span}; -use std::fmt; - -/// Component type for components in a [`Path`]. -#[derive(Copy, Clone, Debug)] -pub enum ComponentType { - AssocConst, - AssocType, - Constant, - Crate, - Enum, - EnumVariant, - Function, - Method, - Module, - ReExport, - Static, - Struct, - StructField, - Trait, - TypeDef, - Union, -} - -/// Represents one component in a [`Path`]. -#[derive(Clone, Debug)] -struct Component { - typ: ComponentType, - name: String, - span: Option, -} - -impl Component { - fn new(typ: ComponentType, name: String, span: Option) -> Self { - Self { typ, name, span } - } -} - -/// Represents the full path to an item being visited by [`Visitor`](crate::visitor::Visitor). -/// -/// This is equivalent to the type path of that item, which has to be re-assembled since -/// it is lost in the flat structure of the Rustdoc JSON output. -#[derive(Clone, Debug)] -pub struct Path { - stack: Vec, -} - -impl Path { - pub fn new(crate_name: &str) -> Self { - Self { - stack: vec![Component::new( - ComponentType::Crate, - crate_name.into(), - None, - )], - } - } - - pub fn push(&mut self, typ: ComponentType, item: &Item) { - self.push_raw(typ, item.name.as_ref().expect("name"), item.span.as_ref()); - } - - pub fn push_raw(&mut self, typ: ComponentType, name: &str, span: Option<&Span>) { - self.stack - .push(Component::new(typ, name.into(), span.cloned())); - } - - /// Returns the span (file + beginning and end positions) of the last [`Component`] in the stack. - pub fn last_span(&self) -> Option<&Span> { - self.stack.last().and_then(|c| c.span.as_ref()) - } - - /// Returns the [`ComponentType`] of the last [`Component`] in the path. - pub fn last_typ(&self) -> Option { - self.stack.last().map(|c| c.typ) - } -} - -impl fmt::Display for Path { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let names: Vec<&str> = self - .stack - .iter() - .map(|component| component.name.as_str()) - .collect(); - write!(f, "{}", names.join("::")) - } -} diff --git a/tools/cargo-check-external-types/src/visitor.rs b/tools/cargo-check-external-types/src/visitor.rs deleted file mode 100644 index d33bead4c0..0000000000 --- a/tools/cargo-check-external-types/src/visitor.rs +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -use crate::config::Config; -use crate::error::{ErrorLocation, ValidationError}; -use crate::here; -use crate::path::{ComponentType, Path}; -use anyhow::{anyhow, Context, Result}; -use rustdoc_types::{ - Crate, FnDecl, GenericArgs, GenericBound, GenericParamDef, GenericParamDefKind, Generics, Id, - Item, ItemEnum, ItemSummary, Struct, Term, Trait, Type, Union, Variant, Visibility, - WherePredicate, -}; -use std::cell::RefCell; -use std::collections::{BTreeSet, HashMap}; -use tracing::debug; -use tracing_attributes::instrument; - -macro_rules! unstable_rust_feature { - ($name:expr, $documentation_uri:expr) => { - panic!( - "unstable Rust feature '{}' (see {}) is not supported by cargo-check-external-types", - $name, $documentation_uri - ) - }; -} - -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -enum VisibilityCheck { - /// Check to make sure the item is public before visiting it - Default, - /// Assume the item is public and examine it. - /// This is useful for visiting private items that are publically re-exported - AssumePublic, -} - -/// Visits all items in the Rustdoc JSON output to discover external types in public APIs -/// and track them as validation errors if the [`Config`] doesn't allow them. -pub struct Visitor { - config: Config, - root_crate_id: u32, - root_crate_name: String, - index: HashMap, - paths: HashMap, - errors: RefCell>, -} - -impl Visitor { - pub fn new(config: Config, package: Crate) -> Result { - Ok(Visitor { - config, - root_crate_id: Self::root_crate_id(&package)?, - root_crate_name: Self::root_crate_name(&package)?, - index: package.index, - paths: package.paths, - errors: RefCell::new(BTreeSet::new()), - }) - } - - /// This is the entry point for visiting the entire Rustdoc JSON tree, starting - /// from the root module (the only module where `is_crate` is true). - pub fn visit_all(self) -> Result> { - let root_path = Path::new(&self.root_crate_name); - let root_module = self - .index - .values() - .filter_map(|item| { - if let ItemEnum::Module(module) = &item.inner { - Some(module) - } else { - None - } - }) - .find(|module| module.is_crate) - .ok_or_else(|| anyhow!("failed to find crate root module"))?; - - for id in &root_module.items { - let item = self.item(id).context(here!())?; - self.visit_item(&root_path, item, VisibilityCheck::Default)?; - } - Ok(self.errors.take()) - } - - /// Returns true if the given item is public. In some cases, this must be determined - /// by examining the surrounding context. For example, enum variants are public if the - /// enum is public, even if their visibility is set to `Visibility::Default`. - fn is_public(path: &Path, item: &Item) -> bool { - match item.visibility { - Visibility::Public => true, - Visibility::Default => match &item.inner { - // Enum variants are public if the enum is public - ItemEnum::Variant(_) => matches!(path.last_typ(), Some(ComponentType::Enum)), - // Struct fields inside of enum variants are public if the enum is public - ItemEnum::StructField(_) => { - matches!(path.last_typ(), Some(ComponentType::EnumVariant)) - } - // Trait items are public if the trait is public - _ => matches!(path.last_typ(), Some(ComponentType::Trait)), - }, - _ => false, - } - } - - #[instrument(level = "debug", skip(self, path, item), fields(path = %path, name = ?item.name, id = %item.id.0))] - fn visit_item( - &self, - path: &Path, - item: &Item, - visibility_check: VisibilityCheck, - ) -> Result<()> { - if visibility_check == VisibilityCheck::Default && !Self::is_public(path, item) { - return Ok(()); - } - - let mut path = path.clone(); - match &item.inner { - ItemEnum::AssocConst { type_, .. } => { - path.push(ComponentType::AssocConst, item); - self.visit_type(&path, &ErrorLocation::StructField, type_) - .context(here!())?; - } - ItemEnum::AssocType { - bounds, - default, - generics, - } => { - path.push(ComponentType::AssocType, item); - if let Some(typ) = default { - self.visit_type(&path, &ErrorLocation::AssocType, typ).context(here!())?; - } - self.visit_generic_bounds(&path, bounds).context(here!())?; - self.visit_generics(&path, generics).context(here!())?; - } - ItemEnum::Constant(constant) => { - path.push(ComponentType::Constant, item); - self.visit_type(&path, &ErrorLocation::Constant, &constant.type_).context(here!())?; - } - ItemEnum::Enum(enm) => { - path.push(ComponentType::Enum, item); - self.visit_generics(&path, &enm.generics).context(here!())?; - for id in &enm.impls { - self.visit_impl(&path, self.item(id).context(here!())?)?; - } - for id in &enm.variants { - self.visit_item(&path, self.item(id).context(here!())?, VisibilityCheck::Default).context(here!())?; - } - } - ItemEnum::ForeignType => unstable_rust_feature!( - "extern_types", - "https://doc.rust-lang.org/beta/unstable-book/language-features/extern-types.html" - ), - ItemEnum::Function(function) => { - path.push(ComponentType::Function, item); - self.visit_fn_decl(&path, &function.decl).context(here!())?; - self.visit_generics(&path, &function.generics).context(here!())?; - } - ItemEnum::Import(import) => { - if let Some(target_id) = &import.id { - if self.in_root_crate(target_id) { - // Override the visibility check for re-exported items - self.visit_item( - &path, - self.item(target_id).context(here!())?, - VisibilityCheck::AssumePublic - ).context(here!())?; - } - path.push_raw(ComponentType::ReExport, &import.name, item.span.as_ref()); - self.check_external(&path, &ErrorLocation::ReExport, target_id) - .context(here!())?; - } - } - ItemEnum::Method(method) => { - path.push(ComponentType::Method, item); - self.visit_fn_decl(&path, &method.decl).context(here!())?; - self.visit_generics(&path, &method.generics).context(here!())?; - } - ItemEnum::Module(module) => { - if !module.is_crate { - path.push(ComponentType::Module, item); - } - for id in &module.items { - let module_item = self.item(id).context(here!())?; - // Re-exports show up twice in the doc json: once as an `ItemEnum::Import`, - // and once as the type as if it were originating from the root crate (but - // with a different crate ID). We only want to examine the `ItemEnum::Import` - // for re-exports since it includes the correct span where the re-export occurs, - // and we don't want to examine the innards of the re-export. - if module_item.crate_id == self.root_crate_id { - self.visit_item(&path, module_item, VisibilityCheck::Default).context(here!())?; - } - } - } - ItemEnum::OpaqueTy(_) => unstable_rust_feature!("type_alias_impl_trait", "https://doc.rust-lang.org/beta/unstable-book/language-features/type-alias-impl-trait.html"), - ItemEnum::Static(sttc) => { - path.push(ComponentType::Static, item); - self.visit_type(&path, &ErrorLocation::Static, &sttc.type_).context(here!())?; - } - ItemEnum::Struct(strct) => { - path.push(ComponentType::Struct, item); - self.visit_struct(&path, strct).context(here!())?; - } - ItemEnum::StructField(typ) => { - path.push(ComponentType::StructField, item); - self.visit_type(&path, &ErrorLocation::StructField, typ) - .context(here!())?; - } - ItemEnum::Trait(trt) => { - path.push(ComponentType::Trait, item); - self.visit_trait(&path, trt).context(here!())?; - } - ItemEnum::Typedef(typedef) => { - path.push(ComponentType::TypeDef, item); - self.visit_type(&path, &ErrorLocation::TypeDef, &typedef.type_) - .context(here!())?; - self.visit_generics(&path, &typedef.generics).context(here!())?; - } - ItemEnum::TraitAlias(_) => unstable_rust_feature!( - "trait_alias", - "https://doc.rust-lang.org/beta/unstable-book/language-features/trait-alias.html" - ), - ItemEnum::Union(unn) => { - path.push(ComponentType::Union, item); - self.visit_union(&path, unn).context(here!())?; - } - ItemEnum::Variant(variant) => { - path.push(ComponentType::EnumVariant, item); - self.visit_variant(&path, variant).context(here!())?; - } - ItemEnum::ExternCrate { .. } - | ItemEnum::Impl(_) - | ItemEnum::Macro(_) - | ItemEnum::PrimitiveType(_) - | ItemEnum::ProcMacro(_) => {} - } - Ok(()) - } - - #[instrument(level = "debug", skip(self, path, strct), fields(path = %path))] - fn visit_struct(&self, path: &Path, strct: &Struct) -> Result<()> { - self.visit_generics(path, &strct.generics)?; - for id in &strct.fields { - let field = self.item(id).context(here!())?; - self.visit_item(path, field, VisibilityCheck::Default)?; - } - for id in &strct.impls { - self.visit_impl(path, self.item(id).context(here!())?)?; - } - Ok(()) - } - - #[instrument(level = "debug", skip(self, path, unn), fields(path = %path))] - fn visit_union(&self, path: &Path, unn: &Union) -> Result<()> { - self.visit_generics(path, &unn.generics)?; - for id in &unn.fields { - let field = self.item(id).context(here!())?; - self.visit_item(path, field, VisibilityCheck::Default)?; - } - for id in &unn.impls { - self.visit_impl(path, self.item(id).context(here!())?)?; - } - Ok(()) - } - - #[instrument(level = "debug", skip(self, path, trt), fields(path = %path))] - fn visit_trait(&self, path: &Path, trt: &Trait) -> Result<()> { - self.visit_generics(path, &trt.generics)?; - self.visit_generic_bounds(path, &trt.bounds)?; - for id in &trt.items { - let item = self.item(id).context(here!())?; - self.visit_item(path, item, VisibilityCheck::Default)?; - } - Ok(()) - } - - #[instrument(level = "debug", skip(self, path, item), fields(path = %path, id = %item.id.0))] - fn visit_impl(&self, path: &Path, item: &Item) -> Result<()> { - if let ItemEnum::Impl(imp) = &item.inner { - // Ignore blanket implementations - if imp.blanket_impl.is_some() { - return Ok(()); - } - self.visit_generics(path, &imp.generics)?; - for id in &imp.items { - self.visit_item( - path, - self.item(id).context(here!())?, - VisibilityCheck::Default, - )?; - } - if let Some(trait_) = &imp.trait_ { - self.visit_type(path, &ErrorLocation::ImplementedTrait, trait_) - .context(here!())?; - } - } else { - unreachable!("should be passed an Impl item"); - } - Ok(()) - } - - #[instrument(level = "debug", skip(self, path, decl), fields(path = %path))] - fn visit_fn_decl(&self, path: &Path, decl: &FnDecl) -> Result<()> { - for (index, (name, typ)) in decl.inputs.iter().enumerate() { - if index == 0 && name == "self" { - continue; - } - self.visit_type(path, &ErrorLocation::ArgumentNamed(name.into()), typ) - .context(here!())?; - } - if let Some(output) = &decl.output { - self.visit_type(path, &ErrorLocation::ReturnValue, output) - .context(here!())?; - } - Ok(()) - } - - #[instrument(level = "debug", skip(self, path, typ), fields(path = %path))] - fn visit_type(&self, path: &Path, what: &ErrorLocation, typ: &Type) -> Result<()> { - match typ { - Type::ResolvedPath { - id, - args, - param_names, - .. - } => { - self.check_external(path, what, id).context(here!())?; - if let Some(args) = args { - self.visit_generic_args(path, args)?; - } - self.visit_generic_bounds(path, param_names)?; - } - Type::Generic(_) => {} - Type::Primitive(_) => {} - Type::FunctionPointer(fp) => { - self.visit_fn_decl(path, &fp.decl)?; - self.visit_generic_param_defs(path, &fp.generic_params)?; - } - Type::Tuple(types) => { - for typ in types { - self.visit_type(path, &ErrorLocation::EnumTupleEntry, typ)?; - } - } - Type::Slice(typ) => self.visit_type(path, what, typ).context(here!())?, - Type::Array { type_, .. } => self.visit_type(path, what, type_).context(here!())?, - Type::ImplTrait(impl_trait) => { - for bound in impl_trait { - match bound { - GenericBound::TraitBound { - trait_, - generic_params, - .. - } => { - self.visit_type(path, what, trait_)?; - self.visit_generic_param_defs(path, generic_params)?; - } - GenericBound::Outlives(_) => {} - } - } - } - Type::Infer => { - unimplemented!( - "visit_type for Type::Infer: not sure what Rust code triggers this. \ - If you encounter this, please report it with a link to the code it happens with." - ) - } - Type::RawPointer { type_, .. } => { - self.visit_type(path, what, type_).context(here!())? - } - Type::BorrowedRef { type_, .. } => { - self.visit_type(path, what, type_).context(here!())? - } - Type::QualifiedPath { - self_type, trait_, .. - } => { - self.visit_type(path, &ErrorLocation::QualifiedSelfType, self_type)?; - self.visit_type(path, &ErrorLocation::QualifiedSelfTypeAsTrait, trait_)?; - } - } - Ok(()) - } - - #[instrument(level = "debug", skip(self, path, args), fields(path = %path))] - fn visit_generic_args(&self, path: &Path, args: &GenericArgs) -> Result<()> { - match args { - GenericArgs::AngleBracketed { args, bindings } => { - for arg in args { - match arg { - rustdoc_types::GenericArg::Type(typ) => { - self.visit_type(path, &ErrorLocation::GenericArg, typ)? - } - rustdoc_types::GenericArg::Lifetime(_) - | rustdoc_types::GenericArg::Const(_) - | rustdoc_types::GenericArg::Infer => {} - } - } - for binding in bindings { - match &binding.binding { - rustdoc_types::TypeBindingKind::Equality(term) => { - if let Term::Type(typ) = term { - self.visit_type(path, &ErrorLocation::GenericDefaultBinding, typ) - .context(here!())?; - } - } - rustdoc_types::TypeBindingKind::Constraint(bounds) => { - self.visit_generic_bounds(path, bounds)?; - } - } - } - } - GenericArgs::Parenthesized { inputs, output } => { - for input in inputs { - self.visit_type(path, &ErrorLocation::ClosureInput, input) - .context(here!())?; - } - if let Some(output) = output { - self.visit_type(path, &ErrorLocation::ClosureOutput, output) - .context(here!())?; - } - } - } - Ok(()) - } - - #[instrument(level = "debug", skip(self, path, bounds), fields(path = %path))] - fn visit_generic_bounds(&self, path: &Path, bounds: &[GenericBound]) -> Result<()> { - for bound in bounds { - if let GenericBound::TraitBound { - trait_, - generic_params, - .. - } = bound - { - self.visit_type(path, &ErrorLocation::TraitBound, trait_) - .context(here!())?; - self.visit_generic_param_defs(path, generic_params)?; - } - } - Ok(()) - } - - #[instrument(level = "debug", skip(self, path, params), fields(path = %path))] - fn visit_generic_param_defs(&self, path: &Path, params: &[GenericParamDef]) -> Result<()> { - for param in params { - match ¶m.kind { - GenericParamDefKind::Type { - bounds, - default, - synthetic: _, - } => { - self.visit_generic_bounds(path, bounds)?; - if let Some(typ) = default { - self.visit_type(path, &ErrorLocation::GenericDefaultBinding, typ) - .context(here!())?; - } - } - GenericParamDefKind::Const { type_, .. } => { - self.visit_type(path, &ErrorLocation::ConstGeneric, type_) - .context(here!())?; - } - _ => {} - } - } - Ok(()) - } - - #[instrument(level = "debug", skip(self, path, generics), fields(path = %path))] - fn visit_generics(&self, path: &Path, generics: &Generics) -> Result<()> { - self.visit_generic_param_defs(path, &generics.params)?; - for where_pred in &generics.where_predicates { - match where_pred { - WherePredicate::BoundPredicate { - type_, - bounds, - generic_params, - } => { - self.visit_type(path, &ErrorLocation::WhereBound, type_) - .context(here!())?; - self.visit_generic_bounds(path, bounds)?; - self.visit_generic_param_defs(path, generic_params)?; - } - WherePredicate::RegionPredicate { bounds, .. } => { - self.visit_generic_bounds(path, bounds)?; - } - WherePredicate::EqPredicate { lhs, .. } => { - self.visit_type(path, &ErrorLocation::WhereBound, lhs) - .context(here!())?; - } - } - } - Ok(()) - } - - #[instrument(level = "debug", skip(self, path, variant), fields(path = %path))] - fn visit_variant(&self, path: &Path, variant: &Variant) -> Result<()> { - match variant { - Variant::Plain => {} - Variant::Tuple(types) => { - for typ in types { - self.visit_type(path, &ErrorLocation::EnumTupleEntry, typ)?; - } - } - Variant::Struct(ids) => { - for id in ids { - self.visit_item( - path, - self.item(id).context(here!())?, - VisibilityCheck::Default, - )?; - } - } - } - Ok(()) - } - - fn check_external(&self, path: &Path, what: &ErrorLocation, id: &Id) -> Result<()> { - if let Ok(type_name) = self.type_name(id) { - if !self.config.allows_type(&self.root_crate_name, &type_name) { - self.add_error(ValidationError::unapproved_external_type_ref( - self.type_name(id)?, - what, - path.to_string(), - path.last_span(), - )); - } - } - // Crates like `pin_project` do some shenanigans to create and reference types that don't end up - // in the doc index, but that should only happen within the root crate. - else if !id.0.starts_with(&format!("{}:", self.root_crate_id)) { - unreachable!("A type is referencing another type that is not in the index, and that type is from another crate."); - } - Ok(()) - } - - fn add_error(&self, error: ValidationError) { - debug!("detected error {:?}", error); - self.errors.borrow_mut().insert(error); - } - - fn item(&self, id: &Id) -> Result<&Item> { - self.index - .get(id) - .ok_or_else(|| anyhow!("Failed to find item in index for ID {:?}", id)) - .context(here!()) - } - - fn item_summary(&self, id: &Id) -> Option<&ItemSummary> { - self.paths.get(id) - } - - fn type_name(&self, id: &Id) -> Result { - Ok(self.item_summary(id).context(here!())?.path.join("::")) - } - - fn root_crate_id(package: &Crate) -> Result { - Ok(Self::root(package)?.crate_id) - } - - /// Returns true if the given `id` belongs to the root crate - fn in_root_crate(&self, id: &Id) -> bool { - id.0.starts_with(&format!("{}:", self.root_crate_id)) - } - - fn root_crate_name(package: &Crate) -> Result { - Ok(Self::root(package)? - .name - .as_ref() - .expect("root should always have a name") - .clone()) - } - - fn root(package: &Crate) -> Result<&Item> { - package - .index - .get(&package.root) - .ok_or_else(|| anyhow!("root not found in index")) - .context(here!()) - } -} diff --git a/tools/cargo-check-external-types/test-workspace/.gitignore b/tools/cargo-check-external-types/test-workspace/.gitignore deleted file mode 100644 index 03314f77b5..0000000000 --- a/tools/cargo-check-external-types/test-workspace/.gitignore +++ /dev/null @@ -1 +0,0 @@ -Cargo.lock diff --git a/tools/cargo-check-external-types/test-workspace/Cargo.toml b/tools/cargo-check-external-types/test-workspace/Cargo.toml deleted file mode 100644 index 9f50884ad5..0000000000 --- a/tools/cargo-check-external-types/test-workspace/Cargo.toml +++ /dev/null @@ -1,2 +0,0 @@ -[workspace] -members = ["external-lib", "test-crate", "test-reexports-crate"] diff --git a/tools/cargo-check-external-types/test-workspace/external-lib/Cargo.toml b/tools/cargo-check-external-types/test-workspace/external-lib/Cargo.toml deleted file mode 100644 index 6f16ff9320..0000000000 --- a/tools/cargo-check-external-types/test-workspace/external-lib/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "external-lib" -version = "0.1.0" -edition = "2021" -publish = false - -[dependencies] diff --git a/tools/cargo-check-external-types/test-workspace/external-lib/src/lib.rs b/tools/cargo-check-external-types/test-workspace/external-lib/src/lib.rs deleted file mode 100644 index d35c9c1cfc..0000000000 --- a/tools/cargo-check-external-types/test-workspace/external-lib/src/lib.rs +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -//! This crate exports a bunch of types for testing cargo-check-external-types against `test-crate` - -pub struct SomeStruct; -pub struct SomeOtherStruct; - -pub trait SimpleTrait { - fn something(&self) -> u32; -} - -impl SimpleTrait for () { - fn something(&self) -> u32 { - 0 - } -} - -pub trait SimpleGenericTrait { - fn something(&self, thing: T) -> u32; -} - -pub trait AssociatedGenericTrait { - type Input; - type Output; - type Error; - - fn something(&self, input: Self::Input) -> Self::Output; - - fn something_result(&self, input: Self::Input) -> Result; -} - -pub struct SimpleNewType(pub u32); - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct ReprCType { - i: i32, - f: f32, -} diff --git a/tools/cargo-check-external-types/test-workspace/test-crate/Cargo.toml b/tools/cargo-check-external-types/test-workspace/test-crate/Cargo.toml deleted file mode 100644 index f80e062860..0000000000 --- a/tools/cargo-check-external-types/test-workspace/test-crate/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "test-crate" -version = "0.1.0" -edition = "2021" -publish = false - -[dependencies] -external-lib = { path = "../external-lib" } diff --git a/tools/cargo-check-external-types/test-workspace/test-crate/src/lib.rs b/tools/cargo-check-external-types/test-workspace/test-crate/src/lib.rs deleted file mode 100644 index 3b643d226f..0000000000 --- a/tools/cargo-check-external-types/test-workspace/test-crate/src/lib.rs +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -#![feature(generic_associated_types)] -#![allow(dead_code)] - -//! This crate is used to test the cargo-check-external-types by exercising the all possible -//! exposure of external types in a public API. - -pub mod test_union; - -use external_lib::{ - AssociatedGenericTrait, - SimpleNewType, - SimpleTrait, - SomeOtherStruct, - SomeStruct, - // Remove this comment if more lines are needed for imports in the future to preserve line numbers - // Remove this comment if more lines are needed for imports in the future to preserve line numbers - // Remove this comment if more lines are needed for imports in the future to preserve line numbers - // Remove this comment if more lines are needed for imports in the future to preserve line numbers - // Remove this comment if more lines are needed for imports in the future to preserve line numbers - // Remove this comment if more lines are needed for imports in the future to preserve line numbers - // Remove this comment if more lines are needed for imports in the future to preserve line numbers - // Remove this comment if more lines are needed for imports in the future to preserve line numbers -}; - -pub struct LocalStruct; - -pub fn fn_with_local_struct(_local: LocalStruct) -> LocalStruct { - unimplemented!() -} - -fn not_pub_external_in_fn_input(_one: &SomeStruct, _two: impl SimpleTrait) {} - -pub fn external_in_fn_input(_one: &SomeStruct, _two: impl SimpleTrait) {} - -fn not_pub_external_in_fn_output() -> SomeStruct { - unimplemented!() -} -pub fn external_in_fn_output() -> SomeStruct { - unimplemented!() -} - -pub fn external_opaque_type_in_output() -> impl SimpleTrait { - unimplemented!() -} - -fn not_pub_external_in_fn_output_generic() -> Option { - unimplemented!() -} -pub fn external_in_fn_output_generic() -> Option { - unimplemented!() -} - -// Try to trick cargo-check-external-types here by putting something in a private module and re-exporting it -mod private_module { - use external_lib::SomeStruct; - - pub fn something(_one: &SomeStruct) {} -} -pub use private_module::something; - -pub struct StructWithExternalFields { - pub field: SomeStruct, - pub optional_field: Option, -} - -impl StructWithExternalFields { - pub fn new(_field: impl Into, _optional_field: Option) -> Self { - unimplemented!() - } -} - -pub trait TraitReferencingExternals { - fn something(&self, a: SomeStruct) -> LocalStruct; - fn optional_something(&self, a: Option) -> LocalStruct; - fn otherthing(&self) -> SomeStruct; - fn optional_otherthing(&self) -> Option; -} - -pub enum EnumWithExternals { - NormalTuple(LocalStruct), - NormalStruct { - v: LocalStruct, - }, - TupleEnum(SomeStruct, Box), - StructEnum { - some_struct: SomeStruct, - simple_trait: Box, - }, - GenericTupleEnum(T), - GenericStructEnum { - t: T, - }, -} - -impl EnumWithExternals { - pub fn thing(_t: LocalStruct) -> Self { - unimplemented!() - } - pub fn another_thing(_s: S) -> Self { - unimplemented!() - } -} - -pub static SOME_STRUCT: SomeStruct = SomeStruct; -pub const SOME_CONST: SomeStruct = SomeStruct; - -pub mod some_pub_mod { - use external_lib::SomeStruct; - - pub static OPTIONAL_STRUCT: Option = None; - pub const OPTIONAL_CONST: Option = None; -} - -pub type NotExternalReferencing = u32; -pub type ExternalReferencingTypedef = SomeStruct; -pub type OptionalExternalReferencingTypedef = Option; -pub type DynExternalReferencingTypedef = Box; -pub type ExternalReferencingRawPtr = *const SomeStruct; - -pub fn fn_with_external_trait_bounds(_thing: T) -where - I: Into, - O: Into, - E: std::error::Error, - T: AssociatedGenericTrait, -{ -} - -pub trait SomeTraitWithExternalDefaultTypes { - type Thing: SimpleTrait; - type OtherThing: AssociatedGenericTrait< - Input = SomeStruct, - Output = u32, - Error = SomeOtherStruct, - >; - - fn something(&self, input: Self::Thing) -> Self::OtherThing; -} - -pub trait SomeTraitWithGenericAssociatedType { - type MyGAT - where - T: SimpleTrait; - - fn some_fn(&self, thing: Self::MyGAT); -} - -pub struct AssocConstStruct; - -impl AssocConstStruct { - pub const SOME_CONST: u32 = 5; - - pub const OTHER_CONST: SimpleNewType = SimpleNewType(5); -} diff --git a/tools/cargo-check-external-types/test-workspace/test-crate/src/test_union.rs b/tools/cargo-check-external-types/test-workspace/test-crate/src/test_union.rs deleted file mode 100644 index 9b311ed87c..0000000000 --- a/tools/cargo-check-external-types/test-workspace/test-crate/src/test_union.rs +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -use external_lib::{ReprCType, SimpleTrait}; - -#[repr(C)] -pub union SimpleUnion { - pub repr_c: ReprCType, - pub something_else: u64, -} - -impl SimpleUnion { - pub fn repr_c(&self) -> &ReprCType { - &self.repr_c - } -} - -#[repr(C)] -pub union GenericUnion { - pub repr_c: T, - pub something_else: u64, -} diff --git a/tools/cargo-check-external-types/test-workspace/test-reexports-crate/Cargo.toml b/tools/cargo-check-external-types/test-workspace/test-reexports-crate/Cargo.toml deleted file mode 100644 index 8790abe4ff..0000000000 --- a/tools/cargo-check-external-types/test-workspace/test-reexports-crate/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "test-reexports-crate" -version = "0.1.0" -edition = "2021" -publish = false - -[dependencies] -external-lib = { path = "../external-lib" } diff --git a/tools/cargo-check-external-types/test-workspace/test-reexports-crate/src/lib.rs b/tools/cargo-check-external-types/test-workspace/test-reexports-crate/src/lib.rs deleted file mode 100644 index 0b98a08849..0000000000 --- a/tools/cargo-check-external-types/test-workspace/test-reexports-crate/src/lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -pub use external_lib::AssociatedGenericTrait; -pub use external_lib::ReprCType; -pub use external_lib::SimpleTrait; - -pub mod Something { - pub use external_lib::SimpleGenericTrait; - pub use external_lib::SimpleNewType; -} - -pub use external_lib::SomeOtherStruct; -pub use external_lib::SomeStruct; diff --git a/tools/cargo-check-external-types/tests/allow-some-types-expected-output.txt b/tools/cargo-check-external-types/tests/allow-some-types-expected-output.txt deleted file mode 100644 index f954bcf2e1..0000000000 --- a/tools/cargo-check-external-types/tests/allow-some-types-expected-output.txt +++ /dev/null @@ -1,39 +0,0 @@ -error: Unapproved external type `external_lib::AssociatedGenericTrait` referenced in public API - --> test-crate/src/lib.rs:125:1 - | -125 | pub fn fn_with_external_trait_bounds(_thing: T) - | ... -132 | }␊ - | ^ - | - = in trait bound of `test_crate::fn_with_external_trait_bounds` - -error: Unapproved external type `external_lib::AssociatedGenericTrait` referenced in public API - --> test-crate/src/lib.rs:136:5 - | -136 | type OtherThing: AssociatedGenericTrait< - | ... -140 | >;␊ - | ^^ - | - = in trait bound of `test_crate::SomeTraitWithExternalDefaultTypes::OtherThing` - -error: Unapproved external type `external_lib::ReprCType` referenced in public API - --> test-crate/src/test_union.rs:10:5 - | -10 | pub repr_c: ReprCType, - | ^-------------------^ - | - = in struct field of `test_crate::test_union::SimpleUnion::repr_c` - -error: Unapproved external type `external_lib::ReprCType` referenced in public API - --> test-crate/src/test_union.rs:15:5 - | -15 | pub fn repr_c(&self) -> &ReprCType { - | ... -17 | }␊ - | ^ - | - = in return value of `test_crate::test_union::SimpleUnion::repr_c` - -4 errors emitted diff --git a/tools/cargo-check-external-types/tests/allow-some-types.toml b/tools/cargo-check-external-types/tests/allow-some-types.toml deleted file mode 100644 index a43571daaa..0000000000 --- a/tools/cargo-check-external-types/tests/allow-some-types.toml +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -# SPDX-License-Identifier: Apache-2.0 - -allowed_external_types = [ - "external_lib::S*", -] diff --git a/tools/cargo-check-external-types/tests/default-config-expected-output.txt b/tools/cargo-check-external-types/tests/default-config-expected-output.txt deleted file mode 100644 index 5854df7a59..0000000000 --- a/tools/cargo-check-external-types/tests/default-config-expected-output.txt +++ /dev/null @@ -1,369 +0,0 @@ -error: Unapproved external type `external_lib::SimpleTrait` referenced in public API - --> test-crate/src/lib.rs:38:1 - | -38 | pub fn external_in_fn_input(_one: &SomeStruct, _two: impl SimpleTrait) {} - | ^-----------------------------------------------------------------------^ - | - = in argument named `_two` of `test_crate::external_in_fn_input` - -error: Unapproved external type `external_lib::SimpleTrait` referenced in public API - --> test-crate/src/lib.rs:38:1 - | -38 | pub fn external_in_fn_input(_one: &SomeStruct, _two: impl SimpleTrait) {} - | ^-----------------------------------------------------------------------^ - | - = in trait bound of `test_crate::external_in_fn_input` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:38:1 - | -38 | pub fn external_in_fn_input(_one: &SomeStruct, _two: impl SimpleTrait) {} - | ^-----------------------------------------------------------------------^ - | - = in argument named `_one` of `test_crate::external_in_fn_input` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:43:1 - | -43 | pub fn external_in_fn_output() -> SomeStruct { - | ... -45 | }␊ - | ^ - | - = in return value of `test_crate::external_in_fn_output` - -error: Unapproved external type `external_lib::SimpleTrait` referenced in public API - --> test-crate/src/lib.rs:47:1 - | -47 | pub fn external_opaque_type_in_output() -> impl SimpleTrait { - | ... -49 | }␊ - | ^ - | - = in return value of `test_crate::external_opaque_type_in_output` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:54:1 - | -54 | pub fn external_in_fn_output_generic() -> Option { - | ... -56 | }␊ - | ^ - | - = in generic arg of `test_crate::external_in_fn_output_generic` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:62:5 - | -62 | pub fn something(_one: &SomeStruct) {} - | ^------------------------------------^ - | - = in argument named `_one` of `test_crate::something` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:67:5 - | -67 | pub field: SomeStruct, - | ^-------------------^ - | - = in struct field of `test_crate::StructWithExternalFields::field` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:68:5 - | -68 | pub optional_field: Option, - | ^------------------------------------^ - | - = in generic arg of `test_crate::StructWithExternalFields::optional_field` - -error: Unapproved external type `external_lib::SomeOtherStruct` referenced in public API - --> test-crate/src/lib.rs:72:5 - | -72 | pub fn new(_field: impl Into, _optional_field: Option) -> Self { - | ... -74 | }␊ - | ^ - | - = in generic arg of `test_crate::StructWithExternalFields::new` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:72:5 - | -72 | pub fn new(_field: impl Into, _optional_field: Option) -> Self { - | ... -74 | }␊ - | ^ - | - = in generic arg of `test_crate::StructWithExternalFields::new` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:78:5 - | -78 | fn something(&self, a: SomeStruct) -> LocalStruct; - | ^------------------------------------------------^ - | - = in argument named `a` of `test_crate::TraitReferencingExternals::something` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:79:5 - | -79 | fn optional_something(&self, a: Option) -> LocalStruct; - | ^-----------------------------------------------------------------^ - | - = in generic arg of `test_crate::TraitReferencingExternals::optional_something` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:80:5 - | -80 | fn otherthing(&self) -> SomeStruct; - | ^---------------------------------^ - | - = in return value of `test_crate::TraitReferencingExternals::otherthing` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:81:5 - | -81 | fn optional_otherthing(&self) -> Option; - | ^--------------------------------------------------^ - | - = in generic arg of `test_crate::TraitReferencingExternals::optional_otherthing` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:84:1 - | -84 | pub enum EnumWithExternals { - | ... -98 | }␊ - | ^ - | - = in generic default binding of `test_crate::EnumWithExternals` - -error: Unapproved external type `external_lib::SimpleTrait` referenced in public API - --> test-crate/src/lib.rs:89:5 - | -89 | TupleEnum(SomeStruct, Box), - | ^-----------------------------------------^ - | - = in generic arg of `test_crate::EnumWithExternals::TupleEnum` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:89:5 - | -89 | TupleEnum(SomeStruct, Box), - | ^-----------------------------------------^ - | - = in enum tuple entry of `test_crate::EnumWithExternals::TupleEnum` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:91:9 - | -91 | some_struct: SomeStruct, - | ^---------------------^ - | - = in struct field of `test_crate::EnumWithExternals::StructEnum::some_struct` - -error: Unapproved external type `external_lib::SimpleTrait` referenced in public API - --> test-crate/src/lib.rs:92:9 - | -92 | simple_trait: Box, - | ^--------------------------------^ - | - = in generic arg of `test_crate::EnumWithExternals::StructEnum::simple_trait` - -error: Unapproved external type `external_lib::SimpleTrait` referenced in public API - --> test-crate/src/lib.rs:104:5 - | -104 | pub fn another_thing(_s: S) -> Self { - | ... -106 | }␊ - | ^ - | - = in trait bound of `test_crate::EnumWithExternals::another_thing` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:109:1 - | -109 | pub static SOME_STRUCT: SomeStruct = SomeStruct; - | ^----------------------------------------------^ - | - = in static value `test_crate::SOME_STRUCT` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:110:1 - | -110 | pub const SOME_CONST: SomeStruct = SomeStruct; - | ^--------------------------------------------^ - | - = in constant `test_crate::SOME_CONST` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:115:5 - | -115 | pub static OPTIONAL_STRUCT: Option = None; - | ^----------------------------------------------------^ - | - = in generic arg of `test_crate::some_pub_mod::OPTIONAL_STRUCT` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:116:5 - | -116 | pub const OPTIONAL_CONST: Option = None; - | ^--------------------------------------------------^ - | - = in generic arg of `test_crate::some_pub_mod::OPTIONAL_CONST` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:120:1 - | -120 | pub type ExternalReferencingTypedef = SomeStruct; - | ^-----------------------------------------------^ - | - = in typedef type of `test_crate::ExternalReferencingTypedef` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:121:1 - | -121 | pub type OptionalExternalReferencingTypedef = Option; - | ^---------------------------------------------------------------^ - | - = in generic arg of `test_crate::OptionalExternalReferencingTypedef` - -error: Unapproved external type `external_lib::SimpleTrait` referenced in public API - --> test-crate/src/lib.rs:122:1 - | -122 | pub type DynExternalReferencingTypedef = Box; - | ^------------------------------------------------------------^ - | - = in generic arg of `test_crate::DynExternalReferencingTypedef` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:123:1 - | -123 | pub type ExternalReferencingRawPtr = *const SomeStruct; - | ^-----------------------------------------------------^ - | - = in typedef type of `test_crate::ExternalReferencingRawPtr` - -error: Unapproved external type `external_lib::AssociatedGenericTrait` referenced in public API - --> test-crate/src/lib.rs:125:1 - | -125 | pub fn fn_with_external_trait_bounds(_thing: T) - | ... -132 | }␊ - | ^ - | - = in trait bound of `test_crate::fn_with_external_trait_bounds` - -error: Unapproved external type `external_lib::SomeOtherStruct` referenced in public API - --> test-crate/src/lib.rs:125:1 - | -125 | pub fn fn_with_external_trait_bounds(_thing: T) - | ... -132 | }␊ - | ^ - | - = in generic arg of `test_crate::fn_with_external_trait_bounds` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:125:1 - | -125 | pub fn fn_with_external_trait_bounds(_thing: T) - | ... -132 | }␊ - | ^ - | - = in generic arg of `test_crate::fn_with_external_trait_bounds` - -error: Unapproved external type `external_lib::SimpleTrait` referenced in public API - --> test-crate/src/lib.rs:135:5 - | -135 | type Thing: SimpleTrait; - | ^----------------------^ - | - = in trait bound of `test_crate::SomeTraitWithExternalDefaultTypes::Thing` - -error: Unapproved external type `external_lib::AssociatedGenericTrait` referenced in public API - --> test-crate/src/lib.rs:136:5 - | -136 | type OtherThing: AssociatedGenericTrait< - | ... -140 | >;␊ - | ^^ - | - = in trait bound of `test_crate::SomeTraitWithExternalDefaultTypes::OtherThing` - -error: Unapproved external type `external_lib::SomeOtherStruct` referenced in public API - --> test-crate/src/lib.rs:136:5 - | -136 | type OtherThing: AssociatedGenericTrait< - | ... -140 | >;␊ - | ^^ - | - = in generic default binding of `test_crate::SomeTraitWithExternalDefaultTypes::OtherThing` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-crate/src/lib.rs:136:5 - | -136 | type OtherThing: AssociatedGenericTrait< - | ... -140 | >;␊ - | ^^ - | - = in generic default binding of `test_crate::SomeTraitWithExternalDefaultTypes::OtherThing` - -error: Unapproved external type `external_lib::SimpleTrait` referenced in public API - --> test-crate/src/lib.rs:146:5 - | -146 | type MyGAT - | ... -148 | T: SimpleTrait;␊ - | ^-----------------^ - | - = in trait bound of `test_crate::SomeTraitWithGenericAssociatedType::MyGAT` - -error: Unapproved external type `external_lib::SimpleTrait` referenced in public API - --> test-crate/src/lib.rs:150:5 - | -150 | fn some_fn(&self, thing: Self::MyGAT); - | ^-------------------------------------------------------^ - | - = in trait bound of `test_crate::SomeTraitWithGenericAssociatedType::some_fn` - -error: Unapproved external type `external_lib::SimpleNewType` referenced in public API - --> test-crate/src/lib.rs:158:5 - | -158 | pub const OTHER_CONST: SimpleNewType = SimpleNewType(5); - | ^------------------------------------------------------^ - | - = in struct field of `test_crate::AssocConstStruct::OTHER_CONST` - -error: Unapproved external type `external_lib::ReprCType` referenced in public API - --> test-crate/src/test_union.rs:10:5 - | -10 | pub repr_c: ReprCType, - | ^-------------------^ - | - = in struct field of `test_crate::test_union::SimpleUnion::repr_c` - -error: Unapproved external type `external_lib::ReprCType` referenced in public API - --> test-crate/src/test_union.rs:15:5 - | -15 | pub fn repr_c(&self) -> &ReprCType { - | ... -17 | }␊ - | ^ - | - = in return value of `test_crate::test_union::SimpleUnion::repr_c` - -error: Unapproved external type `external_lib::SimpleTrait` referenced in public API - --> test-crate/src/test_union.rs:21:1 - | -21 | pub union GenericUnion { - | ... -24 | }␊ - | ^ - | - = in trait bound of `test_crate::test_union::GenericUnion` - -42 errors emitted diff --git a/tools/cargo-check-external-types/tests/integration_test.rs b/tools/cargo-check-external-types/tests/integration_test.rs deleted file mode 100644 index 84686dfa5c..0000000000 --- a/tools/cargo-check-external-types/tests/integration_test.rs +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -use cargo_check_external_types::cargo::handle_failure; -use pretty_assertions::assert_str_eq; -use std::fs; -use std::path::Path; -use std::process::Output; -use test_bin::get_test_bin; - -/// Returns (stdout, stderr) -pub fn output_text(output: &Output) -> (String, String) { - ( - String::from_utf8_lossy(&output.stdout).to_string(), - String::from_utf8_lossy(&output.stderr).to_string(), - ) -} - -fn run_with_args(in_path: impl AsRef, args: &[&str]) -> String { - let mut cmd = get_test_bin("cargo-check-external-types"); - cmd.current_dir(in_path.as_ref()); - cmd.arg("check-external-types"); - for &arg in args { - cmd.arg(arg); - } - let output = cmd - .output() - .expect("failed to start cargo-check-external-types"); - match output.status.code() { - Some(1) => { /* expected */ } - _ => handle_failure("cargo-check-external-types", &output).unwrap(), - } - let (stdout, _) = output_text(&output); - stdout -} - -#[test] -fn with_default_config() { - let expected_output = fs::read_to_string("tests/default-config-expected-output.txt").unwrap(); - let actual_output = run_with_args("test-workspace/test-crate", &[]); - assert_str_eq!(expected_output, actual_output); -} - -#[test] -fn with_some_allowed_types() { - let expected_output = fs::read_to_string("tests/allow-some-types-expected-output.txt").unwrap(); - let actual_output = run_with_args( - "test-workspace/test-crate", - &["--config", "../../tests/allow-some-types.toml"], - ); - assert_str_eq!(expected_output, actual_output); -} - -#[test] -fn with_output_format_markdown_table() { - let expected_output = - fs::read_to_string("tests/output-format-markdown-table-expected-output.md").unwrap(); - let actual_output = run_with_args( - "test-workspace/test-crate", - &["--output-format", "markdown-table"], - ); - assert_str_eq!(expected_output, actual_output); -} - -// Make sure that the visitor doesn't attempt to visit the inner items of re-exported external types. -// Rustdoc doesn't include these inner items in its JSON output, which leads to obtuse crashes if they're -// referenced. It's also just the wrong behavior to look into the type being re-exported, since if it's -// approved, then it doesn't matter what it referenced. If it's not approved, then the re-export itself -// is the violation. -#[test] -fn test_reexports() { - let expected_output = fs::read_to_string("tests/test-reexports-expected-output.md").unwrap(); - let actual_output = run_with_args("test-workspace/test-reexports-crate", &[]); - assert_str_eq!(expected_output, actual_output); -} diff --git a/tools/cargo-check-external-types/tests/output-format-markdown-table-expected-output.md b/tools/cargo-check-external-types/tests/output-format-markdown-table-expected-output.md deleted file mode 100644 index 12f1a19ccf..0000000000 --- a/tools/cargo-check-external-types/tests/output-format-markdown-table-expected-output.md +++ /dev/null @@ -1,44 +0,0 @@ -| Crate | Type | Used In | -| --- | --- | --- | -| external_lib | external_lib::AssociatedGenericTrait | test-crate/src/lib.rs:125:0 | -| external_lib | external_lib::AssociatedGenericTrait | test-crate/src/lib.rs:136:4 | -| external_lib | external_lib::ReprCType | test-crate/src/test_union.rs:10:4 | -| external_lib | external_lib::ReprCType | test-crate/src/test_union.rs:15:4 | -| external_lib | external_lib::SimpleNewType | test-crate/src/lib.rs:158:4 | -| external_lib | external_lib::SimpleTrait | test-crate/src/lib.rs:104:4 | -| external_lib | external_lib::SimpleTrait | test-crate/src/lib.rs:122:0 | -| external_lib | external_lib::SimpleTrait | test-crate/src/lib.rs:135:4 | -| external_lib | external_lib::SimpleTrait | test-crate/src/lib.rs:146:4 | -| external_lib | external_lib::SimpleTrait | test-crate/src/lib.rs:150:4 | -| external_lib | external_lib::SimpleTrait | test-crate/src/lib.rs:38:0 | -| external_lib | external_lib::SimpleTrait | test-crate/src/lib.rs:38:0 | -| external_lib | external_lib::SimpleTrait | test-crate/src/lib.rs:47:0 | -| external_lib | external_lib::SimpleTrait | test-crate/src/lib.rs:89:4 | -| external_lib | external_lib::SimpleTrait | test-crate/src/lib.rs:92:8 | -| external_lib | external_lib::SimpleTrait | test-crate/src/test_union.rs:21:0 | -| external_lib | external_lib::SomeOtherStruct | test-crate/src/lib.rs:125:0 | -| external_lib | external_lib::SomeOtherStruct | test-crate/src/lib.rs:136:4 | -| external_lib | external_lib::SomeOtherStruct | test-crate/src/lib.rs:72:4 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:109:0 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:110:0 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:115:4 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:116:4 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:120:0 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:121:0 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:123:0 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:125:0 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:136:4 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:38:0 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:43:0 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:54:0 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:62:4 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:67:4 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:68:4 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:72:4 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:78:4 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:79:4 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:80:4 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:81:4 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:84:0 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:89:4 | -| external_lib | external_lib::SomeStruct | test-crate/src/lib.rs:91:8 | diff --git a/tools/cargo-check-external-types/tests/test-reexports-expected-output.md b/tools/cargo-check-external-types/tests/test-reexports-expected-output.md deleted file mode 100644 index bfd40d1d02..0000000000 --- a/tools/cargo-check-external-types/tests/test-reexports-expected-output.md +++ /dev/null @@ -1,57 +0,0 @@ -error: Unapproved external type `external_lib::AssociatedGenericTrait` referenced in public API - --> test-reexports-crate/src/lib.rs:6:1 - | -6 | pub use external_lib::AssociatedGenericTrait; - | ^-------------------------------------------^ - | - = in re-export named `test_reexports_crate::AssociatedGenericTrait` - -error: Unapproved external type `external_lib::ReprCType` referenced in public API - --> test-reexports-crate/src/lib.rs:7:1 - | -7 | pub use external_lib::ReprCType; - | ^------------------------------^ - | - = in re-export named `test_reexports_crate::ReprCType` - -error: Unapproved external type `external_lib::SimpleTrait` referenced in public API - --> test-reexports-crate/src/lib.rs:8:1 - | -8 | pub use external_lib::SimpleTrait; - | ^--------------------------------^ - | - = in re-export named `test_reexports_crate::SimpleTrait` - -error: Unapproved external type `external_lib::SimpleGenericTrait` referenced in public API - --> test-reexports-crate/src/lib.rs:11:5 - | -11 | pub use external_lib::SimpleGenericTrait; - | ^---------------------------------------^ - | - = in re-export named `test_reexports_crate::Something::SimpleGenericTrait` - -error: Unapproved external type `external_lib::SimpleNewType` referenced in public API - --> test-reexports-crate/src/lib.rs:12:5 - | -12 | pub use external_lib::SimpleNewType; - | ^----------------------------------^ - | - = in re-export named `test_reexports_crate::Something::SimpleNewType` - -error: Unapproved external type `external_lib::SomeOtherStruct` referenced in public API - --> test-reexports-crate/src/lib.rs:15:1 - | -15 | pub use external_lib::SomeOtherStruct; - | ^------------------------------------^ - | - = in re-export named `test_reexports_crate::SomeOtherStruct` - -error: Unapproved external type `external_lib::SomeStruct` referenced in public API - --> test-reexports-crate/src/lib.rs:16:1 - | -16 | pub use external_lib::SomeStruct; - | ^-------------------------------^ - | - = in re-export named `test_reexports_crate::SomeStruct` - -7 errors emitted diff --git a/tools/ci-build/scripts/check-tools b/tools/ci-build/scripts/check-tools index 1dedf36b93..06aec61516 100755 --- a/tools/ci-build/scripts/check-tools +++ b/tools/ci-build/scripts/check-tools @@ -22,7 +22,6 @@ function test_tool { popd &>/dev/null } -test_tool "tools/cargo-check-external-types" "${RUST_NIGHTLY_VERSION}" test_tool "tools/changelogger" "${RUST_STABLE_VERSION}" test_tool "tools/ci-cdk/canary-runner" "${RUST_STABLE_VERSION}" test_tool "tools/crate-hasher" "${RUST_STABLE_VERSION}"