Adding Jack Jansen's version checking utility.
This commit is contained in:
parent
7f96291ee2
commit
5291037c70
|
@ -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>
|
||||
|
|
@ -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)
|
|
@ -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()
|
||||
|
||||
|
|
@ -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()
|
||||
|
||||
|
Loading…
Reference in New Issue