cargo_emit/
rerun_if_changed.rs

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

#[cfg(test)]
mod tests {
    use std::path::PathBuf;

    #[test]
    fn single_literal() {
        insta::assert_display_snapshot!(
            crate::capture_output(|output| {
                crate::rerun_if_changed!(
                    to: output,
                    "/path/to/resource"
                );
            }),
            @"cargo:rerun-if-changed=/path/to/resource\n"
        );
    }

    #[test]
    fn single_expression() {
        insta::assert_display_snapshot!(
            crate::capture_output(|output| {
                crate::rerun_if_changed!(
                    to: output,
                    PathBuf::from("/path/to/resource").display()
                );
            }),
            @"cargo:rerun-if-changed=/path/to/resource\n"
        );
    }

    #[test]
    fn multiple_literals() {
        insta::assert_display_snapshot!(
            crate::capture_output(|output| {
                crate::rerun_if_changed!(
                    to: output,
                    "/path/to/resource1",
                    "/path/to/resource2",
                    "/path/to/resource3",
                    "/path/to/resource4",
                );
            }),
            @"cargo:rerun-if-changed=/path/to/resource1\n\
              cargo:rerun-if-changed=/path/to/resource2\n\
              cargo:rerun-if-changed=/path/to/resource3\n\
              cargo:rerun-if-changed=/path/to/resource4\n"
        );
    }

    #[test]
    fn multiple_expressions() {
        insta::assert_display_snapshot!(
            crate::capture_output(|output| {
                crate::rerun_if_changed!(
                    to: output,
                    PathBuf::from("/path/to/resource1").display(),
                    PathBuf::from("/path/to/resource2").display(),
                    PathBuf::from("/path/to/resource3").display(),
                    PathBuf::from("/path/to/resource4").display(),
                );
            }),
            @"cargo:rerun-if-changed=/path/to/resource1\n\
              cargo:rerun-if-changed=/path/to/resource2\n\
              cargo:rerun-if-changed=/path/to/resource3\n\
              cargo:rerun-if-changed=/path/to/resource4\n"
        );
    }

    #[test]
    fn multiple_mixed() {
        insta::assert_display_snapshot!(
            crate::capture_output(|output| {
                crate::rerun_if_changed!(
                    to: output,
                    "/path/to/resource1",
                    PathBuf::from("/path/to/resource2").display(),
                    "/path/to/resource3",
                    PathBuf::from("/path/to/resource4").display(),
                );
            }),
            @"cargo:rerun-if-changed=/path/to/resource1\n\
              cargo:rerun-if-changed=/path/to/resource2\n\
              cargo:rerun-if-changed=/path/to/resource3\n\
              cargo:rerun-if-changed=/path/to/resource4\n"
        );
    }
}