'''Install P4Win addins''' # Copyright (c) 2006 Qualcomm # Miki Tebeka from _winreg import OpenKey, CloseKey, EnumValue, REG_SZ, \ HKEY_CURRENT_USER, SetValueEx, KEY_READ, KEY_WRITE from itertools import count import re from install import load_config, _DEFAULTS, InstallError, is_process_running from os.path import join # Convert P4V config file entries to P4Win registry entries P4V2P4WIN = { "name" : "MenuName", "command" : "Command", "arguments" : "Arguments", "directory" : "InitialDirectory", "prompttext" : "PromptText", "console" : "IsConsole", "prompt" : "IsPrompt", "closeOnExit" : "IsCloseOnExit", "subMenu" : "IsSubMenu", "showBrowse" : "IsShowBrowse", "addToContext" : "OnContext", "refresh" : "IsRefresh", } # All addins are flat in /HKLM/Software/perforce/P4Win/Tools where each key # has a suffix which is it's tool id (e.g. Command0, Command1, Arguments0 ...) # Registry key _P4WIN_KEY = r"Software\perforce\P4Win\Tools" def is_boolean(key): if key.startswith("Is"): return 1 return key == "OnContext" def get_tools(): next = count(0).next # Next id endnum = re.compile("\d+$") # Number at end of key tools = {} key = OpenKey(HKEY_CURRENT_USER, _P4WIN_KEY) try: while 1: name, value, rtype = EnumValue(key, next()) match = endnum.search(name) if not match: continue tid = match.group() tkey = endnum.sub("", name) tool = tools.get(tid, None) if not tool: tool = {} tool[tkey] = value tools[tid] = tool except WindowsError: pass CloseKey(key) for tid, tool in tools.iteritems(): tool["id"] = tid return tools.values() def find_tool(name, tools): for tool in tools: if tool["MenuName"] == name: return tool return None def new_tool(): tool = {} for key, value in _DEFAULTS.iteritems(): tool[P4V2P4WIN[key]] = value return tool def install(dest, exclude=None, check_process=0): if check_process and is_process_running("p4win"): raise InstallError("P4Win is running, please close it first") if not exclude: exclude = [] addins = load_config() current_tools = get_tools() if current_tools: next_id = max([int(t["id"]) for t in current_tools]) + 1 else: next_id = 0 tools = [] for addin in addins: tool = find_tool(addin["name"], current_tools) if not tool: tool = new_tool() tool["id"] = str(next_id) next_id += 1 for opt, val in addin.iteritems(): winopt = P4V2P4WIN[opt] if is_boolean(winopt): val = { "yes" : "1", "no" : "0" }[val] # FIXME: Unite with batch install if val == "$install": val = dest tool[winopt] = val tools.append(tool) key = OpenKey(HKEY_CURRENT_USER, _P4WIN_KEY, 0, KEY_READ|KEY_WRITE) for tool in tools: tid = tool["id"] for opt, arg in tool.iteritems(): if opt == "id": continue if opt == "Command": arg = join(dest, arg) SetValueEx(key, "%s%s" % (opt, tid), 0, REG_SZ, arg) CloseKey(key) # FIXME: Find a way to unite with p4v_install if __name__ == "__main__": from optparse import OptionParser parser = OptionParser("usage: %prog [options] DESTINATION") parser.add_option("-e", help="exclude addin from install", dest="exclude", action="append", metavar="ADDIN") parser.add_option("-c", help="check that p4win is not running", dest="check", default=0, action="store_true") opts, args = parser.parse_args() if len(args) != 1: parser.error("wrong number of arguments") # Will exit dest = args[0] try: install(dest, opts.exclude, opts.check) except Exception, e: raise SystemExit("error: %s" % e)