]>
Commit | Line | Data |
---|---|---|
83571aee EH |
1 | //! Tests for the `cargo package` command. |
2 | ||
9115b2c3 | 3 | use cargo_test_support::paths::CargoPathExt; |
156c6512 EH |
4 | use cargo_test_support::publish::validate_crate_contents; |
5 | use cargo_test_support::registry::{self, Package}; | |
9115b2c3 | 6 | use cargo_test_support::{ |
156c6512 | 7 | basic_manifest, cargo_process, git, path2url, paths, project, symlink_supported, t, |
3d84d0ad | 8 | }; |
e46ca84b | 9 | use flate2::read::GzDecoder; |
1232ad3c | 10 | use std::fs::{self, read_to_string, File}; |
4ae79d2f | 11 | use std::path::Path; |
e46ca84b | 12 | use tar::Archive; |
69c16fc6 | 13 | |
0e0d9688 | 14 | #[cargo_test] |
6950bbb0 | 15 | fn 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 | 37 | See [..] |
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 | 49 | Cargo.lock |
229e1e43 | 50 | Cargo.toml |
90887707 | 51 | Cargo.toml.orig |
05400b80 | 52 | src/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 | 68 | fn 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 | 73 | warning: manifest has no description, license, license-file, documentation, \ |
32275465 | 74 | homepage or repository. |
0c3851c0 | 75 | See 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 | 100 | warning: manifest has no description, documentation, homepage or repository. |
0c3851c0 | 101 | See 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 | 138 | fn 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 | 154 | See 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 | 195 | See 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 | 230 | fn 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 | 237 | See 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 |
248 | fn 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 |
280 | in package source |
281 | ", | |
fecb7246 AC |
282 | ) |
283 | .run(); | |
ab787720 DK |
284 | } |
285 | ||
0e0d9688 | 286 | #[cargo_test] |
4f01c02a | 287 | fn 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 | 313 | See 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. |
315 | dependency `bar` does not specify a version\n\ | |
316 | Note: The packaged dependency will use the version from crates.io, | |
317 | the `path` specification will be removed from the dependency declaration. | |
318 | ", | |
319 | ) | |
320 | .run(); | |
321 | } | |
322 | ||
323 | #[cargo_test] | |
324 | fn 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. | |
350 | See 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. | |
352 | dependency `foo` does not specify a version | |
353 | Note: The packaged dependency will use the version from crates.io, | |
354 | the `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 | 361 | fn 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 | 435 | See 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 | 463 | Cargo.lock |
c072ba42 | 464 | Cargo.toml |
90887707 | 465 | Cargo.toml.orig |
c072ba42 BE |
466 | file_root_3 |
467 | file_root_4 | |
468 | file_root_5 | |
05400b80 | 469 | some_dir/dir_deep_2/some_dir/file |
05400b80 DW |
470 | some_dir/dir_deep_4/some_dir/file |
471 | some_dir/dir_deep_5/some_dir/file | |
05400b80 DW |
472 | some_dir/file_deep_2 |
473 | some_dir/file_deep_3 | |
474 | some_dir/file_deep_4 | |
475 | some_dir/file_deep_5 | |
476 | src/main.rs | |
1e682848 | 477 | ", |
fecb7246 AC |
478 | ) |
479 | .run(); | |
6950bbb0 | 480 | } |
5935ec1d | 481 | |
0e0d9688 | 482 | #[cargo_test] |
6950bbb0 | 483 | fn 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 | 509 | See 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 | 525 | fn 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 | 535 | fn 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 | 581 | fn 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 | 625 | fn 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 | 632 | Cargo.lock |
e2cd4cdb | 633 | Cargo.toml |
90887707 | 634 | Cargo.toml.orig |
e2cd4cdb | 635 | src/main.rs |
1e682848 | 636 | ", |
fecb7246 AC |
637 | ) |
638 | .run(); | |
6950bbb0 | 639 | } |
e2cd4cdb | 640 | |
0e0d9688 | 641 | #[cargo_test] |
6950bbb0 | 642 | fn 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 | 667 | See 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 | 679 | Cargo.lock |
d33da549 | 680 | Cargo.toml |
90887707 EH |
681 | Cargo.toml.orig |
682 | src/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 | 700 | fn 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 | 710 | warning: [..] |
32275465 | 711 | See [..] |
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 | 719 | fn 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 | 734 | See [..] |
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 | 764 | fn 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 | |
799 | Caused by: | |
d92dceae | 800 | failed to open for archiving: `[..]foo.rs` |
77812987 AC |
801 | |
802 | Caused 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 | 814 | fn 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. | |
834 | fn 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 | 851 | fn 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 |
892 | error: 1 files in the working directory contain changes that were not yet \ |
893 | committed into git: | |
ee32e105 BBT |
894 | |
895 | Cargo.toml | |
896 | ||
34f2d471 | 897 | to 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] |
904 | fn 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 | "\ | |
929 | error: 1 files in the working directory contain changes that were not yet committed into git: | |
930 | ||
931 | src/build/mod.rs | |
932 | ||
933 | to 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 | |
947 | Cargo.toml | |
948 | Cargo.toml.orig | |
949 | src/build/mod.rs | |
950 | src/lib.rs | |
951 | ", | |
952 | ) | |
953 | .run(); | |
954 | } | |
955 | ||
0e0d9688 | 956 | #[cargo_test] |
57db8bde | 957 | fn 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] |
999 | name = "foo" | |
1000 | version = "0.0.1" | |
1001 | authors = [] | |
1002 | exclude = ["*.txt"] | |
1003 | description = "foo" | |
1004 | license = "MIT" | |
0c704f8d AC |
1005 | |
1006 | [package.metadata] | |
1007 | foo = "bar" | |
f38c53f5 SS |
1008 | [dependencies.abc] |
1009 | version = "1.0" | |
1010 | ||
57db8bde AC |
1011 | [dependencies.bar] |
1012 | version = "0.1" | |
f38c53f5 SS |
1013 | |
1014 | [dependencies.def] | |
1015 | version = "1.0" | |
c40d1836 | 1016 | registry-index = "{}" |
f38c53f5 SS |
1017 | |
1018 | [dependencies.ghi] | |
1019 | version = "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 | 1034 | fn 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] |
1071 | name = "bar" | |
1072 | version = "0.1.0" | |
1073 | authors = [] | |
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 |
1086 | fn 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 | 1110 | fn 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 | 1137 | fn 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 | 1159 | fn 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 |
1178 | error: failed to parse manifest at `[..]` |
1179 | ||
1180 | Caused by: | |
84130089 AC |
1181 | failed to parse the `edition` key |
1182 | ||
1183 | Caused 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] |
1192 | fn 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 | "\ | |
1210 | error: failed to parse manifest at `[..]` | |
1211 | ||
1212 | Caused by: | |
1213 | failed to parse the `edition` key | |
1214 | ||
1215 | Caused 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 | 1224 | fn 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 |
1251 | error: failed to verify package tarball |
1252 | ||
1253 | Caused 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 |
1270 | fn 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 |
1299 | fn 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 |
1328 | fn 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 |
1360 | fn 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 | 1379 | fn 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 |
1412 | fn 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 |
1433 | fn 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 |
1527 | fn 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] | |
1575 | fn 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] | |
1600 | fn 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`). | |
1621 | Please update the license-file setting in the manifest at `[..]/foo/Cargo.toml` | |
1622 | This 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] | |
1630 | fn 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 | |
1653 | Cargo.toml | |
1654 | Cargo.toml.orig | |
1655 | src/lib.rs | |
1656 | subdir/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] | |
1690 | fn 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 | "\ | |
1711 | Cargo.toml | |
1712 | Cargo.toml.orig | |
1713 | LICENSE | |
1714 | src/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] | |
1746 | fn 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 | "\ | |
1768 | Cargo.toml | |
1769 | Cargo.toml.orig | |
1770 | LICENSE | |
1771 | src/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. | |
1803 | fn 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] | |
1837 | fn 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 | "\ | |
1854 | Cargo.toml | |
1855 | Cargo.toml.orig | |
1856 | ignoreme | |
1857 | ignoreme2 | |
1858 | src/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 | |
1868 | Cargo.toml | |
1869 | Cargo.toml.orig | |
1870 | ignoreme2 | |
1871 | src/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 | |
1881 | Cargo.toml | |
1882 | Cargo.toml.orig | |
1883 | src/lib.rs | |
1884 | ", | |
1885 | ) | |
1886 | .run(); | |
1887 | } | |
2c671115 HBA |
1888 | |
1889 | #[cargo_test] | |
1890 | #[cfg(windows)] | |
1891 | fn 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 | "\ | |
1918 | error: failed to verify package tarball | |
1919 | ||
1920 | Caused by: | |
1921 | failed to download replaced source registry `[..]` | |
1922 | ||
1923 | Caused by: | |
1924 | failed to unpack package `[..] `[..]`)` | |
1925 | ||
1926 | Caused by: | |
1927 | failed to unpack entry at `[..]aux.rs` | |
1928 | ||
1929 | Caused by: | |
1930 | `[..]aux.rs` appears to contain a reserved Windows path, it cannot be extracted on Windows | |
1931 | ||
1932 | Caused by: | |
1933 | failed to unpack `[..]aux.rs` | |
1934 | ||
1935 | Caused by: | |
1936 | failed to unpack `[..]aux.rs` into `[..]aux.rs`", | |
1937 | ) | |
1938 | .run(); | |
1939 | } | |
156c6512 EH |
1940 | |
1941 | #[cargo_test] | |
1942 | fn 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 | "\ | |
1971 | Cargo.lock | |
1972 | Cargo.toml | |
1973 | Cargo.toml.orig | |
1974 | src/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. |
1984 | dependency `bar` does not specify a version | |
1985 | Note: The packaged dependency will use the version from crates.io, | |
1986 | the `path` specification will be removed from the dependency declaration. | |
156c6512 EH |
1987 | ", |
1988 | ) | |
1989 | .run(); | |
1990 | } | |
0dfd4a88 MP |
1991 | |
1992 | #[cargo_test] | |
1993 | fn 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 | {} | |
2054 | Cargo.lock | |
2055 | Cargo.toml | |
2056 | Cargo.toml.orig | |
2057 | src/main.rs | |
2058 | ", | |
2059 | long_name | |
2060 | )) | |
2061 | .run(); | |
2062 | } | |
e46ca84b | 2063 | |
2064 | #[cargo_test] | |
2065 | fn 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] | |
2100 | fn 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] | |
2122 | fn 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 | "\ | |
2131 | Cargo.lock | |
2132 | Cargo.toml | |
2133 | Cargo.toml.orig | |
2134 | src/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 | "\ | |
2145 | Cargo.lock | |
2146 | Cargo.toml | |
2147 | Cargo.toml.orig | |
2148 | src/main.rs | |
2149 | ", | |
2150 | ) | |
2151 | .run(); | |
2152 | p.cargo("package --allow-dirty").run(); | |
2153 | } | |
8f1f0e40 | 2154 | |
2155 | #[cargo_test] | |
2156 | fn 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, [..] | |
2192 | See [..] | |
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, [..] | |
2198 | See [..] | |
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 | } |