[Zope-Checkins] CVS: Zope/inst - README.txt:1.1.2.1 file_from_infile.py:1.1.2.1 install.py:1.1.2.1 setup.py:1.1.2.1 configure.py:1.1.2.9 Makefile.in:NONE compile_all.py:NONE compilezpy.py:NONE custom_zodb.py.in:NONE default_content.py:NONE make_instance.py:NONE makeinstance.in:NONE source_install.py:NONE walkandscrub.py:NONE zctl.in:NONE zope.conf.in:NONE zpasswd.py:NONE

Chris McDonough chrism@zope.com
Sun, 29 Sep 2002 17:46:54 -0400


Update of /cvs-repository/Zope/inst
In directory cvs.zope.org:/tmp/cvs-serv12114/inst

Modified Files:
      Tag: chrism-install-branch
	configure.py 
Added Files:
      Tag: chrism-install-branch
	README.txt file_from_infile.py install.py setup.py 
Removed Files:
      Tag: chrism-install-branch
	Makefile.in compile_all.py compilezpy.py custom_zodb.py.in 
	default_content.py make_instance.py makeinstance.in 
	source_install.py walkandscrub.py zctl.in zope.conf.in 
	zpasswd.py 
Log Message:
Updates to the chrism-install-branch:

  - Uses distutils (setup.py) to install all software kept in the
    'lib/python' directory.  This means that the setup.py file
    (which has moved into the inst directory) will need to be maintained
    as new packages, files, and directories are added.  This is
    painful, but it's "the right thing".  It is a departure from the
    past inasmuch as (if this branch is merged into the head at some
    point) when people add stuff to the Zope tree, they will need to
    be careful to update the setup.py file as well.  I know this will become
    incredibly problematic.  To make things easier, it might be
    a reasonable thing to autogenerate a setup.py file based on the
    current state of the Zope tree.  But this is not done yet.
    BTW, many thanks to Matt Hamilton for making the incredible setup.py file
    for all Zope packages.

  - No longer copies the build directory wholesale to create a
    ZOPE_HOME.  Instead 'make install' copies a 'skeleton' directory to the 
    target dir using a custom Python installer and writes out
    files that need post-processing (.in files) to places in the
    hierarchy as needed via the Makefile.  This prevents a lot of
    cruft from reaching the target directory (build directories,
    emacs backup files, etc.)

  - Has an improved 'make instance' implementation which also uses
    a skeleton directory and a similar install.

  - Does away with much cruft in the 'inst' directory lefover from
    band-aids that were produced in the past.

Concessions were made to the realities of moving directories in CVS
for this go-around.  It is desirable to move lots of the current
"top-level" directories (import, var, utilities, Extensions, pcgi, etc.)
into the "skeleton" directory for the kind of install strategy implemented
by this branch, but this is not reasonable as we would divorce these 
packages from updates received on the head if were were to do so now.
If we merge this branch into the head, we will do away with the workarounds
and move the directories.
  


=== Added File Zope/inst/README.txt ===
in -- input files which are text-munged and written out without their .in
      extensions when a 'make install' is performed.

skel -- a ZOPE_HOME skeleton directory.


=== Added File Zope/inst/file_from_infile.py ===
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""
Reads a file named by 'src', performs textual replacements on the
file based on sed-style markup, and writes the result to the file named
by 'dst' unless 'dst' already exists.
"""
import getopt, os, sys
from os.path import abspath, split, dirname
import shutil

default_map = {
    'PYTHON':sys.executable,
    'BASE_DIR':abspath(split(dirname(sys.argv[0]))[0])
    }

def main(source, dest, map, force):
    if not force and os.path.exists(dest):
        print '%s exists, so I left it alone' % dest
    else:
        txt = open(source, 'rb').read()
        for k, v in map.items():
            txt = txt.replace('<<%s>>' % k, v)
        outfile = open(dest, 'wb')
        outfile.write(txt)
        outfile.close()
        shutil.copystat(source, dest)
        print "Wrote %s from %s" % (dest, source)

def usage():
    print "%s [opts] src dst" % sys.argv[0]
    print
    print "Reads a file named by 'src', performs textual replacements on "
    print "the file based on sed-style markup embedded in the infile, and "
    print "and writes the result to the file named by 'dst' unless 'dst'."
    print "already exists.  The generated file will have the same permissions"
    print "and other mode bit settings as the source file."
    print
    print "Options:"
    print
    print "  --force      Force replacement of dst even if it already exists."
    for name, value in default_map.items():
        print ("  --%s=value     controls text replacement, default '%s'"
               % (name, value))

if __name__ == '__main__':
    if len(sys.argv) < 3:
        usage()
        sys.exit(127)
    map = default_map.copy()
    force = 0
    try:
        longopts = ['help', 'force']
        for name in default_map.keys():
            longopts.append('%s=' % name)
        opts, args = getopt.getopt(sys.argv[1:], 'h', longopts)
    except getopt.GetoptError, v:
        print v
        usage()
        sys.exit(1)
    try:
        source, dest = args
    except:
        usage()
        sys.exit(1)
    for o, a in opts:
        if o in ('-h', '--help'):
            usage()
            sys.exit()
        if o == '--force':
            force = 1
        if o in map.keys():
            map[o] = a
    main(source, dest, map, force)



=== Added File Zope/inst/install.py ===
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""
Generic file and directory installer.

Typically called when installing Zope via the Makefile written by
'configure.py' in the 'make install' step.
"""
import sys, getopt, os, stat, glob, re
from shutil import copy2, rmtree
default_omitpattern = r'^.*~$'

def main(src, dst, symlinks=1, dirmode=0755, fmode=0644,
         omitpattern=default_omitpattern, retain_xbit=1):
    """
    Copy a file or directory named by src to a file or directory named by
    dst, normalizing mode bit settings as necessary.  Recursively copies
    directory trees using copy2().

    Errors are reported to standard output.

    If the optional symlinks flag is true, symbolic links in the
    source tree result in symbolic links in the destination tree; if
    it is false, the contents of the files pointed to by symbolic
    links are copied.

      - 'dirmode' is the directory creation mode.  All directories
        are created with this mode.
      - 'fmode' is the default file creation mode.  This mode
        is modified by the status of the source file.  If the source
        file is executable, mod the fmode to be +wgo executable.
      - omitpattern is a Python-style regex pattern.  If a file
        or directory name matches this pattern, it will never be copied.
      - if the dst directory already exists, don't raise an error.
    """
    try:
        if symlinks and os.path.islink(src):
            names = omit([src], omitpattern)
            names and copylink(names[0], dst)
        elif os.path.isdir(src):
            copydir(src, dst, symlinks, dirmode, fmode, omitpattern,
                    retain_xbit)
        else:
            names = omit([src], omitpattern)
            names and copyfile(names[0], dst, fmode, retain_xbit)

    except (IOError, os.error), why:
        print "Can't copy %s to %s: %s" % (`src`, `dst`, str(why))

def copydir(src, dst, symlinks, dirmode, fmode, omitpattern, retain_xbit):
    names = omit(os.listdir(src), omitpattern)
    try:
        # always create directories with dirmode
        os.makedirs(dst, dirmode)
    except os.error, why:
        if why[0] == 17:
            # directory already exists
            pass
        else:
            raise
    for name in names:
        srcname = os.path.join(src, name)
        dstname = os.path.join(dst, name)
        if symlinks and os.path.islink(srcname):
            copylink(srcname, dstname)
        elif os.path.isdir(srcname):
            copydir(srcname, dstname, symlinks, dirmode,fmode,omitpattern,
                    retain_xbit)
        else:
            copyfile(srcname, dstname, fmode, retain_xbit)

def copylink(src, dst):
    linkto = os.readlink(src)
    os.symlink(linkto, dst)

def copyfile(src, dst, mode, retain_xbit):
    copy2(src, dst)
    # change dest file mode to fmode but
    # make +wgo executable if source file is executable
    dstmode = mode
    st = os.stat(src)
    srcmode = st[stat.ST_MODE]
    if retain_xbit and (srcmode & stat.S_IEXEC):
        dstmode = (mode | 0111)
    if os.path.isdir(dst):
        # if dst is a directory, copy the file in to it
        os.chmod(os.path.join(dst, os.path.split(src)[-1]), dstmode)
    else:
        os.chmod(dst, dstmode)

omitcache = {}

def omit(names, omitpattern):
    match = omitcache.setdefault(omitpattern, re.compile(omitpattern).match)
    return [ n for n in names if not match(n) ]

def usage():
    print "%s [opts] source dest" % sys.argv[0]
    print
    print "Copies a file or directory specified by 'source' to 'dest'"
    print "normalizing mode bit settings as necessary."
    print
    print "If src is a file and dst is a directory, the file will be"
    print "copied into the dst directory.  However, if src is a directory"
    print "and dst is a directory, the contents of src will be copied into"
    print "dst."
    print
    print "opts: --copylinks --dirmode=mode --fmode=mode --omitpattern=patt"
    print
    print "  --copylinks      when copying a directory, copy the target of"
    print "                   symlinks in source instead of linking in dest"
    print "  --dontcopyxbit   when copying a file marked as executable,"
    print "                   don't make the copy executable."
    print "  --dirmode        mode bit settings of dest dirs (e.g. '755')"
    print "  --fmode          mode bit settings of dest files (e.g. '644')"
    print "                   (modified wgo+x when dontcopyxbit is not"
    print "                   specified)"
    print "  --omitpattern    a Python-style regex pattern.  File and"
    print "                   directory names which match this pattern will "
    print "                   not be copied.  The default omitpattern is"
    print "                   '%s'" % default_omitpattern

if __name__ == '__main__':
    if len(sys.argv) < 3:
        usage()
        sys.exit(127)
    symlinks = 1
    dirmode = 0755
    fmode   = 0644
    omitpattern = default_omitpattern
    retain_xbit = 1
    try:
        longopts = ['copylinks', 'dirmode=', 'fmode=', 'omitpattern=', 'help',
                    'copyxmode' ]
        opts, args = getopt.getopt(sys.argv[1:], 'h', longopts)
    except getopt.GetoptError, v:
        print v
        usage()
        sys.exit(1)
    try:
        source, dest = args
    except:
        usage()
        sys.exit(1)
    for o, a in opts:
        if o in ('-h', '--help'):
            usage()
            sys.exit()
        if o == '--copylinks':
            symlinks = 0
        if o == '--dirmode':
            if not a.startswith('0'):
                a = '0%s' % a
            dirmode = eval(a)
        if o == '--fmode':
            if not a.startswith('0'):
                a = '0%s' % a
            fmode = eval(a)
        if o == '--omitpattern':
            omitpattern = a
        if o == '--dontcopyxbit':
            retain_xbit = 0
    main(source, dest, symlinks, dirmode, fmode, omitpattern, retain_xbit)
    


=== Added File Zope/inst/setup.py === (992/1092 lines abridged)
#! /usr/bin/env python
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################

"""
Distutils setup for Zope

  In-place building

    This builds extension modules in-place, much like build_extensions.py
    does.  Use 'setup.py' like this::

      python setup.py build_ext -i

  Installation

    This builds extension modules, compiles python modules, and installs
    everything needed to support Zope instances in the directory of
    your choosing.  For example, to use '/usr/local/lib/zope'::

      python setup.py install \
        --home=/usr/local/lib/zope \
        --install-platlib=/usr/local/lib/zope \
        --install-purelib=/usr/local/lib/zope

    Note that with this method, all packages and scripts (including
    ZServer and z2.py) go in the same directory as Zope modules, which
    are distributed in lib/python.  You will need to set both ZOPE_HOME
    and SOFTWARE_HOME to point to your destination directory in order
    for Zope to work in this configuration.
"""

import os
import sys

from distutils.core import setup as distutils_setup
from distutils.extension import Extension

# This function collects setup information for one massive distutils
# run to be done at the end of the script.  If you're making a setup.py

[-=- -=- -=- 992 lines omitted -=- -=- -=-]

)
distutils_setup(
    name='Zope',
    author=AUTHOR,

    py_modules=setup_info.get('py_modules', []),
    cmdclass={'install': install, 'install_data': install_data}
)
setup_info = {}

# Does not work on all platforms... not like we ever compiled it before
# anyway
#
#    ext_modules=[
#       Extension(name='ZServer.medusa.sendfile.sendfilemodule',
#                 sources=['ZServer/medusa/sendfile/sendfilemodule.c'])]

# The rest of these modules live in the root of the source tree
os.chdir(ZOPE_ROOT)

# Default imports
setup(
    name='Zope default imports',
    author=AUTHOR,

    data_files=[['import', ['import/*.zexp']]],
    cmdclass={'install_data': install_data}
)

# And now, the root-level stuff

distutils_setup(
    name='Zope',
    author=AUTHOR,

    packages=setup_info.get('packages', []),
    data_files=setup_info.get('data_files', []),

    headers=setup_info.get('headers', []),
    ext_modules=setup_info.get('ext_modules', []),

    cmdclass={'install': install, 'install_data': install_data}
)
distutils_setup(
    name='Zope',
    author=AUTHOR,

    py_modules=setup_info.get('py_modules', []),
    cmdclass={'install': install, 'install_data': install_data}
)


=== Zope/inst/configure.py 1.1.2.8 => 1.1.2.9 ===
--- Zope/inst/configure.py:1.1.2.8	Tue Sep 17 00:52:30 2002
+++ Zope/inst/configure.py	Sun Sep 29 17:46:23 2002
@@ -12,25 +12,24 @@
 ##############################################################################
 """
 Create a Makefile for building and installing Zope.
-
-Also create a 'makeinstance' script for installing an INSTANCE_HOME
-after the Zope 'binaries' are installed.
 """
 import getopt, sys, os
 
 def main():
+    # below assumes this script is in the BUILD_DIR/inst directory
     BUILD_DIR=os.path.abspath(os.path.split(os.path.dirname(sys.argv[0]))[0])
-    ZOPE_HOME='/usr/local/zope'
+    TARGET_DIR='/usr/local/zope'
     PYTHON=sys.executable
-    HERE = os.path.join(BUILD_DIR, 'inst')
-    MAKEINSTANCE=open(os.path.join(HERE, 'makeinstance.in')).read()
-    MAKEFILE=open(os.path.join(HERE, 'Makefile.in')).read()
+    MAKEFILE=open(os.path.join(BUILD_DIR, 'inst', 'Makefile.in')).read()
     REQUIRE_LF_ENABLED = 1
-    zope_home = ZOPE_HOME
+    REQUIRE_ZLIB=1
+    OPT_FLAGS = ''
+    zope_home = TARGET_DIR
     build_dir = BUILD_DIR
     python = PYTHON
     try:
-        longopts = ["help", "ignore-largefile", "prefix="]
+        longopts = ["help", "ignore-largefile", "ignore-zlib", "prefix=",
+                    "optimize"]
         opts, args = getopt.getopt(sys.argv[1:], "h", longopts)
     except getopt.GetoptError, v:
         print v
@@ -44,22 +43,24 @@
             zope_home=os.path.abspath(os.path.expanduser(a))
         if o == "--ignore-largefile":
             REQUIRE_LF_ENABLED=0
+        if o == "--ignore-zlib":
+            REQUIRE_ZLIB=0
+        if o == "--optimize":
+            OPT_FLAGS = '--optimize=1 --no-compile'
     if REQUIRE_LF_ENABLED:
         test_largefile()
+    if REQUIRE_ZLIB:
+        test_zlib()
     print "  - Zope top-level binary directory will be %s." % zope_home
-    idata = {'<<PYTHON>>':python,'<<ZOPE_HOME>>':zope_home,
-             '<<BUILD_DIR>>':build_dir}
+    if OPT_FLAGS:
+        print "  - Distutils install flags will be '%s'" % OPT_FLAGS
+    idata = {'<<PYTHON>>':python,'<<TARGET_DIR>>':zope_home,
+             '<<BUILD_DIR>>':build_dir, '<<OPT_FLAGS>>':OPT_FLAGS}
     for k,v in idata.items():
         MAKEFILE = MAKEFILE.replace(k, v)
-        MAKEINSTANCE = MAKEINSTANCE.replace(k, v)
     f = open(os.path.join(BUILD_DIR, 'Makefile'), 'w')
     f.write(MAKEFILE)
     print "  - Makefile written."
-    f = open('makeinstance', 'w')
-    f = open(os.path.join(BUILD_DIR, 'makeinstance'), 'w')
-    f.write(MAKEINSTANCE)
-    os.chmod('makeinstance', 0755)
-    print "  - 'makeinstance' script written."
     print
     print "  Next, run 'make'."
     print
@@ -76,20 +77,54 @@
 
 Options:
 
+  --ignore-zlib                 allow configuration to proceeed if
+                                Python zlib module is not found.
+
   --ignore-largefile            allow configuration to proceed without
                                 Python large file support.
 
+  --optimize                    compile Python files as .pyo files
+                                instead of as .pyc files
+
 Installation directories:
 
   --prefix=DIR                  install Zope files in DIR [%(zope_home)s]
 
 By default, 'make install' will install Zope software files in
-'%(zope_home)s'  You can specify an alternate location for these
+'%(target_dir)s'  You can specify an alternate location for these
 files by using '--prefix', for example: '--prefix=$HOME/zope'.
-""" % ({'program':sys.argv[0], 'zope_home':ZOPE_HOME})
+""" % ({'program':sys.argv[0], 'target_dir':TARGET_DIR})
              )
     print usage
 
+def test_zlib():
+    try:
+        import zlib
+    except ImportError:
+        print (
+            """
+The Python interpreter you are using does not appear to have the 'zlib'
+library module installed.  For Zope to be able to run, you must install a
+Python interpreter which includes the zlib module, or install the zlib library
+into your Python interpreter manually.  The file which represents the library
+is named 'zlib.so' (UNIX) or 'zlib.dll' (Windows) and is typically located in
+the 'lib-dynload' directory of your Python's library directory.  Some
+Python packagers ship the zlib module as a separate installable binary. If you
+are using a system-provided Python installation, you may want to look for
+a 'python-zlib' package (or something like it) and install it to make the
+Python zlib module available to Zope.
+
+Run the configure script with the --ignore-zlib option to prevent this
+warning with the understanding that Zope will not start properly until
+you've installed the zlib module.
+"""
+            )
+        sys.exit(127)
+    except:
+        print 'An error occurred while trying to import zlib!'
+        import traceback; traceback.print_exc()
+        sys.exit(127)
+        
 def test_largefile():
     OK=0
     f = open(sys.argv[0], 'r')
@@ -105,12 +140,13 @@
     print (
         """
 This Python interpreter does not have 'large file support' enabled. Large
-file support is required to allow the default Zope database to grow larger
-than 2GB on most platforms.  Either install a Python interpreter with large
-file support (see http://www.python.org/doc/current/lib/posix-large-files.html)
-or run this program again with the --ignore-largefile option to prevent this
-warning, with the understanding that your Zope may fail if the database size
-ever exceeds 2GB.
+file support is required to allow the default Zope ZODB database to grow
+larger than 2GB on most platforms.  Either install a Python interpreter with
+large file support (see
+http://www.python.org/doc/current/lib/posix-large-files.html) or run this
+program again with the --ignore-largefile option to prevent this warning,
+with the understanding that your Zope may fail if the ZODB database
+size ever exceeds 2GB.
 """
         )
     sys.exit(127)

=== Removed File Zope/inst/Makefile.in ===

=== Removed File Zope/inst/compile_all.py ===

=== Removed File Zope/inst/compilezpy.py ===

=== Removed File Zope/inst/custom_zodb.py.in ===

=== Removed File Zope/inst/default_content.py ===

=== Removed File Zope/inst/make_instance.py ===

=== Removed File Zope/inst/makeinstance.in ===

=== Removed File Zope/inst/source_install.py ===

=== Removed File Zope/inst/walkandscrub.py ===

=== Removed File Zope/inst/zctl.in ===

=== Removed File Zope/inst/zope.conf.in ===

=== Removed File Zope/inst/zpasswd.py ===