#!/usr/bin/env python # -*- Mode: python -*- # # Copyright (C) 2000-2001 The ViewCVS Group. All Rights Reserved. # # By using this file, you agree to the terms and conditions set forth in # the LICENSE.html file which can be found at the top level of the ViewCVS # distribution or at http://viewcvs.sourceforge.net/license-1.html. # # Contact information: # Greg Stein, PO Box 760, Palo Alto, CA, 94302 # gstein@lyra.org, http://viewcvs.sourceforge.net/ # # ----------------------------------------------------------------------- # # install script for viewcvs -- temporary? # # ### this will eventually be replaced by autoconf plus tools. an # ### interactive front-end to ./configure may be provided. # # ----------------------------------------------------------------------- # import os import sys import string import re import traceback import py_compile # get access to our library modules sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), 'lib')) import compat import viewcvs version = viewcvs.__version__ ## installer text INFO_TEXT = """\ This is the ViewCVS %s installer. It will allow you to choose the install path for ViewCVS. You will now be asked some installation questions. Defaults are given in square brackets. Just hit [Enter] if a default is okay. """ % version ## installer defaults ROOT_DIR = "/usr/local/viewcvs-" + version ## list of files for installation ## tuple (source path, destination path, install mode, true/false flag for ## search-and-replace, flag or text for prompt before replace, ## compile_it) ## FILE_INFO_LIST = [ ("cgi/viewcvs.cgi", "cgi/viewcvs.cgi", 0755, 1, 0, 0), ("cgi/query.cgi", "cgi/query.cgi", 0755, 1, 0, 0), ("standalone.py", "standalone.py", 0755, 1, 0, 0), ("cgi/viewcvs.conf.dist", "viewcvs.conf", 0644, 1, """Note: If you are upgrading from viewcvs-0.7 or earlier: The section [text] has been removed from viewcvs.conf. The functionality went into the new files in subdirectory templates.""", 0), ("cgi/cvsgraph.conf.dist", "cvsgraph.conf", 0644, 0, 1, 0), ("lib/PyFontify.py", "lib/PyFontify.py", 0644, 0, 0, 1), ("lib/blame.py", "lib/blame.py", 0644, 0, 0, 1), ("lib/compat.py", "lib/compat.py", 0644, 0, 0, 1), ("lib/config.py", "lib/config.py", 0644, 0, 0, 1), ("lib/cvsdb.py", "lib/cvsdb.py", 0644, 1, 0, 1), ("lib/dbi.py", "lib/dbi.py", 0644, 0, 0, 1), ("lib/debug.py", "lib/debug.py", 0644, 0, 0, 1), ("lib/popen.py", "lib/popen.py", 0644, 0, 0, 1), ("lib/py2html.py", "lib/py2html.py", 0644, 0, 0, 1), ("lib/query.py", "lib/query.py", 0644, 1, 0, 1), ("lib/rcsparse.py", "lib/rcsparse.py", 0644, 0, 0, 1), ("lib/rlog.py", "lib/rlog.py", 0644, 0, 0, 1), ("lib/viewcvs.py", "lib/viewcvs.py", 0644, 1, 0, 1), ("lib/ezt.py", "lib/ezt.py", 0644, 0, 0, 1), ("lib/apache_icons.py", "lib/apache_icons.py", 0644, 0, 0, 1), ("templates/directory.ezt", "templates/directory.ezt", 0644, 0, 1, 0), ("templates/log.ezt", "templates/log.ezt", 0644, 0, 1, 0), ("templates/log_table.ezt", "templates/log_table.ezt", 0644, 0, 1, 0), ("templates/query.ezt", "templates/query.ezt", 0644, 0, 1, 0), ("tools/loginfo-handler", "loginfo-handler", 0755, 1, 0, 0), ("tools/cvsdbadmin", "cvsdbadmin", 0755, 1, 0, 0), ("tools/make-database", "make-database", 0755, 1, 0, 0), ("website/help_rootview.html", "doc/help_rootview.html", 0644, 0, 0, 0), ("website/help_dirview.html", "doc/help_dirview.html", 0644, 0, 0, 0), ("website/help_query.html", "doc/help_query.html", 0644, 0, 0, 0), ("website/help_log.html", "doc/help_log.html", 0644, 0, 0, 0), ("website/help_logtable.html", "doc/help_logtable.html", 0644, 0, 0, 0), ("website/images/logo.png", "doc/images/logo.png", 0644, 0, 0, 0), ("website/images/chalk.jpg", "doc/images/chalk.jpg", 0644, 0, 0, 0), ("website/images/cvsgraph_16x16.png", "doc/images/cvsgraph_16x16.png", 0644, 0, 0, 0), ("website/images/cvsgraph_32x32.png", "doc/images/cvsgraph_32x32.png", 0644, 0, 0, 0), ] def Error(text, etype=None, evalue=None): print print "[ERROR] %s" % text if etype: print '[ERROR] ', traceback.print_exception(etype, evalue, None, file=sys.stdout) sys.exit(1) def MkDir(path): try: compat.makedirs(path) except os.error, e: if e[0] == 17: # EEXIST: file exists return if e[0] == 13: # EACCES: permission denied Error("You do not have permission to create directory %s" % path) Error("Unknown error creating directory %s" % path, OSError, e) def SetOnePath(contents, var, value): pattern = re.compile('^' + var + r'\s*=\s*.*$', re.MULTILINE) repl = '%s = "%s"' % (var, os.path.join(ROOT_DIR, value)) return re.sub(pattern, repl, contents) def SetPythonPaths(contents): if contents[:2] == '#!': shbang = '#!' + sys.executable contents = re.sub('^#![^\n]*', shbang, contents) contents = re.sub("", ROOT_DIR, contents) contents = SetOnePath(contents, 'LIBRARY_DIR', 'lib') contents = SetOnePath(contents, 'CONF_PATHNAME', 'viewcvs.conf') return contents def InstallFile(src_path, dest_path, mode, set_python_paths, prompt_replace, compile_it): dest_path = os.path.join(ROOT_DIR, dest_path) if prompt_replace and os.path.exists(dest_path): if type(prompt_replace) == type(""): print prompt_replace temp = raw_input("File %s exists, overwrite? [y/N]: " % (dest_path)) if not temp or string.lower(temp[0]) != "y": return try: contents = open(src_path, "r").read() except IOError, e: Error(str(e)) if set_python_paths: contents = SetPythonPaths(contents) ## write the file to the destination location path, basename = os.path.split(dest_path) MkDir(path) try: open(dest_path, "w").write(contents) except IOError, e: if e[0] == 13: # EACCES: permission denied Error("You do not have permission to write file %s" % dest_path) Error("Unknown error writing file %s" % dest_path, IOError, e) os.chmod(dest_path, mode) if compile_it: py_compile.compile(dest_path) ## MAIN if __name__ == "__main__": print INFO_TEXT ## get the install path temp = raw_input("Installation Path [%s]: " % ROOT_DIR) temp = string.strip(temp) if len(temp): ROOT_DIR = temp ## install the files print print "Installing ViewCVS to:", ROOT_DIR for args in FILE_INFO_LIST: print " ", args[0] apply(InstallFile, args) print print "Installation Complete"