def relpath(path: PathLike, relative_to: Optional[PathLike] = None) -> pathlib.Path: """ Returns the path for the given file or directory relative to the given directory or, if that would require path traversal, returns the absolute path. :param path: Path to find the relative path for :param relative_to: The directory to find the path relative to. Defaults to the current directory. :no-default relative_to: """ # noqa D400 if not isinstance(path, pathlib.Path): path = pathlib.Path(path) abs_path = path.absolute() if relative_to is None: relative_to = pathlib.Path().absolute() if not isinstance(relative_to, pathlib.Path): relative_to = pathlib.Path(relative_to) relative_to = relative_to.absolute() try: return abs_path.relative_to(relative_to) except ValueError: return abs_path
def commit_changed_files( repo_path: PathLike, managed_files: Iterable[PathLike], commit: Optional[bool] = None, message: bytes = b"Updated files with 'repo_helper'.", enable_pre_commit: bool = True, ) -> bool: """ Stage and commit any files that have been updated, added or removed. :param repo_path: The path to the repository root. :param managed_files: List of files managed by ``repo_helper``. :param commit: Whether to commit the changes automatically. :py:obj:`None` (default) indicates the user should be asked. :param message: The commit message to use. Default ``"Updated files with 'repo_helper'."`` :param enable_pre_commit: Whether to install and configure pre-commit. Default :py:obj`True`. :returns: :py:obj:`True` if the changes were committed. :py:obj:`False` otherwise. """ # this package from repo_helper.utils import commit_changes, sort_paths, stage_changes repo_path = PathPlus(repo_path).absolute() r = Repo(str(repo_path)) staged_files = stage_changes(r.path, managed_files) # Ensure pre-commit hooks are installed if enable_pre_commit and platform.system() == "Linux": with in_directory(repo_path), suppress(ImportError): # 3rd party import pre_commit.main # type: ignore pre_commit.main.main(["install"]) if staged_files: click.echo("\nThe following files will be committed:") # Sort staged_files and put directories first for staged_filename in sort_paths(*staged_files): click.echo(f" {staged_filename.as_posix()!s}") click.echo() if commit is None: commit = confirm("Commit?", default=True) if commit: if enable_pre_commit or "pre-commit" in r.hooks: # Ensure the working directory for pre-commit is correct r.hooks["pre-commit"].cwd = str( repo_path.absolute()) # type: ignore try: commit_id = commit_changes(r, message.decode("UTF-8")) click.echo(f"Committed as {commit_id}") return True except CommitError as e: click.echo(f"Unable to commit: {e}", err=True) else: click.echo("Changed files were staged but not committed.") else: click.echo("Nothing to commit") return False