Link to home
Start Free TrialLog in
Avatar of LeonardChallis
LeonardChallisFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Why do I get the error: post-commit hook failed (exit code 255) with no output.

I am getting the following error when I commit to a repository:

post-commit hook failed (exit code 255) with no output.

Open in new window


The post commit code is as follows:

@echo off

setlocal enableextensions

set REPOS=%1
set REV=%2
set TEMPFILE=C:\TEMP\%REV%.txt
set LOGFILE=D:\svn\logs\mysite\post_commit.log

set MANTIS_PATH="D:\home\mantis"

"C:\Program Files\SlikSvn\bin\svnlook" author %REPOS% -r %REV% >> %TEMPFILE% 2>>C:\TEMP\err.txt
"C:\Program Files\SlikSvn\bin\svnlook" date %REPOS% -r %REV% >> %TEMPFILE% 2>>C:\TEMP\err.txt
"C:\Program Files\SlikSvn\bin\svnlook" changed %REPOS% -r %REV% >> %TEMPFILE% 2>>C:\TEMP\err.txt
echo revision:[%REV%] >> %TEMPFILE% 2>>C:\TEMP\err.txt
"C:\Program Files\SlikSvn\bin\svnlook" log %REPOS% -r %REV% >> %TEMPFILE% 2>>C:\TEMP\err.txt

date /T >> %LOGFILE% 2>>C:\TEMP\err.txt
time /T >> %LOGFILE% 2>>C:\TEMP\err.txt
D:\wamp\bin\php\php5.3.0\php.exe %MANTIS_PATH%\scripts\checkin.php < %TEMPFILE% >> %LOGFILE% 2>>C:\TEMP\err.txt

Open in new window


- As you can see there is extensive error logging, but the error log never gets populated
- Both dev and live environments are Windows
- The line that seems to case the error is the final one - where PHP is called. When I take this out the commit works without issue

As you've probably made out, this is hooking up my SVN checkins with Mantis bug tracker. The interesting thing is that the PHP script is being executed, i.e. the notes are being added to bugs and the auto-closing of issues is working. It just seems to erroring for some reason. Mantis' checkin.php looks like this (some general comments removed for readability):

#!/usr/bin/php -q
<?php

global $g_bypass_headers;
$g_bypass_headers = 1;
require_once( dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'core.php' );

# Make sure this script doesn't run via the webserver
if( php_sapi_name() != 'cli' ) {
	echo "checkin.php is not allowed to run through the webserver.\n";
	exit( 1 );
}

# 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' ) );
}

# Detect references to issues + concat all lines to have the comment log.
$t_commit_regexp = config_get( 'source_control_regexp' );
$t_commit_fixed_regexp = config_get( 'source_control_fixed_regexp' );

$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 ) ) {
	echo "Comment does not reference any issues.\n";
	exit( 0 );
}

# Login as source control user
if( !auth_attempt_script_login( $t_username ) ) {
	echo "Unable to login\n";
	exit( 1 );
}

# history parameters are reserved for future use.
$t_history_old_value = '';
$t_history_new_value = '';

# add note to each bug only once
$t_issues = array_unique( $t_issues );
$t_fixed_issues = array_unique( $t_fixed_issues );

# Call the custom function to register the checkin on each issue.

foreach( $t_issues as $t_issue_id ) {
	if( !in_array( $t_issue_id, $t_fixed_issues ) ) {
		helper_call_custom_function( 'checkin', array( $t_issue_id, $t_comment, $t_history_old_value, $t_history_new_value, false ) );
	}
}

foreach( $t_fixed_issues as $t_issue_id ) {
	helper_call_custom_function( 'checkin', array( $t_issue_id, $t_comment, $t_history_old_value, $t_history_new_value, true ) );
}

exit( 0 );

Open in new window

Avatar of Brian Utterback
Brian Utterback
Flag of United States of America image

So to be clear, you get an error when you do a commit, and do not get the error if the call to php is removed, right? And with the call in place, the php
program seems to run okay, but you get the error, right? Are you sure that the php program runs to the end and does not get an error at some
point in the middle? If I recall correctly, SVN expects that if there is an error, the error message will be written to the stderr (standard error) output, not to
the stdout (standard output) file. In the php program, your errors are going to stdout, not stderr, so you may not see them.

Avatar of LeonardChallis

ASKER

@blu Thanks for that. I added this line to the top of my PHP file:

ini_set('display_errors', 'stderr');

Open in new window


Which did in fact show up an error (one of the included files was trying to use zlib compression, which wasn't enabled on that particular server), which I fixed, and now there are no PHP errors at all, but the problem still remains - I still get the hook error. Any more ideas?
ASKER CERTIFIED SOLUTION
Avatar of Brian Utterback
Brian Utterback
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I instructed PHP to output to stderr instead (with the previously mentioned ini_set call. When I put
exit 0;

Open in new window

in the script, even before any other line of code (apart from the ini_set call) it still gives me the same, original error.
What I said was to add the exit 0 to the batch script, not the php script. It would appear that php is returning something other than 0 and the batch script is passing the return code up. Since it doesn't appear that you can easily get the php script to return 0, my thought was to override the php return code.
I was about to reply that it hadn't worked, when I tried one more thing. Very odd... maybe you can help?

When I added
EXIT 0

Open in new window

to the end, I still got the error. But when I added this:

echo "RAN." >> %LOGFILE% 2>>C:\TEMP\err.txt
EXIT 0

Open in new window


It works without error! No idea why! If you could explain why that'd be fantastic, but I will award you the points nevertheless. Thanks :)
I suspect that the echo command sets the error level, while the exit does not. I think that for the exit to work as you and I expected, you need to add the /B flag to it. Just guessing though.