def lint_path( self, path: str, fix: bool = False, ignore_non_existent_files: bool = False, ignore_files: bool = True, processes: int = 1, ) -> LintedDir: """Lint a path.""" linted_path = LintedDir(path) if self.formatter: self.formatter.dispatch_path(path) fnames = list( self.paths_from_path( path, ignore_non_existent_files=ignore_non_existent_files, ignore_files=ignore_files, ) ) runner = get_runner( self, self.config, processes=processes, allow_process_parallelism=self.allow_process_parallelism, ) for linted_file in runner.run(fnames, fix): linted_path.add(linted_file) # If any fatal errors, then stop iteration. if any(v.fatal for v in linted_file.violations): # pragma: no cover linter_logger.error("Fatal linting error. Halting further linting.") break return linted_path
def lint_path( self, path: str, fix: bool = False, ignore_non_existent_files: bool = False, ignore_files: bool = True, processes: int = 1, ) -> LintedDir: """Lint a path.""" linted_path = LintedDir(path) if self.formatter: self.formatter.dispatch_path(path) fnames = list( self.paths_from_path( path, ignore_non_existent_files=ignore_non_existent_files, ignore_files=ignore_files, )) # to avoid circular import from sqlfluff.core.linter.runner import get_runner runner = get_runner( self, self.config, processes=processes, allow_process_parallelism=self.allow_process_parallelism, ) # Show files progress bar only when there is more than one. files_count = len(fnames) progress_bar_files = tqdm( total=files_count, desc=f"file {os.path.basename(fnames[0] if fnames else '')}", leave=False, disable=files_count <= 1 or progress_bar_configuration.disable_progress_bar, ) for i, linted_file in enumerate(runner.run(fnames, fix), start=1): linted_path.add(linted_file) # If any fatal errors, then stop iteration. if any(v.fatal for v in linted_file.violations): # pragma: no cover linter_logger.error( "Fatal linting error. Halting further linting.") break # Progress bar for files is rendered only when there is more than one file. # Additionally as it's updated after each loop, we need to get file name # from the next loop. This is why `enumerate` starts with `1` and there # is `i < len` to not exceed files list length. progress_bar_files.update(n=1) if i < len(fnames): progress_bar_files.set_description( f"file {os.path.basename(fnames[i])}") return linted_path
def lint_string_wrapped(self, string: str, fname: str = "<string input>", fix: bool = False) -> LintingResult: """Lint strings directly.""" result = LintingResult() linted_path = LintedDir(fname) linted_path.add(self.lint_string(string, fname=fname, fix=fix)) result.add(linted_path) return result
def lint_path( self, path: str, fix: bool = False, ignore_non_existent_files: bool = False, ignore_files: bool = True, parallel: int = 1, ) -> LintedDir: """Lint a path.""" linted_path = LintedDir(path) if self.formatter: self.formatter.dispatch_path(path) fnames = list( self.paths_from_path( path, ignore_non_existent_files=ignore_non_existent_files, ignore_files=ignore_files, )) runner: runner_module.BaseRunner if parallel >= self.MIN_THRESHOLD_PARALLEL and sys.version_info > (3, 7): runner = self.PARALLEL_CLS(type(self), self, self.config, self.dialect.name, parallel) else: if parallel > 1: linter_logger.warning( "Parallel linting is not supported in Python %s.%s.", sys.version_info.major, sys.version_info.minor, ) runner = runner_module.SequentialRunner(type(self), self, self.config, self.dialect.name) for linted_file in runner.run(fnames, fix): linted_path.add(linted_file) # If any fatal errors, then stop iteration. if any(v.fatal for v in linted_file.violations): linter_logger.error( "Fatal linting error. Halting further linting.") break return linted_path
def as_records(self) -> List[dict]: """Return the result as a list of dictionaries. Each record contains a key specifying the filepath, and a list of violations. This method is useful for serialization as all objects will be builtin python types (ints, strs). """ return [ { "filepath": path, "violations": sorted( # Sort violations by line and then position [v.get_info_dict() for v in violations], # The tuple allows sorting by line number, then position, then code key=lambda v: (v["line_no"], v["line_pos"], v["code"]), ), } for LintedDir in self.paths for path, violations in LintedDir.violation_dict().items() if violations ]