view libervia/server/tasks/implicit/task_sass.py @ 1260:6161076193e0

tasks: dir event filter: if a Task instance implements `onDirEvent`, it will be called instead of `start`, this way the task can filter the events or modify the workflow.
author Goffi <goffi@goffi.org>
date Sun, 03 May 2020 21:07:22 +0200
parents 1ec41ac1e7cf
children 10748aa888a9
line wrap: on
line source

#!/ur/bin/env python3

import json
from pathlib import Path
from sat.core.i18n import _
from sat.core.log import getLogger
from sat.core import exceptions
from libervia.server.constants import Const as C
from libervia.server.tasks import task


log = getLogger(__name__)

SASS_SUFFIXES = ('.sass', '.scss')


class Task(task.Task):
    """Compile .sass and .scss files found in themes browser paths"""
    AFTER = ['js_modules']

    async def prepare(self):
        # we look for any Sass file, and cancel this task if none is found
        sass_dirs = set()
        for browser_path in self.resource.browser_modules.get('themes_browser_paths', []):
            for p in browser_path.iterdir():
                if p.suffix in SASS_SUFFIXES:
                    sass_dirs.add(browser_path)
                    break

        if not sass_dirs:
            raise exceptions.CancelError("No Sass file found")

        # we have some Sass files, we need to install the compiler
        d_path = self.resource.dev_build_path
        package_path = d_path / "package.json"
        try:
            with package_path.open() as f:
                package = json.load(f)
        except FileNotFoundError:
            package = {}
        except Exception as e:
            log.error(f"Unexepected exception while parsing package.json: {e}")

        if 'node-sass' not in package.setdefault('dependencies', {}):
            package['dependencies']['node-sass'] = 'latest'
            with package_path.open('w') as f:
                json.dump(package, f, indent=4)

        try:
            cmd = self.findCommand('yarn')
        except exceptions.NotFound:
            cmd = self.findCommand('npm')
        await self.runCommand(cmd, 'install', path=str(d_path))

        self.WATCH_DIRS = list(sass_dirs)

    async def onDirEvent(self, host, filepath, flags):
        if filepath.suffix in SASS_SUFFIXES:
            await self.manager.runTaskInstance(self)

    async def start(self):
        d_path = self.resource.dev_build_path
        node_sass = d_path / 'node_modules' / 'node-sass' / 'bin' / 'node-sass'
        for browser_path in self.resource.browser_modules['themes_browser_paths']:
            for p in browser_path.iterdir():
                if p.suffix not in SASS_SUFFIXES:
                    continue
                await self.runCommand(
                    str(node_sass),
                    "--omit-source-map-url",
                    "--output-style", "compressed",
                    "--output", str(self.build_path),
                    str(p),
                    path=str(self.build_path)
                )