Skip to content

Commit c712732

Browse files
author
John Keyes
committed
added automatic usage generation
git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/cli/trunk@129785 13f79535-47bb-0310-9956-ffa450edef68
1 parent 7c571fe commit c712732

3 files changed

Lines changed: 207 additions & 76 deletions

File tree

src/java/org/apache/commons/cli/HelpFormatter.java

Lines changed: 130 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,12 @@
6262
package org.apache.commons.cli;
6363

6464
import java.io.PrintWriter;
65-
import java.util.Iterator;
66-
import java.util.List;
6765
import java.util.ArrayList;
66+
import java.util.Collection;
6867
import java.util.Collections;
6968
import java.util.Comparator;
69+
import java.util.Iterator;
70+
import java.util.List;
7071

7172
/**
7273
* A formatter of help messages for the current command line options
@@ -117,29 +118,54 @@ public HelpFormatter()
117118
public void printHelp( String cmdLineSyntax,
118119
Options options )
119120
{
120-
printHelp( defaultWidth, cmdLineSyntax, null, options, null );
121+
printHelp( defaultWidth, cmdLineSyntax, null, options, null, false );
122+
}
123+
124+
public void printHelp( String cmdLineSyntax,
125+
Options options,
126+
boolean autoUsage )
127+
{
128+
printHelp( defaultWidth, cmdLineSyntax, null, options, null, autoUsage );
121129
}
122130

123131
public void printHelp( String cmdLineSyntax,
124132
String header,
125133
Options options,
126134
String footer )
127135
{
128-
printHelp(defaultWidth, cmdLineSyntax, header, options, footer);
136+
printHelp( cmdLineSyntax, header, options, footer, false );
129137
}
130138

139+
public void printHelp( String cmdLineSyntax,
140+
String header,
141+
Options options,
142+
String footer,
143+
boolean autoUsage )
144+
{
145+
printHelp(defaultWidth, cmdLineSyntax, header, options, footer, autoUsage );
146+
}
147+
131148
public void printHelp( int width,
132149
String cmdLineSyntax,
133150
String header,
134151
Options options,
135152
String footer )
153+
{
154+
printHelp( width, cmdLineSyntax, header, options, footer, false );
155+
}
156+
157+
public void printHelp( int width,
158+
String cmdLineSyntax,
159+
String header,
160+
Options options,
161+
String footer,
162+
boolean autoUsage )
136163
{
137164
PrintWriter pw = new PrintWriter(System.out);
138165
printHelp( pw, width, cmdLineSyntax, header,
139-
options, defaultLeftPad, defaultDescPad, footer );
166+
options, defaultLeftPad, defaultDescPad, footer, autoUsage );
140167
pw.flush();
141168
}
142-
143169
public void printHelp( PrintWriter pw,
144170
int width,
145171
String cmdLineSyntax,
@@ -148,14 +174,34 @@ public void printHelp( PrintWriter pw,
148174
int leftPad,
149175
int descPad,
150176
String footer )
177+
throws IllegalArgumentException
178+
{
179+
printHelp( pw, width, cmdLineSyntax, header, options, leftPad, descPad, footer, false );
180+
}
181+
182+
public void printHelp( PrintWriter pw,
183+
int width,
184+
String cmdLineSyntax,
185+
String header,
186+
Options options,
187+
int leftPad,
188+
int descPad,
189+
String footer,
190+
boolean autoUsage )
151191
throws IllegalArgumentException
152192
{
153193
if ( cmdLineSyntax == null || cmdLineSyntax.length() == 0 )
154194
{
155195
throw new IllegalArgumentException("cmdLineSyntax not provided");
156196
}
157197

158-
printUsage( pw, width, cmdLineSyntax );
198+
if ( autoUsage ) {
199+
printUsage( pw, width, cmdLineSyntax, options );
200+
}
201+
else {
202+
printUsage( pw, width, cmdLineSyntax );
203+
}
204+
159205
if ( header != null && header.trim().length() > 0 )
160206
{
161207
printWrapped( pw, width, header );
@@ -167,6 +213,83 @@ public void printHelp( PrintWriter pw,
167213
}
168214
}
169215

216+
/**
217+
* <p>Prints the usage statement for the specified application.</p>
218+
*
219+
* @param pw The PrintWriter to print the usage statement
220+
* @param width ??
221+
* @param appName The application name
222+
* @param options The command line Options
223+
*
224+
*/
225+
public void printUsage( PrintWriter pw, int width, String app, Options options )
226+
{
227+
// initialise the string buffer
228+
StringBuffer buff = new StringBuffer( defaultSyntaxPrefix ).append( app ).append( " " );
229+
230+
// create a list for processed option groups
231+
ArrayList list = new ArrayList();
232+
233+
// temp variable
234+
Option option;
235+
236+
// iterate over the options
237+
for ( Iterator i = options.getOptions().iterator(); i.hasNext(); )
238+
{
239+
// get the next Option
240+
option = (Option) i.next();
241+
242+
// check if the option is part of an OptionGroup
243+
OptionGroup group = options.getOptionGroup( option );
244+
245+
// if the option is part of a group and the group has not already
246+
// been processed
247+
if( group != null && !list.contains(group)) {
248+
249+
// add the group to the processed list
250+
list.add( group );
251+
252+
// get the names of the options from the OptionGroup
253+
Collection names = group.getNames();
254+
255+
buff.append( "[" );
256+
257+
// for each option in the OptionGroup
258+
for( Iterator iter = names.iterator(); iter.hasNext(); ) {
259+
buff.append( iter.next() );
260+
if( iter.hasNext() ) {
261+
buff.append( " | " );
262+
}
263+
}
264+
buff.append( "]" );
265+
}
266+
// if the Option is not part of an OptionGroup
267+
else {
268+
// if the Option is not a required option
269+
if( !option.isRequired() ) {
270+
buff.append( "[" );
271+
}
272+
buff.append( "-" ).append( option.getOpt() );
273+
274+
// if the Option has a value
275+
if( option.hasArg() ) {
276+
buff.append( " arg" );
277+
}
278+
279+
// if the Option is not a required option
280+
if( !option.isRequired() ) {
281+
buff.append( "]" );
282+
}
283+
buff.append( " " );
284+
}
285+
}
286+
287+
System.out.println( "->" + buff.toString() );
288+
// call printWrapped
289+
printWrapped( pw, width, buff.toString().indexOf(' ')+1,
290+
buff.toString() );
291+
}
292+
170293
public void printUsage( PrintWriter pw, int width, String cmdLineSyntax )
171294
{
172295
int argPos = cmdLineSyntax.indexOf(' ') + 1;

src/java/org/apache/commons/cli/OptionGroup.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public OptionGroup addOption(Option opt) {
9494
* @return the names of the options in this group as a
9595
* <code>Collection</code>
9696
*/
97-
private Collection getNames() {
97+
public Collection getNames() {
9898
// the key set is the collection of names
9999
return optionMap.keySet();
100100
}

src/test/org/apache/commons/cli/TestHelpFormatter.java

Lines changed: 76 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,18 @@
1212
import junit.framework.TestCase;
1313
import junit.framework.TestSuite;
1414

15-
import java.io.StringWriter;
15+
import java.io.ByteArrayOutputStream;
1616
import java.io.PrintWriter;
17+
import java.io.StringWriter;
1718

1819
/**
1920
* Test case for the HelpFormatter class
2021
*
2122
* @author Slawek Zachcial
23+
* @author John Keyes ( jbjk at mac.com )
2224
**/
23-
public class TestHelpFormatter
24-
extends TestCase
25+
public class TestHelpFormatter extends TestCase
2526
{
26-
// --------------------------------------------------------------- Constants
27-
28-
// ------------------------------------------------------------------ Static
29-
3027
public static void main( String[] args )
3128
{
3229
String[] testName = { TestHelpFormatter.class.getName() };
@@ -38,14 +35,10 @@ public static TestSuite suite()
3835
return new TestSuite(TestHelpFormatter.class);
3936
}
4037

41-
// -------------------------------------------------------------- Attributes
42-
43-
// ------------------------------------------------------------ Constructors
4438
public TestHelpFormatter( String s )
4539
{
4640
super( s );
4741
}
48-
// ------------------------------------------------------------------ Public
4942

5043
public void testFindWrapPos()
5144
throws Exception
@@ -100,64 +93,79 @@ public void testPrintWrapped()
10093
}
10194

10295
public void testPrintOptions()
103-
throws Exception
96+
throws Exception
10497
{
105-
StringBuffer sb = new StringBuffer();
106-
HelpFormatter hf = new HelpFormatter();
107-
final int leftPad = 1;
108-
final int descPad = 3;
109-
final String lpad = hf.createPadding(leftPad);
110-
final String dpad = hf.createPadding(descPad);
111-
Options options = null;
112-
String expected = null;
113-
114-
options = new Options().addOption("a", false, "aaaa aaaa aaaa aaaa aaaa");
115-
expected = lpad + "-a" + dpad + "aaaa aaaa aaaa aaaa aaaa";
116-
hf.renderOptions(sb, 60, options, leftPad, descPad);
117-
assertEquals("simple non-wrapped option", expected, sb.toString());
118-
119-
int nextLineTabStop = leftPad+descPad+"-a".length();
120-
expected =
121-
lpad + "-a" + dpad + "aaaa aaaa aaaa" + hf.defaultNewLine +
122-
hf.createPadding(nextLineTabStop) + "aaaa aaaa";
123-
sb.setLength(0);
124-
hf.renderOptions(sb, nextLineTabStop+17, options, leftPad, descPad);
125-
assertEquals("simple wrapped option", expected, sb.toString());
126-
127-
128-
options = new Options().addOption("a", "aaa", false, "dddd dddd dddd dddd");
129-
expected = lpad + "-a,--aaa" + dpad + "dddd dddd dddd dddd";
130-
sb.setLength(0);
131-
hf.renderOptions(sb, 60, options, leftPad, descPad);
132-
assertEquals("long non-wrapped option", expected, sb.toString());
133-
134-
nextLineTabStop = leftPad+descPad+"-a,--aaa".length();
135-
expected =
136-
lpad + "-a,--aaa" + dpad + "dddd dddd" + hf.defaultNewLine +
137-
hf.createPadding(nextLineTabStop) + "dddd dddd";
138-
sb.setLength(0);
139-
hf.renderOptions(sb, 25, options, leftPad, descPad);
140-
assertEquals("long wrapped option", expected, sb.toString());
141-
142-
options = new Options().
143-
addOption("a", "aaa", false, "dddd dddd dddd dddd").
144-
addOption("b", false, "feeee eeee eeee eeee");
145-
expected =
146-
lpad + "-a,--aaa" + dpad + "dddd dddd" + hf.defaultNewLine +
147-
hf.createPadding(nextLineTabStop) + "dddd dddd" + hf.defaultNewLine +
148-
lpad + "-b " + dpad + "feeee eeee" + hf.defaultNewLine +
149-
hf.createPadding(nextLineTabStop) + "eeee eeee";
150-
sb.setLength(0);
151-
hf.renderOptions(sb, 25, options, leftPad, descPad);
152-
assertEquals("multiple wrapped options", expected, sb.toString());
98+
StringBuffer sb = new StringBuffer();
99+
HelpFormatter hf = new HelpFormatter();
100+
final int leftPad = 1;
101+
final int descPad = 3;
102+
final String lpad = hf.createPadding(leftPad);
103+
final String dpad = hf.createPadding(descPad);
104+
Options options = null;
105+
String expected = null;
106+
107+
options = new Options().addOption("a", false, "aaaa aaaa aaaa aaaa aaaa");
108+
expected = lpad + "-a" + dpad + "aaaa aaaa aaaa aaaa aaaa";
109+
hf.renderOptions(sb, 60, options, leftPad, descPad);
110+
assertEquals("simple non-wrapped option", expected, sb.toString());
111+
112+
int nextLineTabStop = leftPad+descPad+"-a".length();
113+
expected =
114+
lpad + "-a" + dpad + "aaaa aaaa aaaa" + hf.defaultNewLine +
115+
hf.createPadding(nextLineTabStop) + "aaaa aaaa";
116+
sb.setLength(0);
117+
hf.renderOptions(sb, nextLineTabStop+17, options, leftPad, descPad);
118+
assertEquals("simple wrapped option", expected, sb.toString());
119+
120+
121+
options = new Options().addOption("a", "aaa", false, "dddd dddd dddd dddd");
122+
expected = lpad + "-a,--aaa" + dpad + "dddd dddd dddd dddd";
123+
sb.setLength(0);
124+
hf.renderOptions(sb, 60, options, leftPad, descPad);
125+
assertEquals("long non-wrapped option", expected, sb.toString());
126+
127+
nextLineTabStop = leftPad+descPad+"-a,--aaa".length();
128+
expected =
129+
lpad + "-a,--aaa" + dpad + "dddd dddd" + hf.defaultNewLine +
130+
hf.createPadding(nextLineTabStop) + "dddd dddd";
131+
sb.setLength(0);
132+
hf.renderOptions(sb, 25, options, leftPad, descPad);
133+
assertEquals("long wrapped option", expected, sb.toString());
134+
135+
options = new Options().
136+
addOption("a", "aaa", false, "dddd dddd dddd dddd").
137+
addOption("b", false, "feeee eeee eeee eeee");
138+
expected =
139+
lpad + "-a,--aaa" + dpad + "dddd dddd" + hf.defaultNewLine +
140+
hf.createPadding(nextLineTabStop) + "dddd dddd" + hf.defaultNewLine +
141+
lpad + "-b " + dpad + "feeee eeee" + hf.defaultNewLine +
142+
hf.createPadding(nextLineTabStop) + "eeee eeee";
143+
sb.setLength(0);
144+
hf.renderOptions(sb, 25, options, leftPad, descPad);
145+
assertEquals("multiple wrapped options", expected, sb.toString());
153146
}
154147

155-
// --------------------------------------------------------------- Protected
156-
157-
// ------------------------------------------------------- Package protected
158-
159-
// ----------------------------------------------------------------- Private
160-
161-
// ----------------------------------------------------------- Inner classes
162-
148+
public void testAutomaticUsage()
149+
throws Exception
150+
{
151+
HelpFormatter hf = new HelpFormatter();
152+
Options options = null;
153+
String expected = "usage: app [-a]\n";
154+
ByteArrayOutputStream out = new ByteArrayOutputStream( );
155+
PrintWriter pw = new PrintWriter( out );
156+
157+
options = new Options().addOption("a", false, "aaaa aaaa aaaa aaaa aaaa");
158+
hf.printUsage( pw, 60, "app", options );
159+
pw.flush();
160+
assertEquals("simple auto usage", expected, out.toString());
161+
out.reset();
162+
163+
expected = "usage: app [-b] [-a]\n";
164+
options = new Options().addOption("a", false, "aaaa aaaa aaaa aaaa aaaa")
165+
.addOption("b", false, "bbb" );
166+
hf.printUsage( pw, 60, "app", options );
167+
pw.flush();
168+
assertEquals("simple auto usage", expected, out.toString());
169+
out.reset();
170+
}
163171
}

0 commit comments

Comments
 (0)