"pgsql": "PostgreSQL"
},
- // The information for publishing diff urls to tracker
- "jira": {
+ // The information for integrating MDK with Jira
+ "tracker": {
"url": "https://tracker.moodle.org/",
"username": "me",
"fieldnames" : {
"master" : {
"branch" : "Pull Master Branch",
"diffurl" : "Pull Master Diff URL"
- },
+ }
}
},
- // The base for github diff urls
- "diffUrlTemplate": "https://github.com/me/moodle/compare/%headcommit%...%branch%",
+ // The base for diff URLs, you can use the following wildcards:
+ // - %branch%: The branch name;
+ // - %stablebranch%: The stable branch (MOODLE_23_STABLE, MOODLE_24_STABLE, master, ...);
+ // - %headcommit%: The head commit.
+ // This is used to populate the fields on the tracker issue.
+ "diffUrlTemplate": "https://github.com/YourGitHub/moodle/compare/%headcommit%...%branch%",
+
+ // The public acccess URL of your repository. It is used to populate the fields on the tracker issue.
+ "repositoryUrl": "git://github.com/YourGitHub/moodle.git",
// The host name to set during an install
"host": "localhost",
(returncode, stdout, stderr) = self.execute(cmd)
return returncode == 0
+ def hashes(self, ref='', format='%H', limit=30):
+ """Returns the latest hashes from git log"""
+ cmd = 'log %s -n %d --format=%s' % (ref, limit, format)
+ hashlist = self.execute(cmd)
+ return hashlist[1].split('\n')[:-1]
+
def isRepository(self, path = None):
if path == None:
path = self.getPath()
cmd = 'pull %s %s' % (remote, ref)
return self.execute(cmd)
- def hashes(self, ref = '', format = '%H', limit = 30):
- cmd = 'log %s -n %d --format=%s' % (ref, limit, format)
- hashlist = self.execute(cmd)
- return hashlist[1].split('\n')[:-1]
-
def push(self, remote = '', branch = '', force = None):
if force:
force = '--force '
http://github.com/FMCorz/mdk
"""
+import sys
import json
-
-from tools import debug, process
+from tools import debug
from config import Conf
import getpass
-import keyring
-from restkit import request, BasicAuth
+try:
+ from restkit import request, BasicAuth
+except:
+ debug('Could not load module restkit for Jira.')
+ debug('Try `apt-get install python-restkit`, or visit http://pypi.python.org/pypi/restkit')
+ debug('Exiting...')
+ sys.exit(1)
+try:
+ import keyring
+except:
+ debug('Could not load module keyring. You might want to install it.')
+ debug('Try `apt-get install python-keyring`, or visit http://pypi.python.org/pypi/keyring')
+ pass
C = Conf()
+
class Jira(object):
serverurl = ''
self.version = {}
self._load()
- def get(self, param, default = None):
+ def get(self, param, default=None):
"""Returns a property of this instance"""
return self.info().get(param, default)
- def info(self):
- """Returns a dictionary of information about this instance"""
- info = {}
- self._load()
- for (k, v) in self.version.items():
- info[k] = v
- return info
-
- def get_issue(self, key):
+ def getIssue(self, key):
"""Load the issue info from the jira server using a rest api call"""
requesturl = self.url + 'rest/api/' + self.apiversion + '/issue/' + key + '?expand=names'
- response = request(requesturl, filters=[self.auth]);
+ response = request(requesturl, filters=[self.auth])
if response.status_int == 404:
raise JiraException('Issue could not be found.')
issue = json.loads(response.body_string())
return issue
- def get_server_info(self):
+ def getServerInfo(self):
"""Load the version info from the jira server using a rest api call"""
requesturl = self.url + 'rest/api/' + self.apiversion + '/serverInfo'
- response = request(requesturl, filters=[self.auth]);
+ response = request(requesturl, filters=[self.auth])
if not response.status_int == 200:
raise JiraException('Jira is not available: ' + response.status)
serverinfo = json.loads(response.body_string())
self.version = serverinfo
+ def info(self):
+ """Returns a dictionary of information about this instance"""
+ info = {}
+ self._load()
+ for (k, v) in self.version.items():
+ info[k] = v
+ return info
+
def _load(self):
"""Loads the information"""
return True
# First get the jira details from the config file.
- self.url = C.get('jira.url')
- self.username = C.get('jira.username')
- # str() is needed because keyring does not handle unicode.
- self.password = keyring.get_password('mdk-jira-password', str(self.username))
+ self.url = C.get('tracker.url')
+ self.username = C.get('tracker.username')
+
+ try:
+ # str() is needed because keyring does not handle unicode.
+ self.password = keyring.get_password('mdk-jira-password', str(self.username))
+ except:
+ # Do not die if keyring package is not available.
+ self.password = None
+ pass
if not self.url or not self.username:
raise JiraException('Jira has not been configured in the config file.')
self.auth = BasicAuth(self.username, self.password)
try:
- self.get_server_info()
+ self.getServerInfo()
self._loaded = True
except JiraException:
print 'Either the password is incorrect or you may need to enter a Captcha to continue.'
if not self._loaded:
- self.password = getpass.getpass('Jira password for user %s:' % self.username)
- keyring.set_password('mdk-jira-password', str(self.username), str(self.password))
+ self.password = getpass.getpass('Jira password for user %s: ' % self.username)
+
+ try:
+ keyring.set_password('mdk-jira-password', str(self.username), str(self.password))
+ except:
+ # Do not die if keyring package is not available.
+ pass
return True
- def set_custom_fields(self, key, updates):
- """ Set a list of fields for this issue in Jira
+ def reload(self):
+ """Reloads the information"""
+ self._loaded = False
+ return self._load()
+
+ def setCustomFields(self, key, updates):
+ """Set a list of fields for this issue in Jira
The updates parameter is a dictionary of key values where the key is the custom field name
- and the value is the new value to set. This only works for fields of type text.
+ and the value is the new value to set.
+
+ /!\ This only works for fields of type text.
"""
- issue = self.get_issue(key)
+ issue = self.getIssue(key)
- customfieldkey = ''
namelist = {}
- update = { 'fields' : {} }
+ update = {'fields': {}}
namelist = issue['names']
for fieldkey in issue['fields']:
return True
requesturl = self.url + 'rest/api/' + self.apiversion + '/issue/' + key
- response = request(requesturl, filters=[self.auth], method='PUT', body=json.dumps(update), headers={'Content-Type' : 'application/json'});
+ response = request(requesturl, filters=[self.auth], method='PUT', body=json.dumps(update), headers={'Content-Type': 'application/json'})
if response.status_int != 204:
raise JiraException('Issue was not updated:' + response.status)
return True
- def reload(self):
- """Reloads the information"""
- self._loaded = False
- return self._load()
class JiraException(Exception):
pass
else:
debug('Popped the stash')
- # Update jira
- if args.updatejira:
- repositoryurl = C.get('repositoryUrl')
- diffurltemplate = C.get('diffUrlTemplate')
- stablebranch = M2.get('stablebranch')
- upstreamremote = C.get('upstreamRemote')
- # Get the hash of the last upstream commit
- ref = '%s/%s' % (upstreamremote, stablebranch)
- headcommit = M.git().hashes(ref=ref, limit=1)[0]
-
- J = jira.Jira()
- diffurl = diffurltemplate.replace('%branch%', newbranch).replace('%stablebranch%', stablebranch).replace('%headcommit%', headcommit)
-
- fieldrepositoryurl = C.get('jira.fieldnames.repositoryurl')
- fieldbranch = C.get('jira.fieldnames.%s.branch' % v)
- fielddiffurl = C.get('jira.fieldnames.%s.diffurl' % v)
-
- if not (fieldrepositoryurl or fieldbranch or fielddiffurl):
- debug('Cannot set Jira fields for this version(%s) as the field names are not configured in the config file.', v)
-
- else:
- debug('Setting jira fields: \n\t%s: %s \n\t%s: %s \n\t%s: %s\n' % (fieldrepositoryurl, repositoryurl,
- fieldbranch, newbranch,
- fielddiffurl, diffurl))
- J.set_custom_fields(issue, { fieldrepositoryurl : repositoryurl,
- fieldbranch : newbranch,
- fielddiffurl : diffurl })
-
debug('Instance %s successfully patched!' % name)
debug('')
import sys
import argparse
-from lib import workplace, moodle, tools, jira
+from lib import workplace, tools, jira
from lib.tools import debug
from lib.config import Conf
parser = argparse.ArgumentParser(description="Push a branch to a remote.")
parser.add_argument('-b', '--branch', metavar='branch', help='the branch to push. Default is current branch.')
parser.add_argument('-r', '--remote', metavar='remote', help='remote to push to. Default is your remote.')
-parser.add_argument('-f', '--force', action='store_true', help='force the push (does not apply on the stable branch)')
-parser.add_argument('-j', '--update-jira', action='store_true', help='also add the github links to the jira issue.', dest='updatejira')
+parser.add_argument('-f', '--force', action='store_true', help='force the push (does not apply on the stable branch).')
+parser.add_argument('-t', '--update-tracker', action='store_true', help='also add the diff information to the tracker issue.', dest='updatetracker')
parser.add_argument('-s', '--include-stable', action='store_true', help='also push the stable branch (MOODLE_xx_STABLE, master)', dest='includestable')
parser.add_argument('-k', '--force-stable', action='store_true', help='force the push on the stable branch', dest='forcestable')
parser.add_argument('name', metavar='name', default=None, nargs='?', help='name of the instance to work on')
# Setting remote
if args.remote == None:
- remote = C.get('myRemote')
+ remote = C.get('myRemote')
else:
- remote = args.remote
+ remote = args.remote
# Setting branch
if args.branch == None:
- branch = M.currentBranch()
- if branch == 'HEAD':
- debug('Cannot push HEAD branch')
- sys.exit(1)
+ branch = M.currentBranch()
+ if branch == 'HEAD':
+ debug('Cannot push HEAD branch')
+ sys.exit(1)
else:
- branch = args.branch
-
+ branch = args.branch
# Pushing current branch
debug('Pushing branch %s to remote %s...' % (branch, remote))
result = M.git().push(remote, branch, force=args.force)
if result[0] != 0:
- debug(result[2])
- sys.exit(1)
+ debug(result[2])
+ sys.exit(1)
-if args.updatejira:
+if args.updatetracker:
# Getting issue number
# Parsing the branch
parsedbranch = tools.parseBranch(branch, C.get('wording.branchRegex'))
J = jira.Jira()
diffurl = diffurltemplate.replace('%branch%', branch).replace('%stablebranch%', stablebranch).replace('%headcommit%', headcommit)
- fieldrepositoryurl = C.get('jira.fieldnames.repositoryurl')
- fieldbranch = C.get('jira.fieldnames.%s.branch' % version)
- fielddiffurl = C.get('jira.fieldnames.%s.diffurl' % version)
+ fieldrepositoryurl = C.get('tracker.fieldnames.repositoryurl')
+ fieldbranch = C.get('tracker.fieldnames.%s.branch' % version)
+ fielddiffurl = C.get('tracker.fieldnames.%s.diffurl' % version)
if not (fieldrepositoryurl or fieldbranch or fielddiffurl):
- debug('Cannot set Jira fields for this version(%s) as the field names are not configured in the config file.', version)
+ debug('Cannot set tracker fields for this version (%s) as the field names are not configured in the config file.', version)
else:
- debug('Setting jira fields: \n\t%s: %s \n\t%s: %s \n\t%s: %s\n' % (fieldrepositoryurl, repositoryurl,
+ debug('Setting tracker fields: \n\t%s: %s \n\t%s: %s \n\t%s: %s\n' % (fieldrepositoryurl, repositoryurl,
fieldbranch, branch,
fielddiffurl, diffurl))
- J.set_custom_fields(issue, { fieldrepositoryurl : repositoryurl,
- fieldbranch : branch,
- fielddiffurl : diffurl })
+ J.setCustomFields(issue, {fieldrepositoryurl: repositoryurl,
+ fieldbranch: branch,
+ fielddiffurl: diffurl})
# Pushing stable branch
if args.includestable:
- branch = M.get('stablebranch')
- debug('Pushing branch %s to remote %s...' % (branch, remote))
- result = M.git().push(remote, branch, force=args.forcestable)
- if result[0] != 0:
- debug(result[2])
- sys.exit(1)
+ branch = M.get('stablebranch')
+ debug('Pushing branch %s to remote %s...' % (branch, remote))
+ result = M.git().push(remote, branch, force=args.forcestable)
+ if result[0] != 0:
+ debug(result[2])
+ sys.exit(1)
debug('Done.')