ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Everitt, Andrew" <Andrew.Ever...@gbr.xerox.com>
Subject RE: Call for patches
Date Tue, 23 May 2000 15:04:37 GMT
Craig,

Here is my code, it just builds a command line and then 'exec's the ss tool:

-----------------------------------------------
package com.xms.antext.taskdefs;

import org.apache.tools.ant.*;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;

/**
 * Task to interact with Microsoft Visual Source Safe. This task can take
the following
 * arguments:
 * <ul>
 * <li>command
 * <li>sourcedir
 * <li>destdir
 * <li>label
 * <li>recursive
 * </ul>
 * Of these arguments, the <b>command</b>, <b>sourcedir</b> and
<b>destdir</b> are required.
 *
 */

public class MSVSS extends Task {

    private static final int BUFFER_SIZE = 512;

    private String m_Command = null;
    private String m_SrcDir = null;
    private String m_DestDir = null;
    private String m_Label = null;
    private boolean m_Recursive = false;

    /**
     * Set the SourceSafe command to execute
     */
    public void setCommand(String command) {
        m_Command = command;
    }

    /**
     * Set the source dir.
     */
    public void setSrcdir(String srcDirName) {
        if ( srcDirName.startsWith("vss://") ) {
            m_SrcDir = srcDirName.substring(5);
        } else {
            m_SrcDir = project.translatePath(srcDirName);
        }
    }

    /**
     * Set the destination.
     */
    public void setDestdir(String destDirName) {
        if ( destDirName.startsWith("vss://") ) {  // a VSS path leave alone
            m_DestDir = destDirName.substring(5);
        } else {                        // translate for platform
            m_DestDir = project.translatePath(destDirName);
        }
    }

    /**
     * Set the labeled version to operate on in SourceSafe
     */
    public void setLabel(String label) {
        m_Label = label;
    }

    /**
     * Set behaviour recursive or non-recursive
     */
    public void setRecursive(String recursive) {
        m_Recursive = Project.toBoolean(recursive);
    }

    /**
     * Executes the task.
     */
    public void execute() throws BuildException {
        String commandLine = "";
        Process ssProc = null;
        int result = 0;

        // first off, make sure that we've got a srcdir and destdir

        if (m_Command == null || m_SrcDir == null || m_DestDir == null ) {
            String msg = "command, srcDir and destDir attributes must be
set!";
            throw new BuildException(msg);
        }

        // build the command line from what we got ...
        commandLine = "ss ";

        if (m_Command.equalsIgnoreCase("get")) {
            // create the destination dir ...
            File dir = project.resolveFile(m_DestDir);
            if (!dir.exists()) {
                boolean done = dir.mkdirs();
                if (done == false) {
                    String msg = "Directory " + m_DestDir + " creation was
not " +
                        "succesful for an unknown reason";
                    throw new BuildException(msg);
                }
                project.log("Created dir: " + dir.getAbsolutePath());
            }

            // build the command line ...
            commandLine += m_Command + " " +
                           "$" + m_SrcDir +  " ";

            if ( m_Recursive ) {
                commandLine += "-r ";
            }

            if ( (m_Label != null) && (!m_Label.equals("")) ) {
                commandLine += "-vl" + m_Label + " ";
            }

            commandLine += "-GL" + m_DestDir + " " +
                           "-I-";
        } else {
            String msg = "Unsupported vss command";
            throw new BuildException(msg);
        }

        try {
            project.log("Executing " + commandLine, Project.MSG_VERBOSE);
            ssProc = Runtime.getRuntime().exec(commandLine);

            // copy input and error to the output stream
            StreamPumper inputPumper =
                new StreamPumper(ssProc.getInputStream(), "vss", project,
null);
            StreamPumper errorPumper =
                new StreamPumper(ssProc.getErrorStream(), "vss:error",
project, null);

            // starts pumping away the generated output/error
            inputPumper.start();
            errorPumper.start();

            // Wait for everything to finish
            ssProc.waitFor();
            inputPumper.join();
            errorPumper.join();
            ssProc.destroy();

            // check its exit value
            int err = ssProc.exitValue();
            if (err != 0) {
                project.log("Result: " + err, "vss", Project.MSG_ERR);
            }

        } catch (java.io.IOException ioe) {
            project.log("Failed to execute SourceSafe command");
        } catch (InterruptedException ie) {
            project.log("Interrupted waiting for ss to complete");
        }

    }

    // Inner class for continually pumping the input stream during
    // Process's runtime.
    class StreamPumper extends Thread {
        private BufferedReader din;
        private String name;
        private boolean endOfStream = false;
        private int SLEEP_TIME = 5;
        private Project project;
        private PrintWriter fos;

        public StreamPumper(InputStream is, String name, Project project,
PrintWriter fos) {
            this.din     = new BufferedReader(new InputStreamReader(is));
            this.name    = name;
            this.project = project;
            this.fos     = fos;
        }

        public void pumpStream()
            throws IOException
        {
            byte[] buf = new byte[BUFFER_SIZE];
            if (!endOfStream) {
                String line = din.readLine();

                if (line != null) {
                    if (fos == null)
                        project.log(line, name, Project.MSG_INFO);
                    else
                        fos.println(line);
                } else {
                    endOfStream = true;
                }
            }
        }

        public void run() {
            try {
                try {
                    while (!endOfStream) {
                        pumpStream();
                        sleep(SLEEP_TIME);
                    }
                } catch (InterruptedException ie) {}
                din.close();
            } catch (IOException ioe) {}
        }

    } // finished class StreamPumper

}
------------------------------------------------

You would invoke it as follows:

<target name="init">
  <taskdef name="vss" classname="com.xms.antext.taskdefs.MSVSS"/>
</target>

<vss command="get"
     srcdir="vss://myproduct/com/xms/mypackage"
     destdir="${basedir}/src/com/xms/mypackage"
     recursive="true"
     label="v1.0"/>

I have ideas of extending this to support more of the available commands but
don't need them yet so I haven't done it ;-). It borrows the StreamPumper
from the exec task written by James Davidson to get the output from ss.exe
onto the console.

How did you do it??

Cheers,
Andi.

Mime
View raw message