|
Running Arbitrary Scripts Under CVSby Jennifer Vesperman, author of Essential CVS06/05/2003 |
CVS is a useful version control tool. Version control is not the only aspect of building a project or maintaining a service, though. This article is about the hooks CVS includes to allow you to expand it and integrate it with other tools.
Five files in the CVSROOT directory of the repository enable you to run arbitrary scripts when a file is committed or tagged. Common uses for these files include interfacing CVS to a bug management system, a change tracker, or another tool; enforcing compliance with a project policy; and triggering processes such as automated export programs.
CVS uses one file during tagging and four files during committing:
|
Related Reading
|
commitinfobefore the files in a directory are committed.loginfoafter the files in a directory are committed.verifymsgafter the log message is entered, but before files are committed.rcsinfofor the template for the log message in a commit.taginfobefore eachtagorrtagoperation.
Syntax
Each line of these files should contain a rule with the following syntax:
name_pattern action. name_pattern should match a
directory in the repository, and CVS will apply this rule to all files in that
directory. The pattern used is a regular expression, described in info
cvs. CVS tests the pattern against the directory's relative path,
starting at the repository root directory.
There are two special patterns, ALL and DEFAULT.
An ALL rule is used on files in any directory. A
DEFAULT rule is used if no other patterns (excluding
ALL) match.
action is a command-line template for the path to a script (or
commit message template), plus any parameters required for that script or
template. The script or template must be able to read from standard input
(stdin). CVS will append its own parameters to actions.
Lines in scripting files that start with the hash symbol (#)
are comments and are ignored.
commitinfo
commitinfo scripts are often used to verify whether checked-in
files conform to company standards or to enforce exclusive development. CVS
passes the relative directory path and a list of all files in that directory
involved in the commit as parameters. If the action of the rule returns a
non-zero value, the commit does not proceed.
CVS makes a set of normal-format files from the data it receives from the CVS client, storing them in a temporary directory. If the action reads (or tries to modify) the file, it reads the file in the temporary directory. Any modifications are discarded after the action is processed.
loginfo
The loginfo file is most often used to control where (aside
from the RCS files) the log information from a commit is sent. It can also be
used to trigger actions, such as notifying all developers of changes,
maintaining a file that logs a record of changes, or exporting the changed
files to a file server.
CVS passes the log message from the commit as well as the repository path
being committed to, followed by an expanded format string, all on standard
input. The format string is part of the action and controls the information
that CVS passes to the script or command. The string consists of a
% followed by a space, a single variable, or a set of variables
enclosed in braces {}. The variables are:
s- Expands to the name of the current file being processed.
V- Expands to the file's revision number prior to the commit.
v- Expands to the file's revision number after the commit.
When CVS process the format string, the output is in the form
variable_expansion [variable_expansion...]. CVS will generate a
variable expansion for each file that was committed, consisting of a
comma-separated set of strings. %{sV} would be expanded to a
string like main.c,1.3. Dollar signs ($), backticks
(`), backslashes (\), and quotation marks (")
in the repository path or filename will be escaped with backslashes.
verifymsg
The scripts in the verifymsg file often either check or modify
the log message you enter when you commit files. CVS passes the path to a
temporary file containing the commit log message and copies the log message on
standard input (stdin). If the script returns a non-zero value,
the commit does not proceed.
The script can modify the log message. The
RereadLogAfterVerify option in the config file in the
repository's CVSROOT directory determines whether the original or
the modified log message is used.
The ALL pattern is not supported in the verifymsg
file.
rcsinfo
The rcsinfo file doesn't contain scripts to run, it contains
the path to a template file for CVS to display when it opens the editor for a
log message. Unless you remove them in editing, the contents of the template
file are stored as part of the log message in addition to whatever you add.
Lines that start with CVS: will be stripped by CVS.
If CVS is running in client/server mode, it stores a copy of the template file in the Template file in the CVS subdirectory of the sandbox when the sandbox is checked out. This file is not updated with other sandbox files, so if the rcsinfo file or the templates it refers to are changed, your users should release and recreate their sandboxes.
taginfo
taginfo scripts are often used to check that tagnames meet
standards, to interact with other programs, or to log tag operations. CVS
appends a parameter string in the following format: tagname operation
repository_path file_revision_pair [file_revision_pair...].
The file_revision_pair is a space-separated pair of filenames
and revision numbers, and there is a pair for each file to be tagged.
The operations CVS provides are add, mov, and
del. CVS provides mov when the tag moving option
-F is used, del when the tag deletion option
-d is used, and add when a new tag is added. If the
script exits with a non-zero exit status, the tag (or
rtag) operation will not proceed.
Processing
CVS processes the scripting files separately for each directory in the
current commit or tag command, calling the script in
the scripting file once for each directory it matches. It runs the first rule
that matches, or the DEFAULT rule (if any) if there are no
matching rules. It also runs any ALL rules.
If any script contains a CVS command, the command that calls the script will not finish until the script does. This can trigger a deadlock if a directory has been locked by the original CVS command, which can't release the lock until the script is finished, but the script can't run until those same locks are released. The deadlock situation can be prevented by having your script call any CVS commands in the background or simply by calling the script in the background.
If the repository is not on the same computer as the client, the script or command in the action is run on the repository computer.
Security
Scripts in these files are run by the user calling CVS, not necessarily the user who added the script. Ensure that only trustworthy users have write access to the CVSROOT directory and the scripting files.
Note: all users must have read and execute access to the CVSROOT directory and write access to the history and val-tags files.
Integration Example: Bugzilla
Bugzilla can accept bug-tracking data via an email form. This integration example relies on it being configured to do so.
Use the rcsinfo file to make a template with the Bugzilla
@bugid, @resolution, and @message fields,
and the verifymsg file to run a script that ensures that the bug
ID, at least, has been filled in. In this example, the verifymsg
file then emails the log message to Bugzilla. Bugzilla needs the bug ID in the
email subject (which must have the format [Bug XXXX]). The rest of
the log message can be sent as the email body.
The script below uses the read command to get the bug ID from
the first line of the log message then mails the bug ID and the rest of the
input to the user bugzilla on the same computer. The script
returns 1 if the format was wrong, which cancels the commit.
#! /bin/bash
read prompt bugid
if [ $prompt != '@bugid' ]; then
return 1
else
mail -s "[Bug $bugid]" bugzilla
fi
return 0
This is a template file for rcsinfo to call. Your users should
enter the bug ID, resolution status, and a log message to the right of each of
these prompts.
CVS: Put the bug ID here
@bugid
CVS: Put the resolution string here. Valid resolutions are...
@resolution
CVS: Record any message you want to add here.
@message
The next example shows the lines in the verifymsg and
rcsinfo files that would call these scripts for a project called
example, if the scripts were called bugzilla-mail and
bugzilla-template.
# In verifymsg, call the script bugzilla-mail
^example\(/\|$\) /var/lib/cvsroot/CVSROOT/scripts/bugzilla-mail
# In rcsinfo, call bugzilla-template
^example\(/\|$\) /var/lib/cvsroot/CVSROOT/scripts/bugzilla-template
Final Words
CVS follows the general Unix ethos of doing one thing and doing it well. These files can allow you expand CVS beyond source and version control, or to integrate CVS with other programs.
Further Reading
man cvsman 5 cvsinfo cvs- CVS Pocket Reference, by Gregor N. Purdy (O'Reilly and Associates)
- Essential CVS, by Jennifer Vesperman (O'Reilly and Associates)
- From the Big Scary Demons column: "BSD Tricks: CVS"
- Sourceforge has several articles on CVS. See sections 6 and 7 on the Sourceforge Site Docs page.
Jennifer Vesperman is the author of Essential CVS. She writes for the O'Reilly Network, the Linux Documentation Project, and occasionally Linux.Com.
Return to the Linux DevCenter
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 8 of 8.
-
Using python script with verifymsg
2003-08-04 03:21:22 anonymous2 [Reply | View]
-
Using python script with verifymsg
2003-08-04 15:00:58 anonymous2 [Reply | View]
CVS doesn't expect you to use interaction in these scripts. There are several reasons the developers didn't include interaction, one of which is that some remote access methods just don't allow it. This is explained on page 163 of 'Essential CVS', and is also somewhere in 'info cvs' but I can't find it there right now.
You may find that verifymsg is more useful to you when checking whether the user has written a proper log file entry. If you combine that with the 'ReReadLogAfterVerify' option in the CVSROOT/config file, your script can change the log message that CVS stores.
If there is simply not enough information in the log file, you can refuse to allow the commit to proceed. -
Using python script with verifymsg
2003-08-05 01:57:13 anonymous2 [Reply | View]
So I guess it's not possible to open editor and re-edit temp log message if original message has been noticed to be incomplete ?? Is this due to client/server model ?? -
Using python script with verifymsg
2003-08-05 15:52:02 anonymous2 [Reply | View]
It is possible - you are, after all, writing a separate program that could do just about anything.
But:
* Some client-server models don't allow such interaction.
* You are adding arbitrary data to the socket CVS is using for its data, and could accidentally trigger some other CVS command.
* You could generate a deadlock, as one person's commit can't proceed because it's waiting on another person doing their editing, but the other person is waiting on the first to do editing. This might or might not be a problem in a loginfo script, which runs after the commit is processed, but would be a problem in a verifymsg script.
In addition, CVS doesn't re-read the log message after a loginfo script, so any changes you make are ignored. It can re-read the log message after a verifymsg script, however. (See my previous response.)
Jenn Vesperman.
-
Speaking of loginfo....
2003-06-10 06:51:43 tcopeland [Reply | View]
...a good commit emailer is the Python script "syncmail" - http://sourceforge.net/projects/cvs-syncmail/. It can be used to send an email containing a diff on each commit.
We use it here - https://ultraforge.ultralog.net/ - and find it's quite helpful to keep track of what's going on without having to do cvs diffs and cvs logs and such...
Yours,
Tom -
Speaking of loginfo....
2003-06-13 22:55:01 Jennifer Vesperman [Reply | View]
Check the article CVS Third Party Tools or the appendices of Essential CVS for extra CVS add-ons, scripts and things. I haven't found them all, by any means, but I have listed quite a few.
Jenn Vesperman.





It's supposed to ask whether user wants to write log again (if log is found incomplete).
How can I add such interactivity ?
All I get is:
Traceback (most recent call last):
File "/home_local/samiviit/CVS/script/environ_test.py", line 18, in ?
rerun = input('Haluatko tayttaa lokin uudelleen y/n? ')
EOFError: EOF when reading a line