]>
Commit | Line | Data |
---|---|---|
83571aee EH |
1 | //! Tests for the `cargo publish` command. |
2 | ||
9115b2c3 AC |
3 | use cargo_test_support::git::{self, repo}; |
4 | use cargo_test_support::paths; | |
5 | use cargo_test_support::registry::{self, registry_path, registry_url, Package}; | |
7a5f0369 | 6 | use cargo_test_support::{basic_manifest, no_such_file_err_msg, project, publish}; |
4ae79d2f | 7 | use std::fs; |
3d84d0ad EH |
8 | |
9 | const 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 | ||
31 | fn 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 | 59 | fn 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 |
87 | fn 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 | 102 | fn 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, [..] |
125 | See [..] | |
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 | 136 | fn 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 |
175 | This may become a hard error in the future[..] | |
176 | Use the --token command-line flag to remove this warning. | |
5cb5e7d8 SF |
177 | [WARNING] manifest has no documentation, [..] |
178 | See [..] | |
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 | 191 | fn 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 | ||
215 | Previous versions of Cargo accepted this flag, but it is being | |
216 | deprecated. The flag is being renamed to 'index', as the flag | |
444101a6 | 217 | wants the location of the index. Please use '--index' instead. |
fba459d2 NB |
218 | |
219 | This will soon become a hard error, so it's either recommended | |
220 | to update to a fixed version or contact the upstream maintainer | |
221 | about this warning. | |
41aa6fba | 222 | [UPDATING] `{reg}` index |
fba459d2 NB |
223 | [WARNING] manifest has no documentation, [..] |
224 | See [..] | |
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 | 238 | fn 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 | ||
264 | Previous versions of Cargo accepted this flag, but it is being | |
265 | deprecated. The flag is being renamed to 'index', as the flag | |
444101a6 | 266 | wants the location of the index. Please use '--index' instead. |
ce9e47ac NB |
267 | |
268 | This will soon become a hard error, so it's either recommended | |
269 | to update to a fixed version or contact the upstream maintainer | |
270 | about this warning. | |
41aa6fba | 271 | [UPDATING] `{reg}` index |
1c991f83 | 272 | [WARNING] manifest has no documentation, [..] |
32275465 | 273 | See [..] |
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 | 285 | fn 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. |
312 | dependency `foo` does not specify a version | |
313 | Note: The published dependency will use the version from crates.io, | |
314 | the `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 | 321 | fn 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 | 350 | dependency `bar` does not specify a version |
d682439b EH |
351 | Note: The published dependency will use the version from crates.io, |
352 | the `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 | 359 | fn 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. |
384 | The 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 | 391 | fn 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 |
418 | error: 1 files in the working directory contain changes that were not yet \ |
419 | committed into git: | |
088d14ad AC |
420 | |
421 | bar | |
422 | ||
34f2d471 | 423 | to 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 | 430 | fn 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 | 459 | fn 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 | 488 | fn 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 | 529 | fn 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 | 567 | fn 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 | 598 | fn 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 | 622 | See [..] |
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 | 639 | fn 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. |
667 | The 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 | 674 | fn 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. |
698 | The 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 | 705 | fn 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] |
745 | fn 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] | |
785 | fn 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. | |
814 | The registry `crates-io` is not listed in the `publish` value in Cargo.toml. | |
815 | ", | |
816 | ) | |
817 | .run(); | |
818 | } | |
819 | ||
0e0d9688 | 820 | #[cargo_test] |
caf7681f | 821 | fn 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. |
845 | The 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 |
852 | fn 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. | |
877 | The 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 | 886 | fn 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 | 919 | fn 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 | 952 | fn 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 |
986 | fn 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 |
1072 | fn 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] | |
1111 | fn 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. | |
1131 | Check 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. | |
1152 | Check for a source-replacement in .cargo/config. | |
1153 | ", | |
1154 | ) | |
1155 | .run(); | |
1156 | } | |
d682439b EH |
1157 | |
1158 | #[cargo_test] | |
1159 | fn 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] | |
1283 | fn 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] |
1348 | name = "foo" | |
1349 | version = "0.1.0" | |
1350 | authors = [] | |
1351 | description = "foo" | |
1352 | homepage = "foo" | |
1353 | documentation = "foo" | |
1354 | license = "MIT" | |
1355 | repository = "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] | |
1366 | fn 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] | |
1399 | fn 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] | |
1434 | fn 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 | |
1458 | This may become a hard error in the future[..] | |
1459 | Use the --token command-line flag to remove this warning. | |
1460 | [WARNING] manifest has no documentation, [..] | |
1461 | See [..] | |
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] | |
1470 | fn 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 | ||
1498 | Caused by: | |
1499 | failed to read `[ROOT]/foo/foo.md` | |
1500 | ||
1501 | Caused by: | |
1502 | {} | |
1503 | ", | |
1504 | no_such_file_err_msg() | |
1505 | )) | |
1506 | .run(); | |
1507 | } | |
06b8d1ca EH |
1508 | |
1509 | #[cargo_test] | |
1510 | fn 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 | ||
1543 | Caused 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] | |
1553 | fn 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 | ||
1589 | Caused 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] | |
1599 | fn 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 | ||
1630 | Caused 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] | |
1646 | fn 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 | ||
1682 | Caused 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] | |
1693 | fn 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 | ||
1724 | Caused by: | |
1725 | invalid response from server | |
06b8d1ca EH |
1726 | |
1727 | Caused by: | |
1728 | response body was not valid utf-8 | |
1729 | ", | |
1730 | ) | |
1731 | .run(); | |
1732 | ||
1733 | t.join().unwrap(); | |
1734 | } | |
8f1f0e40 | 1735 | |
1736 | #[cargo_test] | |
1737 | fn 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, [..] | |
1780 | See [..] | |
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, [..] | |
1794 | See [..] | |
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 | } |