11// Run clippy on a fixed set of crates and collect the warnings.
2- // This helps observing the impact clippy changs have on a set of real-world code.
2+ // This helps observing the impact clippy changes have on a set of real-world code (and not just our testsuite) .
33//
44// When a new lint is introduced, we can search the results for new warnings and check for false
55// positives.
66
7- #![ cfg( feature = "lintcheck" ) ]
87#![ allow( clippy:: filter_map, clippy:: collapsible_else_if) ]
98
10- use crate :: clippy_project_root;
11-
129use std:: process:: Command ;
1310use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
1411use std:: { collections:: HashMap , io:: ErrorKind } ;
@@ -18,7 +15,7 @@ use std::{
1815 path:: { Path , PathBuf } ,
1916} ;
2017
21- use clap:: ArgMatches ;
18+ use clap:: { App , Arg , ArgMatches , SubCommand } ;
2219use rayon:: prelude:: * ;
2320use serde:: { Deserialize , Serialize } ;
2421use serde_json:: Value ;
@@ -564,7 +561,9 @@ fn lintcheck_needs_rerun(lintcheck_logs_path: &Path) -> bool {
564561/// # Panics
565562///
566563/// This function panics if the clippy binaries don't exist.
567- pub fn run ( clap_config : & ArgMatches ) {
564+ pub fn main ( ) {
565+ let clap_config = & get_clap_config ( ) ;
566+
568567 let config = LintcheckConfig :: from_clap ( clap_config) ;
569568
570569 println ! ( "Compiling clippy..." ) ;
@@ -800,6 +799,65 @@ fn create_dirs(krate_download_dir: &Path, extract_dir: &Path) {
800799 } ) ;
801800}
802801
802+ fn get_clap_config < ' a > ( ) -> ArgMatches < ' a > {
803+ let lintcheck_sbcmd = SubCommand :: with_name ( "lintcheck" )
804+ . about ( "run clippy on a set of crates and check output" )
805+ . arg (
806+ Arg :: with_name ( "only" )
807+ . takes_value ( true )
808+ . value_name ( "CRATE" )
809+ . long ( "only" )
810+ . help ( "only process a single crate of the list" ) ,
811+ )
812+ . arg (
813+ Arg :: with_name ( "crates-toml" )
814+ . takes_value ( true )
815+ . value_name ( "CRATES-SOURCES-TOML-PATH" )
816+ . long ( "crates-toml" )
817+ . help ( "set the path for a crates.toml where lintcheck should read the sources from" ) ,
818+ )
819+ . arg (
820+ Arg :: with_name ( "threads" )
821+ . takes_value ( true )
822+ . value_name ( "N" )
823+ . short ( "j" )
824+ . long ( "jobs" )
825+ . help ( "number of threads to use, 0 automatic choice" ) ,
826+ )
827+ . arg ( Arg :: with_name ( "fix" ) . help ( "runs cargo clippy --fix and checks if all suggestions apply" ) ) ;
828+
829+ let app = App :: new ( "Clippy developer tooling" ) ;
830+
831+ let app = app. subcommand ( lintcheck_sbcmd) ;
832+
833+ app. get_matches ( )
834+ }
835+
836+ /// Returns the path to the Clippy project directory
837+ ///
838+ /// # Panics
839+ ///
840+ /// Panics if the current directory could not be retrieved, there was an error reading any of the
841+ /// Cargo.toml files or ancestor directory is the clippy root directory
842+ #[ must_use]
843+ pub fn clippy_project_root ( ) -> PathBuf {
844+ let current_dir = std:: env:: current_dir ( ) . unwrap ( ) ;
845+ for path in current_dir. ancestors ( ) {
846+ let result = std:: fs:: read_to_string ( path. join ( "Cargo.toml" ) ) ;
847+ if let Err ( err) = & result {
848+ if err. kind ( ) == std:: io:: ErrorKind :: NotFound {
849+ continue ;
850+ }
851+ }
852+
853+ let content = result. unwrap ( ) ;
854+ if content. contains ( "[package]\n name = \" clippy\" " ) {
855+ return path. to_path_buf ( ) ;
856+ }
857+ }
858+ panic ! ( "error: Can't determine root of project. Please run inside a Clippy working dir." ) ;
859+ }
860+
803861#[ test]
804862fn lintcheck_test ( ) {
805863 let args = [
0 commit comments