3333
3434 .. versionadded:: 0.4.0
3535
36+ .. option:: -w, --watch
37+
38+ Watch file for changes. Requires the second argument (output CSS
39+ filename).
40+
41+ .. versionadded:: 0.4.0
42+
3643.. option:: -v, --version
3744
3845 Prints the program version.
4855
4956import functools
5057import optparse
58+ import os
5159import sys
60+ import time
5261
5362from sass import __version__ as VERSION , OUTPUT_STYLES , CompileError , compile
5463
@@ -74,6 +83,9 @@ def main(argv=sys.argv, stdout=sys.stdout, stderr=sys.stderr):
7483 'Can be multiply used.' )
7584 parser .add_option ('-i' , '--image-path' , metavar = 'DIR' , default = './' ,
7685 help = 'Path to find images. [default: %default]' )
86+ parser .add_option ('-w' , '--watch' , action = 'store_true' ,
87+ help = 'Watch file for changes. Requires the second '
88+ 'argument (output css filename).' )
7789 options , args = parser .parse_args (argv [1 :])
7890 error = functools .partial (print ,
7991 parser .get_prog_name () + ': error:' ,
@@ -92,39 +104,69 @@ def main(argv=sys.argv, stdout=sys.stdout, stderr=sys.stderr):
92104 error ('-m/-g/--sourcemap requires the second argument, the output '
93105 'css filename.' )
94106 return 2
95- try :
96- if options .source_map :
97- source_map_filename = args [1 ] + '.map' # FIXME
98- css , source_map = compile (
99- filename = filename ,
100- output_style = options .output_style ,
101- source_comments = 'map' ,
102- source_map_filename = source_map_filename ,
103- include_paths = options .include_paths ,
104- image_path = options .image_path
105- )
106- else :
107- source_map_filename = None
108- source_map = None
109- css = compile (
110- filename = filename ,
111- output_style = options .output_style ,
112- include_paths = options .include_paths ,
113- image_path = options .image_path
114- )
115- except CompileError as e :
116- print (parser .get_prog_name () + ': error:' , e ,
117- file = stderr )
118- return 1
107+ elif options .watch and len (args ) < 2 :
108+ parser .print_usage (stderr )
109+ error ('-w/--watch requires the second argument, the output css '
110+ 'filename.' )
111+ return 2
119112 else :
120- if len (args ) < 2 :
121- print (css , file = stdout )
113+ pass
114+ while True :
115+ try :
116+ if options .source_map :
117+ source_map_filename = args [1 ] + '.map' # FIXME
118+ css , source_map = compile (
119+ filename = filename ,
120+ output_style = options .output_style ,
121+ source_comments = 'map' ,
122+ source_map_filename = source_map_filename ,
123+ include_paths = options .include_paths ,
124+ image_path = options .image_path
125+ )
126+ else :
127+ source_map_filename = None
128+ source_map = None
129+ css = compile (
130+ filename = filename ,
131+ output_style = options .output_style ,
132+ include_paths = options .include_paths ,
133+ image_path = options .image_path
134+ )
135+ mtime = os .stat (filename ).st_mtime
136+ except (IOError , OSError ) as e :
137+ error (e )
138+ return 3
139+ except CompileError as e :
140+ error (e )
141+ if not options .watch :
142+ return 1
143+ except KeyboardInterrupt :
144+ break
145+ else :
146+ if len (args ) < 2 :
147+ print (css , file = stdout )
148+ else :
149+ with open (args [1 ], 'w' ) as f :
150+ print (css , file = f )
151+ if options .watch :
152+ print (filename , 'is just compiled to' , args [1 ],
153+ file = stdout )
154+ if source_map_filename :
155+ with open (source_map_filename , 'w' ) as f :
156+ f .write (source_map )
157+ if options .watch :
158+ # FIXME: we should utilize inotify on Linux, and FSEvents on Mac
159+ while True :
160+ try :
161+ st = os .stat (filename )
162+ if st .st_mtime > mtime :
163+ print (filename , 'changed; recompile...' , file = stdout )
164+ break
165+ time .sleep (0.5 )
166+ except KeyboardInterrupt :
167+ return 0
122168 else :
123- with open (args [1 ], 'w' ) as f :
124- print (css , file = f )
125- if source_map_filename :
126- with open (source_map_filename , 'w' ) as f :
127- f .write (source_map )
169+ break
128170 return 0
129171
130172
0 commit comments