diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rebar.app.src | 1 | ||||
-rw-r--r-- | src/rebar_prv_lock.erl | 6 | ||||
-rw-r--r-- | src/rebar_prv_unlock.erl | 84 |
3 files changed, 86 insertions, 5 deletions
diff --git a/src/rebar.app.src b/src/rebar.app.src index 63cca9c..b404c42 100644 --- a/src/rebar.app.src +++ b/src/rebar.app.src @@ -49,6 +49,7 @@ rebar_prv_report, rebar_prv_shell, rebar_prv_tar, + rebar_prv_unlock, rebar_prv_update, rebar_prv_upgrade, rebar_prv_version, diff --git a/src/rebar_prv_lock.erl b/src/rebar_prv_lock.erl index f88b1ff..6fdd743 100644 --- a/src/rebar_prv_lock.erl +++ b/src/rebar_prv_lock.erl @@ -23,7 +23,7 @@ init(State) -> {deps, ?DEPS}, {example, ""}, {short_desc, "Locks dependencies."}, - {desc, info("Locks dependencies")}, + {desc, "Locks dependencies"}, {opts, []}])), {ok, State1}. @@ -39,9 +39,6 @@ do(State) -> format_error(Reason) -> io_lib:format("~p", [Reason]). -info(_) -> - "". - build_locks(State) -> AllDeps = rebar_state:lock(State), [begin @@ -54,4 +51,3 @@ build_locks(State) -> ,rebar_fetch:lock_source(Dir, Source, State) ,rebar_app_info:dep_level(Dep)} end || Dep <- AllDeps, not(rebar_app_info:is_checkout(Dep))]. - diff --git a/src/rebar_prv_unlock.erl b/src/rebar_prv_unlock.erl new file mode 100644 index 0000000..dc9fe11 --- /dev/null +++ b/src/rebar_prv_unlock.erl @@ -0,0 +1,84 @@ +-module(rebar_prv_unlock). + +-behaviour(provider). + +-export([init/1, + do/1, + format_error/1]). + +-include("rebar.hrl"). +-include_lib("providers/include/providers.hrl"). + +-define(PROVIDER, unlock). +-define(DEPS, []). + +%% =================================================================== +%% Public API +%% =================================================================== + +-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. +init(State) -> + State1 = rebar_state:add_provider( + State, + providers:create([{name, ?PROVIDER}, + {module, ?MODULE}, + {bare, false}, + {deps, ?DEPS}, + {example, ""}, + {short_desc, "Unlock dependencies."}, + {desc, "Unlock project dependencies. Mentioning no application " + "will unlock all dependencies. To unlock specific dependencies, " + "their name can be listed in the command."}, + {opts, [ + {package, undefined, undefined, string, + "List of packages to upgrade. If not specified, all dependencies are upgraded."} + ]} + ]) + ), + {ok, State1}. + +do(State) -> + Dir = rebar_state:dir(State), + LockFile = filename:join(Dir, ?LOCK_FILE), + case file:consult(LockFile) of + {error, enoent} -> + %% Our work is done. + {ok, State}; + {error, Reason} -> + ?PRV_ERROR({file,Reason}); + {ok, [Locks]} -> + case handle_unlocks(State, Locks, LockFile) of + ok -> + {ok, State}; + {error, Reason} -> + ?PRV_ERROR({file,Reason}) + end; + {ok, _Other} -> + ?PRV_ERROR(unknown_lock_format) + end. + +-spec format_error(any()) -> iolist(). +format_error({file, Reason}) -> + io_lib:format("Lock file editing failed for reason ~p", [Reason]); +format_error(unknown_lock_format) -> + "Lock file format unknown"; +format_error(Reason) -> + io_lib:format("~p", [Reason]). + +handle_unlocks(State, Locks, LockFile) -> + {Args, _} = rebar_state:command_parsed_args(State), + Names = parse_names(ec_cnv:to_binary(proplists:get_value(package, Args, <<"">>))), + case [Lock || Lock = {Name, _, _} <- Locks, not lists:member(Name, Names)] of + [] -> + file:delete(LockFile); + _ when Names =:= [] -> % implicitly all locks + file:delete(LockFile); + NewLocks -> + file:write_file(LockFile, io_lib:format("~p.~n", [NewLocks])) + end. + +parse_names(Bin) -> + case lists:usort(re:split(Bin, <<" *, *">>, [trim])) of + [<<"">>] -> []; % nothing submitted + Other -> Other + end. |