1
1
//! Helpers for validating and checking names like package and crate names.
2
2
3
- use crate :: util:: CargoResult ;
4
- use anyhow:: bail;
5
3
use std:: path:: Path ;
6
4
7
5
/// Returns `true` if the name contains non-ASCII characters.
@@ -36,80 +34,6 @@ pub fn is_conflicting_artifact_name(name: &str) -> bool {
36
34
[ "deps" , "examples" , "build" , "incremental" ] . contains ( & name)
37
35
}
38
36
39
- /// Check the base requirements for a package name.
40
- ///
41
- /// This can be used for other things than package names, to enforce some
42
- /// level of sanity. Note that package names have other restrictions
43
- /// elsewhere. `cargo new` has a few restrictions, such as checking for
44
- /// reserved names. crates.io has even more restrictions.
45
- pub fn validate_package_name ( name : & str , what : & str , help : & str ) -> CargoResult < ( ) > {
46
- if name. is_empty ( ) {
47
- bail ! ( "{what} cannot be empty" ) ;
48
- }
49
-
50
- let mut chars = name. chars ( ) ;
51
- if let Some ( ch) = chars. next ( ) {
52
- if ch. is_digit ( 10 ) {
53
- // A specific error for a potentially common case.
54
- bail ! (
55
- "the name `{}` cannot be used as a {}, \
56
- the name cannot start with a digit{}",
57
- name,
58
- what,
59
- help
60
- ) ;
61
- }
62
- if !( unicode_xid:: UnicodeXID :: is_xid_start ( ch) || ch == '_' ) {
63
- bail ! (
64
- "invalid character `{}` in {}: `{}`, \
65
- the first character must be a Unicode XID start character \
66
- (most letters or `_`){}",
67
- ch,
68
- what,
69
- name,
70
- help
71
- ) ;
72
- }
73
- }
74
- for ch in chars {
75
- if !( unicode_xid:: UnicodeXID :: is_xid_continue ( ch) || ch == '-' ) {
76
- bail ! (
77
- "invalid character `{}` in {}: `{}`, \
78
- characters must be Unicode XID characters \
79
- (numbers, `-`, `_`, or most letters){}",
80
- ch,
81
- what,
82
- name,
83
- help
84
- ) ;
85
- }
86
- }
87
- Ok ( ( ) )
88
- }
89
-
90
- /// Ensure a package name is [valid][validate_package_name]
91
- pub fn sanitize_package_name ( name : & str , placeholder : char ) -> String {
92
- let mut slug = String :: new ( ) ;
93
- let mut chars = name. chars ( ) ;
94
- while let Some ( ch) = chars. next ( ) {
95
- if ( unicode_xid:: UnicodeXID :: is_xid_start ( ch) || ch == '_' ) && !ch. is_digit ( 10 ) {
96
- slug. push ( ch) ;
97
- break ;
98
- }
99
- }
100
- while let Some ( ch) = chars. next ( ) {
101
- if unicode_xid:: UnicodeXID :: is_xid_continue ( ch) || ch == '-' {
102
- slug. push ( ch) ;
103
- } else {
104
- slug. push ( placeholder) ;
105
- }
106
- }
107
- if slug. is_empty ( ) {
108
- slug. push_str ( "package" ) ;
109
- }
110
- slug
111
- }
112
-
113
37
/// Check the entire path for names reserved in Windows.
114
38
pub fn is_windows_reserved_path ( path : & Path ) -> bool {
115
39
path. iter ( )
@@ -124,140 +48,3 @@ pub fn is_windows_reserved_path(path: &Path) -> bool {
124
48
pub fn is_glob_pattern < T : AsRef < str > > ( name : T ) -> bool {
125
49
name. as_ref ( ) . contains ( & [ '*' , '?' , '[' , ']' ] [ ..] )
126
50
}
127
-
128
- /// Validate dir-names and profile names according to RFC 2678.
129
- pub fn validate_profile_name ( name : & str ) -> CargoResult < ( ) > {
130
- if let Some ( ch) = name
131
- . chars ( )
132
- . find ( |ch| !ch. is_alphanumeric ( ) && * ch != '_' && * ch != '-' )
133
- {
134
- bail ! (
135
- "invalid character `{}` in profile name `{}`\n \
136
- Allowed characters are letters, numbers, underscore, and hyphen.",
137
- ch,
138
- name
139
- ) ;
140
- }
141
-
142
- const SEE_DOCS : & str = "See https://doc.rust-lang.org/cargo/reference/profiles.html \
143
- for more on configuring profiles.";
144
-
145
- let lower_name = name. to_lowercase ( ) ;
146
- if lower_name == "debug" {
147
- bail ! (
148
- "profile name `{}` is reserved\n \
149
- To configure the default development profile, use the name `dev` \
150
- as in [profile.dev]\n \
151
- {}",
152
- name,
153
- SEE_DOCS
154
- ) ;
155
- }
156
- if lower_name == "build-override" {
157
- bail ! (
158
- "profile name `{}` is reserved\n \
159
- To configure build dependency settings, use [profile.dev.build-override] \
160
- and [profile.release.build-override]\n \
161
- {}",
162
- name,
163
- SEE_DOCS
164
- ) ;
165
- }
166
-
167
- // These are some arbitrary reservations. We have no plans to use
168
- // these, but it seems safer to reserve a few just in case we want to
169
- // add more built-in profiles in the future. We can also uses special
170
- // syntax like cargo:foo if needed. But it is unlikely these will ever
171
- // be used.
172
- if matches ! (
173
- lower_name. as_str( ) ,
174
- "build"
175
- | "check"
176
- | "clean"
177
- | "config"
178
- | "fetch"
179
- | "fix"
180
- | "install"
181
- | "metadata"
182
- | "package"
183
- | "publish"
184
- | "report"
185
- | "root"
186
- | "run"
187
- | "rust"
188
- | "rustc"
189
- | "rustdoc"
190
- | "target"
191
- | "tmp"
192
- | "uninstall"
193
- ) || lower_name. starts_with ( "cargo" )
194
- {
195
- bail ! (
196
- "profile name `{}` is reserved\n \
197
- Please choose a different name.\n \
198
- {}",
199
- name,
200
- SEE_DOCS
201
- ) ;
202
- }
203
-
204
- Ok ( ( ) )
205
- }
206
-
207
- pub fn validate_feature_name ( name : & str ) -> CargoResult < ( ) > {
208
- if name. is_empty ( ) {
209
- bail ! ( "feature name cannot be empty" ) ;
210
- }
211
-
212
- if name. starts_with ( "dep:" ) {
213
- bail ! ( "feature named `{name}` is not allowed to start with `dep:`" , ) ;
214
- }
215
- if name. contains ( '/' ) {
216
- bail ! ( "feature named `{name}` is not allowed to contain slashes" , ) ;
217
- }
218
- let mut chars = name. chars ( ) ;
219
- if let Some ( ch) = chars. next ( ) {
220
- if !( unicode_xid:: UnicodeXID :: is_xid_start ( ch) || ch == '_' || ch. is_digit ( 10 ) ) {
221
- bail ! (
222
- "invalid character `{ch}` in feature `{name}`, \
223
- the first character must be a Unicode XID start character or digit \
224
- (most letters or `_` or `0` to `9`)",
225
- ) ;
226
- }
227
- }
228
- for ch in chars {
229
- if !( unicode_xid:: UnicodeXID :: is_xid_continue ( ch) || ch == '-' || ch == '+' || ch == '.' ) {
230
- bail ! (
231
- "invalid character `{ch}` in feature `{name}`, \
232
- characters must be Unicode XID characters, '-', `+`, or `.` \
233
- (numbers, `+`, `-`, `_`, `.`, or most letters)",
234
- ) ;
235
- }
236
- }
237
- Ok ( ( ) )
238
- }
239
-
240
- #[ cfg( test) ]
241
- mod tests {
242
- use super :: * ;
243
-
244
- #[ test]
245
- fn valid_feature_names ( ) {
246
- assert ! ( validate_feature_name( "c++17" ) . is_ok( ) ) ;
247
- assert ! ( validate_feature_name( "128bit" ) . is_ok( ) ) ;
248
- assert ! ( validate_feature_name( "_foo" ) . is_ok( ) ) ;
249
- assert ! ( validate_feature_name( "feat-name" ) . is_ok( ) ) ;
250
- assert ! ( validate_feature_name( "feat_name" ) . is_ok( ) ) ;
251
- assert ! ( validate_feature_name( "foo.bar" ) . is_ok( ) ) ;
252
-
253
- assert ! ( validate_feature_name( "+foo" ) . is_err( ) ) ;
254
- assert ! ( validate_feature_name( "-foo" ) . is_err( ) ) ;
255
- assert ! ( validate_feature_name( ".foo" ) . is_err( ) ) ;
256
- assert ! ( validate_feature_name( "foo:bar" ) . is_err( ) ) ;
257
- assert ! ( validate_feature_name( "foo?" ) . is_err( ) ) ;
258
- assert ! ( validate_feature_name( "?foo" ) . is_err( ) ) ;
259
- assert ! ( validate_feature_name( "ⒶⒷⒸ" ) . is_err( ) ) ;
260
- assert ! ( validate_feature_name( "a¼" ) . is_err( ) ) ;
261
- assert ! ( validate_feature_name( "" ) . is_err( ) ) ;
262
- }
263
- }
0 commit comments