Ejemplo n.º 1
0
    def run(self, args):

        M = self.Wp.resolve(args.name)
        if not M:
            raise Exception('This is not a Moodle instance')

        # Setting remote
        remote = args.remote

        # Setting branch
        if args.branch == None:
            branch = M.currentBranch()
            if branch == 'HEAD':
                raise Exception('Cannot push HEAD branch')
        else:
            branch = args.branch

        # Extra test to see if the commit message is correct. This prevents easy typos in branch or commit messages.
        parsedbranch = tools.parseBranch(branch, self.C.get('wording.branchRegex'))
        if parsedbranch or branch != M.get('stablebranch'):
            message = M.git().messages(count=1)[0]
            mdl = message.split(' ')[0]
            if parsedbranch:
                branchmdl = 'MDL-%s' % (parsedbranch['issue'])
            else:
                branchmdl = branch
            if mdl != branchmdl:
                print 'The MDL number in the last commit does not match the branch being pushed to.'
                print 'Branch: %s vs. commit: %s' % (branchmdl, mdl)
                answer = tools.question('Are you sure you want to continue?', default='n')
                if answer.lower()[0] != 'y':
                    print 'Exiting...'
                    return

        # Pushing current branch
        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])

        # Update the tracker
        if args.updatetracker:
            M.updateTrackerGitInfo(branch=branch)

        # Pushing stable branch
        if args.includestable:
            branch = M.get('stablebranch')
            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])

        logging.info('Done.')
Ejemplo n.º 2
0
    description='Initialise MDK for the current user.')
parser.add_argument('-f',
                    '--force',
                    action='store_true',
                    help='Force the initialisation')
args = parser.parse_args()

# Check root.
if os.getuid() != 0:
    debug('You must execute this as root.')
    debug('  sudo mdk init')
    sys.exit(1)

# Check what user we want to initialise for.
while True:
    username = question('What user are you initialising MDK for?',
                        get_current_user())
    try:
        user = pwd.getpwnam(username)
    except:
        debug('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))
        continue

    break

# Default directories.
Ejemplo n.º 3
0
    def run(self, args):

        M = self.Wp.resolve()
        if not M:
            raise Exception('This is not a Moodle instance')

        if (args.testing and args.integration) or (args.testing and args.nomerge) or (args.integration and args.nomerge):
            raise Exception('You cannot combine --integration, --testing or --no-merge')

        # Tracker issue number.
        issuenb = args.issue
        if not issuenb:
            parsedbranch = tools.parseBranch(M.currentBranch(), self.C.get('wording.branchRegex'))
            if not parsedbranch:
                raise Exception('Could not extract issue number from %s' % M.currentBranch())
            issuenb = parsedbranch['issue']

        issue = re.sub(r'(MDL|mdl)(-|_)?', '', issuenb)
        mdl = 'MDL-' + issue

        # Reading the information about the current instance.
        branch = M.get('branch')

        # Get information from Tracker
        logging.info('Retrieving information about %s from Moodle Tracker' % (mdl))
        J = jira.Jira()
        issueInfo = J.getIssue(mdl)

        mode = 'pull'
        remoteUrl = issueInfo.get('named').get(self.C.get('tracker.fieldnames.repositoryurl'))
        remoteBranch = issueInfo.get('named').get(self.C.get('tracker.fieldnames.%s.branch' % (branch)))
        patchesToApply = []

        if not args.nomerge and (not remoteUrl or not remoteBranch):
            mode = None
            attachments = issueInfo.get('fields').get('attachment')
            patches = {}
            for attachment in attachments:
                if attachment['filename'].endswith('.patch'):
                    patches[attachment['filename']] = attachment

            if len(patches) > 0:
                mapping = {}
                i = 1
                for key in sorted(patches.keys()):
                    patch = patches[key]
                    mapping[i] = patch
                    date = jira.Jira.parseDate(patch['created'])
                    print '{0:<2}: {1:<60} {2}'.format(i, patch['filename'][:60], datetime.strftime(date, '%Y-%m-%d %H:%M'))
                    i += 1

                ids = question('What patches would you like to apply?')
                if ids:
                    ids = re.split(r'\s*[, ]\s*', ids)
                    for i in ids:
                        i = int(i)
                        if not i in mapping.keys():
                            continue
                        j = 0
                        while True:
                            mapping[i]['mdk-filename'] = mapping[i]['filename'] + (('.' + str(j)) if j > 0 else '')
                            j += 1
                            if not os.path.isfile(mapping[i]['mdk-filename']):
                                break
                        patchesToApply.append(mapping[i])
                    mode = 'patch'
            else:
                mode = False

        if not mode:
            raise Exception('Did not find enough information to pull a patch.')

        # Stash
        stash = M.git().stash(untracked=True)
        if stash[0] != 0:
            raise Exception('Error while trying to stash your changes. Exiting...')
        elif not stash[1].startswith('No local changes'):
            logging.info('Stashed your local changes')

        # Create a testing branch
        if args.testing:
            i = 0
            while True:
                i += 1
                suffix = 'test' if i <= 1 else 'test' + str(i)
                newBranch = M.generateBranchName(issue, suffix=suffix, version=branch)
                if not M.git().hasBranch(newBranch):
                    break
            track = '%s/%s' % (self.C.get('upstreamRemote'), M.get('stablebranch'))
            M.git().createBranch(newBranch, track=track)
            if not M.git().checkout(newBranch):
                raise Exception('Could not checkout 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')):
                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:
            i = 0
            while True:
                i += 1
                suffix = 'nomerge' if i <= 1 else 'nomerge' + str(i)
                newBranch = M.generateBranchName(issue, suffix=suffix, version=branch)
                if not M.git().hasBranch(newBranch):
                    break
            track = '%s/%s' % (self.C.get('upstreamRemote'), M.get('stablebranch'))
            M.git().createBranch(newBranch, track=track)
            if not M.git().checkout(newBranch):
                raise Exception('Could not checkout branch %s' % (newBranch))
            logging.info('Checked out branch %s' % (newBranch))
            mode = 'nomerge'

        if mode == 'pull':
            # Pull branch from tracker
            logging.info('Pulling branch %s from %s into %s' % (remoteBranch, remoteUrl, M.currentBranch()))
            M.git().pull(remote=remoteUrl, ref=remoteBranch)

        elif mode == 'patch':
            # Apply a patch from tracker
            files = []
            for patch in patchesToApply:
                dest = patch['mdk-filename']
                logging.info('Downloading %s' % (patch['filename']))
                if not J.download(patch['content'], dest):
                    logging.error('Failed to download. Aborting...')
                    files = []
                    break
                files.append(dest)

            if len(files) > 0:
                logging.info('Applying patch(es)...')
                if not M.git().apply(files):
                    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.
            logging.info('Fetching %s %s' % (remoteUrl, remoteBranch))
            M.git().fetch(remote=remoteUrl, ref=remoteBranch)
            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:
                logging.error('An error ocured while unstashing your changes')
            else:
                logging.info('Popped the stash')

        logging.info('Done.')
Ejemplo n.º 4
0
    def run(self, args):

        M = self.Wp.resolve(args.name)
        if not M:
            raise Exception('This is not a Moodle instance')

        # Setting remote
        remote = args.remote

        # Setting branch
        if args.branch == None:
            branch = M.currentBranch()
            if branch == 'HEAD':
                raise Exception('Cannot push HEAD branch')
        else:
            branch = args.branch

        # Extra test to see if the commit message is correct. This prevents easy typos in branch or commit messages.
        parsedbranch = tools.parseBranch(branch, self.C.get('wording.branchRegex'))
        if parsedbranch or branch != M.get('stablebranch'):
            message = M.git().messages(count=1)[0]

            mdl = getMDLFromCommitMessage(message)

            if parsedbranch:
                branchmdl = 'MDL-%s' % (parsedbranch['issue'])
            else:
                branchmdl = branch

            if not mdl or mdl != branchmdl:
                if not mdl:
                    print 'The MDL number could not be found in the commit message.'
                    print 'Commit: %s' % (message)

                elif mdl != branchmdl:
                    print 'The MDL number in the last commit does not match the branch being pushed to.'
                    print 'Branch: \'%s\' vs. commit: \'%s\'' % (branchmdl, mdl)

                answer = tools.question('Are you sure you want to continue?', default='n')
                if answer.lower()[0] != 'y':
                    print 'Exiting...'
                    return

        J = jira.Jira()

        # If the mode is not set to patch yet, and we can identify the MDL number.
        if not args.patch and parsedbranch:
            mdlIssue = 'MDL-%s' % (parsedbranch['issue'])
            args.patch = J.isSecurityIssue(mdlIssue)
            if args.patch:
                logging.info('%s appears to be a security issue, switching to patch mode...' % (mdlIssue))

        if args.patch:
            if not M.pushPatch(branch):
                return

        else:
            # Pushing current branch
            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])

            # Update the tracker
            if args.updatetracker != None:
                ref = None if args.updatetracker == True else args.updatetracker
                M.updateTrackerGitInfo(branch=branch, ref=ref)

            # Pushing stable branch
            if args.includestable:
                branch = M.get('stablebranch')
                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])

        logging.info('Done.')
Ejemplo n.º 5
0
    def run(self, args):

        # Check root.
        if os.getuid() != 0:
            raise Exception('You must execute this as root.\n  sudo mdk init')

        # Check what user we want to initialise for.
        while True:
            username = question('What user are you initialising MDK for?', get_current_user())
            try:
                user = pwd.getpwnam(username)
            except:
                logging.warning('Error while getting information for user %s' % (username))
                continue

            try:
                usergroup = grp.getgrgid(user.pw_gid)
            except:
                logging.warning('Error while getting the group of user %s' % (username))
                continue

            break

        # Default directories.
        userdir = self.resolve_directory('~/.moodle-sdk', username)
        scriptdir = os.path.dirname(os.path.realpath(__file__))

        # Create the main MDK folder.
        if not os.path.isdir(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):
            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):
            logging.info('Creating user config file in %s.' % userconfigfile)
            open(userconfigfile, 'w')
            os.chown(userconfigfile, user.pw_uid, usergroup.gr_gid)

        # If the group moodle-sdk exists, then we want to add the user to it.
        try:
            group = grp.getgrnam('moodle-sdk')
            if not username in group.gr_mem:
                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])
                chgrp.wait()
        except KeyError:
            # Raised when the group has not been found.
            group = None
            pass

        # Loading the configuration.
        from lib.config import Conf as Config
        C = Config(userfile=userconfigfile)

        # Asks the user what needs to be asked.
        while True:
            www = question('What is the DocumentRoot of your virtual host?', C.get('dirs.www'))
            www = self.resolve_directory(www, username)
            try:
                if not os.path.isdir(www):
                    os.mkdir(www, 0775)
                    os.chown(www, user.pw_uid, usergroup.gr_gid)
            except:
                logging.error('Error while creating directory %s' % www)
                continue
            else:
                C.set('dirs.www', www)
                break

        while True:
            storage = question('Where do you want to store your Moodle instances?', C.get('dirs.storage'))
            storage = self.resolve_directory(storage, username)
            try:
                if not os.path.isdir(storage):
                    if storage != www:
                        os.mkdir(storage, 0775)
                        os.chown(storage, user.pw_uid, usergroup.gr_gid)
                    else:
                        logging.error('Error! dirs.www and dirs.storage must be different!')
                        continue
            except:
                logging.error('Error while creating directory %s' % storage)
                continue
            else:
                C.set('dirs.storage', storage)
                break

        # The default configuration file should point to the right directory for dirs.mdk,
        # we will just ensure that it exists.
        mdkdir = C.get('dirs.mdk')
        mdkdir = self.resolve_directory(mdkdir, username)
        if not os.path.isdir(mdkdir):
            try:
                logging.info('Creating MDK directory %s' % mdkdir)
                os.mkdir(mdkdir, 0775)
                os.chown(mdkdir, user.pw_uid, usergroup.gr_gid)
            except:
                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)')
        if github != None:
            C.set('remotes.mine', C.get('remotes.mine').replace('YourGitHub', github))
            C.set('repositoryUrl', C.get('repositoryUrl').replace('YourGitHub', github))
            C.set('diffUrlTemplate', C.get('diffUrlTemplate').replace('YourGitHub', github))
            C.set('myRemote', 'github')
            C.set('upstreamRemote', 'origin')
        else:
            C.set('remotes.mine', question('What is your remote?', C.get('remotes.mine')))
            C.set('myRemote', question('What to call your remote?', C.get('myRemote')))
            C.set('upstreamRemote', question('What to call the upsream remote (official Moodle remote)?', C.get('upstreamRemote')))

        # Database settings.
        C.set('db.mysqli.user', question('What is your MySQL user?', C.get('db.mysqli.user')))
        C.set('db.mysqli.passwd', question('What is your MySQL password?', C.get('db.mysqli.passwd'), password=True))
        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))

        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`'
Ejemplo n.º 6
0
    return path

# Arguments
parser = argparse.ArgumentParser(description='Initialise MDK for the current user.')
parser.add_argument('-f', '--force', action='store_true', help='Force the initialisation')
args = parser.parse_args()

# Check root.
if os.getuid() != 0:
    debug('You must execute this as root.')
    debug('  sudo mdk init')
    sys.exit(1)

# Check what user we want to initialise for.
while True:
    username = question('What user are you initialising MDK for?', get_current_user())
    try:
        user = pwd.getpwnam(username)
    except:
        debug('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))
        continue

    break

# Default directories.