Ejemplo n.º 1
0
def handle_exception(app: Sphinx,
                     args: Any,
                     exception: BaseException,
                     stderr: IO = sys.stderr) -> None:  # NOQA
    if isinstance(exception, bdb.BdbQuit):
        return

    if args.pdb:
        print(red(__('Exception occurred while building, starting debugger:')),
              file=stderr)
        traceback.print_exc()
        pdb.post_mortem(sys.exc_info()[2])
    else:
        print(file=stderr)
        if args.verbosity or args.traceback:
            traceback.print_exc(None, stderr)
            print(file=stderr)
        if isinstance(exception, KeyboardInterrupt):
            print(__('Interrupted!'), file=stderr)
        elif isinstance(exception, SystemMessage):
            print(red(__('reST markup error:')), file=stderr)
            print(terminal_safe(exception.args[0]), file=stderr)
        elif isinstance(exception, SphinxError):
            print(red('%s:' % exception.category), file=stderr)
            print(str(exception), file=stderr)
        elif isinstance(exception, UnicodeError):
            print(red(__('Encoding error:')), file=stderr)
            print(terminal_safe(str(exception)), file=stderr)
            tbpath = save_traceback(app)
            print(red(
                __('The full traceback has been saved in %s, if you want '
                   'to report the issue to the developers.') % tbpath),
                  file=stderr)
        elif isinstance(exception,
                        RuntimeError) and 'recursion depth' in str(exception):
            print(red(__('Recursion error:')), file=stderr)
            print(terminal_safe(str(exception)), file=stderr)
            print(file=stderr)
            print(__('This can happen with very large or deeply nested source '
                     'files. You can carefully increase the default Python '
                     'recursion limit of 1000 in conf.py with e.g.:'),
                  file=stderr)
            print('    import sys; sys.setrecursionlimit(1500)', file=stderr)
        else:
            print(red(__('Exception occurred:')), file=stderr)
            print(format_exception_cut_frames().rstrip(), file=stderr)
            tbpath = save_traceback(app)
            print(red(
                __('The full traceback has been saved in %s, if you '
                   'want to report the issue to the developers.') % tbpath),
                  file=stderr)
            print(__('Please also report this if it was a user error, so '
                     'that a better error message can be provided next time.'),
                  file=stderr)
            print(__('A bug report can be filed in the tracker at '
                     '<https://github.com/sphinx-doc/sphinx/issues>. Thanks!'),
                  file=stderr)
Ejemplo n.º 2
0
def handle_exception(app, args, exception, stderr=sys.stderr):
    # type: (Sphinx, Any, Union[Exception, KeyboardInterrupt], IO) -> None
    if args.pdb:
        import pdb
        print(red(__('Exception occurred while building, starting debugger:')),
              file=stderr)
        traceback.print_exc()
        pdb.post_mortem(sys.exc_info()[2])
    else:
        print(file=stderr)
        if args.verbosity or args.traceback:
            traceback.print_exc(None, stderr)
            print(file=stderr)
        if isinstance(exception, KeyboardInterrupt):
            print(__('interrupted!'), file=stderr)
        elif isinstance(exception, SystemMessage):
            print(red(__('reST markup error:')), file=stderr)
            print(terminal_safe(exception.args[0]), file=stderr)
        elif isinstance(exception, SphinxError):
            print(red('%s:' % exception.category), file=stderr)
            print(terminal_safe(text_type(exception)), file=stderr)
        elif isinstance(exception, UnicodeError):
            print(red(__('Encoding error:')), file=stderr)
            print(terminal_safe(text_type(exception)), file=stderr)
            tbpath = save_traceback(app)
            print(red(__('The full traceback has been saved in %s, if you want '
                         'to report the issue to the developers.') % tbpath),
                  file=stderr)
        elif isinstance(exception, RuntimeError) and 'recursion depth' in str(exception):
            print(red(__('Recursion error:')), file=stderr)
            print(terminal_safe(text_type(exception)), file=stderr)
            print(file=stderr)
            print(__('This can happen with very large or deeply nested source '
                     'files.  You can carefully increase the default Python '
                     'recursion limit of 1000 in conf.py with e.g.:'), file=stderr)
            print(__('    import sys; sys.setrecursionlimit(1500)'), file=stderr)
        else:
            print(red(__('Exception occurred:')), file=stderr)
            print(format_exception_cut_frames().rstrip(), file=stderr)
            tbpath = save_traceback(app)
            print(red(__('The full traceback has been saved in %s, if you '
                         'want to report the issue to the developers.') % tbpath),
                  file=stderr)
            print(__('Please also report this if it was a user error, so '
                     'that a better error message can be provided next time.'),
                  file=stderr)
            print(__('A bug report can be filed in the tracker at '
                     '<https://github.com/sphinx-doc/sphinx/issues>. Thanks!'),
                  file=stderr)
Ejemplo n.º 3
0
def main(argv):
    if not color_terminal():
        nocolor()

    parser = optparse.OptionParser(USAGE,
                                   epilog=EPILOG,
                                   formatter=MyFormatter())
    parser.add_option('--version',
                      action='store_true',
                      dest='version',
                      help='show version information and exit')

    group = parser.add_option_group('General options')
    group.add_option('-b',
                     metavar='BUILDER',
                     dest='builder',
                     default='html',
                     help='builder to use; default is html')
    group.add_option('-a',
                     action='store_true',
                     dest='force_all',
                     help='write all files; default is to only write new and '
                     'changed files')
    group.add_option('-E',
                     action='store_true',
                     dest='freshenv',
                     help='don\'t use a saved environment, always read '
                     'all files')
    group.add_option('-d',
                     metavar='PATH',
                     default=None,
                     dest='doctreedir',
                     help='path for the cached environment and doctree files '
                     '(default: outdir/.doctrees)')
    group.add_option('-j',
                     metavar='N',
                     default=1,
                     type='int',
                     dest='jobs',
                     help='build in parallel with N processes where possible')
    # this option never gets through to this point (it is intercepted earlier)
    # group.add_option('-M', metavar='BUILDER', dest='make_mode',
    #                 help='"make" mode -- as used by Makefile, like '
    #                 '"sphinx-build -M html"')

    group = parser.add_option_group('Build configuration options')
    group.add_option('-c',
                     metavar='PATH',
                     dest='confdir',
                     help='path where configuration file (conf.py) is located '
                     '(default: same as sourcedir)')
    group.add_option('-C',
                     action='store_true',
                     dest='noconfig',
                     help='use no config file at all, only -D options')
    group.add_option('-D',
                     metavar='setting=value',
                     action='append',
                     dest='define',
                     default=[],
                     help='override a setting in configuration file')
    group.add_option('-A',
                     metavar='name=value',
                     action='append',
                     dest='htmldefine',
                     default=[],
                     help='pass a value into HTML templates')
    group.add_option('-t',
                     metavar='TAG',
                     action='append',
                     dest='tags',
                     default=[],
                     help='define tag: include "only" blocks with TAG')
    group.add_option('-n',
                     action='store_true',
                     dest='nitpicky',
                     help='nit-picky mode, warn about all missing references')

    group = parser.add_option_group('Console output options')
    group.add_option('-v',
                     action='count',
                     dest='verbosity',
                     default=0,
                     help='increase verbosity (can be repeated)')
    group.add_option('-q',
                     action='store_true',
                     dest='quiet',
                     help='no output on stdout, just warnings on stderr')
    group.add_option('-Q',
                     action='store_true',
                     dest='really_quiet',
                     help='no output at all, not even warnings')
    group.add_option('-N',
                     action='store_true',
                     dest='nocolor',
                     help='do not emit colored output')
    group.add_option('-w',
                     metavar='FILE',
                     dest='warnfile',
                     help='write warnings (and errors) to given file')
    group.add_option('-W',
                     action='store_true',
                     dest='warningiserror',
                     help='turn warnings into errors')
    group.add_option('-T',
                     action='store_true',
                     dest='traceback',
                     help='show full traceback on exception')
    group.add_option('-P',
                     action='store_true',
                     dest='pdb',
                     help='run Pdb on exception')

    # parse options
    try:
        opts, args = parser.parse_args(argv[1:])
    except SystemExit as err:
        return err.code

    # handle basic options
    if opts.version:
        print('Sphinx (sphinx-build) %s' % __display_version__)
        return 0

    # get paths (first and second positional argument)
    try:
        srcdir = abspath(args[0])
        confdir = abspath(opts.confdir or srcdir)
        if opts.noconfig:
            confdir = None
        if not path.isdir(srcdir):
            print('Error: Cannot find source directory `%s\'.' % srcdir,
                  file=sys.stderr)
            return 1
        if not opts.noconfig and not path.isfile(path.join(confdir,
                                                           'conf.py')):
            print('Error: Config directory doesn\'t contain a conf.py file.',
                  file=sys.stderr)
            return 1
        outdir = abspath(args[1])
    except IndexError:
        parser.print_help()
        return 1
    except UnicodeError:
        print('Error: Multibyte filename not supported on this filesystem '
              'encoding (%r).' % fs_encoding,
              file=sys.stderr)
        return 1

    # handle remaining filename arguments
    filenames = args[2:]
    err = 0
    for filename in filenames:
        if not path.isfile(filename):
            print('Error: Cannot find file %r.' % filename, file=sys.stderr)
            err = 1
    if err:
        return 1

    # likely encoding used for command-line arguments
    try:
        locale = __import__('locale')  # due to submodule of the same name
        likely_encoding = locale.getpreferredencoding()
    except Exception:
        likely_encoding = None

    if opts.force_all and filenames:
        print('Error: Cannot combine -a option and filenames.',
              file=sys.stderr)
        return 1

    if opts.nocolor:
        nocolor()

    doctreedir = abspath(opts.doctreedir or path.join(outdir, '.doctrees'))

    status = sys.stdout
    warning = sys.stderr
    error = sys.stderr

    if opts.quiet:
        status = None
    if opts.really_quiet:
        status = warning = None
    if warning and opts.warnfile:
        try:
            warnfp = open(opts.warnfile, 'w')
        except Exception as exc:
            print('Error: Cannot open warning file %r: %s' %
                  (opts.warnfile, exc),
                  file=sys.stderr)
            sys.exit(1)
        warning = Tee(warning, warnfp)
        error = warning

    confoverrides = {}
    for val in opts.define:
        try:
            key, val = val.split('=')
        except ValueError:
            print('Error: -D option argument must be in the form name=value.',
                  file=sys.stderr)
            return 1
        if likely_encoding and isinstance(val, binary_type):
            try:
                val = val.decode(likely_encoding)
            except UnicodeError:
                pass
        confoverrides[key] = val

    for val in opts.htmldefine:
        try:
            key, val = val.split('=')
        except ValueError:
            print('Error: -A option argument must be in the form name=value.',
                  file=sys.stderr)
            return 1
        try:
            val = int(val)
        except ValueError:
            if likely_encoding and isinstance(val, binary_type):
                try:
                    val = val.decode(likely_encoding)
                except UnicodeError:
                    pass
        confoverrides['html_context.%s' % key] = val

    if opts.nitpicky:
        confoverrides['nitpicky'] = True

    app = None
    try:
        app = Sphinx(srcdir, confdir, outdir, doctreedir, opts.builder,
                     confoverrides, status, warning, opts.freshenv,
                     opts.warningiserror, opts.tags, opts.verbosity, opts.jobs)
        app.build(opts.force_all, filenames)
        return app.statuscode
    except (Exception, KeyboardInterrupt) as err:
        if opts.pdb:
            import pdb
            print(red('Exception occurred while building, starting debugger:'),
                  file=error)
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        else:
            print(file=error)
            if opts.verbosity or opts.traceback:
                traceback.print_exc(None, error)
                print(file=error)
            if isinstance(err, KeyboardInterrupt):
                print('interrupted!', file=error)
            elif isinstance(err, SystemMessage):
                print(red('reST markup error:'), file=error)
                print(terminal_safe(err.args[0]), file=error)
            elif isinstance(err, SphinxError):
                print(red('%s:' % err.category), file=error)
                print(terminal_safe(text_type(err)), file=error)
            elif isinstance(err, UnicodeError):
                print(red('Encoding error:'), file=error)
                print(terminal_safe(text_type(err)), file=error)
                tbpath = save_traceback(app)
                print(red(
                    'The full traceback has been saved in %s, if you want '
                    'to report the issue to the developers.' % tbpath),
                      file=error)
            else:
                print(red('Exception occurred:'), file=error)
                print(format_exception_cut_frames().rstrip(), file=error)
                tbpath = save_traceback(app)
                print(red('The full traceback has been saved in %s, if you '
                          'want to report the issue to the developers.' %
                          tbpath),
                      file=error)
                print(
                    'Please also report this if it was a user error, so '
                    'that a better error message can be provided next time.',
                    file=error)
                print(
                    'A bug report can be filed in the tracker at '
                    '<https://github.com/sphinx-doc/sphinx/issues>. Thanks!',
                    file=error)
            return 1
Ejemplo n.º 4
0
def main(argv=sys.argv):
    if not sys.stdout.isatty() or sys.platform == 'win32':
        # Windows' poor cmd box doesn't understand ANSI sequences
        nocolor()

    try:
        opts, args = getopt.getopt(argv[1:], 'ab:d:D:NEqP')
        srcdir = path.abspath(args[0])
        if not path.isdir(srcdir):
            print >> sys.stderr, 'Error: Cannot find source directory.'
            return 1
        if not path.isfile(path.join(srcdir, 'conf.py')):
            print >> sys.stderr, 'Error: Source directory doesn\'t contain conf.py file.'
            return 1
        outdir = path.abspath(args[1])
        if not path.isdir(outdir):
            print >> sys.stderr, 'Error: Cannot find output directory.'
            return 1
    except (IndexError, getopt.error):
        usage(argv)
        return 1

    filenames = args[2:]
    err = 0
    for filename in filenames:
        if not path.isfile(filename):
            print >> sys.stderr, 'Cannot find file %r.' % filename
            err = 1
    if err:
        return 1

    buildername = all_files = None
    freshenv = use_pdb = False
    status = sys.stdout
    confoverrides = {}
    doctreedir = path.join(outdir, '.doctrees')
    for opt, val in opts:
        if opt == '-b':
            buildername = val
        elif opt == '-a':
            if filenames:
                usage(argv, 'Cannot combine -a option and filenames.')
                return 1
            all_files = True
        elif opt == '-d':
            doctreedir = val
        elif opt == '-D':
            key, val = val.split('=')
            try:
                val = int(val)
            except:
                pass
            confoverrides[key] = val
        elif opt == '-N':
            nocolor()
        elif opt == '-E':
            freshenv = True
        elif opt == '-q':
            status = StringIO()
        elif opt == '-P':
            use_pdb = True

    try:
        app = Sphinx(srcdir, outdir, doctreedir, buildername, confoverrides,
                     status, sys.stderr, freshenv)
        if not app.builder:
            return 1

        if all_files:
            app.builder.build_all()
        elif filenames:
            app.builder.build_specific(filenames)
        else:
            app.builder.build_update()
    except KeyboardInterrupt:
        # catches BaseExceptions in 2.5 -- SystemExit, KeyboardInterrupt
        return 1
    except SystemExit:
        return 0
    except Exception, err:
        if use_pdb:
            import pdb
            print >> sys.stderr, darkred('Exception occurred while building, '
                                         'starting debugger:')
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        else:
            if isinstance(err, SystemMessage):
                print >> sys.stderr, darkred('reST markup error:')
                print >> sys.stderr, str(err)
            else:
                print >> sys.stderr, darkred('Exception occurred:')
                print >> sys.stderr, format_exception_cut_frames().rstrip()
                tbpath = save_traceback()
                print >> sys.stderr, darkred(
                    'The full traceback has been saved '
                    'in %s, if you want to report the '
                    'issue to the author.' % tbpath)
                print >> sys.stderr, (
                    'Please also report this if it was a user '
                    'error, so that a better error message '
                    'can be provided next time.')
                print >> sys.stderr, 'Send reports to [email protected]. Thanks!'
            return 1
Ejemplo n.º 5
0
 print(file=error)
 if show_traceback:
     traceback.print_exc(None, error)
     print(file=error)
 if isinstance(err, KeyboardInterrupt):
     print('interrupted!', file=error)
 elif isinstance(err, SystemMessage):
     print(red('reST markup error:'), file=error)
     print(terminal_safe(err.args[0]), file=error)
 elif isinstance(err, SphinxError):
     print(red('%s:' % err.category), file=error)
     print(terminal_safe(unicode(err)), file=error)
 elif isinstance(err, UnicodeError):
     print(red('Encoding error:'), file=error)
     print(terminal_safe(unicode(err)), file=error)
     tbpath = save_traceback(app)
     print(red(
         'The full traceback has been saved in %s, if you want '
         'to report the issue to the developers.' % tbpath),
           file=error)
 else:
     print(red('Exception occurred:'), file=error)
     print(format_exception_cut_frames().rstrip(), file=error)
     tbpath = save_traceback(app)
     print(red('The full traceback has been saved in %s, if you '
               'want to report the issue to the developers.' %
               tbpath),
           file=error)
     print(
         'Please also report this if it was a user error, so '
         'that a better error message can be provided next time.',
Ejemplo n.º 6
0
def main(argv=sys.argv):
    # delay-import these to be able to get sphinx.__version__ from setup.py
    # even without docutils installed
    from sphinx.application import Sphinx, SphinxError
    from docutils.utils import SystemMessage

    if not sys.stdout.isatty() or sys.platform == 'win32':
        # Windows' poor cmd box doesn't understand ANSI sequences
        nocolor()

    try:
        opts, args = getopt.getopt(argv[1:], 'ab:d:c:D:NEqP')
        srcdir = confdir = path.abspath(args[0])
        if not path.isdir(srcdir):
            print >>sys.stderr, 'Error: Cannot find source directory.'
            return 1
        if not path.isfile(path.join(srcdir, 'conf.py')) and \
               '-c' not in (opt[0] for opt in opts):
            print >>sys.stderr, 'Error: Source directory doesn\'t contain conf.py file.'
            return 1
        outdir = path.abspath(args[1])
        if not path.isdir(outdir):
            print >>sys.stderr, 'Error: Cannot find output directory.'
            return 1
    except (IndexError, getopt.error):
        usage(argv)
        return 1

    filenames = args[2:]
    err = 0
    for filename in filenames:
        if not path.isfile(filename):
            print >>sys.stderr, 'Cannot find file %r.' % filename
            err = 1
    if err:
        return 1

    buildername = all_files = None
    freshenv = use_pdb = False
    status = sys.stdout
    confoverrides = {}
    doctreedir = path.join(outdir, '.doctrees')
    for opt, val in opts:
        if opt == '-b':
            buildername = val
        elif opt == '-a':
            if filenames:
                usage(argv, 'Cannot combine -a option and filenames.')
                return 1
            all_files = True
        elif opt == '-d':
            doctreedir = path.abspath(val)
        elif opt == '-c':
            confdir = path.abspath(val)
            if not path.isfile(path.join(confdir, 'conf.py')):
                print >>sys.stderr, \
                      'Error: Configuration directory doesn\'t contain conf.py file.'
                return 1
        elif opt == '-D':
            key, val = val.split('=')
            try:
                val = int(val)
            except ValueError:
                pass
            confoverrides[key] = val
        elif opt == '-N':
            nocolor()
        elif opt == '-E':
            freshenv = True
        elif opt == '-q':
            status = StringIO()
        elif opt == '-P':
            use_pdb = True

    try:
        app = Sphinx(srcdir, confdir, outdir, doctreedir, buildername,
                     confoverrides, status, sys.stderr, freshenv)
        app.build(all_files, filenames)
    except KeyboardInterrupt:
        if use_pdb:
            import pdb
            print >>sys.stderr, darkred('Interrupted while building, starting debugger:')
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        return 1
    except Exception, err:
        if use_pdb:
            import pdb
            print >>sys.stderr, darkred('Exception occurred while building, '
                                        'starting debugger:')
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        else:
            if isinstance(err, SystemMessage):
                print >>sys.stderr, darkred('reST markup error:')
                print >>sys.stderr, err.args[0].encode('ascii', 'backslashreplace')
            elif isinstance(err, SphinxError):
                print >>sys.stderr, darkred('%s:' % err.category)
                print >>sys.stderr, err
            else:
                print >>sys.stderr, darkred('Exception occurred:')
                print >>sys.stderr, format_exception_cut_frames().rstrip()
                tbpath = save_traceback()
                print >>sys.stderr, darkred('The full traceback has been saved '
                                            'in %s, if you want to report the '
                                            'issue to the author.' % tbpath)
                print >>sys.stderr, ('Please also report this if it was a user '
                                     'error, so that a better error message '
                                     'can be provided next time.')
                print >>sys.stderr, ('Send reports to [email protected]. '
                                     'Thanks!')
            return 1
Ejemplo n.º 7
0
def main(argv):
    if not color_terminal():
        # Windows' poor cmd box doesn't understand ANSI sequences
        nocolor()

    try:
        opts, args = getopt.getopt(argv[1:], 'ab:t:d:c:CD:A:g:NEqQWw:P')
        allopts = set(opt[0] for opt in opts)
        srcdir = confdir = path.abspath(args[0])
        if not path.isdir(srcdir):
            print >> sys.stderr, 'Error: Cannot find source directory.'
            return 1
        if not path.isfile(path.join(srcdir, 'conf.py')) and \
               '-c' not in allopts and '-C' not in allopts:
            print >> sys.stderr, ('Error: Source directory doesn\'t '
                                  'contain conf.py file.')
            return 1
        outdir = path.abspath(args[1])
        if not path.isdir(outdir):
            print >> sys.stderr, 'Making output directory...'
            os.makedirs(outdir)
    except (IndexError, getopt.error):
        usage(argv)
        return 1

    filenames = args[2:]
    err = 0
    for filename in filenames:
        if not path.isfile(filename):
            print >> sys.stderr, 'Cannot find file %r.' % filename
            err = 1
    if err:
        return 1

    buildername = all_files = None
    freshenv = warningiserror = use_pdb = False
    status = sys.stdout
    warning = sys.stderr
    error = sys.stderr
    warnfile = None
    confoverrides = {}
    htmlcontext = {}
    tags = []
    doctreedir = path.join(outdir, '.doctrees')
    for opt, val in opts:
        if opt == '-b':
            buildername = val
        elif opt == '-a':
            if filenames:
                usage(argv, 'Cannot combine -a option and filenames.')
                return 1
            all_files = True
        elif opt == '-t':
            tags.append(val)
        elif opt == '-d':
            doctreedir = path.abspath(val)
        elif opt == '-c':
            confdir = path.abspath(val)
            if not path.isfile(path.join(confdir, 'conf.py')):
                print >> sys.stderr, ('Error: Configuration directory '
                                      'doesn\'t contain conf.py file.')
                return 1
        elif opt == '-C':
            confdir = None
        elif opt == '-D':
            try:
                key, val = val.split('=')
            except ValueError:
                print >> sys.stderr, ('Error: -D option argument must be '
                                      'in the form name=value.')
                return 1
            try:
                val = int(val)
            except ValueError:
                pass
            confoverrides[key] = val
        elif opt == '-A':
            try:
                key, val = val.split('=')
            except ValueError:
                print >> sys.stderr, ('Error: -A option argument must be '
                                      'in the form name=value.')
                return 1
            try:
                val = int(val)
            except ValueError:
                pass
            htmlcontext[key] = val
        elif opt == '-N':
            nocolor()
        elif opt == '-E':
            freshenv = True
        elif opt == '-q':
            status = None
        elif opt == '-Q':
            status = None
            warning = None
        elif opt == '-W':
            warningiserror = True
        elif opt == '-w':
            warnfile = val
        elif opt == '-P':
            use_pdb = True
    confoverrides['html_context'] = htmlcontext

    if warning and warnfile:
        warnfp = open(warnfile, 'w')
        warning = Tee(warning, warnfp)
        error = warning

    try:
        app = Sphinx(srcdir, confdir, outdir, doctreedir, buildername,
                     confoverrides, status, warning, freshenv, warningiserror,
                     tags)
        app.build(all_files, filenames)
        return app.statuscode
    except KeyboardInterrupt:
        if use_pdb:
            import pdb
            print >> error, red('Interrupted while building, '
                                'starting debugger:')
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        return 1
    except Exception, err:
        if use_pdb:
            import pdb
            print >> error, red('Exception occurred while building, '
                                'starting debugger:')
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        else:
            print >> error
            if isinstance(err, SystemMessage):
                print >> error, red('reST markup error:')
                print >> error, err.args[0].encode('ascii', 'backslashreplace')
            elif isinstance(err, SphinxError):
                print >> error, red('%s:' % err.category)
                print >> error, err
            else:
                print >> error, red('Exception occurred:')
                print >> error, format_exception_cut_frames().rstrip()
                tbpath = save_traceback()
                print >> error, red('The full traceback has been saved '
                                    'in %s, if you want to report the '
                                    'issue to the author.' % tbpath)
                print >> error, ('Please also report this if it was a user '
                                 'error, so that a better error message '
                                 'can be provided next time.')
                print >> error, (
                    'Send reports to [email protected]. '
                    'Thanks!')
            return 1
Ejemplo n.º 8
0
def main(argv):
    if not color_terminal():
        nocolor()

    parser = optparse.OptionParser(USAGE, epilog=EPILOG, formatter=MyFormatter())
    parser.add_option('--version', action='store_true', dest='version',
                      help='show version information and exit')

    group = parser.add_option_group('General options')
    group.add_option('-b', metavar='BUILDER', dest='builder', default='html',
                     help='builder to use; default is html')
    group.add_option('-a', action='store_true', dest='force_all',
                     help='write all files; default is to only write new and '
                     'changed files')
    group.add_option('-E', action='store_true', dest='freshenv',
                     help='don\'t use a saved environment, always read '
                     'all files')
    group.add_option('-d', metavar='PATH', default=None, dest='doctreedir',
                     help='path for the cached environment and doctree files '
                     '(default: outdir/.doctrees)')
    group.add_option('-j', metavar='N', default=1, type='int', dest='jobs',
                     help='build in parallel with N processes where possible')
    # this option never gets through to this point (it is intercepted earlier)
    # group.add_option('-M', metavar='BUILDER', dest='make_mode',
    #                 help='"make" mode -- as used by Makefile, like '
    #                 '"sphinx-build -M html"')

    group = parser.add_option_group('Build configuration options')
    group.add_option('-c', metavar='PATH', dest='confdir',
                     help='path where configuration file (conf.py) is located '
                     '(default: same as sourcedir)')
    group.add_option('-C', action='store_true', dest='noconfig',
                     help='use no config file at all, only -D options')
    group.add_option('-D', metavar='setting=value', action='append',
                     dest='define', default=[],
                     help='override a setting in configuration file')
    group.add_option('-A', metavar='name=value', action='append',
                     dest='htmldefine', default=[],
                     help='pass a value into HTML templates')
    group.add_option('-t', metavar='TAG', action='append',
                     dest='tags', default=[],
                     help='define tag: include "only" blocks with TAG')
    group.add_option('-n', action='store_true', dest='nitpicky',
                     help='nit-picky mode, warn about all missing references')

    group = parser.add_option_group('Console output options')
    group.add_option('-v', action='count', dest='verbosity', default=0,
                     help='increase verbosity (can be repeated)')
    group.add_option('-q', action='store_true', dest='quiet',
                     help='no output on stdout, just warnings on stderr')
    group.add_option('-Q', action='store_true', dest='really_quiet',
                     help='no output at all, not even warnings')
    group.add_option('-N', action='store_true', dest='nocolor',
                     help='do not emit colored output')
    group.add_option('-w', metavar='FILE', dest='warnfile',
                     help='write warnings (and errors) to given file')
    group.add_option('-W', action='store_true', dest='warningiserror',
                     help='turn warnings into errors')
    group.add_option('-T', action='store_true', dest='traceback',
                     help='show full traceback on exception')
    group.add_option('-P', action='store_true', dest='pdb',
                     help='run Pdb on exception')

    # parse options
    try:
        opts, args = parser.parse_args(argv[1:])
    except SystemExit as err:
        return err.code

    # handle basic options
    if opts.version:
        print('Sphinx (sphinx-build) %s' % __version__)
        return 0

    # get paths (first and second positional argument)
    try:
        srcdir = abspath(args[0])
        confdir = abspath(opts.confdir or srcdir)
        if opts.noconfig:
            confdir = None
        if not path.isdir(srcdir):
            print('Error: Cannot find source directory `%s\'.' % srcdir,
                  file=sys.stderr)
            return 1
        if not opts.noconfig and not path.isfile(path.join(confdir, 'conf.py')):
            print('Error: Config directory doesn\'t contain a conf.py file.',
                  file=sys.stderr)
            return 1
        outdir = abspath(args[1])
    except IndexError:
        usage(argv, 'Error: Insufficient arguments.')
        return 1
    except UnicodeError:
        print(
            'Error: Multibyte filename not supported on this filesystem '
            'encoding (%r).' % fs_encoding, file=sys.stderr)
        return 1

    # handle remaining filename arguments
    filenames = args[2:]
    err = 0
    for filename in filenames:
        if not path.isfile(filename):
            print('Error: Cannot find file %r.' % filename, file=sys.stderr)
            err = 1
    if err:
        return 1

    # likely encoding used for command-line arguments
    try:
        locale = __import__('locale')  # due to submodule of the same name
        likely_encoding = locale.getpreferredencoding()
    except Exception:
        likely_encoding = None

    if opts.force_all and filenames:
        print('Error: Cannot combine -a option and filenames.', file=sys.stderr)
        return 1

    if opts.nocolor:
        nocolor()

    doctreedir = abspath(opts.doctreedir or path.join(outdir, '.doctrees'))

    status = sys.stdout
    warning = sys.stderr
    error = sys.stderr

    if opts.quiet:
        status = None
    if opts.really_quiet:
        status = warning = None
    if warning and opts.warnfile:
        try:
            warnfp = open(opts.warnfile, 'w')
        except Exception as exc:
            print('Error: Cannot open warning file %r: %s' %
                  (opts.warnfile, exc), file=sys.stderr)
            sys.exit(1)
        warning = Tee(warning, warnfp)
        error = warning

    confoverrides = {}
    for val in opts.define:
        try:
            key, val = val.split('=')
        except ValueError:
            print('Error: -D option argument must be in the form name=value.',
                  file=sys.stderr)
            return 1
        if likely_encoding and isinstance(val, binary_type):
            try:
                val = val.decode(likely_encoding)
            except UnicodeError:
                pass
        confoverrides[key] = val

    for val in opts.htmldefine:
        try:
            key, val = val.split('=')
        except ValueError:
            print('Error: -A option argument must be in the form name=value.',
                  file=sys.stderr)
            return 1
        try:
            val = int(val)
        except ValueError:
            if likely_encoding and isinstance(val, binary_type):
                try:
                    val = val.decode(likely_encoding)
                except UnicodeError:
                    pass
        confoverrides['html_context.%s' % key] = val

    if opts.nitpicky:
        confoverrides['nitpicky'] = True

    app = None
    try:
        app = Sphinx(srcdir, confdir, outdir, doctreedir, opts.builder,
                     confoverrides, status, warning, opts.freshenv,
                     opts.warningiserror, opts.tags, opts.verbosity, opts.jobs)
        app.build(opts.force_all, filenames)
        return app.statuscode
    except (Exception, KeyboardInterrupt) as err:
        if opts.pdb:
            import pdb
            print(red('Exception occurred while building, starting debugger:'),
                  file=error)
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        else:
            print(file=error)
            if opts.verbosity or opts.traceback:
                traceback.print_exc(None, error)
                print(file=error)
            if isinstance(err, KeyboardInterrupt):
                print('interrupted!', file=error)
            elif isinstance(err, SystemMessage):
                print(red('reST markup error:'), file=error)
                print(terminal_safe(err.args[0]), file=error)
            elif isinstance(err, SphinxError):
                print(red('%s:' % err.category), file=error)
                print(terminal_safe(text_type(err)), file=error)
            elif isinstance(err, UnicodeError):
                print(red('Encoding error:'), file=error)
                print(terminal_safe(text_type(err)), file=error)
                tbpath = save_traceback(app)
                print(red('The full traceback has been saved in %s, if you want '
                          'to report the issue to the developers.' % tbpath),
                      file=error)
            else:
                print(red('Exception occurred:'), file=error)
                print(format_exception_cut_frames().rstrip(), file=error)
                tbpath = save_traceback(app)
                print(red('The full traceback has been saved in %s, if you '
                          'want to report the issue to the developers.' % tbpath),
                      file=error)
                print('Please also report this if it was a user error, so '
                      'that a better error message can be provided next time.',
                      file=error)
                print('A bug report can be filed in the tracker at '
                      '<https://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!',
                      file=error)
            return 1
Ejemplo n.º 9
0
 print(file=error)
 if show_traceback:
     traceback.print_exc(None, error)
     print(file=error)
 if isinstance(err, KeyboardInterrupt):
     print('interrupted!', file=error)
 elif isinstance(err, SystemMessage):
     print(red('reST markup error:'), file=error)
     print(terminal_safe(err.args[0]), file=error)
 elif isinstance(err, SphinxError):
     print(red('%s:' % err.category), file=error)
     print(terminal_safe(unicode(err)), file=error)
 elif isinstance(err, UnicodeError):
     print(red('Encoding error:'), file=error)
     print(terminal_safe(unicode(err)), file=error)
     tbpath = save_traceback(app)
     print(red('The full traceback has been saved in %s, if you want '
               'to report the issue to the developers.' % tbpath),
           file=error)
 else:
     print(red('Exception occurred:'), file=error)
     print(format_exception_cut_frames().rstrip(), file=error)
     tbpath = save_traceback(app)
     print(red('The full traceback has been saved in %s, if you '
               'want to report the issue to the developers.' % tbpath),
           file=error)
     print('Please also report this if it was a user error, so '
           'that a better error message can be provided next time.',
           file=error)
     print('A bug report can be filed in the tracker at '
           '<https://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!',
Ejemplo n.º 10
0
def main(argv=sys.argv):
    if not sys.stdout.isatty() or sys.platform == 'win32':
        # Windows' poor cmd box doesn't understand ANSI sequences
        nocolor()

    try:
        opts, args = getopt.getopt(argv[1:], 'ab:d:D:NEqP')
        srcdir = path.abspath(args[0])
        if not path.isdir(srcdir):
            print >>sys.stderr, 'Error: Cannot find source directory.'
            return 1
        if not path.isfile(path.join(srcdir, 'conf.py')):
            print >>sys.stderr, 'Error: Source directory doesn\'t contain conf.py file.'
            return 1
        outdir = path.abspath(args[1])
        if not path.isdir(outdir):
            print >>sys.stderr, 'Error: Cannot find output directory.'
            return 1
    except (IndexError, getopt.error):
        usage(argv)
        return 1

    filenames = args[2:]
    err = 0
    for filename in filenames:
        if not path.isfile(filename):
            print >>sys.stderr, 'Cannot find file %r.' % filename
            err = 1
    if err:
        return 1

    buildername = all_files = None
    freshenv = use_pdb = False
    status = sys.stdout
    confoverrides = {}
    doctreedir = path.join(outdir, '.doctrees')
    for opt, val in opts:
        if opt == '-b':
            buildername = val
        elif opt == '-a':
            if filenames:
                usage(argv, 'Cannot combine -a option and filenames.')
                return 1
            all_files = True
        elif opt == '-d':
            doctreedir = val
        elif opt == '-D':
            key, val = val.split('=')
            try:
                val = int(val)
            except: pass
            confoverrides[key] = val
        elif opt == '-N':
            nocolor()
        elif opt == '-E':
            freshenv = True
        elif opt == '-q':
            status = StringIO()
        elif opt == '-P':
            use_pdb = True

    try:
        app = Sphinx(srcdir, outdir, doctreedir, buildername,
                     confoverrides, status, sys.stderr, freshenv)
        if not app.builder:
            return 1

        if all_files:
            app.builder.build_all()
        elif filenames:
            app.builder.build_specific(filenames)
        else:
            app.builder.build_update()
    except KeyboardInterrupt:
        # catches BaseExceptions in 2.5 -- SystemExit, KeyboardInterrupt
        return 1
    except SystemExit:
        return 0
    except Exception, err:
        if use_pdb:
            import pdb
            print >>sys.stderr, darkred('Exception occurred while building, '
                                        'starting debugger:')
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        else:
            if isinstance(err, SystemMessage):
                print >>sys.stderr, darkred('reST markup error:')
                print >>sys.stderr, str(err)
            else:
                print >>sys.stderr, darkred('Exception occurred:')
                print >>sys.stderr, format_exception_cut_frames().rstrip()
                tbpath = save_traceback()
                print >>sys.stderr, darkred('The full traceback has been saved '
                                            'in %s, if you want to report the '
                                            'issue to the author.' % tbpath)
                print >>sys.stderr, ('Please also report this if it was a user '
                                     'error, so that a better error message '
                                     'can be provided next time.')
                print >>sys.stderr, 'Send reports to [email protected]. Thanks!'
            return 1
Ejemplo n.º 11
0
def main(argv):
    if not color_terminal():
        # Windows' poor cmd box doesn't understand ANSI sequences
        nocolor()

    # parse options
    try:
        opts, args = getopt.getopt(argv[1:], 'ab:t:d:c:CD:A:nNEqQWw:PThvj:',
                                   ['help', 'version'])
    except getopt.error as err:
        usage(argv, 'Error: %s' % err)
        return 1

    # handle basic options
    allopts = set(opt[0] for opt in opts)
    # help and version options
    if '-h' in allopts or '--help' in allopts:
        usage(argv)
        print(file=sys.stderr)
        print('For more information, see <http://sphinx-doc.org/>.',
              file=sys.stderr)
        return 0
    if '--version' in allopts:
        print('Sphinx (sphinx-build) %s' %  __version__)
        return 0

    # get paths (first and second positional argument)
    try:
        srcdir = confdir = abspath(args[0])
        if not path.isdir(srcdir):
            print('Error: Cannot find source directory `%s\'.' % srcdir,
                  file=sys.stderr)
            return 1
        if not path.isfile(path.join(srcdir, 'conf.py')) and \
               '-c' not in allopts and '-C' not in allopts:
            print('Error: Source directory doesn\'t contain a conf.py file.',
                  file=sys.stderr)
            return 1
        outdir = abspath(args[1])
    except IndexError:
        usage(argv, 'Error: Insufficient arguments.')
        return 1
    except UnicodeError:
        print(
            'Error: Multibyte filename not supported on this filesystem '
            'encoding (%r).' % fs_encoding, file=sys.stderr)
        return 1

    # handle remaining filename arguments
    filenames = args[2:]
    err = 0
    for filename in filenames:
        if not path.isfile(filename):
            print('Error: Cannot find file %r.' % filename, file=sys.stderr)
            err = 1
    if err:
        return 1

    # likely encoding used for command-line arguments
    try:
        locale = __import__('locale')  # due to submodule of the same name
        likely_encoding = locale.getpreferredencoding()
    except Exception:
        likely_encoding = None

    buildername = None
    force_all = freshenv = warningiserror = use_pdb = False
    show_traceback = False
    verbosity = 0
    parallel = 0
    status = sys.stdout
    warning = sys.stderr
    error = sys.stderr
    warnfile = None
    confoverrides = {}
    tags = []
    doctreedir = path.join(outdir, '.doctrees')
    for opt, val in opts:
        if opt == '-b':
            buildername = val
        elif opt == '-a':
            if filenames:
                usage(argv, 'Error: Cannot combine -a option and filenames.')
                return 1
            force_all = True
        elif opt == '-t':
            tags.append(val)
        elif opt == '-d':
            doctreedir = abspath(val)
        elif opt == '-c':
            confdir = abspath(val)
            if not path.isfile(path.join(confdir, 'conf.py')):
                print('Error: Configuration directory doesn\'t contain conf.py file.',
                      file=sys.stderr)
                return 1
        elif opt == '-C':
            confdir = None
        elif opt == '-D':
            try:
                key, val = val.split('=')
            except ValueError:
                print('Error: -D option argument must be in the form name=value.',
                      file=sys.stderr)
                return 1
            if likely_encoding and isinstance(val, binary_type):
                try:
                    val = val.decode(likely_encoding)
                except UnicodeError:
                    pass
            confoverrides[key] = val
        elif opt == '-A':
            try:
                key, val = val.split('=')
            except ValueError:
                print('Error: -A option argument must be in the form name=value.',
                      file=sys.stderr)
                return 1
            try:
                val = int(val)
            except ValueError:
                if likely_encoding and isinstance(val, binary_type):
                    try:
                        val = val.decode(likely_encoding)
                    except UnicodeError:
                        pass
            confoverrides['html_context.%s' % key] = val
        elif opt == '-n':
            confoverrides['nitpicky'] = True
        elif opt == '-N':
            nocolor()
        elif opt == '-E':
            freshenv = True
        elif opt == '-q':
            status = None
        elif opt == '-Q':
            status = None
            warning = None
        elif opt == '-W':
            warningiserror = True
        elif opt == '-w':
            warnfile = val
        elif opt == '-P':
            use_pdb = True
        elif opt == '-T':
            show_traceback = True
        elif opt == '-v':
            verbosity += 1
            show_traceback = True
        elif opt == '-j':
            try:
                parallel = int(val)
            except ValueError:
                print('Error: -j option argument must be an integer.',
                      file=sys.stderr)
                return 1

    if warning and warnfile:
        warnfp = open(warnfile, 'w')
        warning = Tee(warning, warnfp)
        error = warning

    if not path.isdir(outdir):
        if status:
            print('Making output directory...', file=status)
        os.makedirs(outdir)

    app = None
    try:
        app = Sphinx(srcdir, confdir, outdir, doctreedir, buildername,
                     confoverrides, status, warning, freshenv,
                     warningiserror, tags, verbosity, parallel)
        app.build(force_all, filenames)
        return app.statuscode
    except (Exception, KeyboardInterrupt) as err:
        if use_pdb:
            import pdb
            print(red('Exception occurred while building, starting debugger:'),
                  file=error)
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        else:
            print(file=error)
            if show_traceback:
                traceback.print_exc(None, error)
                print(file=error)
            if isinstance(err, KeyboardInterrupt):
                print('interrupted!', file=error)
            elif isinstance(err, SystemMessage):
                print(red('reST markup error:'), file=error)
                print(terminal_safe(err.args[0]), file=error)
            elif isinstance(err, SphinxError):
                print(red('%s:' % err.category), file=error)
                print(terminal_safe(text_type(err)), file=error)
            elif isinstance(err, UnicodeError):
                print(red('Encoding error:'), file=error)
                print(terminal_safe(text_type(err)), file=error)
                tbpath = save_traceback(app)
                print(red('The full traceback has been saved in %s, if you want '
                          'to report the issue to the developers.' % tbpath),
                      file=error)
            else:
                print(red('Exception occurred:'), file=error)
                print(format_exception_cut_frames().rstrip(), file=error)
                tbpath = save_traceback(app)
                print(red('The full traceback has been saved in %s, if you '
                          'want to report the issue to the developers.' % tbpath),
                      file=error)
                print('Please also report this if it was a user error, so '
                      'that a better error message can be provided next time.',
                      file=error)
                print('A bug report can be filed in the tracker at '
                      '<https://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!',
                      file=error)
            return 1
Ejemplo n.º 12
0
 print >> error
 if show_traceback:
     traceback.print_exc(None, error)
     print >> error
 if isinstance(err, KeyboardInterrupt):
     print >> error, "interrupted!"
 elif isinstance(err, SystemMessage):
     print >> error, red("reST markup error:")
     print >> error, terminal_safe(err.args[0])
 elif isinstance(err, SphinxError):
     print >> error, red("%s:" % err.category)
     print >> error, terminal_safe(unicode(err))
 else:
     print >> error, red("Exception occurred:")
     print >> error, format_exception_cut_frames().rstrip()
     tbpath = save_traceback()
     print >> error, red(
         "The full traceback has been saved "
         "in %s, if you want to report the "
         "issue to the developers." % tbpath
     )
     print >> error, (
         "Please also report this if it was a user "
         "error, so that a better error message "
         "can be provided next time."
     )
     print >> error, (
         "Either send bugs to the mailing list at "
         "<http://groups.google.com/group/sphinx-users/>,\n"
         "or report them in the tracker at "
         "<http://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!"
Ejemplo n.º 13
0
def handle_exception(app, opts, exception, stderr=sys.stderr):
    if opts.pdb:
        import pdb

        print(red("Exception occurred while building, starting debugger:"), file=stderr)
        traceback.print_exc()
        pdb.post_mortem(sys.exc_info()[2])
    else:
        print(file=stderr)
        if opts.verbosity or opts.traceback:
            traceback.print_exc(None, stderr)
            print(file=stderr)
        if isinstance(exception, KeyboardInterrupt):
            print("interrupted!", file=stderr)
        elif isinstance(exception, SystemMessage):
            print(red("reST markup error:"), file=stderr)
            print(terminal_safe(exception.args[0]), file=stderr)
        elif isinstance(exception, SphinxError):
            print(red("%s:" % exception.category), file=stderr)
            print(terminal_safe(text_type(exception)), file=stderr)
        elif isinstance(exception, UnicodeError):
            print(red("Encoding error:"), file=stderr)
            print(terminal_safe(text_type(exception)), file=stderr)
            tbpath = save_traceback(app)
            print(
                red(
                    "The full traceback has been saved in %s, if you want "
                    "to report the issue to the developers." % tbpath
                ),
                file=stderr,
            )
        elif isinstance(exception, RuntimeError) and "recursion depth" in str(exception):
            print(red("Recursion error:"), file=stderr)
            print(terminal_safe(text_type(exception)), file=stderr)
            print(file=stderr)
            print(
                "This can happen with very large or deeply nested source "
                "files.  You can carefully increase the default Python "
                "recursion limit of 1000 in conf.py with e.g.:",
                file=stderr,
            )
            print("    import sys; sys.setrecursionlimit(1500)", file=stderr)
        else:
            print(red("Exception occurred:"), file=stderr)
            print(format_exception_cut_frames().rstrip(), file=stderr)
            tbpath = save_traceback(app)
            print(
                red(
                    "The full traceback has been saved in %s, if you "
                    "want to report the issue to the developers." % tbpath
                ),
                file=stderr,
            )
            print(
                "Please also report this if it was a user error, so "
                "that a better error message can be provided next time.",
                file=stderr,
            )
            print(
                "A bug report can be filed in the tracker at " "<https://github.com/sphinx-doc/sphinx/issues>. Thanks!",
                file=stderr,
            )
Ejemplo n.º 14
0
def main(argv):
    if not color_terminal():
        # Windows' poor cmd box doesn't understand ANSI sequences
        nocolor()

    try:
        opts, args = getopt.getopt(argv[1:], "ab:t:d:c:CD:A:ng:NEqQWw:P")
        allopts = set(opt[0] for opt in opts)
        srcdir = confdir = path.abspath(args[0])
        if not path.isdir(srcdir):
            print("Error: Cannot find source directory.", file=sys.stderr)
            return 1
        if not path.isfile(path.join(srcdir, "conf.py")) and "-c" not in allopts and "-C" not in allopts:
            print(("Error: Source directory doesn't " "contain conf.py file."), file=sys.stderr)
            return 1
        outdir = path.abspath(args[1])
        if not path.isdir(outdir):
            print("Making output directory...", file=sys.stderr)
            os.makedirs(outdir)
    except (IndexError, getopt.error):
        usage(argv)
        return 1

    filenames = args[2:]
    err = 0
    for filename in filenames:
        if not path.isfile(filename):
            print("Cannot find file %r." % filename, file=sys.stderr)
            err = 1
    if err:
        return 1

    # likely encoding used for command-line arguments
    try:
        locale = __import__("locale")  # due to submodule of the same name
        likely_encoding = locale.getpreferredencoding()
    except Exception:
        likely_encoding = None

    buildername = None
    force_all = freshenv = warningiserror = use_pdb = False
    status = sys.stdout
    warning = sys.stderr
    error = sys.stderr
    warnfile = None
    confoverrides = {}
    tags = []
    doctreedir = path.join(outdir, ".doctrees")
    for opt, val in opts:
        if opt == "-b":
            buildername = val
        elif opt == "-a":
            if filenames:
                usage(argv, "Cannot combine -a option and filenames.")
                return 1
            force_all = True
        elif opt == "-t":
            tags.append(val)
        elif opt == "-d":
            doctreedir = path.abspath(val)
        elif opt == "-c":
            confdir = path.abspath(val)
            if not path.isfile(path.join(confdir, "conf.py")):
                print(("Error: Configuration directory " "doesn't contain conf.py file."), file=sys.stderr)
                return 1
        elif opt == "-C":
            confdir = None
        elif opt == "-D":
            try:
                key, val = val.split("=")
            except ValueError:
                print(("Error: -D option argument must be " "in the form name=value."), file=sys.stderr)
                return 1
            try:
                val = int(val)
            except ValueError:
                if likely_encoding and isinstance(val, bytes):
                    try:
                        val = val.decode(likely_encoding)
                    except UnicodeError:
                        pass
            confoverrides[key] = val
        elif opt == "-A":
            try:
                key, val = val.split("=")
            except ValueError:
                print(("Error: -A option argument must be " "in the form name=value."), file=sys.stderr)
                return 1
            try:
                val = int(val)
            except ValueError:
                if likely_encoding and isinstance(val, bytes):
                    try:
                        val = val.decode(likely_encoding)
                    except UnicodeError:
                        pass
            confoverrides["html_context.%s" % key] = val
        elif opt == "-n":
            confoverrides["nitpicky"] = True
        elif opt == "-N":
            nocolor()
        elif opt == "-E":
            freshenv = True
        elif opt == "-q":
            status = None
        elif opt == "-Q":
            status = None
            warning = None
        elif opt == "-W":
            warningiserror = True
        elif opt == "-w":
            warnfile = val
        elif opt == "-P":
            use_pdb = True

    if warning and warnfile:
        warnfp = open(warnfile, "w")
        warning = Tee(warning, warnfp)
        error = warning

    try:
        app = Sphinx(
            srcdir,
            confdir,
            outdir,
            doctreedir,
            buildername,
            confoverrides,
            status,
            warning,
            freshenv,
            warningiserror,
            tags,
        )
        app.build(force_all, filenames)
        return app.statuscode
    except KeyboardInterrupt:
        if use_pdb:
            import pdb

            print(red("Interrupted while building, starting debugger:"), file=error)
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        return 1
    except Exception as err:
        if use_pdb:
            import pdb

            print(red("Exception occurred while building, " "starting debugger:"), file=error)
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        else:
            print(file=error)
            if isinstance(err, SystemMessage):
                print(red("reST markup error:"), file=error)
                print(terminal_safe(err.args[0]), file=error)
            elif isinstance(err, SphinxError):
                print(red("%s:" % err.category), file=error)
                print(terminal_safe(str(err)), file=error)
            else:
                print(red("Exception occurred:"), file=error)
                print(format_exception_cut_frames().rstrip(), file=error)
                tbpath = save_traceback()
                print(
                    red(
                        "The full traceback has been saved "
                        "in %s, if you want to report the "
                        "issue to the developers." % tbpath
                    ),
                    file=error,
                )
                print(
                    (
                        "Please also report this if it was a user "
                        "error, so that a better error message "
                        "can be provided next time."
                    ),
                    file=error,
                )
                print(
                    (
                        "Either send bugs to the mailing list at "
                        "<http://groups.google.com/group/sphinx-dev/>,\n"
                        "or report them in the tracker at "
                        "<http://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!"
                    ),
                    file=error,
                )
            return 1
Ejemplo n.º 15
0
def main(argv):
    if not color_terminal():
        nocolor()

    parser = optparse.OptionParser(USAGE, epilog=EPILOG, formatter=MyFormatter())
    parser.add_option("--version", action="store_true", dest="version", help="show version information and exit")

    group = parser.add_option_group("General options")
    group.add_option("-b", metavar="BUILDER", dest="builder", default="html", help="builder to use; default is html")
    group.add_option(
        "-a",
        action="store_true",
        dest="force_all",
        help="write all files; default is to only write new and " "changed files",
    )
    group.add_option(
        "-E", action="store_true", dest="freshenv", help="don't use a saved environment, always read " "all files"
    )
    group.add_option(
        "-d",
        metavar="PATH",
        default=None,
        dest="doctreedir",
        help="path for the cached environment and doctree files " "(default: outdir/.doctrees)",
    )
    group.add_option(
        "-j", metavar="N", default=1, type="int", dest="jobs", help="build in parallel with N processes where possible"
    )
    # this option never gets through to this point (it is intercepted earlier)
    # group.add_option('-M', metavar='BUILDER', dest='make_mode',
    #                 help='"make" mode -- as used by Makefile, like '
    #                 '"sphinx-build -M html"')

    group = parser.add_option_group("Build configuration options")
    group.add_option(
        "-c",
        metavar="PATH",
        dest="confdir",
        help="path where configuration file (conf.py) is located " "(default: same as sourcedir)",
    )
    group.add_option("-C", action="store_true", dest="noconfig", help="use no config file at all, only -D options")
    group.add_option(
        "-D",
        metavar="setting=value",
        action="append",
        dest="define",
        default=[],
        help="override a setting in configuration file",
    )
    group.add_option(
        "-A",
        metavar="name=value",
        action="append",
        dest="htmldefine",
        default=[],
        help="pass a value into HTML templates",
    )
    group.add_option(
        "-t", metavar="TAG", action="append", dest="tags", default=[], help='define tag: include "only" blocks with TAG'
    )
    group.add_option(
        "-n", action="store_true", dest="nitpicky", help="nit-picky mode, warn about all missing references"
    )

    group = parser.add_option_group("Console output options")
    group.add_option("-v", action="count", dest="verbosity", default=0, help="increase verbosity (can be repeated)")
    group.add_option("-q", action="store_true", dest="quiet", help="no output on stdout, just warnings on stderr")
    group.add_option("-Q", action="store_true", dest="really_quiet", help="no output at all, not even warnings")
    group.add_option("-N", action="store_true", dest="nocolor", help="do not emit colored output")
    group.add_option("-w", metavar="FILE", dest="warnfile", help="write warnings (and errors) to given file")
    group.add_option("-W", action="store_true", dest="warningiserror", help="turn warnings into errors")
    group.add_option("-T", action="store_true", dest="traceback", help="show full traceback on exception")
    group.add_option("-P", action="store_true", dest="pdb", help="run Pdb on exception")

    # parse options
    try:
        opts, args = parser.parse_args(list(argv[1:]))
    except SystemExit as err:
        return err.code

    # handle basic options
    if opts.version:
        print("Sphinx (sphinx-build) %s" % __display_version__)
        return 0

    # get paths (first and second positional argument)
    try:
        srcdir = abspath(args[0])
        confdir = abspath(opts.confdir or srcdir)
        if opts.noconfig:
            confdir = None
        if not path.isdir(srcdir):
            print("Error: Cannot find source directory `%s'." % srcdir, file=sys.stderr)
            return 1
        if not opts.noconfig and not path.isfile(path.join(confdir, "conf.py")):
            print("Error: Config directory doesn't contain a conf.py file.", file=sys.stderr)
            return 1
        outdir = abspath(args[1])
        if srcdir == outdir:
            print("Error: source directory and destination directory are same.", file=sys.stderr)
            return 1
    except IndexError:
        parser.print_help()
        return 1
    except UnicodeError:
        print(
            "Error: Multibyte filename not supported on this filesystem " "encoding (%r)." % fs_encoding,
            file=sys.stderr,
        )
        return 1

    # handle remaining filename arguments
    filenames = args[2:]
    err = 0
    for filename in filenames:
        if not path.isfile(filename):
            print("Error: Cannot find file %r." % filename, file=sys.stderr)
            err = 1
    if err:
        return 1

    # likely encoding used for command-line arguments
    try:
        locale = __import__("locale")  # due to submodule of the same name
        likely_encoding = locale.getpreferredencoding()
    except Exception:
        likely_encoding = None

    if opts.force_all and filenames:
        print("Error: Cannot combine -a option and filenames.", file=sys.stderr)
        return 1

    if opts.nocolor:
        nocolor()

    doctreedir = abspath(opts.doctreedir or path.join(outdir, ".doctrees"))

    status = sys.stdout
    warning = sys.stderr
    error = sys.stderr

    if opts.quiet:
        status = None
    if opts.really_quiet:
        status = warning = None
    if warning and opts.warnfile:
        try:
            warnfp = open(opts.warnfile, "w")
        except Exception as exc:
            print("Error: Cannot open warning file %r: %s" % (opts.warnfile, exc), file=sys.stderr)
            sys.exit(1)
        warning = Tee(warning, warnfp)
        error = warning

    confoverrides = {}
    for val in opts.define:
        try:
            key, val = val.split("=")
        except ValueError:
            print("Error: -D option argument must be in the form name=value.", file=sys.stderr)
            return 1
        if likely_encoding and isinstance(val, binary_type):
            try:
                val = val.decode(likely_encoding)
            except UnicodeError:
                pass
        confoverrides[key] = val

    for val in opts.htmldefine:
        try:
            key, val = val.split("=")
        except ValueError:
            print("Error: -A option argument must be in the form name=value.", file=sys.stderr)
            return 1
        try:
            val = int(val)
        except ValueError:
            if likely_encoding and isinstance(val, binary_type):
                try:
                    val = val.decode(likely_encoding)
                except UnicodeError:
                    pass
        confoverrides["html_context.%s" % key] = val

    if opts.nitpicky:
        confoverrides["nitpicky"] = True

    app = None
    try:
        app = Sphinx(
            srcdir,
            confdir,
            outdir,
            doctreedir,
            opts.builder,
            confoverrides,
            status,
            warning,
            opts.freshenv,
            opts.warningiserror,
            opts.tags,
            opts.verbosity,
            opts.jobs,
        )
        app.build(opts.force_all, filenames)
        return app.statuscode
    except (Exception, KeyboardInterrupt) as err:
        if opts.pdb:
            import pdb

            print(red("Exception occurred while building, starting debugger:"), file=error)
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        else:
            print(file=error)
            if opts.verbosity or opts.traceback:
                traceback.print_exc(None, error)
                print(file=error)
            if isinstance(err, KeyboardInterrupt):
                print("interrupted!", file=error)
            elif isinstance(err, SystemMessage):
                print(red("reST markup error:"), file=error)
                print(terminal_safe(err.args[0]), file=error)
            elif isinstance(err, SphinxError):
                print(red("%s:" % err.category), file=error)
                print(terminal_safe(text_type(err)), file=error)
            elif isinstance(err, UnicodeError):
                print(red("Encoding error:"), file=error)
                print(terminal_safe(text_type(err)), file=error)
                tbpath = save_traceback(app)
                print(
                    red(
                        "The full traceback has been saved in %s, if you want "
                        "to report the issue to the developers." % tbpath
                    ),
                    file=error,
                )
            else:
                print(red("Exception occurred:"), file=error)
                print(format_exception_cut_frames().rstrip(), file=error)
                tbpath = save_traceback(app)
                print(
                    red(
                        "The full traceback has been saved in %s, if you "
                        "want to report the issue to the developers." % tbpath
                    ),
                    file=error,
                )
                print(
                    "Please also report this if it was a user error, so "
                    "that a better error message can be provided next time.",
                    file=error,
                )
                print(
                    "A bug report can be filed in the tracker at "
                    "<https://github.com/sphinx-doc/sphinx/issues>. Thanks!",
                    file=error,
                )
            return 1
Ejemplo n.º 16
0
        else:
            print >> error
            if show_traceback:
                traceback.print_exc(None, error)
                print >> error
            if isinstance(err, KeyboardInterrupt):
                print >> error, 'interrupted!'
            elif isinstance(err, SystemMessage):
                print >> error, red('reST markup error:')
                print >> error, terminal_safe(err.args[0])
            elif isinstance(err, SphinxError):
                print >> error, red('%s:' % err.category)
                print >> error, terminal_safe(unicode(err))
            else:
                print >> error, red('Exception occurred:')
                print >> error, format_exception_cut_frames().rstrip()
                tbpath = save_traceback()
                print >> error, red('The full traceback has been saved '
                                    'in %s, if you want to report the '
                                    'issue to the developers.' % tbpath)
                print >> error, ('Please also report this if it was a user '
                                 'error, so that a better error message '
                                 'can be provided next time.')
                print >> error, (
                    'Either send bugs to the mailing list at '
                    '<http://groups.google.com/group/sphinx-users/>,\n'
                    'or report them in the tracker at '
                    '<http://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!'
                )
            return 1
def main(argv):
    if not color_terminal():
        # Windows' poor cmd box doesn't understand ANSI sequences
        nocolor()

    try:
        opts, args = getopt.getopt(argv[1:], 'ab:t:d:c:CD:A:ng:NEqQWw:P')
        allopts = set(opt[0] for opt in opts)
        srcdir = confdir = path.abspath(args[0])
        if not path.isdir(srcdir):
            print >> sys.stderr, 'Error: Cannot find source directory.'
            return 1
        if not path.isfile(path.join(srcdir, 'conf.py')) and \
               '-c' not in allopts and '-C' not in allopts:
            print >> sys.stderr, ('Error: Source directory doesn\'t '
                                  'contain conf.py file.')
            return 1
        outdir = path.abspath(args[1])
        if not path.isdir(outdir):
            print >> sys.stderr, 'Making output directory...'
            os.makedirs(outdir)
    except (IndexError, getopt.error):
        usage(argv)
        return 1

    filenames = args[2:]
    err = 0
    for filename in filenames:
        if not path.isfile(filename):
            print >> sys.stderr, 'Cannot find file %r.' % filename
            err = 1
    if err:
        return 1

    # likely encoding used for command-line arguments
    try:
        locale = __import__('locale')  # due to submodule of the same name
        likely_encoding = locale.getpreferredencoding()
    except Exception:
        likely_encoding = None

    buildername = None
    force_all = freshenv = warningiserror = use_pdb = False
    status = sys.stdout
    warning = sys.stderr
    error = sys.stderr
    warnfile = None
    confoverrides = {}
    tags = []
    doctreedir = path.join(outdir, '.doctrees')
    for opt, val in opts:
        if opt == '-b':
            buildername = val
        elif opt == '-a':
            if filenames:
                usage(argv, 'Cannot combine -a option and filenames.')
                return 1
            force_all = True
        elif opt == '-t':
            tags.append(val)
        elif opt == '-d':
            doctreedir = path.abspath(val)
        elif opt == '-c':
            confdir = path.abspath(val)
            if not path.isfile(path.join(confdir, 'conf.py')):
                print >> sys.stderr, ('Error: Configuration directory '
                                      'doesn\'t contain conf.py file.')
                return 1
        elif opt == '-C':
            confdir = None
        elif opt == '-D':
            try:
                key, val = val.split('=')
            except ValueError:
                print >> sys.stderr, ('Error: -D option argument must be '
                                      'in the form name=value.')
                return 1
            try:
                val = int(val)
            except ValueError:
                if likely_encoding:
                    try:
                        val = val.decode(likely_encoding)
                    except UnicodeError:
                        pass
            confoverrides[key] = val
        elif opt == '-A':
            try:
                key, val = val.split('=')
            except ValueError:
                print >> sys.stderr, ('Error: -A option argument must be '
                                      'in the form name=value.')
                return 1
            try:
                val = int(val)
            except ValueError:
                if likely_encoding:
                    try:
                        val = val.decode(likely_encoding)
                    except UnicodeError:
                        pass
            confoverrides['html_context.%s' % key] = val
        elif opt == '-n':
            confoverrides['nitpicky'] = True
        elif opt == '-N':
            nocolor()
        elif opt == '-E':
            freshenv = True
        elif opt == '-q':
            status = None
        elif opt == '-Q':
            status = None
            warning = None
        elif opt == '-W':
            warningiserror = True
        elif opt == '-w':
            warnfile = val
        elif opt == '-P':
            use_pdb = True

    if warning and warnfile:
        warnfp = open(warnfile, 'w')
        warning = Tee(warning, warnfp)
        error = warning

    try:
        app = Sphinx(srcdir, confdir, outdir, doctreedir, buildername,
                     confoverrides, status, warning, freshenv, warningiserror,
                     tags)
        app.build(force_all, filenames)
        return app.statuscode
    except KeyboardInterrupt:
        if use_pdb:
            import pdb
            print >> error, red(
                'Interrupted while building, starting debugger:')
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        return 1
    except Exception, err:
        if use_pdb:
            import pdb
            print >> error, red('Exception occurred while building, '
                                'starting debugger:')
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        else:
            print >> error
            if isinstance(err, SystemMessage):
                print >> error, red('reST markup error:')
                print >> error, terminal_safe(err.args[0])
            elif isinstance(err, SphinxError):
                print >> error, red('%s:' % err.category)
                print >> error, terminal_safe(unicode(err))
            else:
                print >> error, red('Exception occurred:')
                print >> error, format_exception_cut_frames().rstrip()
                tbpath = save_traceback()
                print >> error, red('The full traceback has been saved '
                                    'in %s, if you want to report the '
                                    'issue to the developers.' % tbpath)
                print >> error, ('Please also report this if it was a user '
                                 'error, so that a better error message '
                                 'can be provided next time.')
                print >> error, (
                    'Either send bugs to the mailing list at '
                    '<http://groups.google.com/group/sphinx-dev/>,\n'
                    'or report them in the tracker at '
                    '<http://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!'
                )
            return 1
Ejemplo n.º 18
0
def main(argv):
    if not color_terminal():
        # Windows' poor cmd box doesn't understand ANSI sequences
        nocolor()

    # parse options
    try:
        opts, args = getopt.getopt(argv[1:], 'ab:t:d:c:CD:A:nNEqQWw:PThvj:',
                                   ['help', 'version'])
    except getopt.error as err:
        usage(argv, 'Error: %s' % err)
        return 1

    # handle basic options
    allopts = set(opt[0] for opt in opts)
    # help and version options
    if '-h' in allopts or '--help' in allopts:
        usage(argv)
        print(file=sys.stderr)
        print('For more information, see <http://sphinx-doc.org/>.',
              file=sys.stderr)
        return 0
    if '--version' in allopts:
        print('Sphinx (sphinx-build) %s' % __version__)
        return 0

    # get paths (first and second positional argument)
    try:
        srcdir = confdir = abspath(args[0])
        if not path.isdir(srcdir):
            print('Error: Cannot find source directory `%s\'.' % (srcdir, ),
                  file=sys.stderr)
            return 1
        if not path.isfile(path.join(srcdir, 'conf.py')) and \
               '-c' not in allopts and '-C' not in allopts:
            print(('Error: Source directory doesn\'t '
                   'contain a conf.py file.'),
                  file=sys.stderr)
            return 1
        outdir = abspath(args[1])
    except IndexError:
        usage(argv, 'Error: Insufficient arguments.')
        return 1
    except UnicodeError:
        print(('Error: Multibyte filename not supported on this filesystem '
               'encoding (%r).' % fs_encoding),
              file=sys.stderr)
        return 1

    # handle remaining filename arguments
    filenames = args[2:]
    err = 0
    for filename in filenames:
        if not path.isfile(filename):
            print('Error: Cannot find file %r.' % filename, file=sys.stderr)
            err = 1
    if err:
        return 1

    # likely encoding used for command-line arguments
    try:
        locale = __import__('locale')  # due to submodule of the same name
        likely_encoding = locale.getpreferredencoding()
    except Exception:
        likely_encoding = None

    buildername = None
    force_all = freshenv = warningiserror = use_pdb = False
    show_traceback = False
    verbosity = 0
    parallel = 0
    status = sys.stdout
    warning = sys.stderr
    error = sys.stderr
    warnfile = None
    confoverrides = {}
    tags = []
    doctreedir = path.join(outdir, '.doctrees')
    for opt, val in opts:
        if opt == '-b':
            buildername = val
        elif opt == '-a':
            if filenames:
                usage(argv, 'Error: Cannot combine -a option and filenames.')
                return 1
            force_all = True
        elif opt == '-t':
            tags.append(val)
        elif opt == '-d':
            doctreedir = abspath(val)
        elif opt == '-c':
            confdir = abspath(val)
            if not path.isfile(path.join(confdir, 'conf.py')):
                print(('Error: Configuration directory '
                       'doesn\'t contain conf.py file.'),
                      file=sys.stderr)
                return 1
        elif opt == '-C':
            confdir = None
        elif opt == '-D':
            try:
                key, val = val.split('=')
            except ValueError:
                print(('Error: -D option argument must be '
                       'in the form name=value.'),
                      file=sys.stderr)
                return 1
            try:
                val = int(val)
            except ValueError:
                if likely_encoding and isinstance(val, bytes):
                    try:
                        val = val.decode(likely_encoding)
                    except UnicodeError:
                        pass
            confoverrides[key] = val
        elif opt == '-A':
            try:
                key, val = val.split('=')
            except ValueError:
                print(('Error: -A option argument must be '
                       'in the form name=value.'),
                      file=sys.stderr)
                return 1
            try:
                val = int(val)
            except ValueError:
                if likely_encoding and isinstance(val, bytes):
                    try:
                        val = val.decode(likely_encoding)
                    except UnicodeError:
                        pass
            confoverrides['html_context.%s' % key] = val
        elif opt == '-n':
            confoverrides['nitpicky'] = True
        elif opt == '-N':
            nocolor()
        elif opt == '-E':
            freshenv = True
        elif opt == '-q':
            status = None
        elif opt == '-Q':
            status = None
            warning = None
        elif opt == '-W':
            warningiserror = True
        elif opt == '-w':
            warnfile = val
        elif opt == '-P':
            use_pdb = True
        elif opt == '-T':
            show_traceback = True
        elif opt == '-v':
            verbosity += 1
            show_traceback = True
        elif opt == '-j':
            try:
                parallel = int(val)
            except ValueError:
                print(('Error: -j option argument must be an '
                       'integer.'),
                      file=sys.stderr)
                return 1

    if warning and warnfile:
        warnfp = open(warnfile, 'w')
        warning = Tee(warning, warnfp)
        error = warning

    if not path.isdir(outdir):
        if status:
            print('Making output directory...', file=status)
        os.makedirs(outdir)

    app = None
    try:
        app = Sphinx(srcdir, confdir, outdir, doctreedir, buildername,
                     confoverrides, status, warning, freshenv, warningiserror,
                     tags, verbosity, parallel)
        app.build(force_all, filenames)
        return app.statuscode
    except (Exception, KeyboardInterrupt) as err:
        if use_pdb:
            import pdb
            print(red('Exception occurred while building, '
                      'starting debugger:'),
                  file=error)
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        else:
            print(file=error)
            if show_traceback:
                traceback.print_exc(None, error)
                print(file=error)
            if isinstance(err, KeyboardInterrupt):
                print('interrupted!', file=error)
            elif isinstance(err, SystemMessage):
                print(red('reST markup error:'), file=error)
                print(terminal_safe(err.args[0]), file=error)
            elif isinstance(err, SphinxError):
                print(red('%s:' % err.category), file=error)
                print(terminal_safe(str(err)), file=error)
            elif isinstance(err, UnicodeError):
                print(red('Encoding error:'), file=error)
                print(terminal_safe(str(err)), file=error)
                tbpath = save_traceback(app)
                print(red('The full traceback has been saved '
                          'in %s, if you want to report the '
                          'issue to the developers.' % tbpath),
                      file=error)
            else:
                print(red('Exception occurred:'), file=error)
                print(format_exception_cut_frames().rstrip(), file=error)
                tbpath = save_traceback(app)
                print(red('The full traceback has been saved '
                          'in %s, if you want to report the '
                          'issue to the developers.' % tbpath),
                      file=error)
                print(('Please also report this if it was a user '
                       'error, so that a better error message '
                       'can be provided next time.'),
                      file=error)
                print((
                    'Either send bugs to the mailing list at '
                    '<http://groups.google.com/group/sphinx-users/>,\n'
                    'or report them in the tracker at '
                    '<http://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!'
                ),
                      file=error)
            return 1
Ejemplo n.º 19
0
def main(argv):
    if not color_terminal():
        # Windows' poor cmd box doesn't understand ANSI sequences
        nocolor()

    try:
        opts, args = getopt.getopt(argv[1:], 'ab:t:d:c:CD:A:ng:NEqQWw:P')
        allopts = set(opt[0] for opt in opts)
        srcdir = confdir = path.abspath(args[0])
        if not path.isdir(srcdir):
            print >>sys.stderr, 'Error: Cannot find source directory.'
            return 1
        if not path.isfile(path.join(srcdir, 'conf.py')) and \
               '-c' not in allopts and '-C' not in allopts:
            print >>sys.stderr, ('Error: Source directory doesn\'t '
                                 'contain conf.py file.')
            return 1
        outdir = path.abspath(args[1])
        if not path.isdir(outdir):
            print >>sys.stderr, 'Making output directory...'
            os.makedirs(outdir)
    except (IndexError, getopt.error):
        usage(argv)
        return 1

    filenames = args[2:]
    err = 0
    for filename in filenames:
        if not path.isfile(filename):
            print >>sys.stderr, 'Cannot find file %r.' % filename
            err = 1
    if err:
        return 1

    buildername = None
    force_all = freshenv = warningiserror = use_pdb = False
    status = sys.stdout
    warning = sys.stderr
    error = sys.stderr
    warnfile = None
    confoverrides = {}
    tags = []
    doctreedir = path.join(outdir, '.doctrees')
    for opt, val in opts:
        if opt == '-b':
            buildername = val
        elif opt == '-a':
            if filenames:
                usage(argv, 'Cannot combine -a option and filenames.')
                return 1
            force_all = True
        elif opt == '-t':
            tags.append(val)
        elif opt == '-d':
            doctreedir = path.abspath(val)
        elif opt == '-c':
            confdir = path.abspath(val)
            if not path.isfile(path.join(confdir, 'conf.py')):
                print >>sys.stderr, ('Error: Configuration directory '
                                     'doesn\'t contain conf.py file.')
                return 1
        elif opt == '-C':
            confdir = None
        elif opt == '-D':
            try:
                key, val = val.split('=')
            except ValueError:
                print >>sys.stderr, ('Error: -D option argument must be '
                                     'in the form name=value.')
                return 1
            try:
                val = int(val)
            except ValueError:
                pass
            confoverrides[key] = val
        elif opt == '-A':
            try:
                key, val = val.split('=')
            except ValueError:
                print >>sys.stderr, ('Error: -A option argument must be '
                                     'in the form name=value.')
                return 1
            try:
                val = int(val)
            except ValueError:
                pass
            confoverrides['html_context.%s' % key] = val
        elif opt == '-n':
            confoverrides['nitpicky'] = True
        elif opt == '-N':
            nocolor()
        elif opt == '-E':
            freshenv = True
        elif opt == '-q':
            status = None
        elif opt == '-Q':
            status = None
            warning = None
        elif opt == '-W':
            warningiserror = True
        elif opt == '-w':
            warnfile = val
        elif opt == '-P':
            use_pdb = True

    if warning and warnfile:
        warnfp = open(warnfile, 'w')
        warning = Tee(warning, warnfp)
        error = warning

    try:
        app = Sphinx(srcdir, confdir, outdir, doctreedir, buildername,
                     confoverrides, status, warning, freshenv,
                     warningiserror, tags)
        app.build(force_all, filenames)
        return app.statuscode
    except KeyboardInterrupt:
        if use_pdb:
            import pdb
            print >>error, red('Interrupted while building, '
                                   'starting debugger:')
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        return 1
    except Exception, err:
        if use_pdb:
            import pdb
            print >>error, red('Exception occurred while building, '
                                   'starting debugger:')
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        else:
            print >>error
            if isinstance(err, SystemMessage):
                print >>error, red('reST markup error:')
                print >>error, err.args[0].encode('ascii', 'backslashreplace')
            elif isinstance(err, SphinxError):
                print >>error, red('%s:' % err.category)
                print >>error, err
            else:
                print >>error, red('Exception occurred:')
                print >>error, format_exception_cut_frames().rstrip()
                tbpath = save_traceback()
                print >>error, red('The full traceback has been saved '
                                   'in %s, if you want to report the '
                                   'issue to the developers.' % tbpath)
                print >>error, ('Please also report this if it was a user '
                                'error, so that a better error message '
                                'can be provided next time.')
                print >>error, (
                    'Either send bugs to the mailing list at '
                    '<http://groups.google.com/group/sphinx-dev/>,\n'
                    'or report them in the tracker at '
                    '<http://bitbucket.org/birkenfeld/sphinx/issues/>. Thanks!')
            return 1
Ejemplo n.º 20
0
def main(argv=sys.argv):
    # delay-import these to be able to get sphinx.__version__ from setup.py
    # even without docutils installed
    from sphinx.application import Sphinx
    from docutils.utils import SystemMessage

    if not sys.stdout.isatty() or sys.platform == "win32":
        # Windows' poor cmd box doesn't understand ANSI sequences
        nocolor()

    try:
        opts, args = getopt.getopt(argv[1:], "ab:d:c:D:NEqP")
        srcdir = confdir = path.abspath(args[0])
        if not path.isdir(srcdir):
            print >>sys.stderr, "Error: Cannot find source directory."
            return 1
        if not path.isfile(path.join(srcdir, "conf.py")) and "-c" not in (opt[0] for opt in opts):
            print >>sys.stderr, "Error: Source directory doesn't contain conf.py file."
            return 1
        outdir = path.abspath(args[1])
        if not path.isdir(outdir):
            print >>sys.stderr, "Error: Cannot find output directory."
            return 1
    except (IndexError, getopt.error):
        usage(argv)
        return 1

    filenames = args[2:]
    err = 0
    for filename in filenames:
        if not path.isfile(filename):
            print >>sys.stderr, "Cannot find file %r." % filename
            err = 1
    if err:
        return 1

    buildername = all_files = None
    freshenv = use_pdb = False
    status = sys.stdout
    confoverrides = {}
    doctreedir = path.join(outdir, ".doctrees")
    for opt, val in opts:
        if opt == "-b":
            buildername = val
        elif opt == "-a":
            if filenames:
                usage(argv, "Cannot combine -a option and filenames.")
                return 1
            all_files = True
        elif opt == "-d":
            doctreedir = val
        elif opt == "-c":
            confdir = path.abspath(val)
            if not path.isfile(path.join(confdir, "conf.py")):
                print >>sys.stderr, "Error: Configuration directory doesn't contain conf.py file."
                return 1
        elif opt == "-D":
            key, val = val.split("=")
            try:
                val = int(val)
            except ValueError:
                pass
            confoverrides[key] = val
        elif opt == "-N":
            nocolor()
        elif opt == "-E":
            freshenv = True
        elif opt == "-q":
            status = StringIO()
        elif opt == "-P":
            use_pdb = True

    try:
        app = Sphinx(srcdir, confdir, outdir, doctreedir, buildername, confoverrides, status, sys.stderr, freshenv)
        if not app.builder:
            return 1

        if all_files:
            app.builder.build_all()
        elif filenames:
            app.builder.build_specific(filenames)
        else:
            app.builder.build_update()
    except KeyboardInterrupt:
        # catches BaseExceptions in 2.5 -- SystemExit, KeyboardInterrupt
        if use_pdb:
            import pdb

            print >>sys.stderr, darkred("Interrupted while building, starting debugger:")
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        return 1
    except Exception, err:
        if use_pdb:
            import pdb

            print >>sys.stderr, darkred("Exception occurred while building, " "starting debugger:")
            traceback.print_exc()
            pdb.post_mortem(sys.exc_info()[2])
        else:
            if isinstance(err, SystemMessage):
                print >>sys.stderr, darkred("reST markup error:")
                print >>sys.stderr, err.args[0].encode("ascii", "backslashreplace")
            else:
                print >>sys.stderr, darkred("Exception occurred:")
                print >>sys.stderr, format_exception_cut_frames().rstrip()
                tbpath = save_traceback()
                print >>sys.stderr, darkred(
                    "The full traceback has been saved "
                    "in %s, if you want to report the "
                    "issue to the author." % tbpath
                )
                print >>sys.stderr, (
                    "Please also report this if it was a user "
                    "error, so that a better error message "
                    "can be provided next time."
                )
                print >>sys.stderr, ("Send reports to [email protected]. " "Thanks!")
            return 1