Implementation documentation for patch_amber.py This document describes how patch_amber.py is implemented and how it performs its various features. Understanding this may help reveal some limitations I hadn't thought of (and, obviously, how to break it horribly -- don't do that). Requirements: Bug fix names have to have a common prefix (BUGFIX_PREFIX set in the global variable section at the top of the file) and end in a single integer with any one of the allowed suffixes according to its allowed patch type (see below). Bug fix format must adhere to outlined specifications (these should always be created with git) No bug fix should contain patches to both Amber and AmberTools-controlled files! This is checked for, and users will be told to complain loudly on the mailing list if any developers make a patch like this! Global variables patch_locs, unapplied_patch_loc, applied_patch_loc, and patch_desc_list MUST be set consistently -- see comments in script for details. This script has been tested with Python 2.4 and Python 2.7, so it will work with 2.5 and 2.6. (Python 2.4 cannot be redirected at a local file:// repository for testing, but it downloads all files from the amber website as expected) Features: Supported Patch Types | ------------------------ 1) Typical ASCII patches that we've been using forever (see bugfix specification document for limitations on this format) 2) ASCII patch compressed with bzip2 (must have BUGFIX_PREFIX.#.bz2 format). 3) ASCII patch compressed with gzip (must have BUGFIX_PREFIX.#.gz format). It could be easily extended to support tarball patches, but I want to avoid this if possible. They're (in general) non-reversible, and any patch that should be included as a tarball is most likely a feature enhancement deserving of its own release. Managing of patches and operational/implementation details | ------------------------------------------------------------ All patches managed by patch_amber.py are stored in a master $AMBERHOME/.patches directory. The directory was hidden to prevent people from messing with this directory, as it is essential for the script's proper operation (yet it's a simple enough system for the advanced user to take advantage of it) At the beginning of the script, global variables set up the website(s) that the bug fixes are downloaded from. The websites must be such that you can just add "bugfix.#" to the website string and get a valid file (so long as that bugfix exists), but it will support an arbitrary number of patch repositories (1 to N) which it always checks in order (and applies, downloads, etc. patches in order). Each bug fix repository must have an unapplied patch directory and an applied patch directory assigned to it (that dumps in .patches -- .patches is hardcoded into the script in several locations, so don't change that), as well as a description so we know how to describe it to the users in our messages. Files are automatically downloaded to the repository's unapplied patches directory. If any patches from the unapplied patches directory are applied, they are then moved to that repository's applied patches directory. This is the ONLY way that patch_amber.py knows which patches have been applied, so DO NOT MESS WITH THIS DIRECTORY or suffer the consequences. By default, I do not trust unapplied bug fixes stored locally to be "good". They may have been messed with or they may have actually been changed on the server (I'm pretty sure that this happened with AmberTools 1.5 patch 1), so to be on the safe side (and it's easier coding), all patches that are not in the applied folder that are online are simply re-downloaded into the unapplied patch folder. In any event, --download-patches is considered an advanced option and will probably only be used by those that will know how to apply them one-by- one via --apply-patch, which will move them into the applied patch folder without ever having to contact the web. There is a check for internet connection for operations that require internet only. If this fails, we stop with an appropriate error message. Currently, off-line bug fixing will require the old way of applying the bugfix.all patch by hand. However, since it's difficult for users to get any files without internet (and even Amber/AmberTools), this is not a bad restriction. The Patch level is determined by collecting all of the integer suffixes in each repository's applied patch folder and finding the maximum of that list. Thus, it ignores any intermediate patch that may be missing. The --show-applied-patches flag can be used to get an explicit list of all applied patches. I wanted to have --patch-level just use the max number (thereby omitting missing intermediate patches) for simpler coding and the fact that missing patches is indicative of either 1) only advanced use can do this, anyway, and --patch-level is listed under normal use. Use --show-applied-patches to get a full list, and 2) for purposely omitted patches (see below). This script has been set up generally enough to allow for separate Amber/AmberTools repositories like we have now, or a single Amber/AmberTools patch repository in which any patch applying files strictly to Amber files (src/sander or src/pmemd) will be ignored and not applied if the user doesn't have a src/pmemd/src directory (which is how I figure out if they have Amber or not). This *may* confuse users if they think they haven't applied a patch that they don't know simply doesn't apply to them, so maybe separate repos are better (but I don't want to move a patch that's not applied to the applied patch folder, lest people try to "reverse" them). The --check-updates mode has been set so that the exit code is the number of missing updates that are available, so it can be used easily in scripts. This is another reason we may want separate Amber/AmberTools bugfix repositories, since if an Amber bug fix is the latest in a joint repository, configure will continue to complain until AmberTools requires a new fix. However, for an AmberTools release, the Amber bug fix repo should be removed from patch_amber.py