From a93f1ba9d3cce33573d730a7faea204f253c62a7 Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Fri, 9 May 2014 17:36:09 +0800 Subject: [PATCH] New JS command --- config-dist.json | 2 + lib/commands/__init__.py | 1 + lib/commands/js.py | 133 +++++++++++++++++++++++++++++++++++++++++++++++ lib/js.py | 106 +++++++++++++++++++++++++++++++++++++ lib/plugins.py | 1 + 5 files changed, 243 insertions(+) create mode 100644 lib/commands/js.py create mode 100644 lib/js.py diff --git a/config-dist.json b/config-dist.json index 5211cc3..a9340a5 100644 --- a/config-dist.json +++ b/config-dist.json @@ -171,6 +171,8 @@ "recess": "/usr/local/bin/recess", // Path to lessc "lessc": "/usr/local/bin/lessc", + // Path to shifter + "shifter": "/usr/bin/shifter", // Path to your favourite editor. Set to null to guess it from the System environment. "editor": null, diff --git a/lib/commands/__init__.py b/lib/commands/__init__.py index cccce6b..44176de 100644 --- a/lib/commands/__init__.py +++ b/lib/commands/__init__.py @@ -41,6 +41,7 @@ commandsList = [ 'info', 'init', 'install', + 'js', 'phpunit', 'plugin', 'pull', diff --git a/lib/commands/js.py b/lib/commands/js.py new file mode 100644 index 0000000..c21f68c --- /dev/null +++ b/lib/commands/js.py @@ -0,0 +1,133 @@ +#!/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 lib.command import Command +from lib import js, plugins + + +class JsCommand(Command): + + _arguments = [ + ( + ['mode'], + { + 'metavar': 'mode', + 'help': 'the type of action to perform', + 'sub-commands': + { + 'shift': ( + { + 'help': 'keen to use shifter?' + }, + [ + ( + ['-p', '--plugin'], + { + 'action': 'store', + 'dest': 'plugin', + 'default': None, + 'help': 'the name of the plugin or subsystem to target. If not passed, we do our best to guess from the current path.' + } + ), + ( + ['-m', '--module'], + { + 'action': 'store', + 'dest': 'module', + 'default': None, + 'help': 'the name of the module in the plugin or subsystem. If omitted all the modules will be shifted, except we are in a module.' + } + ), + # ( + # ['-w', '--watch'], + # { + # 'action': 'store_true', + # 'dest': 'watch', + # 'help': 'watch for changes to re-shift' + # } + # ), + ( + ['names'], + { + 'default': None, + 'help': 'name of the instances', + 'metavar': 'names', + 'nargs': '*' + } + ) + ] + ) + } + } + ) + ] + _description = 'Wrapper for JS functions' + + def run(self, args): + if args.mode == 'shift': + self.shift(args) + + + def shift(self, args): + """The shift mode""" + + Mlist = self.Wp.resolveMultiple(args.names) + if len(Mlist) < 1: + raise Exception('No instances to work on. Exiting...') + + cwd = os.path.realpath(os.path.abspath(os.getcwd())) + mpath = Mlist[0].get('path') + relpath = cwd.replace(mpath, '').strip('/') + + if not args.plugin: + (subsystemOrPlugin, pluginName) = plugins.PluginManager.getSubsystemOrPluginFromPath(cwd, Mlist[0]) + if subsystemOrPlugin: + args.plugin = subsystemOrPlugin + ('_' + pluginName) if pluginName else '' + logging.info("I guessed the plugin/subsystem to work on as '%s'" % (args.plugin)) + else: + self.argumentError('The argument --plugin is required, I could not guess it.') + + if not args.module: + candidate = relpath + module = None + while '/yui/src' in candidate: + (head, tail) = os.path.split(candidate) + if head.endswith('/yui/src'): + module = tail + break + candidate = head + + if module: + args.module = module + logging.info("I guessed the JS module to work on as '%s'" % (args.module)) + + + for M in Mlist: + if len(Mlist) > 1: + logging.info('Let\'s shift everything you wanted on \'%s\'' % (M.get('identifier'))) + + processor = js.Js(M) + processor.shift(subsystemOrPlugin=args.plugin, module=args.module) diff --git a/lib/js.py b/lib/js.py new file mode 100644 index 0000000..ba1b381 --- /dev/null +++ b/lib/js.py @@ -0,0 +1,106 @@ +#!/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 +from plugins import PluginManager + +C = Conf() + + +class Js(object): + """Class wrapping JS related functions""" + + _M = None + + def __init__(self, M): + self._M = M + + def shift(self, subsystemOrPlugin=None, module=None): + """Runs shifter""" + path = self.getYUISrcPath(subsystemOrPlugin, module=module) + if not os.path.isdir(path): + raise ValueError("The directory '%s' was not found" % (path)) + + paths = [] + if module: + paths.append(path) + + else: + dirs = os.listdir(path) + for d in dirs: + if os.path.isdir(os.path.join(path, d, 'js')): + paths.append(os.path.join(path, d)) + + shifter = Shifter(path) + for path in paths: + readablePath = path.replace(self._M.get('path'), '') + logging.info('Shifting in %s' % readablePath) + shifter.setCwd(path) + shifter.compile() + + def getYUISrcPath(self, subsystemOrPlugin, module=None): + """Returns the path to the module, or the component""" + + try: + path = PluginManager.getSubsystemDirectory(subsystemOrPlugin, M=self._M) + except ValueError: + (pluginType, name) = PluginManager.getTypeAndName(subsystemOrPlugin) + path = PluginManager.getTypeDirectory(pluginType, M=self._M) + # An exception will be thrown here if we do not find the plugin or component, that is fine. + path = os.path.join(path, name) + + path = os.path.join(path, 'yui', 'src') + if module: + path = os.path.join(path, module) + + return path + + +class Shifter(object): + + _cwd = None + + def __init__(self, cwd=None): + self.setCwd(cwd) + + def compile(self): + """Runs the shifter command in cwd""" + executable = C.get('shifter') + if not executable or not os.path.isfile(executable): + raise Exception('Could not find executable path %s' % (executable)) + + cmd = [executable] + (code, out, err) = process(cmd, cwd=self._cwd) + if code != 0: + raise ShifterCompileFailed('Error during shifting at %s' % (self._cwd)) + + def setCwd(self, cwd): + self._cwd = cwd + + +class ShifterCompileFailed(Exception): + pass diff --git a/lib/plugins.py b/lib/plugins.py index 11eee83..77e1acc 100644 --- a/lib/plugins.py +++ b/lib/plugins.py @@ -195,6 +195,7 @@ class PluginManager(object): """ subtypes = {} + path = os.path.realpath(os.path.abspath(path)) if M: path = '/' + path.replace(M.get('path'), '').strip('/') admindir = M.get('admin', 'admin') -- 2.11.0