]> git.proxmox.com Git - cargo.git/blame - tests/testsuite/publish.rs
Document lib before bin.
[cargo.git] / tests / testsuite / publish.rs
CommitLineData
83571aee
EH
1//! Tests for the `cargo publish` command.
2
9115b2c3
AC
3use cargo_test_support::git::{self, repo};
4use cargo_test_support::paths;
5use cargo_test_support::registry::{self, registry_path, registry_url, Package};
7a5f0369 6use cargo_test_support::{basic_manifest, no_such_file_err_msg, project, publish};
4ae79d2f 7use std::fs;
3d84d0ad
EH
8
9const CLEAN_FOO_JSON: &str = r#"
10 {
11 "authors": [],
12 "badges": {},
13 "categories": [],
14 "deps": [],
15 "description": "foo",
16 "documentation": "foo",
17 "features": {},
18 "homepage": "foo",
19 "keywords": [],
20 "license": "MIT",
21 "license_file": null,
22 "links": null,
23 "name": "foo",
24 "readme": null,
25 "readme_file": null,
26 "repository": "foo",
27 "vers": "0.0.1"
28 }
29"#;
30
31fn validate_upload_foo() {
32 publish::validate_upload(
33 r#"
34 {
35 "authors": [],
36 "badges": {},
37 "categories": [],
38 "deps": [],
39 "description": "foo",
40 "documentation": null,
41 "features": {},
42 "homepage": null,
43 "keywords": [],
44 "license": "MIT",
45 "license_file": null,
46 "links": null,
47 "name": "foo",
48 "readme": null,
49 "readme_file": null,
50 "repository": null,
51 "vers": "0.0.1"
52 }
53 "#,
54 "foo-0.0.1.crate",
34307c61 55 &["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"],
3d84d0ad
EH
56 );
57}
58
8f1f0e40 59fn validate_upload_bar() {
60 publish::validate_upload(
61 r#"
62 {
63 "authors": [],
64 "badges": {},
65 "categories": [],
66 "deps": [],
67 "description": "bar",
68 "documentation": null,
69 "features": {},
70 "homepage": null,
71 "keywords": [],
72 "license": "MIT",
73 "license_file": null,
74 "links": null,
75 "name": "bar",
76 "readme": null,
77 "readme_file": null,
78 "repository": null,
79 "vers": "0.0.1"
80 }
81 "#,
82 "bar-0.0.1.crate",
83 &["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"],
84 );
85}
86
3d84d0ad
EH
87fn validate_upload_foo_clean() {
88 publish::validate_upload(
89 CLEAN_FOO_JSON,
90 "foo-0.0.1.crate",
91 &[
34307c61 92 "Cargo.lock",
3d84d0ad
EH
93 "Cargo.toml",
94 "Cargo.toml.orig",
95 "src/main.rs",
96 ".cargo_vcs_info.json",
97 ],
98 );
99}
eccdcae0 100
0e0d9688 101#[cargo_test]
6950bbb0 102fn simple() {
b5144c7f 103 registry::init();
6950bbb0 104
7fe2fbc8 105 let p = project()
1e682848
AC
106 .file(
107 "Cargo.toml",
108 r#"
6f8c7d5a
EH
109 [project]
110 name = "foo"
111 version = "0.0.1"
112 authors = []
113 license = "MIT"
114 description = "foo"
115 "#,
fecb7246
AC
116 )
117 .file("src/main.rs", "fn main() {}")
d43ee1dd 118 .build();
ce9e47ac 119
b4c37403 120 p.cargo("publish --no-verify --token sekrit")
8c75e2ff 121 .with_stderr(
1e682848 122 "\
8c75e2ff 123[UPDATING] `dummy-registry` index
ce9e47ac
NB
124[WARNING] manifest has no documentation, [..]
125See [..]
89f43938
ZL
126[PACKAGING] foo v0.0.1 ([CWD])
127[UPLOADING] foo v0.0.1 ([CWD])
5cb5e7d8 128",
8c75e2ff 129 )
fecb7246 130 .run();
5cb5e7d8 131
3d84d0ad 132 validate_upload_foo();
5cb5e7d8
SF
133}
134
0e0d9688 135#[cargo_test]
5cb5e7d8 136fn old_token_location() {
b5144c7f
EH
137 // Check that the `token` key works at the root instead of under a
138 // `[registry]` table.
139 registry::init();
5cb5e7d8 140
7fe2fbc8 141 let p = project()
1e682848
AC
142 .file(
143 "Cargo.toml",
144 r#"
6f8c7d5a
EH
145 [project]
146 name = "foo"
147 version = "0.0.1"
148 authors = []
149 license = "MIT"
150 description = "foo"
151 "#,
fecb7246
AC
152 )
153 .file("src/main.rs", "fn main() {}")
5cb5e7d8
SF
154 .build();
155
b5144c7f
EH
156 let credentials = paths::home().join(".cargo/credentials");
157 fs::remove_file(&credentials).unwrap();
158
159 // Verify can't publish without a token.
b4c37403 160 p.cargo("publish --no-verify")
b5144c7f 161 .with_status(101)
b4c37403
EH
162 .with_stderr_contains(
163 "[ERROR] no upload token found, \
164 please run `cargo login` or pass `--token`",
165 )
b5144c7f
EH
166 .run();
167
4ae79d2f 168 fs::write(&credentials, r#"token = "api-token""#).unwrap();
b5144c7f 169
b4c37403 170 p.cargo("publish --no-verify")
8c75e2ff 171 .with_stderr(
1e682848 172 "\
8c75e2ff 173[UPDATING] `dummy-registry` index
65274ea7
EH
174[WARNING] using `registry.token` config value with source replacement is deprecated
175This may become a hard error in the future[..]
176Use the --token command-line flag to remove this warning.
5cb5e7d8
SF
177[WARNING] manifest has no documentation, [..]
178See [..]
89f43938
ZL
179[PACKAGING] foo v0.0.1 ([CWD])
180[UPLOADING] foo v0.0.1 ([CWD])
ce9e47ac 181",
8c75e2ff 182 )
fecb7246 183 .run();
ce9e47ac 184
3d84d0ad 185 validate_upload_foo();
ce9e47ac
NB
186}
187
78e64de9
NB
188// TODO: Deprecated
189// remove once it has been decided --host can be removed
0e0d9688 190#[cargo_test]
ce9e47ac 191fn simple_with_host() {
b5144c7f 192 registry::init();
ce9e47ac 193
7fe2fbc8 194 let p = project()
1e682848
AC
195 .file(
196 "Cargo.toml",
197 r#"
6f8c7d5a
EH
198 [project]
199 name = "foo"
200 version = "0.0.1"
201 authors = []
202 license = "MIT"
203 description = "foo"
204 "#,
fecb7246
AC
205 )
206 .file("src/main.rs", "fn main() {}")
d43ee1dd 207 .build();
eccdcae0 208
b4c37403 209 p.cargo("publish --no-verify --token sekrit --host")
b5144c7f 210 .arg(registry_url().to_string())
85984a87 211 .with_stderr(&format!(
1e682848 212 "\
ce9e47ac
NB
213[WARNING] The flag '--host' is no longer valid.
214
215Previous versions of Cargo accepted this flag, but it is being
216deprecated. The flag is being renamed to 'index', as the flag
444101a6 217wants the location of the index. Please use '--index' instead.
fba459d2
NB
218
219This will soon become a hard error, so it's either recommended
220to update to a fixed version or contact the upstream maintainer
221about this warning.
41aa6fba 222[UPDATING] `{reg}` index
fba459d2
NB
223[WARNING] manifest has no documentation, [..]
224See [..]
89f43938
ZL
225[PACKAGING] foo v0.0.1 ([CWD])
226[UPLOADING] foo v0.0.1 ([CWD])
fba459d2 227",
b5144c7f 228 reg = registry_path().to_str().unwrap()
fecb7246
AC
229 ))
230 .run();
fba459d2 231
3d84d0ad 232 validate_upload_foo();
fba459d2
NB
233}
234
78e64de9
NB
235// TODO: Deprecated
236// remove once it has been decided --host can be removed
0e0d9688 237#[cargo_test]
fba459d2 238fn simple_with_index_and_host() {
b5144c7f 239 registry::init();
fba459d2 240
7fe2fbc8 241 let p = project()
1e682848
AC
242 .file(
243 "Cargo.toml",
244 r#"
6f8c7d5a
EH
245 [project]
246 name = "foo"
247 version = "0.0.1"
248 authors = []
249 license = "MIT"
250 description = "foo"
251 "#,
fecb7246
AC
252 )
253 .file("src/main.rs", "fn main() {}")
d43ee1dd 254 .build();
fba459d2 255
b4c37403 256 p.cargo("publish --no-verify --token sekrit --index")
b5144c7f 257 .arg(registry_url().to_string())
85984a87 258 .arg("--host")
b5144c7f 259 .arg(registry_url().to_string())
85984a87 260 .with_stderr(&format!(
1e682848 261 "\
fba459d2
NB
262[WARNING] The flag '--host' is no longer valid.
263
264Previous versions of Cargo accepted this flag, but it is being
265deprecated. The flag is being renamed to 'index', as the flag
444101a6 266wants the location of the index. Please use '--index' instead.
ce9e47ac
NB
267
268This will soon become a hard error, so it's either recommended
269to update to a fixed version or contact the upstream maintainer
270about this warning.
41aa6fba 271[UPDATING] `{reg}` index
1c991f83 272[WARNING] manifest has no documentation, [..]
32275465 273See [..]
89f43938
ZL
274[PACKAGING] foo v0.0.1 ([CWD])
275[UPLOADING] foo v0.0.1 ([CWD])
eccdcae0 276",
b5144c7f 277 reg = registry_path().to_str().unwrap()
fecb7246
AC
278 ))
279 .run();
eccdcae0 280
3d84d0ad 281 validate_upload_foo();
6950bbb0
AC
282}
283
0e0d9688 284#[cargo_test]
6950bbb0 285fn git_deps() {
b5144c7f 286 registry::init();
eccdcae0 287
7fe2fbc8 288 let p = project()
1e682848
AC
289 .file(
290 "Cargo.toml",
291 r#"
6f8c7d5a
EH
292 [project]
293 name = "foo"
294 version = "0.0.1"
295 authors = []
296 license = "MIT"
297 description = "foo"
eccdcae0 298
6f8c7d5a
EH
299 [dependencies.foo]
300 git = "git://path/to/nowhere"
301 "#,
fecb7246
AC
302 )
303 .file("src/main.rs", "fn main() {}")
d43ee1dd 304 .build();
eccdcae0 305
b4c37403 306 p.cargo("publish -v --no-verify --token sekrit")
85984a87
DW
307 .with_status(101)
308 .with_stderr(
1e682848 309 "\
41aa6fba 310[UPDATING] [..] index
d682439b
EH
311[ERROR] all dependencies must have a version specified when publishing.
312dependency `foo` does not specify a version
313Note: The published dependency will use the version from crates.io,
314the `git` specification will be removed from the dependency declaration.
1e682848 315",
fecb7246
AC
316 )
317 .run();
6950bbb0
AC
318}
319
0e0d9688 320#[cargo_test]
6950bbb0 321fn path_dependency_no_version() {
b5144c7f 322 registry::init();
9fba127e 323
7fe2fbc8 324 let p = project()
1e682848
AC
325 .file(
326 "Cargo.toml",
327 r#"
6f8c7d5a
EH
328 [project]
329 name = "foo"
330 version = "0.0.1"
331 authors = []
332 license = "MIT"
333 description = "foo"
9fba127e 334
6f8c7d5a
EH
335 [dependencies.bar]
336 path = "bar"
337 "#,
fecb7246
AC
338 )
339 .file("src/main.rs", "fn main() {}")
ab19c483 340 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
d43ee1dd
NK
341 .file("bar/src/lib.rs", "")
342 .build();
eccdcae0 343
b4c37403 344 p.cargo("publish --token sekrit")
85984a87
DW
345 .with_status(101)
346 .with_stderr(
1e682848 347 "\
41aa6fba 348[UPDATING] [..] index
d682439b 349[ERROR] all dependencies must have a version specified when publishing.
9fba127e 350dependency `bar` does not specify a version
d682439b
EH
351Note: The published dependency will use the version from crates.io,
352the `path` specification will be removed from the dependency declaration.
1e682848 353",
fecb7246
AC
354 )
355 .run();
6950bbb0
AC
356}
357
0e0d9688 358#[cargo_test]
6950bbb0 359fn unpublishable_crate() {
b5144c7f 360 registry::init();
d28f8bb0 361
7fe2fbc8 362 let p = project()
1e682848
AC
363 .file(
364 "Cargo.toml",
365 r#"
6f8c7d5a
EH
366 [project]
367 name = "foo"
368 version = "0.0.1"
369 authors = []
370 license = "MIT"
371 description = "foo"
372 publish = false
373 "#,
fecb7246
AC
374 )
375 .file("src/main.rs", "fn main() {}")
d43ee1dd 376 .build();
d28f8bb0 377
85984a87 378 p.cargo("publish --index")
b5144c7f 379 .arg(registry_url().to_string())
85984a87
DW
380 .with_status(101)
381 .with_stderr(
1e682848 382 "\
bf23a7e4
EH
383[ERROR] `foo` cannot be published.
384The registry `crates-io` is not listed in the `publish` value in Cargo.toml.
1e682848 385",
fecb7246
AC
386 )
387 .run();
6950bbb0 388}
088d14ad 389
0e0d9688 390#[cargo_test]
088d14ad 391fn dont_publish_dirty() {
b5144c7f 392 registry::init();
7fe2fbc8 393 let p = project().file("bar", "").build();
088d14ad 394
d682439b 395 let _ = git::repo(&paths::root().join("foo"))
1e682848
AC
396 .file(
397 "Cargo.toml",
398 r#"
6f8c7d5a
EH
399 [project]
400 name = "foo"
401 version = "0.0.1"
402 authors = []
403 license = "MIT"
404 description = "foo"
405 documentation = "foo"
406 homepage = "foo"
407 repository = "foo"
408 "#,
fecb7246
AC
409 )
410 .file("src/main.rs", "fn main() {}")
088d14ad
AC
411 .build();
412
b4c37403 413 p.cargo("publish --token sekrit")
85984a87
DW
414 .with_status(101)
415 .with_stderr(
1e682848 416 "\
41aa6fba 417[UPDATING] `[..]` index
ca1acc57
JL
418error: 1 files in the working directory contain changes that were not yet \
419committed into git:
088d14ad
AC
420
421bar
422
34f2d471 423to proceed despite this and include the uncommitted changes, pass the `--allow-dirty` flag
1e682848 424",
fecb7246
AC
425 )
426 .run();
088d14ad
AC
427}
428
0e0d9688 429#[cargo_test]
088d14ad 430fn publish_clean() {
b5144c7f 431 registry::init();
088d14ad 432
7fe2fbc8 433 let p = project().build();
5e8eef97 434
d43ee1dd 435 let _ = repo(&paths::root().join("foo"))
1e682848
AC
436 .file(
437 "Cargo.toml",
438 r#"
6f8c7d5a
EH
439 [project]
440 name = "foo"
441 version = "0.0.1"
442 authors = []
443 license = "MIT"
444 description = "foo"
445 documentation = "foo"
446 homepage = "foo"
447 repository = "foo"
448 "#,
fecb7246
AC
449 )
450 .file("src/main.rs", "fn main() {}")
088d14ad
AC
451 .build();
452
b4c37403 453 p.cargo("publish --token sekrit").run();
3d84d0ad
EH
454
455 validate_upload_foo_clean();
088d14ad
AC
456}
457
0e0d9688 458#[cargo_test]
088d14ad 459fn publish_in_sub_repo() {
b5144c7f 460 registry::init();
088d14ad 461
252f6e8e 462 let p = project().no_manifest().file("baz", "").build();
5e8eef97 463
d43ee1dd 464 let _ = repo(&paths::root().join("foo"))
1e682848
AC
465 .file(
466 "bar/Cargo.toml",
467 r#"
6f8c7d5a
EH
468 [project]
469 name = "foo"
470 version = "0.0.1"
471 authors = []
472 license = "MIT"
473 description = "foo"
474 documentation = "foo"
475 homepage = "foo"
476 repository = "foo"
477 "#,
fecb7246
AC
478 )
479 .file("bar/src/main.rs", "fn main() {}")
088d14ad
AC
480 .build();
481
b4c37403 482 p.cargo("publish --token sekrit").cwd("bar").run();
3d84d0ad
EH
483
484 validate_upload_foo_clean();
088d14ad
AC
485}
486
0e0d9688 487#[cargo_test]
088d14ad 488fn publish_when_ignored() {
b5144c7f 489 registry::init();
088d14ad 490
7fe2fbc8 491 let p = project().file("baz", "").build();
5e8eef97 492
d43ee1dd 493 let _ = repo(&paths::root().join("foo"))
1e682848
AC
494 .file(
495 "Cargo.toml",
496 r#"
6f8c7d5a
EH
497 [project]
498 name = "foo"
499 version = "0.0.1"
500 authors = []
501 license = "MIT"
502 description = "foo"
503 documentation = "foo"
504 homepage = "foo"
505 repository = "foo"
506 "#,
fecb7246
AC
507 )
508 .file("src/main.rs", "fn main() {}")
088d14ad
AC
509 .file(".gitignore", "baz")
510 .build();
511
b4c37403 512 p.cargo("publish --token sekrit").run();
3d84d0ad
EH
513
514 publish::validate_upload(
515 CLEAN_FOO_JSON,
516 "foo-0.0.1.crate",
517 &[
34307c61 518 "Cargo.lock",
3d84d0ad
EH
519 "Cargo.toml",
520 "Cargo.toml.orig",
521 "src/main.rs",
522 ".gitignore",
523 ".cargo_vcs_info.json",
524 ],
525 );
088d14ad
AC
526}
527
0e0d9688 528#[cargo_test]
088d14ad 529fn ignore_when_crate_ignored() {
b5144c7f 530 registry::init();
088d14ad 531
252f6e8e 532 let p = project().no_manifest().file("bar/baz", "").build();
5e8eef97 533
d43ee1dd 534 let _ = repo(&paths::root().join("foo"))
088d14ad 535 .file(".gitignore", "bar")
1e682848
AC
536 .nocommit_file(
537 "bar/Cargo.toml",
538 r#"
6f8c7d5a
EH
539 [project]
540 name = "foo"
541 version = "0.0.1"
542 authors = []
543 license = "MIT"
544 description = "foo"
545 documentation = "foo"
546 homepage = "foo"
547 repository = "foo"
548 "#,
fecb7246
AC
549 )
550 .nocommit_file("bar/src/main.rs", "fn main() {}");
b4c37403 551 p.cargo("publish --token sekrit").cwd("bar").run();
3d84d0ad
EH
552
553 publish::validate_upload(
554 CLEAN_FOO_JSON,
555 "foo-0.0.1.crate",
34307c61
EH
556 &[
557 "Cargo.lock",
558 "Cargo.toml",
559 "Cargo.toml.orig",
560 "src/main.rs",
561 "baz",
562 ],
3d84d0ad 563 );
088d14ad
AC
564}
565
0e0d9688 566#[cargo_test]
088d14ad 567fn new_crate_rejected() {
b5144c7f 568 registry::init();
088d14ad 569
7fe2fbc8 570 let p = project().file("baz", "").build();
5e8eef97 571
d43ee1dd 572 let _ = repo(&paths::root().join("foo"))
1e682848
AC
573 .nocommit_file(
574 "Cargo.toml",
575 r#"
6f8c7d5a
EH
576 [project]
577 name = "foo"
578 version = "0.0.1"
579 authors = []
580 license = "MIT"
581 description = "foo"
582 documentation = "foo"
583 homepage = "foo"
584 repository = "foo"
585 "#,
fecb7246
AC
586 )
587 .nocommit_file("src/main.rs", "fn main() {}");
b4c37403 588 p.cargo("publish --token sekrit")
85984a87 589 .with_status(101)
f58d107e
EH
590 .with_stderr_contains(
591 "[ERROR] 3 files in the working directory contain \
592 changes that were not yet committed into git:",
593 )
85984a87 594 .run();
088d14ad 595}
c05a5b4a 596
0e0d9688 597#[cargo_test]
c05a5b4a 598fn dry_run() {
b5144c7f 599 registry::init();
c05a5b4a 600
7fe2fbc8 601 let p = project()
1e682848
AC
602 .file(
603 "Cargo.toml",
604 r#"
6f8c7d5a
EH
605 [project]
606 name = "foo"
607 version = "0.0.1"
608 authors = []
609 license = "MIT"
610 description = "foo"
611 "#,
fecb7246
AC
612 )
613 .file("src/main.rs", "fn main() {}")
d43ee1dd 614 .build();
c05a5b4a 615
85984a87 616 p.cargo("publish --dry-run --index")
b5144c7f 617 .arg(registry_url().to_string())
2cd9cce6 618 .with_stderr(
1e682848 619 "\
41aa6fba 620[UPDATING] `[..]` index
c05a5b4a 621[WARNING] manifest has no documentation, [..]
32275465 622See [..]
89f43938
ZL
623[PACKAGING] foo v0.0.1 ([CWD])
624[VERIFYING] foo v0.0.1 ([CWD])
c05a5b4a 625[COMPILING] foo v0.0.1 [..]
34628b65 626[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
89f43938 627[UPLOADING] foo v0.0.1 ([CWD])
c05a5b4a
WM
628[WARNING] aborting upload due to dry run
629",
fecb7246
AC
630 )
631 .run();
c05a5b4a
WM
632
633 // Ensure the API request wasn't actually made
b5144c7f
EH
634 assert!(registry::api_path().join("api/v1/crates").exists());
635 assert!(!registry::api_path().join("api/v1/crates/new").exists());
c05a5b4a 636}
345c03d4 637
0e0d9688 638#[cargo_test]
caf7681f 639fn registry_not_in_publish_list() {
b5144c7f 640 registry::init();
345c03d4 641
7fe2fbc8 642 let p = project()
1e682848
AC
643 .file(
644 "Cargo.toml",
645 r#"
6f8c7d5a
EH
646 [project]
647 name = "foo"
648 version = "0.0.1"
649 authors = []
650 license = "MIT"
651 description = "foo"
652 publish = [
653 "test"
654 ]
655 "#,
fecb7246
AC
656 )
657 .file("src/main.rs", "fn main() {}")
caf7681f 658 .build();
345c03d4 659
85984a87 660 p.cargo("publish")
85984a87
DW
661 .arg("--registry")
662 .arg("alternative")
85984a87
DW
663 .with_status(101)
664 .with_stderr(
1e682848 665 "\
bf23a7e4
EH
666[ERROR] `foo` cannot be published.
667The registry `alternative` is not listed in the `publish` value in Cargo.toml.
1e682848 668",
fecb7246
AC
669 )
670 .run();
345c03d4
CS
671}
672
0e0d9688 673#[cargo_test]
345c03d4 674fn publish_empty_list() {
b5144c7f 675 registry::init();
345c03d4 676
7fe2fbc8 677 let p = project()
1e682848
AC
678 .file(
679 "Cargo.toml",
680 r#"
6f8c7d5a
EH
681 [project]
682 name = "foo"
683 version = "0.0.1"
684 authors = []
685 license = "MIT"
686 description = "foo"
687 publish = []
688 "#,
fecb7246
AC
689 )
690 .file("src/main.rs", "fn main() {}")
caf7681f 691 .build();
345c03d4 692
737382d7 693 p.cargo("publish --registry alternative")
85984a87
DW
694 .with_status(101)
695 .with_stderr(
1e682848 696 "\
bf23a7e4
EH
697[ERROR] `foo` cannot be published.
698The registry `alternative` is not listed in the `publish` value in Cargo.toml.
1e682848 699",
fecb7246
AC
700 )
701 .run();
345c03d4
CS
702}
703
0e0d9688 704#[cargo_test]
caf7681f 705fn publish_allowed_registry() {
340656e2 706 registry::alt_init();
345c03d4 707
7fe2fbc8 708 let p = project().build();
345c03d4 709
caf7681f 710 let _ = repo(&paths::root().join("foo"))
1e682848
AC
711 .file(
712 "Cargo.toml",
713 r#"
6f8c7d5a
EH
714 [project]
715 name = "foo"
716 version = "0.0.1"
717 authors = []
718 license = "MIT"
719 description = "foo"
720 documentation = "foo"
721 homepage = "foo"
722 repository = "foo"
723 publish = ["alternative"]
724 "#,
fecb7246
AC
725 )
726 .file("src/main.rs", "fn main() {}")
345c03d4
CS
727 .build();
728
737382d7 729 p.cargo("publish --registry alternative").run();
3d84d0ad 730
b5144c7f
EH
731 publish::validate_alt_upload(
732 CLEAN_FOO_JSON,
733 "foo-0.0.1.crate",
734 &[
34307c61 735 "Cargo.lock",
b5144c7f
EH
736 "Cargo.toml",
737 "Cargo.toml.orig",
738 "src/main.rs",
739 ".cargo_vcs_info.json",
740 ],
741 );
345c03d4 742}
caf7681f 743
32449a70
NCA
744#[cargo_test]
745fn publish_implicitly_to_only_allowed_registry() {
340656e2 746 registry::alt_init();
32449a70
NCA
747
748 let p = project().build();
749
750 let _ = repo(&paths::root().join("foo"))
751 .file(
752 "Cargo.toml",
753 r#"
6f8c7d5a
EH
754 [project]
755 name = "foo"
756 version = "0.0.1"
757 authors = []
758 license = "MIT"
759 description = "foo"
760 documentation = "foo"
761 homepage = "foo"
762 repository = "foo"
763 publish = ["alternative"]
764 "#,
32449a70
NCA
765 )
766 .file("src/main.rs", "fn main() {}")
767 .build();
768
769 p.cargo("publish").run();
770
771 publish::validate_alt_upload(
772 CLEAN_FOO_JSON,
773 "foo-0.0.1.crate",
774 &[
775 "Cargo.lock",
776 "Cargo.toml",
777 "Cargo.toml.orig",
778 "src/main.rs",
779 ".cargo_vcs_info.json",
780 ],
781 );
782}
783
784#[cargo_test]
785fn publish_fail_with_no_registry_specified() {
786 registry::init();
787
788 let p = project().build();
789
790 let _ = repo(&paths::root().join("foo"))
791 .file(
792 "Cargo.toml",
793 r#"
6f8c7d5a
EH
794 [project]
795 name = "foo"
796 version = "0.0.1"
797 authors = []
798 license = "MIT"
799 description = "foo"
800 documentation = "foo"
801 homepage = "foo"
802 repository = "foo"
803 publish = ["alternative", "test"]
804 "#,
32449a70
NCA
805 )
806 .file("src/main.rs", "fn main() {}")
807 .build();
808
809 p.cargo("publish")
810 .with_status(101)
811 .with_stderr(
812 "\
813[ERROR] `foo` cannot be published.
814The registry `crates-io` is not listed in the `publish` value in Cargo.toml.
815",
816 )
817 .run();
818}
819
0e0d9688 820#[cargo_test]
caf7681f 821fn block_publish_no_registry() {
b5144c7f 822 registry::init();
caf7681f 823
7fe2fbc8 824 let p = project()
1e682848
AC
825 .file(
826 "Cargo.toml",
827 r#"
6f8c7d5a
EH
828 [project]
829 name = "foo"
830 version = "0.0.1"
831 authors = []
832 license = "MIT"
833 description = "foo"
834 publish = []
835 "#,
fecb7246
AC
836 )
837 .file("src/main.rs", "fn main() {}")
caf7681f
CS
838 .build();
839
737382d7 840 p.cargo("publish --registry alternative")
85984a87
DW
841 .with_status(101)
842 .with_stderr(
1e682848 843 "\
bf23a7e4
EH
844[ERROR] `foo` cannot be published.
845The registry `alternative` is not listed in the `publish` value in Cargo.toml.
1e682848 846",
fecb7246
AC
847 )
848 .run();
caf7681f 849}
142bafb7 850
0e0d9688 851#[cargo_test]
bf23a7e4
EH
852fn publish_with_crates_io_explicit() {
853 // Explicitly setting `crates-io` in the publish list.
854 registry::init();
855
856 let p = project()
857 .file(
858 "Cargo.toml",
859 r#"
6f8c7d5a
EH
860 [project]
861 name = "foo"
862 version = "0.0.1"
863 authors = []
864 license = "MIT"
865 description = "foo"
866 publish = ["crates-io"]
867 "#,
bf23a7e4
EH
868 )
869 .file("src/main.rs", "fn main() {}")
870 .build();
871
872 p.cargo("publish --registry alternative")
873 .with_status(101)
874 .with_stderr(
875 "\
876[ERROR] `foo` cannot be published.
877The registry `alternative` is not listed in the `publish` value in Cargo.toml.
878",
879 )
880 .run();
881
882 p.cargo("publish").run();
883}
884
0e0d9688 885#[cargo_test]
142bafb7 886fn publish_with_select_features() {
b5144c7f 887 registry::init();
142bafb7
KF
888
889 let p = project()
890 .file(
891 "Cargo.toml",
892 r#"
6f8c7d5a
EH
893 [project]
894 name = "foo"
895 version = "0.0.1"
896 authors = []
897 license = "MIT"
898 description = "foo"
142bafb7 899
6f8c7d5a
EH
900 [features]
901 required = []
902 optional = []
903 "#,
40cca805
KF
904 )
905 .file(
142bafb7 906 "src/main.rs",
8c3bf82f 907 "#[cfg(not(feature = \"required\"))]
142bafb7
KF
908 compile_error!(\"This crate requires `required` feature!\");
909 fn main() {}",
8c3bf82f
KF
910 )
911 .build();
142bafb7 912
b4c37403 913 p.cargo("publish --features required --token sekrit")
8c3bf82f
KF
914 .with_stderr_contains("[UPLOADING] foo v0.0.1 ([CWD])")
915 .run();
142bafb7
KF
916}
917
0e0d9688 918#[cargo_test]
142bafb7 919fn publish_with_all_features() {
b5144c7f 920 registry::init();
142bafb7
KF
921
922 let p = project()
923 .file(
924 "Cargo.toml",
925 r#"
6f8c7d5a
EH
926 [project]
927 name = "foo"
928 version = "0.0.1"
929 authors = []
930 license = "MIT"
931 description = "foo"
142bafb7 932
6f8c7d5a
EH
933 [features]
934 required = []
935 optional = []
936 "#,
40cca805
KF
937 )
938 .file(
142bafb7 939 "src/main.rs",
8c3bf82f 940 "#[cfg(not(feature = \"required\"))]
142bafb7
KF
941 compile_error!(\"This crate requires `required` feature!\");
942 fn main() {}",
8c3bf82f
KF
943 )
944 .build();
142bafb7 945
b4c37403 946 p.cargo("publish --all-features --token sekrit")
8c3bf82f
KF
947 .with_stderr_contains("[UPLOADING] foo v0.0.1 ([CWD])")
948 .run();
caf7681f 949}
b29e3796 950
0e0d9688 951#[cargo_test]
b29e3796 952fn publish_with_no_default_features() {
b5144c7f 953 registry::init();
b29e3796
KF
954
955 let p = project()
956 .file(
957 "Cargo.toml",
958 r#"
6f8c7d5a
EH
959 [project]
960 name = "foo"
961 version = "0.0.1"
962 authors = []
963 license = "MIT"
964 description = "foo"
b29e3796 965
6f8c7d5a
EH
966 [features]
967 default = ["required"]
968 required = []
969 "#,
b29e3796
KF
970 )
971 .file(
972 "src/main.rs",
973 "#[cfg(not(feature = \"required\"))]
974 compile_error!(\"This crate requires `required` feature!\");
975 fn main() {}",
976 )
977 .build();
978
b4c37403 979 p.cargo("publish --no-default-features --token sekrit")
b29e3796
KF
980 .with_stderr_contains("error: This crate requires `required` feature!")
981 .with_status(101)
982 .run();
983}
b5144c7f 984
0e0d9688 985#[cargo_test]
b5144c7f
EH
986fn publish_with_patch() {
987 Package::new("bar", "1.0.0").publish();
988
989 let p = project()
990 .file(
991 "Cargo.toml",
992 r#"
6f8c7d5a
EH
993 [project]
994 name = "foo"
995 version = "0.0.1"
996 authors = []
997 license = "MIT"
998 description = "foo"
999 [dependencies]
1000 bar = "1.0"
1001 [patch.crates-io]
1002 bar = { path = "bar" }
1003 "#,
b5144c7f 1004 )
d3f7bb0a
JB
1005 .file(
1006 "src/main.rs",
1007 "extern crate bar;
1008 fn main() {
1009 bar::newfunc();
1010 }",
1011 )
b5144c7f 1012 .file("bar/Cargo.toml", &basic_manifest("bar", "1.0.0"))
d3f7bb0a 1013 .file("bar/src/lib.rs", "pub fn newfunc() {}")
b5144c7f
EH
1014 .build();
1015
1016 // Check that it works with the patched crate.
1017 p.cargo("build").run();
1018
d3f7bb0a 1019 // Check that verify fails with patched crate which has new functionality.
b4c37403 1020 p.cargo("publish --token sekrit")
d3f7bb0a 1021 .with_stderr_contains("[..]newfunc[..]")
b5144c7f 1022 .with_status(101)
b5144c7f 1023 .run();
d3f7bb0a
JB
1024
1025 // Remove the usage of new functionality and try again.
1026 p.change_file("src/main.rs", "extern crate bar; pub fn main() {}");
1027
b4c37403 1028 p.cargo("publish --token sekrit").run();
d3f7bb0a
JB
1029
1030 // Note, use of `registry` in the deps here is an artifact that this
1031 // publishes to a fake, local registry that is pretending to be crates.io.
1032 // Normal publishes would set it to null.
1033 publish::validate_upload(
1034 r#"
1035 {
1036 "authors": [],
1037 "badges": {},
1038 "categories": [],
1039 "deps": [
1040 {
1041 "default_features": true,
1042 "features": [],
1043 "kind": "normal",
1044 "name": "bar",
1045 "optional": false,
1046 "registry": "https://github.com/rust-lang/crates.io-index",
1047 "target": null,
1048 "version_req": "^1.0"
1049 }
1050 ],
1051 "description": "foo",
1052 "documentation": null,
1053 "features": {},
1054 "homepage": null,
1055 "keywords": [],
1056 "license": "MIT",
1057 "license_file": null,
1058 "links": null,
1059 "name": "foo",
1060 "readme": null,
1061 "readme_file": null,
1062 "repository": null,
1063 "vers": "0.0.1"
1064 }
1065 "#,
1066 "foo-0.0.1.crate",
34307c61 1067 &["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"],
d3f7bb0a 1068 );
b5144c7f 1069}
f7c424f3 1070
0e0d9688 1071#[cargo_test]
f7c424f3
AH
1072fn publish_checks_for_token_before_verify() {
1073 registry::init();
1074
1075 let p = project()
1076 .file(
1077 "Cargo.toml",
1078 r#"
6f8c7d5a
EH
1079 [project]
1080 name = "foo"
1081 version = "0.0.1"
1082 authors = []
1083 license = "MIT"
1084 description = "foo"
1085 "#,
f7c424f3
AH
1086 )
1087 .file("src/main.rs", "fn main() {}")
1088 .build();
1089
1090 let credentials = paths::home().join(".cargo/credentials");
1091 fs::remove_file(&credentials).unwrap();
1092
1093 // Assert upload token error before the package is verified
1094 p.cargo("publish")
1095 .with_status(101)
b4c37403
EH
1096 .with_stderr_contains(
1097 "[ERROR] no upload token found, \
1098 please run `cargo login` or pass `--token`",
1099 )
f7c424f3
AH
1100 .with_stderr_does_not_contain("[VERIFYING] foo v0.0.1 ([CWD])")
1101 .run();
1102
1103 // Assert package verified successfully on dry run
1104 p.cargo("publish --dry-run")
1105 .with_status(0)
1106 .with_stderr_contains("[VERIFYING] foo v0.0.1 ([CWD])")
1107 .run();
1108}
cce87428
EH
1109
1110#[cargo_test]
1111fn publish_with_bad_source() {
1112 let p = project()
1113 .file(
1114 ".cargo/config",
1115 r#"
1116 [source.crates-io]
1117 replace-with = 'local-registry'
1118
1119 [source.local-registry]
1120 local-registry = 'registry'
1121 "#,
1122 )
1123 .file("src/lib.rs", "")
1124 .build();
1125
b4c37403 1126 p.cargo("publish --token sekrit")
cce87428
EH
1127 .with_status(101)
1128 .with_stderr(
1129 "\
1130[ERROR] registry `[..]/foo/registry` does not support API commands.
1131Check for a source-replacement in .cargo/config.
1132",
1133 )
1134 .run();
1135
1136 p.change_file(
1137 ".cargo/config",
1138 r#"
1139 [source.crates-io]
1140 replace-with = "vendored-sources"
1141
1142 [source.vendored-sources]
1143 directory = "vendor"
1144 "#,
1145 );
1146
b4c37403 1147 p.cargo("publish --token sekrit")
cce87428
EH
1148 .with_status(101)
1149 .with_stderr(
1150 "\
1151[ERROR] dir [..]/foo/vendor does not support API commands.
1152Check for a source-replacement in .cargo/config.
1153",
1154 )
1155 .run();
1156}
d682439b
EH
1157
1158#[cargo_test]
1159fn publish_git_with_version() {
1160 // A dependency with both `git` and `version`.
1161 Package::new("dep1", "1.0.1")
1162 .file("src/lib.rs", "pub fn f() -> i32 {1}")
1163 .publish();
1164
1165 let git_project = git::new("dep1", |project| {
1166 project
1167 .file("Cargo.toml", &basic_manifest("dep1", "1.0.0"))
1168 .file("src/lib.rs", "pub fn f() -> i32 {2}")
1169 });
1170
1171 let p = project()
1172 .file(
1173 "Cargo.toml",
1174 &format!(
1175 r#"
1176 [package]
1177 name = "foo"
1178 version = "0.1.0"
1179 authors = []
1180 edition = "2018"
1181 license = "MIT"
1182 description = "foo"
1183
1184 [dependencies]
1185 dep1 = {{version = "1.0", git="{}"}}
1186 "#,
1187 git_project.url()
1188 ),
1189 )
1190 .file(
1191 "src/main.rs",
1192 r#"
1193 pub fn main() {
1194 println!("{}", dep1::f());
1195 }
1196 "#,
1197 )
1198 .build();
1199
1200 p.cargo("run").with_stdout("2").run();
b4c37403 1201 p.cargo("publish --no-verify --token sekrit").run();
d682439b
EH
1202
1203 publish::validate_upload_with_contents(
1204 r#"
1205 {
1206 "authors": [],
1207 "badges": {},
1208 "categories": [],
1209 "deps": [
1210 {
1211 "default_features": true,
1212 "features": [],
1213 "kind": "normal",
1214 "name": "dep1",
1215 "optional": false,
1216 "registry": "https://github.com/rust-lang/crates.io-index",
1217 "target": null,
1218 "version_req": "^1.0"
1219 }
1220 ],
1221 "description": "foo",
1222 "documentation": null,
1223 "features": {},
1224 "homepage": null,
1225 "keywords": [],
1226 "license": "MIT",
1227 "license_file": null,
1228 "links": null,
1229 "name": "foo",
1230 "readme": null,
1231 "readme_file": null,
1232 "repository": null,
1233 "vers": "0.1.0"
1234 }
1235 "#,
1236 "foo-0.1.0.crate",
1237 &["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"],
1238 &[
1239 (
1240 "Cargo.toml",
1241 // Check that only `version` is included in Cargo.toml.
b73e3d4f
EH
1242 &format!(
1243 "{}\n\
1244 [package]\n\
1245 edition = \"2018\"\n\
1246 name = \"foo\"\n\
1247 version = \"0.1.0\"\n\
1248 authors = []\n\
1249 description = \"foo\"\n\
1250 license = \"MIT\"\n\
1251 [dependencies.dep1]\n\
1252 version = \"1.0\"\n\
1253 ",
1254 cargo::core::package::MANIFEST_PREAMBLE
1255 ),
d682439b
EH
1256 ),
1257 (
1258 "Cargo.lock",
1259 // The important check here is that it is 1.0.1 in the registry.
b73e3d4f
EH
1260 "# This file is automatically @generated by Cargo.\n\
1261 # It is not intended for manual editing.\n\
1262 version = 3\n\
1263 \n\
1264 [[package]]\n\
1265 name = \"dep1\"\n\
1266 version = \"1.0.1\"\n\
1267 source = \"registry+https://github.com/rust-lang/crates.io-index\"\n\
1268 checksum = \"[..]\"\n\
1269 \n\
d682439b
EH
1270 [[package]]\n\
1271 name = \"foo\"\n\
1272 version = \"0.1.0\"\n\
1273 dependencies = [\n\
366ae3f7 1274 \x20\"dep1\",\n\
d682439b 1275 ]\n\
b73e3d4f 1276 ",
d682439b
EH
1277 ),
1278 ],
1279 );
1280}
d709c10d
EH
1281
1282#[cargo_test]
1283fn publish_dev_dep_no_version() {
1284 registry::init();
1285
1286 let p = project()
1287 .file(
1288 "Cargo.toml",
1289 r#"
1290 [package]
1291 name = "foo"
1292 version = "0.1.0"
1293 authors = []
1294 license = "MIT"
1295 description = "foo"
1296 documentation = "foo"
1297 homepage = "foo"
1298 repository = "foo"
1299
1300 [dev-dependencies]
1301 bar = { path = "bar" }
1302 "#,
1303 )
1304 .file("src/lib.rs", "")
1305 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
1306 .file("bar/src/lib.rs", "")
1307 .build();
1308
b4c37403 1309 p.cargo("publish --no-verify --token sekrit")
d709c10d
EH
1310 .with_stderr(
1311 "\
1312[UPDATING] [..]
1313[PACKAGING] foo v0.1.0 [..]
1314[UPLOADING] foo v0.1.0 [..]
1315",
1316 )
1317 .run();
1318
e4345b2e 1319 publish::validate_upload_with_contents(
d709c10d
EH
1320 r#"
1321 {
1322 "authors": [],
1323 "badges": {},
1324 "categories": [],
1325 "deps": [],
1326 "description": "foo",
1327 "documentation": "foo",
1328 "features": {},
1329 "homepage": "foo",
1330 "keywords": [],
1331 "license": "MIT",
1332 "license_file": null,
1333 "links": null,
1334 "name": "foo",
1335 "readme": null,
1336 "readme_file": null,
1337 "repository": "foo",
1338 "vers": "0.1.0"
1339 }
1340 "#,
1341 "foo-0.1.0.crate",
1342 &["Cargo.toml", "Cargo.toml.orig", "src/lib.rs"],
e4345b2e
EH
1343 &[(
1344 "Cargo.toml",
b73e3d4f
EH
1345 &format!(
1346 r#"{}
e4345b2e
EH
1347[package]
1348name = "foo"
1349version = "0.1.0"
1350authors = []
1351description = "foo"
1352homepage = "foo"
1353documentation = "foo"
1354license = "MIT"
1355repository = "foo"
1356
1357[dev-dependencies]
1358"#,
b73e3d4f
EH
1359 cargo::core::package::MANIFEST_PREAMBLE
1360 ),
e4345b2e 1361 )],
d709c10d
EH
1362 );
1363}
4b70f149
TN
1364
1365#[cargo_test]
1366fn credentials_ambiguous_filename() {
1367 registry::init();
1368
1369 let credentials_toml = paths::home().join(".cargo/credentials.toml");
8076f578 1370 fs::write(credentials_toml, r#"token = "api-token""#).unwrap();
4b70f149
TN
1371
1372 let p = project()
1373 .file(
1374 "Cargo.toml",
1375 r#"
6f8c7d5a
EH
1376 [project]
1377 name = "foo"
1378 version = "0.0.1"
1379 authors = []
1380 license = "MIT"
1381 description = "foo"
1382 "#,
4b70f149
TN
1383 )
1384 .file("src/main.rs", "fn main() {}")
1385 .build();
1386
b4c37403 1387 p.cargo("publish --no-verify --token sekrit")
4b70f149
TN
1388 .with_stderr_contains(
1389 "\
1390[WARNING] Both `[..]/credentials` and `[..]/credentials.toml` exist. Using `[..]/credentials`
1391",
1392 )
1393 .run();
1394
1395 validate_upload_foo();
1396}
b4c37403
EH
1397
1398#[cargo_test]
1399fn index_requires_token() {
1400 // --index will not load registry.token to avoid possibly leaking
1401 // crates.io token to another server.
1402 registry::init();
65274ea7
EH
1403 let credentials = paths::home().join(".cargo/credentials");
1404 fs::remove_file(&credentials).unwrap();
b4c37403
EH
1405
1406 let p = project()
1407 .file(
1408 "Cargo.toml",
1409 r#"
1410 [package]
1411 name = "foo"
1412 version = "0.0.1"
1413 authors = []
1414 license = "MIT"
1415 description = "foo"
1416 "#,
1417 )
1418 .file("src/lib.rs", "")
1419 .build();
1420
1421 p.cargo("publish --no-verify --index")
1422 .arg(registry_url().to_string())
1423 .with_status(101)
65274ea7
EH
1424 .with_stderr(
1425 "\
1426[UPDATING] [..]
1427[ERROR] command-line argument --index requires --token to be specified
1428",
1429 )
1430 .run();
1431}
1432
1433#[cargo_test]
1434fn registry_token_with_source_replacement() {
1435 // publish with source replacement without --token
1436 registry::init();
1437
1438 let p = project()
1439 .file(
1440 "Cargo.toml",
1441 r#"
6f8c7d5a
EH
1442 [project]
1443 name = "foo"
1444 version = "0.0.1"
1445 authors = []
1446 license = "MIT"
1447 description = "foo"
1448 "#,
65274ea7
EH
1449 )
1450 .file("src/lib.rs", "")
1451 .build();
1452
1453 p.cargo("publish --no-verify")
1454 .with_stderr(
1455 "\
1456[UPDATING] [..]
1457[WARNING] using `registry.token` config value with source replacement is deprecated
1458This may become a hard error in the future[..]
1459Use the --token command-line flag to remove this warning.
1460[WARNING] manifest has no documentation, [..]
1461See [..]
1462[PACKAGING] foo v0.0.1 ([CWD])
1463[UPLOADING] foo v0.0.1 ([CWD])
1464",
1465 )
b4c37403
EH
1466 .run();
1467}
7a5f0369
EH
1468
1469#[cargo_test]
1470fn publish_with_missing_readme() {
1471 registry::init();
1472 let p = project()
1473 .file(
1474 "Cargo.toml",
1475 r#"
1476 [package]
1477 name = "foo"
1478 version = "0.1.0"
1479 authors = []
1480 license = "MIT"
1481 description = "foo"
1482 homepage = "https://example.com/"
1483 readme = "foo.md"
1484 "#,
1485 )
1486 .file("src/lib.rs", "")
1487 .build();
1488
1489 p.cargo("publish --no-verify --token sekrit")
1490 .with_status(101)
1491 .with_stderr(&format!(
1492 "\
1493[UPDATING] [..]
1494[PACKAGING] foo v0.1.0 [..]
1495[UPLOADING] foo v0.1.0 [..]
1496[ERROR] failed to read `readme` file for package `foo v0.1.0 ([ROOT]/foo)`
1497
1498Caused by:
1499 failed to read `[ROOT]/foo/foo.md`
1500
1501Caused by:
1502 {}
1503",
1504 no_such_file_err_msg()
1505 ))
1506 .run();
1507}
06b8d1ca
EH
1508
1509#[cargo_test]
1510fn api_error_json() {
1511 // Registry returns an API error.
1512 let t = registry::RegistryBuilder::new().build_api_server(&|_headers| {
1513 (403, &r#"{"errors": [{"detail": "you must be logged in"}]}"#)
1514 });
1515
1516 let p = project()
1517 .file(
1518 "Cargo.toml",
1519 r#"
1520 [project]
1521 name = "foo"
1522 version = "0.0.1"
1523 authors = []
1524 license = "MIT"
1525 description = "foo"
1526 documentation = "foo"
1527 homepage = "foo"
1528 repository = "foo"
1529 "#,
1530 )
1531 .file("src/lib.rs", "")
1532 .build();
1533
1534 p.cargo("publish --no-verify --registry alternative")
1535 .with_status(101)
1536 .with_stderr(
1537 "\
1538[UPDATING] [..]
1539[PACKAGING] foo v0.0.1 [..]
1540[UPLOADING] foo v0.0.1 [..]
c9bd6e12
EH
1541[ERROR] failed to publish to registry at http://127.0.0.1:[..]/
1542
1543Caused by:
1544 the remote server responded with an error (status 403 Forbidden): you must be logged in
1545",
1546 )
1547 .run();
1548
1549 t.join().unwrap();
1550}
1551
1552#[cargo_test]
1553fn api_error_200() {
1554 // Registry returns an API error with a 200 status code.
1555 let t = registry::RegistryBuilder::new().build_api_server(&|_headers| {
1556 (
1557 200,
1558 &r#"{"errors": [{"detail": "max upload size is 123"}]}"#,
1559 )
1560 });
1561
1562 let p = project()
1563 .file(
1564 "Cargo.toml",
1565 r#"
1566 [project]
1567 name = "foo"
1568 version = "0.0.1"
1569 authors = []
1570 license = "MIT"
1571 description = "foo"
1572 documentation = "foo"
1573 homepage = "foo"
1574 repository = "foo"
1575 "#,
1576 )
1577 .file("src/lib.rs", "")
1578 .build();
1579
1580 p.cargo("publish --no-verify --registry alternative")
1581 .with_status(101)
1582 .with_stderr(
1583 "\
1584[UPDATING] [..]
1585[PACKAGING] foo v0.0.1 [..]
1586[UPLOADING] foo v0.0.1 [..]
1587[ERROR] failed to publish to registry at http://127.0.0.1:[..]/
1588
1589Caused by:
1590 the remote server responded with an error: max upload size is 123
06b8d1ca
EH
1591",
1592 )
1593 .run();
1594
1595 t.join().unwrap();
1596}
1597
1598#[cargo_test]
1599fn api_error_code() {
1600 // Registry returns an error code without a JSON message.
1601 let t = registry::RegistryBuilder::new().build_api_server(&|_headers| (400, &"go away"));
1602
1603 let p = project()
1604 .file(
1605 "Cargo.toml",
1606 r#"
1607 [project]
1608 name = "foo"
1609 version = "0.0.1"
1610 authors = []
1611 license = "MIT"
1612 description = "foo"
1613 documentation = "foo"
1614 homepage = "foo"
1615 repository = "foo"
1616 "#,
1617 )
1618 .file("src/lib.rs", "")
1619 .build();
1620
1621 p.cargo("publish --no-verify --registry alternative")
1622 .with_status(101)
1623 .with_stderr(
1624 "\
1625[UPDATING] [..]
1626[PACKAGING] foo v0.0.1 [..]
1627[UPLOADING] foo v0.0.1 [..]
c9bd6e12
EH
1628[ERROR] failed to publish to registry at http://127.0.0.1:[..]/
1629
1630Caused by:
1631 failed to get a 200 OK response, got 400
1632 headers:
1633 <tab>HTTP/1.1 400
1634 <tab>Content-Length: 7
1635 <tab>
1636 body:
1637 go away
06b8d1ca
EH
1638",
1639 )
1640 .run();
1641
1642 t.join().unwrap();
1643}
1644
1645#[cargo_test]
1646fn api_curl_error() {
1647 // Registry has a network error.
1648 let t = registry::RegistryBuilder::new().build_api_server(&|_headers| panic!("broke!"));
1649
1650 let p = project()
1651 .file(
1652 "Cargo.toml",
1653 r#"
1654 [project]
1655 name = "foo"
1656 version = "0.0.1"
1657 authors = []
1658 license = "MIT"
1659 description = "foo"
1660 documentation = "foo"
1661 homepage = "foo"
1662 repository = "foo"
1663 "#,
1664 )
1665 .file("src/lib.rs", "")
1666 .build();
1667
1668 // This doesn't check for the exact text of the error in the remote
1669 // possibility that cargo is linked with a weird version of libcurl, or
1670 // curl changes the text of the message. Currently the message 52
1671 // (CURLE_GOT_NOTHING) is:
1672 // Server returned nothing (no headers, no data) (Empty reply from server)
1673 p.cargo("publish --no-verify --registry alternative")
1674 .with_status(101)
1675 .with_stderr(
1676 "\
1677[UPDATING] [..]
1678[PACKAGING] foo v0.0.1 [..]
1679[UPLOADING] foo v0.0.1 [..]
c9bd6e12
EH
1680[ERROR] failed to publish to registry at http://127.0.0.1:[..]/
1681
1682Caused by:
1683 [52] [..]
06b8d1ca
EH
1684",
1685 )
1686 .run();
1687
1688 let e = t.join().unwrap_err();
1689 assert_eq!(*e.downcast::<&str>().unwrap(), "broke!");
1690}
1691
1692#[cargo_test]
1693fn api_other_error() {
1694 // Registry returns an invalid response.
1695 let t = registry::RegistryBuilder::new().build_api_server(&|_headers| (200, b"\xff"));
1696
1697 let p = project()
1698 .file(
1699 "Cargo.toml",
1700 r#"
1701 [project]
1702 name = "foo"
1703 version = "0.0.1"
1704 authors = []
1705 license = "MIT"
1706 description = "foo"
1707 documentation = "foo"
1708 homepage = "foo"
1709 repository = "foo"
1710 "#,
1711 )
1712 .file("src/lib.rs", "")
1713 .build();
1714
1715 p.cargo("publish --no-verify --registry alternative")
1716 .with_status(101)
1717 .with_stderr(
1718 "\
1719[UPDATING] [..]
1720[PACKAGING] foo v0.0.1 [..]
1721[UPLOADING] foo v0.0.1 [..]
c9bd6e12
EH
1722[ERROR] failed to publish to registry at http://127.0.0.1:[..]/
1723
1724Caused by:
1725 invalid response from server
06b8d1ca
EH
1726
1727Caused by:
1728 response body was not valid utf-8
1729",
1730 )
1731 .run();
1732
1733 t.join().unwrap();
1734}
8f1f0e40 1735
1736#[cargo_test]
1737fn in_workspace() {
1738 registry::init();
1739
1740 let p = project()
1741 .file(
1742 "Cargo.toml",
1743 r#"
1744 [workspace]
1745 members = ["foo", "bar"]
1746 "#,
1747 )
1748 .file(
1749 "foo/Cargo.toml",
1750 r#"
1751 [project]
1752 name = "foo"
1753 version = "0.0.1"
1754 authors = []
1755 license = "MIT"
1756 description = "foo"
1757 "#,
1758 )
1759 .file("foo/src/main.rs", "fn main() {}")
1760 .file(
1761 "bar/Cargo.toml",
1762 r#"
1763 [project]
1764 name = "bar"
1765 version = "0.0.1"
1766 authors = []
1767 license = "MIT"
1768 description = "bar"
1769 workspace = ".."
1770 "#,
1771 )
1772 .file("bar/src/main.rs", "fn main() {}")
1773 .build();
1774
1775 p.cargo("publish --no-verify --token sekrit -p foo")
30ff8424 1776 .with_stderr(
8f1f0e40 1777 "\
1778[UPDATING] [..]
1779[WARNING] manifest has no documentation, [..]
1780See [..]
1781[PACKAGING] foo v0.0.1 ([CWD]/foo)
1782[UPLOADING] foo v0.0.1 ([CWD]/foo)
30ff8424
EH
1783",
1784 )
8f1f0e40 1785 .run();
1786
1787 validate_upload_foo();
1788
1789 p.cargo("publish --no-verify --token sekrit -p bar")
30ff8424 1790 .with_stderr(
8f1f0e40 1791 "\
1792[UPDATING] [..]
1793[WARNING] manifest has no documentation, [..]
1794See [..]
1795[PACKAGING] bar v0.0.1 ([CWD]/bar)
1796[UPLOADING] bar v0.0.1 ([CWD]/bar)
30ff8424
EH
1797",
1798 )
8f1f0e40 1799 .run();
1800
1801 validate_upload_bar();
1802}