Beispiel #1
0
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)
Beispiel #2
0
    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
Beispiel #3
0
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)
Beispiel #4
0
    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
Beispiel #5
0
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)
Beispiel #6
0
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
Beispiel #7
0
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)