'''Install P4Win addins'''
# Copyright (c) 2006 Qualcomm
# Miki Tebeka <mtebeka@qualcomm.com>
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)