You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ro...@apache.org on 2003/11/03 22:33:36 UTC
cvs commit: jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli2 SourceDestArgument.java
roxspring 2003/11/03 13:33:36
Added: cli/src/test/org/apache/commons/cli2/apps CpTest.java
cli/src/java/org/apache/commons/cli2 SourceDestArgument.java
Log:
Added application test for the unix "cp" command.
Also added example SourceDestArgument implementation.
Revision Changes Path
1.1 jakarta-commons-sandbox/cli/src/test/org/apache/commons/cli2/apps/CpTest.java
Index: CpTest.java
===================================================================
/*
* $Header: /home/cvs/jakarta-commons-sandbox/cli/src/test/org/apache/commons/cli2/apps/CpTest.java,v 1.1 2003/11/03 21:33:36 roxspring Exp $
* $Revision: 1.1 $
* $Date: 2003/11/03 21:33:36 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 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 acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" 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"
* nor may "Apache" appear in their names without prior written
* permission of the Apache GroupImpl.
*
* 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
* <http://www.apache.org/>.
*
*/
package org.apache.commons.cli2.apps;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.commons.cli2.Argument;
import org.apache.commons.cli2.ArgumentBuilder;
import org.apache.commons.cli2.ArgumentImpl;
import org.apache.commons.cli2.CommandLine;
import org.apache.commons.cli2.CommandLineParser;
import org.apache.commons.cli2.DefaultOptionBuilder;
import org.apache.commons.cli2.Group;
import org.apache.commons.cli2.GroupBuilder;
import org.apache.commons.cli2.HelpFormatter;
import org.apache.commons.cli2.MissingValueException;
import org.apache.commons.cli2.Option;
import org.apache.commons.cli2.OptionException;
import org.apache.commons.cli2.SourceDestArgument;
/**
* <p>
* Test the <code>cp</code> command. Duplicated Option types
* are not tested e.g. -a and -d are the same Option type.
* </p>
*
* <p>
* The following is the man output for 'cp'. See http://www.rt.com/man/cp.1.html.
* </p>
*
* <pre>
* CP(1) FSF CP(1)
*
* NAME
* cp - copy files and directories
*
* SYNOPSIS
* cp [OPTION]... SOURCE DEST
* cp [OPTION]... SOURCE... DIRECTORY
*
* DESCRIPTION
* Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.
*
* -a, --archive
* same as -dpR
*
* -b, --backup
* make backup before removal
*
* -d, --no-dereference
* preserve links
*
* -f, --force
* remove existing destinations, never prompt
*
* -i, --interactive
* prompt before overwrite
*
* -l, --link
* link files instead of copying
*
* -p, --preserve
* preserve file attributes if possible
*
* -P, --parents
* append source path to DIRECTORY
*
* -r copy recursively, non-directories as files
*
* --sparse=WHEN
* control creation of sparse files
*
* -R, --recursive
* copy directories recursively
*
* -s, --symbolic-link
* make symbolic links instead of copying
*
* -S, --suffix=SUFFIX
* override the usual backup suffix
*
* -u, --update
* copy only when the SOURCE file is newer than the
* destination file or when the destination file is
* missing
*
* -v, --verbose
* explain what is being done
*
* -V, --version-control=WORD
* override the usual version control
*
* -x, --one-file-system
* stay on this file system
*
* --help display this help and exit
*
* --version
* output version information and exit
*
* By default, sparse SOURCE files are detected by a crude
* heuristic and the corresponding DEST file is made sparse
* as well. That is the behavior selected by --sparse=auto.
* Specify --sparse=always to create a sparse DEST file when-
* ever the SOURCE file contains a long enough sequence of
* zero bytes. Use --sparse=never to inhibit creation of
* sparse files.
*
* The backup suffix is ~, unless set with SIMPLE_BACKUP_SUF-
* FIX. The version control may be set with VERSION_CONTROL,
* values are:
*
* t, numbered
* make numbered backups
*
* nil, existing
* numbered if numbered backups exist, simple other-
* wise
*
* never, simple
* always make simple backups
*
* As a special case, cp makes a backup of SOURCE when the
* force and backup options are given and SOURCE and DEST are
* the same name for an existing, regular file. * </pre>
* </pre>
*
* @author Rob Oxspring
* @author John Keyes
*/
public class CpTest extends TestCase
{
/** Option Builder */
private static final DefaultOptionBuilder oBuilder =
new DefaultOptionBuilder();
/** Argument Builder */
private static final ArgumentBuilder aBuilder = new ArgumentBuilder();
/** Group Builder */
private static final GroupBuilder gBuilder = new GroupBuilder();
private Group options;
public static Test suite()
{
return new TestSuite(CpTest.class);
}
private ArgumentImpl source;
private ArgumentImpl dest;
private Argument targets;
private Option archive;
private Option backup;
private Option noDereference;
private Option force;
private Option interactive;
private Option link;
private Option preserve;
private Option parents;
private Option recursive1;
private Option sparse;
private Option recursive2;
private Option symbolicLink;
private Option suffix;
private Option update;
private Option verbose;
private Option versionControl;
private Option oneFileSystem;
private Option help;
private Option version;
public void setUp() throws OptionException
{
source =
(ArgumentImpl)aBuilder.withName("SOURCE").withMinimum(1).create();
dest =
(ArgumentImpl)aBuilder
.withName("DEST")
.withMinimum(1)
.withMaximum(1)
.create();
targets = new SourceDestArgument(source, dest);
archive =
oBuilder
.withShortName("a")
.withLongName("archive")
.withDescription("same as -dpR")
.create();
backup =
oBuilder
.withShortName("b")
.withLongName("backup")
.withDescription("make backup before removal")
.create();
noDereference =
oBuilder
.withShortName("d")
.withLongName("no-dereference")
.withDescription("preserve links")
.create();
force =
oBuilder
.withShortName("f")
.withLongName("force")
.withDescription("remove existing destinations, never prompt")
.create();
interactive =
oBuilder
.withShortName("i")
.withLongName("interactive")
.withDescription("prompt before overwrite")
.create();
link =
oBuilder
.withShortName("l")
.withLongName("link")
.withDescription("link files instead of copying")
.create();
preserve =
oBuilder
.withShortName("p")
.withLongName("preserve")
.withDescription("preserve file attributes if possible")
.create();
parents =
oBuilder
.withShortName("P")
.withLongName("parents")
.withDescription("append source path to DIRECTORY")
.create();
recursive1 =
oBuilder
.withShortName("r")
.withDescription("copy recursively, non-directories as files")
.create();
sparse =
oBuilder
.withLongName("sparse")
.withDescription("control creation of sparse files")
.withArgument(
aBuilder
.withName("WHEN")
.withMinimum(1)
.withMaximum(1)
.withInitialSeparator('=')
.create())
.create();
recursive2 =
oBuilder
.withShortName("R")
.withLongName("recursive")
.withDescription("copy directories recursively")
.create();
symbolicLink =
oBuilder
.withShortName("s")
.withLongName("symbolic-link")
.withDescription("make symbolic links instead of copying")
.create();
suffix =
oBuilder
.withShortName("S")
.withLongName("suffix")
.withDescription("override the usual backup suffix")
.withArgument(
aBuilder
.withName("SUFFIX")
.withMinimum(1)
.withMaximum(1)
.create())
.create();
update =
oBuilder
.withShortName("u")
.withLongName("update")
.withDescription("copy only when the SOURCE file is newer than the destination file or when the destination file is missing")
.create();
verbose =
oBuilder
.withShortName("v")
.withLongName("verbose")
.withDescription("explain what is being done")
.create();
versionControl =
oBuilder
.withShortName("V")
.withLongName("version-contol")
.withDescription("explain what is being done")
.withArgument(
aBuilder
.withName("WORD")
.withInitialSeparator('=')
.withMinimum(1)
.withMaximum(1)
.create())
.create();
oneFileSystem =
oBuilder
.withShortName("x")
.withLongName("one-file-system")
.withDescription("stay on this file system")
.create();
help =
oBuilder
.withLongName("help")
.withDescription("display this help and exit")
.create();
version =
oBuilder
.withLongName("version")
.withDescription("output version information and exit")
.create();
options =
gBuilder
.withOption(archive)
.withOption(backup)
.withOption(noDereference)
.withOption(force)
.withOption(interactive)
.withOption(link)
.withOption(preserve)
.withOption(parents)
.withOption(recursive1)
.withOption(sparse)
.withOption(recursive2)
.withOption(symbolicLink)
.withOption(suffix)
.withOption(update)
.withOption(verbose)
.withOption(versionControl)
.withOption(oneFileSystem)
.withOption(help)
.withOption(version)
.withOption(targets)
.withName("OPTIONS")
.create();
}
public void testNoSource() throws OptionException
{
CommandLineParser parser = new CommandLineParser();
parser.setGroup(options);
try
{
parser.parse(new String[0]);
} catch (MissingValueException mve)
{
assertEquals(
"Missing value(s) SOURCE [SOURCE ...]",
mve.getMessage());
}
}
public void testOneSource() throws OptionException, IOException
{
final String[] args = new String[] { "source1", "dest1" };
final CommandLineParser parser = new CommandLineParser();
parser.setGroup(options);
final CommandLine commandLine = parser.parse(args);
assertTrue(commandLine.getValues(source).contains("source1"));
assertEquals(1, commandLine.getValues(source).size());
assertTrue(commandLine.getValues(dest).contains("dest1"));
assertEquals(1, commandLine.getValues(dest).size());
}
public void testMultiSource() throws OptionException
{
final String[] args =
new String[] { "source1", "source2", "source3", "dest1" };
final CommandLineParser parser = new CommandLineParser();
parser.setGroup(options);
final CommandLine commandLine = parser.parse(args);
assertTrue(commandLine.getValues(source).contains("source1"));
assertTrue(commandLine.getValues(source).contains("source2"));
assertTrue(commandLine.getValues(source).contains("source3"));
assertEquals(3, commandLine.getValues(source).size());
assertTrue(commandLine.getValues(dest).contains("dest1"));
assertEquals(1, commandLine.getValues(dest).size());
}
public void testHelp() throws OptionException, IOException {
final StringWriter out = new StringWriter();
final HelpFormatter helpFormatter = new HelpFormatter();
helpFormatter.setGroup(options);
helpFormatter.setPrintWriter(new PrintWriter(out));
helpFormatter.print();
final BufferedReader in = new BufferedReader(new StringReader(out.toString()));
assertEquals("Usage: ",in.readLine());
assertEquals(" [-a -b -d -f -i -l -p -P -r --sparse <WHEN> -R -s -S <SUFFIX> -u -v -V <WORD> ",in.readLine());
assertEquals("-x --help --version] <SOURCE1> [<SOURCE2> ...] <DEST> ",in.readLine());
assertEquals("OPTIONS ",in.readLine());
assertEquals(" -a (--archive) same as -dpR ",in.readLine());
assertEquals(" -b (--backup) make backup before removal ",in.readLine());
assertEquals(" -d (--no-dereference) preserve links ",in.readLine());
assertEquals(" -f (--force) remove existing destinations, never prompt ",in.readLine());
assertEquals(" -i (--interactive) prompt before overwrite ",in.readLine());
assertEquals(" -l (--link) link files instead of copying ",in.readLine());
assertEquals(" -p (--preserve) preserve file attributes if possible ",in.readLine());
assertEquals(" -P (--parents) append source path to DIRECTORY ",in.readLine());
assertEquals(" -r copy recursively, non-directories as files ",in.readLine());
assertEquals(" --sparse control creation of sparse files ",in.readLine());
assertEquals(" -R (--recursive) copy directories recursively ",in.readLine());
assertEquals(" -s (--symbolic-link) make symbolic links instead of copying ",in.readLine());
assertEquals(" -S (--suffix) override the usual backup suffix ",in.readLine());
assertEquals(" -u (--update) copy only when the SOURCE file is newer than the ",in.readLine());
assertEquals(" destination file or when the destination file is ",in.readLine());
assertEquals(" missing ",in.readLine());
assertEquals(" -v (--verbose) explain what is being done ",in.readLine());
assertEquals(" -V (--version-contol) explain what is being done ",in.readLine());
assertEquals(" -x (--one-file-system) stay on this file system ",in.readLine());
assertEquals(" --help display this help and exit ",in.readLine());
assertEquals(" --version output version information and exit ",in.readLine());
assertEquals(" SOURCE [SOURCE ...] ",in.readLine());
assertEquals(" DEST ",in.readLine());
assertNull(in.readLine());
}
}
1.1 jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli2/SourceDestArgument.java
Index: SourceDestArgument.java
===================================================================
/*
* $Header: /home/cvs/jakarta-commons-sandbox/cli/src/java/org/apache/commons/cli2/SourceDestArgument.java,v 1.1 2003/11/03 21:33:36 roxspring Exp $
* $Revision: 1.1 $
* $Date: 2003/11/03 21:33:36 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 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 acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" 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"
* nor may "Apache" appear in their names without prior written
* permission of the Apache GroupImpl.
*
* 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
* <http://www.apache.org/>.
*
*/
package org.apache.commons.cli2;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* @author Rob Oxspring
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public class SourceDestArgument extends ArgumentImpl
{
private static int sum(final int a, final int b)
{
return Math.max(a, Math.max(b, a + b));
}
private final ArgumentImpl source;
private final ArgumentImpl dest;
public SourceDestArgument(final ArgumentImpl source, final ArgumentImpl dest)
{
this(
source,
dest,
DEFAULT_INITIAL_SEPARATOR,
DEFAULT_SUBSEQUENT_SEPARATOR,
DEFAULT_CONSUME_REMAINING,
null);
}
public SourceDestArgument(
final ArgumentImpl source,
final ArgumentImpl dest,
final char initialSeparator,
final char subsequentSeparator,
final String consumeRemaining,
final List defaultValues)
{
super(
"SourceDestArgument",
null,
sum(source.getMinimum(), dest.getMinimum()),
sum(source.getMaximum(), dest.getMaximum()),
initialSeparator,
subsequentSeparator,
null,
consumeRemaining,
defaultValues,
0);
this.source = source;
this.dest = dest;
if (dest.getMinimum() != dest.getMaximum())
{
throw new IllegalArgumentException("The dest argument must enforce a fixed number of values");
}
}
/* (non-Javadoc)
* @see org.apache.commons.cli2.Option#appendUsage(java.lang.StringBuffer, java.util.Set, java.util.Comparator)
*/
public void appendUsage(
final StringBuffer buffer,
final Set helpSettings,
final Comparator comp)
{
final int length = buffer.length();
source.appendUsage(buffer, helpSettings, comp);
if (buffer.length() != length)
{
buffer.append(' ');
}
dest.appendUsage(buffer, helpSettings, comp);
}
/* (non-Javadoc)
* @see org.apache.commons.cli2.Option#helpLines(int, java.util.Set, java.util.Comparator)
*/
public List helpLines(int depth, Set helpSettings, Comparator comp)
{
final List helpLines = new ArrayList();
helpLines.addAll(source.helpLines(depth, helpSettings, comp));
helpLines.addAll(dest.helpLines(depth, helpSettings, comp));
return helpLines;
}
/* (non-Javadoc)
* @see org.apache.commons.cli2.Argument#validate(org.apache.commons.cli2.CommandLine, org.apache.commons.cli2.Option)
*/
public void validate(CommandLine commandLine, Option option)
throws OptionException
{
final List values = commandLine.getValues(option);
final int limit = values.size() - dest.getMinimum();
int count = 0;
final Iterator i = values.iterator();
while (count++ < limit)
{
commandLine.addValue(source, i.next());
}
while (i.hasNext())
{
commandLine.addValue(dest, i.next());
}
source.validate(commandLine, source);
dest.validate(commandLine, dest);
}
/* (non-Javadoc)
* @see org.apache.commons.cli2.Option#canProcess(java.lang.String)
*/
public boolean canProcess(final String arg) {
return source.canProcess(arg) || dest.canProcess(arg);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org