Skip to content

Commit

Permalink
Current state
Browse files Browse the repository at this point in the history
  • Loading branch information
filmor committed Oct 4, 2023
1 parent 4423ece commit c319c8d
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 32 deletions.
10 changes: 5 additions & 5 deletions apps/rebar/src/rebar_packages.erl
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ get_all_names(State) ->
ets:tid(), rebar_state:t()) -> [vsn()].
get_package_versions(Dep, DepVsn, Repo, Table, State) ->
AllowPreRelease = rebar_state:get(State, deps_allow_prerelease, false),
#{matchspec := [{Head, [Match], _}]} = rebar_verl:parse_requirement(DepVsn),
{Head, Match} = rebar_verl:parse_req_as_matchspec(DepVsn),

?MODULE:verify_table(State),
Vsns = ets:select(Table, [{#package{key={Dep, Head, Repo}, _='_'},
[Match], [{Head}]}]),
[Match], [#{major => '$1', minor => '$2', patch => '$3', pre => '$4', build => '$5'}]}]),
handle_vsns(Vsns, AllowPreRelease).

-spec get_package(unicode:unicode_binary(), unicode:unicode_binary(),
Expand All @@ -77,7 +77,7 @@ get_package(Dep, Vsn, Hash, Repos, Table, State) ->
MatchSpec =
case is_binary(Vsn) of
true ->
#{matchspec := [{Head, [Match], _}]} = rebar_verl:parse_requirement(Vsn),
{Head, Match} = rebar_verl:parse_req_as_matchspec(Vsn),
[{#package{key={Dep, Head, Repo}, _='_'}, [Match], ['$_']} || Repo <- Repos];
false ->
[{#package{key={Dep, Vsn, Repo}, _='_'}, [], ['$_']} || Repo <- Repos]
Expand All @@ -102,7 +102,7 @@ get_package(Dep, Vsn, Hash, Repos, Table, State) ->
PackagesWithProperHash;
false ->
lists:filter(
fun(#package{key = {_, {_, _, _, Pre, _}, _}}) ->
fun(#package{key = {_, {{_, _, _}, {Pre, _}}, _}}) ->
Pre =:= []
end,
PackagesWithProperHash
Expand Down Expand Up @@ -226,7 +226,7 @@ handle_vsns(Vsns, AllowPreRelease) ->
Vsn =
lists:foldl(
fun(Version, Highest) when AllowPreRelease orelse length(element(4, Version)) =:= 0 ->
case (Highest =:= none orelse verl:compare(Version, Highest) =:= gt) of
case (Highest =:= none orelse rebar_verl:compare(Version, Highest) =:= gt) of
true ->
Version;
false ->
Expand Down
39 changes: 32 additions & 7 deletions apps/rebar/src/rebar_verl.erl
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@

-export([
parse_requirement/1,
parse_req_as_matchspec/1,
valid_requirement/1,
parse_as_matchable/1,
compare/2,
format_version/1
]).

-type version() :: ec_semver:semver().

-export_type([
version/0
]).

parse_requirement(Vsn) ->
Vsn1 =
case verl:parse(Vsn) of
Expand All @@ -25,6 +33,10 @@ parse_requirement(Vsn) ->
error({Error, Vsn1})
end.

parse_req_as_matchspec(Req) ->
#{matchspec := [{_Head, [Match], _}]} = parse_requirement(Req),
{{{'$1', '$2', '$3'}, {'$4', '$5'}}, Match}.

valid_requirement(Vsn) ->
case verl:parse(Vsn) of
{ok, _} ->
Expand All @@ -42,17 +54,30 @@ parse_as_matchable(Vsn) when is_list(Vsn) ->
parse_as_matchable(list_to_binary(Vsn));
parse_as_matchable(Vsn) ->
case verl:parse(Vsn) of
{ok, Res} ->
verl:to_matchable(Res, true);
{ok, VerlVsn} ->
to_matchable(VerlVsn);
{error, Error} ->
error({Error, Vsn})
end.

format_version(Binary) when is_binary(Binary) ->
Binary;
format_version({Major, Minor, Patch, Pre, _}) ->
format_version(#{major => Major, minor => Minor, patch => Patch, pre => Pre, build => undefined});
format_version(#{major := Major, minor := Minor, patch := Patch, pre := Pre, build := Build}) ->
to_matchable(#{major := Major, minor := Minor, patch := Patch, pre := Pre, build := _Build}) ->
{{Major, Minor, Patch}, {Pre, true}}.

to_verl_vsn(Bin) when is_binary(Bin) ->
{ok, Vsn} = verl:parse(Bin),
Vsn;
to_verl_vsn({{Major, Minor, Patch}, {Pre, Build}}) ->
#{major => Major, minor => Minor, patch => Patch, pre => Pre, build => Build};
to_verl_vsn(Map) when is_map(Map) ->
Map.

compare(V1, V2) ->
verl:compare(to_verl_vsn(V1), to_verl_vsn(V2)).

format_version(Vsn) ->
#{major := Major, minor := Minor, patch := Patch, pre := Pre, build := Build} =
to_verl_vsn(Vsn),

Base = io_lib:format("~p.~p.~p", [Major, Minor, Patch]),
WithPre = case Pre of
[] ->
Expand Down
8 changes: 4 additions & 4 deletions apps/rebar/test/rebar_pkg_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,13 @@ find_highest_matching(_Config) ->
State = rebar_state:new(),
{ok, Vsn} = rebar_packages:find_highest_matching_(
<<"goodpkg">>, <<"~> 1.0.0">>, #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State),
?assertMatch({1,0,1,[],_}, Vsn),
?assertMatch({{1,0,1},{[],_}}, Vsn),
{ok, Vsn1} = rebar_packages:find_highest_matching(
<<"goodpkg">>, <<"~> 1.0">>, #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State),
?assertMatch({1,1,1,[],_}, Vsn1),
?assertMatch({{1,1,1},{[],_}}, Vsn1),
{ok, Vsn2} = rebar_packages:find_highest_matching(
<<"goodpkg">>, <<"~> 2.0">>, #{name => <<"hexpm">>}, ?PACKAGE_TABLE, State),
?assertMatch({2,0,0,[],_}, Vsn2),
?assertMatch({{2,0,0},{[],_}}, Vsn2),

%% regression test. ~> constraints higher than the available packages would result
%% in returning the first package version instead of 'none'.
Expand All @@ -248,7 +248,7 @@ find_highest_matching(_Config) ->

{ok, Vsn3} = rebar_packages:find_highest_matching_(<<"goodpkg">>, <<"== 3.0.0-rc.0">>,
#{name => <<"hexpm">>}, ?PACKAGE_TABLE, State),
?assertMatch({3,0,0,[<<"rc">>,0],_}, Vsn3).
?assertMatch({{3,0,0},{[<<"rc">>,0],_}}, Vsn3).

%%%%%%%%%%%%%%%
%%% Helpers %%%
Expand Down
32 changes: 16 additions & 16 deletions apps/rebar/test/rebar_pkg_repos_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -379,14 +379,14 @@ organization_merging(_Config) ->
use_first_repo_match(Config) ->
State = ?config(state, Config),

?assertMatch({ok,{package,{<<"B">>, {2,0,0,[],_}, Repo2},
?assertMatch({ok,{package,{<<"B">>, {{2,0,0}, {[],[]}}, Repo2},
<<"inner checksum">>,<<"outer checksum">>, false, []},
#{name := Repo2,
http_adapter := {rebar_httpc_adapter, #{profile := rebar}}}},
rebar_packages:resolve_version(<<"B">>, <<"> 1.4.0">>, undefined, undefined,
?PACKAGE_TABLE, State)),

?assertMatch({ok,{package,{<<"B">>, {1,4,0,[],_}, Repo3},
?assertMatch({ok,{package,{<<"B">>, {{1,4,0}, {[],[]}}, Repo3},
<<"inner checksum">>,<<"outer checksum">>, false, []},
#{name := Repo3,
http_adapter := {rebar_httpc_adapter, #{profile := rebar}}}},
Expand All @@ -397,7 +397,7 @@ use_first_repo_match(Config) ->
use_exact_with_hash(Config) ->
State = ?config(state, Config),

?assertMatch({ok,{package,{<<"C">>, {1,3,1,[],_}, Repo2},
?assertMatch({ok,{package,{<<"C">>, {{1,3,1}, {[],[]}}, Repo2},
<<"inner checksum">>, <<"good outer checksum">>, false, []},
#{name := Repo2,
http_adapter := {rebar_httpc_adapter, #{profile := rebar}}}},
Expand All @@ -407,7 +407,7 @@ use_exact_with_hash(Config) ->
fail_repo_update(Config) ->
State = ?config(state, Config),

?assertMatch({ok,{package,{<<"B">>, {1,4,0,[],_}, Repo3},
?assertMatch({ok,{package,{<<"B">>, {{1,4,0}, {[],[]}}, Repo3},
<<"inner checksum">>,<<"outer checksum">>, false, []},
#{name := Repo3,
http_adapter := {rebar_httpc_adapter, #{profile := rebar}}}},
Expand All @@ -418,15 +418,15 @@ ignore_match_in_excluded_repo(Config) ->
State = ?config(state, Config),
Repos = ?config(repos, Config),

?assertMatch({ok,{package,{<<"B">>, {1,4,6,[],_}, Hexpm},
?assertMatch({ok,{package,{<<"B">>, {{1,4,6}, {[],[]}}, Hexpm},
<<"inner checksum">>,<<"outer checksum">>, #{reason := 'RETIRED_INVALID'}, []},
#{name := Hexpm,
http_adapter := {rebar_httpc_adapter, #{profile := rebar}}}},
rebar_packages:resolve_version(<<"B">>, <<"~> 1.4.0">>, undefined, undefined,
?PACKAGE_TABLE, State)),

[_, Repo2 | _] = Repos,
?assertMatch({ok,{package,{<<"A">>, {0,1,1,[],_}, Repo2},
?assertMatch({ok,{package,{<<"A">>, {{0,1,1}, {[],[]}}, Repo2},
<<"inner checksum">>, <<"good outer checksum">>, false, []},
#{name := Repo2,
http_adapter := {rebar_httpc_adapter, #{profile := rebar}}}},
Expand All @@ -436,23 +436,23 @@ ignore_match_in_excluded_repo(Config) ->
optional_prereleases(Config) ->
State = ?config(state, Config),

?assertMatch({ok,{package,{<<"B">>, {1,5,0,[],_}, Hexpm},
?assertMatch({ok,{package,{<<"B">>, {{1,5,0}, {[],[]}}, Hexpm},
<<"inner checksum">>,<<"outer checksum">>, false, []},
#{name := Hexpm,
http_adapter := {rebar_httpc_adapter, #{profile := rebar}}}},
rebar_packages:resolve_version(<<"B">>, <<"~> 1.5.0">>, undefined, undefined,
?PACKAGE_TABLE, State)),

% ?assertMatch({ok,{package,{<<"B">>, {1,5,6,[<<"rc">>,0],_}, Hexpm},
% <<"inner checksum">>,<<"outer checksum">>, true, []},
% #{name := Hexpm,
% http_adapter := {rebar_httpc_adapter, #{profile := rebar}}}},
% rebar_packages:resolve_version(<<"B">>, <<"1.5.6-rc.0">>, <<"inner checksum">>, <<"outer checksum">>,
% ?PACKAGE_TABLE, State)),
?assertMatch({ok,{package,{<<"B">>, {{1,5,6}, {[<<"rc">>,0],[]}}, Hexpm},
<<"inner checksum">>,<<"outer checksum">>, true, []},
#{name := Hexpm,
http_adapter := {rebar_httpc_adapter, #{profile := rebar}}}},
rebar_packages:resolve_version(<<"B">>, <<"1.5.6-rc.0">>, <<"inner checksum">>, <<"outer checksum">>,
?PACKAGE_TABLE, State)),

%% allow prerelease through configuration
State1 = rebar_state:set(State, deps_allow_prerelease, true),
?assertMatch({ok,{package,{<<"B">>, {1,5,6,[<<"rc">>,0],_}, Hexpm},
?assertMatch({ok,{package,{<<"B">>, {{1,5,6}, {[<<"rc">>,0],[]}}, Hexpm},
<<"inner checksum">>,<<"outer checksum">>, true, []},
#{name := Hexpm,
http_adapter := {rebar_httpc_adapter, #{profile := rebar}}}},
Expand All @@ -472,15 +472,15 @@ setup_deps_and_repos(Deps, Repos) ->
insert_deps(Deps) ->
lists:foreach(fun({Name, Version, Repo, Retired}) ->
ets:insert(?PACKAGE_TABLE, #package{key={rebar_utils:to_binary(Name),
rebar_verl:parse_as_matchable(Version),
ec_semver:parse(Version),
rebar_utils:to_binary(Repo)},
dependencies=[],
retired=Retired,
inner_checksum = <<"inner checksum">>,
outer_checksum = <<"outer checksum">>});
({Name, Version, InnerChecksum, OuterChecksum, Repo, Retired}) ->
ets:insert(?PACKAGE_TABLE, #package{key={rebar_utils:to_binary(Name),
rebar_verl:parse_as_matchable(Version),
ec_semver:parse(Version),
rebar_utils:to_binary(Repo)},
dependencies=[],
retired=Retired,
Expand Down

0 comments on commit c319c8d

Please sign in to comment.