From cee2450f9b9bb706025ac9590ce83d0d74c0123c Mon Sep 17 00:00:00 2001 From: Fred Date: Mon, 4 Mar 2013 23:15:45 +0800 Subject: [PATCH] Switch to using logging to open for further debugging --- config-dist.json | 3 +++ lib/backup.py | 38 ++++++++++++++++----------------- lib/command.py | 2 +- lib/commands/backport.py | 47 +++++++++++++++++++++-------------------- lib/commands/backup.py | 18 ++++++++-------- lib/commands/behat.py | 29 +++++++++++++------------ lib/commands/check.py | 25 +++++++++++----------- lib/commands/config.py | 3 +-- lib/commands/create.py | 17 +++++++-------- lib/commands/fix.py | 4 ++-- lib/commands/info.py | 4 ++-- lib/commands/init.py | 45 ++++++++++++++++++++------------------- lib/commands/install.py | 7 +++--- lib/commands/phpunit.py | 7 +++--- lib/commands/pull.py | 35 +++++++++++++++--------------- lib/commands/purge.py | 12 +++++------ lib/commands/push.py | 12 +++++------ lib/commands/rebase.py | 42 ++++++++++++++++++------------------ lib/commands/remove.py | 8 +++---- lib/commands/run.py | 12 +++++------ lib/commands/update.py | 20 +++++++++--------- lib/commands/upgrade.py | 24 ++++++++++----------- lib/db.py | 47 ++++++++++++++++++++++++++++++++++------- lib/git.py | 26 ++++++++++++----------- lib/jira.py | 5 +++-- lib/moodle.py | 37 ++++++++++++++++---------------- lib/tools.py | 5 ----- lib/workplace.py | 55 ++++++++++++++++++++---------------------------- mdk.py | 16 +++++++++++++- 29 files changed, 322 insertions(+), 283 deletions(-) diff --git a/config-dist.json b/config-dist.json index 8671927..d0d9f96 100644 --- a/config-dist.json +++ b/config-dist.json @@ -139,6 +139,9 @@ // Path to Java "java": "/usr/bin/java", + // Debug level of MDK. 'debug', 'info', 'warning', 'error' or 'critical'. + "debug": "info", + // Name of the symlink pointing to the data directory to create in the www directory // during an instance creation. If false, the symlink won't be created. "symlinkToData": false, diff --git a/lib/backup.py b/lib/backup.py index 7442db1..987f1d8 100644 --- a/lib/backup.py +++ b/lib/backup.py @@ -25,9 +25,10 @@ http://github.com/FMCorz/mdk import os import json import time +import logging from distutils.dir_util import copy_tree -from tools import debug, chmodRecursive +from tools import chmodRecursive from db import DB from config import Conf from workplace import Workplace @@ -37,6 +38,7 @@ C = Conf() jason = 'info.json' sqlfile = 'dump.sql' + class BackupManager(object): def __init__(self): @@ -59,27 +61,27 @@ class BackupManager(object): # Copy whole directory, shutil will create topath topath = os.path.join(self.path, backup_identifier) path = Wp.getPath(name) - debug('Copying instance directory') - copy_tree(path, topath, preserve_symlinks = 1) + logging.info('Copying instance directory') + copy_tree(path, topath, preserve_symlinks=1) # Dump the whole database if M.isInstalled(): - debug('Dumping database') + logging.info('Dumping database') dumpto = os.path.join(topath, sqlfile) fd = open(dumpto, 'w') M.dbo().selectdb(M.get('dbname')) M.dbo().dump(fd) else: - debug('Instance not installed. Do not dump database.') + logging.info('Instance not installed. Do not dump database.') # Create a JSON file containing all known information - debug('Saving instance information') + logging.info('Saving instance information') jsonto = os.path.join(topath, jason) info = M.info() info['backup_origin'] = path info['backup_identifier'] = backup_identifier info['backup_time'] = now - json.dump(info, open(jsonto, 'w'), sort_keys = True, indent = 4) + json.dump(info, open(jsonto, 'w'), sort_keys=True, indent=4) return True @@ -151,7 +153,7 @@ class Backup(object): except: raise Exception('Could not load information from JSON file') - def restore(self, destination = None): + def restore(self, destination=None): """Restores the backup""" identifier = self.get('identifier') @@ -176,8 +178,8 @@ class Backup(object): # Copy tree to destination try: - debug('Restoring instance directory') - copy_tree(self.path, destination, preserve_symlinks = 1) + logging.info('Restoring instance directory') + copy_tree(self.path, destination, preserve_symlinks=1) M = Wp.get(identifier) chmodRecursive(Wp.getPath(identifier, 'data'), 0777) except Exception as e: @@ -185,14 +187,14 @@ class Backup(object): # Restoring database if self.get('installed') and os.path.isfile(self.sqlfile): - debug('Restoring database') + logging.info('Restoring database') content = '' f = open(self.sqlfile, 'r') for l in f: content += l queries = content.split(';\n') content = None - debug("%d queries to execute" % (len(queries))) + logging.info("%d queries to execute" % (len(queries))) dbo.createdb(dbname) dbo.selectdb(dbname) @@ -202,12 +204,11 @@ class Backup(object): try: dbo.execute(query) except: - debug('Query failed! You will have to fix this mually.') - debug(query) + logging.error('Query failed! You will have to fix this mually. %s', query) done += 1 if done % 500 == 0: - debug("%d queries done" % done) - debug('%d queries done' % done) + logging.debug("%d queries done" % done) + logging.info('%d queries done' % done) dbo.close() # Restoring symbolic link @@ -215,9 +216,8 @@ class Backup(object): wwwDir = Wp.getPath(identifier, 'www') if os.path.islink(linkDir): os.remove(linkDir) - if os.path.isfile(linkDir) or os.path.isdir(linkDir): # No elif! - debug('Could not create symbolic link') - debug('Please manually create: ln -s %s %s' % (wwwDir, linkDir)) + if os.path.isfile(linkDir) or os.path.isdir(linkDir): # No elif! + logging.warning('Could not create symbolic link. Please manually create: ln -s %s %s' % (wwwDir, linkDir)) else: os.symlink(wwwDir, linkDir) diff --git a/lib/command.py b/lib/command.py index 1808c8c..af7167c 100644 --- a/lib/command.py +++ b/lib/command.py @@ -114,4 +114,4 @@ class CommandRunner(object): if __name__ == "__main__": - RunCommand(Command()).run() + CommandRunner(Command()).run() diff --git a/lib/commands/backport.py b/lib/commands/backport.py index 93c5747..7256788 100644 --- a/lib/commands/backport.py +++ b/lib/commands/backport.py @@ -22,9 +22,10 @@ along with this program. If not, see . http://github.com/FMCorz/mdk """ +import logging from lib import tools from lib.command import Command -from lib.tools import debug, yesOrNo +from lib.tools import yesOrNo class BackportCommand(Command): @@ -127,9 +128,9 @@ class BackportCommand(Command): if not stash[1].startswith('No local changes'): pop = M2.git().stash(command='pop') if pop[0] != 0: - debug('An error ocured while unstashing your changes') + logging.error('An error ocured while unstashing your changes') else: - debug('Popped the stash') + logging.info('Popped the stash') # Begin backport for v in versions: @@ -137,11 +138,11 @@ class BackportCommand(Command): # Gets the instance to cherry-pick to name = self.Wp.generateInstanceName(v, integration=integration) if not self.Wp.isMoodle(name): - debug('Could not find instance %s for version %s' % (name, v)) + logging.warning('Could not find instance %s for version %s' % (name, v)) continue M2 = self.Wp.get(name) - debug("Preparing cherry-pick of %s/%s in %s" % (M.get('identifier'), branch, name)) + logging.info("Preparing cherry-pick of %s/%s in %s" % (M.get('identifier'), branch, name)) # Get hash list cherry = '%s/%s..%s' % (self.C.get('upstreamRemote'), originaltrack, branch) @@ -151,44 +152,44 @@ class BackportCommand(Command): # Stash stash = M2.git().stash(untracked=False) if stash[0] != 0: - debug('Error while trying to stash your changes. Skipping %s.' % M2.get('identifier')) - debug(stash[2]) + logging.error('Error while trying to stash your changes. Skipping %s.' % M2.get('identifier')) + logging.debug(stash[2]) continue elif not stash[1].startswith('No local changes'): - debug('Stashed your local changes') + logging.info('Stashed your local changes') # Fetch the remote to get reference to the branch to backport - debug("Fetching remote %s..." % (M.get('path'))) + logging.info("Fetching remote %s..." % (M.get('path'))) M2.git().fetch(M.get('path'), branch) # Creates a new branch if necessary newbranch = M2.generateBranchName(issue, suffix=suffix) track = '%s/%s' % (self.C.get('upstreamRemote'), M2.get('stablebranch')) if not M2.git().hasBranch(newbranch): - debug('Creating branch %s' % newbranch) + logging.info('Creating branch %s' % newbranch) if not M2.git().createBranch(newbranch, track=track): - debug('Could not create branch %s tracking %s in %s' % (newbranch, track, name)) + logging.error('Could not create branch %s tracking %s in %s' % (newbranch, track, name)) stashPop(stash) continue M2.git().checkout(newbranch) else: M2.git().checkout(newbranch) - debug('Hard reset %s to %s' % (newbranch, track)) + logging.info('Hard reset %s to %s' % (newbranch, track)) M2.git().reset(to=track, hard=True) # Picking the diff upstream/MOODLE_23_STABLE..github/MDL-12345-master - debug('Cherry-picking %s' % (cherry)) + logging.info('Cherry-picking %s' % (cherry)) result = M2.git().pick(hashes) if result[0] != 0: - debug('Error while cherry-picking %s in %s.' % (cherry, name)) - debug(result[2]) + logging.error('Error while cherry-picking %s in %s.' % (cherry, name)) + logging.debug(result[2]) if yesOrNo('The cherry-pick might still be in progress, would you like to abort it?'): result = M2.git().pick(abort=True) if result[0] > 0 and result[0] != 128: - debug('Could not abort the cherry-pick!') + logging.error('Could not abort the cherry-pick!') else: stashPop(stash) - debug('') + logging.info('') continue # Pushing branch @@ -196,17 +197,17 @@ class BackportCommand(Command): pushremote = args.pushremote if pushremote == None: pushremote = self.C.get('myRemote') - debug('Pushing %s to %s' % (newbranch, pushremote)) + logging.info('Pushing %s to %s' % (newbranch, pushremote)) result = M2.git().push(remote=pushremote, branch=newbranch, force=args.forcepush) if result[0] != 0: - debug('Error while pushing to remote %s' % (pushremote)) - debug(result[2]) + logging.warning('Error while pushing to remote %s' % (pushremote)) + logging.debug(result[2]) stashPop(stash) continue stashPop(stash) - debug('Instance %s successfully patched!' % name) - debug('') + logging.info('Instance %s successfully patched!' % name) + logging.info('') - debug('Done.') + logging.info('Done.') diff --git a/lib/commands/backup.py b/lib/commands/backup.py index dbcc331..45057fe 100644 --- a/lib/commands/backup.py +++ b/lib/commands/backup.py @@ -23,11 +23,11 @@ http://github.com/FMCorz/mdk """ import time +import logging from distutils.errors import DistutilsFileError from lib.command import Command from lib import backup from lib.exceptions import * -from lib.tools import debug class BackupCommand(Command): @@ -92,9 +92,9 @@ class BackupCommand(Command): # Restore process B = BackupManager.get(name) infos = B.infos - debug('Displaying information about %s' % name) + print 'Displaying information about %s' % name for key in sorted(infos.keys()): - debug('{0:<20}: {1}'.format(key, infos[key])) + print '{0:<20}: {1}'.format(key, infos[key]) # Restore elif args.restore: @@ -117,15 +117,15 @@ class BackupCommand(Command): 'This command could help: moodle remove %s' % B.get('identifier')) # Loads M object and display information - debug('') - debug('Restored instance information') - debug('') + logging.info('') + logging.info('Restored instance information') + logging.info('') infos = M.info() for key in sorted(infos.keys()): print '{0:<20}: {1}'.format(key, infos[key]) - debug('') + logging.info('') - debug('Done.') + logging.info('Done.') # Backup the instance else: @@ -142,4 +142,4 @@ class BackupCommand(Command): raise Exception('Error while copying files. Check the permissions on the data directory.' + 'Or run: sudo chmod -R 0777 %s' % M.get('dataroot')) - debug('Done.') + logging.info('Done.') diff --git a/lib/commands/behat.py b/lib/commands/behat.py index 16940b7..3580ed9 100644 --- a/lib/commands/behat.py +++ b/lib/commands/behat.py @@ -25,9 +25,10 @@ http://github.com/FMCorz/mdk import os import urllib import re +import logging from time import sleep from lib.command import Command -from lib.tools import debug, process, ProcessInThread +from lib.tools import process, ProcessInThread class BehatCommand(Command): @@ -101,11 +102,11 @@ class BehatCommand(Command): nojavascript = args.nojavascript if not nojavascript and not self.C.get('java') or not os.path.isfile(os.path.abspath(self.C.get('java'))): nojavascript = True - debug('Disabling Javascript because Java is required to run Selenium and could not be found.') + logging.info('Disabling Javascript because Java is required to run Selenium and could not be found.') # If not composer.phar, install Composer if not os.path.isfile(os.path.join(M.get('path'), 'composer.phar')): - debug('Installing Composer') + logging.info('Installing Composer') cliFile = 'behat_install_composer.php' cliPath = os.path.join(M.get('path'), 'behat_install_composer.php') urllib.urlretrieve('http://getcomposer.org/installer', cliPath) @@ -118,15 +119,15 @@ class BehatCommand(Command): if args.selenium: seleniumPath = args.selenium elif not nojavascript and not os.path.isfile(seleniumPath): - debug('Attempting to find a download for Selenium') + logging.info('Attempting to find a download for Selenium') url = urllib.urlopen('http://docs.seleniumhq.org/download/') content = url.read() selenium = re.search(r'http:[a-z0-9/._-]+selenium-server-standalone-[0-9.]+\.jar', content, re.I) if selenium: - debug('Downloading Selenium from %s' % (selenium.group(0))) + logging.info('Downloading Selenium from %s' % (selenium.group(0))) urllib.urlretrieve(selenium.group(0), seleniumPath) else: - debug('Could not locate Selenium server to download') + logging.warning('Could not locate Selenium server to download') if not os.path.isfile(seleniumPath): raise Exception('Selenium file %s does not exist') @@ -134,7 +135,7 @@ class BehatCommand(Command): # Run cli try: M.initBehat(switchcompletely=args.switchcompletely) - debug('Behat ready!') + logging.info('Behat ready!') # Preparing Behat command cmd = ['vendor/bin/behat'] @@ -149,12 +150,12 @@ class BehatCommand(Command): seleniumCommand = '%s -jar %s' % (self.C.get('java'), seleniumPath) if args.run: - debug('Preparing Behat testing') + logging.info('Preparing Behat testing') # Preparing PHP Server phpServer = None if not M.get('behat_switchcompletely'): - debug('Starting standalone PHP server') + logging.info('Starting standalone PHP server') kwargs = {} kwargs['cwd'] = M.get('path') phpServer = ProcessInThread(phpCommand, **kwargs) @@ -163,7 +164,7 @@ class BehatCommand(Command): # Launching Selenium seleniumServer = None if seleniumPath and not nojavascript: - debug('Starting Selenium server') + logging.info('Starting Selenium server') kwargs = {} if args.seleniumverbose: kwargs['stdout'] = None @@ -171,7 +172,7 @@ class BehatCommand(Command): seleniumServer = ProcessInThread(seleniumCommand, **kwargs) seleniumServer.start() - debug('Running Behat tests') + logging.info('Running Behat tests') # Sleep for a few seconds before starting Behat if phpServer or seleniumServer: @@ -191,10 +192,10 @@ class BehatCommand(Command): M.removeConfig('behat_switchcompletely') else: - debug('Launch PHP Server (or set $CFG->behat_switchcompletely to True):\n %s' % (phpCommand)) + logging.info('Launch PHP Server (or set $CFG->behat_switchcompletely to True):\n %s' % (phpCommand)) if seleniumCommand: - debug('Launch Selenium (optional):\n %s' % (seleniumCommand)) - debug('Launch Behat:\n %s' % (cmd)) + logging.info('Launch Selenium (optional):\n %s' % (seleniumCommand)) + logging.info('Launch Behat:\n %s' % (cmd)) except Exception as e: raise e diff --git a/lib/commands/check.py b/lib/commands/check.py index d26037e..625aa15 100644 --- a/lib/commands/check.py +++ b/lib/commands/check.py @@ -26,7 +26,6 @@ import os import shutil from lib import git from lib.command import Command -from lib.tools import debug class CheckCommand(Command): @@ -53,7 +52,7 @@ class CheckCommand(Command): def cachedRepositories(self, args): """Ensure that the cached repositories are valid""" - debug('Checking cached repositories') + print 'Checking cached repositories' cache = os.path.abspath(os.path.realpath(os.path.expanduser(self.C.get('dirs.mdk')))) dirs = [ @@ -73,40 +72,40 @@ class CheckCommand(Command): if os.path.isdir(directory): if os.path.isdir(os.path.join(directory, '.git')): - debug(' %s is not a bare repository' % name) + print ' %s is not a bare repository' % name if args.fix: - debug(' Renaming %s/.git directory to %s' % (directory, directory)) + print ' Renaming %s/.git directory to %s' % (directory, directory) os.rename(directory, directory + '.tmp') os.rename(os.path.join(directory + '.tmp', '.git'), directory) shutil.rmtree(directory + '.tmp') repo = git.Git(directory, self.C.get('git')) if repo.getConfig('core.bare') != 'true': - debug(' %s core.bare is not set to true' % name) + print ' %s core.bare is not set to true' % name if args.fix: - debug(' Setting core.bare to true') + print ' Setting core.bare to true' repo.setConfig('core.bare', 'true') if repo.getConfig('remote.origin.url') != d['url']: - debug(' %s uses an different origin (%s)' % (name, repo.getConfig('remote.origin.url'))) + print ' %s uses an different origin (%s)' % (name, repo.getConfig('remote.origin.url')) if args.fix: - debug(' Setting remote.origin.url to %s' % d['url']) + print ' Setting remote.origin.url to %s' % d['url'] repo.setConfig('remote.origin.url', d['url']) if repo.getConfig('remote.origin.fetch') != '+refs/*:refs/*': - debug(' %s fetch value is invalid (%s)' % (name, repo.getConfig('remote.origin.fetch'))) + print ' %s fetch value is invalid (%s)' % (name, repo.getConfig('remote.origin.fetch')) if args.fix: - debug(' Setting remote.origin.fetch to %s' % '+refs/*:refs/*') + print ' Setting remote.origin.fetch to %s' % '+refs/*:refs/*' repo.setConfig('remote.origin.fetch', '+refs/*:refs/*') def directories(self, args): """Check that the directories are valid""" - debug('Checking directories') + print 'Checking directories' for k, d in self.C.get('dirs').items(): d = os.path.abspath(os.path.realpath(os.path.expanduser(d))) if not os.path.isdir(d): - debug(' %s does not exist' % d) + print ' %s does not exist' % d if args.fix: - debug(' Creating %s' % d) + print ' Creating %s' % d os.mkdir(d, 0777) diff --git a/lib/commands/config.py b/lib/commands/config.py index f21c5f6..981d021 100644 --- a/lib/commands/config.py +++ b/lib/commands/config.py @@ -23,7 +23,6 @@ http://github.com/FMCorz/mdk """ from lib.command import Command -from lib.tools import debug class ConfigCommand(Command): @@ -111,7 +110,7 @@ class ConfigCommand(Command): elif args.action == 'show': setting = self.C.get(args.setting) if setting != None: - debug(setting) + print setting elif args.action == 'set': setting = args.setting diff --git a/lib/commands/create.py b/lib/commands/create.py index d215e4d..abea105 100644 --- a/lib/commands/create.py +++ b/lib/commands/create.py @@ -24,10 +24,11 @@ http://github.com/FMCorz/mdk import sys import re +import logging from lib.db import DB from lib.command import Command -from lib.tools import debug, yesOrNo +from lib.tools import yesOrNo class CreateCommand(Command): @@ -112,7 +113,7 @@ class CreateCommand(Command): fullname += ' ' + args.suffix.replace('-', ' ').replace('_', ' ').title() # Create the instance - debug('Creating instance %s...' % name) + logging.info('Creating instance %s...' % name) kwargs = { 'name': name, 'version': version, @@ -122,8 +123,7 @@ class CreateCommand(Command): try: M = self.Wp.create(**kwargs) except Exception as e: - debug(e) - sys.exit(1) + logging.exception('Error creating %s' % name) # Run the install script if args.install: @@ -133,7 +133,7 @@ class CreateCommand(Command): db = DB(engine, self.C.get('db.%s' % engine)) dropDb = False if db.dbexists(dbname): - debug('Database already exists (%s)' % dbname) + logging.info('Database already exists (%s)' % dbname) dropDb = yesOrNo('Do you want to remove it?') # Install @@ -149,11 +149,10 @@ class CreateCommand(Command): # Running scripts if M.isInstalled() and type(args.run) == list: for script in args.run: - debug('Running script \'%s\'' % (script)) + logging.info('Running script \'%s\'' % (script)) try: M.runScript(script) except Exception as e: - debug('Error while running the script') - debug(e) + logging.warning('Error while running the script: %s' % e) - debug('Process complete!') + logging.info('Process complete!') diff --git a/lib/commands/fix.py b/lib/commands/fix.py index 3a98cfa..d9b350f 100644 --- a/lib/commands/fix.py +++ b/lib/commands/fix.py @@ -23,8 +23,8 @@ http://github.com/FMCorz/mdk """ +import logging from lib.command import Command -from lib.tools import debug class FixCommand(Command): @@ -79,4 +79,4 @@ class FixCommand(Command): if not repo.checkout(branch): raise Exception('Error while checkout out branch %s' % branch) - debug('Branch %s checked out' % branch) + logging.info('Branch %s checked out' % branch) diff --git a/lib/commands/info.py b/lib/commands/info.py index 896483c..b5c323d 100644 --- a/lib/commands/info.py +++ b/lib/commands/info.py @@ -22,8 +22,8 @@ along with this program. If not, see . http://github.com/FMCorz/mdk """ +import logging from lib.command import Command -from lib.tools import debug class InfoCommand(Command): @@ -126,7 +126,7 @@ class InfoCommand(Command): # Not a valid int, let's consider it a string. pass M.updateConfig(args.var, val) - debug('Set $CFG->%s to %s on %s' % (args.var, str(val), M.get('identifier'))) + logging.info('Set $CFG->%s to %s on %s' % (args.var, str(val), M.get('identifier'))) else: print M.get(args.var) diff --git a/lib/commands/init.py b/lib/commands/init.py index 165bbce..44ca1e5 100644 --- a/lib/commands/init.py +++ b/lib/commands/init.py @@ -27,9 +27,10 @@ import grp import re import pwd import subprocess +import logging from lib.command import Command -from lib.tools import debug, question, get_current_user +from lib.tools import question, get_current_user class InitCommand(Command): @@ -63,13 +64,13 @@ class InitCommand(Command): try: user = pwd.getpwnam(username) except: - debug('Error while getting information for user %s' % (username)) + logging.warning('Error while getting information for user %s' % (username)) continue try: usergroup = grp.getgrgid(user.pw_gid) except: - debug('Error while getting the group of user %s' % (username)) + logging.warning('Error while getting the group of user %s' % (username)) continue break @@ -80,19 +81,19 @@ class InitCommand(Command): # Create the main MDK folder. if not os.path.isdir(userdir): - debug('Creating directory %s.' % userdir) + logging.info('Creating directory %s.' % userdir) os.mkdir(userdir, 0755) os.chown(userdir, user.pw_uid, usergroup.gr_gid) # Checking if the config file exists. userconfigfile = os.path.join(userdir, 'config.json') if os.path.isfile(userconfigfile): - debug('Config file %s already in place.' % userconfigfile) + logging.info('Config file %s already in place.' % userconfigfile) if not args.force: raise Exception('Aborting. Use --force to continue.') elif not os.path.isfile(userconfigfile): - debug('Creating user config file in %s.' % userconfigfile) + logging.info('Creating user config file in %s.' % userconfigfile) open(userconfigfile, 'w') os.chown(userconfigfile, user.pw_uid, usergroup.gr_gid) @@ -100,7 +101,7 @@ class InitCommand(Command): try: group = grp.getgrnam('moodle-sdk') if not username in group.gr_mem: - debug('Adding user %s to group %s.' % (username, group.gr_name)) + logging.info('Adding user %s to group %s.' % (username, group.gr_name)) # This command does not work for some reason... # os.initgroups(username, group.gr_gid) chgrp = subprocess.Popen(['usermod', '-a', '-G', 'moodle-sdk', username]) @@ -123,7 +124,7 @@ class InitCommand(Command): os.mkdir(www, 0775) os.chown(www, user.pw_uid, usergroup.gr_gid) except: - debug('Error while creating directory %s' % www) + logging.error('Error while creating directory %s' % www) continue else: C.set('dirs.www', www) @@ -138,10 +139,10 @@ class InitCommand(Command): os.mkdir(storage, 0775) os.chown(storage, user.pw_uid, usergroup.gr_gid) else: - debug('Error! dirs.www and dirs.storage must be different!') + logging.error('Error! dirs.www and dirs.storage must be different!') continue except: - debug('Error while creating directory %s' % storage) + logging.error('Error while creating directory %s' % storage) continue else: C.set('dirs.storage', storage) @@ -153,11 +154,11 @@ class InitCommand(Command): mdkdir = self.resolve_directory(mdkdir, username) if not os.path.isdir(mdkdir): try: - debug('Creating MDK directory %s' % mdkdir) + logging.info('Creating MDK directory %s' % mdkdir) os.mkdir(mdkdir, 0775) os.chown(mdkdir, user.pw_uid, usergroup.gr_gid) except: - debug('Error while creating %s, please fix manually.' % mdkdir) + logging.error('Error while creating %s, please fix manually.' % mdkdir) # Git repository. github = question('What is your Github username? (Leave blank if not using Github)') @@ -178,13 +179,13 @@ class InitCommand(Command): C.set('db.pgsql.user', question('What is your PostgreSQL user?', C.get('db.pgsql.user'))) C.set('db.pgsql.passwd', question('What is your PostgreSQL password?', C.get('db.pgsql.passwd'), password=True)) - debug('') - debug('MDK has been initialised with minimal configuration.') - debug('For more settings, edit your config file: %s.' % userconfigfile) - debug('Use %s as documentation.' % os.path.join(scriptdir, 'config-dist.json')) - debug('') - debug('Type the following command to create your first instance:') - debug(' mdk create') - debug('(This will take some time, but don\'t worry, that\'s because the cache is still empty)') - debug('') - debug('/!\ Please logout/login before to avoid permission issues: sudo su `whoami`') + print '' + print 'MDK has been initialised with minimal configuration.' + print 'For more settings, edit your config file: %s.' % userconfigfile + print 'Use %s as documentation.' % os.path.join(scriptdir, 'config-dist.json') + print '' + print 'Type the following command to create your first instance:' + print ' mdk create' + print '(This will take some time, but don\'t worry, that\'s because the cache is still empty)' + print '' + print '/!\ Please logout/login before to avoid permission issues: sudo su `whoami`' diff --git a/lib/commands/install.py b/lib/commands/install.py index 186e8ee..9d7951e 100644 --- a/lib/commands/install.py +++ b/lib/commands/install.py @@ -23,9 +23,9 @@ http://github.com/FMCorz/mdk """ import os +import logging from lib import db from lib.command import Command -from lib.tools import debug DB = db.DB @@ -99,9 +99,8 @@ class InstallCommand(Command): # Running scripts if M.isInstalled() and type(args.run) == list: for script in args.run: - debug('Running script \'%s\'' % (script)) + logging.info('Running script \'%s\'' % (script)) try: M.runScript(script) except Exception as e: - debug('Error while running the script') - debug(e) + logging.warning('Error while running the script: %s' % e) diff --git a/lib/commands/phpunit.py b/lib/commands/phpunit.py index a31d674..f1b902a 100644 --- a/lib/commands/phpunit.py +++ b/lib/commands/phpunit.py @@ -22,8 +22,9 @@ along with this program. If not, see . http://github.com/FMCorz/mdk """ +import logging from lib.command import Command -from lib.tools import debug, process +from lib.tools import process class PhpunitCommand(Command): @@ -69,9 +70,9 @@ class PhpunitCommand(Command): # Run cli try: M.initPHPUnit(force=args.force) - debug('PHPUnit ready!') + logging.info('PHPUnit ready!') if args.run: - debug('Running PHPUnit') + logging.info('Running PHPUnit') process('phpunit', M.path, None, None) except Exception as e: raise e diff --git a/lib/commands/pull.py b/lib/commands/pull.py index 7edefda..d1cceb1 100644 --- a/lib/commands/pull.py +++ b/lib/commands/pull.py @@ -24,10 +24,11 @@ http://github.com/FMCorz/mdk import re import os +import logging from datetime import datetime from lib import tools, jira from lib.command import Command -from lib.tools import debug, question +from lib.tools import question class PullCommand(Command): @@ -91,7 +92,7 @@ class PullCommand(Command): branch = M.get('branch') # Get information from Tracker - debug('Retrieving information about %s from Moodle Tracker' % (mdl)) + logging.info('Retrieving information about %s from Moodle Tracker' % (mdl)) J = jira.Jira() issueInfo = J.getIssue(mdl) @@ -144,7 +145,7 @@ class PullCommand(Command): if stash[0] != 0: raise Exception('Error while trying to stash your changes. Exiting...') elif not stash[1].startswith('No local changes'): - debug('Stashed your local changes') + logging.info('Stashed your local changes') # Create a testing branch if args.testing: @@ -159,13 +160,13 @@ class PullCommand(Command): M.git().createBranch(newBranch, track=track) if not M.git().checkout(newBranch): raise Exception('Could not checkout branch %s' % (newBranch)) - debug('Checked out branch %s' % (newBranch)) + logging.info('Checked out branch %s' % (newBranch)) # Checkout the stable branch elif args.integration: if not M.git().checkout(M.get('stablebranch')): - debug('Could not checkout branch %s' % (M.get('stablebranch'))) - debug('Checked out branch %s' % (M.get('stablebranch'))) + logging.error('Could not checkout branch %s' % (M.get('stablebranch'))) + logging.info('Checked out branch %s' % (M.get('stablebranch'))) # Create a no-merge branch elif args.nomerge: @@ -180,12 +181,12 @@ class PullCommand(Command): M.git().createBranch(newBranch, track=track) if not M.git().checkout(newBranch): raise Exception('Could not checkout branch %s' % (newBranch)) - debug('Checked out branch %s' % (newBranch)) + logging.info('Checked out branch %s' % (newBranch)) mode = 'nomerge' if mode == 'pull': # Pull branch from tracker - debug('Pulling branch %s from %s into %s' % (remoteBranch, remoteUrl, M.currentBranch())) + logging.info('Pulling branch %s from %s into %s' % (remoteBranch, remoteUrl, M.currentBranch())) M.git().pull(remote=remoteUrl, ref=remoteBranch) elif mode == 'patch': @@ -193,36 +194,36 @@ class PullCommand(Command): files = [] for patch in patchesToApply: dest = patch['mdk-filename'] - debug('Downloading %s' % (patch['filename'])) + logging.info('Downloading %s' % (patch['filename'])) if not J.download(patch['content'], dest): - debug('Failed to download. Aborting...') + logging.error('Failed to download. Aborting...') files = [] break files.append(dest) if len(files) > 0: - debug('Applying patch(es)...') + logging.info('Applying patch(es)...') if not M.git().apply(files): - debug('Could not apply the patch(es), please apply manually') + logging.warning('Could not apply the patch(es), please apply manually') else: for f in files: os.remove(f) elif mode == 'nomerge': # Checking out the patch without merging it. - debug('Fetching %s %s' % (remoteUrl, remoteBranch)) + logging.info('Fetching %s %s' % (remoteUrl, remoteBranch)) M.git().fetch(remote=remoteUrl, ref=remoteBranch) - debug('Hard reset to FETCH_HEAD') + logging.info('Hard reset to FETCH_HEAD') M.git().reset('FETCH_HEAD', hard=True) # Stash pop if not stash[1].startswith('No local changes'): pop = M.git().stash(command='pop') if pop[0] != 0: - debug('An error ocured while unstashing your changes') + logging.error('An error ocured while unstashing your changes') else: - debug('Popped the stash') + logging.info('Popped the stash') - debug('Done.') + logging.info('Done.') # TODO Tidy up the messy logic above! diff --git a/lib/commands/purge.py b/lib/commands/purge.py index 355983b..e215d8e 100644 --- a/lib/commands/purge.py +++ b/lib/commands/purge.py @@ -22,8 +22,8 @@ along with this program. If not, see . http://github.com/FMCorz/mdk """ +import logging from lib.command import Command -from lib.tools import debug class PurgeCommand(Command): @@ -80,15 +80,15 @@ class PurgeCommand(Command): raise Exception('No instances to work on. Exiting...') for M in Mlist: - debug('Purging cache on %s' % (M.get('identifier'))) + logging.info('Purging cache on %s' % (M.get('identifier'))) try: M.purge() except Exception as e: - debug(e) + logging.error('Could not purge cache: %s' % e) else: - debug('Cache purged!') + logging.debug('Cache purged!') - debug('') + logging.info('') - debug('Done.') + logging.info('Done.') diff --git a/lib/commands/push.py b/lib/commands/push.py index 9d0b3b2..f6f3474 100644 --- a/lib/commands/push.py +++ b/lib/commands/push.py @@ -22,9 +22,9 @@ along with this program. If not, see . http://github.com/FMCorz/mdk """ +import logging from lib import tools, jira from lib.command import Command -from lib.tools import debug class PushCommand(Command): @@ -109,7 +109,7 @@ class PushCommand(Command): branch = args.branch # Pushing current branch - debug('Pushing branch %s to remote %s...' % (branch, remote)) + logging.info('Pushing branch %s to remote %s...' % (branch, remote)) result = M.git().push(remote, branch, force=args.force) if result[0] != 0: raise Exception(result[2]) @@ -141,10 +141,10 @@ class PushCommand(Command): fielddiffurl = self.C.get('tracker.fieldnames.%s.diffurl' % version) if not (fieldrepositoryurl or fieldbranch or fielddiffurl): - debug('Cannot set tracker fields for this version (%s) as the field names are not configured in the config file.', version) + logging.error('Cannot set tracker fields for this version (%s) as the field names are not configured in the config file.', version) else: - debug('Setting tracker fields: \n\t%s: %s \n\t%s: %s \n\t%s: %s\n' % (fieldrepositoryurl, repositoryurl, + logging.info('Setting tracker fields: \n\t%s: %s \n\t%s: %s \n\t%s: %s\n' % (fieldrepositoryurl, repositoryurl, fieldbranch, branch, fielddiffurl, diffurl)) J.setCustomFields(issue, {fieldrepositoryurl: repositoryurl, @@ -154,9 +154,9 @@ class PushCommand(Command): # Pushing stable branch if args.includestable: branch = M.get('stablebranch') - debug('Pushing branch %s to remote %s...' % (branch, remote)) + logging.info('Pushing branch %s to remote %s...' % (branch, remote)) result = M.git().push(remote, branch, force=args.forcestable) if result[0] != 0: raise Exception(result[2]) - debug('Done.') + logging.info('Done.') diff --git a/lib/commands/rebase.py b/lib/commands/rebase.py index 4ff3f65..fe7ca6a 100644 --- a/lib/commands/rebase.py +++ b/lib/commands/rebase.py @@ -22,8 +22,8 @@ along with this program. If not, see . http://github.com/FMCorz/mdk """ +import logging from lib.command import Command -from lib.tools import debug class RebaseCommand(Command): @@ -112,12 +112,12 @@ class RebaseCommand(Command): Mlist = self.Wp.resolveMultiple(names) # Updating cache remotes - print 'Updating cached repositories' + logging.info('Updating cached repositories') self.Wp.updateCachedClones() # Loops over instances to rebase for M in Mlist: - debug('Working on %s' % (M.get('identifier'))) + logging.info('Working on %s' % (M.get('identifier'))) M.git().fetch(self.C.get('upstreamRemote')) # Test if currently in a detached branch @@ -125,58 +125,58 @@ class RebaseCommand(Command): result = M.git().checkout(M.get('stablebranch')) # If we can't checkout the stable branch, that is probably because we are in an unmerged situation if not result: - debug('Error. The repository seem to be on a detached branch. Skipping.') + logging.warning('Error. The repository seem to be on a detached branch. Skipping.') continue # Stash stash = M.git().stash(untracked=True) if stash[0] != 0: - debug('Error while trying to stash your changes. Skipping %s.' % M.get('identifier')) - debug(stash[2]) + logging.error('Error while trying to stash your changes. Skipping %s.' % M.get('identifier')) + logging.debug(stash[2]) continue elif not stash[1].startswith('No local changes'): - debug('Stashed your local changes') + logging.info('Stashed your local changes') # Looping over each issue to rebase for issue in issues: branch = M.generateBranchName(issue, suffix=args.suffix) if not M.git().hasBranch(branch): - debug('Could not find branch %s' % (branch)) + logging.warning('Could not find branch %s' % (branch)) continue # Rebase - debug('> Rebasing %s...' % (branch)) + logging.info('> Rebasing %s...' % (branch)) base = '%s/%s' % (self.C.get('upstreamRemote'), M.get('stablebranch')) result = M.git().rebase(branch=branch, base=base) if result[0] != 0: - debug('Error while rebasing branch %s on top of %s' % (branch, base)) + logging.warning('Error while rebasing branch %s on top of %s' % (branch, base)) if result[0] == 1 and result[2].strip() == '': - debug('There must be conflicts.') - debug('Aborting... Please rebase manually.') + logging.debug('There must be conflicts.') + logging.info('Aborting... Please rebase manually.') M.git().rebase(abort=True) else: - debug(result[2]) + logging.debug(result[2]) continue # Pushing branch if args.push: remote = args.remote - debug('Pushing %s to %s' % (branch, remote)) + logging.info('Pushing %s to %s' % (branch, remote)) result = M.git().push(remote=remote, branch=branch, force=args.forcepush) if result[0] != 0: - debug('Error while pushing to remote') - debug(result[2]) + logging.warning('Error while pushing to remote') + logging.debug(result[2]) continue # Stash pop if not stash[1].startswith('No local changes'): pop = M.git().stash(command='pop') if pop[0] != 0: - debug('An error ocured while unstashing your changes') - debug(pop[2]) + logging.error('An error ocured while unstashing your changes') + logging.debug(pop[2]) else: - debug('Popped the stash') + logging.info('Popped the stash') - debug('') + logging.info('') - debug('Done.') + logging.info('Done.') diff --git a/lib/commands/remove.py b/lib/commands/remove.py index 0280d81..e288713 100644 --- a/lib/commands/remove.py +++ b/lib/commands/remove.py @@ -22,8 +22,8 @@ along with this program. If not, see . http://github.com/FMCorz/mdk """ +import logging from lib.command import Command -from lib.tools import debug class RemoveCommand(Command): @@ -56,10 +56,10 @@ class RemoveCommand(Command): if not args.do: confirm = raw_input('Are you sure? (Y/n) ') if confirm != 'Y': - debug('Aborting...') + logging.info('Aborting...') return - debug('Removing %s...' % args.name) + logging.info('Removing %s...' % args.name) try: self.Wp.delete(args.name) except OSError: @@ -67,4 +67,4 @@ class RemoveCommand(Command): 'This is probably a permission issue.\n' + 'Run: sudo chmod -R 0777 %s' % self.Wp.getPath(args.name)) - debug('Instance removed') + logging.info('Instance removed') diff --git a/lib/commands/run.py b/lib/commands/run.py index f0f3b66..52ec812 100644 --- a/lib/commands/run.py +++ b/lib/commands/run.py @@ -22,8 +22,8 @@ along with this program. If not, see . http://github.com/FMCorz/mdk """ +import logging from lib.command import Command -from lib.tools import debug class RunCommand(Command): @@ -84,13 +84,13 @@ class RunCommand(Command): raise Exception('No instances to work on. Exiting...') for M in Mlist: - debug('Running \'%s\' on \'%s\'' % (args.script, M.get('identifier'))) + logging.info('Running \'%s\' on \'%s\'' % (args.script, M.get('identifier'))) try: M.runScript(args.script, stderr=None, stdout=None) except Exception as e: - debug('Error while running the script on %s' % M.get('identifier')) - debug(e) + logging.warning('Error while running the script on %s' % M.get('identifier')) + logging.debug(e) else: - debug('') + logging.info('') - debug('Done.') + logging.info('Done.') diff --git a/lib/commands/update.py b/lib/commands/update.py index f5c37ae..aceff6d 100644 --- a/lib/commands/update.py +++ b/lib/commands/update.py @@ -23,8 +23,8 @@ http://github.com/FMCorz/mdk """ import sys +import logging from lib.command import Command -from lib.tools import debug class UpdateCommand(Command): @@ -94,28 +94,28 @@ class UpdateCommand(Command): errors = [] for M in Mlist: - debug('Updating %s...' % M.get('identifier')) + logging.info('Updating %s...' % M.get('identifier')) try: M.update() except Exception as e: errors.append(M) - debug('Error during the update of %s' % M.get('identifier')) - debug(e) + logging.warning('Error during the update of %s' % M.get('identifier')) + logging.debug(e) else: if args.upgrade: try: M.upgrade() except Exception as e: errors.append(M) - debug('Error during the upgrade of %s' % M.get('identifier')) + logging.warning('Error during the upgrade of %s' % M.get('identifier')) pass - debug('') - debug('Done.') + logging.info('') + logging.info('Done.') if errors and len(Mlist) > 1: - debug('') - debug('/!\ Some errors occurred on the following instances:') + logging.info('') + logging.warning('/!\ Some errors occurred on the following instances:') for M in errors: - debug('- %s' % M.get('identifier')) + logging.warning('- %s' % M.get('identifier')) # Remove sys.exit and handle error code sys.exit(1) diff --git a/lib/commands/upgrade.py b/lib/commands/upgrade.py index b4082d0..f3af29d 100644 --- a/lib/commands/upgrade.py +++ b/lib/commands/upgrade.py @@ -23,8 +23,8 @@ http://github.com/FMCorz/mdk """ import sys +import logging from lib.command import Command -from lib.tools import debug class UpgradeCommand(Command): @@ -103,29 +103,29 @@ class UpgradeCommand(Command): for M in Mlist: if args.update: - debug('Updating %s...' % M.get('identifier')) + logging.info('Updating %s...' % M.get('identifier')) try: M.update() except Exception as e: errors.append(M) - debug('Error during update. Skipping...') - debug(e) + logging.warning('Error during update. Skipping...') + logging.debug(e) continue - debug('Upgrading %s...' % M.get('identifier')) + logging.info('Upgrading %s...' % M.get('identifier')) try: M.upgrade(args.nocheckout) except Exception as e: errors.append(M) - debug('Error during the upgrade of %s' % M.get('identifier')) - debug(e) - debug('') - debug('Done.') + logging.warning('Error during the upgrade of %s' % M.get('identifier')) + logging.debug(e) + logging.info('') + logging.info('Done.') if errors and len(Mlist) > 1: - debug('') - debug('/!\ Some errors occurred on the following instances:') + logging.info('') + logging.warning('/!\ Some errors occurred on the following instances:') for M in errors: - debug('- %s' % M.get('identifier')) + logging.warning('- %s' % M.get('identifier')) # TODO Do not use sys.exit() but handle error code sys.exit(1) diff --git a/lib/db.py b/lib/db.py index 1bf51d3..b96f52d 100644 --- a/lib/db.py +++ b/lib/db.py @@ -1,6 +1,28 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +""" +Moodle Development Kit + +Copyright (c) 2012 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 try: # Try to import the library python-mysqldb. import MySQLdb as mysql @@ -77,6 +99,7 @@ class DB(object): columns = [] if self.engine == 'mysqli': + logging.debug('DESCRIBE %s' % table) self.cur.execute('DESCRIBE %s' % table) for column in self.cur.fetchall(): columns.append(column[0]) @@ -93,9 +116,12 @@ class DB(object): pass if self.engine == 'mysqli': - self.cur.execute('CREATE DATABASE `%s` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci' % db) + sql = 'CREATE DATABASE `%s` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci' % db elif self.engine == 'pgsql': - self.cur.execute('CREATE DATABASE "%s" WITH ENCODING \'UNICODE\'' % db) + sql = 'CREATE DATABASE "%s" WITH ENCODING \'UNICODE\'' % db + + logging.debug(sql) + self.cur.execute(sql) try: self.conn.set_isolation_level(old_isolation_level) @@ -106,12 +132,14 @@ class DB(object): count = None if self.engine == 'mysqli': - self.cur.execute("SELECT COUNT('*') FROM information_schema.SCHEMATA WHERE SCHEMA_NAME LIKE '%s'" % db) - count = self.cur.fetchone()[0] + sql = "SELECT COUNT('*') FROM information_schema.SCHEMATA WHERE SCHEMA_NAME LIKE '%s'" % db elif self.engine == 'pgsql': - self.cur.execute("SELECT COUNT('*') FROM pg_database WHERE datname='%s'" % db) - count = self.cur.fetchone()[0] + sql = "SELECT COUNT('*') FROM pg_database WHERE datname='%s'" % db + + logging.debug(sql) + self.cur.execute(sql) + count = self.cur.fetchone()[0] return count > 0 @@ -125,9 +153,12 @@ class DB(object): pass if self.engine == 'mysqli': - self.cur.execute('DROP DATABASE `%s`' % db) + sql = 'DROP DATABASE `%s`' % db elif self.engine == 'pgsql': - self.cur.execute('DROP DATABASE "%s"' % db) + sql = 'DROP DATABASE "%s"' % db + + logging.debug(sql) + self.cur.execute(sql) try: self.conn.set_isolation_level(old_isolation_level) diff --git a/lib/git.py b/lib/git.py index 265b762..c17897a 100644 --- a/lib/git.py +++ b/lib/git.py @@ -22,7 +22,7 @@ along with this program. If not, see . http://github.com/FMCorz/mdk """ -import os +import logging import re import shlex import subprocess @@ -33,7 +33,7 @@ class Git(object): _path = None _bin = None - def __init__(self, path, bin = '/usr/bin/git'): + def __init__(self, path, bin='/usr/bin/git'): self.setPath(path) self.setBin(bin) @@ -60,7 +60,7 @@ class Git(object): result = self.execute(cmd) return result[0] == 0 - def createBranch(self, branch, track = None): + def createBranch(self, branch, track=None): if track != None: cmd = 'branch --track %s %s' % (branch, track) else: @@ -82,7 +82,7 @@ class Git(object): result = self.execute(cmd) return result[0] == 0 - def execute(self, cmd, path = None): + def execute(self, cmd, path=None): if path == None: path = self.getPath() @@ -93,6 +93,8 @@ class Git(object): cmd = shlex.split(str(cmd)) cmd.insert(0, self.getBin()) + logging.debug(' '.join(cmd)) + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, @@ -101,7 +103,7 @@ class Git(object): (stdout, stderr) = proc.communicate() return (proc.returncode, stdout, stderr) - def fetch(self, remote = '', ref = ''): + def fetch(self, remote='', ref=''): cmd = 'fetch %s %s' % (remote, ref) return self.execute(cmd) @@ -131,7 +133,7 @@ class Git(object): remotes[remote] = repo return remotes - def hasBranch(self, branch, remote = ''): + def hasBranch(self, branch, remote=''): if remote != '': cmd = 'show-ref --verify --quiet "refs/remotes/%s/%s"' % (remote, branch) else: @@ -147,7 +149,7 @@ class Git(object): raise GitException('Error while getting hashes. Command: %s' % (cmd)) return hashlist.split('\n')[:-1] - def isRepository(self, path = None): + def isRepository(self, path=None): if path == None: path = self.getPath() @@ -171,11 +173,11 @@ class Git(object): cmd = 'cherry-pick %s' % (args) return self.execute(cmd) - def pull(self, remote = '', ref = ''): + def pull(self, remote='', ref=''): cmd = 'pull %s %s' % (remote, ref) return self.execute(cmd) - def push(self, remote = '', branch = '', force = None): + def push(self, remote='', branch='', force=None): if force: force = '--force ' else: @@ -183,7 +185,7 @@ class Git(object): cmd = 'push %s%s %s' % (force, remote, branch) return self.execute(cmd) - def rebase(self, base = None, branch = None, abort = False): + def rebase(self, base=None, branch=None, abort=False): cmd = None if abort: cmd = 'rebase --abort' @@ -216,7 +218,7 @@ class Git(object): refs.append([hash, ref]) return refs - def reset(self, to, hard = False): + def reset(self, to, hard=False): mode = '' if hard: mode = '--hard' @@ -237,7 +239,7 @@ class Git(object): result = self.execute(cmd) return result[0] == 0 - def stash(self, command = 'save', untracked = False): + def stash(self, command='save', untracked=False): cmd = 'stash %s' % command if untracked: cmd += ' --include-untracked' diff --git a/lib/jira.py b/lib/jira.py index 7fe7841..0cef620 100644 --- a/lib/jira.py +++ b/lib/jira.py @@ -23,12 +23,13 @@ http://github.com/FMCorz/mdk """ import json -from tools import debug, question +from tools import question from config import Conf from urllib import urlencode from urlparse import urlparse from base64 import b64encode from datetime import datetime +import logging import os import httplib try: @@ -243,7 +244,7 @@ class Jira(object): if not update['fields']: # No fields to update - debug('No updates required') + logging.info('No updates required') return True resp = self.request('issue/%s' % (str(key)), method='PUT', data=json.dumps(update)) diff --git a/lib/moodle.py b/lib/moodle.py index 426312e..995996f 100644 --- a/lib/moodle.py +++ b/lib/moodle.py @@ -24,9 +24,10 @@ http://github.com/FMCorz/mdk import os import re +import logging import shutil -from tools import debug, process +from tools import process from db import DB from config import Conf from git import Git @@ -112,7 +113,7 @@ class Moodle(object): self.reload() - def branch_compare(self, branch, compare = '>='): + def branch_compare(self, branch, compare='>='): """Compare the branch of the current instance with the one passed""" try: branch = int(branch) @@ -136,7 +137,7 @@ class Moodle(object): return b < branch return False - def checkout_stable(self, checkout = True): + def checkout_stable(self, checkout=True): """Checkout the stable branch, do a stash if required. Needs to be called again to pop the stash!""" # Checkout the branch @@ -292,7 +293,7 @@ class Moodle(object): def drop(): result = (None, None, None) try: - debug('Dropping database') + logging.info('Dropping database') result = self.cli('/admin/tool/behat/cli/util.php', args='--drop', stdout=None, stderr=None) except: pass @@ -302,7 +303,7 @@ class Moodle(object): def enable(): result = (None, None, None) try: - debug('Enabling Behat') + logging.info('Enabling Behat') result = self.cli('/admin/tool/behat/cli/util.php', args='--enable') except: pass @@ -312,7 +313,7 @@ class Moodle(object): def install(): result = (None, None, None) try: - debug('Installing Behat tables') + logging.info('Installing Behat tables') result = self.cli('/admin/tool/behat/cli/util.php', args='--install', stdout=None, stderr=None) except: pass @@ -357,7 +358,7 @@ class Moodle(object): info[k] = v return info - def install(self, dbname = None, engine = None, dataDir = None, fullname = None, dropDb = False): + def install(self, dbname=None, engine=None, dataDir=None, fullname=None, dropDb=False): """Launch the install script of an Instance""" if self.isInstalled(): @@ -373,7 +374,7 @@ class Moodle(object): fullname = self.identifier.replace('-', ' ').replace('_', ' ').title() fullname = fullname + ' ' + C.get('wording.%s' % engine) - debug('Creating database...') + logging.info('Creating database...') db = DB(engine, C.get('db.%s' % engine)) if db.dbexists(dbname): if dropDb: @@ -391,7 +392,7 @@ class Moodle(object): wwwroot = wwwroot + C.get('path') + '/' wwwroot = wwwroot + self.identifier - debug('Installing %s...' % self.identifier) + logging.info('Installing %s...' % self.identifier) cli = 'admin/cli/install.php' params = (wwwroot, dataDir, engine, dbname, C.get('db.%s.user' % engine), C.get('db.%s.passwd' % engine), C.get('db.%s.host' % engine), fullname, self.identifier, C.get('login'), C.get('passwd')) args = '--wwwroot="%s" --dataroot="%s" --dbtype="%s" --dbname="%s" --dbuser="%s" --dbpass="%s" --dbhost="%s" --fullname="%s" --shortname="%s" --adminuser="%s" --adminpass="%s" --allow-unstable --agree-license --non-interactive' % params @@ -403,8 +404,8 @@ class Moodle(object): os.chmod(configFile, 0666) try: self.addConfig('sessioncookiepath', '/%s/' % self.identifier) - except Exception as e: - debug('Could not append $CFG->sessioncookiepath to config.php') + except Exception: + logging.warning('Could not append $CFG->sessioncookiepath to config.php') self.reload() @@ -532,8 +533,8 @@ class Moodle(object): f.close() - except Exception as e: - debug('Error while reading config file') + except Exception: + logging.exception('Error while reading config file') else: self.installed = False @@ -549,7 +550,7 @@ class Moodle(object): try: self.cli('admin/cli/purge_caches.php', stderr=None, stdout=None) - except Exception as e: + except Exception: raise Exception('Error while purging cache!') def reload(self): @@ -619,7 +620,7 @@ class Moodle(object): os.remove(dest) return result[0] - def update(self, remote = None): + def update(self, remote=None): """Update the instance from the remote""" if remote == None: @@ -634,7 +635,7 @@ class Moodle(object): # Reset HARD upstream = '%s/%s' % (remote, self.get('stablebranch')) - if not self.git().reset(to = upstream, hard = True): + if not self.git().reset(to=upstream, hard=True): raise Exception('Error while executing git reset.') # Return to previous branch @@ -645,7 +646,7 @@ class Moodle(object): self.removeConfig(name) self.addConfig(name, value) - def upgrade(self, nocheckout = False): + def upgrade(self, nocheckout=False): """Calls the upgrade script""" if not self.isInstalled(): raise Exception('Cannot upgrade an instance which is not installed.') @@ -658,7 +659,7 @@ class Moodle(object): cli = '/admin/cli/upgrade.php' args = '--non-interactive --allow-unstable' - result = self.cli(cli, args, stdout = None, stderr = None) + result = self.cli(cli, args, stdout=None, stderr=None) if result[0] != 0: raise Exception('Error while running the upgrade.') diff --git a/lib/tools.py b/lib/tools.py index 3aad2ab..1896cf2 100644 --- a/lib/tools.py +++ b/lib/tools.py @@ -86,11 +86,6 @@ def get_current_user(): return username -def debug(str): - print str - sys.stdout.flush() - - def parseBranch(branch, pattern): pattern = re.compile(pattern, flags=re.I) result = pattern.search(branch) diff --git a/lib/workplace.py b/lib/workplace.py index dd88563..4ddd4ce 100644 --- a/lib/workplace.py +++ b/lib/workplace.py @@ -24,11 +24,9 @@ http://github.com/FMCorz/mdk import os import shutil -from distutils.dir_util import copy_tree - -from tools import debug, process, stableBranch +import logging +from tools import process, stableBranch from config import Conf -import db import git import moodle @@ -37,7 +35,7 @@ C = Conf() class Workplace(object): - def __init__(self, path = None, wwwDir = None, dataDir = None): + def __init__(self, path=None, wwwDir=None, dataDir=None): if path == None: path = C.get('dirs.storage') if wwwDir == None: @@ -62,19 +60,14 @@ class Workplace(object): cacheStable = os.path.join(self.cache, 'moodle.git') cacheIntegration = os.path.join(self.cache, 'integration.git') if not os.path.isdir(cacheStable) and stable: - debug('Cloning stable repository into cache...') - debug('That\'s going to take a while...') + logging.info('Cloning stable repository into cache...') + logging.info('That\'s going to take a while...') process('%s clone --mirror %s %s' % (C.get('git'), C.get('remotes.stable'), cacheStable)) - else: - # TODO Ensure mirror repo - pass + if not os.path.isdir(cacheIntegration) and integration: - debug('Cloning integration repository into cache...') - debug('Have a break, this operation is slow...') + logging.info('Cloning integration repository into cache...') + logging.info('Have a break, this operation is slow...') process('%s clone --mirror %s %s' % (C.get('git'), C.get('remotes.integration'), cacheIntegration)) - else: - # TODO Ensure mirror repo - pass def create(self, name=None, version='master', integration=False, useCacheAsRemote=False): """Creates a new instance of Moodle. @@ -105,15 +98,14 @@ class Workplace(object): repository = os.path.join(self.cache, 'moodle.git') # Clone the instances - debug('Cloning repository...') + logging.info('Cloning repository...') process('%s clone %s %s' % (C.get('git'), repository, wwwDir)) # Symbolic link if os.path.islink(linkDir): os.remove(linkDir) if os.path.isfile(linkDir) or os.path.isdir(linkDir): # No elif! - debug('Could not create symbolic link') - debug('Please manually create: ln -s %s %s' (wwwDir, linkDir)) + logging.warning('Could not create symbolic link. Please manually create: ln -s %s %s' (wwwDir, linkDir)) else: os.symlink(wwwDir, linkDir) @@ -123,7 +115,7 @@ class Workplace(object): if not os.path.isfile(linkDataDir) and not os.path.isdir(linkDataDir) and not os.path.islink(linkDataDir): os.symlink(dataDir, linkDataDir) - debug('Checking out branch...') + logging.info('Checking out branch...') repo = git.Git(wwwDir, C.get('git')) # Setting up the correct remote names @@ -135,7 +127,7 @@ class Workplace(object): branch = stableBranch(version) track = '%s/%s' % (C.get('upstreamRemote'), branch) if not repo.hasBranch(branch) and not repo.createBranch(branch, track): - debug('Could not create branch %s tracking %s' % (branch, track)) + logging.error('Could not create branch %s tracking %s' % (branch, track)) else: repo.checkout(branch) repo.pull(remote=C.get('upstreamRemote')) @@ -157,7 +149,7 @@ class Workplace(object): if os.path.islink(link): try: os.remove(link) - except Exception as e: + except Exception: pass # Delete db @@ -198,9 +190,9 @@ class Workplace(object): if not self.isMoodle(name): raise Exception('Could not find Moodle instance %s' % name) - return moodle.Moodle(os.path.join(self.path, name, self.wwwDir), identifier = name) + return moodle.Moodle(os.path.join(self.path, name, self.wwwDir), identifier=name) - def getPath(self, name, mode = None): + def getPath(self, name, mode=None): """Returns the path of an instance base on its name""" base = os.path.join(self.path, name) if mode == 'www': @@ -226,7 +218,7 @@ class Workplace(object): return True - def list(self, integration = None, stable = None): + def list(self, integration=None, stable=None): """Return the list of Moodle instances""" dirs = os.listdir(self.path) names = [] @@ -241,7 +233,7 @@ class Workplace(object): names.append(d) return names - def resolve(self, name = None, path = None): + def resolve(self, name=None, path=None): """Try to find a Moodle instance based on its name, a path or the working directory""" if name != None: @@ -263,7 +255,7 @@ class Workplace(object): return False - def resolveMultiple(self, names = []): + def resolveMultiple(self, names=[]): """Return multiple instances""" if type(names) != list: if type(names) == str: @@ -275,18 +267,18 @@ class Workplace(object): if len(names) < 1: M = self.resolve() if M: - return [ M ] + return [M] else: - return [ ] + return [] # Try to resolve each instance result = [] for name in names: - M = self.resolve(name = name) + M = self.resolve(name=name) if M: result.append(M) else: - debug('Could not find instance called %s' % name) + logging.info('Could not find instance called %s' % name) return result def updateCachedClones(self, integration=True, stable=True, verbose=True): @@ -305,8 +297,7 @@ class Workplace(object): repo = git.Git(cache, C.get('git')) - verbose and debug('Working on %s...' % cache) - verbose and debug('Fetching...') + logging.info('Fetching cached repository %s...' % os.path.basename(cache)) if not repo.fetch(): raise Exception('Could not fetch in repository %s' % (cache)) diff --git a/mdk.py b/mdk.py index 26d699d..55bb2a2 100755 --- a/mdk.py +++ b/mdk.py @@ -26,6 +26,7 @@ import sys import argparse import os import re +import logging from lib.command import CommandRunner from lib.commands import getCommand, commandsList from lib.config import Conf @@ -34,6 +35,13 @@ from version import __version__ C = Conf() +try: + debuglevel = getattr(logging, C.get('debug').upper()) +except AttributeError: + debuglevel = logging.WARNING + +logging.basicConfig(format='%(message)s', level=debuglevel) + availaliases = [str(x) for x in C.get('aliases').keys()] choices = sorted(commandsList + availaliases) @@ -80,4 +88,10 @@ if alias != None: cls = getCommand(cmd) Cmd = cls(C) Runner = CommandRunner(Cmd) -Runner.run(args, prog='%s %s' % (os.path.basename(sys.argv[0]), cmd)) +try: + Runner.run(args, prog='%s %s' % (os.path.basename(sys.argv[0]), cmd)) +except Exception as e: + import traceback + info = sys.exc_info() + logging.error('%s: %s', e.__class__.__name__, e) + logging.debug(''.join(traceback.format_tb(info[2]))) -- 2.11.0