@ -45,15 +45,10 @@ package org.eclipse.jgit.pgm.opt;
import java.lang.reflect.Field ;
import java.util.ArrayList ;
import java.util.Collections ;
import java.util.Iterator ;
import java.util.List ;
import org.kohsuke.args4j.Argument ;
import org.kohsuke.args4j.CmdLineException ;
import org.kohsuke.args4j.IllegalAnnotationError ;
import org.kohsuke.args4j.NamedOptionDef ;
import org.kohsuke.args4j.Option ;
import org.kohsuke.args4j.OptionDef ;
import org.kohsuke.args4j.spi.OptionHandler ;
import org.kohsuke.args4j.spi.Setter ;
import org.eclipse.jgit.lib.ObjectId ;
import org.eclipse.jgit.lib.Repository ;
import org.eclipse.jgit.pgm.TextBuiltin ;
@ -63,6 +58,14 @@ import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk ;
import org.eclipse.jgit.transport.RefSpec ;
import org.eclipse.jgit.treewalk.AbstractTreeIterator ;
import org.kohsuke.args4j.Argument ;
import org.kohsuke.args4j.CmdLineException ;
import org.kohsuke.args4j.IllegalAnnotationError ;
import org.kohsuke.args4j.NamedOptionDef ;
import org.kohsuke.args4j.Option ;
import org.kohsuke.args4j.OptionDef ;
import org.kohsuke.args4j.spi.OptionHandler ;
import org.kohsuke.args4j.spi.Setter ;
/ * *
* Extended command line parser which handles - - foo = value arguments .
@ -86,6 +89,8 @@ public class CmdLineParser extends org.kohsuke.args4j.CmdLineParser {
private RevWalk walk ;
private boolean seenHelp ;
/ * *
* Creates a new command line owner that parses arguments / options and set
* them into the given object .
@ -143,9 +148,58 @@ public class CmdLineParser extends org.kohsuke.args4j.CmdLineParser {
}
tmp . add ( str ) ;
if ( containsHelp ( args ) ) {
// suppress exceptions on required parameters if help is present
seenHelp = true ;
// stop argument parsing here
break ;
}
}
List < OptionHandler > backup = null ;
if ( seenHelp ) {
backup = unsetRequiredOptions ( ) ;
}
try {
super . parseArgument ( tmp . toArray ( new String [ tmp . size ( ) ] ) ) ;
} finally {
// reset "required" options to defaults for correct command printout
if ( backup ! = null & & ! backup . isEmpty ( ) ) {
restoreRequiredOptions ( backup ) ;
}
seenHelp = false ;
}
}
private List < OptionHandler > unsetRequiredOptions ( ) {
List < OptionHandler > options = getOptions ( ) ;
List < OptionHandler > backup = new ArrayList < > ( options ) ;
for ( Iterator < OptionHandler > iterator = options . iterator ( ) ; iterator
. hasNext ( ) ; ) {
OptionHandler handler = iterator . next ( ) ;
if ( handler . option instanceof NamedOptionDef
& & handler . option . required ( ) ) {
iterator . remove ( ) ;
}
}
return backup ;
}
private void restoreRequiredOptions ( List < OptionHandler > backup ) {
List < OptionHandler > options = getOptions ( ) ;
options . clear ( ) ;
options . addAll ( backup ) ;
}
super . parseArgument ( tmp . toArray ( new String [ tmp . size ( ) ] ) ) ;
/ * *
* @param args
* non null
* @return true if the given array contains help option
* @since 4 . 2
* /
protected boolean containsHelp ( final String . . . args ) {
return TextBuiltin . containsHelp ( args ) ;
}
/ * *
@ -181,7 +235,7 @@ public class CmdLineParser extends org.kohsuke.args4j.CmdLineParser {
return walk ;
}
static class MyOptionDef extends OptionDef {
class MyOptionDef extends OptionDef {
public MyOptionDef ( OptionDef o ) {
super ( o . usage ( ) , o . metaVar ( ) , o . required ( ) , o . handler ( ) , o
@ -201,6 +255,11 @@ public class CmdLineParser extends org.kohsuke.args4j.CmdLineParser {
return metaVar ( ) ;
}
}
@Override
public boolean required ( ) {
return seenHelp ? false : super . required ( ) ;
}
}
@Override
@ -211,4 +270,22 @@ public class CmdLineParser extends org.kohsuke.args4j.CmdLineParser {
return super . createOptionHandler ( new MyOptionDef ( o ) , setter ) ;
}
@SuppressWarnings ( "unchecked" )
private List < OptionHandler > getOptions ( ) {
List < OptionHandler > options = null ;
try {
Field field = org . kohsuke . args4j . CmdLineParser . class
. getDeclaredField ( "options" ) ; //$NON-NLS-1$
field . setAccessible ( true ) ;
options = ( List < OptionHandler > ) field . get ( this ) ;
} catch ( NoSuchFieldException | SecurityException
| IllegalArgumentException | IllegalAccessException e ) {
// ignore
}
if ( options = = null ) {
return Collections . emptyList ( ) ;
}
return options ;
}
}