p4 repository and report on files that still not under revision control. PR: 13928 Submitted by: Miha git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@273928 13f79535-47bb-0310-9956-ffa450edef68master
@@ -75,10 +75,15 @@ You will also need the Perforce client executable (p4 or p4.exe but not p4win.ex | |||||
<td>Revert files</td> | <td>Revert files</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<tr> | |||||
<td><a href="#p4add">P4Add</a></td> | <td><a href="#p4add">P4Add</a></td> | ||||
<td>Add files</td> | <td>Add files</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td><a href="#p4fstat">P4Fstat</a></td> | |||||
<td>Show differences between local repository and p4 repository</td> | |||||
</tr> | |||||
</table> | </table> | ||||
<h3>General P4 Properties</h3> | <h3>General P4 Properties</h3> | ||||
@@ -566,6 +571,52 @@ and submit | |||||
<p4add> | <p4add> | ||||
<p4submit change="${p4.change}"/> | <p4submit change="${p4.change}"/> | ||||
</pre> | </pre> | ||||
<hr> | |||||
<h2><a name="p4fstat">P4Fstat</a></h2> | |||||
<h3>Description:</h3> | |||||
<p> | |||||
Lists files under Perforce control and files not under Perforce control in one or several filesets | |||||
</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">showfilter</td> | |||||
<td valign="top">should be one of | |||||
<table border="1"> | |||||
<tr><td>value</td><td>description</td></tr> | |||||
<tr><td>"all"</td><td>list all files, first the ones which are under Perforce control, then the others</td></tr> | |||||
<tr><td>"existing"</td><td>list only files under Perforce control</td></tr> | |||||
<tr><td>"non-existing"</td><td>list only files which are not under Perforce control</td></tr></table> | |||||
</td> | |||||
<td valign="top" align="center">Yes</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">fileset</td> | |||||
<td valign="top">one or several <a href="../CoreTypes/fileset.html">fileset(s)</a></td> | |||||
<td valign="top" align="center">yes (at least one fileset is needed)</td> | |||||
</tr> | |||||
</table> | |||||
Several nested filesets can be used with P4Fstat, one should be there at least. | |||||
<h3>Examples</h3> | |||||
will list all the files under C:\dev\gnu\depot, sorted by under Perforce or not under Perforce<br> | |||||
<pre> | |||||
<project name="p4fstat" default="p4fstat" basedir="C:\dev\gnu"> | |||||
<target name="p4fstat" > | |||||
<p4fstat showfilter="all"> | |||||
<fileset dir="depot" includes="**/*"/> | |||||
</p4fstat> | |||||
</target> | |||||
</project></p> | |||||
</pre> | |||||
<h2><a name="changes">Change History</a></h2> | <h2><a name="changes">Change History</a></h2> | ||||
<table border="1" cellpadding="2" cellspacing="0"> | <table border="1" cellpadding="2" cellspacing="0"> | ||||
@@ -588,10 +639,11 @@ and submit | |||||
Refactored exec'ing code</td> | Refactored exec'ing code</td> | ||||
</tr> | </tr> | ||||
<tr> | <tr> | ||||
<td valign="top">Nov 2002</td> | |||||
<td valign="top">Jan 2003</td> | |||||
<td valign="top">V1.2</td> | <td valign="top">V1.2</td> | ||||
<td valign="top">Added globalopts to P4Base to allow<br> | |||||
additional global options to be set.</td> | |||||
<td valign="top">Added globalopts to P4Base to allow | |||||
additional global options to be set.<br> | |||||
Added p4fstat task</td> | |||||
</tr> | </tr> | ||||
</table> | </table> | ||||
<hr> | <hr> | ||||
@@ -0,0 +1,97 @@ | |||||
/* | |||||
* The Apache Software License, Version 1.1 | |||||
* | |||||
* Copyright (c) 2003 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/>. | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs.optional.perforce; | |||||
import org.apache.tools.ant.BuildException; | |||||
import org.apache.tools.ant.Project; | |||||
import org.apache.oro.text.perl.Perl5Util; | |||||
import java.util.ArrayList; | |||||
/** | |||||
* FStatP4OutputHandler - spezialied Perforce output handler | |||||
* able to sort files recognized as managed by Perforce and files not | |||||
* managed by Perforce in the output | |||||
* | |||||
* @author <A HREF="mailto:miha@softhome.net">Miha</A> | |||||
*/ | |||||
class FStatP4OutputHandler extends P4HandlerAdapter { | |||||
private P4Fstat parent; | |||||
private ArrayList existing = new ArrayList(); | |||||
private ArrayList nonExisting = new ArrayList(); | |||||
private static Perl5Util util = new Perl5Util(); | |||||
public FStatP4OutputHandler(P4Fstat parent) { | |||||
this.parent = parent; | |||||
} | |||||
public void process(String line) throws BuildException { | |||||
if (util.match("/^... clientFile (.+)$/", line)) { | |||||
String f = util.group(1); | |||||
existing.add(f); | |||||
} else if (util.match("/^(.+) - no such file/", line)) { | |||||
String f = util.group(1); | |||||
nonExisting.add(f); | |||||
} | |||||
parent.log(parent.util.substitute("s/^.*: //", line), | |||||
Project.MSG_VERBOSE); | |||||
} | |||||
public ArrayList getExisting() { | |||||
return existing; | |||||
} | |||||
public ArrayList getNonExisting() { | |||||
return nonExisting; | |||||
} | |||||
} |
@@ -0,0 +1,212 @@ | |||||
/* | |||||
* The Apache Software License, Version 1.1 | |||||
* | |||||
* Copyright (c) 2003 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 java.io.File; | |||||
import java.util.Vector; | |||||
import java.util.ArrayList; | |||||
import org.apache.tools.ant.BuildException; | |||||
import org.apache.tools.ant.DirectoryScanner; | |||||
import org.apache.tools.ant.Project; | |||||
import org.apache.tools.ant.types.FileSet; | |||||
/** | |||||
* P4Fstat - find out which files are under Perforce control and which are not. | |||||
* | |||||
* <br><b>Example Usage:</b><br> | |||||
* <pre> | |||||
* <project name="p4fstat" default="p4fstat" basedir="C:\dev\gnu"> | |||||
* <target name="p4fstat" > | |||||
* <p4fstat showfilter="all"> | |||||
* <fileset dir="depot" includes="**\/*"/> | |||||
* </p4fstat> | |||||
* </target> | |||||
* </project> | |||||
* </pre> | |||||
* | |||||
* @author <A HREF="mailto:miha@softhome.net">Miha</A> | |||||
* @author <A HREF="mailto:leslie.hughes@rubus.com">Les Hughes</A> | |||||
* @author <A HREF="mailto:ashundi@tibco.com">Anli Shundi</A> | |||||
*/ | |||||
public class P4Fstat extends P4Base { | |||||
private int changelist; | |||||
private String addCmd = ""; | |||||
private Vector filesets = new Vector(); | |||||
private int cmdLength = 300; | |||||
private static final int SHOW_ALL = 0; | |||||
private static final int SHOW_EXISTING = 1; | |||||
private static final int SHOW_NON_EXISTING = 2; | |||||
private int show = SHOW_NON_EXISTING; | |||||
private FStatP4OutputHandler handler; | |||||
private StringBuffer filelist; | |||||
private int fileNum = 0; | |||||
private int doneFileNum = 0; | |||||
private boolean debug = false; | |||||
private static final String EXISTING_HEADER | |||||
= "Following files exist in perforce"; | |||||
private static final String NONEXISTING_HEADER | |||||
= "Following files do not exist in perforce"; | |||||
public void setShowFilter(String filter) { | |||||
if (filter.equalsIgnoreCase("all")) { | |||||
show = SHOW_ALL; | |||||
} else if (filter.equalsIgnoreCase("existing")) { | |||||
show = SHOW_EXISTING; | |||||
} else if (filter.equalsIgnoreCase("non-existing")) { | |||||
show = SHOW_NON_EXISTING; | |||||
} else { | |||||
throw new BuildException("P4Fstat: ShowFilter should be one of: " | |||||
+ "all, existing, non-existing"); | |||||
} | |||||
} | |||||
public void setChangelist(int changelist) throws BuildException { | |||||
if (changelist <= 0) { | |||||
throw new BuildException("P4FStat: Changelist# should be a " | |||||
+ "positive number"); | |||||
} | |||||
this.changelist = changelist; | |||||
} | |||||
public void addFileset(FileSet set) { | |||||
filesets.addElement(set); | |||||
} | |||||
public void execute() throws BuildException { | |||||
handler = new FStatP4OutputHandler(this); | |||||
if (P4View != null) { | |||||
addCmd = P4View; | |||||
} | |||||
P4CmdOpts = (changelist > 0) ? ("-c " + changelist) : ""; | |||||
filelist = new StringBuffer(); | |||||
for (int i = 0; i < filesets.size(); i++) { | |||||
FileSet fs = (FileSet) filesets.elementAt(i); | |||||
DirectoryScanner ds = fs.getDirectoryScanner(getProject()); | |||||
//File fromDir = fs.getDir(project); | |||||
String[] srcFiles = ds.getIncludedFiles(); | |||||
fileNum = srcFiles.length; | |||||
if (srcFiles != null) { | |||||
for (int j = 0; j < srcFiles.length; j++) { | |||||
File f = new File(ds.getBasedir(), srcFiles[j]); | |||||
filelist.append(" ").append('"').append(f.getAbsolutePath()).append('"'); | |||||
doneFileNum++; | |||||
if (filelist.length() > cmdLength) { | |||||
execP4Fstat(filelist); | |||||
filelist.setLength(0); | |||||
} | |||||
} | |||||
if (filelist.length() > 0) { | |||||
execP4Fstat(filelist); | |||||
} | |||||
} else { | |||||
log("No files specified to add!", Project.MSG_WARN); | |||||
} | |||||
} | |||||
if (show == SHOW_ALL || show == SHOW_EXISTING) { | |||||
printRes(handler.getExisting(), EXISTING_HEADER); | |||||
} | |||||
if (show == SHOW_ALL || show == SHOW_NON_EXISTING) { | |||||
printRes(handler.getNonExisting(), NONEXISTING_HEADER); | |||||
} | |||||
} | |||||
public int getLengthOfTask() { | |||||
return fileNum; | |||||
} | |||||
int getPasses() { | |||||
return filesets.size(); | |||||
} | |||||
private void printRes(ArrayList ar, String header) { | |||||
log(header, Project.MSG_INFO); | |||||
for (int i = 0; i < ar.size(); i++) { | |||||
log((String) ar.get(i), Project.MSG_INFO); | |||||
} | |||||
} | |||||
private void execP4Fstat(StringBuffer list) { | |||||
if (debug) { | |||||
log("Executing fstat " + P4CmdOpts + " " + addCmd + list + "\n", | |||||
Project.MSG_INFO); | |||||
} | |||||
execP4Command("fstat " + P4CmdOpts + " " + addCmd + list, handler); | |||||
} | |||||
} |