]> git.proxmox.com Git - cargo.git/blame - tests/testsuite/package.rs
Test IO error resilience while walking directories
[cargo.git] / tests / testsuite / package.rs
CommitLineData
83571aee
EH
1//! Tests for the `cargo package` command.
2
9115b2c3 3use cargo_test_support::paths::CargoPathExt;
156c6512
EH
4use cargo_test_support::publish::validate_crate_contents;
5use cargo_test_support::registry::{self, Package};
9115b2c3 6use cargo_test_support::{
156c6512 7 basic_manifest, cargo_process, git, path2url, paths, project, symlink_supported, t,
3d84d0ad 8};
e46ca84b 9use flate2::read::GzDecoder;
1232ad3c 10use std::fs::{self, read_to_string, File};
4ae79d2f 11use std::path::Path;
e46ca84b 12use tar::Archive;
69c16fc6 13
0e0d9688 14#[cargo_test]
6950bbb0 15fn simple() {
7fe2fbc8 16 let p = project()
fecb7246
AC
17 .file(
18 "Cargo.toml",
19 r#"
6f8c7d5a
EH
20 [project]
21 name = "foo"
22 version = "0.0.1"
23 authors = []
24 exclude = ["*.txt"]
25 license = "MIT"
26 description = "foo"
27 "#,
fecb7246 28 )
ca7d9ee2 29 .file("src/main.rs", r#"fn main() { println!("hello"); }"#)
d43ee1dd
NK
30 .file("src/bar.txt", "") // should be ignored when packaging
31 .build();
69c16fc6 32
85984a87 33 p.cargo("package")
2cd9cce6 34 .with_stderr(
1e682848 35 "\
eeebadff 36[WARNING] manifest has no documentation[..]
32275465 37See [..]
89f43938
ZL
38[PACKAGING] foo v0.0.1 ([CWD])
39[VERIFYING] foo v0.0.1 ([CWD])
40[COMPILING] foo v0.0.1 ([CWD][..])
34628b65 41[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
69c16fc6 42",
fecb7246
AC
43 )
44 .run();
570fe892 45 assert!(p.root().join("target/package/foo-0.0.1.crate").is_file());
85984a87
DW
46 p.cargo("package -l")
47 .with_stdout(
1e682848 48 "\
34307c61 49Cargo.lock
229e1e43 50Cargo.toml
90887707 51Cargo.toml.orig
05400b80 52src/main.rs
1e682848 53",
fecb7246
AC
54 )
55 .run();
85984a87 56 p.cargo("package").with_stdout("").run();
97f073ef 57
9ed3a6ea 58 let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap();
3d84d0ad
EH
59 validate_crate_contents(
60 f,
61 "foo-0.0.1.crate",
34307c61 62 &["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"],
3d84d0ad
EH
63 &[],
64 );
6950bbb0 65}
5db1316a 66
0e0d9688 67#[cargo_test]
6950bbb0 68fn metadata_warning() {
85984a87
DW
69 let p = project().file("src/main.rs", "fn main() {}").build();
70 p.cargo("package")
2cd9cce6 71 .with_stderr(
1e682848 72 "\
eeebadff 73warning: manifest has no description, license, license-file, documentation, \
32275465 74homepage or repository.
0c3851c0 75See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
89f43938
ZL
76[PACKAGING] foo v0.0.1 ([CWD])
77[VERIFYING] foo v0.0.1 ([CWD])
78[COMPILING] foo v0.0.1 ([CWD][..])
34628b65 79[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
5db1316a 80",
fecb7246
AC
81 )
82 .run();
5db1316a 83
f8c9928c 84 let p = project()
1e682848
AC
85 .file(
86 "Cargo.toml",
87 r#"
6f8c7d5a
EH
88 [project]
89 name = "foo"
90 version = "0.0.1"
91 authors = []
92 license = "MIT"
93 "#,
fecb7246
AC
94 )
95 .file("src/main.rs", "fn main() {}")
d43ee1dd 96 .build();
85984a87 97 p.cargo("package")
2cd9cce6 98 .with_stderr(
1e682848 99 "\
32275465 100warning: manifest has no description, documentation, homepage or repository.
0c3851c0 101See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
89f43938
ZL
102[PACKAGING] foo v0.0.1 ([CWD])
103[VERIFYING] foo v0.0.1 ([CWD])
104[COMPILING] foo v0.0.1 ([CWD][..])
34628b65 105[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
5db1316a 106",
fecb7246
AC
107 )
108 .run();
5db1316a 109
f8c9928c 110 let p = project()
1e682848
AC
111 .file(
112 "Cargo.toml",
113 r#"
6f8c7d5a
EH
114 [project]
115 name = "foo"
116 version = "0.0.1"
117 authors = []
118 license = "MIT"
119 description = "foo"
120 repository = "bar"
121 "#,
fecb7246
AC
122 )
123 .file("src/main.rs", "fn main() {}")
d43ee1dd 124 .build();
85984a87 125 p.cargo("package")
2cd9cce6 126 .with_stderr(
1e682848 127 "\
89f43938
ZL
128[PACKAGING] foo v0.0.1 ([CWD])
129[VERIFYING] foo v0.0.1 ([CWD])
130[COMPILING] foo v0.0.1 ([CWD][..])
34628b65 131[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
5db1316a 132",
fecb7246
AC
133 )
134 .run();
6950bbb0 135}
5db1316a 136
0e0d9688 137#[cargo_test]
6950bbb0 138fn package_verbose() {
c84bc16b 139 let root = paths::root().join("all");
6b9961a3 140 let repo = git::repo(&root)
ab19c483 141 .file("Cargo.toml", &basic_manifest("foo", "0.0.1"))
ca7d9ee2 142 .file("src/main.rs", "fn main() {}")
b8b127a8
NK
143 .file("a/a/Cargo.toml", &basic_manifest("a", "0.0.1"))
144 .file("a/a/src/lib.rs", "")
d43ee1dd 145 .build();
85984a87 146 cargo_process("build").cwd(repo.root()).run();
09847df8
AC
147
148 println!("package main repo");
85984a87
DW
149 cargo_process("package -v --no-verify")
150 .cwd(repo.root())
151 .with_stderr(
1e682848 152 "\
eeebadff 153[WARNING] manifest has no description[..]
0c3851c0 154See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
fee4308b 155[PACKAGING] foo v0.0.1 ([..])
6b9961a3 156[ARCHIVING] .cargo_vcs_info.json
34307c61 157[ARCHIVING] Cargo.lock
90887707
EH
158[ARCHIVING] Cargo.toml
159[ARCHIVING] Cargo.toml.orig
160[ARCHIVING] src/main.rs
1e682848 161",
fecb7246
AC
162 )
163 .run();
09847df8 164
6b9961a3 165 let f = File::open(&repo.root().join("target/package/foo-0.0.1.crate")).unwrap();
3d84d0ad
EH
166 let vcs_contents = format!(
167 r#"{{
6b9961a3
DK
168 "git": {{
169 "sha1": "{}"
b8b127a8
NK
170 }},
171 "path_in_vcs": ""
6b9961a3
DK
172}}
173"#,
3d84d0ad
EH
174 repo.revparse_head()
175 );
176 validate_crate_contents(
177 f,
178 "foo-0.0.1.crate",
179 &[
34307c61 180 "Cargo.lock",
3d84d0ad
EH
181 "Cargo.toml",
182 "Cargo.toml.orig",
183 "src/main.rs",
184 ".cargo_vcs_info.json",
185 ],
186 &[(".cargo_vcs_info.json", &vcs_contents)],
6b9961a3
DK
187 );
188
09847df8 189 println!("package sub-repo");
85984a87 190 cargo_process("package -v --no-verify")
b8b127a8 191 .cwd(repo.root().join("a/a"))
85984a87 192 .with_stderr(
1e682848 193 "\
eeebadff 194[WARNING] manifest has no description[..]
0c3851c0 195See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
fee4308b 196[PACKAGING] a v0.0.1 ([..])
90887707 197[ARCHIVING] .cargo_vcs_info.json
6b9961a3 198[ARCHIVING] Cargo.toml
90887707 199[ARCHIVING] Cargo.toml.orig
6b9961a3 200[ARCHIVING] src/lib.rs
1e682848 201",
fecb7246
AC
202 )
203 .run();
b8b127a8
NK
204
205 let f = File::open(&repo.root().join("a/a/target/package/a-0.0.1.crate")).unwrap();
206 let vcs_contents = format!(
207 r#"{{
208 "git": {{
209 "sha1": "{}"
210 }},
211 "path_in_vcs": "a/a"
212}}
213"#,
214 repo.revparse_head()
215 );
216 validate_crate_contents(
217 f,
218 "a-0.0.1.crate",
219 &[
220 "Cargo.toml",
221 "Cargo.toml.orig",
222 "src/lib.rs",
223 ".cargo_vcs_info.json",
224 ],
225 &[(".cargo_vcs_info.json", &vcs_contents)],
226 );
6950bbb0 227}
6e81812e 228
0e0d9688 229#[cargo_test]
6950bbb0 230fn package_verification() {
85984a87
DW
231 let p = project().file("src/main.rs", "fn main() {}").build();
232 p.cargo("build").run();
233 p.cargo("package")
2cd9cce6 234 .with_stderr(
1e682848 235 "\
eeebadff 236[WARNING] manifest has no description[..]
0c3851c0 237See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
89f43938
ZL
238[PACKAGING] foo v0.0.1 ([CWD])
239[VERIFYING] foo v0.0.1 ([CWD])
240[COMPILING] foo v0.0.1 ([CWD][..])
34628b65 241[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
6e81812e 242",
fecb7246
AC
243 )
244 .run();
6950bbb0 245}
5935ec1d 246
0e0d9688 247#[cargo_test]
ab787720
DK
248fn vcs_file_collision() {
249 let p = project().build();
250 let _ = git::repo(&paths::root().join("foo"))
251 .file(
252 "Cargo.toml",
253 r#"
6f8c7d5a
EH
254 [project]
255 name = "foo"
256 description = "foo"
257 version = "0.0.1"
258 authors = []
259 license = "MIT"
260 documentation = "foo"
261 homepage = "foo"
262 repository = "foo"
263 exclude = ["*.no-existe"]
264 "#,
fecb7246
AC
265 )
266 .file(
ab787720
DK
267 "src/main.rs",
268 r#"
6f8c7d5a
EH
269 fn main() {}
270 "#,
fecb7246
AC
271 )
272 .file(".cargo_vcs_info.json", "foo")
ab787720 273 .build();
85984a87
DW
274 p.cargo("package")
275 .arg("--no-verify")
276 .with_status(101)
2cd9cce6 277 .with_stderr(
ab787720 278 "\
90887707 279[ERROR] invalid inclusion of reserved file name .cargo_vcs_info.json \
ab787720
DK
280in package source
281",
fecb7246
AC
282 )
283 .run();
ab787720
DK
284}
285
0e0d9688 286#[cargo_test]
4f01c02a 287fn path_dependency_no_version() {
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"
4f01c02a 298
6f8c7d5a
EH
299 [dependencies.bar]
300 path = "bar"
301 "#,
fecb7246
AC
302 )
303 .file("src/main.rs", "fn main() {}")
ab19c483 304 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
d43ee1dd
NK
305 .file("bar/src/lib.rs", "")
306 .build();
4f01c02a 307
85984a87
DW
308 p.cargo("package")
309 .with_status(101)
310 .with_stderr(
1e682848 311 "\
32275465 312[WARNING] manifest has no documentation, homepage or repository.
0c3851c0 313See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
4e1910d9
B
314[ERROR] all dependencies must have a version specified when packaging.
315dependency `bar` does not specify a version\n\
316Note: The packaged dependency will use the version from crates.io,
317the `path` specification will be removed from the dependency declaration.
318",
319 )
320 .run();
321}
322
323#[cargo_test]
324fn git_dependency_no_version() {
325 registry::init();
326
327 let p = project()
328 .file(
329 "Cargo.toml",
330 r#"
331 [project]
332 name = "foo"
333 version = "0.0.1"
334 authors = []
335 license = "MIT"
336 description = "foo"
337
338 [dependencies.foo]
339 git = "git://path/to/nowhere"
340 "#,
341 )
342 .file("src/main.rs", "fn main() {}")
343 .build();
344
345 p.cargo("package")
346 .with_status(101)
347 .with_stderr(
348 "\
349[WARNING] manifest has no documentation, homepage or repository.
350See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
351[ERROR] all dependencies must have a version specified when packaging.
352dependency `foo` does not specify a version
353Note: The packaged dependency will use the version from crates.io,
354the `git` specification will be removed from the dependency declaration.
1e682848 355",
fecb7246
AC
356 )
357 .run();
4f01c02a
RG
358}
359
0e0d9688 360#[cargo_test]
6950bbb0 361fn exclude() {
dd998a09
XL
362 let root = paths::root().join("exclude");
363 let repo = git::repo(&root)
fecb7246
AC
364 .file(
365 "Cargo.toml",
366 r#"
6f8c7d5a
EH
367 [project]
368 name = "foo"
369 version = "0.0.1"
370 authors = []
371 exclude = [
372 "*.txt",
373 # file in root
374 "file_root_1", # NO_CHANGE (ignored)
375 "/file_root_2", # CHANGING (packaged -> ignored)
376 "file_root_3/", # NO_CHANGE (packaged)
377 "file_root_4/*", # NO_CHANGE (packaged)
378 "file_root_5/**", # NO_CHANGE (packaged)
379 # file in sub-dir
380 "file_deep_1", # CHANGING (packaged -> ignored)
381 "/file_deep_2", # NO_CHANGE (packaged)
382 "file_deep_3/", # NO_CHANGE (packaged)
383 "file_deep_4/*", # NO_CHANGE (packaged)
384 "file_deep_5/**", # NO_CHANGE (packaged)
385 # dir in root
386 "dir_root_1", # CHANGING (packaged -> ignored)
387 "/dir_root_2", # CHANGING (packaged -> ignored)
388 "dir_root_3/", # CHANGING (packaged -> ignored)
389 "dir_root_4/*", # NO_CHANGE (ignored)
390 "dir_root_5/**", # NO_CHANGE (ignored)
391 # dir in sub-dir
392 "dir_deep_1", # CHANGING (packaged -> ignored)
393 "/dir_deep_2", # NO_CHANGE
394 "dir_deep_3/", # CHANGING (packaged -> ignored)
395 "dir_deep_4/*", # CHANGING (packaged -> ignored)
396 "dir_deep_5/**", # CHANGING (packaged -> ignored)
397 ]
398 "#,
fecb7246 399 )
ca7d9ee2 400 .file("src/main.rs", r#"fn main() { println!("hello"); }"#)
5935ec1d 401 .file("bar.txt", "")
c072ba42 402 .file("src/bar.txt", "")
f7c91ba6 403 // File in root.
c072ba42
BE
404 .file("file_root_1", "")
405 .file("file_root_2", "")
406 .file("file_root_3", "")
407 .file("file_root_4", "")
408 .file("file_root_5", "")
f7c91ba6 409 // File in sub-dir.
c072ba42
BE
410 .file("some_dir/file_deep_1", "")
411 .file("some_dir/file_deep_2", "")
412 .file("some_dir/file_deep_3", "")
413 .file("some_dir/file_deep_4", "")
414 .file("some_dir/file_deep_5", "")
f7c91ba6 415 // Dir in root.
c072ba42
BE
416 .file("dir_root_1/some_dir/file", "")
417 .file("dir_root_2/some_dir/file", "")
418 .file("dir_root_3/some_dir/file", "")
419 .file("dir_root_4/some_dir/file", "")
420 .file("dir_root_5/some_dir/file", "")
f7c91ba6 421 // Dir in sub-dir.
c072ba42
BE
422 .file("some_dir/dir_deep_1/some_dir/file", "")
423 .file("some_dir/dir_deep_2/some_dir/file", "")
424 .file("some_dir/dir_deep_3/some_dir/file", "")
425 .file("some_dir/dir_deep_4/some_dir/file", "")
426 .file("some_dir/dir_deep_5/some_dir/file", "")
d43ee1dd 427 .build();
5935ec1d 428
dd998a09
XL
429 cargo_process("package --no-verify -v")
430 .cwd(repo.root())
85984a87
DW
431 .with_stdout("")
432 .with_stderr(
1e682848 433 "\
eeebadff 434[WARNING] manifest has no description[..]
0c3851c0 435See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
6b9961a3 436[PACKAGING] foo v0.0.1 ([..])
90887707
EH
437[ARCHIVING] .cargo_vcs_info.json
438[ARCHIVING] Cargo.lock
34307c61 439[ARCHIVING] Cargo.toml
90887707 440[ARCHIVING] Cargo.toml.orig
34307c61
EH
441[ARCHIVING] file_root_3
442[ARCHIVING] file_root_4
443[ARCHIVING] file_root_5
444[ARCHIVING] some_dir/dir_deep_2/some_dir/file
445[ARCHIVING] some_dir/dir_deep_4/some_dir/file
446[ARCHIVING] some_dir/dir_deep_5/some_dir/file
447[ARCHIVING] some_dir/file_deep_2
448[ARCHIVING] some_dir/file_deep_3
449[ARCHIVING] some_dir/file_deep_4
450[ARCHIVING] some_dir/file_deep_5
451[ARCHIVING] src/main.rs
1e682848 452",
fecb7246
AC
453 )
454 .run();
c072ba42 455
dd998a09 456 assert!(repo.root().join("target/package/foo-0.0.1.crate").is_file());
c072ba42 457
dd998a09
XL
458 cargo_process("package -l")
459 .cwd(repo.root())
85984a87 460 .with_stdout(
1e682848 461 "\
dd998a09 462.cargo_vcs_info.json
34307c61 463Cargo.lock
c072ba42 464Cargo.toml
90887707 465Cargo.toml.orig
c072ba42
BE
466file_root_3
467file_root_4
468file_root_5
05400b80 469some_dir/dir_deep_2/some_dir/file
05400b80
DW
470some_dir/dir_deep_4/some_dir/file
471some_dir/dir_deep_5/some_dir/file
05400b80
DW
472some_dir/file_deep_2
473some_dir/file_deep_3
474some_dir/file_deep_4
475some_dir/file_deep_5
476src/main.rs
1e682848 477",
fecb7246
AC
478 )
479 .run();
6950bbb0 480}
5935ec1d 481
0e0d9688 482#[cargo_test]
6950bbb0 483fn include() {
dd998a09
XL
484 let root = paths::root().join("include");
485 let repo = git::repo(&root)
fecb7246
AC
486 .file(
487 "Cargo.toml",
488 r#"
6f8c7d5a
EH
489 [project]
490 name = "foo"
491 version = "0.0.1"
492 authors = []
493 exclude = ["*.txt"]
494 include = ["foo.txt", "**/*.rs", "Cargo.toml", ".dotfile"]
495 "#,
fecb7246 496 )
5935ec1d 497 .file("foo.txt", "")
ca7d9ee2 498 .file("src/main.rs", r#"fn main() { println!("hello"); }"#)
7662c2d8 499 .file(".dotfile", "")
f7c91ba6
AR
500 // Should be ignored when packaging.
501 .file("src/bar.txt", "")
d43ee1dd 502 .build();
5935ec1d 503
dd998a09
XL
504 cargo_process("package --no-verify -v")
505 .cwd(repo.root())
85984a87 506 .with_stderr(
1e682848 507 "\
eeebadff 508[WARNING] manifest has no description[..]
0c3851c0 509See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
db3328ec 510[WARNING] both package.include and package.exclude are specified; the exclude list will be ignored
fee4308b 511[PACKAGING] foo v0.0.1 ([..])
90887707 512[ARCHIVING] .cargo_vcs_info.json
7662c2d8 513[ARCHIVING] .dotfile
90887707 514[ARCHIVING] Cargo.lock
34307c61 515[ARCHIVING] Cargo.toml
90887707 516[ARCHIVING] Cargo.toml.orig
34307c61
EH
517[ARCHIVING] foo.txt
518[ARCHIVING] src/main.rs
1e682848 519",
fecb7246
AC
520 )
521 .run();
6950bbb0 522}
350bd8d2 523
0e0d9688 524#[cargo_test]
6950bbb0 525fn package_lib_with_bin() {
7fe2fbc8 526 let p = project()
ca7d9ee2 527 .file("src/main.rs", "extern crate foo; fn main() {}")
d43ee1dd
NK
528 .file("src/lib.rs", "")
529 .build();
350bd8d2 530
85984a87 531 p.cargo("package -v").run();
6950bbb0 532}
a8e9ce22 533
0e0d9688 534#[cargo_test]
6950bbb0 535fn package_git_submodule() {
036d6f6d 536 let project = git::new("foo", |project| {
1e682848
AC
537 project
538 .file(
539 "Cargo.toml",
540 r#"
036d6f6d
IU
541 [project]
542 name = "foo"
543 version = "0.0.1"
544 authors = ["foo@example.com"]
545 license = "MIT"
546 description = "foo"
547 repository = "foo"
1e682848 548 "#,
fecb7246
AC
549 )
550 .file("src/lib.rs", "pub fn foo() {}")
3c20a243 551 });
85984a87
DW
552 let library = git::new("bar", |library| {
553 library.no_manifest().file("Makefile", "all:")
3c20a243 554 });
036d6f6d
IU
555
556 let repository = git2::Repository::open(&project.root()).unwrap();
557 let url = path2url(library.root()).to_string();
558 git::add_submodule(&repository, &url, Path::new("bar"));
559 git::commit(&repository);
560
561 let repository = git2::Repository::open(&project.root().join("bar")).unwrap();
1e682848
AC
562 repository
563 .reset(
564 &repository.revparse_single("HEAD").unwrap(),
565 git2::ResetType::Hard,
566 None,
fecb7246
AC
567 )
568 .unwrap();
1e682848 569
fecb7246
AC
570 project
571 .cargo("package --no-verify -v")
85984a87
DW
572 .with_stderr_contains("[ARCHIVING] bar/Makefile")
573 .run();
6950bbb0 574}
d33da549 575
77cfceea 576#[cargo_test]
673bb69c
TW
577/// Tests if a symlink to a git submodule is properly handled.
578///
55e56233
TW
579/// This test requires you to be able to make symlinks.
580/// For windows, this may require you to enable developer mode.
77cfceea 581fn package_symlink_to_submodule() {
50a24ff2 582 #[cfg(unix)]
673bb69c 583 use std::os::unix::fs::symlink;
50a24ff2 584 #[cfg(windows)]
32130f8e 585 use std::os::windows::fs::symlink_dir as symlink;
50a24ff2 586
55e56233
TW
587 if !symlink_supported() {
588 return;
589 }
590
77cfceea 591 let project = git::new("foo", |project| {
673bb69c 592 project.file("src/lib.rs", "pub fn foo() {}")
3c20a243 593 });
77cfceea
TW
594
595 let library = git::new("submodule", |library| {
596 library.no_manifest().file("Makefile", "all:")
3c20a243 597 });
77cfceea
TW
598
599 let repository = git2::Repository::open(&project.root()).unwrap();
600 let url = path2url(library.root()).to_string();
601 git::add_submodule(&repository, &url, Path::new("submodule"));
673bb69c
TW
602 t!(symlink(
603 &project.root().join("submodule"),
604 &project.root().join("submodule-link")
605 ));
50a24ff2 606 git::add(&repository);
77cfceea
TW
607 git::commit(&repository);
608
609 let repository = git2::Repository::open(&project.root().join("submodule")).unwrap();
610 repository
611 .reset(
612 &repository.revparse_single("HEAD").unwrap(),
613 git2::ResetType::Hard,
673bb69c
TW
614 None,
615 )
616 .unwrap();
77cfceea
TW
617
618 project
619 .cargo("package --no-verify -v")
620 .with_stderr_contains("[ARCHIVING] submodule/Makefile")
621 .run();
622}
623
0e0d9688 624#[cargo_test]
6950bbb0 625fn no_duplicates_from_modified_tracked_files() {
4ae79d2f
EH
626 let p = git::new("all", |p| p.file("src/main.rs", "fn main() {}"));
627 p.change_file("src/main.rs", r#"fn main() { println!("A change!"); }"#);
628 p.cargo("build").run();
629 p.cargo("package --list --allow-dirty")
85984a87 630 .with_stdout(
1e682848 631 "\
34307c61 632Cargo.lock
e2cd4cdb 633Cargo.toml
90887707 634Cargo.toml.orig
e2cd4cdb 635src/main.rs
1e682848 636",
fecb7246
AC
637 )
638 .run();
6950bbb0 639}
e2cd4cdb 640
0e0d9688 641#[cargo_test]
6950bbb0 642fn ignore_nested() {
d33da549
SF
643 let cargo_toml = r#"
644 [project]
f8c9928c 645 name = "foo"
d33da549
SF
646 version = "0.0.1"
647 authors = []
648 license = "MIT"
f8c9928c 649 description = "foo"
d33da549
SF
650 "#;
651 let main_rs = r#"
652 fn main() { println!("hello"); }
653 "#;
f8c9928c 654 let p = project()
d33da549
SF
655 .file("Cargo.toml", cargo_toml)
656 .file("src/main.rs", main_rs)
657 // If a project happens to contain a copy of itself, we should
658 // ignore it.
f8c9928c
DW
659 .file("a_dir/foo/Cargo.toml", cargo_toml)
660 .file("a_dir/foo/src/main.rs", main_rs)
d43ee1dd 661 .build();
d33da549 662
85984a87 663 p.cargo("package")
2cd9cce6 664 .with_stderr(
1e682848 665 "\
eeebadff 666[WARNING] manifest has no documentation[..]
0c3851c0 667See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
89f43938
ZL
668[PACKAGING] foo v0.0.1 ([CWD])
669[VERIFYING] foo v0.0.1 ([CWD])
670[COMPILING] foo v0.0.1 ([CWD][..])
34628b65 671[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
d33da549 672",
fecb7246
AC
673 )
674 .run();
570fe892 675 assert!(p.root().join("target/package/foo-0.0.1.crate").is_file());
85984a87
DW
676 p.cargo("package -l")
677 .with_stdout(
1e682848 678 "\
34307c61 679Cargo.lock
d33da549 680Cargo.toml
90887707
EH
681Cargo.toml.orig
682src/main.rs
1e682848 683",
fecb7246
AC
684 )
685 .run();
85984a87 686 p.cargo("package").with_stdout("").run();
d33da549 687
f8c9928c 688 let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap();
3d84d0ad
EH
689 validate_crate_contents(
690 f,
691 "foo-0.0.1.crate",
34307c61 692 &["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"],
3d84d0ad
EH
693 &[],
694 );
6950bbb0 695}
afe837d7 696
f7c91ba6
AR
697// Windows doesn't allow these characters in filenames.
698#[cfg(unix)]
0e0d9688 699#[cargo_test]
6950bbb0 700fn package_weird_characters() {
7fe2fbc8 701 let p = project()
ca7d9ee2 702 .file("src/main.rs", r#"fn main() { println!("hello"); }"#)
d43ee1dd
NK
703 .file("src/:foo", "")
704 .build();
afe837d7 705
85984a87
DW
706 p.cargo("package")
707 .with_status(101)
708 .with_stderr(
1e682848 709 "\
afe837d7 710warning: [..]
32275465 711See [..]
90887707 712[ERROR] cannot package a filename with a special character `:`: src/:foo
1e682848 713",
fecb7246
AC
714 )
715 .run();
6950bbb0 716}
18bf06d3 717
0e0d9688 718#[cargo_test]
18bf06d3 719fn repackage_on_source_change() {
7fe2fbc8 720 let p = project()
ca7d9ee2 721 .file("src/main.rs", r#"fn main() { println!("hello"); }"#)
d43ee1dd 722 .build();
18bf06d3 723
85984a87 724 p.cargo("package").run();
18bf06d3
BF
725
726 // Add another source file
4ae79d2f 727 p.change_file("src/foo.rs", r#"fn main() { println!("foo"); }"#);
18bf06d3 728
18bf06d3 729 // Check that cargo rebuilds the tarball
4415c728 730 p.cargo("package")
2cd9cce6 731 .with_stderr(
1e682848 732 "\
18bf06d3 733[WARNING] [..]
32275465 734See [..]
89f43938
ZL
735[PACKAGING] foo v0.0.1 ([CWD])
736[VERIFYING] foo v0.0.1 ([CWD])
737[COMPILING] foo v0.0.1 ([CWD][..])
34628b65 738[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
18bf06d3 739",
fecb7246
AC
740 )
741 .run();
18bf06d3
BF
742
743 // Check that the tarball contains the added file
744 let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap();
3d84d0ad
EH
745 validate_crate_contents(
746 f,
747 "foo-0.0.1.crate",
34307c61
EH
748 &[
749 "Cargo.lock",
750 "Cargo.toml",
751 "Cargo.toml.orig",
752 "src/main.rs",
753 "src/foo.rs",
754 ],
3d84d0ad
EH
755 &[],
756 );
18bf06d3 757}
77812987 758
0e0d9688 759#[cargo_test]
673bb69c
TW
760/// Tests if a broken symlink is properly handled when packaging.
761///
55e56233
TW
762/// This test requires you to be able to make symlinks.
763/// For windows, this may require you to enable developer mode.
77812987 764fn broken_symlink() {
32130f8e 765 #[cfg(unix)]
673bb69c 766 use std::os::unix::fs::symlink;
32130f8e
TW
767 #[cfg(windows)]
768 use std::os::windows::fs::symlink_dir as symlink;
77812987 769
55e56233
TW
770 if !symlink_supported() {
771 return;
772 }
773
7fe2fbc8 774 let p = project()
1e682848
AC
775 .file(
776 "Cargo.toml",
777 r#"
6f8c7d5a
EH
778 [project]
779 name = "foo"
780 version = "0.0.1"
781 authors = []
782 license = "MIT"
783 description = 'foo'
784 documentation = 'foo'
785 homepage = 'foo'
786 repository = 'foo'
787 "#,
fecb7246
AC
788 )
789 .file("src/main.rs", r#"fn main() { println!("hello"); }"#)
d43ee1dd 790 .build();
32130f8e 791 t!(symlink("nowhere", &p.root().join("src/foo.rs")));
77812987 792
85984a87
DW
793 p.cargo("package -v")
794 .with_status(101)
795 .with_stderr_contains(
1e682848 796 "\
d92dceae 797[ERROR] failed to prepare local package for uploading
77812987
AC
798
799Caused by:
d92dceae 800 failed to open for archiving: `[..]foo.rs`
77812987
AC
801
802Caused by:
803 [..]
1e682848 804",
fecb7246
AC
805 )
806 .run();
77812987 807}
ee32e105 808
77cfceea 809#[cargo_test]
34f2d471 810/// Tests if a symlink to a directory is properly included.
673bb69c 811///
55e56233
TW
812/// This test requires you to be able to make symlinks.
813/// For windows, this may require you to enable developer mode.
77cfceea 814fn package_symlink_to_dir() {
55e56233
TW
815 if !symlink_supported() {
816 return;
817 }
818
77cfceea
TW
819 project()
820 .file("src/main.rs", r#"fn main() { println!("hello"); }"#)
821 .file("bla/Makefile", "all:")
822 .symlink_dir("bla", "foo")
823 .build()
824 .cargo("package -v")
825 .with_stderr_contains("[ARCHIVING] foo/Makefile")
826 .run();
827}
828
6fa0f01d
WL
829#[cargo_test]
830/// Tests if a symlink to ancestor causes filesystem loop error.
831///
832/// This test requires you to be able to make symlinks.
833/// For windows, this may require you to enable developer mode.
834fn filesystem_loop() {
835 if !symlink_supported() {
836 return;
837 }
838
839 project()
840 .file("src/main.rs", r#"fn main() { println!("hello"); }"#)
841 .symlink_dir("a/b", "a/b/c/d/foo")
842 .build()
843 .cargo("package -v")
6fa0f01d 844 .with_stderr_contains(
d92dceae 845 "[WARNING] File system loop found: [..]/a/b/c/d/foo points to an ancestor [..]/a/b",
6fa0f01d
WL
846 )
847 .run();
848}
849
0e0d9688 850#[cargo_test]
ee32e105 851fn do_not_package_if_repository_is_dirty() {
7fe2fbc8 852 let p = project().build();
5e8eef97 853
ee32e105 854 // Create a Git repository containing a minimal Rust project.
d43ee1dd 855 let _ = git::repo(&paths::root().join("foo"))
1e682848
AC
856 .file(
857 "Cargo.toml",
858 r#"
6f8c7d5a
EH
859 [project]
860 name = "foo"
861 version = "0.0.1"
862 license = "MIT"
863 description = "foo"
864 documentation = "foo"
865 homepage = "foo"
866 repository = "foo"
867 "#,
fecb7246
AC
868 )
869 .file("src/main.rs", "fn main() {}")
ee32e105
BBT
870 .build();
871
872 // Modify Cargo.toml without committing the change.
1e682848
AC
873 p.change_file(
874 "Cargo.toml",
875 r#"
5e8eef97
AK
876 [project]
877 name = "foo"
878 version = "0.0.1"
879 license = "MIT"
880 description = "foo"
881 documentation = "foo"
882 homepage = "foo"
883 repository = "foo"
884 # change
6514c289 885 "#,
1e682848 886 );
ee32e105 887
85984a87
DW
888 p.cargo("package")
889 .with_status(101)
890 .with_stderr(
1e682848 891 "\
ca1acc57
JL
892error: 1 files in the working directory contain changes that were not yet \
893committed into git:
ee32e105
BBT
894
895Cargo.toml
896
34f2d471 897to proceed despite this and include the uncommitted changes, pass the `--allow-dirty` flag
1e682848 898",
fecb7246
AC
899 )
900 .run();
ee32e105 901}
57db8bde 902
a200640d
EH
903#[cargo_test]
904fn dirty_ignored() {
905 // Cargo warns about an ignored file that will be published.
906 let (p, repo) = git::new_repo("foo", |p| {
907 p.file(
908 "Cargo.toml",
909 r#"
910 [package]
911 name = "foo"
912 version = "0.1.0"
913 description = "foo"
914 license = "foo"
915 documentation = "foo"
916 include = ["src", "build"]
917 "#,
918 )
919 .file("src/lib.rs", "")
920 .file(".gitignore", "build")
921 });
922 // Example of adding a file that is confusingly ignored by an overzealous
923 // gitignore rule.
924 p.change_file("src/build/mod.rs", "");
925 p.cargo("package --list")
926 .with_status(101)
927 .with_stderr(
928 "\
929error: 1 files in the working directory contain changes that were not yet committed into git:
930
931src/build/mod.rs
932
933to proceed despite this and include the uncommitted changes, pass the `--allow-dirty` flag
934",
935 )
936 .run();
937 // Add the ignored file and make sure it is included.
938 let mut index = t!(repo.index());
939 t!(index.add_path(Path::new("src/build/mod.rs")));
940 t!(index.write());
941 git::commit(&repo);
942 p.cargo("package --list")
943 .with_stderr("")
944 .with_stdout(
945 "\
946.cargo_vcs_info.json
947Cargo.toml
948Cargo.toml.orig
949src/build/mod.rs
950src/lib.rs
951",
952 )
953 .run();
954}
955
0e0d9688 956#[cargo_test]
57db8bde 957fn generated_manifest() {
340656e2 958 registry::alt_init();
f38c53f5 959 Package::new("abc", "1.0.0").publish();
a4a3302d 960 Package::new("def", "1.0.0").alternative(true).publish();
f38c53f5 961 Package::new("ghi", "1.0.0").publish();
34307c61 962 Package::new("bar", "0.1.0").publish();
a4a3302d 963
7fe2fbc8 964 let p = project()
1e682848
AC
965 .file(
966 "Cargo.toml",
967 r#"
6f8c7d5a
EH
968 [project]
969 name = "foo"
970 version = "0.0.1"
971 authors = []
972 exclude = ["*.txt"]
973 license = "MIT"
974 description = "foo"
57db8bde 975
6f8c7d5a
EH
976 [project.metadata]
977 foo = 'bar'
0c704f8d 978
6f8c7d5a 979 [workspace]
57db8bde 980
6f8c7d5a
EH
981 [dependencies]
982 bar = { path = "bar", version = "0.1" }
983 def = { version = "1.0", registry = "alternative" }
984 ghi = "1.0"
985 abc = "1.0"
986 "#,
fecb7246
AC
987 )
988 .file("src/main.rs", "")
ab19c483 989 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
d43ee1dd
NK
990 .file("bar/src/lib.rs", "")
991 .build();
57db8bde 992
87449f45 993 p.cargo("package --no-verify").run();
57db8bde
AC
994
995 let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap();
3d84d0ad 996 let rewritten_toml = format!(
787e75b7 997 r#"{}
57db8bde
AC
998[package]
999name = "foo"
1000version = "0.0.1"
1001authors = []
1002exclude = ["*.txt"]
1003description = "foo"
1004license = "MIT"
0c704f8d
AC
1005
1006[package.metadata]
1007foo = "bar"
f38c53f5
SS
1008[dependencies.abc]
1009version = "1.0"
1010
57db8bde
AC
1011[dependencies.bar]
1012version = "0.1"
f38c53f5
SS
1013
1014[dependencies.def]
1015version = "1.0"
c40d1836 1016registry-index = "{}"
f38c53f5
SS
1017
1018[dependencies.ghi]
1019version = "1.0"
f6dcdb5c 1020"#,
787e75b7 1021 cargo::core::package::MANIFEST_PREAMBLE,
b5144c7f 1022 registry::alt_registry_url()
3d84d0ad
EH
1023 );
1024
1025 validate_crate_contents(
1026 f,
1027 "foo-0.0.1.crate",
34307c61 1028 &["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"],
3d84d0ad 1029 &[("Cargo.toml", &rewritten_toml)],
1e682848 1030 );
57db8bde
AC
1031}
1032
0e0d9688 1033#[cargo_test]
57db8bde 1034fn ignore_workspace_specifier() {
7fe2fbc8 1035 let p = project()
1e682848
AC
1036 .file(
1037 "Cargo.toml",
1038 r#"
6f8c7d5a
EH
1039 [project]
1040 name = "foo"
1041 version = "0.0.1"
d1e70e49 1042
6f8c7d5a 1043 authors = []
57db8bde 1044
6f8c7d5a 1045 [workspace]
57db8bde 1046
6f8c7d5a
EH
1047 [dependencies]
1048 bar = { path = "bar", version = "0.1" }
1049 "#,
fecb7246
AC
1050 )
1051 .file("src/main.rs", "")
1e682848
AC
1052 .file(
1053 "bar/Cargo.toml",
1054 r#"
6f8c7d5a
EH
1055 [package]
1056 name = "bar"
1057 version = "0.1.0"
1058 authors = []
1059 workspace = ".."
1060 "#,
fecb7246
AC
1061 )
1062 .file("bar/src/lib.rs", "")
d43ee1dd 1063 .build();
57db8bde 1064
f16efff1 1065 p.cargo("package --no-verify").cwd("bar").run();
57db8bde
AC
1066
1067 let f = File::open(&p.root().join("target/package/bar-0.1.0.crate")).unwrap();
787e75b7
EH
1068 let rewritten_toml = format!(
1069 r#"{}
57db8bde
AC
1070[package]
1071name = "bar"
1072version = "0.1.0"
1073authors = []
787e75b7
EH
1074"#,
1075 cargo::core::package::MANIFEST_PREAMBLE
1076 );
3d84d0ad
EH
1077 validate_crate_contents(
1078 f,
1079 "bar-0.1.0.crate",
1080 &["Cargo.toml", "Cargo.toml.orig", "src/lib.rs"],
787e75b7 1081 &[("Cargo.toml", &rewritten_toml)],
1e682848 1082 );
57db8bde 1083}
d1e70e49 1084
0e0d9688 1085#[cargo_test]
d1e70e49
AC
1086fn package_two_kinds_of_deps() {
1087 Package::new("other", "1.0.0").publish();
1088 Package::new("other1", "1.0.0").publish();
7fe2fbc8 1089 let p = project()
1e682848
AC
1090 .file(
1091 "Cargo.toml",
1092 r#"
6f8c7d5a
EH
1093 [project]
1094 name = "foo"
1095 version = "0.0.1"
1096 authors = []
d1e70e49 1097
6f8c7d5a
EH
1098 [dependencies]
1099 other = "1.0"
1100 other1 = { version = "1.0" }
1101 "#,
fecb7246
AC
1102 )
1103 .file("src/main.rs", "")
d43ee1dd 1104 .build();
d1e70e49 1105
85984a87 1106 p.cargo("package --no-verify").run();
d1e70e49 1107}
5d615a69 1108
0e0d9688 1109#[cargo_test]
3bbe93ce 1110fn test_edition() {
7fe2fbc8 1111 let p = project()
1e682848
AC
1112 .file(
1113 "Cargo.toml",
1114 r#"
6f8c7d5a
EH
1115 cargo-features = ["edition"]
1116 [package]
1117 name = "foo"
1118 version = "0.0.1"
1119 authors = []
1120 edition = "2018"
1121 "#,
fecb7246
AC
1122 )
1123 .file("src/lib.rs", r#" "#)
5d615a69
MG
1124 .build();
1125
fecb7246 1126 p.cargo("build -v")
fecb7246
AC
1127 .with_stderr_contains(
1128 "\
3dbae343
EH
1129[COMPILING] foo v0.0.1 ([..])
1130[RUNNING] `rustc [..]--edition=2018 [..]
fecb7246
AC
1131",
1132 )
1133 .run();
5d615a69
MG
1134}
1135
0e0d9688 1136#[cargo_test]
8590a5fb 1137fn edition_with_metadata() {
8590a5fb 1138 let p = project()
85984a87
DW
1139 .file(
1140 "Cargo.toml",
1141 r#"
3d029039
AC
1142 [package]
1143 name = "foo"
1144 version = "0.0.1"
1145 authors = []
1146 edition = "2018"
1147
1148 [package.metadata.docs.rs]
1149 features = ["foobar"]
1150 "#,
fecb7246
AC
1151 )
1152 .file("src/lib.rs", "")
8590a5fb
DS
1153 .build();
1154
3d029039 1155 p.cargo("package").run();
5d615a69
MG
1156}
1157
0e0d9688 1158#[cargo_test]
3bbe93ce 1159fn test_edition_malformed() {
7fe2fbc8 1160 let p = project()
1e682848
AC
1161 .file(
1162 "Cargo.toml",
1163 r#"
3d029039
AC
1164 [package]
1165 name = "foo"
1166 version = "0.0.1"
1167 authors = []
1168 edition = "chicken"
1169 "#,
fecb7246
AC
1170 )
1171 .file("src/lib.rs", r#" "#)
5d615a69
MG
1172 .build();
1173
85984a87 1174 p.cargo("build -v")
85984a87
DW
1175 .with_status(101)
1176 .with_stderr(
1e682848 1177 "\
5d615a69
MG
1178error: failed to parse manifest at `[..]`
1179
1180Caused by:
84130089
AC
1181 failed to parse the `edition` key
1182
1183Caused by:
de839dab 1184 supported edition values are `2015`, `2018`, or `2021`, but `chicken` is unknown
fecb7246
AC
1185"
1186 .to_string(),
1187 )
1188 .run();
5d615a69
MG
1189}
1190
f57c4c9b
K
1191#[cargo_test]
1192fn test_edition_from_the_future() {
1193 let p = project()
1194 .file(
1195 "Cargo.toml",
1196 r#"[package]
1197 edition = "2038"
1198 name = "foo"
1199 version = "99.99.99"
1200 authors = []
1201 "#,
1202 )
1203 .file("src/main.rs", r#""#)
1204 .build();
1205
1206 p.cargo("build")
1207 .with_status(101)
1208 .with_stderr(
1209 "\
1210error: failed to parse manifest at `[..]`
1211
1212Caused by:
1213 failed to parse the `edition` key
1214
1215Caused by:
de839dab 1216 this version of Cargo is older than the `2038` edition, and only supports `2015`, `2018`, and `2021` editions.
f57c4c9b
K
1217"
1218 .to_string(),
1219 )
1220 .run();
1221}
1222
0e0d9688 1223#[cargo_test]
ba48ff42 1224fn do_not_package_if_src_was_modified() {
7fe2fbc8 1225 let p = project()
ca7d9ee2 1226 .file("src/main.rs", r#"fn main() { println!("hello"); }"#)
aef2a9cb 1227 .file("dir/foo.txt", "")
78a60bc7 1228 .file("bar.txt", "")
85984a87
DW
1229 .file(
1230 "build.rs",
1231 r#"
6f8c7d5a
EH
1232 use std::fs;
1233
1234 fn main() {
1235 fs::write("src/generated.txt",
1236 "Hello, world of generated files."
1237 ).expect("failed to create file");
1238 fs::remove_file("dir/foo.txt").expect("failed to remove file");
1239 fs::remove_dir("dir").expect("failed to remove dir");
1240 fs::write("bar.txt", "updated content").expect("failed to update");
1241 fs::create_dir("new-dir").expect("failed to create dir");
1242 }
1243 "#,
fecb7246
AC
1244 )
1245 .build();
ba48ff42 1246
85984a87
DW
1247 p.cargo("package")
1248 .with_status(101)
1249 .with_stderr_contains(
1250 "\
53480ac7
GF
1251error: failed to verify package tarball
1252
1253Caused by:
1254 Source directory was modified by build.rs during cargo publish. \
6514c289
AC
1255 Build scripts should not modify anything outside of OUT_DIR.
1256 Changed: [CWD]/target/package/foo-0.0.1/bar.txt
1257 Added: [CWD]/target/package/foo-0.0.1/new-dir
1258 <tab>[CWD]/target/package/foo-0.0.1/src/generated.txt
1259 Removed: [CWD]/target/package/foo-0.0.1/dir
1260 <tab>[CWD]/target/package/foo-0.0.1/dir/foo.txt
1261
1262 To proceed despite this, pass the `--no-verify` flag.",
fecb7246
AC
1263 )
1264 .run();
ba48ff42 1265
85984a87 1266 p.cargo("package --no-verify").run();
ba48ff42 1267}
142bafb7 1268
0e0d9688 1269#[cargo_test]
142bafb7
KF
1270fn package_with_select_features() {
1271 let p = project()
1272 .file(
1273 "Cargo.toml",
1274 r#"
6f8c7d5a
EH
1275 [project]
1276 name = "foo"
1277 version = "0.0.1"
1278 authors = []
1279 license = "MIT"
1280 description = "foo"
142bafb7 1281
6f8c7d5a
EH
1282 [features]
1283 required = []
1284 optional = []
1285 "#,
db09895f 1286 )
1287 .file(
142bafb7
KF
1288 "src/main.rs",
1289 "#[cfg(not(feature = \"required\"))]
1290 compile_error!(\"This crate requires `required` feature!\");
1291 fn main() {}",
db09895f 1292 )
1293 .build();
142bafb7 1294
87449f45 1295 p.cargo("package --features required").run();
142bafb7
KF
1296}
1297
0e0d9688 1298#[cargo_test]
142bafb7
KF
1299fn package_with_all_features() {
1300 let p = project()
1301 .file(
1302 "Cargo.toml",
1303 r#"
6f8c7d5a
EH
1304 [project]
1305 name = "foo"
1306 version = "0.0.1"
1307 authors = []
1308 license = "MIT"
1309 description = "foo"
142bafb7 1310
6f8c7d5a
EH
1311 [features]
1312 required = []
1313 optional = []
1314 "#,
db09895f 1315 )
1316 .file(
142bafb7
KF
1317 "src/main.rs",
1318 "#[cfg(not(feature = \"required\"))]
1319 compile_error!(\"This crate requires `required` feature!\");
1320 fn main() {}",
db09895f 1321 )
1322 .build();
142bafb7 1323
87449f45 1324 p.cargo("package --all-features").run();
142bafb7 1325}
b29e3796 1326
0e0d9688 1327#[cargo_test]
b29e3796
KF
1328fn package_no_default_features() {
1329 let p = project()
1330 .file(
1331 "Cargo.toml",
1332 r#"
6f8c7d5a
EH
1333 [project]
1334 name = "foo"
1335 version = "0.0.1"
1336 authors = []
1337 license = "MIT"
1338 description = "foo"
b29e3796 1339
6f8c7d5a
EH
1340 [features]
1341 default = ["required"]
1342 required = []
1343 "#,
db09895f 1344 )
1345 .file(
b29e3796
KF
1346 "src/main.rs",
1347 "#[cfg(not(feature = \"required\"))]
1348 compile_error!(\"This crate requires `required` feature!\");
1349 fn main() {}",
db09895f 1350 )
1351 .build();
b29e3796
KF
1352
1353 p.cargo("package --no-default-features")
b29e3796
KF
1354 .with_stderr_contains("error: This crate requires `required` feature!")
1355 .with_status(101)
1356 .run();
1357}
49e37f80 1358
0e0d9688 1359#[cargo_test]
49e37f80
EH
1360fn include_cargo_toml_implicit() {
1361 let p = project()
1362 .file(
1363 "Cargo.toml",
1364 r#"
1365 [package]
1366 name = "foo"
1367 version = "0.1.0"
1368 include = ["src/lib.rs"]
1369 "#,
1370 )
1371 .file("src/lib.rs", "")
1372 .build();
1373
1374 p.cargo("package --list")
90887707 1375 .with_stdout("Cargo.toml\nCargo.toml.orig\nsrc/lib.rs\n")
49e37f80
EH
1376 .run();
1377}
d4b6e90f 1378
24d28502 1379fn include_exclude_test(include: &str, exclude: &str, files: &[&str], expected: &str) {
d4b6e90f
EH
1380 let mut pb = project().file(
1381 "Cargo.toml",
1382 &format!(
1383 r#"
1384 [package]
1385 name = "foo"
1386 version = "0.1.0"
1387 authors = []
1388 license = "MIT"
1389 description = "foo"
1390 documentation = "foo"
1391 homepage = "foo"
1392 repository = "foo"
1393 include = {}
1394 exclude = {}
1395 "#,
1396 include, exclude
1397 ),
1398 );
1399 for file in files {
1400 pb = pb.file(file, "");
1401 }
1402 let p = pb.build();
1403
24d28502
EH
1404 p.cargo("package --list")
1405 .with_stderr("")
1406 .with_stdout(expected)
1407 .run();
d4b6e90f
EH
1408 p.root().rm_rf();
1409}
1410
0e0d9688 1411#[cargo_test]
d4b6e90f
EH
1412fn package_include_ignore_only() {
1413 // Test with a gitignore pattern that fails to parse with glob.
1414 // This is a somewhat nonsense pattern, but is an example of something git
1415 // allows and glob does not.
1416 assert!(glob::Pattern::new("src/abc**").is_err());
1417
1418 include_exclude_test(
1419 r#"["Cargo.toml", "src/abc**", "src/lib.rs"]"#,
1420 "[]",
1421 &["src/lib.rs", "src/abc1.rs", "src/abc2.rs", "src/abc/mod.rs"],
1422 "Cargo.toml\n\
90887707 1423 Cargo.toml.orig\n\
d4b6e90f
EH
1424 src/abc/mod.rs\n\
1425 src/abc1.rs\n\
1426 src/abc2.rs\n\
1427 src/lib.rs\n\
1428 ",
1429 )
1430}
1431
0e0d9688 1432#[cargo_test]
d4b6e90f
EH
1433fn gitignore_patterns() {
1434 include_exclude_test(
1435 r#"["Cargo.toml", "foo"]"#, // include
1436 "[]",
1437 &["src/lib.rs", "foo", "a/foo", "a/b/foo", "x/foo/y", "bar"],
1438 "Cargo.toml\n\
90887707 1439 Cargo.toml.orig\n\
d4b6e90f
EH
1440 a/b/foo\n\
1441 a/foo\n\
1442 foo\n\
1443 x/foo/y\n\
1444 ",
1445 );
1446
1447 include_exclude_test(
1448 r#"["Cargo.toml", "/foo"]"#, // include
1449 "[]",
1450 &["src/lib.rs", "foo", "a/foo", "a/b/foo", "x/foo/y", "bar"],
1451 "Cargo.toml\n\
90887707 1452 Cargo.toml.orig\n\
d4b6e90f
EH
1453 foo\n\
1454 ",
1455 );
1456
1457 include_exclude_test(
1458 "[]",
1459 r#"["foo/"]"#, // exclude
1460 &["src/lib.rs", "foo", "a/foo", "x/foo/y", "bar"],
1461 "Cargo.toml\n\
90887707 1462 Cargo.toml.orig\n\
d4b6e90f
EH
1463 a/foo\n\
1464 bar\n\
1465 foo\n\
1466 src/lib.rs\n\
1467 ",
1468 );
1469
1470 include_exclude_test(
1471 "[]",
1472 r#"["*.txt", "[ab]", "[x-z]"]"#, // exclude
1473 &[
1474 "src/lib.rs",
1475 "foo.txt",
1476 "bar/foo.txt",
1477 "other",
1478 "a",
1479 "b",
1480 "c",
1481 "x",
1482 "y",
1483 "z",
1484 ],
1485 "Cargo.toml\n\
90887707 1486 Cargo.toml.orig\n\
d4b6e90f
EH
1487 c\n\
1488 other\n\
1489 src/lib.rs\n\
1490 ",
1491 );
1492
1493 include_exclude_test(
1494 r#"["Cargo.toml", "**/foo/bar"]"#, // include
1495 "[]",
1496 &["src/lib.rs", "a/foo/bar", "foo", "bar"],
1497 "Cargo.toml\n\
90887707 1498 Cargo.toml.orig\n\
d4b6e90f
EH
1499 a/foo/bar\n\
1500 ",
1501 );
1502
1503 include_exclude_test(
1504 r#"["Cargo.toml", "foo/**"]"#, // include
1505 "[]",
1506 &["src/lib.rs", "a/foo/bar", "foo/x/y/z"],
1507 "Cargo.toml\n\
90887707 1508 Cargo.toml.orig\n\
d4b6e90f
EH
1509 foo/x/y/z\n\
1510 ",
1511 );
1512
1513 include_exclude_test(
1514 r#"["Cargo.toml", "a/**/b"]"#, // include
1515 "[]",
1516 &["src/lib.rs", "a/b", "a/x/b", "a/x/y/b"],
1517 "Cargo.toml\n\
90887707 1518 Cargo.toml.orig\n\
d4b6e90f
EH
1519 a/b\n\
1520 a/x/b\n\
1521 a/x/y/b\n\
1522 ",
3ca96e90
EH
1523 );
1524}
1525
0e0d9688 1526#[cargo_test]
3ca96e90
EH
1527fn gitignore_negate() {
1528 include_exclude_test(
1529 r#"["Cargo.toml", "*.rs", "!foo.rs", "\\!important"]"#, // include
1530 "[]",
1531 &["src/lib.rs", "foo.rs", "!important"],
1532 "!important\n\
1533 Cargo.toml\n\
90887707 1534 Cargo.toml.orig\n\
3ca96e90
EH
1535 src/lib.rs\n\
1536 ",
3ca96e90
EH
1537 );
1538
1539 // NOTE: This is unusual compared to git. Git treats `src/` as a
1540 // short-circuit which means rules like `!src/foo.rs` would never run.
1541 // However, because Cargo only works by iterating over *files*, it doesn't
1542 // short-circuit.
1543 include_exclude_test(
1544 r#"["Cargo.toml", "src/", "!src/foo.rs"]"#, // include
1545 "[]",
1546 &["src/lib.rs", "src/foo.rs"],
1547 "Cargo.toml\n\
90887707 1548 Cargo.toml.orig\n\
3ca96e90
EH
1549 src/lib.rs\n\
1550 ",
3ca96e90
EH
1551 );
1552
1553 include_exclude_test(
337fbaaa 1554 r#"["Cargo.toml", "src/*.rs", "!foo.rs"]"#, // include
3ca96e90
EH
1555 "[]",
1556 &["src/lib.rs", "foo.rs", "src/foo.rs", "src/bar/foo.rs"],
1557 "Cargo.toml\n\
90887707 1558 Cargo.toml.orig\n\
3ca96e90
EH
1559 src/lib.rs\n\
1560 ",
3ca96e90
EH
1561 );
1562
1563 include_exclude_test(
1564 "[]",
1565 r#"["*.rs", "!foo.rs", "\\!important"]"#, // exclude
1566 &["src/lib.rs", "foo.rs", "!important"],
1567 "Cargo.toml\n\
90887707 1568 Cargo.toml.orig\n\
3ca96e90
EH
1569 foo.rs\n\
1570 ",
d4b6e90f
EH
1571 );
1572}
5c5d1718
SH
1573
1574#[cargo_test]
1575fn exclude_dot_files_and_directories_by_default() {
1576 include_exclude_test(
1577 "[]",
1578 "[]",
1579 &["src/lib.rs", ".dotfile", ".dotdir/file"],
1580 "Cargo.toml\n\
90887707 1581 Cargo.toml.orig\n\
5c5d1718
SH
1582 src/lib.rs\n\
1583 ",
1584 );
1585
1586 include_exclude_test(
1587 r#"["Cargo.toml", "src/lib.rs", ".dotfile", ".dotdir/file"]"#,
1588 "[]",
1589 &["src/lib.rs", ".dotfile", ".dotdir/file"],
1590 ".dotdir/file\n\
1591 .dotfile\n\
1592 Cargo.toml\n\
90887707 1593 Cargo.toml.orig\n\
5c5d1718
SH
1594 src/lib.rs\n\
1595 ",
1596 );
1597}
ab33bc0c
EH
1598
1599#[cargo_test]
1600fn invalid_license_file_path() {
1601 // Test warning when license-file points to a non-existent file.
1602 let p = project()
1603 .file(
1604 "Cargo.toml",
1605 r#"
1606 [package]
1607 name = "foo"
1608 version = "1.0.0"
1609 license-file = "does-not-exist"
1610 description = "foo"
1611 homepage = "foo"
1612 "#,
1613 )
1614 .file("src/lib.rs", "")
1615 .build();
1616
1617 p.cargo("package --no-verify")
1618 .with_stderr(
1619 "\
1620[WARNING] license-file `does-not-exist` does not appear to exist (relative to `[..]/foo`).
1621Please update the license-file setting in the manifest at `[..]/foo/Cargo.toml`
1622This may become a hard error in the future.
1623[PACKAGING] foo v1.0.0 ([..]/foo)
1624",
1625 )
1626 .run();
1627}
90887707
EH
1628
1629#[cargo_test]
1630fn license_file_implicit_include() {
1631 // license-file should be automatically included even if not listed.
1632 let p = git::new("foo", |p| {
1633 p.file(
1634 "Cargo.toml",
1635 r#"
1636 [package]
1637 name = "foo"
1638 version = "1.0.0"
1639 license-file = "subdir/LICENSE"
1640 description = "foo"
1641 homepage = "foo"
1642 include = ["src"]
1643 "#,
1644 )
1645 .file("src/lib.rs", "")
1646 .file("subdir/LICENSE", "license text")
1647 });
1648
1649 p.cargo("package --list")
1650 .with_stdout(
1651 "\
1652.cargo_vcs_info.json
1653Cargo.toml
1654Cargo.toml.orig
1655src/lib.rs
1656subdir/LICENSE
1657",
1658 )
1659 .with_stderr("")
1660 .run();
1661
1662 p.cargo("package --no-verify -v")
1663 .with_stderr(
1664 "\
1665[PACKAGING] foo v1.0.0 [..]
1666[ARCHIVING] .cargo_vcs_info.json
1667[ARCHIVING] Cargo.toml
1668[ARCHIVING] Cargo.toml.orig
1669[ARCHIVING] src/lib.rs
1670[ARCHIVING] subdir/LICENSE
1671",
1672 )
1673 .run();
1674 let f = File::open(&p.root().join("target/package/foo-1.0.0.crate")).unwrap();
1675 validate_crate_contents(
1676 f,
1677 "foo-1.0.0.crate",
1678 &[
1679 ".cargo_vcs_info.json",
1680 "Cargo.toml",
1681 "Cargo.toml.orig",
1682 "subdir/LICENSE",
1683 "src/lib.rs",
1684 ],
1685 &[("subdir/LICENSE", "license text")],
1686 );
1687}
1688
1689#[cargo_test]
1690fn relative_license_included() {
1691 // license-file path outside of package will copy into root.
1692 let p = project()
1693 .file(
1694 "Cargo.toml",
1695 r#"
1696 [package]
1697 name = "foo"
1698 version = "1.0.0"
1699 license-file = "../LICENSE"
1700 description = "foo"
1701 homepage = "foo"
1702 "#,
1703 )
1704 .file("src/lib.rs", "")
1705 .file("../LICENSE", "license text")
1706 .build();
1707
1708 p.cargo("package --list")
1709 .with_stdout(
1710 "\
1711Cargo.toml
1712Cargo.toml.orig
1713LICENSE
1714src/lib.rs
1715",
1716 )
1717 .with_stderr("")
1718 .run();
1719
1720 p.cargo("package")
1721 .with_stderr(
1722 "\
1723[PACKAGING] foo v1.0.0 [..]
1724[VERIFYING] foo v1.0.0 [..]
1725[COMPILING] foo v1.0.0 [..]
1726[FINISHED] [..]
1727",
1728 )
1729 .run();
1730 let f = File::open(&p.root().join("target/package/foo-1.0.0.crate")).unwrap();
1731 validate_crate_contents(
1732 f,
1733 "foo-1.0.0.crate",
1734 &["Cargo.toml", "Cargo.toml.orig", "LICENSE", "src/lib.rs"],
1735 &[("LICENSE", "license text")],
1736 );
1737 let manifest =
1738 std::fs::read_to_string(p.root().join("target/package/foo-1.0.0/Cargo.toml")).unwrap();
1739 assert!(manifest.contains("license-file = \"LICENSE\""));
1740 let orig =
1741 std::fs::read_to_string(p.root().join("target/package/foo-1.0.0/Cargo.toml.orig")).unwrap();
1742 assert!(orig.contains("license-file = \"../LICENSE\""));
1743}
1744
1745#[cargo_test]
1746fn relative_license_include_collision() {
1747 // Can't copy a relative license-file if there is a file with that name already.
1748 let p = project()
1749 .file(
1750 "Cargo.toml",
1751 r#"
1752 [package]
1753 name = "foo"
1754 version = "1.0.0"
1755 license-file = "../LICENSE"
1756 description = "foo"
1757 homepage = "foo"
1758 "#,
1759 )
1760 .file("src/lib.rs", "")
1761 .file("../LICENSE", "outer license")
1762 .file("LICENSE", "inner license")
1763 .build();
1764
1765 p.cargo("package --list")
1766 .with_stdout(
1767 "\
1768Cargo.toml
1769Cargo.toml.orig
1770LICENSE
1771src/lib.rs
1772",
1773 )
1774 .with_stderr("[WARNING] license-file `../LICENSE` appears to be [..]")
1775 .run();
1776
1777 p.cargo("package")
1778 .with_stderr(
1779 "\
1780[WARNING] license-file `../LICENSE` appears to be [..]
1781[PACKAGING] foo v1.0.0 [..]
1782[VERIFYING] foo v1.0.0 [..]
1783[COMPILING] foo v1.0.0 [..]
1784[FINISHED] [..]
1785",
1786 )
1787 .run();
1788 let f = File::open(&p.root().join("target/package/foo-1.0.0.crate")).unwrap();
1789 validate_crate_contents(
1790 f,
1791 "foo-1.0.0.crate",
1792 &["Cargo.toml", "Cargo.toml.orig", "LICENSE", "src/lib.rs"],
1793 &[("LICENSE", "inner license")],
1794 );
1795 let manifest = read_to_string(p.root().join("target/package/foo-1.0.0/Cargo.toml")).unwrap();
1796 assert!(manifest.contains("license-file = \"LICENSE\""));
1797 let orig = read_to_string(p.root().join("target/package/foo-1.0.0/Cargo.toml.orig")).unwrap();
1798 assert!(orig.contains("license-file = \"../LICENSE\""));
1799}
2a874aa5
EH
1800
1801#[cargo_test]
1802#[cfg(not(windows))] // Don't want to create invalid files on Windows.
1803fn package_restricted_windows() {
1804 let p = project()
1805 .file(
1806 "Cargo.toml",
1807 r#"
1808 [package]
1809 name = "foo"
1810 version = "0.1.0"
1811 license = "MIT"
1812 description = "foo"
1813 homepage = "foo"
1814 "#,
1815 )
1816 .file("src/lib.rs", "pub mod con;\npub mod aux;")
1817 .file("src/con.rs", "pub fn f() {}")
1818 .file("src/aux/mod.rs", "pub fn f() {}")
1819 .build();
1820
1821 p.cargo("package")
6fa0f01d
WL
1822 // use unordered here because the order of the warning is different on each platform.
1823 .with_stderr_unordered(
2a874aa5
EH
1824 "\
1825[WARNING] file src/aux/mod.rs is a reserved Windows filename, it will not work on Windows platforms
1826[WARNING] file src/con.rs is a reserved Windows filename, it will not work on Windows platforms
1827[PACKAGING] foo [..]
1828[VERIFYING] foo [..]
1829[COMPILING] foo [..]
1830[FINISHED] [..]
1831",
1832 )
1833 .run();
1834}
1232ad3c
EH
1835
1836#[cargo_test]
1837fn finds_git_in_parent() {
1838 // Test where `Cargo.toml` is not in the root of the git repo.
1839 let repo_path = paths::root().join("repo");
1840 fs::create_dir(&repo_path).unwrap();
1841 let p = project()
1842 .at("repo/foo")
1843 .file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
1844 .file("src/lib.rs", "")
1845 .build();
1846 let repo = git::init(&repo_path);
1847 git::add(&repo);
1848 git::commit(&repo);
1849 p.change_file("ignoreme", "");
1850 p.change_file("ignoreme2", "");
1851 p.cargo("package --list --allow-dirty")
1852 .with_stdout(
1853 "\
1854Cargo.toml
1855Cargo.toml.orig
1856ignoreme
1857ignoreme2
1858src/lib.rs
1859",
1860 )
1861 .run();
1862
1863 p.change_file(".gitignore", "ignoreme");
1864 p.cargo("package --list --allow-dirty")
1865 .with_stdout(
1866 "\
1867.gitignore
1868Cargo.toml
1869Cargo.toml.orig
1870ignoreme2
1871src/lib.rs
1872",
1873 )
1874 .run();
1875
1876 fs::write(repo_path.join(".gitignore"), "ignoreme2").unwrap();
1877 p.cargo("package --list --allow-dirty")
1878 .with_stdout(
1879 "\
1880.gitignore
1881Cargo.toml
1882Cargo.toml.orig
1883src/lib.rs
1884",
1885 )
1886 .run();
1887}
2c671115
HBA
1888
1889#[cargo_test]
1890#[cfg(windows)]
1891fn reserved_windows_name() {
1892 Package::new("bar", "1.0.0")
1893 .file("src/lib.rs", "pub mod aux;")
1894 .file("src/aux.rs", "")
1895 .publish();
1896
1897 let p = project()
1898 .file(
1899 "Cargo.toml",
1900 r#"
6f8c7d5a
EH
1901 [project]
1902 name = "foo"
1903 version = "0.0.1"
1904 authors = []
1905 license = "MIT"
1906 description = "foo"
2c671115 1907
6f8c7d5a
EH
1908 [dependencies]
1909 bar = "1.0.0"
1910 "#,
2c671115
HBA
1911 )
1912 .file("src/main.rs", "extern crate bar;\nfn main() { }")
1913 .build();
1914 p.cargo("package")
1915 .with_status(101)
1916 .with_stderr_contains(
1917 "\
1918error: failed to verify package tarball
1919
1920Caused by:
1921 failed to download replaced source registry `[..]`
1922
1923Caused by:
1924 failed to unpack package `[..] `[..]`)`
1925
1926Caused by:
1927 failed to unpack entry at `[..]aux.rs`
1928
1929Caused by:
1930 `[..]aux.rs` appears to contain a reserved Windows path, it cannot be extracted on Windows
1931
1932Caused by:
1933 failed to unpack `[..]aux.rs`
1934
1935Caused by:
1936 failed to unpack `[..]aux.rs` into `[..]aux.rs`",
1937 )
1938 .run();
1939}
156c6512
EH
1940
1941#[cargo_test]
1942fn list_with_path_and_lock() {
1943 // Allow --list even for something that isn't packageable.
1944
1945 // Init an empty registry because a versionless path dep will search for
1946 // the package on crates.io.
1947 registry::init();
1948 let p = project()
1949 .file(
1950 "Cargo.toml",
1951 r#"
1952 [package]
1953 name = "foo"
1954 version = "0.1.0"
1955 license = "MIT"
1956 description = "foo"
1957 homepage = "foo"
1958
1959 [dependencies]
1960 bar = {path="bar"}
1961 "#,
1962 )
1963 .file("src/main.rs", "fn main() {}")
1964 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
1965 .file("bar/src/lib.rs", "")
1966 .build();
1967
1968 p.cargo("package --list")
1969 .with_stdout(
1970 "\
1971Cargo.lock
1972Cargo.toml
1973Cargo.toml.orig
1974src/main.rs
1975",
1976 )
1977 .run();
1978
1979 p.cargo("package")
1980 .with_status(101)
1981 .with_stderr(
1982 "\
4e1910d9
B
1983[ERROR] all dependencies must have a version specified when packaging.
1984dependency `bar` does not specify a version
1985Note: The packaged dependency will use the version from crates.io,
1986the `path` specification will be removed from the dependency declaration.
156c6512
EH
1987",
1988 )
1989 .run();
1990}
0dfd4a88
MP
1991
1992#[cargo_test]
1993fn long_file_names() {
1994 // Filenames over 100 characters require a GNU extension tarfile.
1995 // See #8453.
1996
1997 registry::init();
1998 let long_name = concat!(
1999 "012345678901234567890123456789012345678901234567890123456789",
2000 "012345678901234567890123456789012345678901234567890123456789",
2001 "012345678901234567890123456789012345678901234567890123456789"
2002 );
35758d2c
EH
2003 if cfg!(windows) {
2004 // Long paths on Windows require a special registry entry that is
2005 // disabled by default (even on Windows 10).
2006 // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
2007 // If the directory where Cargo runs happens to be more than 80 characters
2008 // long, then it will bump into this limit.
2009 //
2010 // First create a directory to account for various paths Cargo will
2011 // be using in the target directory (such as "target/package/foo-0.1.0").
2012 let test_path = paths::root().join("test-dir-probe-long-path-support");
2013 test_path.mkdir_p();
2014 let test_path = test_path.join(long_name);
2015 if let Err(e) = File::create(&test_path) {
f23b9119
MK
2016 // write to stderr directly to avoid output from being captured
2017 // and always display text, even without --nocapture
35758d2c
EH
2018 use std::io::Write;
2019 writeln!(
2020 std::io::stderr(),
2021 "\nSkipping long_file_names test, this OS or filesystem does not \
2022 appear to support long file paths: {:?}\n{:?}",
2023 e,
2024 test_path
2025 )
2026 .unwrap();
2027 return;
2028 }
2029 }
2030
0dfd4a88
MP
2031 let p = project()
2032 .file(
2033 "Cargo.toml",
2034 r#"
2035 [package]
2036 name = "foo"
2037 version = "0.1.0"
2038 license = "MIT"
2039 description = "foo"
2040 homepage = "foo"
2041
2042 [dependencies]
2043 "#,
2044 )
2045 .file(long_name, "something")
2046 .file("src/main.rs", "fn main() {}")
2047 .build();
2048
2049 p.cargo("package").run();
2050 p.cargo("package --list")
2051 .with_stdout(&format!(
2052 "\
2053{}
2054Cargo.lock
2055Cargo.toml
2056Cargo.toml.orig
2057src/main.rs
2058",
2059 long_name
2060 ))
2061 .run();
2062}
e46ca84b 2063
2064#[cargo_test]
2065fn reproducible_output() {
2066 let p = project()
2067 .file(
2068 "Cargo.toml",
2069 r#"
2070 [project]
2071 name = "foo"
2072 version = "0.0.1"
2073 authors = []
2074 exclude = ["*.txt"]
2075 license = "MIT"
2076 description = "foo"
2077 "#,
2078 )
2079 .file("src/main.rs", r#"fn main() { println!("hello"); }"#)
2080 .build();
2081
449ead05 2082 p.cargo("package").run();
e46ca84b 2083 assert!(p.root().join("target/package/foo-0.0.1.crate").is_file());
2084
2085 let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap();
2086 let decoder = GzDecoder::new(f);
2087 let mut archive = Archive::new(decoder);
2088 for ent in archive.entries().unwrap() {
2089 let ent = ent.unwrap();
a02b6e5b 2090 println!("checking {:?}", ent.path());
e46ca84b 2091 let header = ent.header();
2092 assert_eq!(header.mode().unwrap(), 0o644);
a02b6e5b 2093 assert!(header.mtime().unwrap() != 0);
449ead05 2094 assert_eq!(header.username().unwrap().unwrap(), "");
2095 assert_eq!(header.groupname().unwrap().unwrap(), "");
e46ca84b 2096 }
2097}
6bc74556
AC
2098
2099#[cargo_test]
2100fn package_with_resolver_and_metadata() {
2101 let p = project()
2102 .file(
2103 "Cargo.toml",
2104 r#"
2105 [package]
2106 name = "foo"
2107 version = "0.0.1"
2108 authors = []
2109 resolver = '2'
2110
2111 [package.metadata.docs.rs]
2112 all-features = true
2113 "#,
2114 )
2115 .file("src/lib.rs", "")
2116 .build();
2117
2118 p.cargo("package").run();
2119}
97a13504
EH
2120
2121#[cargo_test]
2122fn deleted_git_working_tree() {
2123 // When deleting a file, but not staged, cargo should ignore the file.
2124 let (p, repo) = git::new_repo("foo", |p| {
2125 p.file("src/lib.rs", "").file("src/main.rs", "fn main() {}")
2126 });
2127 p.root().join("src/lib.rs").rm_rf();
2128 p.cargo("package --allow-dirty --list")
2129 .with_stdout(
2130 "\
2131Cargo.lock
2132Cargo.toml
2133Cargo.toml.orig
2134src/main.rs
2135",
2136 )
2137 .run();
2138 p.cargo("package --allow-dirty").run();
2139 let mut index = t!(repo.index());
2140 t!(index.remove(Path::new("src/lib.rs"), 0));
2141 t!(index.write());
2142 p.cargo("package --allow-dirty --list")
2143 .with_stdout(
2144 "\
2145Cargo.lock
2146Cargo.toml
2147Cargo.toml.orig
2148src/main.rs
2149",
2150 )
2151 .run();
2152 p.cargo("package --allow-dirty").run();
2153}
8f1f0e40 2154
2155#[cargo_test]
2156fn in_workspace() {
2157 let p = project()
2158 .file(
2159 "Cargo.toml",
2160 r#"
2161 [project]
2162 name = "foo"
2163 version = "0.0.1"
2164 authors = []
2165 license = "MIT"
2166 description = "foo"
2167
2168 [workspace]
2169 members = ["bar"]
2170 "#,
2171 )
2172 .file("src/main.rs", "fn main() {}")
2173 .file(
2174 "bar/Cargo.toml",
2175 r#"
2176 [project]
2177 name = "bar"
2178 version = "0.0.1"
2179 authors = []
2180 license = "MIT"
2181 description = "bar"
2182 workspace = ".."
2183 "#,
2184 )
2185 .file("bar/src/main.rs", "fn main() {}")
2186 .build();
2187
2188 p.cargo("package --workspace")
2189 .with_stderr(
2190 "\
2191[WARNING] manifest has no documentation, [..]
2192See [..]
2193[PACKAGING] bar v0.0.1 ([CWD]/bar)
2194[VERIFYING] bar v0.0.1 ([CWD]/bar)
2195[COMPILING] bar v0.0.1 ([CWD][..])
2196[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2197[WARNING] manifest has no documentation, [..]
2198See [..]
2199[PACKAGING] foo v0.0.1 ([CWD])
2200[VERIFYING] foo v0.0.1 ([CWD])
2201[COMPILING] foo v0.0.1 ([CWD][..])
2202[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2203",
2204 )
2205 .run();
2206
2207 assert!(p.root().join("target/package/foo-0.0.1.crate").is_file());
2208 assert!(p.root().join("target/package/bar-0.0.1.crate").is_file());
2209}