View Issue Details

IDProjectCategoryView StatusLast Update
0003758mantisbtfeaturepublic2008-08-12 09:17
Reporternauman Assigned Tojreese  
PrioritynormalSeverityfeatureReproducibilityalways
Status closedResolutionno change required 
Summary0003758: Perforce Integration (script included)
Description

This script monitors perforce changelists and updates bugs referenced in the changelist with a bugnote containing the changelist description. I did this work based on the work by leus in bug 0003371.

This script is run from the command line. One difficultly I encountered using the mantis api was authenticating. All the authentication functions assume a web connection, so I had to hack it in. I will open another bug that highlights this.

Tagspatch
Attached Files
mantis_perforce.php.txt (5,189 bytes)   
<?php
# --------------------------------------------------------
# mantis_perforce
# Basic Perforce Integration with Mantis Bug Tracker
# Copyright (C) 2004 T-VEC Technologies, Inc.
# This program is distributed under the terms and conditions of the GPL
# --------------------------------------------------------

# Mantis is a php based bugtracking system (http://mantisbt.sourceforge.net)
# Perforce is a source control tool (http://mantisbt.sourceforge.net)
# This script monitors the changelists submitted to Perforce.  When it
# detects a new changelist, it checks the changelist for a bug id in the
# form "Bug ###" where ### represents a numeric identifier.  If it locates
# a bug id, it adds a bugnote to the bug in mantis with the contents of
# the changelist.

# This script requires access to the Mantis API.  It uses the mantis
# configuation settings for contacting mantis server. It also requires the
# perforce p4 client.  To get the script working, configure the perforce
# host and port.  Specify the location of mantis on the filesystem.  You
# can also change the name of the log file and polling interval.

# This script has been tested on Windows.  We are currently running it as a 
# windows service.  The script is started using PHP from the command-line
#
#    php -f mantis_perforce.php
#
# For information on running this as a service, google "srvany install perl".


$p4_host = "localhost";                       # perforce server hostname
$p4_port = "1666";                            # perforce server port
$p4 = "p4";                                   # path to p4 (if needed)

$mantis_location = "k:\inetpub\mantis";       # mantis installation

$log = "p4mantis.log";                        # log file
$interval = 15;                               # polling wait interval in seconds 

$p4_counter = "p4mantis";                     # perforce counter for tracking changelists

require_once( $mantis_location.DIRECTORY_SEPARATOR.'core.php' );
db_close();

# uncomment for debugging
#$g_show_detailed_errors = ON;
#$g_show_notices     = ON;
#$g_show_warnings    = ON;
#$g_stop_on_errors   = ON;

$p4 = "$p4 -H $p4_host -p $p4_port ";

msg("starting.\n");

while (1)
{
  do_review();
  sleep($interval);
}

function do_review()
{
  global $p4;
  global $p4_counter;

  $topchange = 0;

  $cmd = "$p4 review -t $p4_counter";
  $pipe = popen($cmd, "r"); 

  if (!$pipe) 
  { 
    msg("couldn't open pipe for cmd: $cmd\n");
    return; 
  }

  global $g_hostname;
  global $g_db_username;
  global $g_db_password;
  global $g_port;
  global $g_database_name;

  db_connect( $g_hostname, $g_db_username, $g_db_password, $g_port );
  db_select_db( $g_database_name );

  if (db_is_connected())
  {
    while($s = fgets($pipe, 1024))
    {
      # Format: "Change x user <email> (Full Name)"
      if (preg_match("/^Change (\d*) (\S*) <(\S*)> (\(.*\))/",$s,$matches))
      {
        $change = $matches[1];    
        $user = $matches[2];    
  
        process_change($change, $user);
        $topchange = $change;
    }
    }
    pclose($pipe);

    if ($topchange) 
    { 
      run_cmd("$p4 counter $p4_counter $topchange");
    }
  db_close();
  }
}

function process_change($change, $user)
{
  global $p4;

  msg("processing change: $change for user $user\n");

  $cmd = "$p4 describe -s $change";
  $pipe = popen($cmd, "r"); 

  if (!$pipe) 
  {
    msg("error opening pipe for cmd: $cmd\n");
    return;
  }

  $bug = "";
  $desc = "";
  while($s = fgets($pipe, 1024))
  {
    if (preg_match("/Bug (\d+)/i",$s,$matches))
    { 
      $bug = $matches[1]; 
    }
    $desc .= $s;
  }
  pclose($pipe);

  if (strlen($bug))
  {
    update_mantis($bug, $change, $desc, $user);
  }
}

function update_mantis($bug, $change, $desc, $user) 
{
  msg("updating mantis bug $bug\n");

  if (bug_exists( $bug ))
  {
    if (!get_user_id($user))
    {
      msg("aborting update b/c invalid user");
      return;
    }

    bugnote_add ( $bug, $desc, false);
  }
  else
  {
    msg("invalid bug id ($bug) specified in changelist ($change)\n");
  }
}

function get_user_id($user)
{
  global $g_cache_current_user_id;

  $g_cache_current_user_id = null;

  $user_id = user_get_id_by_name($user);

  if ( ! $user_id ) 
  {
    msg("could not locate user: $user trying to find user 'perforce'\n");

    $user_id = user_get_id_by_name('perforce');
  }

  if ( ! $user_id ) 
  {
    msg("could not locate user: $user or user 'perforce'.  Add perforce user to mantis.\n");
    return 0;
  }

  $g_cache_current_user_id = (int)$user_id;

  return $g_cache_current_user_id;
}

function run_cmd($cmd)
{
  msg("running: $cmd\n");

  $pipe = popen("$cmd", "r"); 

  if (!$pipe) 
  {
    msg("cmd failed: $cmd\n");
    return;
  }
  $output = "";
  while($s = fgets($pipe, 1024))
  {
    $output .= $s;
  }
  pclose($pipe);

  return ($output);
}


function msg($msg)
{
  global $log;

  print($msg);

  if (! $log) { return; }

  error_log($msg, 3, $log);
}

?>
mantis_perforce.php.txt (5,189 bytes)   
mantis_perforce.inc.php (679 bytes)   
<?php
$p4_host = "localhost";                       # perforce server hostname
$p4_port = "1666";                            # perforce server port
$p4 = "p4";                                   # path to p4 (if needed)
$interval = 5;
$bug_flag = "Bug.";

#$mantis_location = "k:\inetpub\mantis";       # mantis installation
function mantis_location() 
{
	return $mantis_location = "/Applications/MAMP/htdocs/mantis";       # mantis installation
}
$log = "p4mantis.log";                        # log file
$interval = 15;                               # polling wait interval in seconds

$p4_counter = "p4mantis";                     # perforce counter for tracking changelists
?>
mantis_perforce.inc.php (679 bytes)   
mantis_perforce.php (4,444 bytes)   
<?php
# --------------------------------------------------------
# mantis_perforce
# Basic Perforce Integration with Mantis Bug Tracker
# Copyright (C) 2004 T-VEC Technologies, Inc.
# This program is distributed under the terms and conditions of the GPL
# --------------------------------------------------------

# Mantis is a php based bugtracking system (http://mantisbt.sourceforge.net)
# Perforce is a source control tool (http://mantisbt.sourceforge.net)
# This script monitors the changelists submitted to Perforce.  When it
# detects a new changelist, it checks the changelist for a bug id in the
# form "Bug ###" where ### represents a numeric identifier.  If it locates
# a bug id, it adds a bugnote to the bug in mantis with the contents of
# the changelist.

# This script requires access to the Mantis API.  It uses the mantis
# configuation settings for contacting mantis server. It also requires the
# perforce p4 client.  To get the script working, configure the perforce
# host and port.  Specify the location of mantis on the filesystem.  You
# can also change the name of the log file and polling interval.

# This script has been tested on Windows.  We are currently running it as a 
# windows service.  The script is started using PHP from the command-line
#
#    php -f mantis_perforce.php
#
# For information on running this as a service, google "srvany install perl".

include_once "mantis_perforce.inc.php";

$mantis_location = mantis_location();

require_once( $mantis_location.DIRECTORY_SEPARATOR.core.".php" );

# uncomment for debugging
$g_show_detailed_errors = ON;
$g_show_notices     = ON;
$g_show_warnings    = ON;
$g_stop_on_errors   = ON;

$p4 = "$p4 -H $p4_host -p $p4_port ";

msg("starting.\n");


while (1)
{
	do_review();
	echo "sleeping $interval seconds....\n";
	sleep($interval);
}

function do_review()
{
  global $p4;
  global $p4_counter;

  $topchange = 0;

  $cmd = "$p4 review -t $p4_counter";
  $pipe = popen($cmd, "r"); 

  if (!$pipe) 
  { 
    msg("couldn't open pipe for cmd: $cmd\n");
    return; 
  }

  db_connect( false, $g_hostname, $g_db_username, $g_db_password );
#  db_select_db( $g_database_name );

  if (db_is_connected())
  {
    while($s = fgets($pipe, 1024))
    {
      # Format: "Change x user <email> (Full Name)"
      if (preg_match("/^Change (\d*) (\S*) <(\S*)> (\(.*\))/",$s,$matches))
      {
        $change = $matches[1];    
        $user = $matches[2];    
  
        process_change($change, $user);
        $topchange = $change;
    }
    }
    pclose($pipe);

    if ($topchange) 
    { 
      run_cmd("$p4 counter $p4_counter $topchange");
    }
  db_close();
  }
}

function process_change($change, $user)
{
  global $p4;

  msg("processing change: $change for user $user\n");

  $cmd = "$p4 describe -s $change";
  $pipe = popen($cmd, "r"); 

  if (!$pipe) 
  {
    msg("error opening pipe for cmd: $cmd\n");
    return;
  }

  $bug = "";
  $desc = "";
  while($s = fgets($pipe, 1024))
  {
    if (preg_match("/$bug_flag (\d+)/i",$s,$matches))
    { 
      $bug = $matches[1]; 
    }
    $desc .= $s;
  }
  pclose($pipe);

  if (strlen($bug))
  {
    update_mantis($bug, $change, $desc, $user);
  }
}

function update_mantis($bug, $change, $desc, $user) 
{
  msg("updating mantis bug $bug\n");

  if (bug_exists( $bug ))
  {
    if (!get_user_id($user))
    {
      msg("aborting update b/c invalid user");
      return;
    }

    bugnote_add ( $bug, $desc, false);
  }
  else
  {
    msg("invalid bug id ($bug) specified in changelist ($change)\n");
  }
}

function get_user_id($user)
{
  global $g_cache_current_user_id;

  $g_cache_current_user_id = null;

  $user_id = user_get_id_by_name($user);

  if ( ! $user_id ) 
  {
    msg("could not locate user: $user trying to find user 'perforce'\n");

    $user_id = user_get_id_by_name('perforce');
  }

  if ( ! $user_id ) 
  {
    msg("could not locate user: $user or user 'perforce'.  Add perforce user to mantis.\n");
    return 0;
  }

  $g_cache_current_user_id = (int)$user_id;

  return $g_cache_current_user_id;
}

function run_cmd($cmd)
{
  msg("running: $cmd\n");

  $pipe = popen("$cmd", "r"); 

  if (!$pipe) 
  {
    msg("cmd failed: $cmd\n");
    return;
  }
  $output = "";
  while($s = fgets($pipe, 1024))
  {
    $output .= $s;
  }
  pclose($pipe);

  return ($output);
}


function msg($msg)
{
  global $log;

  print($msg);

  if (! $log) { return; }

  error_log($msg, 3, $log);
}

?>
mantis_perforce.php (4,444 bytes)   

Relationships

related to 0003371 closedvboctor CVS Integration (patch included) 
has duplicate 0003757 closed Perforce Integration (script included) 

Activities

nauman

nauman

2004-04-26 13:19

reporter   ~0005439

This should be added at beginning of script so that it does not time out

this is a daemon so no time limit

this only works if safe mode is off in php.ini

set_time_limit(0);

epu

epu

2004-05-12 19:31

reporter   ~0005491

Recommend submitting this to the perforce public depot, if it isn't already.

phecht

phecht

2008-06-08 23:40

reporter   ~0018038

The attached files are to show how I have 1) separated the configuration from the code and 2) Removed some code that did not work in 1.1.x. Since I am on a mac and using MAMP, I think I had to use 1.1.x and can't use 1.2.x until I get motivated to install a real mysql. Hope this helps some one using Perforce!

grangeway

grangeway

2008-07-13 12:52

reporter   ~0018438

Hello,

Assigning this to John who's done some Source integration support for mantis for him to look at whether this code could be integrated

Paul

jreese

jreese

2008-07-30 09:01

reporter   ~0018923

This isn't going to make it into core Mantis, so I'm marking this resolved. If you'd like, I've created a plugin framework for fully integrating source control tools with Mantis. If you'd like to write an extension plugin to add support for Perforce, I would always be willing to include it in the project.

You can find the code repository hosted on GitHub: http://github.com/jreese/mantis-source-integration