# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: mats.kindahl@oracle.com-20110126085532-9c21vqy09keyplg4 # target_branch: file:///bzrroot/mysql/public/mysql-utilities/trunk/ # testament_sha1: 8f0bd46177d82c8258e2ae29d14cbdc8b17acf16 # timestamp: 2011-01-26 09:56:02 +0100 # source_branch: file:///bzrroot/mysql/public/mysql-utilities/trunk/ # base_revision_id: chuck.bell@oracle.com-20110119160835-\ # yqmi38iqbzbs8gmi # # Begin patch === modified file 'MANIFEST.in' --- MANIFEST.in 2010-12-07 12:19:58 +0000 +++ MANIFEST.in 2010-12-21 15:01:54 +0000 @@ -1,4 +1,3 @@ include *.txt recursive-include tests *.py recursive-include man *.rst -prune dist === modified file 'README.txt' --- README.txt 2010-12-07 12:22:29 +0000 +++ README.txt 2010-12-21 15:01:54 +0000 @@ -18,6 +18,27 @@ Note: for some platforms, you may need to execute this command with administrative privileges. +To get help for ``setup.py``, you can do:: + + python setup.py --help + +To get a complete list of commands available for ``setup.py``, you can +do:: + + python setup.py --help-commands + + +Requirements +~~~~~~~~~~~~ + +MySQL Utilities have some dependencies on other packages: +- Python 2.6 or later but Python 3.x is not supported (yet). +- Sphinx version 1.0 or later is needed to build the manuals from + Sphinx markup. If you do not bother about building the manuals, + earlier versions of Sphinx work fine. +- Sphinx requires docutils to build the documentation. +- Sphinx also requires Jinja2 2.1 or later to generate HTML pages. + Windows Notes ~~~~~~~~~~~~~ @@ -49,16 +70,19 @@ python setup.py build_sphinx -b html -To create documentation in man format:: +To create documentation in man format, which requires Sphinx version +1.0 or later either one of the following commands can be used:: python setup.py build_sphinx -b man -or python setup.py build_man +Manual pages are currently not pre-generated. + To create documentation in epub format:: python setup.py build_sphinx -b epub + Unit Tests ---------- @@ -66,6 +90,7 @@ python setup.py test + Systems Tests ------------- @@ -80,15 +105,25 @@ tests. You can specify one or more tests as arguments to the command. See the manual for more information about the MySQL Utilities Testing utility (mut). + Operating System Notes ---------------------- -The MySQL Utilities are designed to run on any platform that supports Python -2.6 or higher. You should ensure you have Python installed and configured -correctly before installing. +The MySQL Utilities are designed to run on any platform that supports +Python 2.6 or higher. You should ensure you have Python installed and +configured correctly before installing. There are no known issues on any platform. + +Reporting bugs +-------------- + +Bugs are reported in the Oracle/MySQL bugs system at: + + http://bugs.mysql.com/ + + Contributors ------------ === renamed directory 'docs' => 'doc' === removed file 'ez_setup.py' --- ez_setup.py 2010-12-07 12:19:58 +0000 +++ ez_setup.py 1970-01-01 00:00:00 +0000 @@ -1,284 +0,0 @@ -#!python -"""Bootstrap setuptools installation - -If you want to use setuptools in your package's setup.py, just include this -file in the same directory with it, and add this to the top of your setup.py:: - - from ez_setup import use_setuptools - use_setuptools() - -If you want to require a specific version of setuptools, set a download -mirror, or use an alternate download directory, you can do so by supplying -the appropriate options to ``use_setuptools()``. - -This file can also be run as a script to install or upgrade setuptools. -""" -import sys -DEFAULT_VERSION = "0.6c11" -DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] - -md5_data = { - 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', - 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', - 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', - 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', - 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', - 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', - 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', - 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', - 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', - 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', - 'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090', - 'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4', - 'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7', - 'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5', - 'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de', - 'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b', - 'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2', - 'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086', - 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', - 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', - 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', - 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', - 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', - 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', - 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', - 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', - 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', - 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', - 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', - 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', - 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', - 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', - 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2', - 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e', - 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', - 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902', - 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de', - 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b', - 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03', - 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a', - 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6', - 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a', -} - -import sys, os -try: from hashlib import md5 -except ImportError: from md5 import md5 - -def _validate_md5(egg_name, data): - if egg_name in md5_data: - digest = md5(data).hexdigest() - if digest != md5_data[egg_name]: - print >>sys.stderr, ( - "md5 validation of %s failed! (Possible download problem?)" - % egg_name - ) - sys.exit(2) - return data - -def use_setuptools( - version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, - download_delay=15 -): - """Automatically find/download setuptools and make it available on sys.path - - `version` should be a valid setuptools version number that is available - as an egg for download under the `download_base` URL (which should end with - a '/'). `to_dir` is the directory where setuptools will be downloaded, if - it is not already available. If `download_delay` is specified, it should - be the number of seconds that will be paused before initiating a download, - should one be required. If an older version of setuptools is installed, - this routine will print a message to ``sys.stderr`` and raise SystemExit in - an attempt to abort the calling script. - """ - was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules - def do_download(): - egg = download_setuptools(version, download_base, to_dir, download_delay) - sys.path.insert(0, egg) - import setuptools; setuptools.bootstrap_install_from = egg - try: - import pkg_resources - except ImportError: - return do_download() - try: - pkg_resources.require("setuptools>="+version); return - except pkg_resources.VersionConflict, e: - if was_imported: - print >>sys.stderr, ( - "The required version of setuptools (>=%s) is not available, and\n" - "can't be installed while this script is running. Please install\n" - " a more recent version first, using 'easy_install -U setuptools'." - "\n\n(Currently using %r)" - ) % (version, e.args[0]) - sys.exit(2) - else: - del pkg_resources, sys.modules['pkg_resources'] # reload ok - return do_download() - except pkg_resources.DistributionNotFound: - return do_download() - -def download_setuptools( - version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, - delay = 15 -): - """Download setuptools from a specified location and return its filename - - `version` should be a valid setuptools version number that is available - as an egg for download under the `download_base` URL (which should end - with a '/'). `to_dir` is the directory where the egg will be downloaded. - `delay` is the number of seconds to pause before an actual download attempt. - """ - import urllib2, shutil - egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) - url = download_base + egg_name - saveto = os.path.join(to_dir, egg_name) - src = dst = None - if not os.path.exists(saveto): # Avoid repeated downloads - try: - from distutils import log - if delay: - log.warn(""" ---------------------------------------------------------------------------- -This script requires setuptools version %s to run (even to display -help). I will attempt to download it for you (from -%s), but -you may need to enable firewall access for this script first. -I will start the download in %d seconds. - -(Note: if this machine does not have network access, please obtain the file - - %s - -and place it in this directory before rerunning this script.) ----------------------------------------------------------------------------""", - version, download_base, delay, url - ); from time import sleep; sleep(delay) - log.warn("Downloading %s", url) - src = urllib2.urlopen(url) - # Read/write all in one block, so we don't create a corrupt file - # if the download is interrupted. - data = _validate_md5(egg_name, src.read()) - dst = open(saveto,"wb"); dst.write(data) - finally: - if src: src.close() - if dst: dst.close() - return os.path.realpath(saveto) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -def main(argv, version=DEFAULT_VERSION): - """Install or upgrade setuptools and EasyInstall""" - try: - import setuptools - except ImportError: - egg = None - try: - egg = download_setuptools(version, delay=0) - sys.path.insert(0,egg) - from setuptools.command.easy_install import main - return main(list(argv)+[egg]) # we're done here - finally: - if egg and os.path.exists(egg): - os.unlink(egg) - else: - if setuptools.__version__ == '0.0.1': - print >>sys.stderr, ( - "You have an obsolete version of setuptools installed. Please\n" - "remove it from your system entirely before rerunning this script." - ) - sys.exit(2) - - req = "setuptools>="+version - import pkg_resources - try: - pkg_resources.require(req) - except pkg_resources.VersionConflict: - try: - from setuptools.command.easy_install import main - except ImportError: - from easy_install import main - main(list(argv)+[download_setuptools(delay=0)]) - sys.exit(0) # try to force an exit - else: - if argv: - from setuptools.command.easy_install import main - main(argv) - else: - print "Setuptools version",version,"or greater has been installed." - print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' - -def update_md5(filenames): - """Update our built-in md5 registry""" - - import re - - for name in filenames: - base = os.path.basename(name) - f = open(name,'rb') - md5_data[base] = md5(f.read()).hexdigest() - f.close() - - data = [" %r: %r,\n" % it for it in md5_data.items()] - data.sort() - repl = "".join(data) - - import inspect - srcfile = inspect.getsourcefile(sys.modules[__name__]) - f = open(srcfile, 'rb'); src = f.read(); f.close() - - match = re.search("\nmd5_data = {\n([^}]+)}", src) - if not match: - print >>sys.stderr, "Internal error!" - sys.exit(2) - - src = src[:match.start(1)] + repl + src[match.end(1):] - f = open(srcfile,'w') - f.write(src) - f.close() - - -if __name__=='__main__': - if len(sys.argv)>2 and sys.argv[1]=='--md5update': - update_md5(sys.argv[2:]) - else: - main(sys.argv[1:]) - - - - - - === modified file 'freeze.py' --- freeze.py 2010-12-07 12:19:58 +0000 +++ freeze.py 2010-12-21 15:01:54 +0000 @@ -1,10 +1,11 @@ #!/usr/bin/python import sys -import cx_Freeze from info import META_INFO, INSTALL, COMMANDS +from cx_Freeze import setup # Setup function to use + if sys.platform.startswith("win32"): META_INFO['name'] = 'MySQL Utilities' @@ -20,5 +21,5 @@ ARGS.update(META_INFO) ARGS.update(INSTALL) ARGS.update(COMMANDS) -cx_Freeze.setup(**ARGS) +setup(**ARGS) === modified file 'info.py' --- info.py 2010-12-07 14:20:44 +0000 +++ info.py 2010-12-21 15:01:54 +0000 @@ -1,11 +1,7 @@ -# Boilerplate code to install setuptools if it is not installed -import ez_setup -ez_setup.use_setuptools() import distutils.command.build_scripts import distutils.util import glob -import setuptools import os import mysql.utilities @@ -35,9 +31,19 @@ } INSTALL = { - 'packages': setuptools.find_packages(exclude=["tests"]), + 'packages': [ + 'mysql', + 'mysql.utilities', + 'mysql.utilities.command', + 'mysql.utilities.common', + ], 'scripts': glob.glob('scripts/*.py'), - 'setup_requires': [ - 'Sphinx >=1.0', + 'requires': [ + 'distutils', + 'sphinx (>=1.0)', + 'jinja2 (>=2.1)', + ], + 'provides': [ + 'mysql.utilities', ], } === modified file 'setup.py' --- setup.py 2010-12-06 22:35:50 +0000 +++ setup.py 2010-12-21 15:01:54 +0000 @@ -1,20 +1,17 @@ #!/usr/bin/python -# Boilerplate code to install setuptools if it is not installed -import ez_setup -ez_setup.use_setuptools() - # Keep the imports sorted (alphabetically) in each group. Makes # merging easier. import distutils.core -import glob import os -import setuptools import sys -import mysql.utilities +# Setup function to use +from distutils.core import setup +from distutils.command.build_scripts import build_scripts as _build_scripts +from distutils.command.install_scripts import install_scripts as _install_scripts from info import META_INFO, INSTALL COMMANDS = { @@ -23,16 +20,55 @@ } ARGS = { - 'test_suite': 'tests.test_all', } +PROFILE_SCRIPT = ''' +prepend_path () ( + IFS=':' + for D in $PATH; do + if test x$D != x$1; then + OUTPATH="${OUTPATH:+$OUTPATH:}$D" + fi + done + echo "$1:$OUTPATH" +) + +PATH=`prepend_path %s` +''' + +class install_scripts(_install_scripts): + description = (_install_scripts.description + + " and add path to /etc/profile.d") + + profile_file = "/etc/profile.d/mysql-utilities.sh" + + def run(self): + # We should probably use distutils.dist.execute here to allow + # --dry-run to work properly. + from distutils import log, dir_util + outfile = self.profile_file + if os.path.isdir(outfile) and not os.path.islink(outfile): + dir_util.remove_tree(outfile) + elif os.path.exists(outfile): + log.info("Removing %s", outfile) + os.unlink(outfile) + script = PROFILE_SCRIPT % (self.install_dir,) + log.info("Writing %s", outfile) + open(outfile, "w+").write(script) + _install_scripts.run(self) + + def get_outputs(self): + outputs = _install_scripts.get_outputs(self) + outputs.append(self.profile_file) + return outputs + class install_man(distutils.core.Command): description = "install (Unix) manual pages" user_options = [ ('install-base=', None, "base installation directory"), ('force', 'f', 'force installation (overwrite existing files)'), - ('build-dir=', None, 'Build directory'), + ('build-dir=', 'b', 'Build directory'), ('skip-build', None, "skip the build steps"), ] @@ -56,30 +92,38 @@ self.source_dir = os.path.join(self.build_dir, 'man') def run(self): - for man_file in self.get_outputs(): + from glob import glob + from distutils import log + + outfiles = [] + man_files = glob(os.path.join(self.source_dir, '*.[12345678]')) + for man_file in man_files: man_dir = 'man' + os.path.splitext(man_file)[1][1:] man_page = os.path.basename(man_file) self.mkpath(man_dir) man_install = os.path.join(self.target_dir, man_dir, man_page) self.copy_file(man_file, man_install) + outfiles.append(man_install) + self.outfiles = outfiles def get_outputs(self): - return glob.glob(os.path.join(self.source_dir, '*.[12345678]')) + return self.outfiles or [] # See if we have Sphinx installed, otherwise, just ignore building # documentation. try: import sphinx.setup_command - from distutils.command.install import install + from distutils.command.install import install as _install - class MyInstall(install): - sub_commands = install.sub_commands + [ + class install(_install): + sub_commands = _install.sub_commands + [ ('install_man', lambda self: True), ] COMMANDS['cmdclass'].update({ - 'install': MyInstall, + 'install': install, 'install_man': install_man, + 'build_sphinx': sphinx.setup_command.BuildDoc, 'build_man': sphinx.setup_command.BuildDoc, }) @@ -96,7 +140,7 @@ 'install': install, }) -class MyBuildScripts(distutils.command.build_scripts.build_scripts): +class build_scripts(_build_scripts): """Class for providing a customized version of build_scripts. When ``run`` is called, this command class will: @@ -111,8 +155,10 @@ def run(self): from distutils import log + if not self.scripts: return + saved_scripts = self.scripts self.scripts = [] for script in saved_scripts: @@ -127,15 +173,16 @@ self.scripts.append(script_copy) # distutils is compatible with 2.1 so we cannot use super() to # call it. - distutils.command.build_scripts.build_scripts.run(self) + _build_scripts.run(self) self.scripts = saved_scripts if os.name != "nt": COMMANDS['cmdclass'].update({ - 'build_scripts': MyBuildScripts, + 'build_scripts': build_scripts, + 'install_scripts': install_scripts, }) ARGS.update(META_INFO) ARGS.update(INSTALL) ARGS.update(COMMANDS) -setuptools.setup(**ARGS) +setup(**ARGS) # Begin bundle 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