Skip to main content

src/version_bump@plugin.erl

-module(version_bump@plugin).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/version_bump/plugin.gleam").
-export([new/1]).
-export_type([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 plugin contract — the extensibility surface of the whole tool.\n"
    "\n"
    " semantic-release plugins are JS modules that duck-type which lifecycle hooks\n"
    " they implement. Gleam has no dynamic dispatch, so a plugin is a record of\n"
    " optional hook functions. A plugin implements a hook by setting that field to\n"
    " `Some(fn)`; the engine skips `None` fields.\n"
    "\n"
    " Per-hook return semantics (enforced by the engine, not plugins):\n"
    "   - analyze_commits: highest `ReleaseType` across plugins wins\n"
    "   - generate_notes:  results are concatenated in plugin order\n"
    "   - publish:         `Some(release)` published, `None` means \"not handled\"\n"
    "   - others:          run for effect; failure aborts the pipeline\n"
).

-type plugin() :: {plugin,
        binary(),
        gleam@option:option(fun((version_bump@config:plugin_spec(), version_bump@context:context()) -> {ok,
                nil} |
            {error, version_bump@error:release_error()})),
        gleam@option:option(fun((version_bump@config:plugin_spec(), version_bump@context:context()) -> {ok,
                gleam@option:option(version_bump@semver:release_type())} |
            {error, version_bump@error:release_error()})),
        gleam@option:option(fun((version_bump@config:plugin_spec(), version_bump@context:context()) -> {ok,
                nil} |
            {error, version_bump@error:release_error()})),
        gleam@option:option(fun((version_bump@config:plugin_spec(), version_bump@context:context()) -> {ok,
                binary()} |
            {error, version_bump@error:release_error()})),
        gleam@option:option(fun((version_bump@config:plugin_spec(), version_bump@context:context()) -> {ok,
                gleam@option:option(version_bump@release:release())} |
            {error, version_bump@error:release_error()})),
        gleam@option:option(fun((version_bump@config:plugin_spec(), version_bump@context:context()) -> {ok,
                nil} |
            {error, version_bump@error:release_error()})),
        gleam@option:option(fun((version_bump@config:plugin_spec(), version_bump@context:context()) -> version_bump@task:task({ok,
                gleam@option:option(version_bump@release:release())} |
            {error, version_bump@error:release_error()}))),
        gleam@option:option(fun((version_bump@config:plugin_spec(), version_bump@context:context()) -> {ok,
                nil} |
            {error, version_bump@error:release_error()})),
        gleam@option:option(fun((version_bump@config:plugin_spec(), version_bump@context:context()) -> {ok,
                nil} |
            {error, version_bump@error:release_error()}))}.

-file("src/version_bump/plugin.gleam", 69).
?DOC(
    " A plugin implementing no hooks. Build concrete plugins with record updates,\n"
    " e.g. `Plugin(..new(\"npm\"), publish: Some(do_publish))`.\n"
).
-spec new(binary()) -> plugin().
new(Name) ->
    {plugin, Name, none, none, none, none, none, none, none, none, none}.