Packages
rebar3_hex
6.8.0
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_docs.erl
-module(rebar3_hex_docs).
-export([init/1,
do/1,
format_error/1]).
-include("rebar3_hex.hrl").
-define(PROVIDER, docs).
-define(DEPS, [{default, edoc}]).
-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 docs"},
{short_desc, "Publish documentation for the current project and version"},
{desc, ""},
{opts, [{revert, undefined, "revert", string, "Revert given version."},
rebar3_hex_utils:repo_opt()]},
{profiles, [docs]}]),
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_utils:repo(State) of
{ok, Repo} ->
handle_command(State, Repo),
{ok, State};
{error, Reason} ->
?PRV_ERROR(Reason)
end.
handle_command(State, Repo) ->
Apps = rebar3_hex_utils:select_apps(rebar_state:project_apps(State)),
case maps:get(write_key, Repo, undefined) of
undefined ->
?PRV_ERROR(no_write_key);
_ ->
lists:foldl(fun(App, {ok, StateAcc}) ->
do_(App, StateAcc)
end, {ok, State}, Apps),
{ok, State}
end.
-spec format_error(any()) -> iolist().
format_error({publish, Status, Package, Version}) when is_integer(Status) ->
io_lib:format("Error publishing docs for package ~ts ~ts: ~ts",
[Package, Version, rebar3_hex_utils:pretty_print_status(Status)]);
format_error({publish, Package, Version, Reason}) ->
io_lib:format("Error publishing docs for package ~ts ~ts: ~p", [Package, Version, Reason]);
format_error({revert, Status, Package, Version}) when is_integer(Status) ->
io_lib:format("Error deleting docs for package ~ts ~ts: ~ts",
[Package, Version, rebar3_hex_utils:pretty_print_status(Status)]);
format_error({revert, Package, Version, Reason}) ->
io_lib:format("Error deleting docs for package ~ts ~ts: ~p", [Package, Version, Reason]).
do_(App, State) ->
AppDir = rebar_app_info:dir(App),
Files = rebar3_hex_utils:expand_paths(["doc"], AppDir),
AppDetails = rebar_app_info:app_details(App),
Name = binary_to_list(rebar_app_info:name(App)),
PkgName = ec_cnv:to_list(proplists:get_value(pkg_name, AppDetails, Name)),
{Args, _} = rebar_state:command_parsed_args(State),
Revert = proplists:get_value(revert, Args, undefined),
{ok, Repo} = rebar3_hex_utils:repo(State),
case Revert of
undefined ->
Vsn = rebar_app_info:original_vsn(App),
Tarball = PkgName++"-"++Vsn++"-docs.tar.gz",
ok = erl_tar:create(Tarball, file_list(Files), [compressed]),
{ok, Tar} = file:read_file(Tarball),
file:delete(Tarball),
case hex_api_publish_docs(Repo, rebar_utils:to_binary(PkgName), rebar_utils:to_binary(Vsn), Tar) of
{ok, {201, _Headers, _Body}} ->
rebar_api:info("Published docs for ~ts ~ts", [PkgName, Vsn]),
{ok, State};
{ok, {Status, _Headers, _Body}} ->
?PRV_ERROR({publish, Status, PkgName, Vsn});
{error, Reason} ->
?PRV_ERROR({publish, PkgName, Vsn, Reason})
end;
Vsn ->
case hex_api_delete_docs(Repo, rebar_utils:to_binary(PkgName), rebar_utils:to_binary(Vsn)) of
{ok, {204, _Headers, _Body}} ->
rebar_api:info("Successfully deleted docs for ~ts ~ts", [Name, Vsn]),
{ok, State};
{ok, {Status, _Headers, _Body}} ->
?PRV_ERROR({revert, Status, PkgName, Vsn});
{error, Reason} ->
?PRV_ERROR({revert, PkgName, Vsn, Reason})
end
end.
hex_api_publish_docs(Repo, Name, Version, Tarball) ->
{ok, Config} = rebar3_hex_utils:hex_config_write(Repo),
TarballContentType = "application/octet-stream",
Headers = maps:get(http_headers, Config, #{}),
Headers1 = maps:put(<<"content-length">>, integer_to_binary(byte_size(Tarball)), Headers),
Config2 = maps:put(http_headers, Headers1, Config),
Body = {TarballContentType, Tarball},
hex_api:post(Config2, ["packages", Name, "releases", Version, "docs"], Body).
hex_api_delete_docs(Config, Name, Version) ->
hex_api:delete(Config, ["packages", Name, "releases", Version, "docs"]).
file_list(Files) ->
[{drop_path(ShortName, ["doc"]), FullName} || {ShortName, FullName} <- Files].
drop_path(File, Path) ->
filename:join(filename:split(File) -- Path).