Current section

Files

Jump to
purl src purl_resource.erl
Raw

src/purl_resource.erl

-module(purl_resource).
-feature(maybe_expr, enable).
-include("internal/doc.hrl").
-include("purl.hrl").
?MODULEDOC(false).
-export([from_uri/1]).
-spec from_uri(Uri) -> {ok, purl:t()} | error when
Uri :: uri_string:uri_map() | uri_string:uri_string().
from_uri(#{scheme := <<"https">>, path := Path, host := <<"github.com">>}) ->
PathWithoutGit = remove_git_suffix(Path),
PathSegments = split_path(PathWithoutGit),
case PathSegments of
[User, Repository] ->
purl:new(#purl{type = <<"github">>, namespace = [User], name = Repository});
_Other ->
error
end;
from_uri(#{scheme := <<"git+ssh">>, path := Path, userinfo := <<"git">>, host := <<"github.com">>}) ->
PathWithoutGit = remove_git_suffix(Path),
PathSegments = split_path(PathWithoutGit),
case PathSegments of
[User, Repository] ->
purl:new(#purl{type = <<"github">>, namespace = [User], name = Repository});
_Other ->
error
end;
from_uri(#{scheme := <<"https">>, path := Path, host := <<"bitbucket.org">>}) ->
PathWithoutGit = remove_git_suffix(Path),
PathSegments = split_path(PathWithoutGit),
case PathSegments of
[User, Repository] ->
purl:new(#purl{type = <<"bitbucket">>, namespace = [User], name = Repository});
_Other ->
error
end;
from_uri(#{
scheme := <<"git+ssh">>, path := Path, userinfo := <<"git">>, host := <<"bitbucket.org">>
}) ->
PathWithoutGit = remove_git_suffix(Path),
PathSegments = split_path(PathWithoutGit),
case PathSegments of
[User, Repository] ->
purl:new(#purl{type = <<"bitbucket">>, namespace = [User], name = Repository});
_Other ->
error
end;
from_uri(#{scheme := <<"https">>, path := <<"/packages/"/utf8, Path/binary>>, host := <<"hex.pm">>}) ->
PathSegments = split_path(Path),
case PathSegments of
[Package] ->
purl:new(#purl{type = <<"hex">>, namespace = [], name = Package});
_Other ->
error
end;
from_uri(#{}) ->
error;
from_uri(Uri) ->
case uri_string:parse(Uri) of
#{} = UriMap ->
from_uri(UriMap);
{error, _Type, _Term} ->
case uri_string:parse(convert_git_to_normal_uri(Uri)) of
#{} = UriMap -> from_uri(UriMap);
{error, _GitType, _GitTerm} -> error
end
end.
-spec remove_git_suffix(Path) -> Path when Path :: binary().
remove_git_suffix(Path) -> re:replace(Path, "\\.git$", "", [{return, binary}, unicode]).
-spec split_path(Path) -> [binary()] when Path :: binary().
split_path(Path) -> binary:split(Path, <<"/">>, [trim_all, global]).
-spec convert_git_to_normal_uri(Uri) -> binary() when Uri :: binary().
convert_git_to_normal_uri(Uri) ->
Replaced = re:replace(Uri, ":", "/", [{return, binary}]),
<<"git+ssh://", Replaced/binary>>.