Packages

Conventional-Commits-driven semantic releases for Gleam: analyse commits, compute the next version, generate release notes, and publish to Hex/npm and GitHub. A native Gleam port of semantic-release.

Current section

Files

Jump to
version_bump src version_bump@repo_url.erl
Raw

src/version_bump@repo_url.erl

-module(version_bump@repo_url).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/version_bump/repo_url.gleam").
-export([parse/1]).
-export_type([repo_ref/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Pure parsing of git remote URLs into host + owner + repo.\n"
"\n"
" Shared by the forge plugins: `github` only needs `owner`/`repo`, while\n"
" `forgejo` also needs the host so it can derive the API base URL of a\n"
" self-hosted instance. Handles the common remote forms:\n"
"\n"
" - `https://host/owner/repo.git` (also `http://`, optional `:port`)\n"
" - `git@host:owner/repo.git` (scp-like)\n"
" - `ssh://git@host/owner/repo.git`\n"
" - `git://host/owner/repo.git`\n"
" - any of the above wrapped in a `git+` prefix\n"
"\n"
" The trailing `.git` suffix and trailing slashes are stripped; extra path\n"
" segments after the repository name are ignored.\n"
).
-type repo_ref() :: {repo_ref, binary(), binary(), binary()}.
-file("src/version_bump/repo_url.gleam", 126).
-spec first_segment(binary()) -> binary().
first_segment(S) ->
case gleam@string:split_once(S, <<"/"/utf8>>) of
{ok, {Head, _}} ->
Head;
{error, _} ->
S
end.
-file("src/version_bump/repo_url.gleam", 112).
-spec drop_trailing_slash(binary()) -> binary().
drop_trailing_slash(S) ->
case gleam_stdlib:string_ends_with(S, <<"/"/utf8>>) of
true ->
drop_trailing_slash(gleam@string:drop_end(S, 1));
false ->
S
end.
-file("src/version_bump/repo_url.gleam", 119).
-spec strip_git_suffix(binary()) -> binary().
strip_git_suffix(S) ->
case gleam_stdlib:string_ends_with(S, <<".git"/utf8>>) of
true ->
gleam@string:drop_end(S, 4);
false ->
S
end.
-file("src/version_bump/repo_url.gleam", 105).
-spec drop_leading_slash(binary()) -> binary().
drop_leading_slash(S) ->
case S of
<<"/"/utf8, Rest/binary>> ->
drop_leading_slash(Rest);
_ ->
S
end.
-file("src/version_bump/repo_url.gleam", 81).
?DOC(
" Split an scp-like remainder (`host:owner/repo`, with the `git@` already\n"
" stripped) at the first `:`, falling back to `/` for bare `host/owner/repo`.\n"
).
-spec split_scp_remainder(binary()) -> {ok, {binary(), binary()}} | {error, nil}.
split_scp_remainder(Rest) ->
case gleam@string:split_once(Rest, <<":"/utf8>>) of
{ok, {Host, Path}} ->
{ok, {Host, Path}};
{error, _} ->
case gleam@string:split_once(Rest, <<"/"/utf8>>) of
{ok, {Host@1, Path@1}} ->
{ok, {Host@1, Path@1}};
{error, _} ->
{error, nil}
end
end.
-file("src/version_bump/repo_url.gleam", 93).
?DOC(" Strip an optional `user@` prefix from a host portion (e.g. `git@github.com`).\n").
-spec strip_userinfo(binary()) -> binary().
strip_userinfo(Rest) ->
case gleam@string:split_once(Rest, <<"@"/utf8>>) of
{ok, {Before, After}} ->
case gleam_stdlib:contains_string(Before, <<"/"/utf8>>) of
true ->
Rest;
false ->
After
end;
{error, _} ->
Rest
end.
-file("src/version_bump/repo_url.gleam", 72).
?DOC(
" Split a scheme URL's remainder (after `https://` etc.) at the first `/`,\n"
" keeping any `:port` as part of the host.\n"
).
-spec split_scheme_remainder(binary()) -> {ok, {binary(), binary()}} |
{error, nil}.
split_scheme_remainder(Rest) ->
case gleam@string:split_once(strip_userinfo(Rest), <<"/"/utf8>>) of
{ok, {Host, Path}} ->
{ok, {Host, Path}};
{error, _} ->
{error, nil}
end.
-file("src/version_bump/repo_url.gleam", 25).
?DOC(" Extract host, owner and repo from a git remote URL.\n").
-spec parse(binary()) -> {ok, repo_ref()} | {error, nil}.
parse(Url) ->
Trimmed = gleam@string:trim(Url),
Without_prefix = case Trimmed of
<<"git+"/utf8, Rest/binary>> ->
Rest;
Other ->
Other
end,
Split = case Without_prefix of
<<"https://"/utf8, Rest@1/binary>> ->
split_scheme_remainder(Rest@1);
<<"http://"/utf8, Rest@2/binary>> ->
split_scheme_remainder(Rest@2);
<<"ssh://"/utf8, Rest@3/binary>> ->
split_scheme_remainder(Rest@3);
<<"git://"/utf8, Rest@4/binary>> ->
split_scheme_remainder(Rest@4);
<<"git@"/utf8, Rest@5/binary>> ->
split_scp_remainder(Rest@5);
Other@1 ->
split_scp_remainder(Other@1)
end,
case Split of
{error, nil} ->
{error, nil};
{ok, {Host, Path}} ->
Path@1 = begin
_pipe = Path,
_pipe@1 = drop_leading_slash(_pipe),
_pipe@2 = strip_git_suffix(_pipe@1),
drop_trailing_slash(_pipe@2)
end,
case gleam@string:split_once(Path@1, <<"/"/utf8>>) of
{ok, {Owner, Repo}} ->
Repo@1 = first_segment(Repo),
case {Owner, Repo@1} of
{<<""/utf8>>, _} ->
{error, nil};
{_, <<""/utf8>>} ->
{error, nil};
{_, _} ->
{ok, {repo_ref, Host, Owner, Repo@1}}
end;
{error, _} ->
{error, nil}
end
end.