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)}")
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)
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)
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
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)
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