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