Example #1
0
def main():
    """Parse arguments, open files, start work."""

    # set up main logger, which logs everything. We'll leave this one logging
    # to the console
    logging.basicConfig(level=logging.INFO)
    arg_parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter,
        usage=USAGE_STRING)
    setup_argparser(arg_parser)
    args = arg_parser.parse_args()

    assert (len(args.infilepaths) == 1
            or args.outfile_path is None), \
        ("if more than one input file is specified, then annotates must be "
         "written to stdout")

    if args.outfile_path is None:
        args.outfile_path = '-'

    if '-' in args.infilepaths:
        assert len(args.infilepaths) == 1, \
            "You cannot mix stdin as an input with other input files"
        assert args.outfile_path == '-', \
            "If stdin is the input file, then stdout must be the output file"

    for infile_path in args.infilepaths:
        # NOTE(josh): have to load config once for every file, because we may pick
        # up a new config file location for each path
        if infile_path == '-':
            config_dict = __main__.get_config(os.getcwd(), args.config_file)
        else:
            config_dict = __main__.get_config(infile_path, args.config_file)

        for key, value in vars(args).items():
            if (key in configuration.Configuration.get_field_names()
                    and value is not None):
                config_dict[key] = value

        cfg = configuration.Configuration(**config_dict)
        if args.outfile_path == '-':
            # NOTE(josh): The behavior or sys.stdout is different in python2 and
            # python3. sys.stdout is opened in 'w' mode which means that write()
            # takes strings in python2 and python3 and, in particular, in python3
            # it does not take byte arrays. io.StreamWriter will write to
            # it with byte arrays (assuming it was opened with 'wb'). So we use
            # io.open instead of open in this case
            outfile = io.open(os.dup(sys.stdout.fileno()),
                              mode='w',
                              encoding=cfg.output_encoding,
                              newline='')
        else:
            outfile = io.open(args.outfile_path,
                              'w',
                              encoding=cfg.output_encoding,
                              newline='')

        if infile_path == '-':
            infile = io.open(os.dup(sys.stdin.fileno()),
                             mode='r',
                             encoding=cfg.input_encoding,
                             newline='')
        else:
            infile = io.open(infile_path, 'r', encoding=cfg.input_encoding)

        try:
            with infile:
                annotate_file(cfg, infile, outfile, args.format)
        except:
            sys.stderr.write('While processing {}\n'.format(infile_path))
            raise
        finally:
            outfile.close()

    return 0
Example #2
0
def inner_main():
    """Parse arguments, open files, start work."""
    logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s")

    argparser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter,
        usage=USAGE_STRING)

    setup_argparse(argparser)
    args = argparser.parse_args()
    logging.getLogger().setLevel(getattr(logging, args.log_level.upper()))

    if args.dump_config:
        config_dict = __main__.get_config(os.getcwd(), args.config_files)
        __main__.dump_config(args, config_dict, sys.stdout)
        sys.exit(0)

    if args.outfile_path is None:
        args.outfile_path = '-'

    if '-' in args.infilepaths:
        assert len(args.infilepaths) == 1, \
            "You cannot mix stdin as an input with other input files"

    if args.outfile_path == '-':
        outfile = io.open(os.dup(sys.stdout.fileno()),
                          mode='w',
                          encoding="utf-8",
                          newline='')
    else:
        outfile = io.open(args.outfile_path, 'w', encoding="utf-8", newline='')

    global_ctx = lint_util.GlobalContext(outfile)
    returncode = 0
    argdict = __main__.get_argdict(args)

    for infile_path in args.infilepaths:
        # NOTE(josh): have to load config once for every file, because we may pick
        # up a new config file location for each path
        if infile_path == '-':
            config_dict = __main__.get_config(os.getcwd(), args.config_files)
        else:
            config_dict = __main__.get_config(infile_path, args.config_files)
        config_dict.update(argdict)

        cfg = configuration.Configuration(**config_dict)
        if infile_path == '-':
            infile_path = os.dup(sys.stdin.fileno())

        try:
            infile = io.open(infile_path,
                             mode='r',
                             encoding=cfg.encode.input_encoding,
                             newline='')
        except (IOError, OSError):
            logger.error("Failed to open %s for read", infile_path)
            returncode = 1
            continue

        try:
            with infile:
                intext = infile.read()
        except UnicodeDecodeError:
            logger.error("Unable to read %s as %s", infile_path,
                         cfg.encode.input_encoding)
            returncode = 1
            continue

        local_ctx = global_ctx.get_file_ctx(infile_path, cfg)
        process_file(cfg, local_ctx, intext)
        outfile.write("{}\n{}\n".format(infile_path, "=" * len(infile_path)))
        local_ctx.writeout(outfile)
        outfile.write("\n")
        if local_ctx.has_lint():
            returncode = 1

    global_ctx.write_summary(outfile)
    outfile.close()
    return returncode