1 //! Tests for the `cargo config` command.
2
3 use super::config::write_config_at;
4 use cargo_test_support::paths;
5 use std::fs;
6 use std::path::PathBuf;
7
cargo_process(s: &str) -> cargo_test_support::Execs8 fn cargo_process(s: &str) -> cargo_test_support::Execs {
9 let mut p = cargo_test_support::cargo_process(s);
10 // Clear out some of the environment added by the default cargo_process so
11 // the tests don't need to deal with it.
12 p.env_remove("CARGO_PROFILE_DEV_SPLIT_DEBUGINFO")
13 .env_remove("CARGO_PROFILE_TEST_SPLIT_DEBUGINFO")
14 .env_remove("CARGO_PROFILE_RELEASE_SPLIT_DEBUGINFO")
15 .env_remove("CARGO_PROFILE_BENCH_SPLIT_DEBUGINFO")
16 .env_remove("CARGO_INCREMENTAL");
17 p
18 }
19
20 #[cargo_test]
gated()21 fn gated() {
22 cargo_process("config get")
23 .masquerade_as_nightly_cargo()
24 .with_status(101)
25 .with_stderr("\
26 error: the `cargo config` command is unstable, pass `-Z unstable-options` to enable it
27 See https://github.com/rust-lang/cargo/issues/9301 for more information about the `cargo config` command.
28 ")
29 .run();
30 }
31
common_setup() -> PathBuf32 fn common_setup() -> PathBuf {
33 write_config_at(
34 paths::home().join(".cargo/config.toml"),
35 "
36 [alias]
37 foo = \"abc --xyz\"
38 [build]
39 jobs = 99
40 rustflags = [\"--flag-global\"]
41 [profile.dev]
42 opt-level = 3
43 [profile.dev.package.foo]
44 opt-level = 1
45 [target.'cfg(target_os = \"linux\")']
46 runner = \"runme\"
47
48 # How unknown keys are handled.
49 [extra-table]
50 somekey = \"somevalue\"
51 ",
52 );
53 let sub_folder = paths::root().join("foo/.cargo");
54 write_config_at(
55 sub_folder.join("config.toml"),
56 "
57 [alias]
58 sub-example = [\"sub\", \"example\"]
59 [build]
60 rustflags = [\"--flag-directory\"]
61 ",
62 );
63 sub_folder
64 }
65
66 #[cargo_test]
get_toml()67 fn get_toml() {
68 // Notes:
69 // - The "extra-table" is shown without a warning. I'm not sure how that
70 // should be handled, since displaying warnings could cause problems
71 // with ingesting the output.
72 // - Environment variables aren't loaded. :(
73 let sub_folder = common_setup();
74 cargo_process("config get -Zunstable-options")
75 .cwd(&sub_folder.parent().unwrap())
76 .masquerade_as_nightly_cargo()
77 .env("CARGO_ALIAS_BAR", "cat dog")
78 .env("CARGO_BUILD_JOBS", "100")
79 // The weird forward slash in the linux line is due to testsuite normalization.
80 .with_stdout(
81 "\
82 alias.foo = \"abc --xyz\"
83 alias.sub-example = [\"sub\", \"example\"]
84 build.jobs = 99
85 build.rustflags = [\"--flag-directory\", \"--flag-global\"]
86 extra-table.somekey = \"somevalue\"
87 profile.dev.opt-level = 3
88 profile.dev.package.foo.opt-level = 1
89 target.\"cfg(target_os = \\\"linux\\\")\".runner = \"runme\"
90 # The following environment variables may affect the loaded values.
91 # CARGO_ALIAS_BAR=[..]cat dog[..]
92 # CARGO_BUILD_JOBS=100
93 # CARGO_HOME=[ROOT]/home/.cargo
94 ",
95 )
96 .with_stderr("")
97 .run();
98
99 // Env keys work if they are specific.
100 cargo_process("config get build.jobs -Zunstable-options")
101 .cwd(&sub_folder.parent().unwrap())
102 .masquerade_as_nightly_cargo()
103 .env("CARGO_BUILD_JOBS", "100")
104 .with_stdout("build.jobs = 100")
105 .with_stderr("")
106 .run();
107
108 // Array value.
109 cargo_process("config get build.rustflags -Zunstable-options")
110 .cwd(&sub_folder.parent().unwrap())
111 .masquerade_as_nightly_cargo()
112 .with_stdout("build.rustflags = [\"--flag-directory\", \"--flag-global\"]")
113 .with_stderr("")
114 .run();
115
116 // Sub-table
117 cargo_process("config get profile -Zunstable-options")
118 .cwd(&sub_folder.parent().unwrap())
119 .masquerade_as_nightly_cargo()
120 .with_stdout(
121 "\
122 profile.dev.opt-level = 3
123 profile.dev.package.foo.opt-level = 1
124 ",
125 )
126 .with_stderr("")
127 .run();
128
129 // Specific profile entry.
130 cargo_process("config get profile.dev.opt-level -Zunstable-options")
131 .cwd(&sub_folder.parent().unwrap())
132 .masquerade_as_nightly_cargo()
133 .with_stdout("profile.dev.opt-level = 3")
134 .with_stderr("")
135 .run();
136
137 // A key that isn't set.
138 cargo_process("config get build.rustc -Zunstable-options")
139 .cwd(&sub_folder.parent().unwrap())
140 .masquerade_as_nightly_cargo()
141 .with_status(101)
142 .with_stdout("")
143 .with_stderr("error: config value `build.rustc` is not set")
144 .run();
145
146 // A key that is not part of Cargo's config schema.
147 cargo_process("config get not.set -Zunstable-options")
148 .cwd(&sub_folder.parent().unwrap())
149 .masquerade_as_nightly_cargo()
150 .with_status(101)
151 .with_stdout("")
152 .with_stderr("error: config value `not.set` is not set")
153 .run();
154 }
155
156 #[cargo_test]
get_json()157 fn get_json() {
158 // Notes:
159 // - This does not show env vars at all. :(
160 let all_json = r#"
161 {
162 "alias": {
163 "foo": "abc --xyz",
164 "sub-example": [
165 "sub",
166 "example"
167 ]
168 },
169 "build": {
170 "jobs": 99,
171 "rustflags": [
172 "--flag-directory",
173 "--flag-global"
174 ]
175 },
176 "extra-table": {
177 "somekey": "somevalue"
178 },
179 "profile": {
180 "dev": {
181 "opt-level": 3,
182 "package": {
183 "foo": {
184 "opt-level": 1
185 }
186 }
187 }
188 },
189 "target": {
190 "cfg(target_os = \"linux\")": {
191 "runner": "runme"
192 }
193 }
194 }
195 "#;
196 let sub_folder = common_setup();
197 cargo_process("config get --format=json -Zunstable-options")
198 .cwd(&sub_folder.parent().unwrap())
199 .masquerade_as_nightly_cargo()
200 .env("CARGO_ALIAS_BAR", "cat dog")
201 .env("CARGO_BUILD_JOBS", "100")
202 .with_json(all_json)
203 .with_stderr(
204 "\
205 note: The following environment variables may affect the loaded values.
206 CARGO_ALIAS_BAR=[..]cat dog[..]
207 CARGO_BUILD_JOBS=100
208 CARGO_HOME=[ROOT]/home/.cargo
209 ",
210 )
211 .run();
212
213 // json-value is the same for the entire root table
214 cargo_process("config get --format=json-value -Zunstable-options")
215 .cwd(&sub_folder.parent().unwrap())
216 .masquerade_as_nightly_cargo()
217 .with_json(all_json)
218 .with_stderr(
219 "\
220 note: The following environment variables may affect the loaded values.
221 CARGO_HOME=[ROOT]/home/.cargo
222 ",
223 )
224 .run();
225
226 cargo_process("config get --format=json build.jobs -Zunstable-options")
227 .cwd(&sub_folder.parent().unwrap())
228 .masquerade_as_nightly_cargo()
229 .with_json(
230 r#"
231 {"build": {"jobs": 99}}
232 "#,
233 )
234 .with_stderr("")
235 .run();
236
237 cargo_process("config get --format=json-value build.jobs -Zunstable-options")
238 .cwd(&sub_folder.parent().unwrap())
239 .masquerade_as_nightly_cargo()
240 .with_stdout("99")
241 .with_stderr("")
242 .run();
243 }
244
245 #[cargo_test]
show_origin_toml()246 fn show_origin_toml() {
247 let sub_folder = common_setup();
248 cargo_process("config get --show-origin -Zunstable-options")
249 .cwd(&sub_folder.parent().unwrap())
250 .masquerade_as_nightly_cargo()
251 .with_stdout(
252 "\
253 alias.foo = \"abc --xyz\" # [ROOT]/home/.cargo/config.toml
254 alias.sub-example = [
255 \"sub\", # [ROOT]/foo/.cargo/config.toml
256 \"example\", # [ROOT]/foo/.cargo/config.toml
257 ]
258 build.jobs = 99 # [ROOT]/home/.cargo/config.toml
259 build.rustflags = [
260 \"--flag-directory\", # [ROOT]/foo/.cargo/config.toml
261 \"--flag-global\", # [ROOT]/home/.cargo/config.toml
262 ]
263 extra-table.somekey = \"somevalue\" # [ROOT]/home/.cargo/config.toml
264 profile.dev.opt-level = 3 # [ROOT]/home/.cargo/config.toml
265 profile.dev.package.foo.opt-level = 1 # [ROOT]/home/.cargo/config.toml
266 target.\"cfg(target_os = \\\"linux\\\")\".runner = \"runme\" # [ROOT]/home/.cargo/config.toml
267 # The following environment variables may affect the loaded values.
268 # CARGO_HOME=[ROOT]/home/.cargo
269 ",
270 )
271 .with_stderr("")
272 .run();
273
274 cargo_process("config get --show-origin build.rustflags -Zunstable-options")
275 .cwd(&sub_folder.parent().unwrap())
276 .masquerade_as_nightly_cargo()
277 .env("CARGO_BUILD_RUSTFLAGS", "env1 env2")
278 .with_stdout(
279 "\
280 build.rustflags = [
281 \"--flag-directory\", # [ROOT]/foo/.cargo/config.toml
282 \"--flag-global\", # [ROOT]/home/.cargo/config.toml
283 \"env1\", # environment variable `CARGO_BUILD_RUSTFLAGS`
284 \"env2\", # environment variable `CARGO_BUILD_RUSTFLAGS`
285 ]
286 ",
287 )
288 .with_stderr("")
289 .run();
290 }
291
292 #[cargo_test]
show_origin_toml_cli()293 fn show_origin_toml_cli() {
294 let sub_folder = common_setup();
295 cargo_process("config get --show-origin build.jobs -Zunstable-options --config build.jobs=123")
296 .cwd(&sub_folder.parent().unwrap())
297 .masquerade_as_nightly_cargo()
298 .env("CARGO_BUILD_JOBS", "1")
299 .with_stdout("build.jobs = 123 # --config cli option")
300 .with_stderr("")
301 .run();
302
303 cargo_process("config get --show-origin build.rustflags -Zunstable-options --config")
304 .arg("build.rustflags=[\"cli1\",\"cli2\"]")
305 .cwd(&sub_folder.parent().unwrap())
306 .masquerade_as_nightly_cargo()
307 .env("CARGO_BUILD_RUSTFLAGS", "env1 env2")
308 .with_stdout(
309 "\
310 build.rustflags = [
311 \"--flag-directory\", # [ROOT]/foo/.cargo/config.toml
312 \"--flag-global\", # [ROOT]/home/.cargo/config.toml
313 \"cli1\", # --config cli option
314 \"cli2\", # --config cli option
315 \"env1\", # environment variable `CARGO_BUILD_RUSTFLAGS`
316 \"env2\", # environment variable `CARGO_BUILD_RUSTFLAGS`
317 ]
318 ",
319 )
320 .with_stderr("")
321 .run();
322 }
323
324 #[cargo_test]
show_origin_json()325 fn show_origin_json() {
326 let sub_folder = common_setup();
327 cargo_process("config get --show-origin --format=json -Zunstable-options")
328 .cwd(&sub_folder.parent().unwrap())
329 .masquerade_as_nightly_cargo()
330 .with_status(101)
331 .with_stderr("error: the `json` format does not support --show-origin, try the `toml` format instead")
332 .run();
333 }
334
335 #[cargo_test]
unmerged_toml()336 fn unmerged_toml() {
337 let sub_folder = common_setup();
338 cargo_process("config get --merged=no -Zunstable-options")
339 .cwd(&sub_folder.parent().unwrap())
340 .masquerade_as_nightly_cargo()
341 .env("CARGO_ALIAS_BAR", "cat dog")
342 .env("CARGO_BUILD_JOBS", "100")
343 .with_stdout(
344 "\
345 # Environment variables
346 # CARGO=[..]
347 # CARGO_ALIAS_BAR=[..]cat dog[..]
348 # CARGO_BUILD_JOBS=100
349 # CARGO_HOME=[ROOT]/home/.cargo
350
351 # [ROOT]/foo/.cargo/config.toml
352 alias.sub-example = [\"sub\", \"example\"]
353 build.rustflags = [\"--flag-directory\"]
354
355 # [ROOT]/home/.cargo/config.toml
356 alias.foo = \"abc --xyz\"
357 build.jobs = 99
358 build.rustflags = [\"--flag-global\"]
359 extra-table.somekey = \"somevalue\"
360 profile.dev.opt-level = 3
361 profile.dev.package.foo.opt-level = 1
362 target.\"cfg(target_os = \\\"linux\\\")\".runner = \"runme\"
363
364 ",
365 )
366 .with_stderr("")
367 .run();
368
369 cargo_process("config get --merged=no build.rustflags -Zunstable-options")
370 .cwd(&sub_folder.parent().unwrap())
371 .masquerade_as_nightly_cargo()
372 .env("CARGO_BUILD_RUSTFLAGS", "env1 env2")
373 .with_stdout(
374 "\
375 # Environment variables
376 # CARGO_BUILD_RUSTFLAGS=[..]env1 env2[..]
377
378 # [ROOT]/foo/.cargo/config.toml
379 build.rustflags = [\"--flag-directory\"]
380
381 # [ROOT]/home/.cargo/config.toml
382 build.rustflags = [\"--flag-global\"]
383
384 ",
385 )
386 .with_stderr("")
387 .run();
388
389 cargo_process("config get --merged=no does.not.exist -Zunstable-options")
390 .cwd(&sub_folder.parent().unwrap())
391 .masquerade_as_nightly_cargo()
392 .with_stderr("")
393 .with_stderr("")
394 .run();
395
396 cargo_process("config get --merged=no build.rustflags.extra -Zunstable-options")
397 .cwd(&sub_folder.parent().unwrap())
398 .masquerade_as_nightly_cargo()
399 .with_status(101)
400 .with_stderr(
401 "error: expected table for configuration key `build.rustflags`, \
402 but found array in [ROOT]/foo/.cargo/config.toml",
403 )
404 .run();
405 }
406
407 #[cargo_test]
unmerged_toml_cli()408 fn unmerged_toml_cli() {
409 let sub_folder = common_setup();
410 cargo_process("config get --merged=no build.rustflags -Zunstable-options --config")
411 .arg("build.rustflags=[\"cli1\",\"cli2\"]")
412 .cwd(&sub_folder.parent().unwrap())
413 .masquerade_as_nightly_cargo()
414 .env("CARGO_BUILD_RUSTFLAGS", "env1 env2")
415 .with_stdout(
416 "\
417 # --config cli option
418 build.rustflags = [\"cli1\", \"cli2\"]
419
420 # Environment variables
421 # CARGO_BUILD_RUSTFLAGS=[..]env1 env2[..]
422
423 # [ROOT]/foo/.cargo/config.toml
424 build.rustflags = [\"--flag-directory\"]
425
426 # [ROOT]/home/.cargo/config.toml
427 build.rustflags = [\"--flag-global\"]
428
429 ",
430 )
431 .with_stderr("")
432 .run();
433 }
434
435 #[cargo_test]
unmerged_json()436 fn unmerged_json() {
437 let sub_folder = common_setup();
438 cargo_process("config get --merged=no --format=json -Zunstable-options")
439 .cwd(&sub_folder.parent().unwrap())
440 .masquerade_as_nightly_cargo()
441 .with_status(101)
442 .with_stderr(
443 "error: the `json` format does not support --merged=no, try the `toml` format instead",
444 )
445 .run();
446 }
447
448 #[cargo_test]
includes()449 fn includes() {
450 let sub_folder = common_setup();
451 fs::write(
452 sub_folder.join("config.toml"),
453 "
454 include = 'other.toml'
455 [build]
456 rustflags = [\"--flag-directory\"]
457 ",
458 )
459 .unwrap();
460 fs::write(
461 sub_folder.join("other.toml"),
462 "
463 [build]
464 rustflags = [\"--flag-other\"]
465 ",
466 )
467 .unwrap();
468
469 cargo_process("config get build.rustflags -Zunstable-options -Zconfig-include")
470 .cwd(&sub_folder.parent().unwrap())
471 .masquerade_as_nightly_cargo()
472 .with_stdout(r#"build.rustflags = ["--flag-other", "--flag-directory", "--flag-global"]"#)
473 .with_stderr("")
474 .run();
475
476 cargo_process(
477 "config get build.rustflags --show-origin=yes -Zunstable-options -Zconfig-include",
478 )
479 .cwd(&sub_folder.parent().unwrap())
480 .masquerade_as_nightly_cargo()
481 .with_stdout(
482 "\
483 build.rustflags = [
484 \"--flag-other\", # [ROOT]/foo/.cargo/other.toml
485 \"--flag-directory\", # [ROOT]/foo/.cargo/config.toml
486 \"--flag-global\", # [ROOT]/home/.cargo/config.toml
487 ]
488 ",
489 )
490 .with_stderr("")
491 .run();
492
493 cargo_process("config get --merged=no -Zunstable-options -Zconfig-include")
494 .cwd(&sub_folder.parent().unwrap())
495 .masquerade_as_nightly_cargo()
496 .with_stdout(
497 "\
498 # Environment variables
499 # CARGO=[..]
500 # CARGO_HOME=[ROOT]/home/.cargo
501
502 # [ROOT]/foo/.cargo/other.toml
503 build.rustflags = [\"--flag-other\"]
504
505 # [ROOT]/foo/.cargo/config.toml
506 build.rustflags = [\"--flag-directory\"]
507 include = \"other.toml\"
508
509 # [ROOT]/home/.cargo/config.toml
510 alias.foo = \"abc --xyz\"
511 build.jobs = 99
512 build.rustflags = [\"--flag-global\"]
513 extra-table.somekey = \"somevalue\"
514 profile.dev.opt-level = 3
515 profile.dev.package.foo.opt-level = 1
516 target.\"cfg(target_os = \\\"linux\\\")\".runner = \"runme\"
517
518 ",
519 )
520 .with_stderr("")
521 .run();
522 }
523