summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Sloughter <tristan.sloughter@gmail.com>2015-09-07 13:19:11 -0500
committerTristan Sloughter <tristan.sloughter@gmail.com>2015-09-07 13:19:11 -0500
commitd7f2226d31f4708518c1ddb41f7666f9c1d0f151 (patch)
tree1ef34c11592cac77eac4ccfbd047bcb952642bef
parent77e5e6b8f3028626afb4a687c1b02709a2dbd9b6 (diff)
parent04da2ffd5e65895ff0beb6f8f3ffd0deb95328de (diff)
Merge pull request #761 from talentdeficit/rebar_path
`rebar3 path' provider
-rw-r--r--README.md1
-rw-r--r--priv/shell-completion/bash/rebar312
-rw-r--r--priv/shell-completion/fish/rebar3.fish12
-rw-r--r--priv/shell-completion/zsh/_rebar311
-rw-r--r--src/rebar.app.src1
-rw-r--r--src/rebar_prv_path.erl127
6 files changed, 164 insertions, 0 deletions
diff --git a/README.md b/README.md
index 4054b8d..8d85934 100644
--- a/README.md
+++ b/README.md
@@ -35,6 +35,7 @@ locations ([hex.pm](http://hex.pm), git, hg, and so on).
| eunit | Run eunit tests |
| help | Print help for rebar or task |
| new | Create new rebar project from templates |
+| path | Print paths to build dirs in current profile |
| pkgs | List available packages |
| plugins | List or upgrade plugins |
| release | Build release of project |
diff --git a/priv/shell-completion/bash/rebar3 b/priv/shell-completion/bash/rebar3
index 40009b7..511d537 100644
--- a/priv/shell-completion/bash/rebar3
+++ b/priv/shell-completion/bash/rebar3
@@ -23,6 +23,7 @@ _rebar3()
eunit \
help \
new \
+ path \
pkgs \
plugins \
release \
@@ -98,6 +99,17 @@ _rebar3()
elif [[ ${prev} == new ]] ; then
sopts="-f"
lopts="--force"
+ elif [[ ${prev} == path ]] ; then
+ sopts="-s"
+ lopts="--app \
+ --base \
+ --bin \
+ --ebin \
+ --lib \
+ --priv \
+ --separator \
+ --src \
+ --rel"
elif [[ ${prev} == pkgs ]] ; then
:
elif [[ ${prev} == plugins ]] ; then
diff --git a/priv/shell-completion/fish/rebar3.fish b/priv/shell-completion/fish/rebar3.fish
index df1697e..f3b449e 100644
--- a/priv/shell-completion/fish/rebar3.fish
+++ b/priv/shell-completion/fish/rebar3.fish
@@ -44,6 +44,7 @@ end
## eunit Run EUnit Tests.
## help Display a list of tasks or help for a given task or subtask.
## new Create new project from templates.
+## path Print paths to build dirs in current profile.
## pkgs List available packages.
## release Build release of project.
## relup Create relup of releases.
@@ -118,6 +119,17 @@ complete -f -c 'rebar3' -n '__fish_rebar3_needs_command' -a new -d "Create new p
complete -f -c 'rebar3' -n '__fish_rebar3_using_command new' -s f -l force -d "Overwrite existing files"
complete -f -c 'rebar3' -n '__fish_rebar3_using_command new' -a help -d "Display all variables and arguments for each template"
+complete -f -c 'rebar3' -n '__fish_rebar3_needs_command' -a paths -d "Print paths to build dirs in current profile."
+complete -f -c 'rebar3' -n '__fish_rebar3_needs_command paths' -l app -d "Comma seperated list of applications to return paths for."
+complete -f -c 'rebar3' -n '__fish_rebar3_needs_command paths' -l base -d "Return the `base' path of the current profile."
+complete -f -c 'rebar3' -n '__fish_rebar3_needs_command paths' -l bin -d Return the `bin' path of the current profile."
+complete -f -c 'rebar3' -n '__fish_rebar3_needs_command paths' -l ebin -d "Return all `ebin' paths of the current profile's applications."
+complete -f -c 'rebar3' -n '__fish_rebar3_needs_command paths' -l lib -d "Return the `lib' path of the current profile."
+complete -f -c 'rebar3' -n '__fish_rebar3_needs_command paths' -l priv -d "Return the `priv' path of the current profile's applications."
+complete -f -c 'rebar3' -n '__fish_rebar3_needs_command paths' -s s -l separator -d "In case of multiple return paths, the separator character to use to join them."
+complete -f -c 'rebar3' -n '__fish_rebar3_needs_command paths' -l src -d "Return the `src' path of the current profile's applications."
+complete -f -c 'rebar3' -n '__fish_rebar3_needs_command paths' -l rel -d "Return the `rel' path of the current profile."
+
complete -f -c 'rebar3' -n '__fish_rebar3_needs_command' -a pkgs -d "List available packages."
complete -f -c 'rebar3' -n '__fish_rebar3_needs_command' -a release -d "Build release of project."
complete -f -c 'rebar3' -n '__fish_rebar3_needs_command' -a relup -d "Create relup of releases."
diff --git a/priv/shell-completion/zsh/_rebar3 b/priv/shell-completion/zsh/_rebar3
index 04575bc..8855bdf 100644
--- a/priv/shell-completion/zsh/_rebar3
+++ b/priv/shell-completion/zsh/_rebar3
@@ -108,6 +108,17 @@ _rebar3 () {
'(-f --force)'{-f,--force}'[ overwrite existing files]' \
&& ret=0
;;
+ (path)
+ _arguments \
+ '(--app)--app[Comma seperated list of applications to return paths for.]:apps' \
+ '(--base)--base[Return the `base' path of the current profile.]' \
+ '(--bin)--bin[Return the `bin' path of the current profile.]' \
+ '(--ebin)--ebin[Return all `ebin' paths of the current profile's applications.]' \
+ '(--lib)--lib[Return the `lib' path of the current profile.]' \
+ '(--priv)--priv[Return the `priv' path of the current profile's applications.]' \
+ '(-s --separator)--separator[In case of multiple return paths, the separator character to use to join them.]' \
+ && ret=0
+ ;;
(pkgs)
_message 'List available packages.' && ret=0
;;
diff --git a/src/rebar.app.src b/src/rebar.app.src
index 6b0f315..655506e 100644
--- a/src/rebar.app.src
+++ b/src/rebar.app.src
@@ -52,6 +52,7 @@
rebar_prv_lock,
rebar_prv_new,
rebar_prv_packages,
+ rebar_prv_path,
rebar_prv_plugins,
rebar_prv_plugins_upgrade,
rebar_prv_release,
diff --git a/src/rebar_prv_path.erl b/src/rebar_prv_path.erl
new file mode 100644
index 0000000..2a59ae4
--- /dev/null
+++ b/src/rebar_prv_path.erl
@@ -0,0 +1,127 @@
+%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+
+-module(rebar_prv_path).
+
+-behaviour(provider).
+
+-export([init/1,
+ do/1,
+ format_error/1]).
+
+-include("rebar.hrl").
+
+-define(PROVIDER, path).
+-define(DEPS, [app_discovery]).
+
+%% ===================================================================
+%% 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, true},
+ {deps, ?DEPS},
+ {example, "rebar3 path"},
+ {short_desc, "Print paths to build dirs in current profile."},
+ {desc, "Print paths to build dirs in current profile."},
+ {opts, eunit_opts(State)}])),
+
+ {ok, State1}.
+
+-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
+do(State) ->
+ {RawOpts, _} = rebar_state:command_parsed_args(State),
+ %% retrieve apps to filter by for other args
+ Apps = filter_apps(RawOpts, State),
+ %% remove apps and separator opts from options
+ Paths = lists:filter(fun({app, _}) -> false; ({separator, _}) -> false; (_) -> true end, RawOpts),
+ %% if no paths requested in opts print the base_dir instead
+ P = case Paths of [] -> [{ebin, true}]; _ -> Paths end,
+ case paths(P, Apps, State, []) of
+ ok -> {ok, State};
+ {error, Error} -> {error, Error}
+ end.
+
+-spec format_error(any()) -> iolist().
+format_error(Reason) ->
+ io_lib:format("~p", [Reason]).
+
+filter_apps(RawOpts, State) ->
+ RawApps = proplists:get_all_values(app, RawOpts),
+ Apps = lists:foldl(fun(String, Acc) -> string:tokens(String, ",") ++ Acc end, [], RawApps),
+ case Apps of
+ [] ->
+ ProjectDeps = project_deps(State),
+ ProjectApps = rebar_state:project_apps(State),
+ lists:map(fun(A) -> binary_to_list(rebar_app_info:name(A)) end, ProjectApps) ++ ProjectDeps;
+ _ -> Apps
+ end.
+
+
+paths([], _, State, Acc) -> print_paths_if_exist(lists:reverse(Acc), State);
+paths([{base, true}|Rest], Apps, State, Acc) ->
+ paths(Rest, Apps, State, [base_dir(State)|Acc]);
+paths([{bin, true}|Rest], Apps, State, Acc) ->
+ paths(Rest, Apps, State, [bin_dir(State)|Acc]);
+paths([{ebin, true}|Rest], Apps, State, Acc) ->
+ paths(Rest, Apps, State, ebin_dirs(Apps, State) ++ Acc);
+paths([{lib, true}|Rest], Apps, State, Acc) ->
+ paths(Rest, Apps, State, [lib_dir(State)|Acc]);
+paths([{priv, true}|Rest], Apps, State, Acc) ->
+ paths(Rest, Apps, State, priv_dirs(Apps, State) ++ Acc);
+paths([{src, true}|Rest], Apps, State, Acc) ->
+ paths(Rest, Apps, State, src_dirs(Apps, State) ++ Acc);
+paths([{rel, true}|Rest], Apps, State, Acc) ->
+ paths(Rest, Apps, State, [rel_dir(State)|Acc]).
+
+base_dir(State) -> io_lib:format("~s", [rebar_dir:base_dir(State)]).
+bin_dir(State) -> io_lib:format("~s/bin", [rebar_dir:base_dir(State)]).
+lib_dir(State) -> io_lib:format("~s/lib", [rebar_dir:base_dir(State)]).
+rel_dir(State) -> io_lib:format("~s/rel", [rebar_dir:base_dir(State)]).
+
+ebin_dirs(Apps, State) ->
+ lists:map(fun(App) -> io_lib:format("~s/lib/~s/ebin", [rebar_dir:base_dir(State), App]) end, Apps).
+priv_dirs(Apps, State) ->
+ lists:map(fun(App) -> io_lib:format("~s/lib/~s/priv", [rebar_dir:base_dir(State), App]) end, Apps).
+src_dirs(Apps, State) ->
+ lists:map(fun(App) -> io_lib:format("~s/lib/~s/src", [rebar_dir:base_dir(State), App]) end, Apps).
+
+print_paths_if_exist(Paths, State) ->
+ {RawOpts, _} = rebar_state:command_parsed_args(State),
+ Sep = proplists:get_value(separator, RawOpts, " "),
+ RealPaths = lists:filter(fun(P) -> ec_file:is_dir(P) end, Paths),
+ io:format("~s", [string:join(RealPaths, Sep)]).
+
+project_deps(State) ->
+ Profiles = rebar_state:current_profiles(State),
+ List = lists:foldl(fun(Profile, Acc) -> rebar_state:get(State, {deps, Profile}, []) ++ Acc end, [], Profiles),
+ Deps = [normalize(Name) || {Name, _} <- List],
+ lists:usort(Deps).
+
+normalize(AppName) when is_list(AppName) -> AppName;
+normalize(AppName) when is_atom(AppName) -> atom_to_list(AppName);
+normalize(AppName) when is_binary(AppName) -> binary_to_list(AppName).
+
+eunit_opts(_State) ->
+ [{app, undefined, "app", string, help(app)},
+ {base, undefined, "base", boolean, help(base)},
+ {bin, undefined, "bin", boolean, help(bin)},
+ {ebin, undefined, "ebin", boolean, help(ebin)},
+ {lib, undefined, "lib", boolean, help(lib)},
+ {priv, undefined, "priv", boolean, help(priv)},
+ {separator, $s, "separator", string, help(separator)},
+ {src, undefined, "src", boolean, help(src)},
+ {rel, undefined, "rel", boolean, help(rel)}].
+
+help(app) -> "Comma seperated list of applications to return paths for.";
+help(base) -> "Return the `base' path of the current profile.";
+help(bin) -> "Return the `bin' path of the current profile.";
+help(ebin) -> "Return all `ebin' paths of the current profile's applications.";
+help(lib) -> "Return the `lib' path of the current profile.";
+help(priv) -> "Return the `priv' path of the current profile's applications.";
+help(separator) -> "In case of multiple return paths, the separator character to use to join them.";
+help(src) -> "Return the `src' path of the current profile's applications.";
+help(rel) -> "Return the `rel' path of the current profile.". \ No newline at end of file