From a911d49dc68205cebbd6b7e728f2cd1ad49b9aca Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Wed, 16 Mar 2005 17:15:19 +0000 Subject: Version installation of scripts. --- README | 88 ++++++++++-------- SConstruct | 24 +++-- src/README.txt | 85 ++++++++++------- src/RELEASE.txt | 10 ++ src/setup.py | 271 +++++++++++++++++++++++++++++++++++++----------------- src/test_setup.py | 269 ++++++++++++++++++++++++++++++++++++++++++----------- 6 files changed, 531 insertions(+), 216 deletions(-) diff --git a/README b/README index 358cdc8..f34c9c2 100644 --- a/README +++ b/README @@ -125,61 +125,75 @@ And on Windows: C:\scons\>cd build\scons C:\scons\build\scons>python setup.py install -If this is the first time you are installing SCons on your system, -the above command will install: +By default, the above commands will do the following: - -- the scons script in the default system script directory (/usr/bin - or C:\Python*\Scripts, for example); + -- Install the version-numbered "scons-0.96" and "sconsign-0.96" + scripts in the default system script directory (/usr/bin or + C:\Python*\Scripts, for example). This can be disabled by + specifying the "--no-version-script" option on the command + line. - -- the build engine in an appropriate stand-alone SCons library - directory (/usr/lib/scons or C:\Python*\scons, for example); - - -- on UNIX or Linux systems, the troff-formatted man pages in an - appropriate directory (/usr/share/man/man1 or /usr/man/man1, + -- Install scripts named "scons" and "sconsign" scripts in the + default system script directory (/usr/bin or C:\Python*\Scripts, + for example). This can be disabled by specifying the + "--no-scons-script" option on the command line, which is useful + if you want to install and experiment with a new version before + making it the default on your system. On UNIX or Linux systems, + you can have the "scons" and "sconsign" scripts be hard links or + symbolic links to the "scons-0.96" and "sconsign-0.96" scripts + by specifying the "--hardlink-scons" or "--symlink-scons" + options on the command line. + + -- Install "scons-0.96.bat" and "scons.bat" wrapper scripts in the + Python prefix directory on Windows (C:\Python*, for example). + This can be disabled by specifying the "--no-install-bat" option + on the command line. On UNIX or Linux systems, the + "--install-bat" option may be specified to have "scons-0.96.bat" + and "scons.bat" files installed in the default system script + directory, which is useful if you want to install SCons in a + shared file system directory that can be used to execute SCons + from both UNIX/Linux and Windows systems. + + -- Install the SCons build engine (a Python module) in an + appropriate version-numbered SCons library directory + (/usr/lib/scons-0.96 or C:\Python*\scons-0.96, for example). + See below for more options related to installing the build + engine library. + + -- Install the troff-format man pages in an appropriate directory + on UNIX or Linux systems (/usr/share/man/man1 or /usr/man/man1, for example). This can be disabled by specifying the - "--no-install-doc" option on the command line. + "--no-install-man" option on the command line. The man pages + can be installed on Windows systems by specifying the + "--install-man" option on the command line. -Note that, by default, SCons does not install its library in the -standard Python library directories. If you want to be able to use the -SCons library modules (the build engine) in other Python scripts, you -can run the setup script as follows: +Note that, by default, SCons does not install its build engine library +in the standard Python library directories. If you want to be able to +use the SCons library modules (the build engine) in other Python +scripts, specify the "--standard-lib" option on the command line, as +follows: - # cd build/scons # python setup.py install --standard-lib -This will install the build engine in the standard Python -library directory (/usr/lib/python*/site-packages or +This will install the build engine in the standard Python library +directory (/usr/lib/python*/site-packages or C:\Python*\Lib\site-packages). -Alternatively, you may want to install multiple versions of SCons -side-by-side, which you can do as follows: - - # cd build/scons - # python setup.py install --version-lib +Alternatively, you can have SCons install its build engine library in a +hard-coded standalone library directory, instead of the default +version-numbered directory, by specifying the "--standalone-lib" option +on the command line, as follows: -This will install the build engine in a version-specific library -directory (/usr/lib/scons-__VERSION__ or C:\Python*\scons-__VERSION__). - -If this is not the first time you are installing SCons on your system, -the setup script will, by default, search for where you have previously -installed the SCons library, and install this version's library the -same way--that is, if you previously installed the SCons library in -the standard Python library, the setup script will install this one -in the same location. You may, of course, specify one of the --*-lib -options described above to select a specific library location, or use -the following option to explicitly select installation into the default -standalone library directory (/usr/lib/scons or C:\Python*\scons): - - # cd build/scons # python setup.py install --standalone-lib +This is usually not recommended, however. + Note that, to install SCons in any of the above system directories, you should have system installation privileges (that is, "root" or "Administrator") when running the setup.py script. If you don't have system installation privileges, you can use the --prefix option to specify an alternate installation location, such as your home directory: - $ cd build/scons $ python setup.py install --prefix=$HOME This will install SCons in the appropriate locations relative to diff --git a/SConstruct b/SConstruct index f928efb..4ea2246 100644 --- a/SConstruct +++ b/SConstruct @@ -397,11 +397,16 @@ scons_script = { ], 'filemap' : { - 'LICENSE.txt' : '../LICENSE.txt', - 'scons' : 'scons.py', - 'sconsign' : 'sconsign.py', + 'LICENSE.txt' : '../LICENSE.txt', + 'scons' : 'scons.py', + 'sconsign' : 'sconsign.py', }, + 'extra_rpm_files' : [ + 'scons-' + version, + 'sconsign-' + version, + ], + 'explicit_deps' : { 'scons' : Version_values, 'sconsign' : Version_values, @@ -525,6 +530,9 @@ for p in [ scons ]: rpm_files.append(r) if f[-3:] == ".py": rpm_files.append(r + 'c') + for f in sp.get('extra_rpm_files', []): + r = os.path.join(sp['rpm_dir'], f) + rpm_files.append(r) files = map(lambda x, i=isubdir: os.path.join(i, x), files) dst_files.extend(files) for k, f in sp['filemap'].items(): @@ -631,7 +639,7 @@ for p in [ scons ]: env.Command(dfiles, unpack_tar_gz_files, [ Delete(os.path.join(unpack_tar_gz_dir, pkg_version, 'build')), Delete("$TEST_TAR_GZ_DIR"), - '$PYTHON "%s" install "--prefix=$TEST_TAR_GZ_DIR"' % \ + '$PYTHON "%s" install "--prefix=$TEST_TAR_GZ_DIR" --standalone-lib' % \ os.path.join(unpack_tar_gz_dir, pkg_version, 'setup.py'), ]) @@ -704,7 +712,7 @@ for p in [ scons ]: env.Command(dfiles, unpack_zip_files, [ Delete(os.path.join(unpack_zip_dir, pkg_version, 'build')), Delete("$TEST_ZIP_DIR"), - '$PYTHON "%s" install "--prefix=$TEST_ZIP_DIR"' % \ + '$PYTHON "%s" install "--prefix=$TEST_ZIP_DIR" --standalone-lib' % \ os.path.join(unpack_zip_dir, pkg_version, 'setup.py'), ]) @@ -823,7 +831,7 @@ for p in [ scons ]: commands = [ Delete(local), - '$PYTHON $SETUP_PY install "--install-script=%s" "--install-lib=%s" --no-install-doc --no-compile' % \ + '$PYTHON $SETUP_PY install "--install-script=%s" "--install-lib=%s" --no-install-man --no-compile --standalone-lib --no-version-script' % \ (cwd_local, cwd_local_slv), ] @@ -1011,7 +1019,7 @@ if change: (os.path.join(unpack_tar_gz_dir, psv), os.path.join('src', 'script', 'scons.py'), os.path.join('build', 'scons')), - '$PYTHON "%s" install "--prefix=$TEST_SRC_TAR_GZ_DIR"' % \ + '$PYTHON "%s" install "--prefix=$TEST_SRC_TAR_GZ_DIR" --standalone-lib' % \ os.path.join(unpack_tar_gz_dir, psv, 'build', @@ -1067,7 +1075,7 @@ if change: (os.path.join(unpack_zip_dir, psv), os.path.join('src', 'script', 'scons.py'), os.path.join('build', 'scons')), - '$PYTHON "%s" install "--prefix=$TEST_SRC_ZIP_DIR"' % \ + '$PYTHON "%s" install "--prefix=$TEST_SRC_ZIP_DIR" --standalone-lib' % \ os.path.join(unpack_zip_dir, psv, 'build', diff --git a/src/README.txt b/src/README.txt index 1264571..c821e94 100644 --- a/src/README.txt +++ b/src/README.txt @@ -86,51 +86,70 @@ provided Python-standard setup script as follows: # python setup.py install -If this is the first time you are installing SCons on your system, -the above command will install: +By default, the above command will do the following: - -- the scons script in the default system script directory (/usr/bin - or C:\Python*\Scripts, for example); + -- Install the version-numbered "scons-__VERSION__" and + "sconsign-__VERSION__" + scripts in the default system script directory (/usr/bin or + C:\Python*\Scripts, for example). This can be disabled by + specifying the "--no-version-script" option on the command + line. - -- the build engine in an appropriate stand-alone SCons library - directory (/usr/lib/scons or C:\Python*\scons, for example); - - -- on UNIX or Linux systems, the troff-formatted man pages in an - appropriate directory (/usr/share/man/man1 or /usr/man/man1, + -- Install scripts named "scons" and "sconsign" scripts in the + default system script directory (/usr/bin or C:\Python*\Scripts, + for example). This can be disabled by specifying the + "--no-scons-script" option on the command line, which is useful + if you want to install and experiment with a new version before + making it the default on your system. On UNIX or Linux systems, + you can have the "scons" and "sconsign" scripts be hard links or + symbolic links to the "scons-__VERSION__" and "sconsign-__VERSION__" scripts + by specifying the "--hardlink-scons" or "--symlink-scons" + options on the command line. + + -- Install "scons-__VERSION__.bat" and "scons.bat" wrapper scripts in the + Python prefix directory on Windows (C:\Python*, for example). + This can be disabled by specifying the "--no-install-bat" option + on the command line. On UNIX or Linux systems, the + "--install-bat" option may be specified to have "scons-__VERSION__.bat" + and "scons.bat" files installed in the default system script + directory, which is useful if you want to install SCons in a + shared file system directory that can be used to execute SCons + from both UNIX/Linux and Windows systems. + + -- Install the SCons build engine (a Python module) in an + appropriate version-numbered SCons library directory + (/usr/lib/scons-__VERSION__ or C:\Python*\scons-__VERSION__, for example). + See below for more options related to installing the build + engine library. + + -- Install the troff-format man pages in an appropriate directory + on UNIX or Linux systems (/usr/share/man/man1 or /usr/man/man1, for example). This can be disabled by specifying the - "--no-install-doc" option on the command line. + "--no-install-man" option on the command line. The man pages + can be installed on Windows systems by specifying the + "--install-man" option on the command line. -Note that, by default, SCons does not install its library in the -standard Python library directories. If you want to be able to use the -SCons library modules (the build engine) in other Python scripts, you -can run the setup script as follows: +Note that, by default, SCons does not install its build engine library +in the standard Python library directories. If you want to be able to +use the SCons library modules (the build engine) in other Python +scripts, specify the "--standard-lib" option on the command line, as +follows: # python setup.py install --standard-lib -This will install the build engine in the standard Python -library directory (/usr/lib/python*/site-packages or +This will install the build engine in the standard Python library +directory (/usr/lib/python*/site-packages or C:\Python*\Lib\site-packages). -Alternatively, you may want to install multiple versions of SCons -side-by-side, which you can do as follows: - - # python setup.py install --version-lib - -This will install the build engine in a version-specific library -directory (/usr/lib/scons-__VERSION__ or C:\Python*\scons-__VERSION__). - -If this is not the first time you are installing SCons on your system, -the setup script will, by default, search for where you have previously -installed the SCons library, and install this version's library the -same way--that is, if you previously installed the SCons library in -the standard Python library, the setup script will install this one -in the same location. You may, of course, specify one of the --*-lib -options described above to select a specific library location, or use -the following option to explicitly select installation into the default -standalone library directory (/usr/lib/scons or C:\Python*\scons): +Alternatively, you can have SCons install its build engine library in a +hard-coded standalone library directory, instead of the default +version-numbered directory, by specifying the "--standalone-lib" option +on the command line, as follows: # python setup.py install --standalone-lib +This is usually not recommended, however. + Note that, to install SCons in any of the above system directories, you should have system installation privileges (that is, "root" or "Administrator") when running the setup.py script. If you don't have diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 1c23c10..eabc4f6 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -64,6 +64,16 @@ RELEASE 0.97 - XXX different file. This may cause configuration tests to be re-run the first time after you install 0.97. + -- setup.py INSTALLS VERSION-NUMBERED SCRIPTS AND DIRS BY DEFAULT + + The setup.py script has been changed to always install SCons in + a version-numbered directory (e.g. /usr/local/lib/scons-0.97 + or D:\Python23\scons-0.97) and with a version-numbered script + name (scons-0.97) in addition to the usual installation of an + "scons" script name. A number of new setup.py options allow + control over what does or does not get installed, and where. + See the README.txt or README files for additional information. + -- setup.py NOW INSTALLS MAN PAGES ON UNIX AND Linux SYSTEMS The SCons setup.py script now installs the "scons.1" and diff --git a/src/setup.py b/src/setup.py index bec2b18..2eed585 100644 --- a/src/setup.py +++ b/src/setup.py @@ -25,16 +25,30 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os import os.path +import stat import string import sys +Version = "0.96" + (head, tail) = os.path.split(sys.argv[0]) if head: os.chdir(head) sys.argv[0] = tail +is_win32 = 0 +if not sys.platform == 'win32': + try: + if sys.argv[1] == 'bdist_wininst': + is_win32 = 1 + except IndexError: + pass +else: + is_win32 = 1 + try: + import distutils import distutils.core import distutils.command.install import distutils.command.install_data @@ -57,14 +71,12 @@ _install_lib = distutils.command.install_lib.install_lib _install_scripts = distutils.command.install_scripts.install_scripts _build_scripts = distutils.command.build_scripts.build_scripts -install_doc = 1 -standard_lib = 0 -standalone_lib = 0 -version_lib = 0 +class _options: + pass -installed_lib_dir = None -installed_man_pages_dir = None -installed_scripts_dir = None +Options = _options() + +Installed = [] def set_explicitly(name, args): """ @@ -88,38 +100,85 @@ def set_explicitly(name, args): class install(_install): user_options = _install.user_options + [ - ('no-install-doc', None, + ('no-scons-script', None, + "don't install 'scons', only install 'scons-%s'" % Version), + ('no-version-script', None, + "don't install 'scons-%s', only install 'scons'" % Version), + ('install-bat', None, + "install 'scons.bat' script"), + ('no-install-bat', None, + "do not install 'scons.bat' script"), + ('install-man', None, + "install SCons man pages"), + ('no-install-man', None, "do not install SCons man pages"), ('standard-lib', None, "install SCons library in standard Python location"), ('standalone-lib', None, "install SCons library in separate standalone directory"), ('version-lib', None, - "install SCons library in version-specific directory") + "install SCons library in version-numbered directory"), ] boolean_options = _install.boolean_options + [ - 'no-install-doc', + 'no-scons-script', + 'no-version-script', + 'install-bat', + 'no-install-bat', + 'install-man', + 'no-install-man', 'standard-lib', 'standalone-lib', 'version-lib' ] + if hasattr(os, 'symlink'): + user_options.append( + ('hardlink-scons', None, + "hard link 'scons' to the version-numbered script, don't make a separate 'scons' copy"), + ) + boolean_options.append('hardlink-script') + + if hasattr(os, 'symlink'): + user_options.append( + ('symlink-scons', None, + "make 'scons' a symbolic link to the version-numbered script, don't make a separate 'scons' copy"), + ) + boolean_options.append('symlink-script') + def initialize_options(self): _install.initialize_options(self) - self.no_install_doc = 0 + self.no_scons_script = 0 + self.no_version_script = 0 + self.install_bat = 0 + self.no_install_bat = not is_win32 + self.install_man = 0 + self.no_install_man = is_win32 self.standard_lib = 0 self.standalone_lib = 0 self.version_lib = 0 + self.hardlink_scons = 0 + self.symlink_scons = 0 + # Don't warn about having to put the library directory in the + # search path. self.warn_dir = 0 def finalize_options(self): _install.finalize_options(self) - global install_doc, standard_lib, standalone_lib, version_lib - if self.no_install_doc: - install_doc = 0 - standard_lib = self.standard_lib - standalone_lib = self.standalone_lib - version_lib = self.version_lib + if self.install_bat: + Options.install_bat = 1 + else: + Options.install_bat = not self.no_install_bat + if self.install_man: + Options.install_man = 1 + else: + Options.install_man = not self.no_install_man + Options.standard_lib = self.standard_lib + Options.standalone_lib = self.standalone_lib + Options.version_lib = self.version_lib + Options.install_scons_script = not self.no_scons_script + Options.install_version_script = not self.no_version_script + Options.hardlink_scons = self.hardlink_scons + Options.symlink_scons = self.symlink_scons def get_scons_prefix(libdir, is_win32): """ @@ -146,13 +205,6 @@ def get_scons_prefix(libdir, is_win32): return libdir class install_lib(_install_lib): - def initialize_options(self): - _install_lib.initialize_options(self) - global standard_lib, standalone_lib, version_lib - self.standard_lib = standard_lib - self.standalone_lib = standalone_lib - self.version_lib = version_lib - def finalize_options(self): _install_lib.finalize_options(self) args = self.distribution.script_args @@ -161,43 +213,108 @@ class install_lib(_install_lib): # directory for libraries... is_win32 = sys.platform == "win32" or args[0] == 'bdist_wininst' prefix = get_scons_prefix(self.install_dir, is_win32) - standard_dir = os.path.join(self.install_dir, "SCons") - version_dir = os.path.join(prefix, "scons-__VERSION__") - standalone_dir = os.path.join(prefix, "scons") - if self.version_lib: - # ...but they asked for a version-specific directory. - self.install_dir = version_dir - elif self.standalone_lib: + if Options.standalone_lib: # ...but they asked for a standalone directory. - self.install_dir = standalone_dir - elif not self.standard_lib: - # ...and they didn't explicitly ask for the standard - # directory, so guess based on what's out there. - try: - l = os.listdir(prefix) - except OSError: - e = None - else: - e = filter(lambda x: x[:6] == "scons-", l) - if e: - # We found a path name (e.g.) /usr/lib/scons-XXX, - # so pick the version-specific directory. - self.install_dir = version_dir - elif os.path.exists(standalone_dir) or \ - not os.path.exists(standard_dir): - # There's already a standalone directory, or - # there's no SCons library in the standard - # directory, so go with the standalone. - self.install_dir = standalone_dir - global installed_lib_dir - installed_lib_dir = self.install_dir + self.install_dir = os.path.join(prefix, "scons") + elif Options.version_lib or not Options.standard_lib: + # ...they asked for a version-specific directory, + # or they get it by default. + self.install_dir = os.path.join(prefix, "scons-%s" % Version) + + msg = "Installed SCons library modules into %s" % self.install_dir + Installed.append(msg) class install_scripts(_install_scripts): def finalize_options(self): _install_scripts.finalize_options(self) self.build_dir = os.path.join('build', 'scripts') - global installed_scripts_dir - installed_scripts_dir = self.install_dir + msg = "Installed SCons scripts into %s" % self.install_dir + Installed.append(msg) + + def do_nothing(self, *args, **kw): + pass + + def hardlink_scons(self, src, dst, ver): + try: os.unlink(dst) + except OSError: pass + os.link(ver, dst) + + def symlink_scons(self, src, dst, ver): + try: os.unlink(dst) + except OSError: pass + os.symlink(os.path.split(ver)[1], dst) + + def copy_scons(self, src, dst, *args): + try: os.unlink(dst) + except OSError: pass + self.copy_file(src, dst) + self.outfiles.append(dst) + + def report(self, msg, args): + # Wrapper around self.announce, used by older distutils versions. + self.announce(msg % args) + + def run(self): + # This "skip_build/build_scripts" block is cut-and-paste from + # distutils. + if not self.skip_build: + self.run_command('build_scripts') + + # Custom SCons installation stuff. + if Options.hardlink_scons: + create_basename_script = self.hardlink_scons + elif Options.symlink_scons: + create_basename_script = self.symlink_scons + elif Options.install_scons_script: + create_basename_script = self.copy_scons + else: + create_basename_script = self.do_nothing + + if Options.install_version_script: + create_version_script = self.copy_scons + else: + create_version_script = self.do_nothing + + inputs = self.get_inputs() + bat_scripts = filter(lambda x: x[-4:] == '.bat', inputs) + non_bat_scripts = filter(lambda x: x[-4:] != '.bat', inputs) + + self.outfiles = [] + self.mkpath(self.install_dir) + + for src in non_bat_scripts: + base = os.path.basename(src) + scons = os.path.join(self.install_dir, base) + scons_ver = scons + '-' + Version + create_version_script(src, scons_ver) + create_basename_script(src, scons, scons_ver) + + if Options.install_bat: + if is_win32: + bat_install_dir = get_scons_prefix(self.install_dir, is_win32) + else: + bat_install_dir = self.install_dir + for src in bat_scripts: + scons_bat = os.path.join(bat_install_dir, 'scons.bat') + scons_version_bat = os.path.join(bat_install_dir, + 'scons-' + Version + '.bat') + self.copy_scons(src, scons_bat) + self.copy_scons(src, scons_version_bat) + + # This section is cut-and-paste from distutils, modulo being + # able + if os.name == 'posix': + try: report = distutils.log.info + except AttributeError: report = self.report + # Set the executable bits (owner, group, and world) on + # all the scripts we just installed. + for file in self.get_outputs(): + if self.dry_run: + report("changing mode of %s", file) + else: + mode = ((os.stat(file)[stat.ST_MODE]) | 0555) & 07777 + report("changing mode of %s", file) + os.chmod(file, mode) class build_scripts(_build_scripts): def finalize_options(self): @@ -207,19 +324,23 @@ class build_scripts(_build_scripts): class install_data(_install_data): def initialize_options(self): _install_data.initialize_options(self) - global install_doc - self.install_doc = install_doc def finalize_options(self): _install_data.finalize_options(self) - if self.install_doc: - global installed_man_pages_dir - installed_man_pages_dir = self.install_dir + '/man/man1' + if Options.install_man: + if is_win32: + dir = 'Doc' + else: + dir = os.path.join('man', 'man1') + self.data_files = [(dir, ["scons.1", "sconsign.1"])] + man_dir = os.path.join(self.install_dir, dir) + msg = "Installed SCons man pages into %s" % man_dir + Installed.append(msg) else: self.data_files = [] arguments = { 'name' : "scons", - 'version' : "__VERSION__", + 'version' : Version, 'packages' : ["SCons", "SCons.Node", "SCons.Optik", @@ -230,7 +351,10 @@ arguments = { "SCons.Sig", "SCons.Tool"], 'package_dir' : {'' : 'engine'}, - 'scripts' : ['script/scons', 'script/sconsign'], + 'data_files' : [('man/man1', ["scons.1", "sconsign.1"])], + 'scripts' : ['script/scons', + 'script/sconsign', + 'script/scons.bat'], 'cmdclass' : {'install' : install, 'install_lib' : install_lib, 'install_data' : install_data, @@ -238,26 +362,7 @@ arguments = { 'build_scripts' : build_scripts} } -is_win32 = 0 -if not sys.platform == 'win32': - try: - if sys.argv[1] == 'bdist_wininst': - is_win32 = 1 - except IndexError: - pass -else: - is_win32 = 1 - -if is_win32: - arguments['data_files'] = [('.', ["script/scons.bat"])] -else: - arguments['data_files'] = [('man/man1', ["scons.1", "sconsign.1"])] - apply(distutils.core.setup, (), arguments) -if installed_lib_dir: - print "Installed SCons library modules into %s" % installed_lib_dir -if installed_man_pages_dir: - print "Installed SCons man pages into %s" % installed_man_pages_dir -if installed_scripts_dir: - print "Installed SCons scripts into %s" % installed_scripts_dir +if Installed: + print string.join(Installed, '\n') diff --git a/src/test_setup.py b/src/test_setup.py index 73b6588..7d220e2 100644 --- a/src/test_setup.py +++ b/src/test_setup.py @@ -37,6 +37,9 @@ import shutil import string import sys +try: WindowsError +except NameError: WindowsError = OSError + #try: # version = os.environ['SCONS_VERSION'] #except KeyError: @@ -51,12 +54,34 @@ python = TestSCons.python class MyTestSCons(TestSCons.TestSCons): - scripts = [ + _lib_modules = [ + # A representative smattering of build engine modules. + '__init__.py', + 'Action.py', + 'Builder.py', + 'Environment.py', + 'Util.py', + ] + + _base_scripts = [ 'scons', 'sconsign', ] - man_pages = [ + _version_scripts = [ + 'scons-%s' % version, + 'sconsign-%s' % version, + ] + + _bat_scripts = [ + 'scons.bat', + ] + + _bat_version_scripts = [ + 'scons-%s.bat' % version, + ] + + _man_pages = [ 'scons.1', 'sconsign.1', ] @@ -64,18 +89,33 @@ class MyTestSCons(TestSCons.TestSCons): def __init__(self): TestSCons.TestSCons.__init__(self) self.root = self.workpath('root') - self.prefix = self.root + sys.prefix - - self.lib_dir = os.path.join(self.prefix, 'lib') - self.standard_lib = os.path.join(self.lib_dir, - 'python%s' % sys.version[:3], - 'site-packages/') - self.standalone_lib = os.path.join(self.lib_dir, 'scons') - self.version_lib = os.path.join(self.lib_dir, scons_version) - - self.bin_dir = os.path.join(self.prefix, 'bin') - - self.man_dir = os.path.join(self.prefix, 'man', 'man1') + self.prefix = self.root + os.path.splitdrive(sys.prefix)[1] + + if sys.platform == 'win32': + self.bin_dir = os.path.join(self.prefix, 'Scripts') + self.bat_dir = self.prefix + self.standalone_lib = os.path.join(self.prefix, 'scons') + self.standard_lib = os.path.join(self.prefix, + 'Lib', + 'site-packages', + '') + self.version_lib = os.path.join(self.prefix, scons_version) + self.man_dir = os.path.join(self.prefix, 'Doc') + else: + self.bin_dir = os.path.join(self.prefix, 'bin') + self.bat_dir = self.bin_dir + self.lib_dir = os.path.join(self.prefix, 'lib') + self.standalone_lib = os.path.join(self.lib_dir, 'scons') + self.standard_lib = os.path.join(self.lib_dir, + 'python%s' % sys.version[:3], + 'site-packages', + '') + self.version_lib = os.path.join(self.lib_dir, scons_version) + self.man_dir = os.path.join(self.prefix, 'man', 'man1') + + self.prepend_bin_dir = lambda p, d=self.bin_dir: os.path.join(d, p) + self.prepend_bat_dir = lambda p, d=self.bat_dir: os.path.join(d, p) + self.prepend_man_dir = lambda p, d=self.man_dir: os.path.join(d, p) def run(self, *args, **kw): kw['chdir'] = scons_version @@ -83,24 +123,50 @@ class MyTestSCons(TestSCons.TestSCons): kw['stderr'] = None return apply(TestSCons.TestSCons.run, (self,)+args, kw) - def must_have_installed_lib(self, lib): - lines = string.split(self.stdout(), '\n') - line = 'Installed SCons library modules into %s' % lib - self.fail_test(not line in lines) - - def must_have_installed_scripts(self): - lines = string.split(self.stdout(), '\n') - line = 'Installed SCons scripts into %s' % self.bin_dir - self.fail_test(not line in lines) - for script in self.scripts: - self.must_exist([self.bin_dir, script]) - - def must_have_installed_man_pages(self): - lines = string.split(self.stdout(), '\n') - line = 'Installed SCons man pages into %s' % self.man_dir - self.fail_test(not line in lines) - for mp in self.man_pages: - self.must_exist([self.man_dir, mp]) + def remove(self, dir): + try: shutil.rmtree(dir) + except (OSError, WindowsError): pass + + def stdout_lines(self): + return string.split(self.stdout(), '\n') + + + def lib_line(self, lib): + return 'Installed SCons library modules into %s' % lib + + def lib_paths(self, lib_dir): + prepend_lib_dir = lambda p, d=lib_dir: os.path.join(d, 'SCons', p) + return map(prepend_lib_dir, self._lib_modules) + + def scripts_line(self): + return 'Installed SCons scripts into %s' % self.bin_dir + + def base_script_paths(self): + scripts = self._base_scripts + return map(self.prepend_bin_dir, scripts) + + def version_script_paths(self): + scripts = self._version_scripts + return map(self.prepend_bin_dir, scripts) + + def bat_script_paths(self): + scripts = self._bat_scripts + self._bat_version_scripts + return map(self.prepend_bat_dir, scripts) + + def man_page_line(self): + return 'Installed SCons man pages into %s' % self.man_dir + + def man_page_paths(self): + return map(self.prepend_man_dir, self._man_pages) + + + def must_have_installed(self, paths): + for p in paths: + self.must_exist(p) + + def must_not_have_installed(self, paths): + for p in paths: + self.must_not_exist(p) try: cwd = os.environ['SCONS_CWD'] @@ -112,53 +178,146 @@ test = MyTestSCons() test.subdir(test.root) tar_gz = os.path.join(cwd, 'build', 'dist', '%s.tar.gz' % scons_version) - -if not os.path.isfile(tar_gz): - print "Did not find an SCons package `%s'." % tar_gz +zip = os.path.join(cwd, 'build', 'dist', '%s.zip' % scons_version) + +if os.path.isfile(zip): + try: import zipfile + except ImportError: pass + else: + zf = zipfile.ZipFile(zip, 'r') + + for name in zf.namelist(): + dir = os.path.dirname(name) + try: os.makedirs(dir) + except: pass + # if the file exists, then delete it before writing + # to it so that we don't end up trying to write to a symlink: + if os.path.isfile(name) or os.path.islink(name): + os.unlink(name) + if not os.path.isdir(name): + open(name, 'w').write(zf.read(name)) + +if not os.path.isdir(scons_version) and os.path.isfile(tar_gz): + # Unpack the .tar.gz file. This should create the scons_version/ + # subdirectory from which we execute the setup.py script therein. + os.system("gunzip -c %s | tar xf -" % tar_gz) + +if not os.path.isdir(scons_version): + print "Found neither SCons package `%s' nor `%s'." % (tar_gz, zip) print "Cannot test package installation." test.no_result(1) -# Unpack the .tar.gz file. This should create the scons_version/ -# subdirectory from which we execute the setup.py script therein. -os.system("gunzip -c %s | tar xf -" % tar_gz) - -# Verify that a virgin installation installs the standalone library, -# the scripts and the man pages. +# Verify that a virgin installation installs the version library, +# the scripts and (on UNIX/Linux systems) the man pages. test.run(arguments = 'setup.py install --root=%s' % test.root) -test.must_have_installed_lib(test.standalone_lib) -test.must_have_installed_scripts() -test.must_have_installed_man_pages() +test.fail_test(not test.lib_line(test.version_lib) in test.stdout_lines()) +test.must_have_installed(test.lib_paths(test.version_lib)) # Verify that --standard-lib installs into the Python standard library. test.run(arguments = 'setup.py install --root=%s --standard-lib' % test.root) -test.must_have_installed_lib(test.standard_lib) +test.fail_test(not test.lib_line(test.standard_lib) in test.stdout_lines()) +test.must_have_installed(test.lib_paths(test.standard_lib)) # Verify that --standalone-lib installs the standalone library. test.run(arguments = 'setup.py install --root=%s --standalone-lib' % test.root) -test.must_have_installed_lib(test.standalone_lib) +test.fail_test(not test.lib_line(test.standalone_lib) in test.stdout_lines()) +test.must_have_installed(test.lib_paths(test.standalone_lib)) # Verify that --version-lib installs into a version-specific library directory. test.run(arguments = 'setup.py install --root=%s --version-lib' % test.root) -test.must_have_installed_lib(test.version_lib) +test.fail_test(not test.lib_line(test.version_lib) in test.stdout_lines()) # Now that all of the libraries are in place, -# verify that a default installation finds the version-specific library first. +# verify that a default installation still installs the version library. test.run(arguments = 'setup.py install --root=%s' % test.root) -test.must_have_installed_lib(test.version_lib) +test.fail_test(not test.lib_line(test.version_lib) in test.stdout_lines()) -shutil.rmtree(test.version_lib) +test.remove(test.version_lib) # Now with only the standard and standalone libraries in place, -# verify that a default installation finds the standalone library first. +# verify that a default installation still installs the version library. test.run(arguments = 'setup.py install --root=%s' % test.root) -test.must_have_installed_lib(test.standalone_lib) +test.fail_test(not test.lib_line(test.version_lib) in test.stdout_lines()) -shutil.rmtree(test.standalone_lib) +test.remove(test.version_lib) +test.remove(test.standalone_lib) # Now with only the standard libraries in place, -# verify that a default installation installs the standard library. +# verify that a default installation still installs the version library. test.run(arguments = 'setup.py install --root=%s' % test.root) -test.must_have_installed_lib(test.standard_lib) +test.fail_test(not test.lib_line(test.version_lib) in test.stdout_lines()) + + + +# +test.run(arguments = 'setup.py install --root=%s' % test.root) +test.fail_test(not test.scripts_line() in test.stdout_lines()) +if sys.platform == 'win32': + test.must_have_installed(test.base_script_paths()) + test.must_have_installed(test.version_script_paths()) + test.must_have_installed(test.bat_script_paths()) +else: + test.must_have_installed(test.base_script_paths()) + test.must_have_installed(test.version_script_paths()) + test.must_not_have_installed(test.bat_script_paths()) + +test.remove(test.prefix) + +test.run(arguments = 'setup.py install --root=%s --no-install-bat' % test.root) +test.fail_test(not test.scripts_line() in test.stdout_lines()) +test.must_have_installed(test.base_script_paths()) +test.must_have_installed(test.version_script_paths()) +test.must_not_have_installed(test.bat_script_paths()) + +test.remove(test.prefix) + +test.run(arguments = 'setup.py install --root=%s --install-bat' % test.root) +test.fail_test(not test.scripts_line() in test.stdout_lines()) +test.must_have_installed(test.base_script_paths()) +test.must_have_installed(test.version_script_paths()) +test.must_have_installed(test.bat_script_paths()) + +test.remove(test.prefix) + +test.run(arguments = 'setup.py install --root=%s --no-scons-script' % test.root) +test.fail_test(not test.scripts_line() in test.stdout_lines()) +test.must_not_have_installed(test.base_script_paths()) +test.must_have_installed(test.version_script_paths()) +# Doesn't matter whether we installed the .bat scripts or not. + +test.remove(test.prefix) + +test.run(arguments = 'setup.py install --root=%s --no-version-script' % test.root) +test.fail_test(not test.scripts_line() in test.stdout_lines()) +test.must_have_installed(test.base_script_paths()) +test.must_not_have_installed(test.version_script_paths()) +# Doesn't matter whether we installed the .bat scripts or not. + + + +test.remove(test.man_dir) + +test.run(arguments = 'setup.py install --root=%s' % test.root) +if sys.platform == 'win32': + test.fail_test(test.man_page_line() in test.stdout_lines()) + test.must_not_have_installed(test.man_page_paths()) +else: + test.fail_test(not test.man_page_line() in test.stdout_lines()) + test.must_have_installed(test.man_page_paths()) + +test.remove(test.man_dir) + +test.run(arguments = 'setup.py install --root=%s --no-install-man' % test.root) +test.fail_test(test.man_page_line() in test.stdout_lines()) +test.must_not_have_installed(test.man_page_paths()) + +test.remove(test.man_dir) + +test.run(arguments = 'setup.py install --root=%s --install-man' % test.root) +test.fail_test(not test.man_page_line() in test.stdout_lines()) +test.must_have_installed(test.man_page_paths()) + + # Verify that we don't warn about the directory in which we've # installed the modules when using a non-standard prefix. -- cgit v0.12