From 38cb573dbe72019eff4005c371b32bbbcef5318c Mon Sep 17 00:00:00 2001 From: Adrian Quintas Date: Fri, 29 Nov 2024 15:27:34 +1100 Subject: [PATCH] Ensure git path resolution for different versions Updated `resolve_git_path/1` to handle both legacy and modern git versions correctly and ensured absolute paths are returned for all git-related path resolution functions. --- lib/git/git_path.ex | 46 +++++++++++++++++++++++++++++++++++++++------ mix.exs | 2 +- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/lib/git/git_path.ex b/lib/git/git_path.ex index a83d3ed..732168e 100644 --- a/lib/git/git_path.ex +++ b/lib/git/git_path.ex @@ -1,35 +1,69 @@ defmodule GitHooks.Git.GitPath do @moduledoc false + alias GitHooks.Git + @doc """ Returns the absolute path to the project's root directory. """ def resolve_app_path do - # Attempt to get the project path from the config, - # otherwise find the git root by traversing upwards. - Application.get_env(:git_hooks, :project_path) || + project_path = Application.get_env(:git_hooks, :project_path) + + if project_path do + Path.expand(project_path) + else + # Find the git root by traversing upwards find_git_root(File.cwd!()) || - raise "Could not find .git directory from #{File.cwd!()}" + raise "Could not find .git directory from #{File.cwd!()}" + end end @doc """ Returns the absolute `.git/hooks` path directory for the parent project. """ def resolve_git_hooks_path do - Path.join(resolve_git_dir(), "hooks") + "hooks" + |> resolve_git_path() + |> Path.expand(resolve_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 - Path.join(resolve_git_hooks_path(), hook_name) + resolve_git_hooks_path() + |> Path.join(hook_name) + |> Path.expand() end # # Private helper functions # + # Resolves the absolute path to a directory within the `.git` directory + defp resolve_git_path(dir) when is_binary(dir) and dir != "" do + git_path = + Git.git_version() + |> Version.compare(Version.parse!("2.10.0")) + |> case do + :lt -> + git_dir = resolve_git_dir() + Path.join(git_dir, dir) + + _ -> + {git_path, 0} = + System.cmd("git", ["rev-parse", "--git-path", dir], cd: resolve_app_path()) + + String.trim(git_path) + end + + Path.expand(git_path, resolve_app_path()) + end + + defp resolve_git_path(_dir) do + raise ArgumentError, "resolve_git_path/1 requires a non-empty directory argument" + end + # Returns the absolute `.git` directory path for the parent project. defp resolve_git_dir do {git_dir, 0} = diff --git a/mix.exs b/mix.exs index 2f142ae..a9eea47 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule GitHooks.MixProject do use Mix.Project @source_url "https://github.com/qgadrian/elixir_git_hooks" - @version "0.8.0-pre1" + @version "0.8.0-pre2" def project do [