def darker_help_output(capsys): """Test for ``--help`` option output""" # Make sure the description is re-rendered since its content depends on whether # isort is installed or not: reload(darker.help) with pytest.raises(SystemExit): parse_command_line(["--help"]) return re.sub(r'\s+', ' ', capsys.readouterr().out)
def main(argv: List[str] = None) -> None: """Parse the command line and apply black formatting for each source file""" if argv is None: argv = sys.argv[1:] args = parse_command_line(argv) log_level = logging.WARNING - sum(args.log_level or ()) logging.basicConfig(level=log_level) if log_level == logging.INFO: formatter = logging.Formatter("%(levelname)s: %(message)s") logging.getLogger().handlers[0].setFormatter(formatter) # Make sure we don't get excessive debug log output from Black logging.getLogger("blib2to3.pgen2.driver").setLevel(logging.WARNING) if args.version: print(__version__) if args.isort and not isort: logger.error(f"{ISORT_INSTRUCTION} to use the `--isort` option.") exit(1) black_args = {} if args.config: black_args["config"] = args.config if args.line_length: black_args["line_length"] = args.line_length if args.skip_string_normalization: black_args["skip_string_normalization"] = args.skip_string_normalization paths = {Path(p) for p in args.src} format_edited_parts(paths, args.isort, black_args, args.diff)
def main(argv: List[str] = None) -> int: """Parse the command line and apply black formatting for each source file :param argv: The command line arguments to the ``darker`` command :return: 1 if the ``--check`` argument was provided and at least one file was (or should be) reformatted; 0 otherwise. """ if argv is None: argv = sys.argv[1:] args, config, config_nondefault = parse_command_line(argv) logging.basicConfig(level=args.log_level) if args.log_level == logging.INFO: formatter = logging.Formatter("%(levelname)s: %(message)s") logging.getLogger().handlers[0].setFormatter(formatter) # Make sure we don't get excessive debug log output from Black logging.getLogger("blib2to3.pgen2.driver").setLevel(logging.WARNING) if args.log_level <= logging.DEBUG: print("\n# Effective configuration:\n") print(dump_config(config)) print("\n# Configuration options which differ from defaults:\n") print(dump_config(config_nondefault)) print("\n") if args.isort and not isort: logger.error(f"{ISORT_INSTRUCTION} to use the `--isort` option.") exit(1) black_args = BlackArgs() if args.config: black_args["config"] = args.config if args.line_length: black_args["line_length"] = args.line_length if args.skip_string_normalization is not None: black_args[ "skip_string_normalization"] = args.skip_string_normalization paths = {Path(p) for p in args.src} some_files_changed = False # `new_content` is just `new_lines` concatenated with newlines. # We need both forms when showing diffs or modifying files. # Pass them both on to avoid back-and-forth conversion. for path, old_content, new_content, new_lines in format_edited_parts( paths, args.revision, args.isort, args.lint, black_args): some_files_changed = True if args.diff: post_gh_suggestion(str(path.relative_to(Path(os.getcwd()))), old_content, new_lines) # print_diff(path, old_content, new_lines) if not args.check and not args.diff: modify_file(path, new_content) return 1 if args.check and some_files_changed else 0
def test_parse_command_line_config_src( tmpdir, monkeypatch, config, argv, expect, ): """The ``src`` positional argument from config and cmdline is handled correctly""" monkeypatch.chdir(tmpdir) if config is not None: toml.dump({"tool": {"darker": config}}, tmpdir / "pyproject.toml") with raises_if_exception(expect): args, effective_cfg, modified_cfg = parse_command_line(argv) assert filter_dict(args.__dict__, "src") == expect assert filter_dict(effective_cfg, "src") == expect assert filter_dict(modified_cfg, "src") == expect
def test_parse_command_line(tmpdir, monkeypatch, argv, expect_value, expect_config, expect_modified): monkeypatch.chdir(tmpdir) args, effective_cfg, modified_cfg = parse_command_line(argv) arg_name, expect_arg_value = expect_value assert getattr(args, arg_name) == expect_arg_value option, expect_config_value = expect_config if expect_config_value is ...: assert option not in effective_cfg else: assert effective_cfg[option] == expect_config_value modified_option, expect_modified_value = expect_modified if expect_modified_value is ...: assert modified_option not in modified_cfg else: assert modified_cfg[modified_option] == expect_modified_value
def darker_help_output(capsys): with pytest.raises(SystemExit): parse_command_line(["--help"]) return re.sub(r'\s+', ' ', capsys.readouterr().out)
def main(argv: List[str] = None) -> int: """Parse the command line and reformat and optionally lint each source file 1. run isort on each edited file (optional) 2. diff the given revision and worktree (optionally with isort modifications) for all file & dir paths on the command line 3. extract line numbers in each edited to-file for changed lines 4. run black on the contents of each edited to-file 5. get a diff between the edited to-file and the reformatted content 6. convert the diff into chunks, keeping original and reformatted content for each chunk 7. choose reformatted content for each chunk if there were any changed lines inside the chunk in the edited to-file, or choose the chunk's original contents if no edits were done in that chunk 8. verify that the resulting reformatted source code parses to an identical AST as the original edited to-file 9. write the reformatted source back to the original file 10. run linter subprocesses for all edited files (10.-13. optional) 11. diff the given revision and worktree (after isort and Black reformatting) for each file reported by a linter 12. extract line numbers in each file reported by a linter for changed lines 13. print only linter error lines which fall on changed lines :param argv: The command line arguments to the ``darker`` command :return: 1 if the ``--check`` argument was provided and at least one file was (or should be) reformatted; 0 otherwise. """ if argv is None: argv = sys.argv[1:] args, config, config_nondefault = parse_command_line(argv) logging.basicConfig(level=args.log_level) if args.log_level == logging.INFO: formatter = logging.Formatter("%(levelname)s: %(message)s") logging.getLogger().handlers[0].setFormatter(formatter) # Make sure we don't get excessive debug log output from Black logging.getLogger("blib2to3.pgen2.driver").setLevel(logging.WARNING) if args.log_level <= logging.DEBUG: print("\n# Effective configuration:\n") print(dump_config(config)) print("\n# Configuration options which differ from defaults:\n") print(dump_config(config_nondefault)) print("\n") if args.isort and not isort: logger.error(f"{ISORT_INSTRUCTION} to use the `--isort` option.") exit(1) black_args = BlackArgs() if args.config: black_args["config"] = args.config if args.line_length: black_args["line_length"] = args.line_length if args.skip_string_normalization is not None: black_args[ "skip_string_normalization"] = args.skip_string_normalization paths = {Path(p) for p in args.src} git_root = get_common_root(paths) failures_on_modified_lines = False revrange = RevisionRange.parse(args.revision) changed_files = git_get_modified_files(paths, revrange, git_root) for path, old, new in format_edited_parts(git_root, changed_files, revrange, args.isort, black_args): failures_on_modified_lines = True if args.diff: print_diff(path, old, new) if not args.check and not args.diff: modify_file(path, new) if run_linters(args.lint, git_root, changed_files, revrange): failures_on_modified_lines = True return 1 if args.check and failures_on_modified_lines else 0