-module(version_bump). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/version_bump.gleam"). -export([apply_dry_run/2, parse_args/1, main/0]). -export_type([command/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( " CLI entrypoint for version_bump, a native Gleam port of semantic-release.\n" "\n" " The default invocation runs the full release pipeline against the working\n" " directory (`--cwd `, default `.`):\n" "\n" " 1. read every environment variable into a `Dict(String, String)`\n" " 2. load configuration from the project (`config.load`)\n" " 3. apply CLI overrides (e.g. `--dry-run`)\n" " 4. run `engine.run` and report the resulting `Summary`\n" "\n" " On error the formatted message is printed and the process exits non-zero.\n" " `--version`/`version` prints the tool version; `--help`/`-h` prints usage.\n" ). -type command() :: {release, binary(), boolean()} | show_version | show_help. -file("src/version_bump.gleam", 149). -spec usage() -> binary(). usage() -> gleam@string:join( [<<"version_bump "/utf8, "0.1.2"/utf8>>, <<""/utf8>>, <<"Usage:"/utf8>>, <<" version_bump [--cwd ] [--dry-run] Run the release pipeline"/utf8>>, <<" version_bump --version Print the version and exit"/utf8>>, <<" version_bump --help Print this help and exit"/utf8>>, <<""/utf8>>, <<"Flags:"/utf8>>, <<" --cwd Run against the project at (default: .)"/utf8>>, <<" --dry-run Compute the next release without tagging or publishing"/utf8>>], <<"\n"/utf8>> ). -file("src/version_bump.gleam", 142). ?DOC(" Report an error to the log and exit non-zero.\n"). -spec fail(version_bump@error:release_error()) -> nil. fail(Err) -> version_bump@logging:error(version_bump@error:to_string(Err)), version_bump_ffi:halt(1). -file("src/version_bump.gleam", 133). ?DOC(" Print a human-readable summary of a successful (or no-op) run.\n"). -spec print_summary(version_bump@engine:summary()) -> nil. print_summary(Summary) -> case {erlang:element(2, Summary), erlang:element(3, Summary)} of {true, {some, V}} -> version_bump@logging:success( <<"Published release "/utf8, V/binary>> ); {false, {some, V@1}} -> version_bump@logging:info( <<"Dry-run: next release would be "/utf8, V@1/binary>> ); {_, none} -> version_bump@logging:info(<<"No release published"/utf8>>) end. -file("src/version_bump.gleam", 125). ?DOC( " Apply the `--dry-run` flag, only ever turning dry-run on (the flag is an\n" " override, never a way to force a real release when config disables it). Pure,\n" " so it is unit-tested directly.\n" ). -spec apply_dry_run(version_bump@config:config(), boolean()) -> version_bump@config:config(). apply_dry_run(Config, Dry_run) -> case Dry_run of true -> {config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), true, erlang:element(7, Config), erlang:element(8, Config)}; false -> Config end. -file("src/version_bump.gleam", 104). ?DOC(" Load config, apply the `--dry-run` override, run the pipeline, and report.\n"). -spec run_release(binary(), boolean()) -> nil. run_release(Cwd, Dry_run) -> Env = envoy_ffi:all(), case version_bump@config:load(Cwd) of {error, Err} -> fail(Err); {ok, Loaded} -> Config = apply_dry_run(Loaded, Dry_run), version_bump_task_ffi:run( version_bump@engine:run(Config, Cwd, Env), fun(Result) -> case Result of {ok, Summary} -> print_summary(Summary); {error, Err@1} -> fail(Err@1) end end ) end. -file("src/version_bump.gleam", 78). ?DOC(" Walk the release flags, threading the working directory and dry-run state.\n"). -spec accumulate_release(list(binary()), binary(), boolean()) -> {ok, command()} | {error, binary()}. accumulate_release(Args, Cwd, Dry_run) -> case Args of [] -> {ok, {release, Cwd, Dry_run}}; [<<"--dry-run"/utf8>> | Rest] -> accumulate_release(Rest, Cwd, true); [<<"--cwd"/utf8>>] -> {error, <<"--cwd requires a path argument"/utf8>>}; [<<"--cwd"/utf8>>, Value | Rest@1] -> case gleam_stdlib:string_starts_with(Value, <<"-"/utf8>>) of true -> {error, <<"--cwd requires a path argument"/utf8>>}; false -> accumulate_release(Rest@1, Value, Dry_run) end; [Arg | Rest@2] -> case gleam@string:split_once(Arg, <<"="/utf8>>) of {ok, {<<"--cwd"/utf8>>, <<""/utf8>>}} -> {error, <<"--cwd requires a path argument"/utf8>>}; {ok, {<<"--cwd"/utf8>>, Value@1}} -> accumulate_release(Rest@2, Value@1, Dry_run); _ -> {error, <<"Unknown flag: "/utf8, Arg/binary>>} end end. -file("src/version_bump.gleam", 73). ?DOC( " Parse the flags accepted by the default (release) command: `--dry-run` and\n" " `--cwd ` (the `--cwd=` form is also accepted). Unknown flags are\n" " rejected so the user gets clear feedback rather than a silent no-op.\n" ). -spec parse_release_args(list(binary())) -> {ok, command()} | {error, binary()}. parse_release_args(Args) -> accumulate_release(Args, <<"."/utf8>>, false). -file("src/version_bump.gleam", 59). ?DOC( " Classify the raw arguments into a `Command`. Unknown flags are rejected so\n" " the user gets clear feedback rather than a silent no-op. Pure, so it is\n" " unit-tested directly.\n" ). -spec parse_args(list(binary())) -> {ok, command()} | {error, binary()}. parse_args(Args) -> case gleam@list:contains(Args, <<"--version"/utf8>>) orelse gleam@list:contains( Args, <<"version"/utf8>> ) of true -> {ok, show_version}; false -> case gleam@list:contains(Args, <<"--help"/utf8>>) orelse gleam@list:contains( Args, <<"-h"/utf8>> ) of true -> {ok, show_help}; false -> parse_release_args(Args) end end. -file("src/version_bump.gleam", 40). -spec main() -> nil. main() -> Args = erlang:element(4, argv:load()), case parse_args(Args) of {ok, show_version} -> gleam_stdlib:println(<<"0.1.2"/utf8>>); {ok, show_help} -> gleam_stdlib:println(usage()); {ok, {release, Cwd, Dry_run}} -> run_release(Cwd, Dry_run); {error, Message} -> version_bump@logging:error(Message), gleam_stdlib:println(usage()), version_bump_ffi:halt(2) end.