@@ -69,6 +69,69 @@ const ESSENTIAL_FILES_UNVERSIONED: &[&str] = &[
6969const DUMMY_CRATE_NAME : & str = "empty-library" ;
7070const DUMMY_CRATE_VERSION : & str = "1.0.0" ;
7171
72+ macro_rules! config_command {
73+ ( $obj: ident, $build: expr, $target: expr, $metadata: expr, $limits: expr, $rustdoc_flags_extras: expr, $( $extra: tt) +) => { {
74+ let mut cargo_args = vec![ "doc" , "--lib" , "--no-deps" ] ;
75+ if $target != HOST_TARGET {
76+ // If the explicit target is not a tier one target, we need to install it.
77+ if !TARGETS . contains( & $target) {
78+ // This is a no-op if the target is already installed.
79+ $obj. toolchain. add_target( & $obj. workspace, $target) ?;
80+ }
81+ cargo_args. push( "--target" ) ;
82+ cargo_args. push( $target) ;
83+ } ;
84+
85+ let tmp;
86+ if let Some ( cpu_limit) = $obj. cpu_limit {
87+ tmp = format!( "-j{}" , cpu_limit) ;
88+ cargo_args. push( & tmp) ;
89+ }
90+
91+ let tmp;
92+ if let Some ( features) = & $metadata. features {
93+ cargo_args. push( "--features" ) ;
94+ tmp = features. join( " " ) ;
95+ cargo_args. push( & tmp) ;
96+ }
97+ if $metadata. all_features {
98+ cargo_args. push( "--all-features" ) ;
99+ }
100+ if $metadata. no_default_features {
101+ cargo_args. push( "--no-default-features" ) ;
102+ }
103+
104+ let mut rustdoc_flags = vec![
105+ "-Z" . to_string( ) ,
106+ "unstable-options" . to_string( ) ,
107+ "--static-root-path" . to_string( ) ,
108+ "/" . to_string( ) ,
109+ "--cap-lints" . to_string( ) ,
110+ "warn" . to_string( ) ,
111+ ] ;
112+ rustdoc_flags. extend( $rustdoc_flags_extras) ;
113+
114+ $build
115+ . cargo( )
116+ . timeout( Some ( $limits. timeout( ) ) )
117+ . no_output_timeout( None )
118+ . env(
119+ "RUSTFLAGS" ,
120+ $metadata
121+ . rustc_args
122+ . as_ref( )
123+ . map( |args| args. join( " " ) )
124+ . unwrap_or_default( ) ,
125+ )
126+ . env( "RUSTDOCFLAGS" , rustdoc_flags. join( " " ) )
127+ // For docs.rs detection from build script:
128+ // https://github.com/rust-lang/docs.rs/issues/147
129+ . env( "DOCS_RS" , "1" )
130+ . args( & cargo_args)
131+ $( $extra) +
132+ } }
133+ }
134+
72135pub struct RustwideBuilder {
73136 workspace : Workspace ,
74137 toolchain : Toolchain ,
@@ -474,121 +537,48 @@ impl RustwideBuilder {
474537 Ok ( ( ) )
475538 }
476539
477- fn make_build_object < T , F : Fn ( Vec < & str > , Vec < String > , LogStorage ) -> Result < T > > (
478- & self ,
479- target : & str ,
480- metadata : & Metadata ,
481- limits : & Limits ,
482- f : F ,
483- ) -> Result < T > {
484- let mut cargo_args = vec ! [ "doc" , "--lib" , "--no-deps" ] ;
485- if target != HOST_TARGET {
486- // If the explicit target is not a tier one target, we need to install it.
487- if !TARGETS . contains ( & target) {
488- // This is a no-op if the target is already installed.
489- self . toolchain . add_target ( & self . workspace , target) ?;
490- }
491- cargo_args. push ( "--target" ) ;
492- cargo_args. push ( target) ;
493- } ;
494-
495- let tmp_jobs;
496- if let Some ( cpu_limit) = self . cpu_limit {
497- tmp_jobs = format ! ( "-j{}" , cpu_limit) ;
498- cargo_args. push ( & tmp_jobs) ;
499- }
500-
501- let tmp;
502- if let Some ( features) = & metadata. features {
503- cargo_args. push ( "--features" ) ;
504- tmp = features. join ( " " ) ;
505- cargo_args. push ( & tmp) ;
506- }
507- if metadata. all_features {
508- cargo_args. push ( "--all-features" ) ;
509- }
510- if metadata. no_default_features {
511- cargo_args. push ( "--no-default-features" ) ;
512- }
513-
514- let mut storage = LogStorage :: new ( LevelFilter :: Info ) ;
515- storage. set_max_size ( limits. max_log_size ( ) ) ;
516-
517- let rustdoc_flags: Vec < String > = vec ! [
518- "-Z" . to_string( ) ,
519- "unstable-options" . to_string( ) ,
520- "--static-root-path" . to_string( ) ,
521- "/" . to_string( ) ,
522- "--cap-lints" . to_string( ) ,
523- "warn" . to_string( ) ,
524- ] ;
525-
526- f ( cargo_args, rustdoc_flags, storage)
527- }
528-
529540 fn get_coverage (
530541 & self ,
531542 target : & str ,
532543 build : & Build ,
533544 metadata : & Metadata ,
534545 limits : & Limits ,
535546 ) -> Result < Option < DocCoverage > > {
536- self . make_build_object (
537- target,
538- metadata,
539- limits,
540- |cargo_args, mut rustdoc_flags, _| {
541- rustdoc_flags. extend ( vec ! [
542- "--output-format" . to_string( ) ,
543- "json" . to_string( ) ,
544- "--show-coverage" . to_string( ) ,
545- ] ) ;
546- let mut doc_coverage_json = None ;
547- build
548- . cargo ( )
549- . timeout ( Some ( limits. timeout ( ) ) )
550- . no_output_timeout ( None )
551- . env (
552- "RUSTFLAGS" ,
553- metadata
554- . rustc_args
555- . as_ref ( )
556- . map ( |args| args. join ( " " ) )
557- . unwrap_or_default ( ) ,
558- )
559- . env ( "RUSTDOCFLAGS" , rustdoc_flags. join ( " " ) )
560- // For docs.rs detection from build script:
561- // https://github.com/rust-lang/docs.rs/issues/147
562- . env ( "DOCS_RS" , "1" )
563- . args ( & cargo_args)
564- . log_output ( false )
565- . process_lines ( & mut |line, _| {
566- if line. starts_with ( '{' ) && line. ends_with ( '}' ) {
567- doc_coverage_json = Some ( line. to_owned ( ) ) ;
568- }
569- } )
570- . run ( )
571- . ok ( ) ;
572- if let Some ( json) = doc_coverage_json {
573- if let Ok ( Value :: Object ( m) ) = serde_json:: from_str ( & json) {
574- let ( mut total_items, mut documented_items) = ( 0 , 0 ) ;
575- for entry in m. values ( ) {
576- if let Some ( Value :: Number ( n) ) = entry. get ( "total" ) {
577- total_items += n. as_i64 ( ) . unwrap_or ( 0 ) as i32 ;
578- }
579- if let Some ( Value :: Number ( n) ) = entry. get ( "with_docs" ) {
580- documented_items += n. as_i64 ( ) . unwrap_or ( 0 ) as i32 ;
581- }
582- }
583- return Ok ( Some ( DocCoverage {
584- total_items,
585- documented_items,
586- } ) ) ;
547+ let mut doc_coverage_json = None ;
548+
549+ let rustdoc_flags = vec ! [
550+ "--output-format" . to_string( ) ,
551+ "json" . to_string( ) ,
552+ "--show-coverage" . to_string( ) ,
553+ ] ;
554+ config_command ! ( self , build, target, metadata, limits, rustdoc_flags,
555+ . process_lines( & mut |line, _| {
556+ if line. starts_with( '{' ) && line. ends_with( '}' ) {
557+ doc_coverage_json = Some ( line. to_owned( ) ) ;
558+ }
559+ } )
560+ . log_output( false )
561+ . run( ) ?;
562+ ) ;
563+
564+ if let Some ( json) = doc_coverage_json {
565+ if let Ok ( Value :: Object ( m) ) = serde_json:: from_str ( & json) {
566+ let ( mut total_items, mut documented_items) = ( 0 , 0 ) ;
567+ for entry in m. values ( ) {
568+ if let Some ( Value :: Number ( n) ) = entry. get ( "total" ) {
569+ total_items += n. as_i64 ( ) . unwrap_or ( 0 ) as i32 ;
570+ }
571+ if let Some ( Value :: Number ( n) ) = entry. get ( "with_docs" ) {
572+ documented_items += n. as_i64 ( ) . unwrap_or ( 0 ) as i32 ;
587573 }
588574 }
589- Ok ( None )
590- } ,
591- )
575+ return Ok ( Some ( DocCoverage {
576+ total_items,
577+ documented_items,
578+ } ) ) ;
579+ }
580+ }
581+ Ok ( None )
592582 }
593583
594584 fn execute_build (
@@ -599,87 +589,69 @@ impl RustwideBuilder {
599589 limits : & Limits ,
600590 metadata : & Metadata ,
601591 ) -> Result < FullBuildResult > {
602- self . make_build_object (
603- target,
604- metadata,
605- limits,
606- |cargo_args, mut rustdoc_flags, storage| {
607- rustdoc_flags. extend ( vec ! [
608- "--resource-suffix" . to_string( ) ,
609- format!( "-{}" , parse_rustc_version( & self . rustc_version) ?) ,
610- ] ) ;
611- let cargo_metadata = CargoMetadata :: load (
612- & self . workspace ,
613- & self . toolchain ,
614- & build. host_source_dir ( ) ,
615- ) ?;
592+ let cargo_metadata =
593+ CargoMetadata :: load ( & self . workspace , & self . toolchain , & build. host_source_dir ( ) ) ?;
594+
595+ let mut rustdoc_flags = Vec :: new ( ) ;
596+
597+ for dep in & cargo_metadata. root_dependencies ( ) {
598+ rustdoc_flags. push ( "--extern-html-root-url" . to_string ( ) ) ;
599+ rustdoc_flags. push ( format ! (
600+ "{}=https://docs.rs/{}/{}" ,
601+ dep. name. replace( "-" , "_" ) ,
602+ dep. name,
603+ dep. version
604+ ) ) ;
605+ }
606+ if let Some ( package_rustdoc_args) = & metadata. rustdoc_args {
607+ rustdoc_flags. append ( & mut package_rustdoc_args. iter ( ) . map ( |s| s. to_owned ( ) ) . collect ( ) ) ;
608+ }
616609
617- for dep in & cargo_metadata. root_dependencies ( ) {
618- rustdoc_flags. push ( "--extern-html-root-url" . to_string ( ) ) ;
619- rustdoc_flags. push ( format ! (
620- "{}=https://docs.rs/{}/{}" ,
621- dep. name. replace( "-" , "_" ) ,
622- dep. name,
623- dep. version
624- ) ) ;
625- }
626- if let Some ( package_rustdoc_args) = & metadata. rustdoc_args {
627- rustdoc_flags
628- . append ( & mut package_rustdoc_args. iter ( ) . map ( |s| s. to_owned ( ) ) . collect ( ) ) ;
629- }
610+ rustdoc_flags. extend ( vec ! [
611+ "--resource-suffix" . to_string( ) ,
612+ format!( "-{}" , parse_rustc_version( & self . rustc_version) ?) ,
613+ ] ) ;
630614
631- let successful = logging:: capture ( & storage, || {
632- build
633- . cargo ( )
634- . timeout ( Some ( limits. timeout ( ) ) )
635- . no_output_timeout ( None )
636- . env (
637- "RUSTFLAGS" ,
638- metadata
639- . rustc_args
640- . as_ref ( )
641- . map ( |args| args. join ( " " ) )
642- . unwrap_or_default ( ) ,
643- )
644- . env ( "RUSTDOCFLAGS" , rustdoc_flags. join ( " " ) )
645- // For docs.rs detection from build script:
646- // https://github.com/rust-lang/docs.rs/issues/147
647- . env ( "DOCS_RS" , "1" )
648- . args ( & cargo_args)
649- . run ( )
650- . is_ok ( )
651- } ) ;
652- let doc_coverage = if successful {
653- self . get_coverage ( target, build, metadata, limits) ?
654- } else {
655- None
656- } ;
657- // If we're passed a default_target which requires a cross-compile,
658- // cargo will put the output in `target/<target>/doc`.
659- // However, if this is the default build, we don't want it there,
660- // we want it in `target/doc`.
661- if target != HOST_TARGET && is_default_target {
662- // mv target/$target/doc target/doc
663- let target_dir = build. host_target_dir ( ) ;
664- let old_dir = target_dir. join ( target) . join ( "doc" ) ;
665- let new_dir = target_dir. join ( "doc" ) ;
666- debug ! ( "rename {} to {}" , old_dir. display( ) , new_dir. display( ) ) ;
667- std:: fs:: rename ( old_dir, new_dir) ?;
668- }
615+ let mut storage = LogStorage :: new ( LevelFilter :: Info ) ;
616+ storage. set_max_size ( limits. max_log_size ( ) ) ;
617+
618+ let successful = logging:: capture ( & storage, || {
619+ let wrap = || {
620+ config_command ! ( self , build, target, metadata, limits, rustdoc_flags,
621+ . run( )
622+ )
623+ } ;
624+ wrap ( ) . is_ok ( )
625+ } ) ;
626+ let doc_coverage = if successful {
627+ self . get_coverage ( target, build, metadata, limits) ?
628+ } else {
629+ None
630+ } ;
631+ // If we're passed a default_target which requires a cross-compile,
632+ // cargo will put the output in `target/<target>/doc`.
633+ // However, if this is the default build, we don't want it there,
634+ // we want it in `target/doc`.
635+ if target != HOST_TARGET && is_default_target {
636+ // mv target/$target/doc target/doc
637+ let target_dir = build. host_target_dir ( ) ;
638+ let old_dir = target_dir. join ( target) . join ( "doc" ) ;
639+ let new_dir = target_dir. join ( "doc" ) ;
640+ debug ! ( "rename {} to {}" , old_dir. display( ) , new_dir. display( ) ) ;
641+ std:: fs:: rename ( old_dir, new_dir) ?;
642+ }
669643
670- Ok ( FullBuildResult {
671- result : BuildResult {
672- build_log : storage. to_string ( ) ,
673- rustc_version : self . rustc_version . clone ( ) ,
674- docsrs_version : format ! ( "docsrs {}" , crate :: BUILD_VERSION ) ,
675- successful,
676- doc_coverage
677- } ,
678- cargo_metadata,
679- target : target. to_string ( ) ,
680- } )
644+ Ok ( FullBuildResult {
645+ result : BuildResult {
646+ build_log : storage. to_string ( ) ,
647+ rustc_version : self . rustc_version . clone ( ) ,
648+ docsrs_version : format ! ( "docsrs {}" , crate :: BUILD_VERSION ) ,
649+ successful,
650+ doc_coverage,
681651 } ,
682- )
652+ cargo_metadata,
653+ target : target. to_string ( ) ,
654+ } )
683655 }
684656
685657 fn copy_docs (
0 commit comments