Skip to main content

src/version_bump@plugins@git.erl

-module(version_bump@plugins@git).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/version_bump/plugins/git.gleam").
-export([render_message/2, parse_assets/1, plugin/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(
    " The git plugin (plugin name \"git\").\n"
    "\n"
    " Mirrors `@semantic-release/git`. In `prepare` it stages the release assets\n"
    " that earlier plugins changed (e.g. the `gleam.toml` version bumped by `hex`,\n"
    " or a `CHANGELOG.md`) and commits them. Because the engine creates the release\n"
    " tag *after* all `prepare` hooks and pushes the branch alongside the tag, the\n"
    " tag then points at the commit containing the bump — keeping the committed\n"
    " version, the tag, and the published version consistent.\n"
    "\n"
    " List this plugin AFTER the plugins that modify files (e.g. `hex`). Options\n"
    " (all optional, with sensible defaults):\n"
    "   - `assets`         comma-separated paths to stage (default \"gleam.toml\")\n"
    "   - `message`        commit message template; `${version}` is substituted\n"
    "                      (default \"chore(release): ${version} [skip ci]\")\n"
    "   - `committerName`  commit author/committer name (default \"version_bump\")\n"
    "   - `committerEmail` commit author/committer email\n"
).

-file("src/version_bump/plugins/git.gleam", 79).
?DOC(" Look up an option, treating a present-but-blank value as absent.\n").
-spec option_or(version_bump@config:plugin_spec(), binary(), binary()) -> binary().
option_or(Spec, Key, Fallback) ->
    case gleam_stdlib:map_get(erlang:element(3, Spec), Key) of
        {ok, Value} ->
            case gleam@string:trim(Value) of
                <<""/utf8>> ->
                    Fallback;

                _ ->
                    Value
            end;

        {error, _} ->
            Fallback
    end.

-file("src/version_bump/plugins/git.gleam", 63).
?DOC(" Render the commit message, substituting `${version}`. PURE.\n").
-spec render_message(binary(), binary()) -> binary().
render_message(Template, Version) ->
    gleam@string:replace(Template, <<"${version}"/utf8>>, Version).

-file("src/version_bump/plugins/git.gleam", 69).
?DOC(
    " Parse a comma-separated `assets` option into a trimmed, non-empty path list.\n"
    " PURE.\n"
).
-spec parse_assets(binary()) -> list(binary()).
parse_assets(Raw) ->
    _pipe = Raw,
    _pipe@1 = gleam@string:split(_pipe, <<","/utf8>>),
    _pipe@2 = gleam@list:map(_pipe@1, fun gleam@string:trim/1),
    gleam@list:filter(_pipe@2, fun(Path) -> Path /= <<""/utf8>> end).

-file("src/version_bump/plugins/git.gleam", 90).
-spec require_next_release(version_bump@context:context()) -> {ok,
        version_bump@release:next_release()} |
    {error, version_bump@error:release_error()}.
require_next_release(Context) ->
    case erlang:element(9, Context) of
        {some, Next} ->
            {ok, Next};

        none ->
            {error,
                {plugin_error,
                    <<"git"/utf8>>,
                    <<"no next release determined"/utf8>>}}
    end.

-file("src/version_bump/plugins/git.gleam", 47).
-spec do_prepare(
    version_bump@config:plugin_spec(),
    version_bump@context:context()
) -> {ok, nil} | {error, version_bump@error:release_error()}.
do_prepare(Spec, Context) ->
    gleam@result:'try'(
        require_next_release(Context),
        fun(Next) ->
            Assets = parse_assets(
                option_or(Spec, <<"assets"/utf8>>, <<"gleam.toml"/utf8>>)
            ),
            Message = render_message(
                option_or(
                    Spec,
                    <<"message"/utf8>>,
                    <<"chore(release): ${version} [skip ci]"/utf8>>
                ),
                erlang:element(2, Next)
            ),
            Committer_name = option_or(
                Spec,
                <<"committerName"/utf8>>,
                <<"version_bump"/utf8>>
            ),
            Committer_email = option_or(
                Spec,
                <<"committerEmail"/utf8>>,
                <<"version_bump@users.noreply.github.com"/utf8>>
            ),
            gleam@result:'try'(
                version_bump@git:stage(erlang:element(2, Context), Assets),
                fun(_) ->
                    version_bump@git:commit(
                        erlang:element(2, Context),
                        Message,
                        Committer_name,
                        Committer_email
                    )
                end
            )
        end
    ).

-file("src/version_bump/plugins/git.gleam", 43).
?DOC(
    " Build the git plugin: implements only `prepare` (the commit). The engine\n"
    " handles creating and pushing the tag and the branch.\n"
).
-spec plugin() -> version_bump@plugin:plugin().
plugin() ->
    _record = version_bump@plugin:new(<<"git"/utf8>>),
    {plugin,
        erlang:element(2, _record),
        erlang:element(3, _record),
        erlang:element(4, _record),
        erlang:element(5, _record),
        erlang:element(6, _record),
        erlang:element(7, _record),
        {some, fun do_prepare/2},
        erlang:element(9, _record),
        erlang:element(10, _record),
        erlang:element(11, _record)}.