summaryrefslogtreecommitdiffstats
path: root/Tools/versioncheck
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/versioncheck')
-rw-r--r--Tools/versioncheck/README41
-rw-r--r--Tools/versioncheck/_checkversion.py16
-rw-r--r--Tools/versioncheck/checkversions.py54
-rw-r--r--Tools/versioncheck/pyversioncheck.py101
4 files changed, 212 insertions, 0 deletions
diff --git a/Tools/versioncheck/README b/Tools/versioncheck/README
new file mode 100644
index 0000000..a51411b
--- /dev/null
+++ b/Tools/versioncheck/README
@@ -0,0 +1,41 @@
+This is versioncheck 1.0, a first stab at automatic checking of versions of
+Python extension packages installed on your system.
+
+The basic idea is that each package contains a _checkversion.py
+somewhere, probably at the root level of the package. In addition, each
+package maintainer makes a file available on the net, through ftp or
+http, which contains the version number of the most recent distribution
+and some readable text explaining the differences with previous
+versions, where to download the package, etc.
+
+The checkversions.py script walks through the installed Python tree (or
+through a tree of choice), and runs each _checkversion.py script. These
+scripts retrieve the current-version file over the net, compares version
+numbers and tells the user about new versions of packages available.
+
+A boilerplate for the _checkversion.py file can be found here. Replace
+package name, version and the URL of the version-check file and put it in
+your distribution. In stead of a single URL you can also specify a list
+of URLs. Each of these will be checked in order until one is available,
+this is handy for distributions that live in multiple places. Put the
+primary distribution site (the most up-to-date site) before others.
+The script is executed with execfile(), not imported, and the current
+directory is the checkversion directory, so be careful with globals,
+importing, etc.
+
+The version-check file consists of an rfc822-style header followed by
+plaintext. The only header field checked currently is
+'Current-Version:', which should contain te current version and is
+matched against the string contained in the _checkversion.py script.
+The rest of the file is human-readable text and presented to the user if
+there is a version mismatch. It should contain at the very least a URL
+of either the current distribution or a webpage describing it.
+
+Pycheckversion.py is the module that does the actual checking of versions.
+It should be fine where it is, it is imported by checkversion before anything
+else is done, but if imports fail you may want to move it to somewhere
+along sys.path.
+
+ Jack Jansen, CWI, 23-Dec-97.
+ <jack@cwi.nl>
+
diff --git a/Tools/versioncheck/_checkversion.py b/Tools/versioncheck/_checkversion.py
new file mode 100644
index 0000000..a103bf9
--- /dev/null
+++ b/Tools/versioncheck/_checkversion.py
@@ -0,0 +1,16 @@
+"""This file (which is sourced, not imported) checks the version of the
+"versioncheck" package. It is also an example of how to format your own
+_checkversion.py file"""
+
+import pyversioncheck
+
+_PACKAGE="versioncheck"
+_VERSION="1.0"
+_URL="http://www.cwi.nl/~jack/versioncheck/curversion.txt"
+
+try:
+ _myverbose=VERBOSE
+except NameError:
+ _myverbose=1
+
+pyversioncheck.versioncheck(_PACKAGE, _URL, _VERSION, verbose=_myverbose)
diff --git a/Tools/versioncheck/checkversions.py b/Tools/versioncheck/checkversions.py
new file mode 100644
index 0000000..5715da1
--- /dev/null
+++ b/Tools/versioncheck/checkversions.py
@@ -0,0 +1,54 @@
+"""Checkversions - recursively search a directory (default: sys.prefix)
+for _checkversion.py files, and run each of them. This will tell you of
+new versions available for any packages you have installed."""
+
+import os
+import getopt
+import sys
+import pyversioncheck
+
+CHECKNAME="_checkversion.py"
+
+VERBOSE=1
+
+USAGE="""Usage: checkversions [-v verboselevel] [dir ...]
+Recursively examine a tree (default: sys.prefix) and for each package
+with a _checkversion.py file compare the installed version against the current
+version.
+
+Values for verboselevel:
+0 - Minimal output, one line per package
+1 - Also print descriptions for outdated packages (default)
+2 - Print information on each URL checked
+3 - Check every URL for packages with multiple locations"""
+
+def check1dir(dummy, dir, files):
+ if CHECKNAME in files:
+ fullname = os.path.join(dir, CHECKNAME)
+ try:
+ execfile(fullname)
+ except:
+ print '** Exception in', fullname
+
+def walk1tree(tree):
+ os.path.walk(tree, check1dir, None)
+
+def main():
+ global VERBOSE
+ try:
+ options, arguments = getopt.getopt(sys.argv[1:], 'v:')
+ except getopt.error:
+ print USAGE
+ sys.exit(1)
+ for o, a in options:
+ if o == '-v':
+ VERBOSE = string.atoi(a)
+ if not arguments:
+ arguments = [sys.prefix]
+ for dir in arguments:
+ walk1tree(dir)
+
+if __name__ == '__main__':
+ main()
+
+
diff --git a/Tools/versioncheck/pyversioncheck.py b/Tools/versioncheck/pyversioncheck.py
new file mode 100644
index 0000000..074e917
--- /dev/null
+++ b/Tools/versioncheck/pyversioncheck.py
@@ -0,0 +1,101 @@
+"""pyversioncheck - Module to help with checking versions"""
+import Types
+import rfc822
+import urllib
+import sys
+import string
+
+# Verbose options
+VERBOSE_SILENT=0 # Single-line reports per package
+VERBOSE_NORMAL=1 # Single-line reports per package, more info if outdated
+VERBOSE_EACHFILE=2 # Report on each URL checked
+VERBOSE_CHECKALL=3 # Check each URL for each package
+
+# Test directory
+## urllib bug: _TESTDIR="ftp://ftp.cwi.nl/pub/jack/python/versiontestdir/"
+_TESTDIR="http://www.cwi.nl/~jack/versiontestdir/"
+
+def versioncheck(package, url, version, verbose=0):
+ ok, newversion, fp = checkonly(package, url, version, verbose)
+ if verbose > VERBOSE_NORMAL:
+ return ok
+ if ok < 0:
+ print '%s: No correctly formatted current version file found'%(package)
+ elif ok == 1:
+ print '%s: up-to-date (version %s)'%(package, version)
+ else:
+ print '%s: version %s installed, version %s found:' % \
+ (package, version, newversion)
+ if verbose > VERBOSE_SILENT:
+ while 1:
+ line = fp.readline()
+ if not line: break
+ sys.stdout.write('\t'+line)
+ return ok
+
+def checkonly(package, url, version, verbose=0):
+ if verbose >= VERBOSE_EACHFILE:
+ print '%s:'%package
+ if type(url) == Types.StringType:
+ ok, newversion, fp = _check1version(package, url, version, verbose)
+ else:
+ for u in url:
+ ok, newversion, fp = _check1version(package, u, version, verbose)
+ if ok >= 0 and verbose < VERBOSE_CHECKALL:
+ break
+ return ok, newversion, fp
+
+def _check1version(package, url, version, verbose=0):
+ if verbose >= VERBOSE_EACHFILE:
+ print ' Checking %s'%url
+ try:
+ fp = urllib.urlopen(url)
+ except IOError, arg:
+ if verbose >= VERBOSE_EACHFILE:
+ print ' Cannot open:', arg
+ return -1, None, None
+ msg = rfc822.Message(fp, seekable=0)
+ newversion = msg.getheader('current-version')
+ if not newversion:
+ if verbose >= VERBOSE_EACHFILE:
+ print ' No "Current-Version:" header in URL or URL not found'
+ return -1, None, None
+ version = string.strip(string.lower(version))
+ newversion = string.strip(string.lower(newversion))
+ if version == newversion:
+ if verbose >= VERBOSE_EACHFILE:
+ print ' Version identical (%s)'%newversion
+ return 1, version, fp
+ else:
+ if verbose >= VERBOSE_EACHFILE:
+ print ' Versions different (installed: %s, new: %s)'% \
+ (version, newversion)
+ return 0, newversion, fp
+
+
+def _test():
+ print '--- TEST VERBOSE=1'
+ print '--- Testing existing and identical version file'
+ versioncheck('VersionTestPackage', _TESTDIR+'Version10.txt', '1.0', verbose=1)
+ print '--- Testing existing package with new version'
+ versioncheck('VersionTestPackage', _TESTDIR+'Version11.txt', '1.0', verbose=1)
+ print '--- Testing package with non-existing version file'
+ versioncheck('VersionTestPackage', _TESTDIR+'nonexistent.txt', '1.0', verbose=1)
+ print '--- Test package with 2 locations, first non-existing second ok'
+ versfiles = [_TESTDIR+'nonexistent.txt', _TESTDIR+'Version10.txt']
+ versioncheck('VersionTestPackage', versfiles, '1.0', verbose=1)
+ print '--- TEST VERBOSE=2'
+ print '--- Testing existing and identical version file'
+ versioncheck('VersionTestPackage', _TESTDIR+'Version10.txt', '1.0', verbose=2)
+ print '--- Testing existing package with new version'
+ versioncheck('VersionTestPackage', _TESTDIR+'Version11.txt', '1.0', verbose=2)
+ print '--- Testing package with non-existing version file'
+ versioncheck('VersionTestPackage', _TESTDIR+'nonexistent.txt', '1.0', verbose=2)
+ print '--- Test package with 2 locations, first non-existing second ok'
+ versfiles = [_TESTDIR+'nonexistent.txt', _TESTDIR+'Version10.txt']
+ versioncheck('VersionTestPackage', versfiles, '1.0', verbose=2)
+
+if __name__ == '__main__':
+ _test()
+
+