370 lines
14 KiB
Python
370 lines
14 KiB
Python
# Additional mappings that are not present in the pygments lexers
|
|
# used for building stats
|
|
# format is {'ext':['Names']} eg. {'py':['Python']} note: there can be
|
|
# more than one name for extension
|
|
# NOTE: that this will overide any mappings in LANGUAGES_EXTENSIONS_MAP
|
|
# build by pygments
|
|
EXTRA_MAPPINGS = {}
|
|
|
|
# additional lexer definitions for custom files
|
|
# it's overrides pygments lexers, and uses defined name of lexer to colorize the
|
|
# files. Format is {'ext': 'lexer_name'}
|
|
# List of lexers can be printed running:
|
|
# python -c "import pprint;from pygments import lexers;pprint.pprint([(x[0], x[1]) for x in lexers.get_all_lexers()]);"
|
|
|
|
EXTRA_LEXERS = {}
|
|
|
|
#==============================================================================
|
|
# WHOOSH INDEX EXTENSIONS
|
|
#==============================================================================
|
|
# if INDEX_EXTENSIONS is [] it'll use pygments lexers extensions by default.
|
|
# To set your own just add to this list extensions to index with content
|
|
INDEX_EXTENSIONS = []
|
|
|
|
# additional extensions for indexing besides the default from pygments
|
|
# those get's added to INDEX_EXTENSIONS
|
|
EXTRA_INDEX_EXTENSIONS = []
|
|
|
|
# without trailing slash
|
|
# CHANGE NEXT TWO VARIABLES, if no auth is required JENKINS_AUTH can be None
|
|
JENKINS_URL = 'http://CHANGEME/jenkins'
|
|
import base64
|
|
JENKINS_AUTH = "Basic {0}".format(base64.b64encode("{0}:{1}".format('CHANGEME-username', 'CHANGEME-apikey')))
|
|
|
|
def cleanRepoNameJenkins(repo_name):
|
|
if repo_name is None:
|
|
return None
|
|
try:
|
|
# 2 options, either strip off everything before last /, results in possible duplicates
|
|
#return repo_name[repo_name.rindex('/')+1:]
|
|
# or replace all / with _, no duplicates
|
|
return repo_name.replace('/', '_')
|
|
except Exception as e:
|
|
#raise
|
|
return repo_name
|
|
|
|
# generic helper functions to get and post resources
|
|
|
|
def getUrl(url, **kwargs):
|
|
#print 'url:', url, 'kwargs:', kwargs
|
|
import urllib2
|
|
req = urllib2.Request(url, **kwargs)
|
|
f = urllib2.urlopen(req)
|
|
ret = f.read().strip()
|
|
f.close()
|
|
return ret
|
|
|
|
def getJenkins(url, **kwargs):
|
|
if JENKINS_AUTH is not None:
|
|
if 'headers' not in kwargs:
|
|
kwargs['headers'] = {}
|
|
kwargs['headers']['Authorization'] = JENKINS_AUTH
|
|
return getUrl(JENKINS_URL + url, **kwargs)
|
|
|
|
def postJenkins(url, **kwargs):
|
|
if 'data' not in kwargs:
|
|
kwargs['data'] = '' # force POST
|
|
return getJenkins(url, **kwargs)
|
|
|
|
# specific functions to make jenkins do certain things
|
|
|
|
def deleteJenkins(**kwargs):
|
|
import urllib2
|
|
try:
|
|
postJenkins('/job/%(jenkins_job)s/doDelete' % kwargs)
|
|
output = 'successful!'
|
|
except urllib2.HTTPError as e:
|
|
output = 'Error code '+str(e.code)
|
|
if output:
|
|
print 'Jenkins: Delete job %(jenkins_job)s' % kwargs, output
|
|
return 0
|
|
|
|
def pollJenkins(**kwargs):
|
|
import urllib2
|
|
try:
|
|
# only supported for mercurial, the second should be supported for everything
|
|
#if kwargs['scm'] == 'hg':
|
|
# output = getJenkins('/mercurial/notifyCommit?url=%(server_url)s/%(repository)s' % kwargs)
|
|
postJenkins('/job/%(jenkins_job)s/polling' % kwargs)
|
|
output = 'Scheduled polling of %(jenkins_job)s' % kwargs
|
|
output = 'successfully!'
|
|
except urllib2.HTTPError as e:
|
|
output = 'Error code '+str(e.code)
|
|
if output:
|
|
print 'Jenkins: Scheduled polling of %(jenkins_job)s' % kwargs, output
|
|
return 0
|
|
|
|
def jsonJenkins(url):
|
|
import urllib2, json
|
|
try:
|
|
ret = json.loads(postJenkins(url))
|
|
except urllib2.HTTPError as e:
|
|
ret = "Error code "+str(e.code)
|
|
return ret
|
|
|
|
def lastBuildStatusJenkins(**kwargs):
|
|
job = jsonJenkins('/job/%(jenkins_job)s/api/json' % kwargs)
|
|
if isinstance(job, basestring):
|
|
print "Jenkins:", job
|
|
return 0
|
|
#print 'jsonJenkins:', job
|
|
lastBuild = job['lastBuild']
|
|
if lastBuild is None:
|
|
print 'Jenkins: No builds yet for', kwargs['jenkins_job']
|
|
return 0
|
|
lastSuccessfulBuild = job['lastSuccessfulBuild']
|
|
if lastSuccessfulBuild is None:
|
|
print 'Jenkins: No successful builds yet for', kwargs['jenkins_job']
|
|
print 'Jenkins: Last build failed: ', lastBuild['url']
|
|
return 0
|
|
if lastBuild['number'] == lastSuccessfulBuild['number']:
|
|
print 'Jenkins: Last build was successful: ', lastBuild['url']
|
|
else:
|
|
print 'Jenkins: Last build failed: ', lastBuild['url']
|
|
print 'Jenkins: Last successful build: ', lastSuccessfulBuild['url']
|
|
return 0
|
|
|
|
# obviously this can go away when all info is sent into all functions
|
|
def getRepoDescription(repo_name):
|
|
try:
|
|
#from rhodecode.bin.base import json, api_call
|
|
from rhodecode.lib.compat import json
|
|
#from rhodecode.tests.api.api_base import api_call
|
|
|
|
def api_call(apikey, apihost, method=None, **kw):
|
|
import random
|
|
import urllib2
|
|
import pprint
|
|
"""
|
|
Api_call wrapper for RhodeCode.
|
|
|
|
:param apikey:
|
|
:param apihost:
|
|
:param format: formatting, pretty means prints and pprint of json
|
|
json returns unparsed json
|
|
:param method:
|
|
:returns: json response from server
|
|
"""
|
|
def _build_data(random_id):
|
|
"""
|
|
Builds API data with given random ID
|
|
|
|
:param random_id:
|
|
"""
|
|
return {
|
|
"id": random_id,
|
|
"api_key": apikey,
|
|
"method": method,
|
|
"args": kw
|
|
}
|
|
|
|
if not method:
|
|
raise Exception('please specify method name !')
|
|
|
|
id_ = random.randrange(1, 9999)
|
|
req = urllib2.Request('%s/_admin/api' % apihost,
|
|
data=json.dumps(_build_data(id_)),
|
|
headers={'content-type': 'text/plain'})
|
|
ret = urllib2.urlopen(req)
|
|
raw_json = ret.read()
|
|
json_data = json.loads(raw_json)
|
|
id_ret = json_data['id']
|
|
if id_ret == id_:
|
|
return json_data
|
|
|
|
else:
|
|
_formatted_json = pprint.pformat(json_data)
|
|
raise Exception('something went wrong. '
|
|
'ID mismatch got %s, expected %s | %s' % (
|
|
id_ret, id_, _formatted_json))
|
|
|
|
# CHANGE apikey AND server-name
|
|
apikey = 'CHANGEME'
|
|
json_resp = api_call(apikey, 'http://CHANGEME/hg', 'get_repo', repoid=repo_name)
|
|
|
|
# for testing purposes
|
|
#with open('response.txt','a') as f:
|
|
#f.write(json.dumps(json_resp))
|
|
|
|
if json_resp['error']:
|
|
return repo_name, None, None
|
|
else:
|
|
response = json_resp['result']
|
|
return response['description'], response['repo_name'], response['fork_of']
|
|
except Exception as e:
|
|
return repo_name, None, None
|
|
|
|
def createJobJenkins(**kwargs):
|
|
# fix to give us info that should be sent in in future
|
|
if 'repo_name' not in kwargs:
|
|
# called from push or pull, repo exists so just get info
|
|
kwargs['repo_name'] = kwargs['repository']
|
|
kwargs['description'], trash, kwargs['fork_name'] = getRepoDescription(kwargs['repository'])
|
|
else:
|
|
# called from create_repo, repo doesn't exist so must get info from parent and use what we have here
|
|
trash, kwargs['fork_name'], trash = getRepoDescription(kwargs['fork_id'])
|
|
kwargs['fork_jenkins_job'] = cleanRepoNameJenkins(kwargs['fork_name'])
|
|
|
|
# for testing purposes
|
|
if 'jenkins_job' not in kwargs:
|
|
kwargs['jenkins_job'] = cleanRepoNameJenkins(kwargs['repo_name'])
|
|
#with open('kwargs.txt','a') as f:
|
|
#f.write('\n---------------------------------------------\nnew kwargs\n')
|
|
#for key, val in kwargs.iteritems():
|
|
#f.write('%s : %s\n' % (key, val))
|
|
|
|
# variables we will eventually get from extra_fields, after they are copied over from forks
|
|
# CHANGE THE NEXT 3 VARIABLES
|
|
create_jenkins_job = True
|
|
# default config for projects without fork
|
|
config_xml_url = 'http://CHANGEME/config.xml'
|
|
config_replacements = {
|
|
# should we just always do this one?
|
|
'<description>.*<\/description>':'<description>%(description)s</description>',
|
|
# you might want to include these for a default config
|
|
'JOBNAME':'%(repo_name)s',
|
|
'ARTIFACTS_TO_ARCHIVE':'**/target/*.war,**/target/*.ear,**/target/*.jar',
|
|
# this is definitly specific to our company, removing all permission restrictions
|
|
'<hudson.security.AuthorizationMatrixProperty>.*<\/hudson.security.AuthorizationMatrixProperty>':'',
|
|
}
|
|
if not create_jenkins_job:
|
|
return False
|
|
#print 'jenkins_job: %(jenkins_job)s description: %(description)s' % kwargs
|
|
import urllib2, re
|
|
try:
|
|
config = None
|
|
if kwargs['fork_jenkins_job'] is not None:
|
|
try:
|
|
# then we will get the config from there, and replace it
|
|
config = getJenkins('/job/%(fork_jenkins_job)s/config.xml' % kwargs)
|
|
config_replacements[kwargs['fork_jenkins_job']] = '%(jenkins_job)s'
|
|
config_replacements[kwargs['fork_name']] = '%(repo_name)s'
|
|
except Exception as e:
|
|
config = None
|
|
if config == None:
|
|
config = getUrl(config_xml_url)
|
|
for key, replacement in config_replacements.iteritems():
|
|
#config = config.replace(key, replacement)
|
|
config = re.compile(key, re.DOTALL).sub(replacement, config)
|
|
#config = re.sub('<description>.*<\/description>', '<description>%(description)s</description>', config)
|
|
config = config % kwargs
|
|
#print "Jenkins config:", config,
|
|
postJenkins('/createItem?name=%(jenkins_job)s' % kwargs, data=config, headers={'Content-type':'text/xml'})
|
|
print 'Jenkins: Create job %(jenkins_job)s successful!' % kwargs
|
|
return True
|
|
except urllib2.HTTPError:
|
|
#print 'Jenkins: Create job %(jenkins_job)s failed, maybe it already exists?' % kwargs
|
|
return False
|
|
|
|
#==============================================================================
|
|
# POST CREATE REPOSITORY HOOK
|
|
#==============================================================================
|
|
# this function will be executed after each repository is created
|
|
def _crhook(*args, **kwargs):
|
|
"""
|
|
Post create repository HOOK
|
|
kwargs available:
|
|
:param repo_name:
|
|
:param repo_type:
|
|
:param description:
|
|
:param private:
|
|
:param created_on:
|
|
:param enable_downloads:
|
|
:param repo_id:
|
|
:param user_id:
|
|
:param enable_statistics:
|
|
:param clone_uri:
|
|
:param fork_id:
|
|
:param group_id:
|
|
:param created_by:
|
|
"""
|
|
kwargs['jenkins_job'] = cleanRepoNameJenkins(kwargs['repo_name'])
|
|
createJobJenkins(**kwargs)
|
|
return 0
|
|
CREATE_REPO_HOOK = _crhook
|
|
|
|
|
|
#==============================================================================
|
|
# POST DELETE REPOSITORY HOOK
|
|
#==============================================================================
|
|
# this function will be executed after each repository deletion
|
|
def _dlhook(*args, **kwargs):
|
|
"""
|
|
Post create repository HOOK
|
|
kwargs available:
|
|
:param repo_name:
|
|
:param repo_type:
|
|
:param description:
|
|
:param private:
|
|
:param created_on:
|
|
:param enable_downloads:
|
|
:param repo_id:
|
|
:param user_id:
|
|
:param enable_statistics:
|
|
:param clone_uri:
|
|
:param fork_id:
|
|
:param group_id:
|
|
:param deleted_by:
|
|
:param deleted_on:
|
|
"""
|
|
kwargs['jenkins_job'] = cleanRepoNameJenkins(kwargs['repo_name'])
|
|
deleteJenkins(**kwargs)
|
|
return 0
|
|
DELETE_REPO_HOOK = _dlhook
|
|
|
|
|
|
#==============================================================================
|
|
# POST PUSH HOOK
|
|
#==============================================================================
|
|
|
|
# this function will be executed after each push it's executed after the
|
|
# build-in hook that RhodeCode uses for logging pushes
|
|
def _pushhook(*args, **kwargs):
|
|
"""
|
|
Post push hook
|
|
kwargs available:
|
|
|
|
:param server_url: url of instance that triggered this hook
|
|
:param config: path to .ini config used
|
|
:param scm: type of VS 'git' or 'hg'
|
|
:param username: name of user who pushed
|
|
:param ip: ip of who pushed
|
|
:param action: push
|
|
:param repository: repository name
|
|
:param pushed_revs: list of pushed revisions
|
|
"""
|
|
kwargs['jenkins_job'] = cleanRepoNameJenkins(kwargs['repository'])
|
|
if not createJobJenkins(**kwargs):
|
|
lastBuildStatusJenkins(**kwargs)
|
|
pollJenkins(**kwargs)
|
|
return 0
|
|
PUSH_HOOK = _pushhook
|
|
|
|
|
|
#==============================================================================
|
|
# POST PULL HOOK
|
|
#==============================================================================
|
|
|
|
# this function will be executed after each push it's executed after the
|
|
# build-in hook that RhodeCode uses for logging pulls
|
|
def _pullhook(*args, **kwargs):
|
|
"""
|
|
Post pull hook
|
|
kwargs available::
|
|
|
|
:param server_url: url of instance that triggered this hook
|
|
:param config: path to .ini config used
|
|
:param scm: type of VS 'git' or 'hg'
|
|
:param username: name of user who pulled
|
|
:param ip: ip of who pulled
|
|
:param action: pull
|
|
:param repository: repository name
|
|
"""
|
|
kwargs['jenkins_job'] = cleanRepoNameJenkins(kwargs['repository'])
|
|
createJobJenkins(**kwargs)
|
|
# turns out output from this function isn't visible to the user, so might as well just run create...
|
|
#if not createJobJenkins(**kwargs):
|
|
# lastBuildStatusJenkins(**kwargs)
|
|
return 0
|
|
PULL_HOOK = _pullhook
|