You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by bu...@apache.org on 2003/01/27 15:50:15 UTC

DO NOT REPLY [Bug 11562] - Extra options to set Timestamp on VSSGET

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=11562>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=11562

Extra options to set Timestamp on VSSGET

cxi@gltg.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Extra command line switches |Extra options to set
                   |on VSSGET                   |Timestamp on VSSGET



------- Additional Comments From cxi@gltg.com  2003-01-27 14:50 -------
As described in the Fiann's original post, the default option for timestamp 
when getting files from VSS is set to the current date and time. However, a lot 
of times setting the time to the modified time is more desirable. 

According to Microsoft, the followings are the available options:
-GTC    Local copy is given the current date and time. 
-GTM    Local copy is given the date and time that the file was last modified, 
        not the current date and time. 
-GTU    Local copy is given the date and time that the file was last updated,
        not the current date and time. 

I modified MSVSS.java and MSVSSGET.java to take these options into 
consideration. The following changes have only been tested when no files are 
checked out by the user. There are more options available regarding how local
writable copies are handled. Please see 
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=4387 for more information. 

********************************************
*            MSVSS.java                    *                 
********************************************
package org.apache.tools.ant.taskdefs.optional.vss;



import org.apache.tools.ant.Task;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.Execute;
import org.apache.tools.ant.taskdefs.LogStreamHandler;
import org.apache.tools.ant.types.Commandline;

/**
 * A base class for creating tasks for executing commands on Visual SourceSafe.
 * <p>
 * The class extends the 'exec' task as it operates by executing the ss.exe 
program
 * supplied with SourceSafe. By default the task expects ss.exe to be in the 
path,
 * you can override this be specifying the ssdir attribute.
 * </p>
 * <p>
 * This class provides set and get methods for 'login' and 'vsspath' 
attributes. It
 * also contains constants for the flags that can be passed to SS.
 * </p>
 *
 * @author Craig Cottingham
 * @author Andrew Everitt
 */
public abstract class MSVSS extends Task {

    private String m_SSDir = "";
    private String m_vssLogin = null;
    private String m_vssPath = null;
    private String m_serverPath = null;

    /**
     * directory where <code>ss.exe</code> resides; optional.
     * By default the task expects it to be in the PATH.
     *
     * @param dir the directory containing ss.exe
     */
    public final void setSsdir(String dir) {
        m_SSDir = Project.translatePath(dir);
    }

    /**
     * Builds and returns the command string to execute ss.exe
     */
    public final String getSSCommand() {
        String toReturn = m_SSDir;
        if (!toReturn.equals("") && !toReturn.endsWith("\\")) {
            toReturn += "\\";
        }
        toReturn += SS_EXE;

        return toReturn;
    }

    /**
     * The login to use when accessing VSS, formatted as "username,password";
     * optional.
     * <p>
     * You can omit the password if your database is not password protected.
     *  if you have a password and omit it, Ant/VSS will hang.
     *
     * @param login the login string to use
     */
    public final void setLogin(String login) {
        m_vssLogin = login;
    }

    /**
     * @return the appropriate login command if the 'login' attribute was 
specified, otherwise an empty string
     */
    public void getLoginCommand(Commandline cmd) {
        if (m_vssLogin == null) {
            return;
        } else {
            cmd.createArgument().setValue(FLAG_LOGIN + m_vssLogin);
        }
    }

    /**
     * SourceSafe path which specifies the project/file(s) you wish to
     * perform the action on; required. You should not specify the leading 
dollar-sign -
     * it is prepended by Ant automatically.
     * <p>
     * Ant can't cope with a '$' sign in an attribute so we have to add it here.
     * Also we strip off any 'vss://' prefix which is an XMS special and should 
probably be removed!
     * @todo dont add a $ prefix if it has one
     * @param vssPath
     */
    public final void setVsspath(String vssPath) {
        if (vssPath.startsWith("vss://")) {
            m_vssPath = PROJECT_PREFIX + vssPath.substring(5);
        } else {
            m_vssPath = PROJECT_PREFIX + vssPath;
        }
    }

    /**
     * @return m_vssPath
     */
    public String getVsspath() {
        return m_vssPath;
    }

    /**
     * Set the directory where <code>srssafe.ini</code> resides; optional.
     * @param serverPath
     */
    public final void setServerpath(String serverPath) {
        m_serverPath = serverPath;
    }

    protected int run(Commandline cmd) {
        try {
            Execute exe = new Execute(new LogStreamHandler(this,
                                                           Project.MSG_INFO,
                                                           Project.MSG_WARN));

            // If location of ss.ini is specified we need to set the
            // environment-variable SSDIR to this value
            if (m_serverPath != null) {
                String[] env = exe.getEnvironment();
                if (env == null) {
                    env = new String[0];
                }
                String[] newEnv = new String[env.length + 1];
                for (int i = 0; i < env.length ; i++) {
                    newEnv[i] = env[i];
                }
                newEnv[env.length] = "SSDIR=" + m_serverPath;

                exe.setEnvironment(newEnv);
            }

            exe.setAntRun(project);
            exe.setWorkingDirectory(project.getBaseDir());
            exe.setCommandline(cmd.getCommandline());
            return exe.execute();
        } catch (java.io.IOException e) {
            throw new BuildException(e, location);
        }
    }

    /**
     * Constant for the thing to execute
     */
    private static final String SS_EXE = "ss";
    /** */
    public static final String PROJECT_PREFIX = "$";

    /**
     * The 'CP' command
     */
    public static final String COMMAND_CP = "CP";
    /**
     * The 'Add' command
     */
    public static final String COMMAND_ADD = "Add";
    /**
     * The 'Get' command
     */
    public static final String COMMAND_GET = "Get";
    /**
     * The 'Checkout' command
     */
    public static final String COMMAND_CHECKOUT = "Checkout";
    /**
     * The 'Checkin' command
     */
    public static final String COMMAND_CHECKIN = "Checkin";
    /**
     * The 'Label' command
     */
    public static final String COMMAND_LABEL = "Label";
    /**
     * The 'History' command
     */
    public static final String COMMAND_HISTORY = "History";
    /**
     * The 'Create' command
     */
    public static final String COMMAND_CREATE = "Create";


    /** */
    public static final String FLAG_LOGIN = "-Y";
    /** */
    public static final String FLAG_OVERRIDE_WORKING_DIR = "-GL";
    /** */
    public static final String FLAG_AUTORESPONSE_DEF = "-I-";
    /** */
    public static final String FLAG_AUTORESPONSE_YES = "-I-Y";
    /** */
    public static final String FLAG_AUTORESPONSE_NO = "-I-N";
    /** */
    public static final String FLAG_RECURSION = "-R";
    /** */
    public static final String FLAG_VERSION = "-V";
    /** */
    public static final String FLAG_VERSION_DATE = "-Vd";
    /** */
    public static final String FLAG_VERSION_LABEL = "-VL";
    /** */
    public static final String FLAG_WRITABLE = "-W";
    /** */
    public static final String VALUE_NO = "-N";
    /** */
    public static final String VALUE_YES = "-Y";
    /** */
    public static final String FLAG_QUIET = "-O-";

    public static final String FLAG_FILETIME_DEF = "-GTC";

    public static final String FLAG_FILETIME_MODIFIED = "-GTM";

    public static final String FLAG_FILETIME_UPDATED = "-GTU";
}

********************************************
*            MSVSSGET.java                 *                 
********************************************

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

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.Path;

import java.io.File;

/**
 * Perform Get commands to Microsoft Visual SourceSafe.
 * <p>
 * The following attributes are interpreted:
 * <table border="1">
 *   <tr>
 *     <th>Attribute</th>
 *     <th>Values</th>
 *     <th>Required</th>
 *   </tr>
 *   <tr>
 *      <td>login</td>
 *      <td>username,password</td>
 *      <td>No</td>
 *   </tr>
 *   <tr>
 *      <td>vsspath</td>
 *      <td>SourceSafe path</td>
 *      <td>Yes</td>
 *   </tr>
 *   <tr>
 *      <td>localpath</td>
 *      <td>Override the working directory and get to the specified path</td>
 *      <td>No</td>
 *   </tr>
 *   <tr>
 *      <td>writable</td>
 *      <td>true or false</td>
 *      <td>No</td>
 *   </tr>
 *   <tr>
 *      <td>recursive</td>
 *      <td>true or false</td>
 *      <td>No</td>
 *   </tr>
 *   <tr>
 *      <td>version</td>
 *      <td>a version number to get</td>
 *      <td>No</td>
 *   </tr>
 *   <tr>
 *      <td>date</td>
 *      <td>a date stamp to get at</td>
 *      <td>No</td>
 *   </tr>
 *   <tr>
 *      <td>label</td>
 *      <td>a label to get for</td>
 *      <td>No</td>
 *   </tr>
 *   <tr>
 *      <td>quiet</td>
 *      <td>suppress output (off by default)</td>
 *      <td>No</td>
 *   </tr>
 *   <tr>
 *      <td>autoresponse</td>
 *      <td>What to respond with (sets the -I option). By default, -I- is
 *      used; values of Y or N will be appended to this.</td>
 *      <td>No</td>
 *   </tr>
 *   <tr>
 *      <td>filetime</td>
 *      <td>What date time to give to the local copy.</td>
 *   </tr>
 * </table>
 * <p>Note that only one of version, date or label should be specified</p>
 *
 * @author Craig Cottingham
 * @author Andrew Everitt
 *
 * @ant.task name="vssget" category="scm"
 */
public class MSVSSGET extends MSVSS {

    private String m_LocalPath = null;
    private boolean m_Recursive = false;
    private boolean m_Writable = false;
    private String m_Version = null;
    private String m_Date = null;
    private String m_Label = null;
    private String m_AutoResponse = null;
    private boolean m_Quiet = false;
    private String m_FileTime = null;

    /**
     * Executes the task.
     * <p>
     * Builds a command line to execute ss and then calls Exec's run method
     * to execute the command line.
     */
    public void execute() throws BuildException {
        Commandline commandLine = new Commandline();
        int result = 0;

        // first off, make sure that we've got a command and a vssdir ...
        if (getVsspath() == null) {
            String msg = "vsspath attribute must be set!";
            throw new BuildException(msg, location);
        }

        // now look for illegal combinations of things ...

        // build the command line from what we got the format is
        // ss Get VSS items [-G] [-H] [-I-] [-N] [-O] [-R] [-V] [-W] [-Y] [-?]
        // as specified in the SS.EXE help
        commandLine.setExecutable(getSSCommand());
        commandLine.createArgument().setValue(COMMAND_GET);

        // VSS items
        commandLine.createArgument().setValue(getVsspath());
        // -GL
        getLocalpathCommand(commandLine);
        // -I- or -I-Y or -I-N
        getAutoresponse(commandLine);
        // -O-
        getQuietCommand(commandLine);
        // -R
        getRecursiveCommand(commandLine);
        // -V
        getVersionCommand(commandLine);
        // -W
        getWritableCommand(commandLine);
        // -Y
        getLoginCommand(commandLine);
        // -GTC or -GTM or -GTU
        getFileTimeCommand(commandLine);

        result = run(commandLine);
        if (result != 0) {
            String msg = "Failed executing: " + commandLine.toString();
            throw new BuildException(msg, location);
        }
    }

    /**
     * Override the working directory and get to the specified path; optional.
     */
    public void setLocalpath(Path localPath) {
        m_LocalPath = localPath.toString();
    }

    /**
     * Builds and returns the -GL flag command if required.
     * <p>
     * The localpath is created if it didn't exist
     */
    public void getLocalpathCommand(Commandline cmd) {
        if (m_LocalPath == null) {
            return;
        } else {
            // make sure m_LocalDir exists, create it if it doesn't
            File dir = project.resolveFile(m_LocalPath);
            if (!dir.exists()) {
                boolean done = dir.mkdirs();
                if (!done) {
                    String msg = "Directory " + m_LocalPath + " creation was 
not " +
                        "successful for an unknown reason";
                    throw new BuildException(msg, location);
                }
                project.log("Created dir: " + dir.getAbsolutePath());
            }

            cmd.createArgument().setValue(FLAG_OVERRIDE_WORKING_DIR + 
m_LocalPath);
        }
    }

    /**
     * Flag to tell the task to recurse down the tree;
     * optional, default false.
     */
    public void setRecursive(boolean recursive) {
        m_Recursive = recursive;
    }

    /**
     * @return the 'recursive' command if the attribute was 'true', otherwise 
an empty string
     */
    public void getRecursiveCommand(Commandline cmd) {
        if (!m_Recursive) {
            return;
        } else {
            cmd.createArgument().setValue(FLAG_RECURSION);
        }
    }

    /**
     * Flag to suppress output when true ; false by default.
     */
    public final void setQuiet (boolean quiet) {
        this.m_Quiet = quiet;
    }

    public void getQuietCommand (Commandline cmd) {
        if (m_Quiet) {
            cmd.createArgument().setValue (FLAG_QUIET);
        }
    }

    /**
     * make fetched files  writable; optional, default false.
     */
    public final void setWritable(boolean argWritable) {
        m_Writable = argWritable;
    }

    /**
     * @return the 'make writable' command if the attribute was 'true', 
otherwise an empty string
     */
    public void getWritableCommand(Commandline cmd) {
        if (!m_Writable) {
            return;
        } else {
            cmd.createArgument().setValue(FLAG_WRITABLE);
        }
    }

    /**
     * Set a version number to get;
     * optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
     * allowed.
     * <p>
     * ORIGINAL COMMENT THAT DOES NOT SEEM AT ALL VALID:
     * Note we assume that if the supplied string has the value "null" that 
something
     * went wrong and that the string value got populated from a null object. 
This
     * happens if a ant variable is used e.g. version="${ver_server}" when 
ver_server
     * has not been defined to ant!
     * NO, in this case the version string is "${ver_server}".
     * @todo fix this
     */
    public void setVersion(String version) {
        if (version.equals("") || version.equals("null")) {
            m_Version = null;
        } else {
            m_Version = version;
        }
    }

    /**
     * Set the date to get;
     * optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
     * allowed.
     * <p>
     * ORIGINAL COMMENT THAT DOES NOT SEEM AT ALL VALID:
     * Note we assume that if the supplied string has the value "null" that 
something
     * went wrong and that the string value got populated from a null object. 
This
     * happens if a ant variable is used e.g. date="${date}" when date
     * has not been defined to ant!
     * @todo fix this
     */
    public void setDate(String date) {
        if (date.equals("") || date.equals("null")) {
            m_Date = null;
        } else {
            m_Date = date;
        }
    }

    /**
     * Set the label to get;
     * optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
     * allowed.
     * <p>
     * Note we assume that if the supplied string has the value "null" that 
something
     * went wrong and that the string value got populated from a null object. 
This
     * happens if a ant variable is used e.g. label="${label_server}" when 
label_server
     * has not been defined to ant!
     */
    public void setLabel(String label) {
        if (label.equals("") || label.equals("null")) {
            m_Label = null;
        } else {
            m_Label = label;
        }
    }

    /**
     * Simple order of priority. Returns the first specified of version, date, 
label.
     * If none of these was specified returns ""
     */
    public void getVersionCommand(Commandline cmd) {

        if (m_Version != null) {
            cmd.createArgument().setValue(FLAG_VERSION + m_Version);
        } else if (m_Date != null) {
            cmd.createArgument().setValue(FLAG_VERSION_DATE + m_Date);
        } else if (m_Label != null) {
            cmd.createArgument().setValue(FLAG_VERSION_LABEL + m_Label);
        }
    }

    /**
     * What to respond with (sets the -I option). By default, -I- is
     * used; values of Y or N will be appended to this.
     */
    public void setAutoresponse(String response){
        if (response.equals("") || response.equals("null")) {
            m_AutoResponse = null;
        } else {
            m_AutoResponse = response;
        }
    }

    /**
     * Checks the value set for the autoResponse.
     * if it equals "Y" then we return -I-Y
     * if it equals "N" then we return -I-N
     * otherwise we return -I
     */
    public void getAutoresponse(Commandline cmd) {

        if (m_AutoResponse == null) {
            cmd.createArgument().setValue(FLAG_AUTORESPONSE_DEF);
        } else if (m_AutoResponse.equalsIgnoreCase("Y")) {
            cmd.createArgument().setValue(FLAG_AUTORESPONSE_YES);

        } else if (m_AutoResponse.equalsIgnoreCase("N")) {
            cmd.createArgument().setValue(FLAG_AUTORESPONSE_NO);
        } else {
            cmd.createArgument().setValue(FLAG_AUTORESPONSE_DEF);
        } // end of else

    }

    /**
     * Set the option to the date and time given to the local copy
     * optional, only one of <tt>current</tt>, <tt>modified</tt>, or
     * <tt>updated</tt> allowed. The default is <tt>current</tt>.
     */
    public void setFileTime(String fileTime){
        if (fileTime.equals("") || fileTime.equals("null")) {
            m_FileTime = null;
        } else {
            m_FileTime = fileTime;
        }
    }

    /**
     * Checks the value set for the fileTime.
     * 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
     */
    public void getFileTimeCommand(Commandline cmd) {

        if (m_FileTime == null) {
            cmd.createArgument().setValue(FLAG_FILETIME_DEF);
        } else if (m_FileTime.equalsIgnoreCase("modified")) {
            cmd.createArgument().setValue(FLAG_FILETIME_MODIFIED);
        } else if (m_FileTime.equalsIgnoreCase("updated")) {
            cmd.createArgument().setValue(FLAG_FILETIME_UPDATED);
        } else {
            cmd.createArgument().setValue(FLAG_FILETIME_DEF);
        } // end of else

    }
}



Note if you already have local copy that has a newer timestamp than the 
modified timestamp in VSS, I don't think VSS will get the files. So you might 
want to call an ant clean task to delete the local copies before you use this.

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>