7.4. Interfacing with External Programs
CVS is rarely used alone. There are a number of project-management tools available, each used to perform a different set of tasks. The scripting files can be used to connect CVS to other project-management tools, such as bug trackers and build scripts.
7.4.1. Interfacing with Bug Trackers
Interfacing with a bug tracker is easiest if the tracker accepts input from standard input or via an email form. Use the rcsinfo file to have the cvs commit editor screen include the template your bug tracker requires, and use the verifymsg file to ensure that all fields are filled in appropriately. Then have a script in verifymsg or loginfo mail the log data to your bug tracker.
Examples 7-11 and 7-12 show how to integrate with the Bugzilla bug-tracking tool, available at http://bugzilla.mozilla.org. These examples assume that the Bugzilla email gateway has been enabled. The @resolution field in the message template allows you to change a project's status and is supported directly by Bugzilla.
Use the verifymsg script in Example 7-11 to separate out the bug ID so it can be used in the mail subject (which must have the format [Bug XXXX]). The rest of the log message can be sent as the mail body. The script uses the read command to get the bug ID from the first line of the log message, checks that the first line it reads uses the format it expects, and then mails the bug ID and the rest of the stdin input to the user bugzilla on the same computer. The script returns 1 if the format was wrong and 0 if it succeeds in mailing everything to Bugzilla.
Example 7-11. Interfacing with Bugzilla, verifymsg
Example 7-12 shows an rcsinfo template file that contains the @bugid string that Example 7-11 expects and the @resolution and @message strings that Bugzilla supports. Enter the bug ID, resolution status, and a log message to the right of each of these prompts.
Example 7-12. Interfacing with Bugzilla, message template
A more complete verifymsg script than the one shown in Example 7-11 would include a facility to strip comments out of the template file, and the template file would have comments explaining what to write beside each prompt. (CVS strips lines that start with the string CVS:, so you can use that mechanism instead of your own comment-stripping code.)
Example 7-13 shows the lines in the verifymsg and rcsinfo files that would call these scripts for the wizzard project, if the scripts were called bugzilla-mail (Example 7-11) and bugzilla-template (Example 7-12).
Example 7-13. Interfacing with Bugzilla, scripting files
7.4.2. Interfacing with Build Scripts
A build for publication should be slightly different from a build for development. During development, your developers want to start with a recent sandbox, build from that sandbox, make their changes, and then test only those changes. However, a build for testing or publication should be taken from a known set of revisions, frequently the most up-to-date revisions.
Fortunately, both building for incremental testing and building for a major release can be done using the same build script. If the script is included in the project files and designed to be able to be run from a sandbox, the developers can run their test builds from their sandboxes and the project lead can run testing or publication builds from an exported copy of the project files. Note that it's good practice to tag the project's files just before a testing or publication build, so that the exact revisions can be easily retrieved later.
If your developers are sharing a central set of files and have only a partial set of the project's files in their sandboxes, you can have the build script set up symbolic links to the shared files from their sandboxes or call files from a central location.
If your developers are changing copies of a set of files but will eventually want to distribute your project's files across several unrelated directories, it is best to develop the project to build under a single root directory, then distribute the files across multiple directories as part of the installation script.
Example 7-14 is a script for the wizzard project that tags the head revisions of all files, then builds and installs the project (assuming that the Makefile is properly configured). To create a build of this script for development, produce a smaller script that contains only the make and make install commands and run that smaller script from a developer's sandbox. To create a build of the project for testing or publication, run the full script given in Example 7-14 from any directory.
Example 7-14. Building for testing or publication
7.4.3. Enforcing Standards
The different scripting files can be used in the following ways to enforce project standards:
7.4.4. Making Patchfiles
A patchfile is a special file that can be used by the patch utility to update a set of files from one revision to another. You don't need to use a patchfile to change files stored under CVSbut you may have exported and distributed your project and want to update the exported sets with only the changes.
To make a patch, use cvs diff or cvs rdiff, and redirect the output to a file. In most shells the command would be cvs diff -r old -r new filenames > patchfile. You can replace filenames with any project, file, module, or directory names that are compatible with cvs diff or rdiff. The parameters old and new are the old and new revision numbers or tags, and patchfile is the name of the file you want to create. The > symbol tells the shell to redirect the output into the file.
If your installation script rearranges the exported files so that they're in different places from where they are in a sandbox, use the GNU diff utility rather than the CVS diff utility. Export and install the old version in one directory, then export and install the new version in another. Run diff -Nuar old new > patchfile, where old and new are the names of the two top-level directories of the two installations. The result of the diff is your patchfile; test it by typing patch -p1 old patchfile, This command should update the older revision so it matches the newer revision.
I recommend the diffutils manual for information on using GNU diff, including ideas on creating top-quality patchfiles.