here's something i've been using.  i haven't felt it's good enuf to be
sourceforge'd, but it's worked for me.

it works w/ nant 0.8.2  (i.e. before the namespace revamp), so it might
need some refactoring.

it's invoked like so:

sync:

 <p4 verbose="${Trace.P4}" failonerror="false" action="sync"
files="${Dir.Leap.Commands}..." />

add files to a changelist for edit/add:

 <p4 verbose="${Trace.P4}" action="edit" changelist="${P4.ChangeList}"
files="${p}gen*.cs" />
 <p4 verbose="${Trace.P4}" action="add" changelist="${P4.ChangeList}"
files="${Dir.Work.Sql.Gen}*.sql" />
 <p4 verbose="${Trace.P4}" action="edit" changelist="${P4.ChangeList}"
files="${Dir.Leap.Sql.Gen}*.sql" />

submit them:

 <p4 verbose="${Trace.P4}" action="submit" changelist="${P4.ChangeList}"
/>   

or not:
 
 <p4 verbose="${Trace.P4}" action="revert" options="-a"
changelist="${P4.ChangeList}" />   

creating a label involves creating a label file and submitting it like
so:
 
 <p4 verbose="${Trace.P4}" action="label" labelfile="${File.Label}" />


there's a kludge in the task that checks for a global property ${Is.Lan}
to be true.  the caller might set Is.Lan false in order to make the task
bail w/o working.  this is needed when you're using the build files off
line. 

otherwise, for simpler p4 tasks, i just <exec program="p4" .../>

hth


-----8<---------------

using System;
using System.IO;
using System.Text.RegularExpressions;

using SourceForge.NAnt;
using SourceForge.NAnt.Attributes;

namespace NAnt.Contrib.Tasks
{

  [TaskName("p4")]
  public class P4Task : Task 
  {
    string _action = null;
    /// <summary>
    /// the actions for p4.  possible values are:
    ///   sync    : req: files
    ///   edit    : req: files, changelist
    ///   add     : req: files, changelist
    ///   submit  : req: changelist OR files
    ///   revert  : req: changelist OR files; optional: options
    ///   label   : req: labelfile
    /// </summary>
    [TaskAttribute( "action", Required=true)]
    public string Action
    {
      get { return _action; }
      set { _action = value; }
    }
    string _changeList = null;
    [TaskAttribute( "changelist", Required=false)]
    public string ChangeList
    {
      get { return _changeList; }
      set { _changeList = value; }
    }
    string _labelFile = null;
    [TaskAttribute( "labelfile", Required=false)]
    /// <summary>
    /// required for action = label
    /// </summary>
    public string LabelFile
    {
      get { return _labelFile; }
      set { _labelFile = value; }
    }
    string _files = null;
    [TaskAttribute( "files", Required=false)]
    public string Files
    {
      get { return _files; }
      set { _files = value; }
    }
    string _options = string.Empty;
    /// <summary>
    /// any text that goes bet. the command and the other args (eg: -n )
    /// applied on actions= submit or revert
    /// </summary>
    [TaskAttribute( "options", Required=false)]
    public string Options
    {
      get { return _options; }
      set { _options = value; }
    }

    private void showAction( string format, params object[] prms )
    {
      if ( ( Project != null) && this.Verbose )
        Log.WriteLine( string.Format( format, prms ) );
    }
    protected override void ExecuteTask() 
    {
      Log.WriteLine( LogPrefix + "action={0} changelist=\"{1}\"
files=\"{2}\" labelfile=\"{3}\" options=\"{4}\"", 
        Action, ChangeList, Files, LabelFile, Options );
      bool onLan = true;
      if ( ( Project != null ) && ( Project.Properties[ "Is.Lan" ] !=
null ) )
        onLan = Convert.ToBoolean( Project.Properties[ "Is.Lan" ] );
      if ( !onLan ) 
      {
        showAction( "No LAN, no P4! action={0} files={1}", _action,
_files );
        return;
      }
      string runStr = null;
      string output = null;
      int exitCode = -1;
      string changeListParam = string.Empty;
      if ( string.Compare( _action, "add", true ) == 0 )
      {
        assertPropFiles();
        string[] files = Directory.GetFiles( Path.GetDirectoryName(
_files ), Path.GetFileName( _files) ) ;
        if ( files.Length == 0 )
        {
          exitCode = 0;
          output = "No file(s) found to add." ; 
        }
        else
        {
          changeListParam = string.Concat( "-c ", getChangeList() );
          exitCode = RunProcess( "p4", 
            string.Format( "add {0} {1}", changeListParam, _files ),
null, ref output );
        }
      }
      else if ( string.Compare( _action, "edit", true ) == 0 )
      {
        assertPropFiles();
        changeListParam = string.Concat( "-c ", getChangeList() );
        exitCode = RunProcess( "p4", 
          string.Format( "edit {0}", _files ), null, ref output );
        if ( changeListParam != string.Empty ) 
          exitCode = RunProcess( "p4", 
            string.Format( "reopen {0} {1}", changeListParam, _files ),
null, ref output );
      }
      else if ( string.Compare( _action, "sync", true ) == 0 )
      {
        assertPropFiles();
        exitCode = RunProcess( "p4", 
          string.Format( "sync {0}", _files ), null, ref output );
      }
      else if (( string.Compare( _action, "submit", true ) == 0 ) || (
string.Compare( _action, "revert", true ) == 0 ) )
      {
        changeListParam = string.Concat( "-c ", getChangeList() );
        if ( ( changeListParam != string.Empty ) && ( _files != null) &&
( _files != string.Empty ) )
          throw new BuildException( "Cannot have both files and
changelist set when action = " + _action );
        else if ( changeListParam != string.Empty )        
          runStr = string.Format( "{0} {1} {2}", _action, _options,
changeListParam );
        else if ( ( _files != null ) && ( _files != string.Empty ) )
          runStr = string.Format( "{0} {1} {2}", _action, _options,
_files );
        if ( runStr == null )
          throw new BuildException( string.Format( "{0} action requires
either files or changelist.", _action ) );
        exitCode = RunProcess( "p4", runStr, null, ref output );
      }
      else if ( string.Compare( _action, "label", true ) == 0 )
      {
        if ( ( _labelFile == null ) || ( _labelFile == string.Empty ) )
          throw new BuildException( "labelfile is a required property"
);
        if ( !File.Exists( LabelFile ) ) throw new BuildException(
string.Format( "{0} not found", LabelFile ) );
        string labelText = Frogware.Utils.ReadTextFromFile( LabelFile );
        string labelName = getLabelName( labelText );
        exitCode = RunProcess( "p4", "label -i", labelText, ref output
);
        if ( exitCode != 0 ) 
          throw new BuildException( string.Format( "P4 LABEL returned
EXITCODE = {0}", exitCode ) );
        exitCode = RunProcess( "p4", string.Format( "labelsync -l {0}",
labelName), null ); // don't take the output
        if ( exitCode != 0 ) 
          throw new BuildException( string.Format( "P4 LABEL (SYNC)
returned EXITCODE = {0}", exitCode ) );
      }
      else
      {
        throw new BuildException( string.Format( "unknown action = {0}",
_action ) );
      }
      showAction( output );
      if ( exitCode != 0 ) 
        throw new BuildException( string.Format( "P4 returned EXITCODE =
{0}\n** Output follows: ** \n{1}", exitCode, output ) );
    }
    private string getLabelName( string labelText )
    {
      Regex rex = new Regex( @"Label:\s*(?'name'\S+)" );
      Match m = rex.Match( labelText );
      if ( !m.Success ) 
        throw new BuildException( string.Format( "invalid label file:
{0}", LabelFile ));
      return m.Groups["name"].Value;
    }
    private void assertPropFiles()
    {
      if ( ( _files == null ) || ( _files == string.Empty ) )
        throw new BuildException( "files is a required property" );
    }
    private string getChangeList() 
    {
      if ( _changeList == null ) return string.Empty;
      string testOut = getProcessOutput( "p4", 
        string.Format( "changes -s pending -u {0}",
Environment.UserName.ToLower() ), null );
      string[] lines = testOut.Split( '\n' );
      foreach( string line in lines )
      {
        if ( line.IndexOf( _changeList ) > -1 )
        {
          string[] s2 = line.Split( ' ' );   // poor manz regex
          return s2[ 1 ];
        }
      }
      // create new changelist
      string changeListDef = string.Concat(
        "Change: new\n",
        "Client: ", Environment.MachineName.ToLower(), "\n", 
        "User: ", Environment.UserName.ToLower(), "\n", 
        "Status: new\nDescription:\n ",
        _changeList + "\nFiles:\n\n" );
      string output = getProcessOutput( "p4", "change -i", changeListDef
);
      string[] s = output.Split( ' ' );   // poor manz regex
      if ( ( s.Length == 3) && ( s[0] == "Change" ) && (
s[2].StartsWith( "created." ) ) )
        return s[ 1 ];
      else
      {
        throw new BuildException( string.Format( "Unexpected P4 output =
{0}", output));
      }
    }
    private string getProcessOutput( string exe, string prms, string
input )
    {
      string output = null;
      int exitCode = RunProcess( exe, prms, input, ref output );
      return output;
    }
    public int RunProcess( string exe, string prms, string input, ref
string output )
    {
      showAction( "{0} {1}", exe, prms );
      System.Diagnostics.Process p = new System.Diagnostics.Process();
      System.Diagnostics.ProcessStartInfo si = new
System.Diagnostics.ProcessStartInfo( exe, prms );
      si.UseShellExecute = false;
      si.RedirectStandardOutput = true;
      si.RedirectStandardInput = ( input != null );
      p.StartInfo = si;
      p.Start();
      if ( input != null )
      {
        StreamWriter sw = p.StandardInput;
        sw.Write( input );
        sw.Close();
      }          
      output = p.StandardOutput.ReadToEnd();
      p.WaitForExit();
      showAction( output );
      return p.ExitCode;
    }
    public int RunProcess( string exe, string prms, string input )
    {
      showAction( "{0} {1}", exe, prms );
      System.Diagnostics.Process p = new System.Diagnostics.Process();
      System.Diagnostics.ProcessStartInfo si = new
System.Diagnostics.ProcessStartInfo( exe, prms );
      si.UseShellExecute = false;
      si.RedirectStandardOutput = false;
      si.RedirectStandardInput = ( input != null );
      p.StartInfo = si;
      p.Start();
      if ( input != null )
      {
        StreamWriter sw = p.StandardInput;
        sw.Write( input );
        sw.Close();
      }          
      p.WaitForExit();
      return p.ExitCode;
    }
  }

}







> -----Original Message-----
> From: [EMAIL PROTECTED] 
> [mailto:[EMAIL PROTECTED] On Behalf Of 
> Ben Lowery
> Sent: Tuesday, November 04, 2003 12:43
> To: [EMAIL PROTECTED]
> Subject: [Nant-users] Perforce Tasks?
> 
> 
> Has anyone worked up some Perforce tasks for NAnt?  If so, 
> would you be willing to share them?
> 
> Thanks,
> 
> --b
> 
> 
> 
> 
> -------------------------------------------------------
> This SF.net email is sponsored by: SF.net Giveback Program. 
> Does SourceForge.net help you be more productive?  Does it 
> help you create better code?  SHARE THE LOVE, and help us 
> help YOU!  Click Here: http://sourceforge.net/donate/ 
> _______________________________________________
> Nant-users mailing list
> [EMAIL PROTECTED] 
> https://lists.sourceforge.net/lists/listinfo/n> ant-users
> 



-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
Does SourceForge.net help you be more productive?  Does it
help you create better code?  SHARE THE LOVE, and help us help
YOU!  Click Here: http://sourceforge.net/donate/
_______________________________________________
Nant-users mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/nant-users

Reply via email to