#! /usr/bin/python3 # # Run sassc and watch for changes in source files (using inotitfy) to rebuild # automatically. # # Usage: sassw INPUT # (output will automatically be INPUT with .scss changed to .css) import json import glob import os import pyinotify import subprocess import sys import time filename = sys.argv[1] if os.path.isdir(filename): scss_filenames = [x for x in os.listdir(filename) if x.startswith('_') and x.endswith('.scss')] if not scss_filenames: print('Error: directory specified but no proper scss file within.', file=sys.stderr) filename = os.path.join(filename, scss_filenames[0]) def build(): global sources, directories subprocess.call(['sassc', '-mauto', filename, filename.replace('.scss', '.css')]) basepath = os.path.abspath(os.path.dirname(filename)) sources = [os.path.abspath(os.path.join(basepath, x)) for x in json.load(open(filename.replace('.scss', '.css.map')))['sources']] directories = set([os.path.dirname(x) for x in sources]) class EventManager(pyinotify.ProcessEvent): def process_default(self, event): if event.pathname in sources: filename = os.path.basename(event.pathname) print(f'{filename} changed, building', end='') t0 = time.time() build() print(f' ({time.time() - t0:.2f}s)') build() wm = pyinotify.WatchManager() notifier = pyinotify.Notifier(wm, default_proc_fun=EventManager()) for directory in directories: wm.add_watch(directory, pyinotify.IN_CLOSE_WRITE) notifier.coalesce_events() print('>>> Sassw is watching for changes. Press Ctrl-C to stop.') notifier.loop()