class XmlCommandLineApp(CommandLineApp.CommandLineApp): from Ft.__config__ import \ NAME as project_name, VERSION as project_version, URL as project_url name = '4xml' summary = 'command-line tool for working with XML documents' description = """4XML command-line application""" options = [ Options.Option( 'v', 'validate', 'DTD validate the input file as it is being parsed'), Options.Option( 'e', 'encoding=ENC', 'The encoding to use for output'), Options.Option( None, 'input-encoding=ENC', 'The encoding to assume for input'), Options.Option( 'o', 'outfile=FILE', 'Direct output to FILE (file will be overwritten if it exists)'), Options.Option( 'p', 'pretty', 'Pretty-print the result'), Options.Option( 'n', 'noserialize', "Do not serialize; just parse"), Options.Option( None, 'html', 'Use HTML mode when pretty-printing (emit XHTML as HTML)'), Options.Option( None, 'noxinclude', 'Do not expand XIncludes'), Options.Option( None, 'rng=FILE', 'Apply RELAX NG from the given file (technically RNG with XVIF' ' features)'), ] arguments = [ Arguments.RequiredArgument( 'source-uri', 'The URI of the XML document to parse, or "-" to indicate standard' ' input.'), ] def validate_arguments(self, args): if not args: raise SystemExit('A source URI argument is required.' \ ' See "%s -h" for usage info.' % sys.argv[0]) return CommandLineApp.CommandLineApp.validate_arguments(self, args) def run(self, options, arguments): return Run(options, arguments)
def __init__( self, name, description, example, verbose_description, function=None, options=None, arguments=None, subCommands=None, fileName=None, ): self.name = name self.description = description self.function = function self.example = example self.verbose_description = verbose_description self.options = options or Options.Options() self.arguments = arguments or [] self.subCommands = subCommands or {} self._fileName = fileName if isinstance(self.subCommands, (list, tuple)): cmds = {} for c in self.subCommands: cmds[c.name] = c self.subCommands = cmds if not isinstance(self.options, Options.Options): # Options constructor takes care of validating option values self.options = Options.Options(self.options) for arg in self.arguments: if not isinstance(arg, Arguments.Argument): raise ValueError("argument %d is not an instance of Argument" % self.arguments.index(arg)) return
class XPathCommandLineApp(CommandLineApp.CommandLineApp): from Ft.__config__ import \ NAME as project_name, VERSION as project_version, URL as project_url name = '4xpath' summary = 'command-line tool for performing XPath queries on XML documents' description = """4XPath command-line application""" options = [ Options.Option('D', 'define=NAME=VALUE', 'Bind a top-level parameter'), Options.Option('N', 'namespace=PREFIX=NAMESPACE', 'Define a namespace/prefix binding'), Options.Option('e', 'stacktrace-on-error', 'Display a stack trace when an error occurs'), Options.Option(None, 'string', 'Print the string-value of the results'), ] arguments = [ Arguments.RequiredArgument( 'source-uri', 'The URI of the XML document to parse, or "-" to indicate' ' standard input. The document\'s root node will be used as the' ' context node.'), Arguments.RequiredArgument('expression', 'The XPath expression to evaluate'), ] def validate_arguments(self, args): if len(args) < 2: raise SystemExit('A source URI argument and an expression' ' argument are required. See "%s -h" for usage' ' info.' % sys.argv[0]) return CommandLineApp.CommandLineApp.validate_arguments(self, args) def run(self, options, arguments): return Run(options, arguments)
def __init__(self): self.script_name = None self.script_args = None self.stream = sys.stdout if __debug__: for attr in ('name', 'summary', 'description'): value = getattr(self, attr) if not isinstance(value, str): tp_name = value is None and 'None' or type(value).__name__ raise TypeError('%r must be a string, not %s' % (name, tp_name)) # The options that come into an application are global to all # commands in the application. if self.options: global_options = self.global_options[:] global_options.extend(self.options) else: global_options = self.global_options if self.commands: # The application options are just the default global options # and the --show-commands option. options = self.global_options[:] options.append( Options.Option(None, 'show-commands', 'show system command tree')) else: # The application options are all the available options as the # application is the only command. options = global_options filename = sys.modules[self.__class__.__module__].__file__ Command.Command.__init__(self, self.name, self.summary, self.example, self.description, None, options, self.arguments, self.commands, filename) # Add the global options to all of the commands. if self.commands: commands = self.flatten_command_tree(0) for (level, cmd, fullName) in commands[1:]: cmd.options[0:0] = global_options return
class XUpdateCommandLineApp(CommandLineApp.CommandLineApp): from Ft.__config__ import \ NAME as project_name, VERSION as project_version, URL as project_url name = '4xupdate' summary = 'command-line tool for performing XUpdates on XML documents' description = """4XUpdate command-line application""" options = [ Options.Option( 'o', 'outfile=FILE', 'Write the result to the given output file', ), ] arguments = [ Arguments.RequiredArgument( 'source-uri', 'The URI of the XML document to which to apply the XUpdate, or' ' "-" to indicate standard input.'), Arguments.RequiredArgument( 'xupdate-uri', 'The URI of the XML document containing XUpdate instructions, or' ' "-" to indicate standard input.'), ] def validate_arguments(self, args): msg = '' if len(args) < 2: msg = 'A source URI argument and an XUpdate URI argument are required.' elif len(filter(lambda arg: arg == '-', args)) > 1: msg = 'Standard input may be used for only 1 document.' if msg: raise SystemExit('%s\nSee "4xupdate -h" for usage info.' % msg) return CommandLineApp.CommandLineApp.validate_arguments(self, args) def run(self, options, arguments): return Run(options, arguments)
class CommandLineApp(Command.Command): project_name = None project_version = None project_url = None global_options = [ Options.Option('h', 'help', 'show detailed help message'), Options.Option('V', 'version', 'display version information and exit'), ] name = None summary = None description = None example = None options = None arguments = None commands = None def __init__(self): self.script_name = None self.script_args = None self.stream = sys.stdout if __debug__: for attr in ('name', 'summary', 'description'): value = getattr(self, attr) if not isinstance(value, str): tp_name = value is None and 'None' or type(value).__name__ raise TypeError('%r must be a string, not %s' % (name, tp_name)) # The options that come into an application are global to all # commands in the application. if self.options: global_options = self.global_options[:] global_options.extend(self.options) else: global_options = self.global_options if self.commands: # The application options are just the default global options # and the --show-commands option. options = self.global_options[:] options.append( Options.Option(None, 'show-commands', 'show system command tree')) else: # The application options are all the available options as the # application is the only command. options = global_options filename = sys.modules[self.__class__.__module__].__file__ Command.Command.__init__(self, self.name, self.summary, self.example, self.description, None, options, self.arguments, self.commands, filename) # Add the global options to all of the commands. if self.commands: commands = self.flatten_command_tree(0) for (level, cmd, fullName) in commands[1:]: cmd.options[0:0] = global_options return #@classmethod def main(cls, argv=None): if argv is None: argv = sys.argv script_name = argv[0] script_args = argv[1:] return cls().run_commands(script_name, script_args) main = classmethod(main) def run_commands(self, script_name=None, script_args=None): """ Parse the command line and attempt to run the command. Typically overridden in the subclasses. """ if not script_name: self.script_name = sys.argv[0] else: self.script_name = script_name self.script_name = os.path.basename(self.script_name or '') if not script_args: self.script_args = sys.argv[1:] else: self.script_args = script_args parsed = self.parse_command_line() if parsed: cmd, options, args = parsed try: status = cmd.run(options, args) except SystemExit, e: status = e.code if not isinstance(status, int): print >> sys.stderr, str(e) status = 1 except KeyboardInterrupt: print >> sys.stderr, 'interrupted' status = 130 except ImportError, e: print >> sys.stderr, str(e) status = 1
class XsltCommandLineApp(CommandLineApp.CommandLineApp): from Ft.__config__ import \ NAME as project_name, VERSION as project_version, URL as project_url name = '4xslt' summary = ('command-line tool for performing XSLT transformations on XML' 'documents') description = """4XSLT command-line application""" options = [ Options.Option('v', 'validate', 'Validate the input file as it is being parsed'), Options.Option('i', 'ignore', 'Ignore <?xml-stylesheet ...?> instructions'), Options.Option(None, 'media=MEDIA', 'Set media to honor in xml-stylesheet PIs'), Options.Option('D', 'define=NAME=VALUE', 'Bind a top-level parameter'), Options.Option( 'P', 'prefix=PREFIX=NSURI', 'Assign a namespace to a prefix used in a top-level parameter'), Options.Option('I', 'alt-sty-path=PATH', "Same as --alt-sty-uri but uses OS path"), Options.Option(None, 'alt-sty-uri=URI', "Define an add'l base URI for imports and includes"), Options.Option( 'o', 'outfile=FILE', 'Direct transformation output to FILE (file will be overwritten' ' if it exists)'), Options.Option('e', 'stacktrace-on-error', 'Display a stack trace when an error occurs'), Options.Option( None, 'noxinclude', 'Do not expand XIncludes in source document and stylesheet'), Options.Option( None, 'trace', 'Send execution trace output to stderr or file set by' ' --trace-file'), Options.Option( None, 'trace-file=FILE', 'Trace file for execution trace output when using --trace'), Options.ExclusiveOptions([ Options.Option( None, 'reflex', 'Reflexive transform (use the stylesheet as the source' ' document).'), Options.Option( None, 'compile', 'Compile an instant stylesheet. The result is written to' ' stdout, unless -o is used.'), Options.Option( None, 'instant', 'The stylesheet is "instant" (compiled). Only one stylesheet' ' can be specified with this option.'), Options.Option( None, 'chain', 'Chain the stylesheets (result of transforming with the first' ' is the source document for transforming with the second, and' ' so on). Without this option, each extra stylesheet is' ' imported by the preceding one.'), ]), Options.Option(None, 'time', 'Display the elapsed transformation time on stderr'), Options.Option(None, 'msg-prefix=STRING', 'Prepend string to xsl:message output'), Options.Option(None, 'msg-suffix=STRING', 'Append string to xsl:message output'), Options.Option(None, 'no-messages', 'Suppress xsl:message output and warnings'), ] arguments = [ Arguments.RequiredArgument( 'source-uri', 'The URI of the XML document to transform, or "-" to indicate' ' standard input. If using --reflex, it is also the stylesheet.' ' If using --compile, it is the stylesheet to compile.'), Arguments.ZeroOrMoreArgument( 'stylesheet-uri', 'The URI(s) of the stylesheet(s) to apply.'), ] def validate_options(self, options): if options.has_key('trace'): outputfile = options.get('outfile') tracefile = options.get('trace-file') msg = '' if not outputfile and not tracefile: msg = 'When using --trace, you must specify an output' \ ' file for the trace info (--trace-file) and/or' \ ' for the transformation result (-o or --outfile).' else: outputfile_abspath = outputfile and os.path.abspath( outputfile) or None tracefile_abspath = tracefile and os.path.abspath( tracefile) or None if outputfile_abspath == tracefile_abspath: msg = 'The trace and result output destinations must differ.' for path in (outputfile, outputfile_abspath): if not path: pass # we already handled the one case that matters elif path.endswith(os.sep): msg = 'The output file %s would be a directory.' % path elif os.path.isdir(path): msg = 'The output file %s is a directory.' % path for path in (tracefile, tracefile_abspath): if not path: pass # we already handled the one case that matters elif path.endswith(os.sep): msg = 'The trace file %s would be a directory.' % path elif os.path.isdir(path): msg = 'The trace file %s is a directory.' % path if msg: raise SystemExit('%s\n See "%s -h" for usage info.' % (msg, sys.argv[0])) return CommandLineApp.CommandLineApp.validate_options(self, options) def run(self, options, arguments): # 1st arg ('source-uri') will be the source doc normally, or the # source doc & stylesheet in the case of --reflex, or the # 1st stylesheet in the case of --compile. It is never OK to have # zero args. For --reflex, there must be only one arg. For # --instant, there must be exactly two. For --chain, three or more. msg = '' argslen = len(arguments) if argslen != 2 and options.has_key('instant'): msg = 'When using --instant, exactly 1 source doc URI and 1 stylesheet URI are required.' elif argslen < 3 and options.has_key('chain'): msg = 'When using --chain, 1 source doc URI and at least 2 stylesheet URIs are required.' elif argslen > 1: if options.has_key('reflex'): msg = 'When using --reflex, only 1 source/stylesheet URI may be given.' elif arguments.values().count('-') > 1: msg = 'Standard input may be used for only 1 source document or stylesheet.' if msg: raise SystemExit('%s\n See "%s -h" for usage info.' % (msg, sys.argv[0])) return Run(options, arguments)