Current section
Files
Jump to
Current section
Files
lib/git/git_path.ex
defmodule GitHooks.Git.GitPath do
@moduledoc false
@doc """
Returns the absolute path to the project's root directory.
"""
def resolve_app_path do
case Application.get_env(:git_hooks, :project_path) do
nil -> git_toplevel()
path -> Path.expand(path)
end
end
@doc """
Returns the absolute `.git/hooks` path directory for the parent project.
"""
def resolve_git_hooks_path do
app_path = resolve_app_path()
{git_hooks_path, 0} =
System.cmd("git", ["rev-parse", "--git-path", "hooks"], cd: app_path)
git_hooks_path
|> String.trim()
|> Path.expand(app_path)
end
@doc """
Returns the path to a specific hook file within the `.git/hooks` directory.
"""
def git_hooks_path_for(hook_name) do
resolve_git_hooks_path()
|> Path.join(hook_name)
|> Path.expand()
end
#
# Private helper functions
#
# Resolves the working tree root via git so it works inside worktrees, where
# `.git` is a file rather than a directory (including worktrees nested in an
# unrelated parent repo).
defp git_toplevel do
case System.cmd("git", ["rev-parse", "--show-toplevel"],
cd: File.cwd!(),
stderr_to_stdout: true
) do
{path, 0} ->
path
|> String.trim()
|> Path.expand()
{output, _exit_code} ->
raise "git_hooks: #{File.cwd!()} is not inside a git working tree.\n#{String.trim(output)}"
end
end
end