示例#1
0
文件: simple.py 项目: sti0/sqlfluff
def get_simple_config(
    dialect: Optional[str] = None,
    rules: Optional[List[str]] = None,
    exclude_rules: Optional[List[str]] = None,
    config_path: Optional[str] = None,
) -> FluffConfig:
    """Get a config object from simple API arguments."""
    # Create overrides for simple API arguments.
    overrides = {}
    if dialect is not None:
        # Check the requested dialect exists and is valid.
        try:
            dialect_selector(dialect)
        except SQLFluffUserError as err:  # pragma: no cover
            raise SQLFluffUserError(
                f"Error loading dialect '{dialect}': {str(err)}")
        except KeyError:
            raise SQLFluffUserError(f"Error: Unknown dialect '{dialect}'")

        overrides["dialect"] = dialect
    if rules is not None:
        overrides["rules"] = ",".join(rules)
    if exclude_rules is not None:
        overrides["exclude_rules"] = ",".join(exclude_rules)

    # Instantiate a config object.
    try:
        return FluffConfig.from_root(
            extra_config_path=config_path,
            ignore_local_config=True,
            overrides=overrides,
        )
    except SQLFluffUserError as err:  # pragma: no cover
        raise SQLFluffUserError(f"Error loading config: {str(err)}")
示例#2
0
def get_config(**kwargs):
    """Get a config object from kwargs."""
    if kwargs.get("dialect", None):
        try:
            # We're just making sure it exists at this stage - it will be fetched properly in the linter
            dialect_selector(kwargs["dialect"])
        except KeyError:
            click.echo("Error: Unknown dialect {!r}".format(kwargs["dialect"]))
            sys.exit(66)
    # Instantiate a config object (filtering out the nulls)
    overrides = {k: kwargs[k] for k in kwargs if kwargs[k] is not None}
    return FluffConfig.from_root(overrides=overrides)
示例#3
0
def get_config(
    extra_config_path: Optional[str] = None,
    ignore_local_config: bool = False,
    **kwargs,
) -> FluffConfig:
    """Get a config object from kwargs."""
    plain_output = OutputStreamFormatter.should_produce_plain_output(kwargs["nocolor"])
    if kwargs.get("dialect"):
        try:
            # We're just making sure it exists at this stage.
            # It will be fetched properly in the linter.
            dialect_selector(kwargs["dialect"])
        except SQLFluffUserError as err:
            click.echo(
                OutputStreamFormatter.colorize_helper(
                    plain_output,
                    f"Error loading dialect '{kwargs['dialect']}': {str(err)}",
                    color=Color.red,
                )
            )
            sys.exit(EXIT_ERROR)
        except KeyError:
            click.echo(
                OutputStreamFormatter.colorize_helper(
                    plain_output,
                    f"Error: Unknown dialect '{kwargs['dialect']}'",
                    color=Color.red,
                )
            )
            sys.exit(EXIT_ERROR)
    from_root_kwargs = {}
    if "require_dialect" in kwargs:
        from_root_kwargs["require_dialect"] = kwargs.pop("require_dialect")
    # Instantiate a config object (filtering out the nulls)
    overrides = {k: kwargs[k] for k in kwargs if kwargs[k] is not None}
    try:
        return FluffConfig.from_root(
            extra_config_path=extra_config_path,
            ignore_local_config=ignore_local_config,
            overrides=overrides,
            **from_root_kwargs,
        )
    except SQLFluffUserError as err:  # pragma: no cover
        click.echo(
            OutputStreamFormatter.colorize_helper(
                plain_output,
                f"Error loading config: {str(err)}",
                color=Color.red,
            )
        )
        sys.exit(EXIT_ERROR)
示例#4
0
    def violations(src_path: str) -> List[Violation]:
        """Return list of violations.

        Given the path to a .sql file, analyze it and return a list of
        violations (i.e. formatting or style issues).
        """
        linter = Linter(config=FluffConfig.from_root())
        linted_path = linter.lint_path(src_path,
                                       ignore_non_existent_files=True)
        result = []
        for violation in linted_path.get_violations():
            try:
                # Normal SQLFluff warnings
                message = f"{violation.rule_code()}: {violation.description}"
            except AttributeError:
                # Parse errors
                message = str(violation)
            result.append(Violation(violation.line_no, message))
        return result
示例#5
0
def get_config(
    extra_config_path: Optional[str] = None,
    ignore_local_config: bool = False,
    **kwargs,
) -> FluffConfig:
    """Get a config object from kwargs."""
    if "dialect" in kwargs:
        try:
            # We're just making sure it exists at this stage.
            # It will be fetched properly in the linter.
            dialect_selector(kwargs["dialect"])
        except SQLFluffUserError as err:
            click.echo(
                colorize(
                    f"Error loading dialect '{kwargs['dialect']}': {str(err)}",
                    color=Color.red,
                ))
            sys.exit(66)
        except KeyError:
            click.echo(
                colorize(f"Error: Unknown dialect '{kwargs['dialect']}'",
                         color=Color.red))
            sys.exit(66)
    # Instantiate a config object (filtering out the nulls)
    overrides = {k: kwargs[k] for k in kwargs if kwargs[k] is not None}
    try:
        return FluffConfig.from_root(
            extra_config_path=extra_config_path,
            ignore_local_config=ignore_local_config,
            overrides=overrides,
        )
    except SQLFluffUserError as err:  # pragma: no cover
        click.echo(
            colorize(
                f"Error loading config: {str(err)}",
                color=Color.red,
            ))
        sys.exit(66)
示例#6
0
def auto_fix_test(dialect, folder, caplog):
    """A test for roundtrip testing, take a file buffer, lint, fix and lint.

    This is explicitly different from the linter version of this, in that
    it uses the command line rather than the direct api.
    """
    # Log just the rules logger for this test.
    # NOTE: In debugging it may be instructive to enable some of
    # the other loggers listed here to debug particular issues.
    # Enabling all of them results in very long logs so use
    # wisely.
    # caplog.set_level(logging.DEBUG, logger="sqlfluff.templater")
    # caplog.set_level(logging.DEBUG, logger="sqlfluff.lexer")
    caplog.set_level(logging.DEBUG, logger="sqlfluff.linter")
    caplog.set_level(logging.DEBUG, logger="sqlfluff.rules")

    filename = "testing.sql"
    # Lets get the path of a file to use
    tempdir_path = tempfile.mkdtemp()
    filepath = os.path.join(tempdir_path, filename)
    cfgpath = os.path.join(tempdir_path, ".sqlfluff")
    src_filepath = os.path.join(*base_auto_fix_path, dialect, folder,
                                "before.sql")
    cmp_filepath = os.path.join(*base_auto_fix_path, dialect, folder,
                                "after.sql")
    vio_filepath = os.path.join(*base_auto_fix_path, dialect, folder,
                                "violations.json")
    cfg_filepath = os.path.join(*base_auto_fix_path, dialect, folder,
                                ".sqlfluff")
    test_conf_filepath = os.path.join(*base_auto_fix_path, dialect, folder,
                                      "test-config.yml")

    # Load the config file for the test:
    with open(test_conf_filepath) as cfg_file:
        cfg = yaml.safe_load(cfg_file)
    print("## Config: ", cfg)
    rules = ",".join(cfg["test-config"]["rules"])

    # Open the example file and write the content to it
    print_buff = ""
    with open(filepath, mode="w") as dest_file:
        with open(src_filepath, mode="r") as source_file:
            for line in source_file:
                dest_file.write(line)
                print_buff += line
    # Copy the config file too
    try:
        with open(cfgpath, mode="w") as dest_file:
            with open(cfg_filepath, mode="r") as source_file:
                print("## Config File Found.")
                for line in source_file:
                    dest_file.write(line)
    except FileNotFoundError:
        # No config file? No biggie
        print("## No Config File Found.")
        pass
    print("## Input file:\n{0}".format(print_buff))
    # Do we need to do a violations check?
    try:
        with open(vio_filepath, mode="r") as vio_file:
            violations = json.load(vio_file)
    except FileNotFoundError:
        # No violations file. Let's not worry
        violations = None

    # Run the fix command
    cfg = FluffConfig.from_root(overrides=dict(rules=rules, dialect=dialect))
    lnt = Linter(config=cfg)
    res = lnt.lint_path(filepath, fix=True)

    print("## Templated file:\n{0}".format(res.tree.raw))

    # We call the check_tuples here, even to makes sure any non-linting
    # violations are raised, and the test fails.
    vs = set(res.check_tuples())
    # If we have a violations structure, let's enforce it.
    if violations:
        # Format the violations file
        expected_vs = set()
        for rule_key in violations["violations"]["linting"]:
            for elem in violations["violations"]["linting"][rule_key]:
                expected_vs.add((rule_key, *elem))
        assert expected_vs == vs

    # Actually do the fixes
    res = res.persist_changes()
    # Read the fixed file
    with open(filepath, mode="r") as fixed_file:
        fixed_buff = fixed_file.read()
    # Clearup once read
    shutil.rmtree(tempdir_path)
    # Read the comparison file
    with open(cmp_filepath, mode="r") as comp_file:
        comp_buff = comp_file.read()

    # Make sure we were successful
    assert res
    # Assert that we fixed as expected
    assert fixed_buff == comp_buff
def auto_fix_test(rules, dialect, folder):
    """A test for roundtrip testing, take a file buffer, lint, fix and lint.

    This is explicitly different from the linter version of this, in that
    it uses the command line rather than the direct api.
    """
    filename = "testing.sql"
    # Lets get the path of a file to use
    tempdir_path = tempfile.mkdtemp()
    filepath = os.path.join(tempdir_path, filename)
    cfgpath = os.path.join(tempdir_path, ".sqlfluff")
    src_filepath = os.path.join(*base_auto_fix_path, dialect, folder,
                                "before.sql")
    cmp_filepath = os.path.join(*base_auto_fix_path, dialect, folder,
                                "after.sql")
    vio_filepath = os.path.join(*base_auto_fix_path, dialect, folder,
                                "violations.json")
    cfg_filepath = os.path.join(*base_auto_fix_path, dialect, folder,
                                ".sqlfluff")
    # Open the example file and write the content to it
    print_buff = ""
    with open(filepath, mode="w") as dest_file:
        with open(src_filepath, mode="r") as source_file:
            for line in source_file:
                dest_file.write(line)
                print_buff += line
    # Copy the config file too
    try:
        with open(cfgpath, mode="w") as dest_file:
            with open(cfg_filepath, mode="r") as source_file:
                for line in source_file:
                    dest_file.write(line)
    except FileNotFoundError:
        # No config file? No biggie
        pass
    print("## Input file:\n{0}".format(print_buff))
    # Do we need to do a violations check?
    try:
        with open(vio_filepath, mode="r") as vio_file:
            violations = json.load(vio_file)
    except FileNotFoundError:
        # No violations file. Let's not worry
        violations = None

    # Run the fix command
    cfg = FluffConfig.from_root(overrides=dict(rules=rules, dialect=dialect))
    lnt = Linter(config=cfg)
    res = lnt.lint_path(filepath, fix=True)

    # If we have a violations structure, let's enforce it.
    if violations:
        vs = set(res.check_tuples())
        # Format the violations file
        expected_vs = set()
        for rule_key in violations["violations"]["linting"]:
            for elem in violations["violations"]["linting"][rule_key]:
                expected_vs.add((rule_key, *elem))
        assert expected_vs == vs

    # Actually do the fixes
    res = do_fixes(lnt, res)
    # Read the fixed file
    with open(filepath, mode="r") as fixed_file:
        fixed_buff = fixed_file.read()
    # Clearup once read
    shutil.rmtree(tempdir_path)
    # Read the comparison file
    with open(cmp_filepath, mode="r") as comp_file:
        comp_buff = comp_file.read()

    # Make sure we were successful
    assert res
    # Assert that we fixed as expected
    assert fixed_buff == comp_buff