Browse Source

New perforce functionality

PR:	15707
Submitted by:	Antoine Levy-Lambert


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@273968 13f79535-47bb-0310-9956-ffa450edef68
master
Conor MacNeill 22 years ago
parent
commit
a1a910e2df
8 changed files with 911 additions and 9 deletions
  1. +230
    -2
      docs/manual/OptionalTasks/perforce.html
  2. +2
    -0
      src/main/org/apache/tools/ant/taskdefs/defaults.properties
  3. +353
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/perforce/P4Integrate.java
  4. +185
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/perforce/P4Resolve.java
  5. +40
    -7
      src/main/org/apache/tools/ant/taskdefs/optional/perforce/P4Submit.java
  6. +33
    -0
      src/testcases/org/apache/tools/ant/taskdefs/optional/perforce/build1.xml
  7. +53
    -0
      src/testcases/org/apache/tools/ant/taskdefs/optional/perforce/build2.xml
  8. +15
    -0
      src/testcases/org/apache/tools/ant/taskdefs/optional/perforce/p4integrate.xml

+ 230
- 2
docs/manual/OptionalTasks/perforce.html View File

@@ -79,7 +79,18 @@ You will also need the Perforce client executable (p4 or p4.exe but not p4win.ex
<td><a href="#p4add">P4Add</a></td>
<td>Add files</td>
</tr>

<tr>
<td><a href="#p4delete">P4Delete</a></td>
<td>Delete files</td>
</tr>
<tr>
<td><a href="#p4integrate">P4Integrate</a></td>
<td>Integrate files</td>
</tr>
<tr>
<td><a href="#p4resolve">P4Resolve</a></td>
<td>Resolve files</td>
</tr>
<tr>
<td><a href="#p4fstat">P4Fstat</a></td>
<td>Show differences between local repository and p4 repository</td>
@@ -204,6 +215,9 @@ available from the <a href="http://www.perforce.com/" target="_top">Perforce web
&lt;taskdef name=&quot;p4reopen&quot; classname=&quot;org.apache.tools.ant.taskdefs.optional.perforce.P4Reopen&quot;/&gt;
&lt;taskdef name=&quot;p4revert&quot; classname=&quot;org.apache.tools.ant.taskdefs.optional.perforce.P4Revert&quot;/&gt;
&lt;taskdef name=&quot;p4add&quot; classname=&quot;org.apache.tools.ant.taskdefs.optional.perforce.P4Add&quot;/&gt;
&lt;taskdef name=&quot;p4delete&quot; classname=&quot;org.apache.tools.ant.taskdefs.optional.perforce.P4Delete&quot;/&gt;
&lt;taskdef name=&quot;p4integrate&quot; classname=&quot;org.apache.tools.ant.taskdefs.optional.perforce.P4Integrate&quot;/&gt;
&lt;taskdef name=&quot;p4resolve&quot; classname=&quot;org.apache.tools.ant.taskdefs.optional.perforce.P4Resolve&quot;/&gt;
</pre>

<hr>
@@ -245,7 +259,8 @@ available from the <a href="http://www.perforce.com/" target="_top">Perforce web
<h3>Description:</h3>
<p>Request a new changelist from the Perforce server.
This task sets the ${p4.change} property which can then be passed to <A HREF="#p4submit">P4Submit</A>,
<A HREF="#p4edit">P4Edit</A>, or <a HREF="#p4add">P4Add</A>.
<A HREF="#p4edit">P4Edit</A>, or <a HREF="#p4add">P4Add</A>, or <a HREF="#p4delete">P4Delete</A>,
then to <A HREF="#p4submit">P4Submit</A>.
</p>
<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
@@ -309,6 +324,11 @@ although P4Edit can open files to the default change, P4Submit cannot yet submi
<h2><a name="p4submit">P4Submit</a></h2>
<h3>Description:</h3>
<p>Submit a changelist, usually obtained from P4Change.
<p>P4Submit will also change the value of the property p4.change if the change list is renamed by the Perforce server.
<p>P4Submit will set a property p4.needsresolve to 1 if the change could not be submitted due to files needing resolving.
<p>Files will need resolve if at the time of checking in, the revision that was checked out to do the current edit
is not the latest any more.
<p>If no files need resolve, the p4.needsresolve will be set to 0.
</p>
<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
@@ -618,6 +638,214 @@ will list all the files under C:\dev\gnu\depot, sorted by under Perforce or not



<h2><a name="p4delete">P4Delete</a></h2>
<h3>Description:</h3>
<p>Open file(s) for delete. P4Change should be used to obtain a new changelist for P4Delete as,
although P4Delete can open files to the default change, P4Submit cannot yet submit it.
</p>
<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
<td valign="top"><b>Attribute</b></td>
<td valign="top"><b>Description</b></td>
<td align="center" valign="top"><b>Required</b></td>
</tr>
<tr>
<td valign="top">view</td>
<td valign="top">The filespec to request to delete</td>
<td valign="top" align="center">Yes</td>
</tr>
<tr>
<td valign="top">change</td>
<td valign="top">An existing changelist number to assign files to.</td>
<td valign="top" align="center">No, but see above.</td>
</tr>

</table>

<h3>Examples</h3>
<pre>
&lt;p4delete
view=&quot;//depot/projects/projectfoo/main/src/Blah.java...&quot;
change=&quot;${p4.change}&quot;/&gt;
</pre>
<hr>
<h2><a name="p4integrate">P4Integrate</a></h2>
<h3>Description:</h3>
<p>Open file(s) for integrate. P4Change should be used to obtain a new changelist for P4Integrate as,
although P4Integrate can open files to the default change, P4Submit cannot yet submit it.
</p>
<h3>Parameters</h3>
<p>If this task is used without using a branch definition, both fromfile and tofile must be supplied.
If a branch definition is supplied, at least one of fromfile or tofile should be supplied.
Both fromfile and tofile can be supplied together with a branch definition.</p>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
<td valign="top"><b>Attribute</b></td>
<td valign="top"><b>Description</b></td>
<td align="center" valign="top"><b>Required</b></td>
<td align="center" valign="top"><b>Perforce command line flag</b></td>
</tr>
<tr>
<td valign="top">fromfile</td>
<td valign="top">Original file or view</td>
<td valign="top" align="center">required if a branch is not specified</td>
<td valign="top" align="center"></td>
</tr>
<tr>
<td valign="top">tofile</td>
<td valign="top">Target file or view.</td>
<td valign="top" align="center">required if a branch is not specified</td>
<td valign="top" align="center"></td>
</tr>
<tr>
<td valign="top">branch</td>
<td valign="top">Name of branch specification</td>
<td valign="center">No</td>
<td valign="top" align="center">-b</td>
</tr>
<tr>
<td valign="top">change</td>
<td valign="top">An existing changelist number to assign files to.</td>
<td valign="top" align="center">No, but see above.</td>
<td valign="top" align="center">-c</td>
</tr>
<tr>
<td valign="top">forceintegrate</td>
<td valign="top">Forces integration regardless of previous integration history (*)</td>
<td valign="center">No</td>
<td valign="top" align="center">-f</td>
</tr>
<tr>
<td valign="top">restoredeletedrevisions</td>
<td valign="top">Enables integration around deleted revisions (*)</td>
<td valign="center">No</td>
<td valign="top" align="center">-d</td>
</tr>
<tr>
<td valign="top">leavetargetrevision</td>
<td valign="top">Prevents target files from being synced to head revision before integration (*)</td>
<td valign="center">No</td>
<td valign="top" align="center">-h</td>
</tr>
<tr>
<td valign="top">enablebaselessmerges</td>
<td valign="top">Forces integration to existing target files which have no integration history relative to the source files (*)</td>
<td valign="center">No</td>
<td valign="top" align="center">-i</td>
</tr>
<tr>
<td valign="top">simulationmode</td>
<td valign="top">Displays which integrations are necessary but do not actually schedule them (*)</td>
<td valign="center">No</td>
<td valign="top" align="center">-n</td>
</tr>
<tr>
<td valign="top">reversebranchmappings</td>
<td valign="top">Reverses mappings in the branch view, with source and target files exchanging place (*)</td>
<td valign="center">No</td>
<td valign="top" align="center">-r</td>
</tr>
<tr>
<td valign="top">propagatesourcefiletype</td>
<td valign="top">Makes source file type propagate to existing target files (*)</td>
<td valign="center">No</td>
<td valign="top" align="center">-t</td>
</tr>
<tr>
<td valign="top">nocopytargetfiles</td>
<td valign="top">Prevents the physical delivery on disk of new target files (*)</td>
<td valign="center">No</td>
<td valign="top" align="center">-v</td>
</tr>
</table>
<br>
(*) The following applies for a number of flags. The default is false. To set the flag, use &quot;true&quot;

<h3>Examples</h3>
<pre>
&lt;p4integrate
fromfile=&quot;//depot/projects/projectfoo/main/src/Blah.java...&quot;
tofile=&quot;//depot/projects/projectfoo/release/src/Blah.java...&quot;
change=&quot;${p4.change}&quot;/&gt;
</pre>
<hr>
<h2><a name="p4resolve">P4Resolve</a></h2>
<h3>Description:</h3>
<p>Resolves files. You want to do this if :
<ul>
<li>
there have been or there may be concurrent edits of the same file. For instance, you have begun to edit a file, and while you were working on it, somebody has submitted a new version of the same file. When you first attempt to submit your file(s), you will get a message (property p4.needsresolve set).
</li>
<li>
you have just been doing an integration to existing target files
</li>
</ul>
P4Resolve does not use a change list number (it takes it from the files it is working on).
</p>
<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
<td valign="top"><b>Attribute</b></td>
<td valign="top"><b>Description</b></td>
<td align="center" valign="top"><b>Required</b></td>
<td align="center" valign="top"><b>Perforce command line flag</b></td>
</tr>
<tr>
<td valign="top">view</td>
<td valign="top">The filespec to request to delete</td>
<td valign="top" align="center">Yes</td>
<td valign="top" align="center"></td>
</tr>
<tr>
<td valign="top">resolvemode</td>
<td valign="top">Should have one of these values :
<ul>
<li>&quot;automatic&quot;</li>
<li>&quot;force&quot;</li>
<li>&quot;safe&quot;</li>
<li>&quot;theirs&quot;</li>
<li>&quot;yours&quot;</li>
</ul></td>
<td valign="top" align="center">Yes</td>
<td valign="top" align="center">corresponds to one of -am -af -as -at -ay </td>
</tr>
<tr>
<td valign="top">redoall</td>
<td valign="top">allows previously resolved files to be resolved again (*)</td>
<td valign="top" align="center">No</td>
<td valign="top" align="center">-f</td>
</tr>
<tr>
<td valign="top">simulationmode</td>
<td valign="top">Lists the integrations which would be performed, without actually doing them. (*)</td>
<td valign="top" align="center">No</td>
<td valign="top" align="center">-n</td>
</tr>
<tr>
<td valign="top">forcetextmode</td>
<td valign="top">Attempts a textual merge, even for binary files (*)</td>
<td valign="top" align="center">No</td>
<td valign="top" align="center">-t</td>
</tr>
<tr>
<td valign="top">markersforall</td>
<td valign="top">Puts in markers for all changes, conflicting or not (*)</td>
<td valign="top" align="center">No</td>
<td valign="top" align="center">-v</td>
</tr>
</table>
<br>
(*) The following applies for a number of flags. The default is false. To set the flag, use &quot;true&quot;

<h3>Examples</h3>
<pre>
&lt;p4resolve
view=&quot;//depot/projects/projectfoo/main/src/Blah.java...&quot;
change=&quot;${p4.change}&quot;
resolvemode=&quot;automatic&quot;/&gt;
</pre>

<h2><a name="changes">Change History</a></h2>
<table border="1" cellpadding="2" cellspacing="0">
<tr>


+ 2
- 0
src/main/org/apache/tools/ant/taskdefs/defaults.properties View File

@@ -128,6 +128,8 @@ p4label=org.apache.tools.ant.taskdefs.optional.perforce.P4Label
p4have=org.apache.tools.ant.taskdefs.optional.perforce.P4Have
p4sync=org.apache.tools.ant.taskdefs.optional.perforce.P4Sync
p4edit=org.apache.tools.ant.taskdefs.optional.perforce.P4Edit
p4integrate=org.apache.tools.ant.taskdefs.optional.perforce.P4Integrate
p4resolve=org.apache.tools.ant.taskdefs.optional.perforce.P4Resolve
p4submit=org.apache.tools.ant.taskdefs.optional.perforce.P4Submit
p4counter=org.apache.tools.ant.taskdefs.optional.perforce.P4Counter
p4revert=org.apache.tools.ant.taskdefs.optional.perforce.P4Revert


+ 353
- 0
src/main/org/apache/tools/ant/taskdefs/optional/perforce/P4Integrate.java View File

@@ -0,0 +1,353 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* Portions of this software are based upon public domain software
* originally written at the National Center for Supercomputing Applications,
* University of Illinois, Urbana-Champaign.
*/

package org.apache.tools.ant.taskdefs.optional.perforce;

import org.apache.tools.ant.BuildException;

/**
* Integrate file(s).
* P4Change should be used to obtain a new changelist for P4Integrate,
* although P4Integrate can open files to the default change,
* P4Submit cannot yet submit to it.
* Example Usage:<br>
* &lt;p4integrate change="${p4.change}" fromfile="//depot/project/dev/foo.txt" tofile="//depot/project/main/foo.txt" /&gt;
*
* @author <A HREF="mailto:levylambert@tiscali-dsl.de">Antoine Levy-Lambert</A>
*
*/

public class P4Integrate extends P4Base {

private String change = null;
private String fromfile = null;
private String tofile = null;
private String branch = null;
private boolean restoredeletedrevisions = false;
private boolean forceintegrate = false;
private boolean leavetargetrevision = false;
private boolean enablebaselessmerges = false;
private boolean simulationmode = false;
private boolean reversebranchmappings = false;
private boolean propagatesourcefiletype = false;
private boolean nocopynewtargetfiles = false;

/**
* get the changelist number
*
* @returns the changelist number set for this task
*/
public String getChange() {
return change;
}

/**
* set the changelist number for the operation
*
* @param change An existing changelist number to assign files to; optional
* but strongly recommended.
*/
public void setChange(String change) {
this.change = change;
}

/**
* get the from file specification
*
* @returns the from file specification
*/
public String getFromfile() {
return fromfile;
}

/**
* sets the from file specification
*
* @param fromf the from file specification
*/
public void setFromfile(String fromf) {
this.fromfile = fromf;
}

/**
* get the to file specification
*
* @returns the to file specification
*/
public String getTofile() {
return tofile;
}

/**
* sets the to file specification
*
* @param tof the to file specification
*/
public void setTofile(String tof) {
this.tofile = tof;
}

/**
* get the branch
*
* @returns the name of the branch
*/
public String getBranch() {
return branch;
}

/**
* sets the branch
*
* @param br the name of the branch to use
*/
public void setBranch(String br) {
this.branch = br;
}

/**
* gets the restoredeletedrevisions flag
*
* @returns restore deleted revisions
*/
public boolean isRestoreDeletedRevisions() {
return restoredeletedrevisions;
}

/**
* sets the restoredeletedrevisions flag
*
* @param setrest value chosen for restoredeletedrevisions
*/
public void setRestoreDeletedRevisions(boolean setrest) {
this.restoredeletedrevisions = setrest;
}

/**
* gets the forceintegrate flag
*
* @returns restore deleted revisions
*/
public boolean isForceIntegrate() {
return forceintegrate;
}

/**
* sets the forceintegrate flag
*
* @param setrest value chosen for forceintegrate
*/
public void setForceIntegrate(boolean setrest) {
this.forceintegrate = setrest;
}

/**
* gets the leavetargetrevision flag
*
* @returns flag indicating if the target revision should be preserved
*/
public boolean isLeaveTargetRevision() {
return leavetargetrevision;
}

/**
* sets the leavetargetrevision flag
*
* @param setrest value chosen for leavetargetrevision
*/
public void setLeaveTargetRevision(boolean setrest) {
this.leavetargetrevision = setrest;
}

/**
* gets the enablebaselessmerges flag
*
* @returns boolean indicating if baseless merges are desired
*/
public boolean isEnableBaselessMerges() {
return enablebaselessmerges;
}

/**
* sets the enablebaselessmerges flag
*
* @param setrest value chosen for enablebaselessmerges
*/
public void setEnableBaselessMerges(boolean setrest) {
this.enablebaselessmerges = setrest;
}

/**
* gets the simulationmode flag
*
* @returns simulation mode flag
*/
public boolean isSimulationMode() {
return simulationmode;
}

/**
* sets the simulationmode flag
*
* @param setrest value chosen for simulationmode
*/
public void setSimulationMode(boolean setrest) {
this.simulationmode = setrest;
}
/**
* returns the flag indicating if reverse branch mappings are sought
*
* @returns reversebranchmappings flag
*/
public boolean isReversebranchmappings() {
return reversebranchmappings;
}

/**
* sets the reversebranchmappings flag
*
* @param reversebranchmappings flag indicating if reverse branch mappings are sought
*/
public void setReversebranchmappings(boolean reversebranchmappings) {
this.reversebranchmappings = reversebranchmappings;
}
/**
* returns flag indicating if propagation of source file type is sought
*
* @returns flag set to true if you want to propagate source file type for existing target files
*/
public boolean isPropagatesourcefiletype() {
return propagatesourcefiletype;
}
/**
* sets flag indicating if one wants to propagate the source file type
*
* @param propagatesourcefiletype set it to true if you want to change the type of existing target files according to type of source file.
*/
public void setPropagatesourcefiletype(boolean propagatesourcefiletype) {
this.propagatesourcefiletype = propagatesourcefiletype;
}
/**
* returns flag indicating if one wants to suppress the copying on the local hard disk of new target files
*
* @returns flag indicating if one wants to suppress the copying on the local hard disk of new target files
*/
public boolean isNocopynewtargetfiles() {
return nocopynewtargetfiles;
}

/**
* sets nocopynewtargetfiles flag
*
* @param nocopynewtargetfiles set it to true to gain speed in integration by not copying on the local Perforce client new target files
*/
public void setNocopynewtargetfiles(boolean nocopynewtargetfiles) {
this.nocopynewtargetfiles = nocopynewtargetfiles;
}

/**
* execute the p4 integrate
*/
public void execute() throws BuildException {
if (change != null) {
P4CmdOpts = "-c " + change;
}
if (this.forceintegrate) {
P4CmdOpts = P4CmdOpts + " -f";
}
if (this.restoredeletedrevisions) {
P4CmdOpts = P4CmdOpts + " -d";
}
if ( this.leavetargetrevision) {
P4CmdOpts = P4CmdOpts + " -h";
}
if ( this.enablebaselessmerges ) {
P4CmdOpts = P4CmdOpts + " -i";
}
if (this.simulationmode ) {
P4CmdOpts = P4CmdOpts + " -n";
}
if ( this.reversebranchmappings ) {
P4CmdOpts = P4CmdOpts + " -r";
}
if ( this.propagatesourcefiletype ) {
P4CmdOpts = P4CmdOpts + " -t";
}
if ( this.nocopynewtargetfiles ) {
P4CmdOpts = P4CmdOpts + "-v";
}
String command;
if (branch == null && fromfile != null && tofile != null) {
command = P4CmdOpts + " " + fromfile + " " + tofile;

}
else if ( branch != null && fromfile == null && tofile != null )
{
command = P4CmdOpts + " -b " + branch + " " + tofile;
}
else if ( branch != null && fromfile != null )
{
command = P4CmdOpts + " -b " + branch + " -s "+ fromfile + " " + tofile;
}
else {
throw new BuildException("you need to specify fromfile and tofile, or branch and tofile, or branch and fromfile, or branch and fromfile and tofile ");
}
execP4Command("-s integrate " + command, new SimpleP4OutputHandler(this));
}
}

+ 185
- 0
src/main/org/apache/tools/ant/taskdefs/optional/perforce/P4Resolve.java View File

@@ -0,0 +1,185 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* Portions of this software are based upon public domain software
* originally written at the National Center for Supercomputing Applications,
* University of Illinois, Urbana-Champaign.
*/

package org.apache.tools.ant.taskdefs.optional.perforce;

import org.apache.tools.ant.BuildException;

public class P4Resolve extends P4Base{
private String resolvemode = null;


private boolean redoall; /* -f */
private boolean simulationmode; /* -n */
private boolean forcetextmode; /* -t */
private boolean markersforall; /* -v */
private static final String AUTOMATIC = "automatic";
private static final String FORCE = "force";
private static final String SAFE = "safe";
private static final String THEIRS = "theirs";
private static final String YOURS = "yours";
private static final String[] resolvemodes = {
AUTOMATIC,
FORCE,
SAFE,
THEIRS,
YOURS
};

public String getResolvemode() {
return resolvemode;
}
/**
* values for resolvemode
* <ul>
* <li> automatic -am</li>
* <li> force -af </li>
* <li> safe -as </li>
* <li> theirs -at </li>
* <li> yours -ay </li>
* </ul>
*/
public void setResolvemode(String resolvemode) {
boolean found=false;
for (int counter=0; counter < resolvemodes.length; counter++)
{
if (resolvemode.equals(resolvemodes[counter])) {
found=true;
break;
}
}
if (found==false) {
throw new BuildException("Unacceptable value for resolve mode");
}
this.resolvemode = resolvemode;
}

public boolean isRedoall() {
return redoall;
}

public void setRedoall(boolean redoall) {
this.redoall = redoall;
}

public boolean isSimulationmode() {
return simulationmode;
}

public void setSimulationmode(boolean simulationmode) {
this.simulationmode = simulationmode;
}

public boolean isForcetextmode() {
return forcetextmode;
}

public void setForcetextmode(boolean forcetextmode) {
this.forcetextmode = forcetextmode;
}

public boolean isMarkersforall() {
return markersforall;
}

public void setMarkersforall(boolean markersforall) {
this.markersforall = markersforall;
}

/**
* execute the p4 resolve
*/
public void execute() throws BuildException {
if (this.resolvemode.equals(AUTOMATIC)) {
P4CmdOpts = P4CmdOpts + " -am";
}
else if (this.resolvemode.equals(FORCE)) {
P4CmdOpts = P4CmdOpts + " -af";
}
else if (this.resolvemode.equals(SAFE)) {
P4CmdOpts = P4CmdOpts + " -as";
}
else if (this.resolvemode.equals(THEIRS)) {
P4CmdOpts = P4CmdOpts + " -at";
}
else if (this.resolvemode.equals(YOURS)) {
P4CmdOpts = P4CmdOpts + " -ay";
}
else
{
throw new BuildException("unsupported or absent resolve mode");
}
if (P4View==null) {
throw new BuildException("please specify a view");
}
if ( this.isRedoall() ) {
P4CmdOpts = P4CmdOpts + " -f";
}
if ( this.isSimulationmode() ) {
P4CmdOpts = P4CmdOpts + " -n";
}
if ( this.isForcetextmode() ) {
P4CmdOpts = P4CmdOpts + " -t";
}
if ( this.isMarkersforall() ) {
P4CmdOpts = P4CmdOpts + " -v";
}
execP4Command("-s resolve " + P4CmdOpts + " " + P4View, new SimpleP4OutputHandler(this));
}
}

+ 40
- 7
src/main/org/apache/tools/ant/taskdefs/optional/perforce/P4Submit.java View File

@@ -61,6 +61,7 @@ package org.apache.tools.ant.taskdefs.optional.perforce;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import java.util.Vector;

/** Submits a numbered changelist to Perforce.
*
@@ -80,7 +81,7 @@ public class P4Submit extends P4Base {
public String change;

/**
* The changelist number to submit; required.
* @param change The changelist number to submit; required.
*/
public void setChange(String change) {
this.change = change;
@@ -88,12 +89,7 @@ public class P4Submit extends P4Base {

public void execute() throws BuildException {
if (change != null) {
execP4Command("submit -c " + change,
new P4HandlerAdapter() {
public void process(String line) {
log(line, Project.MSG_VERBOSE);
}
});
execP4Command("submit -c " + change, (P4HandlerAdapter) new P4SubmitAdapter());
} else {
//here we'd parse the output from change -o into submit -i
//in order to support default change.
@@ -101,4 +97,41 @@ public class P4Submit extends P4Base {
}
}

public class P4SubmitAdapter extends P4HandlerAdapter {
public void process(String line) {
log(line, Project.MSG_VERBOSE);
getProject().setProperty("p4.needsresolve","0");
// this type of output might happen
// Change 18 renamed change 20 and submitted.
if (util.match("/renamed/", line)) {
try {
Vector myarray = new Vector();
util.split(myarray, line);
boolean found = false;
for (int counter = 0; counter < myarray.size(); counter++) {
if (found == true) {
int changenumber = Integer.parseInt((String) myarray.elementAt(counter + 1));
log("Perforce change renamed " + changenumber, Project.MSG_INFO);
getProject().setProperty("p4.change", "" + changenumber);
found = false;
}
if (((String) (myarray.elementAt(counter))).equals("renamed")) {
found = true;
}
}
}
// NumberFormatException or ArrayOutOfBondsException could happen here
catch (Exception e) {
String msg = "Failed to parse " + line + "\n"
+ " due to " + e.getMessage();
throw new BuildException(msg, e, getLocation());
}
}
if (util.match("/p4 submit -c/",line)) {
getProject().setProperty("p4.needsresolve","1");
}

}
}

}

+ 33
- 0
src/testcases/org/apache/tools/ant/taskdefs/optional/perforce/build1.xml View File

@@ -0,0 +1,33 @@
<!-- author Antoine Levy-Lambert levylambert@tiscali-dsl.de -->
<!-- this file demonstrates that p4.change will be modified by p4submit -->
<!-- if the change number is modified by the Perforce daemon during the submission -->
<project name="build1" default="runtest">
<target name="runtest">
<p4change/>
<property name="change1" value="${p4.change}" />
<echo>
doing a first change ${change1}
</echo>
<p4change/>
<property name="change2" value="${p4.change}" />
<echo>
doing a second change ${change2}
</echo>
<p4edit view="//depot/foobar" change="${change1}" />
<p4edit view="//depot/hello" change="${change2}" />
<echo>
before submitting of hello change ${change2} p4.change is now ${p4.change}
</echo>
<p4submit change="${change2}"/>
<echo>
after submitting of hello p4.change is now ${p4.change}
</echo>
<echo>
before submitting of foobar change ${change1}
</echo>
<p4submit change="${change1}"/>
<echo>
after submitting of foobar p4.change is now ${p4.change}
</echo>
</target>
</project>

+ 53
- 0
src/testcases/org/apache/tools/ant/taskdefs/optional/perforce/build2.xml View File

@@ -0,0 +1,53 @@
<!-- author Antoine Levy-Lambert levylambert@tiscali-dsl.de -->
<!-- this test shows that p4 submit can now indicate that a file needs to be resolved -->
<!-- before running the test, edit this xml and change the 5 properties at the top to values which make sense on your system-->
<!-- the test uses two Perforce client specs which must exist beforehand -->
<!-- also using both client specs you should be able to edit the file ${depot_file_spec} -->
<project name="testresolve" default= "test">
<property name="first_client" value="levyant_dev_ant"/>
<property name="first_client_root" value="C:\dev\gnu"/>
<property name="second_client" value="levyant_cygwin_test"/>
<property name="second_client_root" value="C:\dev\test"/>
<property name="depot_file_spec" value="//depot/foobar"/>
<target name="test">
<p4change client="${first_client}"/>
<property name="change1" value="${p4.change}" />
<p4change client="${second_client}"/>
<property name="change2" value="${p4.change}" />
<sequential>
<antcall target="edit">
<param name="p4.client" value="${first_client}"/>
<param name="client_root" value="${first_client_root}"/>
<param name="change" value="${change1}"/>
</antcall>
<antcall target="edit">
<param name="p4.client" value="${second_client}"/>
<param name="client_root" value="${second_client_root}"/>
<param name="change" value="${change2}"/>
</antcall>
<antcall target="submit">
<param name="p4.client" value="${first_client}"/>
<param name="change" value="${change1}"/>
</antcall>
<antcall target="submit">
<param name="p4.client" value="${second_client}"/>
<param name="change" value="${change2}"/>
</antcall>
</sequential>
</target>
<target name="edit">
<echo>
doing a change ${change} on client ${p4.client}
</echo>
<p4edit change="${change}" view="${depot_file_spec}"/>
<echo file="${depot_file_spec}">
hello ${p4.client} ${change}
</echo>
</target>
<target name="submit">
<p4submit change="${change}"/>
<echo>
p4.needsresolve ${p4.needsresolve} after submit
</echo>
</target>
</project>

+ 15
- 0
src/testcases/org/apache/tools/ant/taskdefs/optional/perforce/p4integrate.xml View File

@@ -0,0 +1,15 @@
<!-- author Antoine Levy-Lambert levylambert@tiscali-dsl.de -->
<!-- this test demonstrates p4integrate -->
<project name="integrate" default= "testintegrate">
<property name="second_client" value="levyant_cygwin_test"/>
<property name="second_client_root" value="C:\dev\test"/>
<property name="depot_file_spec" value="//depot/foobar"/>
<property name="depot_file_spec_2" value="//depot/hello"/>
<target name="testintegrate">
<p4change client="${second_client}"/>
<property name="change1" value="${p4.change}" />
<p4integrate client="${second_client}" change="${p4.change}" fromfile="${depot_file_spec}" tofile="${depot_file_spec_2}" forceintegrate="true" />
<p4resolve client="${second_client}" view="${depot_file_spec_2}" resolvemode="theirs"/>
<p4submit client="${second_client}" change="${p4.change}"/>
</target>
</project>

Loading…
Cancel
Save