"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,
'info',
'init',
'install',
+ 'js',
'phpunit',
'plugin',
'pull',
--- /dev/null
+#!/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://www.gnu.org/licenses/>.
+
+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)
--- /dev/null
+#!/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://www.gnu.org/licenses/>.
+
+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
"""
subtypes = {}
+ path = os.path.realpath(os.path.abspath(path))
if M:
path = '/' + path.replace(M.get('path'), '').strip('/')
admindir = M.get('admin', 'admin')