@@ -2,6 +2,70 @@ use anyhow::{Context as _, Error, Result};
22use git2:: Repository ;
33use std:: { env, path:: Path } ;
44
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+
569fn main ( ) -> Result < ( ) > {
670 let out_dir = env:: var ( "OUT_DIR" ) . context ( "missing OUT_DIR" ) ?;
771 let out_dir = Path :: new ( & out_dir) ;
@@ -22,10 +86,6 @@ fn write_git_version(out_dir: &Path) -> Result<()> {
2286 format ! ( "({} {})" , git_hash, build_date) ,
2387 ) ?;
2488
25- // TODO: are these right?
26- println ! ( "cargo:rerun-if-changed=.git/HEAD" ) ;
27- println ! ( "cargo:rerun-if-changed=.git/index" ) ;
28-
2989 Ok ( ( ) )
3090}
3191
@@ -34,6 +94,10 @@ fn get_git_hash() -> Result<Option<String>> {
3494 Ok ( repo) => {
3595 let head = repo. head ( ) ?;
3696
97+ // TODO: are these right?
98+ tracked:: track ( ".git/HEAD" ) ?;
99+ tracked:: track ( ".git/index" ) ?;
100+
37101 Ok ( head. target ( ) . map ( |h| {
38102 let mut h = format ! ( "{}" , h) ;
39103 h. truncate ( 7 ) ;
@@ -51,7 +115,9 @@ fn compile_sass_file(src: &Path, dest: &Path) -> Result<()> {
51115 let css = grass:: from_path (
52116 src. to_str ( )
53117 . 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 ) ,
55121 )
56122 . map_err ( |e| Error :: msg ( e. to_string ( ) ) ) ?;
57123
@@ -65,29 +131,27 @@ fn compile_sass(out_dir: &Path) -> Result<()> {
65131
66132 for entry in walkdir:: WalkDir :: new ( STYLE_DIR ) {
67133 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 ( )
72139 . 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+ }
83149 }
84150 }
85151
86152 // 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" ) ?;
91155 let vendored = pure + & grids;
92156 std:: fs:: write ( out_dir. join ( "vendored" ) . with_extension ( "css" ) , vendored) ?;
93157
0 commit comments