Skip to content
This repository has been archived by the owner on Oct 8, 2020. It is now read-only.

Commit

Permalink
Xgit.Core.Ref: Add link_target member.
Browse files Browse the repository at this point in the history
  • Loading branch information
scouten committed Nov 26, 2019
1 parent fd1ca70 commit 3fb77c7
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 4 deletions.
15 changes: 11 additions & 4 deletions lib/xgit/core/ref.ex
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ defmodule Xgit.Core.Ref do
* `:name`: the name of the reference (typically `refs/heads/master` or similar)
* `:target`: the object ID currently marked by this reference or a symbolic link
(`ref: refs/heads/master` or similar) to another reference
* `:link_target`: the name of another reference which is targeted by this ref
"""
@type t :: %__MODULE__{
name: name(),
target: target()
target: target(),
link_target: name()
}

@enforce_keys [:name, :target]
defstruct [:name, :target]
defstruct [:name, :target, :link_target]

@doc ~S"""
Return `true` if the string describes a valid reference name.
Expand All @@ -64,18 +66,23 @@ defmodule Xgit.Core.Ref do
@spec valid?(ref :: any, allow_one_level?: boolean, refspec?: boolean) :: boolean
def valid?(ref, opts \\ [])

def valid?(%__MODULE__{name: name, target: target}, opts)
def valid?(%__MODULE__{name: name, target: target} = ref, opts)
when is_binary(name) and is_binary(target)
when is_list(opts) do
valid_name?(
name,
Keyword.get(opts, :allow_one_level?, false),
Keyword.get(opts, :refspec?, false)
) && valid_target?(target)
) && valid_target?(target) &&
valid_name_or_nil?(Map.get(ref, :link_target))
end

def valid?(_, _opts), do: cover(false)

defp valid_name_or_nil?(nil), do: cover(true)
defp valid_name_or_nil?("refs/" <> _ = target_name), do: cover(valid_name?(target_name))
defp valid_name_or_nil?(_), do: cover(false)

defp valid_name?("@", _, _), do: cover(false)

defp valid_name?(name, true, false) do
Expand Down
37 changes: 37 additions & 0 deletions test/xgit/core/ref_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,43 @@ defmodule Xgit.Core.RefTest do
end
end

describe "valid?/1 link_target" do
defp assert_valid_link_target(link_target) do
assert Ref.valid?(%Ref{
name: "refs/heads/master",
target: "fd1ca70f4d329c6ee9e47f3bbef65a3884236f08",
link_target: link_target
})
end

defp refute_valid_link_target(link_target) do
refute Ref.valid?(%Ref{
name: "refs/heads/master",
target: "fd1ca70f4d329c6ee9e47f3bbef65a3884236f08",
link_target: link_target
})
end

test "object ID" do
refute_valid_link_target("1234567890abcdef12341234567890abcdef1234")
end

test "nil" do
assert_valid_link_target(nil)
end

test "valid ref name" do
assert_valid_link_target("refs/heads/master")
refute_valid_link_target("")
refute_valid_link_target("refs")
end

test "ref must point inside of refs/ hierarchy" do
refute_valid_link_target("refsxyz/heads/master")
refute_valid_link_target("rex/heads/master")
end
end

test "valid?/1 not a Ref" do
refute Ref.valid?("refs/heads/master")
refute Ref.valid?(42)
Expand Down

0 comments on commit 3fb77c7

Please sign in to comment.