Packages
rebar3_hex
6.9.2
7.1.0
7.0.11
7.0.10
7.0.9
7.0.8
7.0.7
7.0.6
7.0.5
7.0.4
7.0.3
7.0.2
7.0.1
7.0.0
6.11.9
6.11.8
6.11.7
6.11.6
6.11.5
6.11.4
6.11.3
6.11.2
6.11.1
6.11.0
6.10.3
6.10.2
6.10.1
6.10.0
6.9.6
6.9.5
6.9.4
6.9.3
6.9.2
6.9.1
6.9.0
6.8.0
6.7.0
6.6.0
6.5.0
6.4.0
6.3.0
6.2.0
6.1.0
6.0.0
4.1.0
4.0.0
3.1.0
3.0.0
2.5.1
2.5.0
2.4.0
2.3.0
2.2.0
2.1.0
2.0.0
1.20.0
1.19.0
1.18.0
1.17.0
1.16.0
1.15.0
1.14.0
1.13.0
1.12.0
1.11.0
1.10.0
1.9.1
1.9.0
1.8.1
1.8.0
1.7.2
1.7.1
1.7.0
1.6.3
1.6.1
1.6.0
1.5.0
1.4.0
1.3.0
1.2.0
1.1.0
0.9.0
0.8.0
0.7.0
0.6.0
0.5.1
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
Hex.pm plugin for rebar3
Current section
Files
Jump to
Current section
Files
src/rebar3_hex_cut.erl
-module(rebar3_hex_cut).
-export([init/1,
do/1,
format_error/1]).
-include("rebar3_hex.hrl").
-define(PROVIDER, cut).
-define(DEPS, [{default, lock}]).
-define(ENDPOINT, "packages").
%% ===================================================================
%% Public API
%% ===================================================================
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
init(State) ->
Provider = providers:create([
{name, ?PROVIDER},
{module, ?MODULE},
{namespace, hex},
{bare, true},
{deps, ?DEPS},
{example, "rebar3 hex cut"},
{short_desc, "Increment version number and publish package"},
{desc, ""},
{opts, [{increment, $i, "increment", string,
"Type of semver increment: major, minor or patch"},
rebar3_hex:repo_opt()]}
]),
State1 = rebar_state:add_provider(State, Provider),
{ok, State1}.
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) ->
case rebar3_hex_config:repo(State) of
{ok, Repo} ->
handle_command(State, Repo);
{error, Reason} ->
?PRV_ERROR(Reason)
end.
handle_command(State, Repo) ->
{Args, _} = rebar_state:command_parsed_args(State),
case proplists:get_value(increment, Args, undefined) of
undefined ->
Apps = rebar3_hex_io:select_apps(rebar_state:project_apps(State)),
lists:foldl(fun(App, {ok, StateAcc}) ->
do_(App, Repo, StateAcc)
end, {ok, State}, Apps);
Type ->
case string_to_bump(Type) of
error ->
{error, {?MODULE, {bad_increment, Type}}};
Bump ->
Apps = rebar3_hex_io:select_apps(rebar_state:project_apps(State)),
lists:foldl(fun(App, {ok, StateAcc}) ->
do_(Bump, App, Repo, StateAcc)
end, {ok, State}, Apps)
end
end.
-spec format_error(any()) -> iolist().
format_error({no_write_key, RepoName}) ->
io_lib:format("No api key with permissions to write to the repository ~ts was found.", [RepoName]);
format_error({bad_increment, Type}) ->
io_lib:format("Increment must be major, minor or patch. ~s is not valid.", [Type]);
format_error(Reason) ->
rebar3_hex_error:format_error(Reason).
%% ===================================================================
%% Public API
%% ===================================================================
do_(App, HexConfig, State) ->
Version = rebar_app_info:original_vsn(App),
ResolvedVersion = rebar_utils:vcs_vsn(Version,
rebar_app_info:dir(App),
rebar_state:resources(State)),
Type = get_increment(ResolvedVersion),
do_(Type, App, HexConfig, State).
do_(Type, App, HexConfig, State) ->
Version = rebar_app_info:original_vsn(App),
ResolvedVersion = rebar_utils:vcs_vsn(Version,
rebar_app_info:dir(App),
rebar_state:resources(State)),
{ok, Ver} = verl:parse(rebar_utils:to_binary(ResolvedVersion)),
NewVersion = increment(Type, Ver),
AppSrcFile = rebar_app_info:app_file_src(App),
case Version of
_Git when Version =:= git orelse Version =:= "git" ->
rebar_api:info("Creating new tag v~s...", [NewVersion]),
rebar_utils:sh(io_lib:format("git tag v~s", [NewVersion]), []),
{application, _, AppDetails} = rebar3_hex_file:update_app_src(App, NewVersion),
case rebar3_hex_publish:validate_app_details(AppDetails) of
ok ->
Name = rebar_app_info:name(App),
AppDir = rebar_app_info:dir(App),
Deps = rebar_state:get(State, {locks, default}, []),
TopLevel = [{N, [{<<"app">>, A}, {<<"optional">>, false}, {<<"requirement">>, V}]}
|| {A,{pkg,N,V,_},0} <- Deps],
Excluded = [binary_to_list(N) || {N,{T,_,_},0} <- Deps, T =/= pkg],
case rebar3_hex_publish:publish(AppDir, Name, NewVersion, TopLevel,
Excluded, AppDetails, HexConfig, State) of
{ok, _State} ->
case rebar3_hex_io:ask("Push new tag to origin?", boolean, "Y") of
true ->
rebar_api:info("Pushing new tag v~s...", [NewVersion]),
rebar_utils:sh(io_lib:format("git push origin v~s", [NewVersion]), []),
{ok, State};
false ->
{ok, State}
end;
{error, _} = Error ->
rebar_api:info("Deleting new tag v~s...", [NewVersion]),
rebar_utils:sh(io_lib:format("git tag -d v~s", [NewVersion]), []),
Error
end;
Error ->
Error
end;
_ ->
Spec = rebar3_hex_file:update_app_src(App, NewVersion),
NewAppSrcFile = io_lib:format("~tp.\n", [Spec]),
ok = rebar_file_utils:write_file_if_contents_differ(AppSrcFile, NewAppSrcFile),
ask_commit_and_push(NewVersion),
rebar3_hex_publish:publish(rebar_app_info:original_vsn(App, NewVersion), HexConfig, State),
{ok, State}
end.
get_increment(Version) ->
rebar3_hex_io:say("Select semver increment or other (Current ~s):", [Version]),
rebar3_hex_io:say("1) patch", []),
rebar3_hex_io:say("2) minor", []),
rebar3_hex_io:say("3) major", []),
rebar3_hex_io:say("4) other", []),
case rebar3_hex_io:ask("[1-4] ", number) of
4 ->
rebar3_hex_io:ask("New Version ", string);
Type ->
int_to_bump(Type)
end.
increment(patch, #{major := Maj, minor := Min, patch := Patch}) ->
ver_format(#{major => Maj, minor => Min, patch => Patch + 1});
increment(minor, #{major := Maj, minor := Min}) ->
ver_format(#{major => Maj, minor => Min + 1, patch => 0});
increment(major, #{major := Maj}) ->
ver_format(#{major => Maj + 1, minor => 0, patch => 0});
increment(Version, _) when is_list(Version) ->
rebar_utils:to_binary(Version).
%% TODO: Support pre and build
ver_format(#{major := Maj, minor := Min, patch := Patch}) ->
MajBin = integer_to_binary(Maj),
MinBin = integer_to_binary(Min),
PatchBin = integer_to_binary(Patch),
DotBin = <<".">>,
<<MajBin/binary, DotBin/binary, MinBin/binary, DotBin/binary, PatchBin/binary>>.
int_to_bump(1) -> patch;
int_to_bump(2) -> minor;
int_to_bump(3) -> major;
int_to_bump(_) -> error.
string_to_bump("patch") -> patch;
string_to_bump("minor") -> minor;
string_to_bump("major") -> major;
string_to_bump(_) -> error.
ask_commit_and_push(NewVersion) ->
case rebar3_hex_io:ask(io_lib:format("Create 'v~s' commit?", [NewVersion]), boolean, "Y") of
true ->
rebar_utils:sh(io_lib:format("git commit -a -m 'v~s'", [NewVersion]), []),
case rebar3_hex_io:ask("Push master to origin master?", boolean, "N") of
true ->
rebar_utils:sh("git push origin master:master", []);
false ->
ok
end;
false ->
ok
end.