I've also started porting the Ant perforce tasks. I haven't gotten too far - just the base class and p4 add. We should be able to merge the two efforts.

Ian

Good stuff.

Any chance of getting those into nantcontrib or whereever they fit best?
Would be nice to have some perforce tasks in a position that they can be
actively developed.

Brett

-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Jean
Rajotte
Sent: Thursday, 20 November 2003 2:50 AM
To: [EMAIL PROTECTED]; [EMAIL PROTECTED]
Subject: RE: [Nant-users] Perforce Tasks?


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




-------------------------------------------------------
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




--
Ian MacLean, Developer, ActiveState, a division of Sophos
http://www.ActiveState.com





------------------------------------------------------- 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