viewvc-4intranet/viewcvs-install

263 lines
8.8 KiB
Python
Executable File

#!/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
import StringIO
# get access to our library modules
sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), 'lib'))
import compat
import viewcvs
import ndiff
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),
("lib/accept.py", "lib/accept.py", 0644, 0, 0, 1),
("templates/annotate.ezt", "templates/annotate.ezt", 0644, 0, 1, 0),
("templates/diff.ezt", "templates/diff.ezt", 0644, 0, 1, 0),
("templates/directory.ezt", "templates/directory.ezt", 0644, 0, 1, 0),
("templates/dir_alternate.ezt", "templates/dir_alternate.ezt", 0644, 0, 1, 0),
("templates/footer.ezt", "templates/footer.ezt", 0644, 0, 1, 0),
("templates/graph.ezt", "templates/graph.ezt", 0644, 0, 1, 0),
("templates/header.ezt", "templates/header.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/markup.ezt", "templates/markup.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("<VIEWCVS_INSTALL_DIRECTORY>", 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):
# Collect ndiff output from ndiff
sys.stdout = StringIO.StringIO()
ndiff.main([dest_path,src_path])
ndiff_output = sys.stdout.getvalue()
# Return everything to normal
sys.stdout = sys.__stdout__
# Collect the '+ ' and '- ' lines
# total collects the difference lines to be printed later
total = ""
# I use flag to throw out match lines.
flag = 1
for line in string.split(ndiff_output,'\n'):
# Print line if it is a difference line
if line[:2] == "+ " or line[:2] == "- " or line[:2] == "? ":
total = total + line + "\n"
flag = 1
else:
# Compress lines that are the same to print one blank line
if flag:
total = total + "\n"
flag = 0
if total == "\n":
print " File %s exists,\n but there is no difference between target and source files.\n" % (dest_path)
return
if type(prompt_replace) == type(""):
print prompt_replace
while 1:
temp = raw_input("\n File %s\n exists and is different from source file.\n DO YOU WANT TO,\n overwrite [o]\n do not overwrite [d]\n view differences [v]: " % (dest_path))
print
temp = string.lower(temp[0])
if temp == "d":
return
if temp == "v":
print total
print "\nLEGEND\n A leading '- ' indicates line to remove from installed file\n A leading '+ ' indicates line to add to installed file\n A leading '? ' shows intraline differences."
if temp == "o":
ReplaceFile(src_path, dest_path, mode, set_python_paths, prompt_replace, compile_it)
return
else:
ReplaceFile(src_path, dest_path, mode, set_python_paths, prompt_replace, compile_it)
return
def ReplaceFile(src_path, dest_path, mode, set_python_paths, prompt_replace, compile_it):
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)
return
## 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"