61 lines
2.1 KiB
Python
Executable File
61 lines
2.1 KiB
Python
Executable File
#! /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
|
|
result = subprocess.run(
|
|
['sassc', '-mauto', filename, filename.replace('.scss', '.css')],
|
|
capture_output=True)
|
|
sys.stdout.write(result.stdout.decode('utf-8'))
|
|
sys.stderr.write(result.stderr.decode('utf-8'))
|
|
if result.returncode:
|
|
# error
|
|
with open(filename.replace('.scss', '.css'), 'w') as fd:
|
|
print('''body::before {
|
|
white-space: pre;
|
|
font-family: monospace;
|
|
content: "%s";
|
|
}''' % result.stderr.decode('utf-8').replace('\n', '\\A').replace('"', '\\"'),
|
|
file=fd)
|
|
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()
|