From e857b9e40619f889631ef0bc326772c46ddcd9b7 Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Mon, 17 Feb 2014 10:41:40 +0800 Subject: [PATCH] New command for CSS related tasks --- README.md | 13 ++++++ config-dist.json | 2 + extra/bash_completion | 5 +- lib/commands/__init__.py | 1 + lib/commands/css.py | 62 +++++++++++++++++++++++++ lib/css.py | 118 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 lib/commands/css.py create mode 100644 lib/css.py diff --git a/README.md b/README.md index 5892290..63706aa 100644 --- a/README.md +++ b/README.md @@ -168,6 +168,19 @@ Change the value of the setting 'dirs.storage' to '/var/www/repositories' mdk config set dirs.storage /var/www/repositories + +css +--- + +CSS related functions. + +**Example** + +Compile the LESS files from Bootstrapbase + + mdk css --compile + + fix --- diff --git a/config-dist.json b/config-dist.json index 1eee99f..39d2d6e 100644 --- a/config-dist.json +++ b/config-dist.json @@ -167,6 +167,8 @@ "php": "/usr/bin/php", // Path to Java "java": "/usr/bin/java", + // Path to recess + "recess": "/usr/local/bin/recess", // Debug level of MDK. 'debug', 'info', 'warning', 'error' or 'critical'. "debug": "info", diff --git a/extra/bash_completion b/extra/bash_completion index 942018d..4a2cd6a 100644 --- a/extra/bash_completion +++ b/extra/bash_completion @@ -49,7 +49,7 @@ function _mdk() { if [[ "${COMP_CWORD}" == 1 ]]; then # List the commands and aliases. # Ignoring these commands on purpose: init - OPTS="alias backport backup behat check config create fix info install phpunit plugin purge pull push rebase remove run tracker uninstall update upgrade" + OPTS="alias backport backup behat check config create css fix info install phpunit plugin purge pull push rebase remove run tracker uninstall update upgrade" OPTS="$OPTS $($BIN alias list 2> /dev/null | cut -d ':' -f 1)" else # List of options according to the command. @@ -107,6 +107,9 @@ function _mdk() { OPTS="$(_list_scripts)" fi ;; + css) + OPTS="--compile" + ;; fix) if [[ "$PREV" == "-n" || "$PREV" == "--name" ]]; then OPTS=`$BIN info -ln` diff --git a/lib/commands/__init__.py b/lib/commands/__init__.py index 35de075..d5b8241 100644 --- a/lib/commands/__init__.py +++ b/lib/commands/__init__.py @@ -36,6 +36,7 @@ commandsList = [ 'check', 'config', 'create', + 'css', 'fix', 'info', 'init', diff --git a/lib/commands/css.py b/lib/commands/css.py new file mode 100644 index 0000000..41381f2 --- /dev/null +++ b/lib/commands/css.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Moodle Development Kit + +Copyright (c) 2014 Frédéric Massart - FMCorz.net + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +http://github.com/FMCorz/mdk +""" + +import logging +from lib.command import Command +from lib import css + + +class CssCommand(Command): + + _arguments = [ + ( + ['-c', '--compile'], + { + 'action': 'store_true', + 'dest': 'compile', + 'help': 'compile the theme less files' + } + ), + ( + ['names'], + { + 'default': None, + 'help': 'name of the instances', + 'metavar': 'names', + 'nargs': '*' + } + ) + ] + _description = 'Wrapper for CSS functions' + + def run(self, args): + + Mlist = self.Wp.resolveMultiple(args.names) + if len(Mlist) < 1: + raise Exception('No instances to work on. Exiting...') + + for M in Mlist: + if args.compile: + processor = css.Css(M) + processor.compile() diff --git a/lib/css.py b/lib/css.py new file mode 100644 index 0000000..ad92a40 --- /dev/null +++ b/lib/css.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Moodle Development Kit + +Copyright (c) 2014 Frédéric Massart - FMCorz.net + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +http://github.com/FMCorz/mdk +""" + +import logging +import os +from tools import process +from config import Conf + +C = Conf() + + +class Css(object): + """Class wrapping CSS related functions""" + + _M = None + + def __init__(self, M): + self._M = M + + def compile(self, theme='bootstrapbase', sheets=['moodle', 'editor']): + """Compile LESS sheets contained within a theme""" + + cwd = os.path.join(self._M.get('path'), 'theme', theme, 'less') + if not os.path.isdir(cwd): + raise Exception('Unknown theme %s, or less directory not found' % (theme)) + + source = os.path.join(self._M.get('path'), 'theme', theme, 'less') + dest = os.path.join(self._M.get('path'), 'theme', theme, 'style') + hadErrors = False + + for name in sheets: + sheet = name + '.less' + destSheet = name + '.css' + + if not os.path.isfile(os.path.join(source, sheet)): + logging.warning('Could not find file %s' % (sheet)) + hadErrors = True + continue + + try: + compiler = Recess(cwd, os.path.join(source, sheet), os.path.join(dest, destSheet)) + compiler.execute() + except CssCompileFailed: + logging.warning('Failed compilation of %s' % (sheet)) + hadErrors = True + continue + else: + logging.info('Compiled %s' % (sheet)) + + return not hadErrors + + +class Compiler(object): + """LESS compiler abstract""" + + _compress = True + _cwd = None + _source = None + _dest = None + + def __init__(self, cwd, source, dest): + self._cwd = cwd + self._source = source + self._dest = dest + + def execute(self): + raise Exception('Compiler does not implement execute() method') + + def setCompress(self, compress): + self._compress = compress + + +class Recess(Compiler): + """Recess compiler""" + + def execute(self): + executable = C.get('recess') + if not executable: + raise Exception('Could not find executable path') + + cmd = [executable, self._source, '--compile'] + + if self._compress: + cmd.append('--compress') + + + (code, out, err) = process(cmd, self._cwd) + if code != 0 or len(out) == 0: + raise CssCompileFailed('Error during compile') + + # Saving to destination + with open(self._dest, 'w') as f: + f.write(out) + + +class CssCompileFailed(Exception): + pass -- 2.11.0