Esempio n. 1
0
def lint(paths,
         parallel,
         format,
         nofail,
         disregard_sqlfluffignores,
         logger=None,
         **kwargs):
    """Lint SQL files via passing a list of files or using stdin.

    PATH is the path to a sql file or directory to lint. This can be either a
    file ('path/to/file.sql'), a path ('directory/of/sql/files'), a single ('-')
    character to indicate reading from *stdin* or a dot/blank ('.'/' ') which will
    be interpreted like passing the current working directory as a path argument.

    Linting SQL files:

        sqlfluff lint path/to/file.sql
        sqlfluff lint directory/of/sql/files

    Linting a file via stdin (note the lone '-' character):

        cat path/to/file.sql | sqlfluff lint -
        echo 'select col from tbl' | sqlfluff lint -

    """
    c = get_config(**kwargs)
    non_human_output = format in ("json", "yaml")
    lnt, formatter = get_linter_and_formatter(c, silent=non_human_output)
    verbose = c.get("verbose")

    formatter.dispatch_config(lnt)

    # Set up logging.
    set_logging_level(verbosity=verbose,
                      logger=logger,
                      stderr_output=non_human_output)
    # add stdin if specified via lone '-'
    if ("-", ) == paths:
        # TODO: Remove verbose
        result = lnt.lint_string_wrapped(sys.stdin.read(), fname="stdin")
    else:
        # Output the results as we go
        if verbose >= 1:
            click.echo(format_linting_result_header())
        try:
            # TODO: Remove verbose
            result = lnt.lint_paths(
                paths,
                ignore_non_existent_files=False,
                ignore_files=not disregard_sqlfluffignores,
                parallel=parallel,
            )
        except IOError:
            click.echo(
                colorize(
                    "The path(s) {0!r} could not be accessed. Check it/they exist(s)."
                    .format(paths),
                    "red",
                ))
            sys.exit(1)
        # Output the final stats
        if verbose >= 1:
            click.echo(format_linting_stats(result, verbose=verbose))

    if format == "json":
        click.echo(json.dumps(result.as_records()))
    elif format == "yaml":
        click.echo(yaml.dump(result.as_records()))

    if not nofail:
        if not non_human_output:
            click.echo("All Finished 📜 🎉!")
        sys.exit(result.stats()["exit code"])
    else:
        sys.exit(0)
Esempio n. 2
0
def lint(
    paths,
    processes,
    format,
    annotation_level,
    nofail,
    disregard_sqlfluffignores,
    logger=None,
    bench=False,
    **kwargs,
):
    """Lint SQL files via passing a list of files or using stdin.

    PATH is the path to a sql file or directory to lint. This can be either a
    file ('path/to/file.sql'), a path ('directory/of/sql/files'), a single ('-')
    character to indicate reading from *stdin* or a dot/blank ('.'/' ') which will
    be interpreted like passing the current working directory as a path argument.

    Linting SQL files:

        sqlfluff lint path/to/file.sql
        sqlfluff lint directory/of/sql/files

    Linting a file via stdin (note the lone '-' character):

        cat path/to/file.sql | sqlfluff lint -
        echo 'select col from tbl' | sqlfluff lint -

    """
    config = get_config(**kwargs)
    non_human_output = format != "human"
    lnt, formatter = get_linter_and_formatter(config, silent=non_human_output)
    verbose = config.get("verbose")

    formatter.dispatch_config(lnt)

    # Set up logging.
    set_logging_level(verbosity=verbose, logger=logger, stderr_output=non_human_output)
    # add stdin if specified via lone '-'
    if ("-",) == paths:
        result = lnt.lint_string_wrapped(sys.stdin.read(), fname="stdin")
    else:
        # Output the results as we go
        if verbose >= 1:
            click.echo(format_linting_result_header())
        try:
            result = lnt.lint_paths(
                paths,
                ignore_non_existent_files=False,
                ignore_files=not disregard_sqlfluffignores,
                processes=processes,
            )
        except OSError:
            click.echo(
                colorize(
                    "The path(s) {!r} could not be accessed. Check it/they exist(s).".format(
                        paths
                    ),
                    "red",
                )
            )
            sys.exit(1)
        # Output the final stats
        if verbose >= 1:
            click.echo(format_linting_stats(result, verbose=verbose))

    if format == "json":
        click.echo(json.dumps(result.as_records()))
    elif format == "yaml":
        click.echo(yaml.dump(result.as_records()))
    elif format == "github-annotation":
        github_result = []
        for record in result.as_records():
            filepath = record["filepath"]
            for violation in record["violations"]:
                # NOTE: The output format is designed for this GitHub action:
                # https://github.com/yuzutech/annotations-action
                # It is similar, but not identical, to the native GitHub format:
                # https://docs.github.com/en/rest/reference/checks#annotations-items
                github_result.append(
                    {
                        "file": filepath,
                        "line": violation["line_no"],
                        "start_column": violation["line_pos"],
                        "end_column": violation["line_pos"],
                        "title": "SQLFluff",
                        "message": f"{violation['code']}: {violation['description']}",
                        "annotation_level": annotation_level,
                    }
                )
        click.echo(json.dumps(github_result))

    if bench:
        click.echo("==== overall timings ====")
        click.echo(cli_table([("Clock time", result.total_time)]))
        timing_summary = result.timing_summary()
        for step in timing_summary:
            click.echo(f"=== {step} ===")
            click.echo(cli_table(timing_summary[step].items()))

    if not nofail:
        if not non_human_output:
            _completion_message(config)
        sys.exit(result.stats()["exit code"])
    else:
        sys.exit(0)