Last update: 20 December 09


Home Usage/Deployment Included Plug-ins Custom Plug-ins Hacks


Questions, comments and requests regarding plugins are welcome on the Developers forum!


The empty plugin can be used as template for your own plugin. You can find-and-replace all occurrences of the word 'empty'.

Plug-in structure

A plug-in consist of a directory containing at least one shell script, the plug-in name must match both. For example my_plugin/ is a valid structure to be be placed in the plugin/ directory.
The script must implement the following functions:


This function is invoked once when the plugin is loaded during the execution of a gen command. If there is any action you want to take before the analysis begins, this is the right place. For example you may check that some required tool is installed in the system.
Arguments: 1
Arg $1 contains a (relative) path to a folder which is granted to exist, to be empty and to be writeable. This folder is hidden to the user and the plug-in can use it to store any intermediate state.


This function is invoked once when the plugin is loaded during the execution of an up command. Here you should restore your state which was previously stored on file. You can also load the previous value
When this function returns the plug-in must be ready to analyze the next version from the repository. (If resume is invoked, at least a version is going to be analyzed).
Arguments: 1
Arg $1 contains a (relative) path to the folder where the plug-in stored the state previously. It is good practice to check that all files you expect are there.


This function is invoked once when the analysis ends. The plug-in should do two things: generate the results for the user in the appropriate directory and save all necessary variables and intermediate results, in order to be able to resume later from "this version + 1"
Arguments: None


This function is invoked multiple times after an init/resume, the arguments contains the current version information. The plug-in should annotate relevant information in his state folder or local variables, another crawl or a finalize will follow.
Arguments: 8
Arg $1 : The current version number.
Arg $2 : The author of this commit.
Arg $3 : The commit date in YYYY-MM-DD format.
Arg $4 : The commit time in HH:MM:SS format.
Arg $5 : The commit message (as a string).
Arg $6 : The (relative) path to a textfile containing the list of changed files as generated by a diff --summarize -c REVNO.
Arg $7 : The (relative) path to a textfile containing the diff for this commit as generated by a svn diff -c REVNO.
Arg $8 : The (relative) path to a working copy of the source code at the current version.

This picture should clarify the order in which plugin function are invokedImage: Order of invocation of plugin functions

Naming rules

There's no kind of namespace separation, all plugins are "source-d" from the main script. Therefore it's essential to avoid clashes of variables and functions names.
Each helper function and global variable defined by a plugin must be prefixed by the plug-in name.
Global variables will hold values from an init/resume until a finalize, if that's not strictly necessary, declare local function variables.

System variables

There are different global variables used by SvnCrawler at runtime, plug-ins can read those variables but not modify them for any reason.
The (commented) list of variables is listed in core/, those include the repository URL, the first and the last versions, the folder in which to generate the results and so on.

System functions

The following functions are offered by SvnCrawler:

sc_log msg

you should use this function instead of echo for messages to the user, the string argument is printed only if verbosity is enabled. Use echo for errors only.

sc_store_key file key_name key_value

This function is useful for storing multiple integer or single-line strings to a file trough a convenient interface.
For example you have two variables my_plugin_var1 and my_plugin_var2, when finalize is called, you can save them with:
local myp_state_file="$my_plugin_state_dir/my_plugin_state.txt"
rm -f $myp_state_file #Remove if exists
sc_store_key $myp_state_file "var1" $my_plugin_var1
sc_store_key $myp_state_file "var2" $my_plugin_var1

sc_load_key file key_name

If you stored something with sc_store_key, you can retrieve it during a resume in the following way:
local myp_state_file="$my_plugin_state_dir/my_plugin_state.txt"
sc_load_key $myp_state_file "var1" #Load to a tmp variable
my_plugin_var1=$SC_TMPLOAD_VALUE; #Save to yours
sc_load_key $myp_state_file "var2" #Load to a tmp variable
my_plugin_var2=$SC_TMPLOAD_VALUE; #Save to yours

Repository analysis with Java, Ruby, Python, ...

SvnCrawler can be used as crawling engine for more complex tool implemented in any language. The easiest way is probably to just accumulate data in the crawl_version invocations, for example by building a CSV file or copying all diff files. Later, when finalize is called, the real tool can start with the state directory as argument.