cargo_emit/rerun_if_changed.rs
1/// Tells Cargo to run again if the file or directory at `$path` changes.
2///
3/// This is equivalent to:
4///
5/// ```
6/// println!("cargo:rerun-if-changed=$path");
7/// ```
8///
9/// `$path` is a path to a file or directory which indicates that the build
10/// script should be re-run if it changes (detected by a more-recent
11/// last-modified timestamp on the file). Normally build scripts are re-run if
12/// any file inside the crate root changes, but this can be used to scope
13/// changes to just a small set of files. (If this path points to a directory
14/// the entire directory will not be traversed for changes -- only changes to
15/// the timestamp of the directory itself (which corresponds to some types of
16/// changes within the directory, depending on platform) will trigger a rebuild.
17/// To request a re-run on any changes within an entire directory, print a line
18/// for the directory and another line for everything inside it, recursively.)
19/// Note that if the build script itself (or one of its dependencies) changes,
20/// then it's rebuilt and rerun unconditionally, so
21/// `rerun_if_changed!("build.rs")` is almost always redundant (unless you want
22/// to ignore changes in all other files except for `build.rs`).
23///
24/// # Examples
25///
26/// This is useful for tracking build-dependent files that Cargo does not
27/// already know.
28///
29/// ```
30/// cargo_emit::rerun_if_changed!(
31/// "/path/to/resource1",
32/// "/path/to/resource2",
33/// );
34/// ```
35///
36/// or, in case you want it to emit to a custom stream:
37///
38/// ```
39/// let mut stdout = std::io::stdout();
40/// // ..
41/// cargo_emit::rerun_if_changed!(
42/// to: stdout,
43/// "/path/to/resource1",
44/// "/path/to/resource2",
45/// );
46/// ```
47#[macro_export]
48macro_rules! rerun_if_changed {
49 (to: $stream:expr, $($path:expr),+ $(,)?) => {
50 $($crate::pair!(to: $stream, "rerun-if-changed", "{}", $path);)+
51 };
52 ($($path:expr),+ $(,)?) => {
53 $crate::rerun_if_changed!(to: std::io::stdout(), $($path),+);
54 };
55}
56
57#[cfg(test)]
58mod tests {
59 use std::path::PathBuf;
60
61 #[test]
62 fn single_literal() {
63 insta::assert_display_snapshot!(
64 crate::capture_output(|output| {
65 crate::rerun_if_changed!(
66 to: output,
67 "/path/to/resource"
68 );
69 }),
70 @"cargo:rerun-if-changed=/path/to/resource\n"
71 );
72 }
73
74 #[test]
75 fn single_expression() {
76 insta::assert_display_snapshot!(
77 crate::capture_output(|output| {
78 crate::rerun_if_changed!(
79 to: output,
80 PathBuf::from("/path/to/resource").display()
81 );
82 }),
83 @"cargo:rerun-if-changed=/path/to/resource\n"
84 );
85 }
86
87 #[test]
88 fn multiple_literals() {
89 insta::assert_display_snapshot!(
90 crate::capture_output(|output| {
91 crate::rerun_if_changed!(
92 to: output,
93 "/path/to/resource1",
94 "/path/to/resource2",
95 "/path/to/resource3",
96 "/path/to/resource4",
97 );
98 }),
99 @"cargo:rerun-if-changed=/path/to/resource1\n\
100 cargo:rerun-if-changed=/path/to/resource2\n\
101 cargo:rerun-if-changed=/path/to/resource3\n\
102 cargo:rerun-if-changed=/path/to/resource4\n"
103 );
104 }
105
106 #[test]
107 fn multiple_expressions() {
108 insta::assert_display_snapshot!(
109 crate::capture_output(|output| {
110 crate::rerun_if_changed!(
111 to: output,
112 PathBuf::from("/path/to/resource1").display(),
113 PathBuf::from("/path/to/resource2").display(),
114 PathBuf::from("/path/to/resource3").display(),
115 PathBuf::from("/path/to/resource4").display(),
116 );
117 }),
118 @"cargo:rerun-if-changed=/path/to/resource1\n\
119 cargo:rerun-if-changed=/path/to/resource2\n\
120 cargo:rerun-if-changed=/path/to/resource3\n\
121 cargo:rerun-if-changed=/path/to/resource4\n"
122 );
123 }
124
125 #[test]
126 fn multiple_mixed() {
127 insta::assert_display_snapshot!(
128 crate::capture_output(|output| {
129 crate::rerun_if_changed!(
130 to: output,
131 "/path/to/resource1",
132 PathBuf::from("/path/to/resource2").display(),
133 "/path/to/resource3",
134 PathBuf::from("/path/to/resource4").display(),
135 );
136 }),
137 @"cargo:rerun-if-changed=/path/to/resource1\n\
138 cargo:rerun-if-changed=/path/to/resource2\n\
139 cargo:rerun-if-changed=/path/to/resource3\n\
140 cargo:rerun-if-changed=/path/to/resource4\n"
141 );
142 }
143}