From 9100b172d001c51542a9ab02cbe474f4c26baa2c Mon Sep 17 00:00:00 2001 From: epugh Date: Sat, 25 Oct 2003 18:33:14 +0000 Subject: [PATCH] Integrate cvslib to provide java based access to CVS. Requires jar file attached to JIRA issue MAVEN-968. http://jira.codehaus.org/secure/ViewIssue.jspa?key=MAVEN-968 git-svn-id: https://svn.apache.org/repos/asf/maven/maven-1/plugins/trunk@114231 13f79535-47bb-0310-9956-ffa450edef68 --- changelog/project.properties | 1 + changelog/project.xml | 18 +- .../maven/cvslib/CvsChangeLogGenerator.java | 263 ++++++----- .../apache/maven/cvslib/CvsConnection.java | 442 ++++++++++++++++++ .../apache/maven/cvslib/CvsLogListener.java | 113 +++++ .../cvslib/CvsChangeLogGeneratorTest.java | 6 +- .../maven/cvslib/CvsLogListenerTest.java | 110 +++++ changelog/xdocs/changes.xml | 6 + 8 files changed, 841 insertions(+), 118 deletions(-) create mode 100644 changelog/src/main/org/apache/maven/cvslib/CvsConnection.java create mode 100644 changelog/src/main/org/apache/maven/cvslib/CvsLogListener.java create mode 100644 changelog/src/test/org/apache/maven/cvslib/CvsLogListenerTest.java diff --git a/changelog/project.properties b/changelog/project.properties index d3d5d12f..57b7d586 100644 --- a/changelog/project.properties +++ b/changelog/project.properties @@ -6,3 +6,4 @@ maven.xdoc.version=${pom.currentVersion} maven.license.licenseFile=${basedir}/../../../LICENSE.txt maven.checkstyle.header.file=${basedir}/../../../LICENSE.txt maven.checkstyle.format = turbine +maven.junit.fork=true diff --git a/changelog/project.xml b/changelog/project.xml index 9148437f..ddabb2eb 100644 --- a/changelog/project.xml +++ b/changelog/project.xml @@ -5,7 +5,7 @@ 3 maven-changelog-plugin Maven Changelog Plug-in - 1.3 + 1.4-dev Produce SCM changelog reports http://maven.apache.org/reference/plugins/changelog/ @@ -35,6 +35,15 @@ Java Developer + + Eric Pugh + epugh + epugh@upstate.com + + + Java Developer + + Emmanuel Venisse evenisse @@ -55,7 +64,7 @@ - + ant 1.5.3-1 @@ -79,6 +88,11 @@ junit 3.8.1 + + netbeans + cvslib + 200310240100 + regexp 1.2 diff --git a/changelog/src/main/org/apache/maven/cvslib/CvsChangeLogGenerator.java b/changelog/src/main/org/apache/maven/cvslib/CvsChangeLogGenerator.java index 410f602c..d4e22efb 100644 --- a/changelog/src/main/org/apache/maven/cvslib/CvsChangeLogGenerator.java +++ b/changelog/src/main/org/apache/maven/cvslib/CvsChangeLogGenerator.java @@ -1,94 +1,87 @@ package org.apache.maven.cvslib; -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2002 The Apache Software Foundation. All rights - * reserved. - * +/* + * ==================================================================== The + * Apache Software License, Version 1.1 + * + * Copyright (c) 2002 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 acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache Maven" 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", - * "Apache Maven", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * 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. + * 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 acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if and + * wherever such third-party acknowledgments normally appear. + * 4. The names "Apache" and "Apache Software Foundation" and "Apache Maven" + * 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", "Apache + * Maven", nor may "Apache" appear in their name, without prior written + * permission of the Apache Software Foundation. + * + * 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 - * . - * + * + * 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 . + * * ==================================================================== */ -import java.io.InputStream; +import java.io.FileNotFoundException; import java.io.IOException; -import java.util.Date; +import java.io.InputStream; +import java.io.StringBufferInputStream; import java.text.SimpleDateFormat; -// commons imports +import java.util.Collection; +import java.util.Date; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -// maven imports import org.apache.maven.changelog.AbstractChangeLogGenerator; +import org.apache.maven.changelog.ChangeLogParser; import org.apache.maven.project.Repository; import org.apache.maven.util.AsyncStreamReader; -// ant imports import org.apache.tools.ant.types.Commandline; /** * A CVS implementation of the {@link org.apache.maven.changelog.ChangeLog} * interface. - * - * @task Check CVS exists first by running cvs -version instead of current hack + * + * * @author Glenn McAllister + * @author Eric Pugh * @author Jeff Martin * @author Jason van Zyl * @author dIon Gillard * @author Stefan Bodewig * @author Peter Donald * @author Pete Kazmier - * @version - * $Id: CvsChangeLogGenerator.java,v 1.6 2003/04/11 18:53:19 bwalding Exp $ + * @version $Id: CvsChangeLogGenerator.java,v 1.6 2003/04/11 18:53:19 bwalding + * Exp $ */ class CvsChangeLogGenerator extends AbstractChangeLogGenerator { /** Log */ - private static final Log LOG = LogFactory.getLog(CvsChangeLogGenerator.class); + private static final Log LOG = + LogFactory.getLog(CvsChangeLogGenerator.class); public static final int POS_SCM = 0; public static final int POS_SCM_TYPE = 1; @@ -97,19 +90,59 @@ class CvsChangeLogGenerator extends AbstractChangeLogGenerator public static final int POS_SCM_PATH = 4; public static final int POS_SCM_MODULE = 5; - /** - * @return the cvs command line to be executed. - */ + * Execute cvslib client driving the given parser. + * + * @param parser A {@link ChangeLogParser parser}to process the scm + * output. + * @return A collection of {@link ChangeLogEntry entries}parsed from the + * scm output. + * @throws IOException When there are issues executing scm. + * @see ChangeLogGenerator#getEntries(ChangeLogParser) + */ + public Collection getEntries(ChangeLogParser parser) throws IOException + { + if (parser == null) + { + throw new NullPointerException("parser cannot be null"); + } + + if (base == null) + { + throw new NullPointerException("basedir must be set"); + } + + if (!base.exists()) + { + throw new FileNotFoundException( + "Cannot find base dir " + base.getAbsolutePath()); + } + + clParser = parser; + CvsConnection connection = new CvsConnection(); + String[] args = getScmLogCommand().getArguments(); + CvsLogListener ml = new CvsLogListener(); + + CvsConnection.processCommand(args, this.changeLogExecutor.getBasedir().toString(), ml); + + entries = clParser.parse(new StringBufferInputStream(ml.getStdout().toString())); + + return entries; + } + /** + * @return the cvs command line to be executed. + */ protected Commandline getScmLogCommand() { String tokens[] = Repository.splitSCMConnection(getConnection()); - + if (!tokens[POS_SCM_TYPE].equals("cvs")) { - throw new IllegalArgumentException("repository connection string" + " does not specify 'cvs' as the scm"); + throw new IllegalArgumentException( + "repository connection string" + + " does not specify 'cvs' as the scm"); } - + Commandline command = new Commandline(); command.setExecutable("cvs"); @@ -120,26 +153,30 @@ class CvsChangeLogGenerator extends AbstractChangeLogGenerator // :pserver:anoncvs@cvs.apache.org:/home/cvspublic // use tokens 3+4+5 String connectionBuffer = ""; - + if (tokens[POS_SCM_SUBTYPE].equalsIgnoreCase("local")) { // use the local repository directory eg. '/home/cvspublic' connectionBuffer = tokens[POS_SCM_PATH]; } - else - { - if (tokens[POS_SCM_SUBTYPE].equalsIgnoreCase("lserver")) + else + { + if (tokens[POS_SCM_SUBTYPE].equalsIgnoreCase("lserver")) { //create the cvsroot as the local socket cvsroot - connectionBuffer = tokens[POS_SCM_USERHOST] + ":" + tokens[POS_SCM_PATH]; + connectionBuffer = + tokens[POS_SCM_USERHOST] + ":" + tokens[POS_SCM_PATH]; } - else + else { //create the cvsroot as the remote cvsroot connectionBuffer = - ":" + tokens[POS_SCM_SUBTYPE] - + ":" + tokens[POS_SCM_USERHOST] - + ":" + tokens[POS_SCM_PATH]; + ":" + + tokens[POS_SCM_SUBTYPE] + + ":" + + tokens[POS_SCM_USERHOST] + + ":" + + tokens[POS_SCM_PATH]; } } @@ -154,36 +191,37 @@ class CvsChangeLogGenerator extends AbstractChangeLogGenerator return command; } - /** - * Construct the CVS command-line argument that is used to specify - * the appropriate date range. - * - * @param before The starting point. - * @param to The ending point. - * @return A string that can be used to specify a date to a scm - * system. - */ + /** + * Construct the CVS command-line argument that is used to specify the + * appropriate date range. + * + * @param before The starting point. + * @param to The ending point. + * @return A string that can be used to specify a date to a scm system. + */ protected String getScmDateArgument(Date before, Date to) { SimpleDateFormat outputDate = new SimpleDateFormat("yyyy-MM-dd"); return "-d " + outputDate.format(before) + "<" + outputDate.format(to); } - /** - * Handle ChangeLogParser IOExceptions. - * - * @param ioe The IOException thrown. - * @throws IOException If the handler doesn't wish to handle the - * exception. - */ + /** + * Handle ChangeLogParser IOExceptions. + * + * @param ioe The IOException thrown. + * @throws IOException If the handler doesn't wish to handle the exception. + */ protected void handleParserException(IOException ioe) throws IOException { - if (ioe.getMessage().indexOf("CreateProcess") != -1 || ioe.getMessage().indexOf("cvs: not found") != -1) + if (ioe.getMessage().indexOf("CreateProcess") != -1 + || ioe.getMessage().indexOf("cvs: not found") != -1) { // can't find CVS on Win32 or Linux... if (LOG.isWarnEnabled()) { - LOG.warn("Unable to find cvs executable. " + "Changelog will be empty"); + LOG.warn( + "Unable to find cvs executable. " + + "Changelog will be empty"); } } else @@ -193,39 +231,40 @@ class CvsChangeLogGenerator extends AbstractChangeLogGenerator } /** - * Set the error stream for reading from cvs log. This stream will be read - * on a separate thread. - * @param is - an {@link java.io.InputStream} - */ + * Set the error stream for reading from cvs log. This stream will be read + * on a separate thread. + * + * @param is - an {@link java.io.InputStream} + */ public void setProcessErrorStream(InputStream is) { errorReader = new CvsAsyncErrorReader(is); } /** - * A private AsyncStreamReader class that "swallows" the "cvs server: - * Logging" lines. - */ + * A private AsyncStreamReader class that "swallows" the "cvs server: + * Logging" lines. + */ private static class CvsAsyncErrorReader extends AsyncStreamReader { /** - * The obvious constructor. - * - * @param anInputStream the input stream to consume - */ + * The obvious constructor. + * + * @param anInputStream the input stream to consume + */ public CvsAsyncErrorReader(InputStream anInputStream) { super(anInputStream); } /** - * If the line does not start with "cvs server: Logging", it's ok to - * consume it. - * - * @param line the line to check - * @return true if the line does not start with "cvs - * server: Logging" - */ + * If the line does not start with "cvs server: Logging", it's ok to + * consume it. + * + * @param line the line to check + * @return true if the line does not start with "cvs + * server: Logging" + */ protected boolean okToConsume(String line) { return !line.startsWith("cvs server: Logging"); diff --git a/changelog/src/main/org/apache/maven/cvslib/CvsConnection.java b/changelog/src/main/org/apache/maven/cvslib/CvsConnection.java new file mode 100644 index 00000000..75ca6b7a --- /dev/null +++ b/changelog/src/main/org/apache/maven/cvslib/CvsConnection.java @@ -0,0 +1,442 @@ +package org.apache.maven.cvslib; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 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 acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache Maven" 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", + * "Apache Maven", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * 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 + * . + * + * ==================================================================== + */ + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.netbeans.lib.cvsclient.CVSRoot; +import org.netbeans.lib.cvsclient.Client; +import org.netbeans.lib.cvsclient.admin.StandardAdminHandler; +import org.netbeans.lib.cvsclient.command.Command; +import org.netbeans.lib.cvsclient.command.CommandException; +import org.netbeans.lib.cvsclient.command.GlobalOptions; +import org.netbeans.lib.cvsclient.commandLine.CommandFactory; +import org.netbeans.lib.cvsclient.commandLine.GetOpt; +import org.netbeans.lib.cvsclient.connection.AuthenticationException; +import org.netbeans.lib.cvsclient.connection.Connection; +import org.netbeans.lib.cvsclient.connection.ConnectionFactory; +import org.netbeans.lib.cvsclient.connection.PServerConnection; +import org.netbeans.lib.cvsclient.connection.StandardScrambler; +import org.netbeans.lib.cvsclient.event.CVSListener; + +/** + * A Cvs connection that simulates a command line interface. + * + * @author Eric Pugh + */ +public class CvsConnection +{ + + /** Log */ + private static final Log LOG = + LogFactory.getLog(CvsConnection.class); + /** + * The path to the repository on the server + */ + private String repository; + + /** + * The local path to use to perform operations (the top level) + */ + private String localPath; + + /** + * The connection to the server + */ + private Connection connection; + + /** + * The client that manages interactions with the server + */ + private Client client; + + /** + * The global options being used. GlobalOptions are only global for a + * particular command. + */ + private GlobalOptions globalOptions; + + /** + * Execute a configured CVS command + * + * @param command the command to execute + * @throws CommandException if there is an error running the command + */ + public void executeCommand(Command command) + throws CommandException, AuthenticationException + { + client.executeCommand(command, globalOptions); + } + + public void setRepository(String repository) + { + this.repository = repository; + } + + public void setLocalPath(String localPath) + { + this.localPath = localPath; + } + + public void setGlobalOptions(GlobalOptions globalOptions) + { + this.globalOptions = globalOptions; + } + + /** + * Creates the connection and the client and connects. + */ + private void connect(CVSRoot root, String password) + throws IllegalArgumentException, AuthenticationException + { + connection = ConnectionFactory.getConnection(root); + if (CVSRoot.METHOD_PSERVER.equals(root.getMethod())) + { + ((PServerConnection) connection).setEncodedPassword(password); + } + connection.open(); + + client = new Client(connection, new StandardAdminHandler()); + client.setLocalPath(localPath); + } + + private void addListener(CVSListener listener) + { + if (client != null) + { + // add a listener to the client + client.getEventManager().addCVSListener(listener); + } + } + + + /** + * Obtain the CVS root, either from the -D option cvs.root or from the CVS + * directory + * + * @return the CVSRoot string + */ + private static String getCVSRoot(String workingDir) + { + String root = null; + BufferedReader r = null; + if (workingDir == null) + { + workingDir = System.getProperty("user.dir"); + } + try + { + File f = new File(workingDir); + File rootFile = new File(f, "CVS/Root"); + if (rootFile.exists()) + { + r = new BufferedReader(new FileReader(rootFile)); + root = r.readLine(); + } + } + catch (IOException e) + { + // ignore + } + finally + { + try + { + if (r != null) + r.close(); + } + catch (IOException e) + { + System.err.println("Warning: could not close CVS/Root file!"); + } + } + if (root == null) + { + root = System.getProperty("cvs.root"); + } + return root; + } + + /** + * Process global options passed into the application + * + * @param args the argument list, complete + * @param globalOptions the global options structure that will be passed to + * the command + */ + private static int processGlobalOptions( + String[] args, + GlobalOptions globalOptions) + { + final String getOptString = globalOptions.getOptString(); + GetOpt go = new GetOpt(args, getOptString); + int ch = -1; + boolean usagePrint = false; + while ((ch = go.getopt()) != GetOpt.optEOF) + { + //System.out.println("Global option '"+((char) ch)+"', + // '"+go.optArgGet()+"'"); + boolean success = + globalOptions.setCVSCommand((char) ch, go.optArgGet()); + if (!success) + usagePrint = true; + } + + return go.optIndexGet(); + } + + /** + * Lookup the password in the .cvspass file. This file is looked for in the + * user.home directory if the option cvs.passfile is not set + * + * @param CVSRoot the CVS root for which the password is being searched + * @return the password, scrambled + */ + private static String lookupPassword(String CVSRoot) + { + File passFile = + new File( + System.getProperty( + "cvs.passfile", + System.getProperty("user.home") + "/.cvspass")); + + BufferedReader reader = null; + String password = null; + + try + { + reader = new BufferedReader(new FileReader(passFile)); + String line; + while ((line = reader.readLine()) != null) + { + if (line.startsWith(CVSRoot)) + { + password = line.substring(CVSRoot.length() + 1); + break; + } + } + } + catch (IOException e) + { + LOG.error("Could not read password for host: " + e); + return null; + } + finally + { + if (reader != null) + { + try + { + reader.close(); + } + catch (IOException e) + { + LOG.error("Warning: could not close password file."); + } + } + } + if (password == null) + { + LOG.error( + "Didn't find password for CVSROOT '" + CVSRoot + "'."); + } + return password; + } + + /** + * Process the CVS command passed in args[] array with all necessary + * options. The only difference from main() method is, that this method + * does not exit the JVM and provides command output. + * + * @param args The command with options + * @param files The files to execute the command on. + * @param stdout The standard output of the command + */ + public static boolean processCommand( + String[] args, + String localPath, + CVSListener listener) + { + + // Set up the CVSRoot. Note that it might still be null after this + // call if the user has decided to set it with the -d command line + // global option + GlobalOptions globalOptions = new GlobalOptions(); + globalOptions.setCVSRoot(getCVSRoot(localPath)); + + // Set up any global options specified. These occur before the + // name of the command to run + int commandIndex = -1; + try + { + commandIndex = processGlobalOptions(args, globalOptions); + + } + catch (IllegalArgumentException e) + { + LOG.error("Invalid argument: " + e); + return false; + } + + // if we don't have a CVS root by now, the user has messed up + if (globalOptions.getCVSRoot() == null) + { + LOG.error( + "No CVS root is set. Use the cvs.root " + + "property, e.g. java -Dcvs.root=\":pserver:user@host:/usr/cvs\"" + + " or start the application in a directory containing a CVS subdirectory" + + " or use the -d command switch."); + return false; + } + + // parse the CVS root into its constituent parts + CVSRoot root = null; + final String cvsRoot = globalOptions.getCVSRoot(); + try + { + root = CVSRoot.parse(cvsRoot); + } + catch (IllegalArgumentException e) + { + LOG.error( + "Incorrect format for CVSRoot: " + + cvsRoot + + "\nThe correct format is: " + + "[:method:][[user][:password]@][hostname:[port]]/path/to/repository" + + "\nwhere \"method\" is pserver."); + return false; + } + + final String command = args[commandIndex]; + + // this is not login, but a 'real' cvs command, so construct it, + // set the options, and then connect to the server and execute it + + Command c = null; + try + { + c = + CommandFactory.getDefault().createCommand( + command, + args, + ++commandIndex, + globalOptions, + localPath); + } + catch (IllegalArgumentException e) + { + LOG.error("Illegal argument: " + e.getMessage()); + return false; + } + + + String password = null; + + if (CVSRoot.METHOD_PSERVER.equals(root.getMethod())) + { + password = root.getPassword(); + if (password != null) + { + password = StandardScrambler.getInstance().scramble(password); + } + else + { + password = lookupPassword(cvsRoot); + if (password == null) + { + password = StandardScrambler.getInstance().scramble(""); + // an empty password + } + } + } + CvsConnection cvsCommand = new CvsConnection(); + cvsCommand.setGlobalOptions(globalOptions); + cvsCommand.setRepository(root.getRepository()); + // the local path is just the path where we executed the + // command. This is the case for command-line CVS but not + // usually for GUI front-ends + cvsCommand.setLocalPath(localPath); + try + { + cvsCommand.connect(root, password); + + + cvsCommand.addListener(listener); + cvsCommand.executeCommand(c); + + } + catch (Exception t) + { + LOG.error("Error: " + t,t); + + return false; + } + finally + { + + } + return true; + } + + + +} diff --git a/changelog/src/main/org/apache/maven/cvslib/CvsLogListener.java b/changelog/src/main/org/apache/maven/cvslib/CvsLogListener.java new file mode 100644 index 00000000..bd329e90 --- /dev/null +++ b/changelog/src/main/org/apache/maven/cvslib/CvsLogListener.java @@ -0,0 +1,113 @@ +package org.apache.maven.cvslib; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 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 acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache Maven" 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", + * "Apache Maven", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * 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 + * . + * + * ==================================================================== + */ + +import org.netbeans.lib.cvsclient.event.CVSAdapter; +import org.netbeans.lib.cvsclient.event.MessageEvent; + +/** + * A basic implementation of a CVS listener. It merely saves up + * into StringBuffers the stdout and stderr printstreams. + * + * @author Eric Pugh + */ +public class CvsLogListener extends CVSAdapter +{ + private final StringBuffer taggedLine = new StringBuffer(); + private StringBuffer stdout = new StringBuffer(); + private StringBuffer stderr = new StringBuffer(); + + /** + * Called when the server wants to send a message to be displayed to the + * user. The message is only for information purposes and clients can + * choose to ignore these messages if they wish. + * + * @param e the event + */ + public void messageSent(MessageEvent e) + { + String line = e.getMessage(); + StringBuffer stream = e.isError() ? stderr : stdout; + + if (e.isTagged()) + { + String message = + MessageEvent.parseTaggedMessage(taggedLine, e.getMessage()); + if (message != null) + { + //stream.println(message); + stream.append(message+"\n"); + + } + } + else + { + //stream.println(line); + stream.append(line+"\n"); + + } + } + + /** + * @return Returns the standard output from cvs as a StringBuffer.. + */ + public StringBuffer getStdout() + { + return stdout; + } + +} \ No newline at end of file diff --git a/changelog/src/test/org/apache/maven/cvslib/CvsChangeLogGeneratorTest.java b/changelog/src/test/org/apache/maven/cvslib/CvsChangeLogGeneratorTest.java index cc1f97f0..0a766b40 100644 --- a/changelog/src/test/org/apache/maven/cvslib/CvsChangeLogGeneratorTest.java +++ b/changelog/src/test/org/apache/maven/cvslib/CvsChangeLogGeneratorTest.java @@ -56,8 +56,6 @@ package org.apache.maven.cvslib; * ==================================================================== */ -import java.util.ArrayList; -import java.util.List; import org.apache.maven.project.Repository; import org.apache.maven.util.EnhancedStringTokenizer; @@ -67,7 +65,7 @@ import junit.framework.TestCase; /** * @author Ben Walding - * @version $Id: CvsChangeLogGeneratorTest.java,v 1.5 2003/04/11 18:53:19 bwalding Exp $ + * @version $Id: CvsChangeLogGeneratorTest.java,v 1.6 2003/10/25 18:33:13 epugh Exp $ */ class ExposeGenerator extends CvsChangeLogGenerator { @@ -80,7 +78,7 @@ class ExposeGenerator extends CvsChangeLogGenerator /** * @author Ben Walding - * @version $Id: CvsChangeLogGeneratorTest.java,v 1.5 2003/04/11 18:53:19 bwalding Exp $ + * @version $Id: CvsChangeLogGeneratorTest.java,v 1.6 2003/10/25 18:33:13 epugh Exp $ */ public class CvsChangeLogGeneratorTest extends TestCase { diff --git a/changelog/src/test/org/apache/maven/cvslib/CvsLogListenerTest.java b/changelog/src/test/org/apache/maven/cvslib/CvsLogListenerTest.java new file mode 100644 index 00000000..12ac4f93 --- /dev/null +++ b/changelog/src/test/org/apache/maven/cvslib/CvsLogListenerTest.java @@ -0,0 +1,110 @@ +package org.apache.maven.cvslib; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 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 acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache Maven" 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", + * "Apache Maven", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * 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 + * . + */ + +import junit.framework.TestCase; + +import org.netbeans.lib.cvsclient.event.MessageEvent; + + +/** + * Test cases for {@link CvsLogListener} + * @author Eric Pugh + * @version $Id: CvsLogListenerTest.java,v 1.1 2003/10/25 18:33:13 epugh Exp $ + */ +public class CvsLogListenerTest extends TestCase +{ + + + /** + * Create a test with the given name + * @param testName the name of the test + */ + public CvsLogListenerTest(String testName) + { + super(testName); + } + + /** + * Test of listening to a regular output + * @throws Exception when there is an unexpected problem + */ + public void testNormalEvent() throws Exception + { + String MESSAGE = "I am a message"; + CvsLogListener listener = new CvsLogListener(); + MessageEvent me = new MessageEvent("souce",MESSAGE,false); + listener.messageSent(me); + assertTrue(listener.getStdout().indexOf(MESSAGE)>-1); + + } + + /** + * Test of listening to an error + * @throws Exception when there is an unexpected problem + */ + public void testErrorEvent() throws Exception + { + String MESSAGE = "I am a message"; + CvsLogListener listener = new CvsLogListener(); + MessageEvent me = new MessageEvent("souce",MESSAGE,true); + listener.messageSent(me); + assertTrue(listener.getStdout().indexOf(MESSAGE)==-1); + + } + + + +} diff --git a/changelog/xdocs/changes.xml b/changelog/xdocs/changes.xml index 78107a26..9110daf1 100644 --- a/changelog/xdocs/changes.xml +++ b/changelog/xdocs/changes.xml @@ -7,6 +7,12 @@ + + + Added java based CVS library using cvslib. Removed + requirement for cvs executable. + + MAVEN-811. Add support of IBM Rational ClearCase SCM.