Everyone who experienced this use-case, wants to synchronize bag tracking system with version control system and you can find some products that aims to do it. However, if you use Subversion and Mantis you can integrate it with 100 lines of script without learning manual and installation instructions of new product, that always met only part of your requirements . There is excellent explanation how to do it, at "alt-tag.com" ( see link at the end). Although the blog mentioned, is short and clear, it has two leaks. First, the scripts code wrote for Linux ( I love Linux, but there are still some Windows servers). Second, it assumes that developer, who commits the changes, always wrote comments in same pattern. The opinion, that developers are robots, is partly true, but they do mistakes, sometimes.
In this article, I'll give you the example of scripts that check commit label before the revision committed, blocks it if it has a error, change bug status after commitment and adds commit label to bug notes at Mantis. There are 6 steps: Mantis definitions, SVN comment template definitions, post-commit svn hook, pre-commit svn hook, post-commit mantis script and pre-commit mantis script.
1. Mantis definitions( config_inc.php ):
<?php
$g_hostname = 'localhost';
$g_db_type = 'mysql';
$g_database_name = 'bugtracker';
$g_db_username = 'root';
$g_db_password = 'rcadminsin';
#User that looks in svn for comments with bug_id
$g_source_control_account = 'svn';
#comments that identifies bug in subversion
$g_source_control_regexp = '/\b(?:bug|issue)\s*[#]{0,1}(\d+)\b/i';
#definition of svn commitements that change bug status in Mantis
$g_source_control_set_status_to = RESOLVED;
$g_source_control_set_resolution_to = FIXED;
$g_source_control_fixed_regexp = '/\bfix(?:ed|es)\s+(?:bug|issue)?\s*[#]{0,1}(\d+)\b/i';
?>
2. SVN comment template: Set property "tsvn:logtemplate" recursively for all files in your project. In this case the property value can be "fixed bug #", so the developer need only add Mantis bug_id.
3. Post-commit SVN hook: Every SVN repository has "hooks" folder( e.g. C:\Subversion\repository\hooks ). An executable or batch file placed in this directory will be called if its name correlates with SVN event. At this stage it is "post-commit.bat". It calls for PHP script in purpose to update bug status at Mantis and to add revision comment as bug note.
@ECHO OFF
SET REPOS=%1
SET REV=%2
SET PHP=C:\AppServ\PHP5\php.exe
SET CHECKIN=C:\AppServ\www\mantisbt-1.2.1\scripts\checkin.php
SET SVNLOOK=C:\Subversion\bin\svnlook.exe
SET LOGFILE=log_post_%REV%.txt
SET AUTHORFILE=author_post_%REV%.txt
SET OUTPUTFILE=output_post_%REV%.txt
%SVNLOOK% log -r %REV% %REPOS% > %LOGFILE%
%SVNLOOK% author -r %REV% %REPOS% > %AUTHORFILE%
ECHO SVN %REPOS% Revision %REV% > %OUTPUTFILE%
TYPE %AUTHORFILE% >> %OUTPUTFILE%
TYPE %LOGFILE% >> %OUTPUTFILE%
TYPE %OUTPUTFILE% | %PHP% %CHECKIN%
CALL DEL %LOGFILE%
CALL DEL %AUTHORFILE%
CALL DEL %OUTPUTFILE%
4. Pre-commit SVN hook: This hook calls other PHP script ( "pre-commit.bat" ):
@ECHO OFF
SET REPOS=%1
SET TX=%2
SET PHP=C:\AppServ\PHP5\php.exe
SET VALIDATOR=C:\AppServ\www\mantisbt-1.2.1\scripts\validate_bug_fix.php
SET SVNLOOK=C:\Subversion\bin\svnlook.exe
SET LOGFILE=log_pre_%TX%.txt
SET OUTPUTFILE=output_pre_%TX%.txt
%SVNLOOK% log -t %TX% %REPOS% > %LOGFILE%
ECHO SVN %REPOS% Transaction %TX% > %OUTPUTFILE%
TYPE %LOGFILE% >> %OUTPUTFILE%
TYPE %OUTPUTFILE% | %PHP% %VALIDATOR% 1>&2
IF %ERRORLEVEL% gtr 0 ( GOTO ERR ) ELSE ( GOTO RM_LOG )
:RM_LOG
CALL DEL %LOGFILE%
CALL DEL %OUTPUTFILE%
exit 0
:ERR
ECHO commit denied >&2
exit 1
The script above prevents from developers to commit revision, that aims to fix already fixed issue. If pre-commit hook has exit code other then zero, SVN will not commit the changes and will display content of STDERR. ">&2" purpose is to copy STDOUT content to STDERR, so developer can see what error prevents his commitment. Most of work are done by PHP script called (see 5 and 6).
5. Post-commit PHP script: This script is already included in Mantis distrubution. It checks if text in STDIN stream is matches the template. If true, its find bug_id changes its status in mantis and add comment as note of the issue. If you need additional functionality you can change it or override default "custom_function_checkin" fuction.
6. Pre-commit PHP script: This script is not part of Mantis, but you can easy create it, because most of it, similar to checkin.php script, included in Mantis( see 5 ). You can use Mantise's "bug_api.php" methods to add other validations.
<?php
# Detect references to issues + concat all lines to have the comment log.
# Called before SVN commits changes to ensure that bug committed is not already resolved
global $g_bypass_headers;
$g_bypass_headers = 1;
require_once( dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'core.php' );
$t_commit_regexp = config_get( 'source_control_regexp' );
$t_commit_fixed_regexp = config_get( 'source_control_fixed_regexp' );
# Check that the username is set and exists
$t_username = config_get( 'source_control_account' );
if( is_blank( $t_username ) || ( user_get_id_by_name( $t_username ) === false ) ) {
echo "Invalid source control account ('$t_username').\n";
exit( 1 );
}
if( !defined( "STDIN" ) ) {
define( "STDIN", fopen( 'php://stdin', 'r' ) );
}
$t_comment = '';
$t_issues = array();
$t_fixed_issues = array();
while(( $t_line = fgets( STDIN, 1024 ) ) ) {
$t_comment .= $t_line;
if( preg_match_all( $t_commit_regexp, $t_line, $t_matches ) ) {
$t_count = count( $t_matches[0] );
for( $i = 0;$i < $t_count;++$i ) {
$t_issues[] = $t_matches[1][$i];
}
}
if( preg_match_all( $t_commit_fixed_regexp, $t_line, $t_matches ) ) {
$t_count = count( $t_matches[0] );
for( $i = 0;$i < $t_count;++$i ) {
$t_fixed_issues[] = $t_matches[1][$i];
}
}
}
# If no issues found, then no work to do.
if(( count( $t_issues ) == 0 ) && ( count( $t_fixed_issues ) == 0 ) ) {
exit( 0 );
}
# If one of the issues are already resolved it is a error to commit it.
foreach( $t_fixed_issues as $t_issue_id ) {
if( bug_is_resolved( $t_issue_id ) ) {
echo "The bug with id ".$t_issue_id." is already resolved.\n";
exit( 1 );
}
}
#echo "Comment ".$t_comment." OK.\n";
exit( 0 );
?>
That's all. You can add additional functionality to php scripts described, if you need. Link to the article, that used as base: