#!/usr/bin/python # this script was written for Python 2.5.2 on Windows. CONFIG = { #name of the perforce counter we read/write for --daemon mode 'counter-name' : 'collab-last-updated-change', 'collab-url' : 'http://collaborator:8080/ 'collab-login' : 'admin', 'collab-password' : 'secret', #this is the p4port collab will use when updating changelist ids 'p4port' : 'perforce:1666', #change this to add login/ticket information to all calls to perforce 'p4' : ["p4"], 'max-changes-per-daemon-wake' : 100, } DEBUG = False def debug(*args): if DEBUG: print(args) from subprocess import Popen, PIPE from marshal import load def get_counter_value(): cmd = CONFIG['p4'] + ["-G", "counter", CONFIG["counter-name"]] popen = Popen(cmd, stdout=PIPE) counter = load(popen.stdout) debug('perforce get counter info: ', counter) return int(counter['value']) def set_counter_value(value): popen = Popen(CONFIG['p4'] + ["-G", "counter", CONFIG["counter-name"], str(value)], stdout=PIPE) counter = load(popen.stdout) debug('perforce set counter info: ', counter) def get_latest_submitted(): cmd = CONFIG['p4'] + ["-G", "changes", "-m", "1", "-s", "submitted"] popen = Popen(cmd, stdout=PIPE) change = load(popen.stdout) debug('perforce last submitted change: ', change) return int(change["change"]) def get_old_change(change): popen = Popen(CONFIG['p4'] + ["-G", "describe", str(change)], stdout=PIPE) desc = load(popen.stdout) debug('Change description', desc) if desc.has_key("oldChange"): return int(desc["oldChange"]) return None def do_update_id(old_id, new_id): args = [ "--scm", "perforce", "--p4port", CONFIG['p4port'], "--user", CONFIG['collab-login'], "--password", CONFIG['collab-password'], "--non-interactive", "admin", "changelist", "update-id", str(old_id), str(new_id) ] debug('updating ', old_id, ' to ', new_id) if DEBUG: args = ["--debug"] + args popen = Popen(["ccollab"] + args, stdout=PIPE, stderr=PIPE) debug('ccollab stdout', popen.stdout.readlines()) stderr = popen.stderr.readlines() debug('ccollab stderr', stderr) if len(stderr) != 0: raise Exception('\n'.join(stderr)) def do_trigger(new_id): debug('checking change:', new_id) old_id = get_old_change(new_id) if old_id is None: debug('skipping: ', new_id) return do_update_id(old_id, new_id) def change_range(): last_hit = get_counter_value() stop_after = get_latest_submitted() cap = CONFIG['max-changes-per-daemon-wake'] if stop_after - last_hit > cap: stop_after = last_hit + cap return int(last_hit), int(stop_after) def do_daemon(): debug('DAEMON MODE') last_hit, stop_after = change_range() max_touched = last_hit try: for change in xrange(last_hit + 1, stop_after + 1): do_trigger(change) max_touched = change finally: set_counter_value(max_touched) from sys import argv if "--debug" in argv: DEBUG = True debug(CONFIG) try: do_daemon() except Exception, e: print 'Error:', e print """ Welcome to Smart Bear (tm)'s example changelist renumbering script This script requires a Code Collaborator client and server both at 5.0.5005 or better, and a Perforce client and server 2007.3 or better This script will renumber changelists uploaded to the Code Collaborator(tm) server at %(collab-url)s for the Perforce(tm) server at %(p4port)s. You can configure this script by editing the CONFIG dictionary at it's start. USAGE: To run in daemon mode, set up a recurring task (e.g. cron) that runs this: %(script-location)s If you're experiencing any problems with the script, you can enable debugging with: %(script-location)s --debug """ % CONFIG