Merge pull request #11849 from open-craft/omar/watch-assets
Fix paver watch_assets
This commit is contained in:
@@ -4,13 +4,15 @@ Asset compilation and collection.
|
||||
|
||||
from __future__ import print_function
|
||||
from datetime import datetime
|
||||
from functools import wraps
|
||||
from threading import Timer
|
||||
import argparse
|
||||
import glob
|
||||
import traceback
|
||||
|
||||
from paver import tasks
|
||||
from paver.easy import sh, path, task, cmdopts, needs, consume_args, call_task, no_help
|
||||
from watchdog.observers import Observer
|
||||
from watchdog.observers.polling import PollingObserver
|
||||
from watchdog.events import PatternMatchingEventHandler
|
||||
|
||||
from .utils.envs import Env
|
||||
@@ -239,6 +241,29 @@ def get_watcher_dirs(themes_base_dir=None, themes=None):
|
||||
return dirs
|
||||
|
||||
|
||||
def debounce(seconds=1):
|
||||
"""
|
||||
Prevents the decorated function from being called more than every `seconds`
|
||||
seconds. Waits until calls stop coming in before calling the decorated
|
||||
function.
|
||||
"""
|
||||
def decorator(func): # pylint: disable=missing-docstring
|
||||
func.timer = None
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs): # pylint: disable=missing-docstring
|
||||
def call(): # pylint: disable=missing-docstring
|
||||
func(*args, **kwargs)
|
||||
func.timer = None
|
||||
if func.timer:
|
||||
func.timer.cancel()
|
||||
func.timer = Timer(seconds, call)
|
||||
func.timer.start()
|
||||
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
class CoffeeScriptWatcher(PatternMatchingEventHandler):
|
||||
"""
|
||||
Watches for coffeescript changes
|
||||
@@ -256,7 +281,8 @@ class CoffeeScriptWatcher(PatternMatchingEventHandler):
|
||||
for dirname in dirnames:
|
||||
observer.schedule(self, dirname)
|
||||
|
||||
def on_modified(self, event):
|
||||
@debounce()
|
||||
def on_any_event(self, event):
|
||||
print('\tCHANGED:', event.src_path)
|
||||
try:
|
||||
compile_coffeescript(event.src_path)
|
||||
@@ -289,7 +315,8 @@ class SassWatcher(PatternMatchingEventHandler):
|
||||
for dirname in paths:
|
||||
observer.schedule(self, dirname, recursive=True)
|
||||
|
||||
def on_modified(self, event):
|
||||
@debounce()
|
||||
def on_any_event(self, event):
|
||||
print('\tCHANGED:', event.src_path)
|
||||
try:
|
||||
compile_sass() # pylint: disable=no-value-for-parameter
|
||||
@@ -304,7 +331,8 @@ class XModuleSassWatcher(SassWatcher):
|
||||
ignore_directories = True
|
||||
ignore_patterns = []
|
||||
|
||||
def on_modified(self, event):
|
||||
@debounce()
|
||||
def on_any_event(self, event):
|
||||
print('\tCHANGED:', event.src_path)
|
||||
try:
|
||||
process_xmodule_assets()
|
||||
@@ -325,7 +353,8 @@ class XModuleAssetsWatcher(PatternMatchingEventHandler):
|
||||
"""
|
||||
observer.schedule(self, 'common/lib/xmodule/', recursive=True)
|
||||
|
||||
def on_modified(self, event):
|
||||
@debounce()
|
||||
def on_any_event(self, event):
|
||||
print('\tCHANGED:', event.src_path)
|
||||
try:
|
||||
process_xmodule_assets()
|
||||
@@ -635,7 +664,7 @@ def watch_assets(options):
|
||||
themes = themes if isinstance(themes, list) else [themes]
|
||||
|
||||
sass_directories = get_watcher_dirs(theme_base_dir, themes)
|
||||
observer = Observer()
|
||||
observer = PollingObserver()
|
||||
|
||||
CoffeeScriptWatcher().register(observer)
|
||||
SassWatcher().register(observer, sass_directories)
|
||||
|
||||
@@ -6,7 +6,7 @@ from unittest import TestCase
|
||||
from paver.easy import call_task
|
||||
from paver.easy import path
|
||||
from mock import patch
|
||||
from watchdog.observers import Observer
|
||||
from watchdog.observers.polling import PollingObserver
|
||||
from .utils import PaverTestCase
|
||||
|
||||
ROOT_PATH = path(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
|
||||
@@ -161,7 +161,7 @@ class TestPaverWatchAssetTasks(TestCase):
|
||||
Test the "compile_sass" task.
|
||||
"""
|
||||
with patch('pavelib.assets.SassWatcher.register') as mock_register:
|
||||
with patch('pavelib.assets.Observer.start'):
|
||||
with patch('pavelib.assets.PollingObserver.start'):
|
||||
call_task(
|
||||
'pavelib.assets.watch_assets',
|
||||
options={"background": True},
|
||||
@@ -170,7 +170,7 @@ class TestPaverWatchAssetTasks(TestCase):
|
||||
|
||||
sass_watcher_args = mock_register.call_args_list[0][0]
|
||||
|
||||
self.assertIsInstance(sass_watcher_args[0], Observer)
|
||||
self.assertIsInstance(sass_watcher_args[0], PollingObserver)
|
||||
self.assertIsInstance(sass_watcher_args[1], list)
|
||||
self.assertItemsEqual(sass_watcher_args[1], self.expected_sass_directories)
|
||||
|
||||
@@ -186,7 +186,7 @@ class TestPaverWatchAssetTasks(TestCase):
|
||||
])
|
||||
|
||||
with patch('pavelib.assets.SassWatcher.register') as mock_register:
|
||||
with patch('pavelib.assets.Observer.start'):
|
||||
with patch('pavelib.assets.PollingObserver.start'):
|
||||
call_task(
|
||||
'pavelib.assets.watch_assets',
|
||||
options={"background": True, "themes_dir": TEST_THEME.dirname(),
|
||||
@@ -195,7 +195,7 @@ class TestPaverWatchAssetTasks(TestCase):
|
||||
self.assertEqual(mock_register.call_count, 2)
|
||||
|
||||
sass_watcher_args = mock_register.call_args_list[0][0]
|
||||
self.assertIsInstance(sass_watcher_args[0], Observer)
|
||||
self.assertIsInstance(sass_watcher_args[0], PollingObserver)
|
||||
self.assertIsInstance(sass_watcher_args[1], list)
|
||||
self.assertItemsEqual(sass_watcher_args[1], self.expected_sass_directories)
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ reportlab==3.1.44
|
||||
pdfminer==20140328
|
||||
|
||||
# Used for development operation
|
||||
watchdog==0.7.1
|
||||
watchdog==0.8.3
|
||||
|
||||
# Metrics gathering and monitoring
|
||||
dogapi==1.2.1
|
||||
|
||||
Reference in New Issue
Block a user