import re
import logging
import shutil
-import subprocess
from tools import process, parseBranch
from db import DB
from git import Git
from exceptions import ScriptNotFound, InstallException
from jira import Jira
+from scripts import Scripts
C = Conf()
def runScript(self, scriptname, **kwargs):
"""Runs a script on the instance"""
- supported = ['php']
- directories = ['~/.moodle-sdk']
- if C.get('dirs.moodle') != None:
- directories.insert(0, C.get('dirs.moodle'))
- directories.append('/etc/moodle-sdk')
- directories.append(os.path.join(os.path.dirname(__file__), '..'))
-
- # Loop over each directory in order of preference.
- for directory in directories:
- script = None
- type = None
-
- f = os.path.expanduser(os.path.join(directory, 'scripts', scriptname))
- if os.path.isfile(f) and scriptname.rsplit('.', 1)[1] in supported:
- script = f
- type = scriptname.rsplit('.', 1)[1]
- else:
- for ext in supported:
- if os.path.isfile(f + '.' + ext):
- script = f + '.' + ext
- type = ext
- break
- # Exit the loop if the script has been found.
- if script != None and type != None:
- break
-
- if not script:
- raise ScriptNotFound('Could not find the script, or format not supported')
-
- if type == 'php':
- dest = os.path.join(self.get('path'), 'mdkrun.php')
- shutil.copyfile(script, dest)
- result = self.cli('mdkrun.php', **kwargs)
- os.remove(dest)
- return result[0]
+ return Scripts.run(scriptname, self.get('path'), cmdkwargs=kwargs)
def update(self, remote=None):
"""Update the instance from the remote"""
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Moodle Development Kit
+
+Copyright (c) 2013 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 os
+import shutil
+from tools import process
+from config import Conf
+from exceptions import ScriptNotFound, ConflictInScriptName, UnsupportedScript
+
+C = Conf()
+
+
+class Scripts(object):
+
+ _supported = ['php']
+ _dirs = None
+ _list = None
+
+ @classmethod
+ def dirs(cls):
+ """Return the directories containing scripts, in priority order"""
+
+ if not cls._dirs:
+ dirs = ['~/.moodle-sdk']
+ if C.get('dirs.moodle') != None:
+ dirs.insert(0, C.get('dirs.moodle'))
+ dirs.append('/etc/moodle-sdk')
+ dirs.append(os.path.join(os.path.dirname(__file__), '..'))
+
+ i = 0
+ for d in dirs:
+ dirs[i] = os.path.expanduser(os.path.join(d, 'scripts'))
+ i += 1
+
+ cls._dirs = dirs
+
+ return cls._dirs
+
+ @classmethod
+ def list(cls):
+ """Return a dict where keys are the name of the scripts
+ and the value is the directory in which the script is stored"""
+
+ if not cls._list:
+ scripts = {}
+
+ # Walk through the directories, in reverse to get the higher
+ # priority last.
+ dirs = cls.dirs()
+ dirs.reverse()
+ for d in dirs:
+
+ if not os.path.isdir(d):
+ continue
+
+ # For each file found in the directory.
+ l = os.listdir(d)
+ for f in l:
+
+ # Check if supported format.
+ supported = False
+ for ext in cls._supported:
+ if f.endswith(u'.' + ext):
+ supported = True
+ break
+
+ if supported:
+ scripts[f] = d
+
+ cls._list = scripts
+
+ return cls._list
+
+ @classmethod
+ def find(cls, script):
+ """Return the path to a script"""
+
+ lst = cls.list()
+ cli = None
+ if script in lst.keys():
+ cli = os.path.join(lst[script], script)
+ else:
+ for ext in cls._supported:
+ found = 0
+ scriptFile = script + u'.' + ext
+ if scriptFile in lst.keys():
+ found += 1
+
+ if found > 1:
+ raise ConflictInScriptName('The script name conflicts with other ones')
+ elif found == 1:
+ cli = os.path.join(lst[scriptFile], scriptFile)
+
+ if not cli:
+ raise ScriptNotFound('Script not found')
+
+ return cli
+
+ @classmethod
+ def run(cls, script, path, cmdkwargs={}):
+ """Executes a script at in a certain directory"""
+
+ cli = cls.find(script)
+ if cli.endswith('.php'):
+ dest = os.path.join(path, 'mdkscriptrun.php')
+ shutil.copyfile(cli, dest)
+
+ cmd = '%s %s' % (C.get('php'), dest)
+ result = process(cmd, cwd=path, **cmdkwargs)
+ os.remove(dest)
+ else:
+ raise UnsupportedScript('Script not supported')
+
+ return result[0]