@@ -2,6 +2,70 @@ use anyhow::{Context as _, Error, Result};
2
2
use git2:: Repository ;
3
3
use std:: { env, path:: Path } ;
4
4
5
+ mod tracked {
6
+ use once_cell:: sync:: Lazy ;
7
+ use std:: {
8
+ collections:: HashSet ,
9
+ io:: { Error , ErrorKind , Result } ,
10
+ path:: { Path , PathBuf } ,
11
+ sync:: Mutex ,
12
+ } ;
13
+
14
+ static SEEN : Lazy < Mutex < HashSet < PathBuf > > > = Lazy :: new ( || Mutex :: new ( HashSet :: new ( ) ) ) ;
15
+
16
+ pub ( crate ) fn track ( path : impl AsRef < Path > ) -> Result < ( ) > {
17
+ let path = path. as_ref ( ) ;
18
+ if path. exists ( ) {
19
+ let mut seen = SEEN . lock ( ) . unwrap ( ) ;
20
+ // TODO: Needs something like `HashSet::insert_owned` to check before cloning
21
+ // https://github.com/rust-lang/rust/issues/60896
22
+ if !seen. contains ( path) {
23
+ seen. insert ( path. to_owned ( ) ) ;
24
+ let path = path. to_str ( ) . ok_or_else ( || {
25
+ Error :: new (
26
+ ErrorKind :: Other ,
27
+ format ! ( "{} is a non-utf-8 path" , path. display( ) ) ,
28
+ )
29
+ } ) ?;
30
+ println ! ( "cargo:rerun-if-changed={path}" ) ;
31
+ }
32
+ } else if let Some ( parent) = path. parent ( ) {
33
+ // if the file doesn't exist, we need to notice if it begins existing
34
+ track ( parent) ?;
35
+ }
36
+ Ok ( ( ) )
37
+ }
38
+
39
+ pub ( crate ) fn read ( path : impl AsRef < Path > ) -> Result < Vec < u8 > > {
40
+ let path = path. as_ref ( ) ;
41
+ track ( path) ?;
42
+ std:: fs:: read ( path)
43
+ }
44
+
45
+ pub ( crate ) fn read_to_string ( path : impl AsRef < Path > ) -> Result < String > {
46
+ let path = path. as_ref ( ) ;
47
+ track ( path) ?;
48
+ std:: fs:: read_to_string ( path)
49
+ }
50
+
51
+ #[ derive( Debug ) ]
52
+ pub ( crate ) struct Fs ;
53
+
54
+ impl grass:: Fs for Fs {
55
+ fn is_dir ( & self , path : & Path ) -> bool {
56
+ track ( path) . unwrap ( ) ;
57
+ path. is_dir ( )
58
+ }
59
+ fn is_file ( & self , path : & Path ) -> bool {
60
+ track ( path) . unwrap ( ) ;
61
+ path. is_file ( )
62
+ }
63
+ fn read ( & self , path : & Path ) -> Result < Vec < u8 > > {
64
+ read ( path)
65
+ }
66
+ }
67
+ }
68
+
5
69
fn main ( ) -> Result < ( ) > {
6
70
let out_dir = env:: var ( "OUT_DIR" ) . context ( "missing OUT_DIR" ) ?;
7
71
let out_dir = Path :: new ( & out_dir) ;
@@ -22,10 +86,6 @@ fn write_git_version(out_dir: &Path) -> Result<()> {
22
86
format ! ( "({} {})" , git_hash, build_date) ,
23
87
) ?;
24
88
25
- // TODO: are these right?
26
- println ! ( "cargo:rerun-if-changed=.git/HEAD" ) ;
27
- println ! ( "cargo:rerun-if-changed=.git/index" ) ;
28
-
29
89
Ok ( ( ) )
30
90
}
31
91
@@ -34,6 +94,10 @@ fn get_git_hash() -> Result<Option<String>> {
34
94
Ok ( repo) => {
35
95
let head = repo. head ( ) ?;
36
96
97
+ // TODO: are these right?
98
+ tracked:: track ( ".git/HEAD" ) ?;
99
+ tracked:: track ( ".git/index" ) ?;
100
+
37
101
Ok ( head. target ( ) . map ( |h| {
38
102
let mut h = format ! ( "{}" , h) ;
39
103
h. truncate ( 7 ) ;
@@ -51,7 +115,9 @@ fn compile_sass_file(src: &Path, dest: &Path) -> Result<()> {
51
115
let css = grass:: from_path (
52
116
src. to_str ( )
53
117
. context ( "source file path must be a utf-8 string" ) ?,
54
- & grass:: Options :: default ( ) . style ( grass:: OutputStyle :: Compressed ) ,
118
+ & grass:: Options :: default ( )
119
+ . fs ( & tracked:: Fs )
120
+ . style ( grass:: OutputStyle :: Compressed ) ,
55
121
)
56
122
. map_err ( |e| Error :: msg ( e. to_string ( ) ) ) ?;
57
123
@@ -65,29 +131,27 @@ fn compile_sass(out_dir: &Path) -> Result<()> {
65
131
66
132
for entry in walkdir:: WalkDir :: new ( STYLE_DIR ) {
67
133
let entry = entry?;
68
- println ! (
69
- "cargo:rerun-if-changed={}" ,
70
- entry
71
- . path( )
134
+ if entry. metadata ( ) ?. is_dir ( ) {
135
+ tracked:: track ( entry. path ( ) ) ?;
136
+ } else {
137
+ let file_name = entry
138
+ . file_name ( )
72
139
. to_str ( )
73
- . with_context( || format!( "{} is a non-utf-8 path" , entry. path( ) . display( ) ) ) ?
74
- ) ;
75
- let file_name = entry. file_name ( ) . to_str ( ) . unwrap ( ) ;
76
- if entry. metadata ( ) ?. is_file ( ) && !file_name. starts_with ( '_' ) {
77
- let dest = out_dir
78
- . join ( entry. path ( ) . strip_prefix ( STYLE_DIR ) ?)
79
- . with_extension ( "css" ) ;
80
- compile_sass_file ( entry. path ( ) , & dest) . with_context ( || {
81
- format ! ( "compiling {} to {}" , entry. path( ) . display( ) , dest. display( ) )
82
- } ) ?;
140
+ . context ( "file name must be a utf-8 string" ) ?;
141
+ if !file_name. starts_with ( '_' ) {
142
+ let dest = out_dir
143
+ . join ( entry. path ( ) . strip_prefix ( STYLE_DIR ) ?)
144
+ . with_extension ( "css" ) ;
145
+ compile_sass_file ( entry. path ( ) , & dest) . with_context ( || {
146
+ format ! ( "compiling {} to {}" , entry. path( ) . display( ) , dest. display( ) )
147
+ } ) ?;
148
+ }
83
149
}
84
150
}
85
151
86
152
// Compile vendored.css
87
- println ! ( "cargo:rerun-if-changed=vendor/pure-css/css/pure-min.css" ) ;
88
- let pure = std:: fs:: read_to_string ( "vendor/pure-css/css/pure-min.css" ) ?;
89
- println ! ( "cargo:rerun-if-changed=vendor/pure-css/css/grids-responsive-min.css" ) ;
90
- let grids = std:: fs:: read_to_string ( "vendor/pure-css/css/grids-responsive-min.css" ) ?;
153
+ let pure = tracked:: read_to_string ( "vendor/pure-css/css/pure-min.css" ) ?;
154
+ let grids = tracked:: read_to_string ( "vendor/pure-css/css/grids-responsive-min.css" ) ?;
91
155
let vendored = pure + & grids;
92
156
std:: fs:: write ( out_dir. join ( "vendored" ) . with_extension ( "css" ) , vendored) ?;
93
157
0 commit comments