diff options
-rw-r--r-- | doc/templates.md | 10 | ||||
-rw-r--r-- | priv/templates/Makefile.dtl | 74 | ||||
-rw-r--r-- | priv/templates/cmake.template | 2 | ||||
-rw-r--r-- | src/rebar.hrl | 1 | ||||
-rw-r--r-- | src/rebar3.erl | 5 | ||||
-rw-r--r-- | src/rebar_app_discover.erl | 51 | ||||
-rw-r--r-- | src/rebar_app_info.erl | 2 | ||||
-rw-r--r-- | src/rebar_app_utils.erl | 107 | ||||
-rw-r--r-- | src/rebar_config.erl | 2 | ||||
-rw-r--r-- | src/rebar_dir.erl | 39 | ||||
-rw-r--r-- | src/rebar_erlc_compiler.erl | 8 | ||||
-rw-r--r-- | src/rebar_otp_app.erl | 86 | ||||
-rw-r--r-- | src/rebar_packages.erl | 2 | ||||
-rw-r--r-- | src/rebar_prv_dialyzer.erl | 3 | ||||
-rw-r--r-- | src/rebar_prv_install_deps.erl | 268 | ||||
-rw-r--r-- | src/rebar_prv_update.erl | 2 | ||||
-rw-r--r-- | src/rebar_templater.erl | 24 | ||||
-rw-r--r-- | src/rebar_utils.erl | 21 | ||||
-rw-r--r-- | test/rebar_new_SUITE.erl | 2 | ||||
-rw-r--r-- | test/rebar_upgrade_SUITE.erl | 6 |
20 files changed, 351 insertions, 364 deletions
diff --git a/doc/templates.md b/doc/templates.md index 096cd37..598a689 100644 --- a/doc/templates.md +++ b/doc/templates.md @@ -17,7 +17,7 @@ ## Global Variables -Global variables can be set by editing the file at `$HOME/.rebar3/templates/globals`: +Global variables can be set by editing the file at `$HOME/.config/rebar3/templates/globals`: {variables, [ {author_name, "My Name Is A String"}, @@ -29,7 +29,7 @@ This will let you define variables for all templates. Variables left undefined will be ignored and revert to the default value. -The override order for these variables will be: Defaults < $HOME/.rebar3/templates/globals < command line invocation. +The override order for these variables will be: Defaults < $HOME/.config/rebar3/templates/globals < command line invocation. ## Batteries-Included Templates ## @@ -77,7 +77,7 @@ Then go to the directory created for the project by rebar3. ## Custom Templates ## -Custom templates can be added in `$HOME/.rebar3/templates/`. Each template is at least two files: +Custom templates can be added in `$HOME/.config/rebar3/templates/`. Each template is at least two files: - `my_template.dtl`: There can be many of these files. They are regular Erlang files using the django template syntax for variable replacements. - `my_template.template`; Called the *template index*, there is one per template callable from `rebar3`. This one will be visible when calling `rebar3 new my_template`. This file regroups the different \*.dtl files into a more cohesive template. @@ -112,7 +112,7 @@ Specifically: ### Example ### -As an example, we'll create a template for Common Test test suites. Create the directory structure `~/.rebar/templates/` and then go in there. +As an example, we'll create a template for Common Test test suites. Create the directory structure `~/.config/rebar/templates/` and then go in there. We'll start with an index for our template, called `ct_suite.template`: @@ -173,7 +173,7 @@ Let's look at the details: → ./rebar3 new help ct_suite ct_suite: - custom template (/home/ferd/.rebar3/templates/ct_suite.template) + custom template (/home/ferd/.config/rebar3/templates/ct_suite.template) Description: A basic Common Test suite for an OTP application Variables: name="suite" (Name of the suite, prepended to the standard _SUITE suffix) diff --git a/priv/templates/Makefile.dtl b/priv/templates/Makefile.dtl new file mode 100644 index 0000000..e168f6c --- /dev/null +++ b/priv/templates/Makefile.dtl @@ -0,0 +1,74 @@ +# Based on c_src.mk from erlang.mk by Loic Hoguin <essen@ninenines.eu> + +CURDIR := $(shell pwd) +BASEDIR := $(abspath $(CURDIR)/..) + +PROJECT ?= $(notdir $(BASEDIR)) +PROJECT := $(strip $(PROJECT)) + +ERTS_INCLUDE_DIR ?= $(shell erl -noshell -s init stop -eval "io:format(\"~s/erts-~s/include/\", [code:root_dir(), erlang:system_info(version)]).") +ERL_INTERFACE_INCLUDE_DIR ?= $(shell erl -noshell -s init stop -eval "io:format(\"~s\", [code:lib_dir(erl_interface, include)]).") +ERL_INTERFACE_LIB_DIR ?= $(shell erl -noshell -s init stop -eval "io:format(\"~s\", [code:lib_dir(erl_interface, lib)]).") + +C_SRC_DIR = $(CURDIR) +C_SRC_OUTPUT ?= $(CURDIR)/../priv/$(PROJECT).so + +# System type and C compiler/flags. + +UNAME_SYS := $(shell uname -s) +ifeq ($(UNAME_SYS), Darwin) + CC ?= cc + CFLAGS ?= -O3 -std=c99 -arch x86_64 -finline-functions -Wall -Wmissing-prototypes + CXXFLAGS ?= -O3 -arch x86_64 -finline-functions -Wall + LDFLAGS ?= -arch x86_64 -flat_namespace -undefined suppress +else ifeq ($(UNAME_SYS), FreeBSD) + CC ?= cc + CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes + CXXFLAGS ?= -O3 -finline-functions -Wall +else ifeq ($(UNAME_SYS), Linux) + CC ?= gcc + CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes + CXXFLAGS ?= -O3 -finline-functions -Wall +endif + +CFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR) +CXXFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR) + +LDLIBS += -L $(ERL_INTERFACE_LIB_DIR) -lerl_interface -lei +LDFLAGS += -shared + +# Verbosity. + +c_verbose_0 = @echo " C " $(?F); +c_verbose = $(c_verbose_$(V)) + +cpp_verbose_0 = @echo " CPP " $(?F); +cpp_verbose = $(cpp_verbose_$(V)) + +link_verbose_0 = @echo " LD " $(@F); +link_verbose = $(link_verbose_$(V)) + +SOURCES := $(shell find $(C_SRC_DIR) -type f \( -name "*.c" -o -name "*.C" -o -name "*.cc" -o -name "*.cpp" \)) +OBJECTS = $(addsuffix .o, $(basename $(SOURCES))) + +COMPILE_C = $(c_verbose) $(CC) $(CFLAGS) $(CPPFLAGS) -c +COMPILE_CPP = $(cpp_verbose) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c + +$(C_SRC_OUTPUT): $(OBJECTS) + @mkdir -p $(BASEDIR)/priv/ + $(link_verbose) $(CC) $(OBJECTS) $(LDFLAGS) $(LDLIBS) -o $(C_SRC_OUTPUT) + +%.o: %.c + $(COMPILE_C) $(OUTPUT_OPTION) $< + +%.o: %.cc + $(COMPILE_CPP) $(OUTPUT_OPTION) $< + +%.o: %.C + $(COMPILE_CPP) $(OUTPUT_OPTION) $< + +%.o: %.cpp + $(COMPILE_CPP) $(OUTPUT_OPTION) $< + +clean: + @rm $(C_SRC_OUTPUT) $(OBJECTS) diff --git a/priv/templates/cmake.template b/priv/templates/cmake.template new file mode 100644 index 0000000..b3f23e8 --- /dev/null +++ b/priv/templates/cmake.template @@ -0,0 +1,2 @@ +{description, "Makefile for building C/C++ in c_src"}. +{template, "Makefile.dtl", "c_src/Makefile"}. diff --git a/src/rebar.hrl b/src/rebar.hrl index fdef438..bbd9a2f 100644 --- a/src/rebar.hrl +++ b/src/rebar.hrl @@ -22,7 +22,6 @@ -define(DEFAULT_RELEASE_DIR, "rel"). -define(DEFAULT_CONFIG_FILE, "rebar.config"). -define(LOCK_FILE, "rebar.lock"). --define(CONFIG_DIR, ".rebar3"). -ifdef(namespaced_types). -type rebar_dict() :: dict:dict(). diff --git a/src/rebar3.erl b/src/rebar3.erl index d9024bb..bd52fee 100644 --- a/src/rebar3.erl +++ b/src/rebar3.erl @@ -147,9 +147,8 @@ init_config() -> Config1 = rebar_config:merge_locks(Config, rebar_config:consult_file(?LOCK_FILE)), - %% If $HOME/.rebar3/config exists load and use as global config - Home = rebar_dir:home_dir(), - GlobalConfigFile = filename:join([Home, ?CONFIG_DIR, "config"]), + %% If $HOME/.config/rebar3/config exists load and use as global config + GlobalConfigFile = rebar_dir:global_config(), State = case filelib:is_regular(GlobalConfigFile) of true -> ?DEBUG("Load global config file ~p", diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index df2211e..f6ed91b 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -5,9 +5,7 @@ find_unbuilt_apps/1, find_apps/1, find_apps/2, - find_app/2, - validate_application_info/1, - validate_application_info/2]). + find_app/2]). -include_lib("providers/include/providers.hrl"). @@ -104,14 +102,14 @@ find_app(AppDir, Validate) -> end, case Validate of valid -> - case validate_application_info(AppInfo2) of + case rebar_app_utils:validate_application_info(AppInfo2) of true -> {true, AppInfo2}; _ -> false end; invalid -> - case validate_application_info(AppInfo2) of + case rebar_app_utils:validate_application_info(AppInfo2) of true -> false; _ -> @@ -157,46 +155,3 @@ create_app_info(AppDir, AppFile) -> _ -> error end. - --spec validate_application_info(rebar_app_info:t()) -> boolean(). -validate_application_info(AppInfo) -> - validate_application_info(AppInfo, rebar_app_info:app_details(AppInfo)). - -validate_application_info(AppInfo, AppDetail) -> - EbinDir = rebar_app_info:ebin_dir(AppInfo), - case rebar_app_info:app_file(AppInfo) of - undefined -> - false; - AppFile -> - case get_modules_list(AppFile, AppDetail) of - {ok, List} -> - has_all_beams(EbinDir, List); - _Error -> - ?PRV_ERROR({module_list, AppFile}) - end - end. - --spec get_modules_list(file:filename_all(), proplists:proplist()) -> - {ok, list()} | - {warning, Reason::term()} | - {error, Reason::term()}. -get_modules_list(AppFile, AppDetail) -> - case proplists:get_value(modules, AppDetail) of - undefined -> - {warning, {invalid_app_file, AppFile}}; - ModulesList -> - {ok, ModulesList} - end. - --spec has_all_beams(file:filename_all(), list()) -> true | providers:error(). -has_all_beams(EbinDir, [Module | ModuleList]) -> - BeamFile = filename:join([EbinDir, - ec_cnv:to_list(Module) ++ ".beam"]), - case filelib:is_file(BeamFile) of - true -> - has_all_beams(EbinDir, ModuleList); - false -> - ?PRV_ERROR({missing_module, Module}) - end; -has_all_beams(_, []) -> - true. diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl index 9d779be..7a01307 100644 --- a/src/rebar_app_info.erl +++ b/src/rebar_app_info.erl @@ -224,7 +224,7 @@ state(#app_info_t{state=State}) -> -spec valid(t()) -> boolean(). valid(AppInfo=#app_info_t{valid=undefined}) -> - case rebar_app_discover:validate_application_info(AppInfo) of + case rebar_app_utils:validate_application_info(AppInfo) of true -> true; _ -> diff --git a/src/rebar_app_utils.erl b/src/rebar_app_utils.erl index 2b63519..cd1124a 100644 --- a/src/rebar_app_utils.erl +++ b/src/rebar_app_utils.erl @@ -28,13 +28,13 @@ -export([find/2, find/3, - is_app_dir/0, is_app_dir/1, is_app_src/1, app_src_to_app/1, - load_app_file/2, - app_vsn/2]). + validate_application_info/1, + validate_application_info/2]). -include("rebar.hrl"). +-include_lib("providers/include/providers.hrl"). %% =================================================================== %% Public API @@ -51,35 +51,6 @@ find(Name, Vsn, Apps) -> andalso rebar_app_info:original_vsn(App) =:= Vsn end, Apps). --spec is_app_dir() -> {true, file:name()} | false. -is_app_dir() -> - is_app_dir(rebar_dir:get_cwd()). - --spec is_app_dir(file:name()) -> {true, file:name()} | false. -is_app_dir(Dir) -> - SrcDir = filename:join([Dir, "src"]), - AppSrc = filename:join([SrcDir, "*.app.src"]), - case filelib:wildcard(AppSrc) of - [AppSrcFile] -> - {true, AppSrcFile}; - [] -> - EbinDir = filename:join([Dir, "ebin"]), - App = filename:join([EbinDir, "*.app"]), - case filelib:wildcard(App) of - [AppFile] -> - {true, AppFile}; - [] -> - false; - _ -> - ?ERROR("More than one .app file in ~s~n", [EbinDir]), - false - end; - _ -> - ?ERROR("More than one .app.src file in ~s~n", [SrcDir]), - false - end. - - is_app_src(Filename) -> %% If removing the extension .app.src yields a shorter name, %% this is an .app.src file. @@ -91,58 +62,38 @@ app_src_to_app(Filename) -> filelib:ensure_dir(AppFile), AppFile. -app_vsn(Config, AppFile) -> - case load_app_file(Config, AppFile) of - {ok, Config1, _, AppInfo} -> - AppDir = filename:dirname(filename:dirname(AppFile)), - rebar_utils:vcs_vsn(Config1, get_value(vsn, AppInfo, AppFile), - AppDir); - {error, Reason} -> - ?ABORT("Failed to extract vsn from ~s: ~p\n", - [AppFile, Reason]) - end. +-spec validate_application_info(rebar_app_info:t()) -> boolean(). +validate_application_info(AppInfo) -> + validate_application_info(AppInfo, rebar_app_info:app_details(AppInfo)). -load_app_file(_State, undefined) -> {error, missing_app_file}; -load_app_file(State, Filename) -> - AppFile = {app_file, Filename}, - case rebar_state:get(State, {appfile, AppFile}, undefined) of +validate_application_info(AppInfo, AppDetail) -> + EbinDir = rebar_app_info:ebin_dir(AppInfo), + case rebar_app_info:app_file(AppInfo) of undefined -> - case consult_app_file(Filename) of - {ok, [{application, AppName, AppData}]} -> - State1 = rebar_state:set(State, - {appfile, AppFile}, - {AppName, AppData}), - {ok, State1, AppName, AppData}; - {error, _} = Error -> - Error; - Other -> - {error, {unexpected_terms, Other}} - end; - {AppName, AppData} -> - {ok, State, AppName, AppData} + false; + AppFile -> + case proplists:get_value(modules, AppDetail) of + undefined -> + ?PRV_ERROR({module_list, AppFile}); + List -> + has_all_beams(EbinDir, List) + + end end. %% =================================================================== %% Internal functions %% =================================================================== -%% In the case of *.app.src we want to give the user the ability to -%% dynamically script the application resource file (think dynamic version -%% string, etc.), in a way similar to what can be done with the rebar -%% config. However, in the case of *.app, rebar should not manipulate -%% that file. This enforces that dichotomy between app and app.src. -consult_app_file(Filename) -> - case lists:suffix(".app.src", Filename) of - false -> - file:consult(Filename); +-spec has_all_beams(file:filename_all(), list()) -> true | providers:error(). +has_all_beams(EbinDir, [Module | ModuleList]) -> + BeamFile = filename:join([EbinDir, + ec_cnv:to_list(Module) ++ ".beam"]), + case filelib:is_file(BeamFile) of true -> - {ok, rebar_config:consult_file(Filename)} - end. - -get_value(Key, AppInfo, AppFile) -> - case proplists:get_value(Key, AppInfo) of - undefined -> - ?ABORT("Failed to get app value '~p' from '~s'~n", [Key, AppFile]); - Value -> - Value - end. + has_all_beams(EbinDir, ModuleList); + false -> + ?PRV_ERROR({missing_module, Module}) + end; +has_all_beams(_, []) -> + true. diff --git a/src/rebar_config.erl b/src/rebar_config.erl index 43730ea..36d6b18 100644 --- a/src/rebar_config.erl +++ b/src/rebar_config.erl @@ -91,7 +91,7 @@ try_consult(File) -> {error, enoent} -> []; {error, Reason} -> - ?ABORT("Failed to read config file ~s: ~p", [File, Reason]) + ?ABORT("Failed to read config file ~s:~n ~p", [File, Reason]) end. bs(Vars) -> diff --git a/src/rebar_dir.erl b/src/rebar_dir.erl index 58ce716..3962bf8 100644 --- a/src/rebar_dir.erl +++ b/src/rebar_dir.erl @@ -7,8 +7,13 @@ lib_dirs/1, home_dir/0, global_config_dir/1, + global_config/1, + global_config/0, + global_cache_dir/1, + local_cache_dir/0, get_cwd/0, - ensure_dir/1, + template_globals/1, + template_dir/1, src_dirs/1, ebin_dir/0, processing_base_dir/1, @@ -47,23 +52,31 @@ home_dir() -> global_config_dir(State) -> Home = home_dir(), - rebar_state:get(State, global_rebar_dir, filename:join(Home, ?CONFIG_DIR)). + rebar_state:get(State, global_rebar_dir, filename:join([Home, ".config", "rebar3"])). + +global_config(State) -> + filename:join(global_config_dir(State), "config"). + +global_config() -> + Home = home_dir(), + filename:join([Home, ".config", "rebar3", "config"]). + +global_cache_dir(State) -> + Home = home_dir(), + rebar_state:get(State, global_rebar_dir, filename:join([Home, ".cache", "rebar3"])). + +local_cache_dir() -> + filename:join(get_cwd(), ".rebar3"). get_cwd() -> {ok, Dir} = file:get_cwd(), Dir. -%% TODO: filelib:ensure_dir/1 corrected in R13B04. Remove when we drop -%% support for OTP releases older than R13B04. -ensure_dir(Path) -> - case filelib:ensure_dir(Path) of - ok -> - ok; - {error,eexist} -> - ok; - Error -> - Error - end. +template_globals(State) -> + filename:join([global_config_dir(State), "templates", "globals"]). + +template_dir(State) -> + filename:join([global_config_dir(State), "templates"]). -spec src_dirs([string()]) -> [file:filename(), ...]. src_dirs([]) -> diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl index 330f20b..afdd6bd 100644 --- a/src/rebar_erlc_compiler.erl +++ b/src/rebar_erlc_compiler.erl @@ -270,7 +270,7 @@ opts_changed(Opts, Target) -> code:purge(Mod), lists:sort(Opts) =/= lists:sort(proplists:get_value(options, Compile)); - {error, nofile} -> true + {error, _} -> true end. check_erlcinfo(_Config, #erlcinfo{vsn=?ERLCINFO_VSN}) -> @@ -283,7 +283,7 @@ check_erlcinfo(Config, _) -> [erlcinfo_file(Config)]). erlcinfo_file(_Config) -> - filename:join([rebar_dir:get_cwd(), ?CONFIG_DIR, ?ERLCINFO_FILE]). + filename:join(rebar_dir:local_cache_dir(), ?ERLCINFO_FILE). init_erlcinfo(Config, Erls) -> G = restore_erlcinfo(Config), @@ -464,8 +464,8 @@ internal_erl_compile(Config, Dir, Source, OutDir, ErlOpts, G) -> -spec compile_mib(file:filename(), file:filename(), rebar_state:t()) -> 'ok'. compile_mib(Source, Target, Config) -> - ok = rebar_dir:ensure_dir(Target), - ok = rebar_dir:ensure_dir(filename:join("include", "dummy.hrl")), + ok = filelib:ensure_dir(Target), + ok = filelib:ensure_dir(filename:join("include", "dummy.hrl")), Opts = [{outdir, "priv/mibs"}, {i, ["priv/mibs"]}] ++ rebar_state:get(Config, mib_opts, []), case snmpc:compile(Source, Opts) of diff --git a/src/rebar_otp_app.erl b/src/rebar_otp_app.erl index 272d950..49579ae 100644 --- a/src/rebar_otp_app.erl +++ b/src/rebar_otp_app.erl @@ -27,8 +27,7 @@ -module(rebar_otp_app). -export([compile/2, - format_error/1, - clean/2]). + format_error/1]). -include("rebar.hrl"). -include_lib("providers/include/providers.hrl"). @@ -42,52 +41,33 @@ compile(State, App) -> %% written out as a ebin/*.app file. That resulting file will then %% be validated as usual. Dir = ec_cnv:to_list(rebar_app_info:dir(App)), - {State2, App1} = case rebar_app_info:app_file_src(App) of - undefined -> - {State, App}; - AppFileSrc -> - {State1, File} = preprocess(State, Dir, AppFileSrc), - {State1, rebar_app_info:app_file(App, File)} - end, + App1 = case rebar_app_info:app_file_src(App) of + undefined -> + App; + AppFileSrc -> + File = preprocess(State, Dir, AppFileSrc), + rebar_app_info:app_file(App, File) + end, %% Load the app file and validate it. - validate_app(State2, App1). - - + validate_app(State, App1). format_error({file_read, File, Reason}) -> io_lib:format("Failed to read ~s for processing: ~p", [File, Reason]); format_error({invalid_name, File, AppName}) -> io_lib:format("Invalid ~s: name of application (~p) must match filename.", [File, AppName]). -clean(_State, File) -> - %% If the app file is a .app.src, delete the generated .app file - case rebar_app_utils:is_app_src(File) of - true -> - case file:delete(rebar_app_utils:app_src_to_app(File)) of - ok -> - ok; - {error, enoent} -> - %% The file not existing is OK, we can ignore the error. - ok; - Other -> - Other - end; - false -> - ok - end. - %% =================================================================== %% Internal functions %% =================================================================== validate_app(State, App) -> AppFile = rebar_app_info:app_file(App), - case rebar_app_utils:load_app_file(State, AppFile) of - {ok, State1, AppName, AppData} -> + case consult_app_file(AppFile) of + {ok, [{application, AppName, AppData}]} -> case validate_name(AppName, AppFile) of ok -> - validate_app_modules(State1, App, AppData); + validate_app_modules(State, App, AppData); Error -> Error end; @@ -102,7 +82,7 @@ validate_app_modules(State, App, AppData) -> AppVsn = proplists:get_value(vsn, AppData), case rebar_state:get(State, validate_app_modules, true) of true -> - case rebar_app_discover:validate_application_info(App, AppData) of + case rebar_app_utils:validate_application_info(App, AppData) of true -> {ok, rebar_app_info:original_vsn(App, AppVsn)}; Error -> @@ -113,16 +93,16 @@ validate_app_modules(State, App, AppData) -> end. preprocess(State, Dir, AppSrcFile) -> - case rebar_app_utils:load_app_file(State, AppSrcFile) of - {ok, State1, AppName, AppData} -> + case consult_app_file(AppSrcFile) of + {ok, [{application, AppName, AppData}]} -> %% Look for a configuration file with vars we want to %% substitute. Note that we include the list of modules available in %% ebin/ and update the app data accordingly. - AppVars = load_app_vars(State1) ++ [{modules, ebin_modules(Dir)}], + AppVars = load_app_vars(State) ++ [{modules, ebin_modules(Dir)}], A1 = apply_app_vars(AppVars, AppData), %% AppSrcFile may contain instructions for generating a vsn number - {State2, Vsn} = rebar_app_utils:app_vsn(State1, AppSrcFile), + Vsn = app_vsn(AppSrcFile), A2 = lists:keystore(vsn, 1, A1, {vsn, Vsn}), %% systools:make_relup/4 fails with {missing_param, registered} @@ -140,7 +120,7 @@ preprocess(State, Dir, AppSrcFile) -> %% on the code path true = code:add_path(filename:absname(filename:dirname(AppFile))), - {State2, AppFile}; + AppFile; {error, Reason} -> ?PRV_ERROR({file_read, AppSrcFile, Reason}) end. @@ -185,3 +165,33 @@ ensure_registered(AppData) -> %% We could further check whether the value is a list of atoms. AppData end. + +%% In the case of *.app.src we want to give the user the ability to +%% dynamically script the application resource file (think dynamic version +%% string, etc.), in a way similar to what can be done with the rebar +%% config. However, in the case of *.app, rebar should not manipulate +%% that file. This enforces that dichotomy between app and app.src. +consult_app_file(Filename) -> + case lists:suffix(".app.src", Filename) of + false -> + file:consult(Filename); + true -> + {ok, rebar_config:consult_file(Filename)} + end. + +app_vsn(AppFile) -> + case consult_app_file(AppFile) of + {ok, [{application, _AppName, AppData}]} -> + AppDir = filename:dirname(filename:dirname(AppFile)), + rebar_utils:vcs_vsn(get_value(vsn, AppData, AppFile), AppDir); + {error, Reason} -> + ?ABORT("Failed to consult app file ~s: ~p\n", [AppFile, Reason]) + end. + +get_value(Key, AppInfo, AppFile) -> + case proplists:get_value(Key, AppInfo) of + undefined -> + ?ABORT("Failed to get app value '~p' from '~s'~n", [Key, AppFile]); + Value -> + Value + end. diff --git a/src/rebar_packages.erl b/src/rebar_packages.erl index 38dfbbf..5c67600 100644 --- a/src/rebar_packages.erl +++ b/src/rebar_packages.erl @@ -12,7 +12,7 @@ -spec get_packages(rebar_state:t()) -> {rebar_dict(), rebar_digraph()}. get_packages(State) -> - RebarDir = rebar_dir:global_config_dir(State), + RebarDir = rebar_dir:global_cache_dir(State), RegistryDir = filename:join(RebarDir, "packages"), DictFile = filename:join(RegistryDir, "dict"), Edges = filename:join(RegistryDir, "edges"), diff --git a/src/rebar_prv_dialyzer.erl b/src/rebar_prv_dialyzer.erl index 240427b..24abc4f 100644 --- a/src/rebar_prv_dialyzer.erl +++ b/src/rebar_prv_dialyzer.erl @@ -311,8 +311,7 @@ build_proj_plt(State, Plt, Files) -> end. get_base_plt_location(State) -> - Home = rebar_dir:home_dir(), - GlobalConfigDir = filename:join(Home, ?CONFIG_DIR), + GlobalConfigDir = rebar_dir:global_config_dir(State), BaseDir = rebar_state:get(State, dialyzer_base_plt_dir, GlobalConfigDir), BasePlt = rebar_state:get(State, dialyzer_base_plt, default_plt()), filename:join(BaseDir, BasePlt). diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index 8db4761..6270660 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -74,15 +74,7 @@ do(State) -> ProjectApps = rebar_state:project_apps(State), {Apps, State1} = - lists:foldl(fun(Profile, {AppsAcc, StateAcc}) -> - Locks = rebar_state:get(StateAcc, {locks, Profile}, []), - {ok, NewApps, NewState} = - handle_deps(Profile - ,StateAcc - ,rebar_state:get(StateAcc, {deps, Profile}, []) - ,Locks), - {NewApps++AppsAcc, NewState} - end, {[], State}, lists:reverse(Profiles)), + lists:foldl(fun deps_per_profile/2, {[], State}, lists:reverse(Profiles)), Source = ProjectApps ++ Apps, case find_cycles(Source) of @@ -91,11 +83,9 @@ do(State) -> {error, Error} -> {error, Error}; no_cycle -> - case rebar_digraph:compile_order(Source) of - {ok, Sort} -> - {ok, rebar_state:deps_to_build(State1, - lists:dropwhile(fun rebar_app_info:valid/1, - Sort -- ProjectApps))}; + case compile_order(Source, ProjectApps) of + {ok, ToCompile} -> + {ok, rebar_state:deps_to_build(State1, ToCompile)}; {error, Error} -> {error, Error} end @@ -106,13 +96,6 @@ do(State) -> {error, Reason} end. -find_cycles(Apps) -> - case rebar_digraph:compile_order(Apps) of - {error, {cycles, Cycles}} -> {cycles, Cycles}; - {error, Error} -> {error, Error}; - {ok, _} -> no_cycle - end. - -spec format_error(any()) -> iolist(). format_error({parse_dep, Dep}) -> io_lib:format("Failed parsing dep ~p", [Dep]); @@ -155,22 +138,8 @@ handle_deps(Profile, State, Deps, Upgrade, Locks) -> {State1, SrcApps, PkgDeps1, Seen} = update_src_deps(Profile, 0, SrcDeps, PkgDeps, [], State, Upgrade, sets:new(), Locks), - {Solved, State2} = case PkgDeps1 of - [] -> %% No pkg deps - {[], State1}; - PkgDeps2 -> - %% Find pkg deps needed - S = case rebar_digraph:cull_deps(Graph, PkgDeps2) of - {ok, [], _} -> - throw({rebar_digraph, no_solution}); - {ok, Solution, []} -> - Solution; - {ok, Solution, Discarded} -> - [warn_skip_pkg(Pkg) || Pkg <- Discarded], - Solution - end, - update_pkg_deps(Profile, S, Packages, Upgrade, Seen, State1) - end, + {Solved, State2} = + update_pkg_deps(Profile, Packages, PkgDeps1, Graph, Upgrade, Seen, State1), AllDeps = lists:ukeymerge(2 ,lists:ukeysort(2, SrcApps) @@ -184,33 +153,74 @@ handle_deps(Profile, State, Deps, Upgrade, Locks) -> %% Internal functions %% =================================================================== +deps_per_profile(Profile, {Apps, State}) -> + Locks = rebar_state:get(State, {locks, Profile}, []), + ProfileDeps = rebar_state:get(State, {deps, Profile}, []), + {ok, NewApps, NewState} = handle_deps(Profile, State, ProfileDeps, Locks), + {NewApps++Apps, NewState}. + +find_cycles(Apps) -> + case rebar_digraph:compile_order(Apps) of + {error, {cycles, Cycles}} -> {cycles, Cycles}; + {error, Error} -> {error, Error}; + {ok, _} -> no_cycle + end. + +compile_order(Source, ProjectApps) -> + case rebar_digraph:compile_order(Source) of + {ok, Sort} -> + %% Valid apps are compiled and good + {ok, lists:dropwhile(fun rebar_app_info:valid/1, Sort -- ProjectApps)}; + {error, Error} -> + {error, Error} + end. + +update_pkg_deps(Profile, Packages, PkgDeps, Graph, Upgrade, Seen, State) -> + case PkgDeps of + [] -> %% No pkg deps + {[], State}; + PkgDeps -> + %% Find pkg deps needed + S = case rebar_digraph:cull_deps(Graph, PkgDeps) of + {ok, [], _} -> + throw({rebar_digraph, no_solution}); + {ok, Solution, []} -> + Solution; + {ok, Solution, Discarded} -> + [warn_skip_pkg(Pkg) || Pkg <- Discarded], + Solution + end, + update_pkg_deps(Profile, S, Packages, Upgrade, Seen, State) + end. + update_pkg_deps(Profile, Pkgs, Packages, Upgrade, Seen, State) -> %% Create app_info record for each pkg dep DepsDir = rebar_dir:deps_dir(State), {Solved, _, State1} = lists:foldl(fun(Pkg, {Acc, SeenAcc, StateAcc}) -> - AppInfo = package_to_app(DepsDir - ,Packages - ,Pkg), - {SeenAcc1, StateAcc1} = maybe_lock(Profile, AppInfo, SeenAcc, StateAcc, 0), - case maybe_fetch(AppInfo, Upgrade, SeenAcc1, State) of - true -> - {[AppInfo | Acc], SeenAcc1, StateAcc1}; - false -> - {Acc, SeenAcc1, StateAcc1} - end + handle_pkg_dep(Profile, Pkg, Packages, Upgrade, DepsDir, Acc, SeenAcc, StateAcc) end, {[], Seen, State}, Pkgs), {Solved, State1}. +handle_pkg_dep(Profile, Pkg, Packages, Upgrade, DepsDir, Fetched, Seen, State) -> + AppInfo = package_to_app(DepsDir, Packages, Pkg), + {NewSeen, NewState} = maybe_lock(Profile, AppInfo, Seen, State, 0), + case maybe_fetch(AppInfo, Upgrade, NewSeen, NewState) of + true -> + {[AppInfo | Fetched], NewSeen, NewState}; + false -> + {Fetched, NewSeen, NewState} + end. + + maybe_lock(Profile, AppInfo, Seen, State, Level) -> - Name = rebar_app_info:name(AppInfo), case Profile of default -> + Name = rebar_app_info:name(AppInfo), case sets:is_element(Name, Seen) of false -> - AppName = rebar_app_info:name(AppInfo), Locks = rebar_state:lock(State), - case lists:any(fun(App) -> rebar_app_info:name(App) =:= AppName end, Locks) of + case lists:any(fun(App) -> rebar_app_info:name(App) =:= Name end, Locks) of true -> {sets:add_element(Name, Seen), State}; false -> @@ -239,81 +249,77 @@ package_to_app(DepsDir, Packages, {Name, Vsn}) -> -spec update_src_deps(atom(), non_neg_integer(), list(), list(), list(), rebar_state:t(), boolean(), sets:set(binary()), list()) -> {rebar_state:t(), list(), list(), sets:set(binary())}. update_src_deps(Profile, Level, SrcDeps, PkgDeps, SrcApps, State, Upgrade, Seen, Locks) -> - case lists:foldl(fun(AppInfo, {SrcDepsAcc, PkgDepsAcc, SrcAppsAcc, StateAcc, SeenAcc, LocksAcc}) -> - %% If not seen, add to list of locks to write out - Name = rebar_app_info:name(AppInfo), - case sets:is_element(Name, SeenAcc) of - true -> - %% If from lock file don't print warning about skipping - case lists:keymember(Name, 1, Locks) of - false -> - warn_skip_deps(AppInfo); - true -> - ok - end, - %% scan for app children here if upgrading - case Upgrade of - false -> - {SrcDepsAcc, PkgDepsAcc, SrcAppsAcc, StateAcc, SeenAcc, LocksAcc}; - true -> - {SrcDepsAcc1, PkgDepsAcc1, SrcAppsAcc1, StateAcc2, LocksAcc1} = - handle_dep(AppInfo - ,SrcDepsAcc - ,PkgDepsAcc - ,SrcAppsAcc - ,Level - ,StateAcc - ,LocksAcc), - - {SrcDepsAcc1, PkgDepsAcc1, SrcAppsAcc1, StateAcc2, SeenAcc, LocksAcc1} - end; - false -> - {SeenAcc1, StateAcc1} = maybe_lock(Profile, AppInfo, SeenAcc, StateAcc, Level), - {SrcDepsAcc1, PkgDepsAcc1, SrcAppsAcc1, StateAcc2, LocksAcc1} = - case Upgrade of - true -> - %{true, UpgradeName, UpgradeLevel} -> - handle_upgrade(AppInfo - ,SrcDepsAcc - ,PkgDepsAcc - ,SrcAppsAcc - ,Level - ,StateAcc1 - ,LocksAcc); - _ -> - maybe_fetch(AppInfo, false, SeenAcc, StateAcc), - handle_dep(AppInfo - ,SrcDepsAcc - ,PkgDepsAcc - ,SrcAppsAcc - ,Level - ,StateAcc1 - ,LocksAcc) - end, - {SrcDepsAcc1, PkgDepsAcc1, SrcAppsAcc1, StateAcc2, SeenAcc1, LocksAcc1} - end - end, - {[], PkgDeps, SrcApps, State, Seen, Locks}, - rebar_utils:sort_deps(SrcDeps)) of + case lists:foldl( + fun(AppInfo, {SrcDepsAcc, PkgDepsAcc, SrcAppsAcc, StateAcc, SeenAcc, LocksAcc}) -> + update_src_dep(AppInfo, Profile, Level, + SrcDepsAcc, PkgDepsAcc, SrcAppsAcc, StateAcc, + Upgrade, SeenAcc, Locks, LocksAcc) + end, + {[], PkgDeps, SrcApps, State, Seen, Locks}, + rebar_utils:sort_deps(SrcDeps)) of {[], NewPkgDeps, NewSrcApps, State1, Seen1, _NewLocks} -> {State1, NewSrcApps, NewPkgDeps, Seen1}; {NewSrcDeps, NewPkgDeps, NewSrcApps, State1, Seen1, NewLocks} -> update_src_deps(Profile, Level+1, NewSrcDeps, NewPkgDeps, NewSrcApps, State1, Upgrade, Seen1, NewLocks) end. +update_src_dep(AppInfo, Profile, Level, SrcDeps, PkgDeps, SrcApps, State, Upgrade, Seen, BaseLocks, Locks) -> + %% If not seen, add to list of locks to write out + Name = rebar_app_info:name(AppInfo), + case sets:is_element(Name, Seen) of + true -> + update_seen_src_dep(AppInfo, Level, + SrcDeps, PkgDeps, SrcApps, + State, Upgrade, Seen, BaseLocks, Locks); + false -> + update_unseen_src_dep(AppInfo, Profile, Level, + SrcDeps, PkgDeps, SrcApps, + State, Upgrade, Seen, Locks) + + end. + +update_seen_src_dep(AppInfo, Level, SrcDeps, PkgDeps, SrcApps, State, Upgrade, Seen, BaseLocks, Locks) -> + Name = rebar_app_info:name(AppInfo), + %% If seen from lock file don't print warning about skipping + case lists:keymember(Name, 1, BaseLocks) of + false -> + warn_skip_deps(AppInfo); + true -> + ok + end, + %% scan for app children here if upgrading + case Upgrade of + false -> + {SrcDeps, PkgDeps, SrcApps, State, Seen, Locks}; + true -> + {NewSrcDeps, NewPkgDeps, NewSrcApps, NewState, NewLocks} + = handle_dep(AppInfo, SrcDeps, PkgDeps, SrcApps, + Level, State, Locks), + {NewSrcDeps, NewPkgDeps, NewSrcApps, NewState, Seen, NewLocks} + end. + +update_unseen_src_dep(AppInfo, Profile, Level, SrcDeps, PkgDeps, SrcApps, State, Upgrade, Seen, Locks) -> + {NewSeen, State1} = maybe_lock(Profile, AppInfo, Seen, State, Level), + {NewSrcDeps, NewPkgDeps, NewSrcApps, State2, NewLocks} + = case Upgrade of + true -> + handle_upgrade(AppInfo, SrcDeps, PkgDeps, SrcApps, + Level, State1, Locks); + _ -> + maybe_fetch(AppInfo, false, Seen, State1), + handle_dep(AppInfo, SrcDeps, PkgDeps, SrcApps, + Level, State1, Locks) + end, + {NewSrcDeps, NewPkgDeps, NewSrcApps, State2, NewSeen, NewLocks}. + handle_upgrade(AppInfo, SrcDeps, PkgDeps, SrcApps, Level, State, Locks) -> Name = rebar_app_info:name(AppInfo), case lists:keyfind(Name, 1, Locks) of false -> case maybe_fetch(AppInfo, true, sets:new(), State) of true -> - handle_dep(AppInfo - ,SrcDeps - ,PkgDeps - ,SrcApps - ,Level - ,State - ,Locks); + handle_dep(AppInfo, SrcDeps, PkgDeps, SrcApps, + Level, State, Locks); false -> {[AppInfo|SrcDeps], PkgDeps, SrcApps, State, Locks} @@ -359,16 +365,15 @@ handle_dep(State, DepsDir, AppInfo, Locks, Level) -> sets:set(binary()), rebar_state:t()) -> boolean(). maybe_fetch(AppInfo, Upgrade, Seen, State) -> AppDir = ec_cnv:to_list(rebar_app_info:dir(AppInfo)), - Apps = rebar_app_discover:find_apps(["_checkouts"], all), - case rebar_app_utils:find(rebar_app_info:name(AppInfo), Apps) of - {ok, _} -> - %% Don't fetch dep if it exists in the _checkouts dir + %% Don't fetch dep if it exists in the _checkouts dir + case in_checkouts(AppInfo) of + true -> false; - error -> - case not app_exists(AppDir) of - true -> - fetch_app(AppInfo, AppDir, State); + false -> + case rebar_app_discover:find_app(AppDir, all) of false -> + fetch_app(AppInfo, AppDir, State); + {true, _} -> case sets:is_element(rebar_app_info:name(AppInfo), Seen) of true -> false; @@ -378,6 +383,14 @@ maybe_fetch(AppInfo, Upgrade, Seen, State) -> end end. +in_checkouts(AppInfo) -> + Apps = rebar_app_discover:find_apps(["_checkouts"], all), + case rebar_app_utils:find(rebar_app_info:name(AppInfo), Apps) of + {ok, _} -> true; + error -> false + end. + + -spec parse_deps(binary(), list(), list(), list(), integer()) -> {[rebar_app_info:t()], [pkg_dep()]}. parse_deps(DepsDir, Deps, State, Locks, Level) -> lists:foldl(fun(Dep, Acc) -> @@ -443,19 +456,6 @@ new_dep(DepsDir, Name, Vsn, Source, State) -> rebar_state:overrides(S, ParentOverrides++Overrides)), rebar_app_info:source(Dep1, Source). -app_exists(AppDir) -> - case rebar_app_utils:is_app_dir(filename:absname(AppDir)++"-*") of - {true, _} -> - true; - _ -> - case rebar_app_utils:is_app_dir(filename:absname(AppDir)) of - {true, _} -> - true; - _ -> - false - end - end. - fetch_app(AppInfo, AppDir, State) -> ?INFO("Fetching ~s (~p)", [rebar_app_info:name(AppInfo), rebar_app_info:source(AppInfo)]), Source = rebar_app_info:source(AppInfo), diff --git a/src/rebar_prv_update.erl b/src/rebar_prv_update.erl index f4985f3..20f6974 100644 --- a/src/rebar_prv_update.erl +++ b/src/rebar_prv_update.erl @@ -59,7 +59,7 @@ format_error(package_index_write) -> "Failed to write package index.". write_registry(Dict, {digraph, Edges, Vertices, Neighbors, _}, State) -> - Dir = rebar_dir:global_config_dir(State), + Dir = rebar_dir:global_cache_dir(State), RegistryDir = filename:join(Dir, "packages"), filelib:ensure_dir(filename:join(RegistryDir, "dummy")), ets:tab2file(Edges, filename:join(RegistryDir, "edges")), diff --git a/src/rebar_templater.erl b/src/rebar_templater.erl index 47ce093..edfe3bd 100644 --- a/src/rebar_templater.erl +++ b/src/rebar_templater.erl @@ -48,13 +48,13 @@ new(Template, Vars, Force, State) -> ?DEBUG("Looking for ~p~n", [Template]), case lists:keyfind(Template, 1, AvailTemplates) of false -> {not_found, Template}; - TemplateTup -> create(TemplateTup, Files, Vars, Force) + TemplateTup -> create(TemplateTup, Files, Vars, Force, State) end. %% Give a list of templates with their expanded content list_templates(State) -> {AvailTemplates, Files} = find_templates(State), - [list_template(Files, Template) || Template <- AvailTemplates]. + [list_template(Files, Template, State) || Template <- AvailTemplates]. %% =================================================================== %% Rendering API / legacy? @@ -89,11 +89,11 @@ render(Template, Context) -> %% =================================================================== %% Expand a single template's value -list_template(Files, {Name, Type, File}) -> +list_template(Files, {Name, Type, File}, State) -> TemplateTerms = consult(load_file(Files, Type, File)), {Name, Type, File, get_template_description(TemplateTerms), - get_template_vars(TemplateTerms)}. + get_template_vars(TemplateTerms, State)}. %% Load up the template description out from a list of attributes read in %% a .template file. @@ -105,12 +105,12 @@ get_template_description(TemplateTerms) -> %% Load up the variables out from a list of attributes read in a .template file %% and return them merged with the globally-defined and default variables. -get_template_vars(TemplateTerms) -> +get_template_vars(TemplateTerms, State) -> Vars = case lists:keyfind(variables, 1, TemplateTerms) of {_, Value} -> Value; false -> [] end, - override_vars(Vars, override_vars(global_variables(), default_variables())). + override_vars(Vars, override_vars(global_variables(State), default_variables())). %% Provide a way to merge a set of variables with another one. The left-hand %% set of variables takes precedence over the right-hand set. @@ -142,9 +142,8 @@ default_variables() -> %% Load variable definitions from the 'Globals' file in the home template %% directory -global_variables() -> - Home = rebar_dir:home_dir(), - GlobalFile = filename:join([Home, ?CONFIG_DIR, "templates", "globals"]), +global_variables(State) -> + GlobalFile = rebar_dir:template_globals(State), case file:consult(GlobalFile) of {error, enoent} -> []; {ok, Data} -> proplists:get_value(variables, Data, []) @@ -157,9 +156,9 @@ drop_var_docs([{K,V}|Rest]) -> [{K,V} | drop_var_docs(Rest)]. %% Load the template index, resolve all variables, and then execute %% the template. -create({Template, Type, File}, Files, UserVars, Force) -> +create({Template, Type, File}, Files, UserVars, Force, State) -> TemplateTerms = consult(load_file(Files, Type, File)), - Vars = drop_var_docs(override_vars(UserVars, get_template_vars(TemplateTerms))), + Vars = drop_var_docs(override_vars(UserVars, get_template_vars(TemplateTerms, State))), TemplateCwd = filename:dirname(File), execute_template(TemplateTerms, Files, {Template, Type, TemplateCwd}, Vars, Force). @@ -270,8 +269,7 @@ find_escript_templates(Files) -> %% Fetch template indexes that sit on disk in the user's HOME find_disk_templates(State) -> OtherTemplates = find_other_templates(State), - Home = rebar_dir:home_dir(), - HomeFiles = rebar_utils:find_files(filename:join([Home, ?CONFIG_DIR, "templates"]), + HomeFiles = rebar_utils:find_files(rebar_dir:template_dir(State), ?TEMPLATE_RE, true), % recursive [{file, F} || F <- OtherTemplates ++ HomeFiles]. diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 943c0d7..b3ae9ff 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -43,7 +43,7 @@ beams/1, find_executable/1, expand_code_path/0, - vcs_vsn/3, + vcs_vsn/2, deprecated/3, deprecated/4, erl_opts/1, @@ -179,19 +179,6 @@ expand_code_path() -> end, [], code:get_path()), code:set_path(lists:reverse(CodePath)). -vcs_vsn(Config, Vsn, Dir) -> - Key = {Vsn, Dir}, - Cache = rebar_state:get(Config, vsn_cache, dict:new()), - case dict:find(Key, Cache) of - error -> - VsnString = vcs_vsn_1(Vsn, Dir), - Cache1 = dict:store(Key, VsnString, Cache), - Config1 = rebar_state:set(Config, vsn_cache, Cache1), - {Config1, VsnString}; - {ok, VsnString} -> - {Config, VsnString} - end. - deprecated(Old, New, Opts, When) when is_list(Opts) -> case lists:member(Old, Opts) of true -> @@ -413,16 +400,16 @@ escript_foldl(Fun, Acc, File) -> Error end. -vcs_vsn_1(Vcs, Dir) -> +vcs_vsn(Vcs, Dir) -> case vcs_vsn_cmd(Vcs, Dir) of {plain, VsnString} -> VsnString; {cmd, CmdString} -> vcs_vsn_invoke(CmdString, Dir); unknown -> - ?ABORT("vcs_vsn: Unknown vsn format: ~p\n", [Vcs]); + ?ABORT("vcs_vsn: Unknown vsn format: ~p", [Vcs]); {error, Reason} -> - ?ABORT("vcs_vsn: ~s\n", [Reason]) + ?ABORT("vcs_vsn: ~s", [Reason]) end. %% Temp work around for repos like relx that use "semver" diff --git a/test/rebar_new_SUITE.erl b/test/rebar_new_SUITE.erl index 62a26af..6b57b74 100644 --- a/test/rebar_new_SUITE.erl +++ b/test/rebar_new_SUITE.erl @@ -23,7 +23,7 @@ end_per_testcase(_, Config) -> mock_home_dir(Path) -> meck:new(rebar_dir, [passthrough]), - meck:expect(rebar_dir, home_dir, fun() -> Path end). + meck:expect(rebar_dir, template_dir, fun(_) -> Path end). mock_empty_escript_templates() -> %% Can't find escript templates unless we run diff --git a/test/rebar_upgrade_SUITE.erl b/test/rebar_upgrade_SUITE.erl index b4daef9..ed0b2d8 100644 --- a/test/rebar_upgrade_SUITE.erl +++ b/test/rebar_upgrade_SUITE.erl @@ -357,10 +357,10 @@ upgrades(delete_d) -> %% running the upgrade code is enough to properly upgrade things. top_level_deps([]) -> []; -top_level_deps([{{Name, Vsn, Ref}, _} | Deps]) -> - [{list_to_atom(Name), Vsn, Ref} | top_level_deps(Deps)]; top_level_deps([{{pkg, Name, Vsn}, _} | Deps]) -> - [{list_to_atom(Name), Vsn} | top_level_deps(Deps)]. + [{list_to_atom(Name), Vsn} | top_level_deps(Deps)]; +top_level_deps([{{Name, Vsn, Ref}, _} | Deps]) -> + [{list_to_atom(Name), Vsn, Ref} | top_level_deps(Deps)]. mock_deps(git, Deps, Upgrades) -> catch mock_git_resource:unmock(), |