3
3
//! This module implements the command-line parsing of the build system which
4
4
//! has various flags to configure how it's run.
5
5
6
- use std:: path:: PathBuf ;
6
+ use std:: path:: { Path , PathBuf } ;
7
7
8
- use clap:: { Parser , ValueEnum } ;
8
+ use clap:: { CommandFactory , Parser , ValueEnum } ;
9
9
10
10
use crate :: builder:: { Builder , Kind } ;
11
11
use crate :: config:: { target_selection_list, Config , TargetSelectionList } ;
@@ -54,15 +54,15 @@ pub struct Flags {
54
54
/// Build directory, overrides `build.build-dir` in `config.toml`
55
55
pub build_dir : Option < PathBuf > ,
56
56
57
- #[ arg( global( true ) , long, value_name = "BUILD" ) ]
57
+ #[ arg( global( true ) , long, value_hint = clap :: ValueHint :: Other , value_name = "BUILD" ) ]
58
58
/// build target of the stage0 compiler
59
59
pub build : Option < String > ,
60
60
61
- #[ arg( global( true ) , long, value_name = "HOST" , value_parser = target_selection_list) ]
61
+ #[ arg( global( true ) , long, value_hint = clap :: ValueHint :: Other , value_name = "HOST" , value_parser = target_selection_list) ]
62
62
/// host targets to build
63
63
pub host : Option < TargetSelectionList > ,
64
64
65
- #[ arg( global( true ) , long, value_name = "TARGET" , value_parser = target_selection_list) ]
65
+ #[ arg( global( true ) , long, value_hint = clap :: ValueHint :: Other , value_name = "TARGET" , value_parser = target_selection_list) ]
66
66
/// target targets to build
67
67
pub target : Option < TargetSelectionList > ,
68
68
@@ -73,7 +73,7 @@ pub struct Flags {
73
73
/// include default paths in addition to the provided ones
74
74
pub include_default_paths : bool ,
75
75
76
- #[ arg( global( true ) , long) ]
76
+ #[ arg( global( true ) , value_hint = clap :: ValueHint :: Other , long) ]
77
77
pub rustc_error_format : Option < String > ,
78
78
79
79
#[ arg( global( true ) , long, value_hint = clap:: ValueHint :: CommandString , value_name = "CMD" ) ]
@@ -82,16 +82,16 @@ pub struct Flags {
82
82
#[ arg( global( true ) , long) ]
83
83
/// dry run; don't build anything
84
84
pub dry_run : bool ,
85
- #[ arg( global( true ) , long, value_name = "N" ) ]
85
+ #[ arg( global( true ) , value_hint = clap :: ValueHint :: Other , long, value_name = "N" ) ]
86
86
/// stage to build (indicates compiler to use/test, e.g., stage 0 uses the
87
87
/// bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)
88
88
pub stage : Option < u32 > ,
89
89
90
- #[ arg( global( true ) , long, value_name = "N" ) ]
90
+ #[ arg( global( true ) , value_hint = clap :: ValueHint :: Other , long, value_name = "N" ) ]
91
91
/// stage(s) to keep without recompiling
92
92
/// (pass multiple times to keep e.g., both stages 0 and 1)
93
93
pub keep_stage : Vec < u32 > ,
94
- #[ arg( global( true ) , long, value_name = "N" ) ]
94
+ #[ arg( global( true ) , value_hint = clap :: ValueHint :: Other , long, value_name = "N" ) ]
95
95
/// stage(s) of the standard library to keep without recompiling
96
96
/// (pass multiple times to keep e.g., both stages 0 and 1)
97
97
pub keep_stage_std : Vec < u32 > ,
@@ -103,6 +103,7 @@ pub struct Flags {
103
103
global( true ) ,
104
104
short,
105
105
long,
106
+ value_hint = clap:: ValueHint :: Other ,
106
107
default_value_t = std:: thread:: available_parallelism( ) . map_or( 1 , std:: num:: NonZeroUsize :: get) ,
107
108
value_name = "JOBS"
108
109
) ]
@@ -117,7 +118,7 @@ pub struct Flags {
117
118
/// otherwise, use the default configured behaviour
118
119
pub warnings : Warnings ,
119
120
120
- #[ arg( global( true ) , long, value_name = "FORMAT" ) ]
121
+ #[ arg( global( true ) , value_hint = clap :: ValueHint :: Other , long, value_name = "FORMAT" ) ]
121
122
/// rustc error format
122
123
pub error_format : Option < String > ,
123
124
#[ arg( global( true ) , long) ]
@@ -133,13 +134,13 @@ pub struct Flags {
133
134
#[ arg( global( true ) , long, value_name = "VALUE" ) ]
134
135
pub llvm_skip_rebuild : Option < bool > ,
135
136
/// generate PGO profile with rustc build
136
- #[ arg( global( true ) , long, value_name = "PROFILE" ) ]
137
+ #[ arg( global( true ) , value_hint = clap :: ValueHint :: FilePath , long, value_name = "PROFILE" ) ]
137
138
pub rust_profile_generate : Option < String > ,
138
139
/// use PGO profile for rustc build
139
- #[ arg( global( true ) , long, value_name = "PROFILE" ) ]
140
+ #[ arg( global( true ) , value_hint = clap :: ValueHint :: FilePath , long, value_name = "PROFILE" ) ]
140
141
pub rust_profile_use : Option < String > ,
141
142
/// use PGO profile for LLVM build
142
- #[ arg( global( true ) , long, value_name = "PROFILE" ) ]
143
+ #[ arg( global( true ) , value_hint = clap :: ValueHint :: FilePath , long, value_name = "PROFILE" ) ]
143
144
pub llvm_profile_use : Option < String > ,
144
145
// LLVM doesn't support a custom location for generating profile
145
146
// information.
@@ -152,7 +153,7 @@ pub struct Flags {
152
153
#[ arg( global( true ) , long) ]
153
154
pub llvm_bolt_profile_generate : bool ,
154
155
/// use BOLT profile for LLVM build
155
- #[ arg( global( true ) , long, value_name = "PROFILE" ) ]
156
+ #[ arg( global( true ) , value_hint = clap :: ValueHint :: FilePath , long, value_name = "PROFILE" ) ]
156
157
pub llvm_bolt_profile_use : Option < String > ,
157
158
#[ arg( global( true ) ) ]
158
159
/// paths for the subcommand
@@ -524,3 +525,23 @@ impl Subcommand {
524
525
}
525
526
}
526
527
}
528
+
529
+ /// Returns the shell completion for a given shell, if the result differs from the current
530
+ /// content of `path`. If `path` does not exist, always returns `Some`.
531
+ pub fn get_completion < G : clap_complete:: Generator > ( shell : G , path : & Path ) -> Option < String > {
532
+ let mut cmd = Flags :: command ( ) ;
533
+ let current = if !path. exists ( ) {
534
+ String :: new ( )
535
+ } else {
536
+ std:: fs:: read_to_string ( path) . unwrap_or_else ( |_| {
537
+ eprintln ! ( "couldn't read {}" , path. display( ) ) ;
538
+ crate :: detail_exit ( 1 )
539
+ } )
540
+ } ;
541
+ let mut buf = Vec :: new ( ) ;
542
+ clap_complete:: generate ( shell, & mut cmd, "x.py" , & mut buf) ;
543
+ if buf == current. as_bytes ( ) {
544
+ return None ;
545
+ }
546
+ Some ( String :: from_utf8 ( buf) . expect ( "completion script should be UTF-8" ) )
547
+ }
0 commit comments