def test_make_executable(): with TemporaryDirectory() as tmpdir: tempfile = pathlib.Path(tmpdir) / "tmpfile.sh" tempfile.touch() paths.make_executable(tempfile) assert os.access(tempfile, os.X_OK) with TemporaryDirectory() as tmpdir: tempfile = pathlib.Path(tmpdir) / "tmpfile.sh" tempfile.touch() paths.make_executable(str(tempfile)) assert os.access(str(tempfile), os.X_OK) with TemporaryDirectory() as tmpdir: tempfile = PathPlus(tmpdir) / "tmpfile.sh" tempfile.touch() tempfile.make_executable() assert os.access(tempfile, os.X_OK)
def make_pre_commit(repo_path: pathlib.Path, templates: Environment) -> List[str]: """ Add configuration for ``pre-commit``. https://github.com/pre-commit/pre-commit # See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks :param repo_path: Path to the repository root. :param templates: """ docs_dir = templates.globals["docs_dir"] import_name = templates.globals["import_name"] stubs_package = templates.globals["stubs_package"] non_source_files = [ posixpath.join(docs_dir, "conf"), "__pkginfo__", "setup" ] domdfcoding_hooks = Repo( repo=make_github_url("domdfcoding", "pre-commit-hooks"), rev="v0.3.0", hooks=[ { "id": "requirements-txt-sorter", "args": ["--allow-git"] }, { "id": "check-docstring-first", "exclude": fr"^({'|'.join(non_source_files)}|{templates.globals['tests_dir']}/.*)\.py$" }, "bind-requirements", ]) flake8_dunder_all = Repo( repo=make_github_url("domdfcoding", "flake8-dunder-all"), rev="v0.1.8", hooks=[{ "id": "ensure-dunder-all", "files": fr"^{import_name}{'-stubs' if stubs_package else ''}/.*\.py$" }]) snippet_fmt = Repo( repo=make_github_url("python-formate", "snippet-fmt"), rev="v0.1.4", hooks=["snippet-fmt"], ) formate_excludes = fr"^({'|'.join([*templates.globals['yapf_exclude'], *non_source_files])})\.(_)?py$" formate = Repo( repo=make_github_url("python-formate", "formate"), rev="v0.4.9", hooks=[{ "id": "formate", "exclude": formate_excludes }], ) dep_checker_args = [templates.globals["import_name"].replace('.', '/')] if templates.globals["source_dir"]: dep_checker_args.extend( ["--work-dir", templates.globals["source_dir"]]) dep_checker = Repo(repo=make_github_url("domdfcoding", "dep_checker"), rev="v0.6.2", hooks=[{ "id": "dep_checker", "args": dep_checker_args }]) pre_commit_file = PathPlus(repo_path / ".pre-commit-config.yaml") if not pre_commit_file.is_file(): pre_commit_file.touch() dumper = ruamel.yaml.YAML() dumper.indent(mapping=2, sequence=3, offset=1) output = StringList([ f"# {templates.globals['managed_message']}", "---", '', f"exclude: {templates.globals['pre_commit_exclude']}", '', "repos:", ]) indent_re = re.compile("^ {3}") managed_hooks = [ pyproject_parser, pre_commit_hooks, domdfcoding_hooks, flake8_dunder_all, flake2lint, pygrep_hooks, pyupgrade, lucas_c_hooks, snippet_fmt, formate, ] if not templates.globals["stubs_package"]: managed_hooks.append(dep_checker) managed_hooks_urls = [str(hook.repo) for hook in managed_hooks] custom_hooks_comment = "# Custom hooks can be added below this comment" for hook in managed_hooks: buf = StringIO() dumper.dump(hook.to_dict(), buf) output.append(indent_re.sub(" - ", indent(buf.getvalue(), " "))) output.blankline(ensure_single=True) output.append(custom_hooks_comment) output.blankline(ensure_single=True) raw_yaml = pre_commit_file.read_text() if custom_hooks_comment in raw_yaml: custom_hooks_yaml = pre_commit_file.read_text().split( custom_hooks_comment)[1] custom_hooks = [] local_hooks = [] for repo in yaml_safe_loader.load(custom_hooks_yaml) or []: if repo["repo"] == "local": local_hooks.append(repo) elif repo["repo"] not in managed_hooks_urls: custom_hooks.append(Repo(**repo)) for hook in custom_hooks: buf = StringIO() dumper.dump(hook.to_dict(), buf) output.append(indent_re.sub(" - ", indent(buf.getvalue(), " "))) output.blankline(ensure_single=True) for hook in local_hooks: buf = StringIO() dumper.dump(hook, buf) output.append(indent_re.sub(" - ", indent(buf.getvalue(), " "))) output.blankline(ensure_single=True) pre_commit_file.write_lines(output) return [pre_commit_file.name]