Skip to content

Commit

Permalink
Merge pull request #4439 from mmascher/optparser2
Browse files Browse the repository at this point in the history
Refactor command line option parsing code
  • Loading branch information
mmascher committed Mar 28, 2015
2 parents e3d857d + ee563d0 commit 3c5c073
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 86 deletions.
49 changes: 4 additions & 45 deletions bin/crab
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ import pycurl
import logging
import logging.handlers


from httplib import HTTPException
from optparse import OptionParser, OptionGroup
from socket import error as SocketError

from CRABClient.CRABOptParser import CRABOptParser
from CRABClient import __version__ as client_version
from CRABClient.ClientUtilities import getAvailCommands, logfilter , uploadlogfile, getLoggers, StopExecution
from CRABClient.ClientExceptions import ClientException
Expand All @@ -40,61 +39,21 @@ class MyNullHandler(logging.Handler):
pass


class MyParser(OptionParser):
"""
Allows to make OptionParser behave how we prefer
"""
def format_epilog(self, formatter):
"""
do not strip the new lines from the epilog
"""
return self.epilog


class CRABClient(object):
def __init__( self ):
"""
Get the command to run, the options to pass it and a logger instance
at appropriate level
"""

self.sub_commands = getAvailCommands()
usage = "usage: %prog [options] COMMAND [command-options] [args]"
epilog = '\nValid commands are: \n'
for k in sorted(self.sub_commands.keys()):
epilog += ' %s' % self.sub_commands[k].name
epilog += ''.join( [' (%s)' % name for name in self.sub_commands[k].shortnames ] )
epilog += '\n'
epilog += "To get single command help run:\n crab command --help|-h\n"

epilog += '\nFor more information on how to run CRAB-3 please follow this link:\n'
epilog += 'https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookCRAB3Tutorial\n'

self.parser = MyParser( usage = usage,
epilog = epilog,
version = "CRAB client v%s" % client_version
)

# This is the important bit
self.parser.disable_interspersed_args()
self.parser.add_option( "--quiet",
action = "store_true",
dest = "quiet",
default = False,
help = "don't print any messages to stdout" )

self.parser.add_option( "--debug",
action = "store_true",
dest = "debug",
default = False,
help = "print extra messages to stdout" )
self.subCommands = getAvailCommands()
self.parser = CRABOptParser(self.subCommands)


def __call__(self):

(options, args) = self.parser.parse_args()


#the default the logfile destination is /crab.log, it will be changed when we have loaded the taskname
loglevel = logging.INFO
if options.quiet:
Expand Down Expand Up @@ -158,7 +117,7 @@ class CRABClient(object):

sub_cmd = None
try:
sub_cmd = next( v for k,v in self.sub_commands.items() if args[0] in v.shortnames or args[0]==v.name)
sub_cmd = next( v for k,v in self.subCommands.items() if args[0] in v.shortnames or args[0]==v.name)
except StopIteration:
print "'" + str(args[0]) + "' is not a valid command."
print self.parser.print_help()
Expand Down
109 changes: 109 additions & 0 deletions src/python/CRABClient/CRABOptParser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
from optparse import OptionParser

from CRABClient import __version__ as client_version
from CRABClient.ClientUtilities import getAvailCommands
from CRABClient.ClientUtilities import SERVICE_INSTANCES


class CRABOptParser(OptionParser):
"""
Allows to make OptionParser behave how we prefer
"""

def __init__(self, subCommands=None):
""" Initialize the option parser used in the the client. That's only the first step parsing
which basically creates the help and looks for the --debug/--quiet options. Each command
than has its own set of arguments (some are shared, see CRABCmdOptParser ).
subCommands: if present used to prepare a nice help summary for all the commands
"""
usage = "usage: %prog [options] COMMAND [command-options] [args]"
epilog = ""
if subCommands:
epilog = '\nValid commands are: \n'
for k in sorted(subCommands.keys()):
epilog += ' %s' % subCommands[k].name
epilog += ''.join( [' (%s)' % name for name in subCommands[k].shortnames ] )
epilog += '\n'
epilog += "To get single command help run:\n crab command --help|-h\n"

epilog += '\nFor more information on how to run CRAB-3 please follow this link:\n'
epilog += 'https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookCRAB3Tutorial\n'

OptionParser.__init__(self, usage = usage, epilog = epilog,
version = "CRAB client v%s" % client_version
)

# This is the important bit
self.disable_interspersed_args()

self.add_option( "--quiet",
action = "store_true",
dest = "quiet",
default = False,
help = "don't print any messages to stdout" )

self.add_option( "--debug",
action = "store_true",
dest = "debug",
default = False,
help = "print extra messages to stdout" )


def format_epilog(self, formatter):
"""
do not strip the new lines from the epilog
"""
return self.epilog



class CRABCmdOptParser(OptionParser):
""" A class that extract the pieces for parsing the command line arguments
of the CRAB commands.
"""

def __init__(self, cmdname, doc, disable_interspersed_args):
"""
doc: the description of the command. Taken from self.__doc__
disable_interspersed_args: some commands (e.g.: submit) allow to overwrite configuration parameters
"""
usage = "usage: %prog " + cmdname + " [options] [args]"
OptionParser.__init__(self, description = doc, usage = usage, add_help_option = True)
if disable_interspersed_args:
self.disable_interspersed_args()


def addCommonOptions(self, cmdconf):
"""
cmdconf: the command configuration from the ClientMapping
"""
self.add_option("--proxy",
dest = "proxy",
default = False,
help = "Use the given proxy. Skip Grid proxy creation and myproxy delegation.")

if cmdconf['requiresTaskOption']:
self.add_option("-d", "--dir",
dest = "task",
default = None,
help = "Path to the CRAB project directory for which the crab command should be executed.")
self.add_option("-t", "--task",
dest = "oldtask",
default = None,
help = "Deprecated option renamed to -d/--dir in CRAB v3.3.12.")

if cmdconf['requiresProxyVOOptions']:
self.add_option("--voRole",
dest = "voRole",
default = None)
self.add_option("--voGroup",
dest = "voGroup",
default = None)

if cmdconf['requiresREST']:
self.add_option("--instance",
dest = "instance",
type = "string",
help = "Running instance of CRAB service. Valid values are %s." % str(SERVICE_INSTANCES.keys()))
54 changes: 13 additions & 41 deletions src/python/CRABClient/Commands/SubCommand.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@
import imp
import json
import types
from optparse import OptionParser
from ast import literal_eval
from optparse import OptionParser

from CRABClient.ClientUtilities import loadCache, getWorkArea, server_info, createWorkArea
from CRABClient.ClientUtilities import BASEURL, SERVICE_INSTANCES
from CRABClient import SpellChecker
import CRABClient.Emulator
from CRABClient.ClientExceptions import ConfigurationException, MissingOptionException, EnvironmentException, UnknownOptionException
from CRABClient.ClientMapping import renamedParams, commandsConfiguration, configParametersInfo, getParamDefaultValue
from CRABClient.CredentialInteractions import CredentialInteractions
from CRABClient import SpellChecker
from CRABClient.__init__ import __version__
from CRABClient.ClientUtilities import colors
from WMCore.Credential.Proxy import Proxy
from CRABClient.CRABOptParser import CRABCmdOptParser
from CRABClient.ClientUtilities import BASEURL, SERVICE_INSTANCES
from CRABClient.CredentialInteractions import CredentialInteractions
from CRABClient.ClientUtilities import loadCache, getWorkArea, server_info, createWorkArea
from CRABClient.ClientMapping import renamedParams, commandsConfiguration, configParametersInfo, getParamDefaultValue
from CRABClient.ClientExceptions import ConfigurationException, MissingOptionException, EnvironmentException, UnknownOptionException

from WMCore.Credential.Proxy import Proxy
from WMCore.Configuration import loadConfigurationFile, Configuration

#if certificates in myproxy expires in less than RENEW_MYPROXY_THRESHOLD days renew them
Expand Down Expand Up @@ -106,7 +107,7 @@ def _extractReason(self, configname, re):
modPath[1], modPath[2])
except Exception, ex:
msg = str(ex)

return msg


Expand Down Expand Up @@ -232,10 +233,7 @@ def __init__(self, logger, cmdargs = None, disable_interspersed_args = False):
self.crab3dic = self.getConfiDict()

## The options parser.
self.usage = "usage: %prog " + self.name + " [options] [args]"
self.parser = OptionParser(description = self.__doc__, usage = self.usage, add_help_option = True)
if disable_interspersed_args:
self.parser.disable_interspersed_args()
self.parser = CRABCmdOptParser(self.name, self.__doc__, disable_interspersed_args)

## Define the command options.
self.setSuperOptions()
Expand Down Expand Up @@ -511,38 +509,12 @@ def setOptions(self):

def setSuperOptions(self):
try:
#add command related options
self.setOptions()
except NotImplementedError:
pass

self.parser.add_option("--proxy",
dest = "proxy",
default = False,
help = "Use the given proxy. Skip Grid proxy creation and myproxy delegation.")

if self.cmdconf['requiresTaskOption']:
self.parser.add_option("-d", "--dir",
dest = "task",
default = None,
help = "Path to the CRAB project directory for which the crab command should be executed.")
self.parser.add_option("-t", "--task",
dest = "oldtask",
default = None,
help = "Deprecated option renamed to -d/--dir in CRAB v3.3.12.")

if self.cmdconf['requiresProxyVOOptions']:
self.parser.add_option("--voRole",
dest = "voRole",
default = None)
self.parser.add_option("--voGroup",
dest = "voGroup",
default = None)

if self.cmdconf['requiresREST']:
self.parser.add_option("--instance",
dest = "instance",
type = "string",
help = "Running instance of CRAB service. Valid values are %s." % str(SERVICE_INSTANCES.keys()))
self.parser.addCommonOptions(self.cmdconf)


def validateOptions(self):
Expand Down

0 comments on commit 3c5c073

Please sign in to comment.