diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..849f2733 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,140 @@ +# Changelog +--------- + +## 0.11.0 + - TODO: Prepare release. + +## 0.10.2 + - __Bugfix__: Avoid panic and log warnings on parse failure. [#105] + - Upgraded all dependencies. + +## 0.10.1 + - Expose the `cargo` crate feature: `vendored-openssl`. [#99] + - Upgraded all dependencies. + +## 0.10.0 + - Upgraded all dependencies. [#98] + +## 0.9.1 + - __Bugfix__: Avoid counting the same crate multiple times. [#79] + - Upgraded cargo to 0.41. [#85] + - Upgraded all dependencies. + +## 0.9.0 + - __Breaking change__: Replaced structopt & clap with [pico-args], to reduce + compile times [#77]. As a result the `-Z` flag now requires quotes around + its list of sub arguments, other than that there should be no changes to + the CLI. + +## 0.8.0 + - __Bugfix:__ Count all expressions in unsafe functions and nested unsafe + scopes, in [geiger 0.4.1](geiger), [#72] & [#71]. + - __Bugfix:__ Properly account for possibly patched dependencies [#70]. + - Summary for each metrics column, [#76]. + - Now requires all entry points for a crate to declare + `#[forbid(unsafe_code)]` for it to count as crate-wide. + - New optional scan mode `--forbid-only`. This mode doesn't require any calls + to `rustc` and only requires parsing the entry point `.rs` files, making it + much faster than the normal mode. + - Updated dependencies. + +## 0.7.3 + - __Bugfix:__ Fix dependency collection for mixed workspaces [#66]. + - Updated dependencies. + +## 0.7.2 + - Updated dependencies to fix [#59]. + +## 0.7.1 + - __Bugfix:__ related to attributes, in [geiger] [#57]. + - Updated all dependencies. + +## 0.7.0 + - Updated all dependencies, [geiger] to 0.3.0. + +## 0.6.1 + - A tiny readme fix. + +## 0.6.0 + - There are now three crate scanning result variants [#52]: + - 🔒 No unsafe usage found and all build target entry point `.rs` source + files, used by the build, declare `#![forbid(unsafe_code)]`. Crates like + this will be printed in green. + - ❓ No unsafe usage found, but at least one build target entry point `.rs` + file, used by the build, does not declare `#[forbid(unsafe_code)]`. Crates + like this will be printed in the default terminal foreground color. + - ☢️ Unsafe usage found. Crates like this will be printed in red, same as in + the previous version. + +## 0.5.0 + - Moved reusable parts, decoupled from `cargo`, to the new crate + [geiger]. Main github issue: [#30]. + - Some general refactoring and cleanup. + - Merge pull request [#46] from alexmaco/dependency_kind_control. add options + to filter dependencies by kind; defaults to Kind::Normal. + - Merge pull request [#40] from jiminhsieh/rust-2018. Use Rust 2018 edition. + +## 0.4.2 + - __Bugfix:__ Merge pull request [#33] from ajpaverd/windows_filepaths. + Canonicalize file paths from walker. + + - Merge pull request [#38] from anderejd/updated-deps. Updated deps and fixed + build errors. + +## 0.4.1 + - Merge pull request [#28] from alexmaco/deps_upgrade. fix build on rust 1.30: + upgrade petgraph to 0.4.13 + + - __Bugfix:__ Merge pull request [#29] from alexmaco/invalid_utf8_source. fix + handling source files with invalid utf8: lossy conversion to string + +## 0.4.0 + - Filters out tests by default. Tests can still be included by using + `--include-tests`. The test code is filtered out by looking for the attribute + `#[test]` on functions and `#[cfg(test)]` on modules. + +## 0.3.1 + - __Bugfix:__ Some bugfixes related to cargo workspace path handling. + - Slightly better error messages in some cases. + +## 0.3.0 + - Intercepts `rustc` calls and reads the `.d` files generated by `rustc` to + identify which `.rs` files are used by the build. This allows a crate that + contains `.rs` files with unsafe code usage to pass as "green" if the unsafe + code isn't used by the build. + - Each metric is now printed as `x/y`, where `x` is the unsafe code used by the + build and `y` is the total unsafe usage found in the crate. + - Removed the `--compact` output format to avoid some code complexity. A new + and better compact mode can be added later if requested. + +## 0.2.0 + - Table based output format [#9]. + +## 0.1.x + - Initial experimental versions. + - Mostly README.md updates. + +[#9]: https://github.com/rust-secure-code/cargo-geiger/pull/9 +[#28]: https://github.com/rust-secure-code/cargo-geiger/issues/28 +[#29]: https://github.com/rust-secure-code/cargo-geiger/issues/29 +[#30]: https://github.com/rust-secure-code/cargo-geiger/issues/30 +[#33]: https://github.com/rust-secure-code/cargo-geiger/issues/33 +[#38]: https://github.com/rust-secure-code/cargo-geiger/issues/38 +[#40]: https://github.com/rust-secure-code/cargo-geiger/issues/40 +[#46]: https://github.com/rust-secure-code/cargo-geiger/issues/46 +[#52]: https://github.com/rust-secure-code/cargo-geiger/issues/52 +[#57]: https://github.com/rust-secure-code/cargo-geiger/issues/57 +[#59]: https://github.com/rust-secure-code/cargo-geiger/issues/59 +[#66]: https://github.com/rust-secure-code/cargo-geiger/issues/66 +[#70]: https://github.com/rust-secure-code/cargo-geiger/pull/70 +[#71]: https://github.com/rust-secure-code/cargo-geiger/issues/71 +[#72]: https://github.com/rust-secure-code/cargo-geiger/pull/72 +[#76]: https://github.com/rust-secure-code/cargo-geiger/pull/76 +[#77]: https://github.com/rust-secure-code/cargo-geiger/pull/77 +[#79]: https://github.com/rust-secure-code/cargo-geiger/issues/79 +[#85]: https://github.com/rust-secure-code/cargo-geiger/pull/85 +[#98]: https://github.com/rust-secure-code/cargo-geiger/pull/98 +[#99]: https://github.com/rust-secure-code/cargo-geiger/pull/99 +[#105]: https://github.com/rust-secure-code/cargo-geiger/issues/105 +[geiger]: https://crates.io/crates/geiger +[pico-args]: https://crates.io/crates/pico-args diff --git a/README.md b/README.md index e8775213..efce1b9e 100644 --- a/README.md +++ b/README.md @@ -76,150 +76,25 @@ Roadmap - ~~There should be no false negatives. All unsafe code should be identified.~~ This is probably too ambitious, but scanning for `#![forbid(unsafe_code)]` should be a reliable alternative (implemented since - 0.6.0). Please see the changelog. + 0.6.0). Please see the [changelog]. - An optional whitelist file at the root crate level to specify crates that are trusted to use unsafe (should only have an effect if placed in the root project). +Libraries +--------- + +Cargo Geiger exposes three libraries: + + - `cargo-geiger` - Unversioned and highly unstable library exposing the internals of the `cargo-geiger` binary. As such any function contained within this library may be subject to change. + - `cargo-geiger-serde` - A library containing the serializable report types + - `geiger` - A library containing some components used by [cargo-geiger] that are decoupled from [cargo] Changelog --------- -### 0.11.0 - - TODO: Prepare release. - -### 0.10.2 - - __Bugfix__: Avoid panic and log warnings on parse failure. [#105] - - Upgraded all dependencies. - -### 0.10.1 - - Expose the `cargo` crate feature: `vendored-openssl`. [#99] - - Upgraded all dependencies. - -### 0.10.0 - - Upgraded all dependencies. [#98] - -### 0.9.1 - - __Bugfix__: Avoid counting the same crate multiple times. [#79] - - Upgraded cargo to 0.41. [#85] - - Upgraded all dependencies. - -### 0.9.0 - - __Breaking change__: Replaced structopt & clap with [pico-args], to reduce - compile times [#77]. As a result the `-Z` flag now requires quotes around - its list of sub arguments, other than that there should be no changes to - the CLI. - -### 0.8.0 - - __Bugfix:__ Count all expressions in unsafe functions and nested unsafe - scopes, in [geiger 0.4.1](geiger), [#72] & [#71]. - - __Bugfix:__ Properly account for possibly patched dependencies [#70]. - - Summary for each metrics column, [#76]. - - Now requires all entry points for a crate to declare - `#[forbid(unsafe_code)]` for it to count as crate-wide. - - New optional scan mode `--forbid-only`. This mode doesn't require any calls - to `rustc` and only requires parsing the entry point `.rs` files, making it - much faster than the normal mode. - - Updated dependencies. - -### 0.7.3 - - __Bugfix:__ Fix dependency collection for mixed workspaces [#66]. - - Updated dependencies. - -### 0.7.2 - - Updated dependencies to fix [#59]. - -### 0.7.1 - - __Bugfix:__ related to attributes, in [geiger] [#57]. - - Updated all dependencies. - -### 0.7.0 - - Updated all dependencies, [geiger] to 0.3.0. - -### 0.6.1 - - A tiny readme fix. - -### 0.6.0 - - There are now three crate scanning result variants [#52]: - - 🔒 No unsafe usage found and all build target entry point `.rs` source - files, used by the build, declare `#![forbid(unsafe_code)]`. Crates like - this will be printed in green. - - ❓ No unsafe usage found, but at least one build target entry point `.rs` - file, used by the build, does not declare `#[forbid(unsafe_code)]`. Crates - like this will be printed in the default terminal foreground color. - - ☢️ Unsafe usage found. Crates like this will be printed in red, same as in - the previous version. - -### 0.5.0 - - Moved reusable parts, decoupled from `cargo`, to the new crate - [geiger]. Main github issue: [#30]. - - Some general refactoring and cleanup. - - Merge pull request [#46] from alexmaco/dependency_kind_control. add options - to filter dependencies by kind; defaults to Kind::Normal. - - Merge pull request [#40] from jiminhsieh/rust-2018. Use Rust 2018 edition. - -### 0.4.2 - - __Bugfix:__ Merge pull request [#33] from ajpaverd/windows_filepaths. - Canonicalize file paths from walker. - - - Merge pull request [#38] from anderejd/updated-deps. Updated deps and fixed - build errors. - -### 0.4.1 - - Merge pull request [#28] from alexmaco/deps_upgrade. fix build on rust 1.30: - upgrade petgraph to 0.4.13 - - - __Bugfix:__ Merge pull request [#29] from alexmaco/invalid_utf8_source. fix - handling source files with invalid utf8: lossy conversion to string - -### 0.4.0 - - Filters out tests by default. Tests can still be included by using - `--include-tests`. The test code is filtered out by looking for the attribute - `#[test]` on functions and `#[cfg(test)]` on modules. - -### 0.3.1 - - __Bugfix:__ Some bugfixes related to cargo workspace path handling. - - Slightly better error messages in some cases. - -### 0.3.0 - - Intercepts `rustc` calls and reads the `.d` files generated by `rustc` to - identify which `.rs` files are used by the build. This allows a crate that - contains `.rs` files with unsafe code usage to pass as "green" if the unsafe - code isn't used by the build. - - Each metric is now printed as `x/y`, where `x` is the unsafe code used by the - build and `y` is the total unsafe usage found in the crate. - - Removed the `--compact` output format to avoid some code complexity. A new - and better compact mode can be added later if requested. - -### 0.2.0 - - Table based output format [#9]. - -### 0.1.x - - Initial experimental versions. - - Mostly README.md updates. - -[#9]: https://github.com/rust-secure-code/cargo-geiger/pull/9 -[#28]: https://github.com/rust-secure-code/cargo-geiger/issues/28 -[#29]: https://github.com/rust-secure-code/cargo-geiger/issues/29 -[#30]: https://github.com/rust-secure-code/cargo-geiger/issues/30 -[#33]: https://github.com/rust-secure-code/cargo-geiger/issues/33 -[#38]: https://github.com/rust-secure-code/cargo-geiger/issues/38 -[#40]: https://github.com/rust-secure-code/cargo-geiger/issues/40 -[#46]: https://github.com/rust-secure-code/cargo-geiger/issues/46 -[#52]: https://github.com/rust-secure-code/cargo-geiger/issues/52 -[#57]: https://github.com/rust-secure-code/cargo-geiger/issues/57 -[#59]: https://github.com/rust-secure-code/cargo-geiger/issues/59 -[#66]: https://github.com/rust-secure-code/cargo-geiger/issues/66 -[#70]: https://github.com/rust-secure-code/cargo-geiger/pull/70 -[#71]: https://github.com/rust-secure-code/cargo-geiger/issues/71 -[#72]: https://github.com/rust-secure-code/cargo-geiger/pull/72 -[#76]: https://github.com/rust-secure-code/cargo-geiger/pull/76 -[#77]: https://github.com/rust-secure-code/cargo-geiger/pull/77 -[#79]: https://github.com/rust-secure-code/cargo-geiger/issues/79 -[#85]: https://github.com/rust-secure-code/cargo-geiger/pull/85 -[#98]: https://github.com/rust-secure-code/cargo-geiger/pull/98 -[#99]: https://github.com/rust-secure-code/cargo-geiger/pull/99 -[#105]: https://github.com/rust-secure-code/cargo-geiger/issues/105 -[geiger]: https://crates.io/crates/geiger -[pico-args]: https://crates.io/crates/pico-args +The changelog can be found [here](https://github.com/rust-secure-code/cargo-geiger/blob/master/CHANGELOG.md) +[cargo]: https://crates.io/crates/cargo +[cargo-geiger]: https://crates.io/crates/cargo-geiger +[changelog]: https://github.com/rust-secure-code/cargo-geiger/blob/master/CHANGELOG.md diff --git a/cargo-geiger-serde/Cargo.toml b/cargo-geiger-serde/Cargo.toml index 3ee50d92..55ac6738 100644 --- a/cargo-geiger-serde/Cargo.toml +++ b/cargo-geiger-serde/Cargo.toml @@ -1,9 +1,12 @@ [package] authors = ["anderejd "] +categories = ["development-tools", "serialization"] description = "TODO: Write description" edition = "2018" license = "Apache-2.0/MIT" +keywords = ["unsafe"] name = "cargo-geiger-serde" +repository = "https://github.com/rust-secure-code/cargo-geiger" version = "0.1.0" [dependencies] diff --git a/cargo-geiger/src/args.rs b/cargo-geiger/src/args.rs index 71bda147..b98ed3ee 100644 --- a/cargo-geiger/src/args.rs +++ b/cargo-geiger/src/args.rs @@ -6,6 +6,7 @@ use cargo::{CliResult, Config}; use pico_args::Arguments; use std::path::PathBuf; +/// Constant `&str` containing help text pub const HELP: &str = "Detects usage of unsafe Rust in a Rust crate and its dependencies. @@ -89,6 +90,13 @@ pub struct Args { } impl Args { + /// Construct `Args` struct from `pico_args::Arguments` loaded from command line arguments + /// provided by the user + /// ``` + /// # use cargo_geiger::args::Args; + /// let pico_arguments = pico_args::Arguments::from_env(); + /// let args = Args::parse_args(pico_arguments); + /// ``` pub fn parse_args( mut raw_args: Arguments, ) -> Result> { @@ -152,6 +160,17 @@ impl Args { Ok(args) } + /// Update `cargo::util::Config` with values from `Args` struct, and set the shell + /// colour choice + /// ``` + /// # use cargo::Config; + /// # use cargo_geiger::args::Args; + /// let args = Args::parse_args( + /// pico_args::Arguments::from_env() + /// ).unwrap(); + /// let mut config = Config::default().unwrap(); + /// args.update_config(&mut config); + /// ``` pub fn update_config(&self, config: &mut Config) -> CliResult { let target_dir = None; // Doesn't add any value for cargo-geiger. config.configure( diff --git a/cargo-geiger/src/cli.rs b/cargo-geiger/src/cli.rs index 25eabe46..c076a6f0 100644 --- a/cargo-geiger/src/cli.rs +++ b/cargo-geiger/src/cli.rs @@ -1,5 +1,3 @@ -//! This module provides the bulk of the code for the `cargo-geiger` executable. - // TODO: Review the module structure in this crate. There is very tight coupling // between the main.rs and this module. Should this module be split into smaller // parts? The printing and scanning can probably be further decoupled to provide @@ -8,7 +6,7 @@ // TODO: Investigate how cargo-clippy is implemented. Is it using syn? Is is // using rustc? Is it implementing a compiler plugin? -use crate::Args; +use crate::args::Args; // TODO: Consider making this a lib.rs (again) and expose a full API, excluding // only the terminal output..? That API would be dependent on cargo. @@ -53,7 +51,7 @@ pub fn get_cargo_metadata( /// TODO: Write proper documentation for this. /// This function seems to be looking up the active flags for conditional -/// compilation (cargo_platform::Cfg instances). +/// compilation (`cargo_platform::Cfg` instances). pub fn get_cfgs( config: &Config, target: &Option, diff --git a/cargo-geiger/src/lib.rs b/cargo-geiger/src/lib.rs new file mode 100644 index 00000000..364b409f --- /dev/null +++ b/cargo-geiger/src/lib.rs @@ -0,0 +1,26 @@ +//! These modules expose the internal workings of `cargo-geiger`. They +//! are currently not stable, and therefore have no associated `SemVer`. +//! As such, any function contained within may be subject to change. + +#![deny(clippy::cargo)] +#![deny(clippy::doc_markdown)] +#![forbid(unsafe_code)] +#![forbid(warnings)] + +/// Argument parsing +pub mod args; +/// Bootstrapping functions for structs required by the CLI +pub mod cli; +/// Construction of the dependency graph +pub mod graph; +/// Mapping functionality from `cargo::core` to `cargo_metadata` +pub mod mapping; +/// Interaction with README.md files +pub mod readme; +/// Functions for scanning projects for unsafe code +pub mod scan; + +/// Inner display formatting +mod format; +/// Tree construction +mod tree; diff --git a/cargo-geiger/src/main.rs b/cargo-geiger/src/main.rs index cb041ff2..c60d50ec 100644 --- a/cargo-geiger/src/main.rs +++ b/cargo-geiger/src/main.rs @@ -1,6 +1,8 @@ //! The outer CLI parts of the `cargo-geiger` cargo plugin executable. //! TODO: Refactor this file to only deal with command line argument processing. +#![deny(clippy::cargo)] +#![deny(clippy::doc_markdown)] #![forbid(unsafe_code)] #![forbid(warnings)] @@ -10,25 +12,18 @@ extern crate petgraph; extern crate strum; extern crate strum_macros; -mod args; -mod cli; -mod format; -mod graph; -mod mapping; -mod readme; -mod scan; -mod tree; - -use crate::args::{Args, HELP}; -use crate::cli::{get_cargo_metadata, get_krates, get_workspace}; -use crate::graph::build_graph; -use crate::mapping::{CargoMetadataParameters, QueryResolve}; -use crate::scan::scan; +use cargo_geiger::args::{Args, HELP}; +use cargo_geiger::cli::{get_cargo_metadata, get_krates, get_workspace}; +use cargo_geiger::graph::build_graph; +use cargo_geiger::mapping::{CargoMetadataParameters, QueryResolve}; +use cargo_geiger::readme::{ + create_or_replace_section_in_readme, README_FILENAME, +}; +use cargo_geiger::scan::scan; use cargo::core::shell::Shell; use cargo::util::important_paths; use cargo::{CliError, CliResult, Config}; -use readme::create_or_replace_section_in_readme; const VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION"); @@ -98,7 +93,7 @@ fn real_main(args: &Args, config: &mut Config) -> CliResult { if args.update_readme { let mut current_dir_path_buf = std::env::current_dir().unwrap(); - current_dir_path_buf.push(readme::README_FILENAME); + current_dir_path_buf.push(README_FILENAME); create_or_replace_section_in_readme( current_dir_path_buf, diff --git a/cargo-geiger/src/mapping.rs b/cargo-geiger/src/mapping.rs index db552f2b..da183cb6 100644 --- a/cargo-geiger/src/mapping.rs +++ b/cargo-geiger/src/mapping.rs @@ -8,6 +8,8 @@ use cargo_metadata::Metadata; use std::collections::HashSet; use std::path::PathBuf; +/// Holds a pointer to both a `Krates` graph, and the `Metadata` struct +/// which are often required together pub struct CargoMetadataParameters<'a> { pub krates: &'a Krates, pub metadata: &'a Metadata, diff --git a/cargo-geiger/src/scan/default.rs b/cargo-geiger/src/scan/default.rs index b5e0ebc0..899361a2 100644 --- a/cargo-geiger/src/scan/default.rs +++ b/cargo-geiger/src/scan/default.rs @@ -47,7 +47,7 @@ pub fn scan_unsafe( } } -/// Based on code from cargo-bloat. It seems weird that CompileOptions can be +/// Based on code from cargo-bloat. It seems weird that `CompileOptions` can be /// constructed without providing all standard cargo options, TODO: Open an issue /// in cargo? fn build_compile_options<'a>( diff --git a/cargo-geiger/src/scan/rs_file.rs b/cargo-geiger/src/scan/rs_file.rs index 21ed9c51..80d9cbc6 100644 --- a/cargo-geiger/src/scan/rs_file.rs +++ b/cargo-geiger/src/scan/rs_file.rs @@ -20,7 +20,7 @@ use walkdir::{DirEntry, WalkDir}; /// Provides information needed to scan for crate root /// `#![forbid(unsafe_code)]`. -/// The wrapped PathBufs are canonicalized. +/// The wrapped `PathBufs` are canonicalized. #[derive(Debug, PartialEq)] pub enum RsFile { /// Executable entry point source file, usually src/main.rs @@ -247,7 +247,7 @@ fn compile_with_exec( Ok(()) } -/// Copy-pasted (almost) from the private module cargo::core::compiler::fingerprint. +/// Copy-pasted (almost) from the private module `cargo::core::compiler::fingerprint`. /// /// TODO: Make a PR to the cargo project to expose this function or to expose /// the dependency data in some other way. diff --git a/cargo-geiger/src/tree/traversal.rs b/cargo-geiger/src/tree/traversal.rs index 90b08d3d..7928f740 100644 --- a/cargo-geiger/src/tree/traversal.rs +++ b/cargo-geiger/src/tree/traversal.rs @@ -20,10 +20,10 @@ pub struct WalkDependencyParameters<'a> { pub visited_deps: &'a mut HashSet, } -/// Printing the returned TextTreeLines in order is expected to produce a nice +/// Printing the returned `TextTreeLines` in order is expected to produce a nice /// looking tree structure. /// -/// TODO: Return a impl Iterator +/// TODO: Return a impl `Iterator` /// TODO: Consider separating the tree vine building from the tree traversal. /// pub fn walk_dependency_tree( diff --git a/geiger/Cargo.toml b/geiger/Cargo.toml index 5bf5f8fd..abaf3159 100644 --- a/geiger/Cargo.toml +++ b/geiger/Cargo.toml @@ -1,14 +1,14 @@ [package] -name = "geiger" +authors = ["anderejd "] +categories = ["development-tools", "parsing"] description = "Some library parts of cargo-geiger, decoupled from cargo." -version = "0.4.5" edition = "2018" -authors = ["anderejd "] -repository = "https://github.com/rust-secure-code/cargo-geiger" -readme = "README.md" keywords = ["unsafe"] -categories = ["development-tools", "parsing"] license = "Apache-2.0/MIT" +name = "geiger" +readme = "README.md" +repository = "https://github.com/rust-secure-code/cargo-geiger" +version = "0.4.5" [badges] maintenance = { status = "experimental" }