From 56b7d88975aa8da6446857cfd92de0825024bf63 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Thu, 13 Sep 2018 19:36:00 -0600 Subject: support for hex v2, multiple repository fetching, private organizations (#1884) * update to hex_core for hex-v2 repo support (#1865) * update to hex_core for hex-v2 repo support This patch adds only single repo hex-v2 support through hex_core. Packages no longer filtered out by buildtool metadata and the package index is updated per-package instead of fetched as one large ets dump. * tell travis to also build hex_core branch * support list of repos for hex packages (#1866) * support list of repos for hex packages repos are defined under the hex key in rebar configs. They can be defined at the top level of a project or globally, but not in profiles and the repos configured in dependencies are also ignored. Searching for packages involves first checking for a match in the local repo index cache, in the order repos are defined. If not found each repo is checked through the hex api for any known versions of the package and the first repo with a version that fits the constraint is used. * add {repos, replace, []} for overriding the global & default repos * add hex auth handling for repos (#1874) auth token are kept in a hex.config file that is modified by the rebar3 hex plugin. Repo names that have a : separating a parent and child are considered organizations. The parent repo's auth will be included with the child. So an organization named hexpm:rebar3_test will include any hexpm auth tokens found in the rebar3_test organization's configuration. * move packages to top level of of hexpm cache dir (#1876) * move packages to top level of of hexpm cache dir * append organization name to parent's repo_url when parsing repos * only eval config scripts and apply overrides once per app (#1879) * only eval config scripts and apply overrides once per app * move new resource behaviour to rebar_resource_v2 and keep v1 * cleanup use of rebar_resource module and unused functions * cleanup error messages and unused code * when discovering apps support mix packages as unbuilt apps (#1882) * use hex_core tarball unpacking support in pkg resource (#1883) * use hex_core tarball unpacking support in pkg resource * ignore etag if package doesn't exist and delete if checksum fails * add back tests for bad package checksums * improve bad registry checksum error message --- src/rebar_app_info.erl | 70 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 28 deletions(-) (limited to 'src/rebar_app_info.erl') diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl index 88d6335..56ae4c0 100644 --- a/src/rebar_app_info.erl +++ b/src/rebar_app_info.erl @@ -7,6 +7,7 @@ new/4, new/5, update_opts/3, + update_opts_deps/2, discover/1, name/1, name/2, @@ -43,8 +44,6 @@ get/2, get/3, set/3, - resource_type/1, - resource_type/2, source/1, source/2, is_lock/1, @@ -53,6 +52,8 @@ is_checkout/2, valid/1, valid/2, + is_available/1, + is_available/2, verify_otp_vsn/1, has_all_artifacts/1, @@ -72,7 +73,7 @@ app_file_src :: file:filename_all() | undefined, app_file_src_script:: file:filename_all() | undefined, app_file :: file:filename_all() | undefined, - original_vsn :: binary() | string() | undefined, + original_vsn :: binary() | undefined, parent=root :: binary() | root, app_details=[] :: list(), applications=[] :: list(), @@ -83,11 +84,11 @@ dep_level=0 :: integer(), dir :: file:name(), out_dir :: file:name(), - resource_type :: pkg | src | undefined, source :: string() | tuple() | checkout | undefined, is_lock=false :: boolean(), is_checkout=false :: boolean(), - valid :: boolean() | undefined}). + valid :: boolean() | undefined, + is_available=false :: boolean()}). %%============================================================================ %% types @@ -114,14 +115,14 @@ new(AppName) -> {ok, t()}. new(AppName, Vsn) -> {ok, #app_info_t{name=rebar_utils:to_binary(AppName), - original_vsn=Vsn}}. + original_vsn=rebar_utils:to_binary(Vsn)}}. %% @doc build a complete version of the app info with all fields set. -spec new(atom() | binary() | string(), binary() | string(), file:name()) -> {ok, t()}. new(AppName, Vsn, Dir) -> {ok, #app_info_t{name=rebar_utils:to_binary(AppName), - original_vsn=Vsn, + original_vsn=rebar_utils:to_binary(Vsn), dir=rebar_utils:to_list(Dir), out_dir=rebar_utils:to_list(Dir)}}. @@ -130,7 +131,7 @@ new(AppName, Vsn, Dir) -> {ok, t()}. new(AppName, Vsn, Dir, Deps) -> {ok, #app_info_t{name=rebar_utils:to_binary(AppName), - original_vsn=Vsn, + original_vsn=rebar_utils:to_binary(Vsn), dir=rebar_utils:to_list(Dir), out_dir=rebar_utils:to_list(Dir), deps=Deps}}. @@ -141,7 +142,7 @@ new(AppName, Vsn, Dir, Deps) -> new(Parent, AppName, Vsn, Dir, Deps) -> {ok, #app_info_t{name=rebar_utils:to_binary(AppName), parent=Parent, - original_vsn=Vsn, + original_vsn=rebar_utils:to_binary(Vsn), dir=rebar_utils:to_list(Dir), out_dir=rebar_utils:to_list(Dir), deps=Deps}}. @@ -150,10 +151,12 @@ new(Parent, AppName, Vsn, Dir, Deps) -> %% file for the app -spec update_opts(t(), rebar_dict(), [any()]) -> t(). update_opts(AppInfo, Opts, Config) -> - LockDeps = case resource_type(AppInfo) of - pkg -> - Deps = deps(AppInfo), - [{{locks, default}, Deps}, {{deps, default}, Deps}]; + LockDeps = case source(AppInfo) of + Tuple when is_tuple(Tuple) andalso element(1, Tuple) =:= pkg -> + %% Deps are set separate for packages + %% instead of making it seem we have no deps + %% don't set anything here. + []; _ -> deps_from_config(dir(AppInfo), Config) end, @@ -165,8 +168,18 @@ update_opts(AppInfo, Opts, Config) -> NewOpts = rebar_opts:merge_opts(LocalOpts, Opts), - AppInfo#app_info_t{opts=NewOpts - ,default=NewOpts}. + AppInfo#app_info_t{opts=NewOpts, + default=NewOpts}. + +%% @doc update the opts based on new deps, usually from an app's hex registry metadata +-spec update_opts_deps(t(), [any()]) -> t(). +update_opts_deps(AppInfo=#app_info_t{opts=Opts}, Deps) -> + LocalOpts = dict:from_list([{{locks, default}, Deps}, {{deps, default}, Deps}]), + NewOpts = rebar_opts:merge_opts(LocalOpts, Opts), + AppInfo#app_info_t{opts=NewOpts, + default=NewOpts, + deps=Deps}. + %% @private extract the deps for an app in `Dir' based on its config file data -spec deps_from_config(file:filename(), [any()]) -> [{tuple(), any()}, ...]. @@ -350,15 +363,15 @@ parent(AppInfo=#app_info_t{}, Parent) -> %% @doc returns the original version of the app (unevaluated if %% asking for a semver) --spec original_vsn(t()) -> string(). +-spec original_vsn(t()) -> binary(). original_vsn(#app_info_t{original_vsn=Vsn}) -> Vsn. %% @doc stores the original version of the app (unevaluated if %% asking for a semver) --spec original_vsn(t(), string()) -> t(). +-spec original_vsn(t(), binary() | string()) -> t(). original_vsn(AppInfo=#app_info_t{}, Vsn) -> - AppInfo#app_info_t{original_vsn=Vsn}. + AppInfo#app_info_t{original_vsn=rebar_utils:to_binary(Vsn)}. %% @doc returns the list of applications the app depends on. -spec applications(t()) -> list(). @@ -438,16 +451,6 @@ ebin_dir(#app_info_t{out_dir=OutDir}) -> priv_dir(#app_info_t{out_dir=OutDir}) -> rebar_utils:to_list(filename:join(OutDir, "priv")). -%% @doc returns whether the app is source app or a package app. --spec resource_type(t()) -> pkg | src. -resource_type(#app_info_t{resource_type=ResourceType}) -> - ResourceType. - -%% @doc sets whether the app is source app or a package app. --spec resource_type(t(), pkg | src) -> t(). -resource_type(AppInfo=#app_info_t{}, Type) -> - AppInfo#app_info_t{resource_type=Type}. - %% @doc finds the source specification for the app -spec source(t()) -> string() | tuple(). source(#app_info_t{source=Source}) -> @@ -478,6 +481,17 @@ is_checkout(#app_info_t{is_checkout=IsCheckout}) -> is_checkout(AppInfo=#app_info_t{}, IsCheckout) -> AppInfo#app_info_t{is_checkout=IsCheckout}. +%% @doc returns whether the app source exists in the deps dir +-spec is_available(t()) -> boolean(). +is_available(#app_info_t{is_available=IsAvailable}) -> + IsAvailable. + +%% @doc sets whether the app's source is available +%% only set if the app's source is found in the expected dep directory +-spec is_available(t(), boolean()) -> t(). +is_available(AppInfo=#app_info_t{}, IsAvailable) -> + AppInfo#app_info_t{is_available=IsAvailable}. + %% @doc returns whether the app is valid (built) or not -spec valid(t()) -> boolean(). valid(AppInfo=#app_info_t{valid=undefined}) -> -- cgit v1.1 From 2dfba204e4dea5d1c3821fd26d22bd7201595f6c Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 21 Sep 2018 10:32:57 -0600 Subject: properly support top level app erl_opts from REBAR_CONFIG os var (#1889) When REBAR_CONFIG was set it would not effect the top level app's configuration because app_discover was rereading the top level rebar.config which ignored REBAR_CONFIG. Instead this patch has it use the existing configuration from REBAR_CONFIG. --- src/rebar_app_info.erl | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/rebar_app_info.erl') diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl index 56ae4c0..eb95311 100644 --- a/src/rebar_app_info.erl +++ b/src/rebar_app_info.erl @@ -7,6 +7,7 @@ new/4, new/5, update_opts/3, + update_opts/2, update_opts_deps/2, discover/1, name/1, @@ -158,7 +159,7 @@ update_opts(AppInfo, Opts, Config) -> %% don't set anything here. []; _ -> - deps_from_config(dir(AppInfo), Config) + deps_from_config(dir(AppInfo), proplists:get_value(deps, Config, [])) end, Plugins = proplists:get_value(plugins, Config, []), @@ -171,6 +172,13 @@ update_opts(AppInfo, Opts, Config) -> AppInfo#app_info_t{opts=NewOpts, default=NewOpts}. +%% @doc update current app info opts by merging in a new dict of opts +-spec update_opts(t(), rebar_dict()) -> t(). +update_opts(AppInfo=#app_info_t{opts=LocalOpts}, Opts) -> + NewOpts = rebar_opts:merge_opts(LocalOpts, Opts), + AppInfo#app_info_t{opts=NewOpts, + default=NewOpts}. + %% @doc update the opts based on new deps, usually from an app's hex registry metadata -spec update_opts_deps(t(), [any()]) -> t(). update_opts_deps(AppInfo=#app_info_t{opts=Opts}, Deps) -> @@ -183,10 +191,10 @@ update_opts_deps(AppInfo=#app_info_t{opts=Opts}, Deps) -> %% @private extract the deps for an app in `Dir' based on its config file data -spec deps_from_config(file:filename(), [any()]) -> [{tuple(), any()}, ...]. -deps_from_config(Dir, Config) -> +deps_from_config(Dir, ConfigDeps) -> case rebar_config:consult_lock_file(filename:join(Dir, ?LOCK_FILE)) of [] -> - [{{deps, default}, proplists:get_value(deps, Config, [])}]; + [{{deps, default}, ConfigDeps}]; D -> %% We want the top level deps only from the lock file. %% This ensures deterministic overrides for configs. -- cgit v1.1 From dec484643c233fda9c17d38c1854ba7f3f37547b Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Fri, 5 Oct 2018 08:29:07 -0600 Subject: compiler behaviour (#1893) * add compile type for dynamic project compilation * new rebar_compiler abstraction for running multiple compilers rebar_compiler is a new behaviour that a plugin can implement to be called on any ues of the compile provider to compile source files and keep track of their dependencies. * fix check that modules in .app modules list are from src_dirs * use project_type to find module for building projects * allow plugins to add project builders and compilers --- src/rebar_app_info.erl | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) (limited to 'src/rebar_app_info.erl') diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl index eb95311..b1c6243 100644 --- a/src/rebar_app_info.erl +++ b/src/rebar_app_info.erl @@ -24,7 +24,6 @@ parent/2, original_vsn/1, original_vsn/2, - ebin_dir/1, priv_dir/1, applications/1, applications/2, @@ -38,6 +37,8 @@ dir/2, out_dir/1, out_dir/2, + ebin_dir/1, + ebin_dir/2, default/1, default/2, opts/1, @@ -47,6 +48,8 @@ set/3, source/1, source/2, + project_type/1, + project_type/2, is_lock/1, is_lock/2, is_checkout/1, @@ -68,7 +71,10 @@ -include("rebar.hrl"). -include_lib("providers/include/providers.hrl"). --export_type([t/0]). +-export_type([t/0, + project_type/0]). + +-type project_type() :: rebar3 | mix | undefined. -record(app_info_t, {name :: binary() | undefined, app_file_src :: file:filename_all() | undefined, @@ -85,10 +91,12 @@ dep_level=0 :: integer(), dir :: file:name(), out_dir :: file:name(), + ebin_dir :: file:name(), source :: string() | tuple() | checkout | undefined, is_lock=false :: boolean(), is_checkout=false :: boolean(), valid :: boolean() | undefined, + project_type :: project_type(), is_available=false :: boolean()}). %%============================================================================ @@ -125,7 +133,8 @@ new(AppName, Vsn, Dir) -> {ok, #app_info_t{name=rebar_utils:to_binary(AppName), original_vsn=rebar_utils:to_binary(Vsn), dir=rebar_utils:to_list(Dir), - out_dir=rebar_utils:to_list(Dir)}}. + out_dir=rebar_utils:to_list(Dir), + ebin_dir=filename:join(rebar_utils:to_list(Dir), "ebin")}}. %% @doc build a complete version of the app info with all fields set. -spec new(atom() | binary() | string(), binary() | string(), file:name(), list()) -> @@ -135,6 +144,7 @@ new(AppName, Vsn, Dir, Deps) -> original_vsn=rebar_utils:to_binary(Vsn), dir=rebar_utils:to_list(Dir), out_dir=rebar_utils:to_list(Dir), + ebin_dir=filename:join(rebar_utils:to_list(Dir), "ebin"), deps=Deps}}. %% @doc build a complete version of the app info with all fields set. @@ -146,6 +156,7 @@ new(Parent, AppName, Vsn, Dir, Deps) -> original_vsn=rebar_utils:to_binary(Vsn), dir=rebar_utils:to_list(Dir), out_dir=rebar_utils:to_list(Dir), + ebin_dir=filename:join(rebar_utils:to_list(Dir), "ebin"), deps=Deps}}. %% @doc update the opts based on the contents of a config @@ -447,12 +458,21 @@ out_dir(#app_info_t{out_dir=OutDir}) -> %% should go -spec out_dir(t(), file:name()) -> t(). out_dir(AppInfo=#app_info_t{}, OutDir) -> - AppInfo#app_info_t{out_dir=rebar_utils:to_list(OutDir)}. + AppInfo#app_info_t{out_dir=rebar_utils:to_list(OutDir), + ebin_dir=filename:join(rebar_utils:to_list(OutDir), "ebin")}. %% @doc gets the directory where ebin files for the app should go -spec ebin_dir(t()) -> file:name(). -ebin_dir(#app_info_t{out_dir=OutDir}) -> - rebar_utils:to_list(filename:join(OutDir, "ebin")). +ebin_dir(#app_info_t{ebin_dir=undefined, + out_dir=OutDir}) -> + filename:join(rebar_utils:to_list(OutDir), "ebin"); +ebin_dir(#app_info_t{ebin_dir=EbinDir}) -> + EbinDir. + +%% @doc sets the directory where beam files should go +-spec ebin_dir(t(), file:name()) -> t(). +ebin_dir(AppInfo, EbinDir) -> + AppInfo#app_info_t{ebin_dir=EbinDir}. %% @doc gets the directory where private files for the app should go -spec priv_dir(t()) -> file:name(). @@ -500,6 +520,17 @@ is_available(#app_info_t{is_available=IsAvailable}) -> is_available(AppInfo=#app_info_t{}, IsAvailable) -> AppInfo#app_info_t{is_available=IsAvailable}. +%% @doc +-spec project_type(t()) -> atom(). +project_type(#app_info_t{project_type=ProjectType}) -> + ProjectType. + +%% @doc +-spec project_type(t(), atom()) -> t(). +project_type(AppInfo=#app_info_t{}, ProjectType) -> + AppInfo#app_info_t{project_type=ProjectType}. + + %% @doc returns whether the app is valid (built) or not -spec valid(t()) -> boolean(). valid(AppInfo=#app_info_t{valid=undefined}) -> -- cgit v1.1 From 86519cf743204eab1d922ca8133fbf00c66f9ee8 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sun, 14 Oct 2018 10:50:16 -0600 Subject: fix resolving versions from vcs (#1915) app_info was turning any vsn into a binary which the vcs_vsn function interprets as being an actual version and not something like <<"git">>. original_vsn shouldn't be converted as it is then not longer "original". --- src/rebar_app_info.erl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/rebar_app_info.erl') diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl index b1c6243..9dfe278 100644 --- a/src/rebar_app_info.erl +++ b/src/rebar_app_info.erl @@ -124,14 +124,14 @@ new(AppName) -> {ok, t()}. new(AppName, Vsn) -> {ok, #app_info_t{name=rebar_utils:to_binary(AppName), - original_vsn=rebar_utils:to_binary(Vsn)}}. + original_vsn=Vsn}}. %% @doc build a complete version of the app info with all fields set. -spec new(atom() | binary() | string(), binary() | string(), file:name()) -> {ok, t()}. new(AppName, Vsn, Dir) -> {ok, #app_info_t{name=rebar_utils:to_binary(AppName), - original_vsn=rebar_utils:to_binary(Vsn), + original_vsn=Vsn, dir=rebar_utils:to_list(Dir), out_dir=rebar_utils:to_list(Dir), ebin_dir=filename:join(rebar_utils:to_list(Dir), "ebin")}}. @@ -141,7 +141,7 @@ new(AppName, Vsn, Dir) -> {ok, t()}. new(AppName, Vsn, Dir, Deps) -> {ok, #app_info_t{name=rebar_utils:to_binary(AppName), - original_vsn=rebar_utils:to_binary(Vsn), + original_vsn=Vsn, dir=rebar_utils:to_list(Dir), out_dir=rebar_utils:to_list(Dir), ebin_dir=filename:join(rebar_utils:to_list(Dir), "ebin"), @@ -153,7 +153,7 @@ new(AppName, Vsn, Dir, Deps) -> new(Parent, AppName, Vsn, Dir, Deps) -> {ok, #app_info_t{name=rebar_utils:to_binary(AppName), parent=Parent, - original_vsn=rebar_utils:to_binary(Vsn), + original_vsn=Vsn, dir=rebar_utils:to_list(Dir), out_dir=rebar_utils:to_list(Dir), ebin_dir=filename:join(rebar_utils:to_list(Dir), "ebin"), @@ -390,7 +390,7 @@ original_vsn(#app_info_t{original_vsn=Vsn}) -> %% asking for a semver) -spec original_vsn(t(), binary() | string()) -> t(). original_vsn(AppInfo=#app_info_t{}, Vsn) -> - AppInfo#app_info_t{original_vsn=rebar_utils:to_binary(Vsn)}. + AppInfo#app_info_t{original_vsn=Vsn}. %% @doc returns the list of applications the app depends on. -spec applications(t()) -> list(). -- cgit v1.1