From d76fda652ab6bb3f3840e8606f73d23307a33ca4 Mon Sep 17 00:00:00 2001 From: Jesse Stockall Date: Tue, 15 Apr 2003 04:26:52 +0000 Subject: [PATCH] Add ability to overwrite or skip writable files during 'get latest' or 'checkout' Add ability to specify timestamps for files retrieved during 'get latest' or 'checkout' Fix label length issues Other minor fixes unearthed after major refactoring of VSS tasks PR: #11562 #8451 #4387 #12793 #14174 #13532 #14463 Submitted by: Nigel Magnay, Keying Xi, and others git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274457 13f79535-47bb-0310-9956-ffa450edef68 --- .../testcases/taskdefs/optional/vss/vss.xml | 24 +- .../ant/taskdefs/optional/vss/MSVSS.java | 209 ++++++++++++++++-- .../ant/taskdefs/optional/vss/MSVSSADD.java | 3 +- .../taskdefs/optional/vss/MSVSSCHECKOUT.java | 45 +++- .../taskdefs/optional/vss/MSVSSCREATE.java | 9 - .../taskdefs/optional/vss/MSVSSConstants.java | 20 ++ .../ant/taskdefs/optional/vss/MSVSSGET.java | 34 ++- .../ant/taskdefs/optional/vss/MSVSSLABEL.java | 6 +- 8 files changed, 313 insertions(+), 37 deletions(-) diff --git a/src/etc/testcases/taskdefs/optional/vss/vss.xml b/src/etc/testcases/taskdefs/optional/vss/vss.xml index 96af4319c..87d4dd0b4 100644 --- a/src/etc/testcases/taskdefs/optional/vss/vss.xml +++ b/src/etc/testcases/taskdefs/optional/vss/vss.xml @@ -10,37 +10,43 @@ - + - + - + - + - + - + + + + + - + - + - + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSS.java b/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSS.java index 6cf2572eb..56cdf6747 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSS.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSS.java @@ -54,6 +54,7 @@ package org.apache.tools.ant.taskdefs.optional.vss; +import org.apache.tools.ant.types.EnumeratedAttribute; import java.io.File; import java.io.IOException; import java.text.DateFormat; @@ -126,10 +127,16 @@ public abstract class MSVSS extends Task implements MSVSSConstants { private boolean m_Writable = false; /** Fail on error defaults to true */ private boolean m_FailOnError = true; + /** Get local copy for checkout defaults to true */ + private boolean m_getLocalCopy = true; /** Number of days offset for History */ private int m_NumDays = Integer.MIN_VALUE; /** Date format for History */ private DateFormat m_DateFormat = DateFormat.getDateInstance(DateFormat.SHORT); + /** Timestamp for retreived files */ + private CurrentModUpdated m_timestamp = null; + /** Behaviour for writable files */ + private WritableFiles m_writablefiles = null; /** * Each sub-class must implemnt this method and return the constructed @@ -196,6 +203,15 @@ public abstract class MSVSS extends Task implements MSVSSConstants { m_serverPath = serverPath; } + /** + * Sets behaviour, whether task should fail if there is an error creating + * the project.; optional, default true + * @param failOnError True if task should fail on any error. + */ + public final void setFailOnError (boolean failOnError) { + m_FailOnError = failOnError; + } + /** * Executes the task.
* Builds a command line to execute ss.exe and then calls Exec's run method @@ -208,7 +224,7 @@ public abstract class MSVSS extends Task implements MSVSSConstants { Commandline commandLine = buildCmdLine(); result = run(commandLine); if (result != 0 && getFailOnError()) { - String msg = "Failed executing: " + commandLine.toString() + String msg = "Failed executing: " + formatCommandLine(commandLine) + " With a return code of " + result; throw new BuildException(msg, getLocation()); } @@ -292,6 +308,18 @@ public abstract class MSVSS extends Task implements MSVSSConstants { m_Writable = writable; } + protected void setInternalFileTimeStamp(CurrentModUpdated timestamp) { + m_timestamp = timestamp; + } + + protected void setInternalWritableFiles(WritableFiles files) { + m_writablefiles = files; + } + + protected void setInternalGetLocalCopy(boolean get) { + m_getLocalCopy = get; + } + /** * Gets the sscommand string. "ss" or "c:\path\to\ss" * @@ -344,10 +372,24 @@ public abstract class MSVSS extends Task implements MSVSSConstants { /** * Gets the label string. "-Lbuild1" * + * Max label length is 32 chars + * * @return An empty string if label is not set. */ protected String getLabel() { - return m_Label != null ? FLAG_LABEL + m_Label : ""; + if (m_Label != null) { + if (m_Label.length() > 31) { + String label = m_Label.substring(0, 30); + log("Label is longer than 31 characters, truncated to: " + label, Project.MSG_WARN); + return FLAG_LABEL + label; + } + else { + return FLAG_LABEL + m_Label; + } + } + else { + return ""; + } } /** @@ -363,18 +405,33 @@ public abstract class MSVSS extends Task implements MSVSSConstants { * Gets the version string. Returns the first specified of version "-V1.0", * date "-Vd01.01.01", label "-Vlbuild1". * - * @return An empty string if a version is not set. + * @return An empty string if a version, date and label are not set. */ - protected String getVersion() { + protected String getVersionDateLabel() { if (m_Version != null) { return FLAG_VERSION + m_Version; - } else if (m_Date != null) { + } + else if (m_Date != null) { return FLAG_VERSION_DATE + m_Date; - } else if (m_Label != null) { - return FLAG_VERSION_LABEL + m_Label; - } else { - return ""; } + else { + // Use getLabel() so labels longer then 30 char are truncated + // and the user is warned + String label = getLabel(); + if (! label.equals("")) { + return FLAG_VERSION_LABEL + label; + } + } + return ""; + } + + /** + * Gets the version string. + * + * @return An empty string if a version is not set. + */ + protected String getVersion() { + return m_Version != null ? FLAG_VERSION + m_Version : ""; } /** @@ -468,17 +525,37 @@ public abstract class MSVSS extends Task implements MSVSSConstants { return ""; } if (m_FromLabel != null && m_ToLabel != null) { + if (m_FromLabel.length() > 31) { + m_FromLabel = m_FromLabel.substring(0, 30); + log("FromLabel is longer than 31 characters, truncated to: " + + m_FromLabel, Project.MSG_WARN); + } + if (m_ToLabel.length() > 31) { + m_ToLabel = m_ToLabel.substring(0, 30); + log("ToLabel is longer than 31 characters, truncated to: " + + m_ToLabel, Project.MSG_WARN); + } return FLAG_VERSION_LABEL + m_ToLabel + VALUE_FROMLABEL + m_FromLabel; } else if (m_FromLabel != null) { + if (m_FromLabel.length() > 31) { + m_FromLabel = m_FromLabel.substring(0, 30); + log("FromLabel is longer than 31 characters, truncated to: " + + m_FromLabel, Project.MSG_WARN); + } return FLAG_VERSION + VALUE_FROMLABEL + m_FromLabel; } else { + if (m_ToLabel.length() > 31) { + m_ToLabel = m_ToLabel.substring(0, 30); + log("ToLabel is longer than 31 characters, truncated to: " + + m_ToLabel, Project.MSG_WARN); + } return FLAG_VERSION_LABEL + m_ToLabel; } } /** * Gets the Version date string. - * @return An empty string is neither Todate or from date are set. + * @return An empty string if neither Todate or from date are set. * @throws BuildException */ protected String getVersionDate() throws BuildException { @@ -511,13 +588,69 @@ public abstract class MSVSS extends Task implements MSVSSConstants { } /** - * Gets the value of the fail on error flag. This is only used by execute - * when checking the return code. + * Builds and returns the -G- flag if required. + * + * @return An empty string if get local copy is true. + */ + protected String getGetLocalCopy() { + return (! m_getLocalCopy) ? FLAG_NO_GET : ""; + } + + /** + * Gets the value of the fail on error flag. * - * @return True if the FailOnError flag has been set. + * @return True if the FailOnError flag has been set or if 'writablefiles=skip'. */ private boolean getFailOnError() { - return m_FailOnError; + return getWritableFiles().equals(WRITABLE_SKIP) ? false : m_FailOnError; + } + + + /** + * Gets the value set for the FileTimeStamp. + * if it equals "current" then we return -GTC + * if it equals "modified" then we return -GTM + * if it equals "updated" then we return -GTU + * otherwise we return -GTC + * + * @return The default file time flag, if not set. + */ + public String getFileTimeStamp() { + if (m_timestamp == null) { + return FLAG_FILETIME_DEF; + } + else if (m_timestamp.getValue().equals(TIME_MODIFIED)) { + return FLAG_FILETIME_MODIFIED; + } + else if (m_timestamp.getValue().equals(TIME_UPDATED)) { + return FLAG_FILETIME_UPDATED; + } + else { + return FLAG_FILETIME_DEF; + } + } + + + /** + * Gets the value to determine the behaviour when encountering writable files. + * @return An empty String, if not set. + */ + public String getWritableFiles() { + if (m_writablefiles == null) { + return ""; + } + else if (m_writablefiles.getValue().equals(WRITABLE_REPLACE)) { + return FLAG_REPLACE_WRITABLE; + } + else if (m_writablefiles.getValue().equals(WRITABLE_SKIP)) { + // ss.exe exits with '100', when files have been skipped + // so we have to ignore the failure + m_FailOnError = false; + return FLAG_SKIP_WRITABLE; + } + else { + return ""; + } } /** @@ -551,6 +684,8 @@ public abstract class MSVSS extends Task implements MSVSSConstants { exe.setAntRun(getProject()); exe.setWorkingDirectory(getProject().getBaseDir()); exe.setCommandline(cmd.getCommandline()); + // Use the OS launcher so we get environment variables + exe.setVMLauncher(false); return exe.execute(); } catch (IOException e) { throw new BuildException(e, getLocation()); @@ -576,4 +711,50 @@ public abstract class MSVSS extends Task implements MSVSSConstants { toDate = m_DateFormat.format(calend.getTime()); return toDate; } + + /** + * Changes the password to '***' so it isn't displayed on screen if the build fails + * + * @param cmd The command line to clean + * @return The command line as a string with out the password + */ + private String formatCommandLine(Commandline cmd) { + StringBuffer sBuff = new StringBuffer(cmd.toString()); + int indexUser = sBuff.indexOf(FLAG_LOGIN); + if (indexUser > 0) { + int indexPass = sBuff.indexOf(",", indexUser); + int indexAfterPass = sBuff.indexOf(" ", indexPass); + + for (int i = indexPass + 1; i < indexAfterPass; i++) { + sBuff.setCharAt(i, '*'); + } + } + return sBuff.toString(); + } + + /** + * Extention of EnumeratedAttribute to hold the values for file time stamp. + */ + public static class CurrentModUpdated extends EnumeratedAttribute { + /** + * Gets the list of allowable values. + * @return The values. + */ + public String[] getValues() { + return new String[] { TIME_CURRENT, TIME_MODIFIED, TIME_UPDATED }; + } + } + + /** + * Extention of EnumeratedAttribute to hold the values for writable filess. + */ + public static class WritableFiles extends EnumeratedAttribute { + /** + * Gets the list of allowable values. + * @return The values. + */ + public String[] getValues() { + return new String[] { WRITABLE_REPLACE, WRITABLE_SKIP, WRITABLE_FAIL }; + } + } } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSADD.java b/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSADD.java index ada2f00be..2f7c990b3 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSADD.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSADD.java @@ -125,7 +125,8 @@ public class MSVSSADD extends MSVSS { } /** - * Leave checked in files writable? Default: false. + * Sets behaviour, unset the READ-ONLY flag on files added to VSS.; + * optional, default false * @param writable The boolean value for writable. */ public final void setWritable(boolean writable) { diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCHECKOUT.java b/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCHECKOUT.java index 10b9fd977..424f68880 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCHECKOUT.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCHECKOUT.java @@ -98,9 +98,15 @@ public class MSVSSCHECKOUT extends MSVSS { // -R commandLine.createArgument().setValue(getRecursive()); // -V - commandLine.createArgument().setValue(getVersion()); + commandLine.createArgument().setValue(getVersionDateLabel()); // -Y commandLine.createArgument().setValue(getLogin()); + // -G + commandLine.createArgument().setValue(getFileTimeStamp()); + // -GWS or -GWR + commandLine.createArgument().setValue(getWritableFiles()); + // -G- + commandLine.createArgument().setValue(getGetLocalCopy()); return commandLine; } @@ -158,4 +164,41 @@ public class MSVSSCHECKOUT extends MSVSS { public void setAutoresponse(String response){ super.setInternalAutoResponse(response); } + + /** + * Set the option to the date and time given to the local copy.; optional + * + * Valid options are current, modified, or + * updated. Defaults to current. + * + * @param timestamp The file time stamping behaviour. + */ + public void setFileTimeStamp(CurrentModUpdated timestamp){ + super.setInternalFileTimeStamp(timestamp); + } + + /** + * Set the behaviour when local files are writable.; optional + * + * Valid options are replace, skip and fail. + * The default is fail + * + * Due to ss.exe returning with an exit code of '100' for both errors and when + * a file has been skipped, failonerror is set to false when using + * the skip option + * + * @param files The writable files behaviour + */ + public void setWritableFiles(WritableFiles files) { + super.setInternalWritableFiles(files); + } + + /** + * Set the behaviour to retrieve local copies during a checkout.; optional, Defaults to true. + * + * @param get The get local copy behaviour + */ + public void setGetLocalCopy(boolean get) { + super.setInternalGetLocalCopy(get); + } } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCREATE.java b/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCREATE.java index b429f4a1a..c19b4e911 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCREATE.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCREATE.java @@ -167,15 +167,6 @@ public class MSVSSCREATE extends MSVSS { super.setInternalQuiet(quiet); } - /** - * Sets behaviour, whether task should fail if there is an error creating - * the project.; optional, default true - * @param failOnError True if task should fail on any error. - */ - public final void setFailOnError (boolean failOnError) { - super.setInternalFailOnError(failOnError); - } - /** * Sets the autoresponce behaviour.; optional. *

diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSConstants.java b/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSConstants.java index b90f6a977..08f7a2758 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSConstants.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSConstants.java @@ -90,6 +90,20 @@ public interface MSVSSConstants { /** The default style flag */ String STYLE_DEFAULT = "default"; + /** The text for current (default) timestamp */ + String TIME_CURRENT = "current"; + /** The text for modified timestamp */ + String TIME_MODIFIED = "modified"; + /** The text for updated timestamp */ + String TIME_UPDATED = "updated"; + + /** The text for replacing writable files */ + String WRITABLE_REPLACE = "replace"; + /** The text for skiping writable files */ + String WRITABLE_SKIP = "skip"; + /** The text for failing on writable files */ + String WRITABLE_FAIL = "fail"; + String FLAG_LOGIN = "-Y"; String FLAG_OVERRIDE_WORKING_DIR = "-GL"; String FLAG_AUTORESPONSE_DEF = "-I-"; @@ -112,4 +126,10 @@ public interface MSVSSConstants { String FLAG_NO_FILE = "-F-"; String FLAG_BRIEF = "-B"; String FLAG_CODEDIFF = "-D"; + String FLAG_FILETIME_DEF = "-GTC"; + String FLAG_FILETIME_MODIFIED = "-GTM"; + String FLAG_FILETIME_UPDATED = "-GTU"; + String FLAG_REPLACE_WRITABLE = "-GWR"; + String FLAG_SKIP_WRITABLE = "-GWS"; + String FLAG_NO_GET = "-G-"; } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSGET.java b/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSGET.java index 2b221c360..886e13ae6 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSGET.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSGET.java @@ -157,11 +157,15 @@ public class MSVSSGET extends MSVSS { // -R commandLine.createArgument().setValue(getRecursive()); // -V - commandLine.createArgument().setValue(getVersion()); + commandLine.createArgument().setValue(getVersionDateLabel()); // -W commandLine.createArgument().setValue(getWritable()); // -Y commandLine.createArgument().setValue(getLogin()); + // -G + commandLine.createArgument().setValue(getFileTimeStamp()); + // -GWS or -GWR + commandLine.createArgument().setValue(getWritableFiles()); return commandLine; } @@ -235,4 +239,32 @@ public class MSVSSGET extends MSVSS { public void setAutoresponse(String response){ super.setInternalAutoResponse(response); } + + /** + * Set the behavior for timestamps of local files.; optional + * + * Valid options are current, modified, or + * updated. Defaults to current. + * + * @param timestamp The file time stamping behaviour. + */ + public void setFileTimeStamp(CurrentModUpdated timestamp) { + super.setInternalFileTimeStamp(timestamp); + } + + /** + * Set the behavior when local files are writable.; optional + * + * Valid options are replace, skip and fail. + * Defaults to fail + * + * Due to ss.exe returning with an exit code of '100' for both errors and when + * a file has been skipped, failonerror is set to false when using + * the skip option + * + * @param files + */ + public void setWritableFiles(WritableFiles files) { + super.setInternalWritableFiles(files); + } } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSLABEL.java b/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSLABEL.java index 45ba135c8..ad3cd75f5 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSLABEL.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSLABEL.java @@ -126,7 +126,9 @@ public class MSVSSLABEL extends MSVSS { if (getVsspath() == null) { throw new BuildException("vsspath attribute must be set!", getLocation()); } - if (getLabel() == "") { + + String label = getLabel(); + if (label == "") { String msg = "label attribute must be set!"; throw new BuildException(msg, getLocation()); } @@ -144,7 +146,7 @@ public class MSVSSLABEL extends MSVSS { // -I- or -I-Y or -I-N commandLine.createArgument().setValue(getAutoresponse()); // -L Specify the new label on the command line (instead of being prompted) - commandLine.createArgument().setValue(getLabel()); + commandLine.createArgument().setValue(label); // -V Label an existing file or project version commandLine.createArgument().setValue(getVersion()); // -Y