25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2532 lines
98 KiB

10 년 전
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
6 년 전
10 년 전
Fix handling of updated files in extra_src_dirs This change fixes cases where changes in .hrl files would not be picked up in .erl files that are in extra source directories (such as those defined with `extra_src_dirs` or modules in the test/ directory during a CT or Eunit run). The problem was due to the way the Directed Acyclic Graph (DAG) of dependencies between files was being loaded and stored by the compiler modules. Prior to this fix, a single DAG would be used for all runs. On a regular run, the prior DAG is loaded from disk, re-checked, and if changed, it would get re-written to disk with the changes deciding what to re-compile. However, whenever extra source directories were specified, a second run would be done which swaps target directories around in the compiler modules. Bug 1: this second run was done without properly tracking the private .hrl files (in src/), so the changes were invisible. This has been fixed by re-adding the paths. The problem is that the DAG handling is self-contained; just invoking it was sufficient to get it loaded and rewritten to disk. But since runs with extra src dirs were done on different sets, the compilation of extra src dirs would be done with bad historical data (all the modules in src/ are dropped, all those in test/ are re-added); this DAG was then written to disk once again, polluting the next non-extra run. This is bug 2, and it is fixed by adding an optional label to each run so that a regular or extra compile round can be distinguished, each tracking their own files in their own DAG. A single test (and a lot of diffing) were sufficient for this.
6 년 전
10 년 전
10 년 전
10 년 전
10 년 전
10 년 전
10 년 전
10 년 전
10 년 전
Fix handling of updated files in extra_src_dirs This change fixes cases where changes in .hrl files would not be picked up in .erl files that are in extra source directories (such as those defined with `extra_src_dirs` or modules in the test/ directory during a CT or Eunit run). The problem was due to the way the Directed Acyclic Graph (DAG) of dependencies between files was being loaded and stored by the compiler modules. Prior to this fix, a single DAG would be used for all runs. On a regular run, the prior DAG is loaded from disk, re-checked, and if changed, it would get re-written to disk with the changes deciding what to re-compile. However, whenever extra source directories were specified, a second run would be done which swaps target directories around in the compiler modules. Bug 1: this second run was done without properly tracking the private .hrl files (in src/), so the changes were invisible. This has been fixed by re-adding the paths. The problem is that the DAG handling is self-contained; just invoking it was sufficient to get it loaded and rewritten to disk. But since runs with extra src dirs were done on different sets, the compilation of extra src dirs would be done with bad historical data (all the modules in src/ are dropped, all those in test/ are re-added); this DAG was then written to disk once again, polluting the next non-extra run. This is bug 2, and it is fixed by adding an optional label to each run so that a regular or extra compile round can be distinguished, each tracking their own files in their own DAG. A single test (and a lot of diffing) were sufficient for this.
6 년 전
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
6 년 전
  1. -module(rebar_compile_SUITE).
  2. -compile(export_all).
  3. -include_lib("common_test/include/ct.hrl").
  4. -include_lib("eunit/include/eunit.hrl").
  5. -include_lib("kernel/include/file.hrl").
  6. suite() ->
  7. [].
  8. all() ->
  9. [{group, basic_app}, {group, release_apps},
  10. {group, checkout_apps}, {group, checkout_deps},
  11. {group, basic_srcdirs}, {group, release_srcdirs}, {group, unbalanced_srcdirs},
  12. {group, basic_extras}, {group, release_extras}, {group, unbalanced_extras},
  13. {group, root_extras},
  14. recompile_when_hrl_changes, recompile_when_included_hrl_changes,
  15. recompile_extra_when_hrl_in_src_changes,
  16. recompile_when_opts_included_hrl_changes,
  17. recompile_when_opts_change,
  18. dont_recompile_when_opts_dont_change, dont_recompile_yrl_or_xrl,
  19. delete_beam_if_source_deleted,
  20. deps_in_path, checkout_priority, highest_version_of_pkg_dep,
  21. parse_transform_test, erl_first_files_test, mib_test,
  22. umbrella_mib_first_test, only_default_transitive_deps, clean_all,
  23. clean_specific, profile_deps, deps_build_in_prod, only_deps,
  24. override_deps, override_add_deps, override_del_deps,
  25. override_opts, override_add_opts, override_del_opts,
  26. apply_overrides_exactly_once, override_only_deps,
  27. profile_override_deps, profile_override_add_deps, profile_override_del_deps,
  28. profile_override_opts, profile_override_add_opts, profile_override_del_opts,
  29. include_file_relative_to_working_directory, include_file_in_src,
  30. include_file_relative_to_working_directory_test, include_file_in_src_test,
  31. include_file_in_src_test_multiapp,
  32. recompile_when_parse_transform_as_opt_changes,
  33. recompile_when_parse_transform_inline_changes,
  34. regex_filter_skip, regex_filter_regression,
  35. recursive, no_recursive,
  36. always_recompile_when_erl_compiler_options_set,
  37. dont_recompile_when_erl_compiler_options_env_does_not_change,
  38. recompile_when_erl_compiler_options_env_changes,
  39. rebar_config_os_var,
  40. app_file_linting].
  41. groups() ->
  42. [{basic_app, [], [build_basic_app, paths_basic_app, clean_basic_app]},
  43. {release_apps, [], [build_release_apps, paths_release_apps, clean_release_apps]},
  44. {checkout_apps, [], [build_checkout_apps, paths_checkout_apps]},
  45. {checkout_deps, [], [build_checkout_deps, paths_checkout_deps]},
  46. {basic_srcdirs, [], [build_basic_srcdirs, paths_basic_srcdirs]},
  47. {release_srcdirs, [], [build_release_srcdirs,
  48. paths_release_srcdirs]},
  49. {unbalanced_srcdirs, [], [build_unbalanced_srcdirs,
  50. paths_unbalanced_srcdirs]},
  51. {basic_extras, [], [build_basic_extra_dirs,
  52. paths_basic_extra_dirs,
  53. clean_basic_extra_dirs]},
  54. {release_extras, [], [build_release_extra_dirs,
  55. paths_release_extra_dirs,
  56. clean_release_extra_dirs]},
  57. {unbalanced_extras, [], [build_unbalanced_extra_dirs,
  58. paths_unbalanced_extra_dirs]},
  59. {root_extras, [], [build_extra_dirs_in_project_root,
  60. paths_extra_dirs_in_project_root,
  61. clean_extra_dirs_in_project_root]}].
  62. init_per_group(basic_app, Config) ->
  63. NewConfig = rebar_test_utils:init_rebar_state(Config, "basic_app_"),
  64. AppDir = ?config(apps, NewConfig),
  65. Name = rebar_test_utils:create_random_name("app1"),
  66. Vsn = rebar_test_utils:create_random_vsn(),
  67. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  68. [{app_names, [Name]}, {vsns, [Vsn]}|NewConfig];
  69. init_per_group(release_apps, Config) ->
  70. NewConfig = rebar_test_utils:init_rebar_state(Config, "release_apps_"),
  71. AppDir = ?config(apps, NewConfig),
  72. Name1 = rebar_test_utils:create_random_name("relapp1_"),
  73. Vsn1 = rebar_test_utils:create_random_vsn(),
  74. rebar_test_utils:create_app(filename:join([AppDir,"apps",Name1]), Name1, Vsn1, [kernel, stdlib]),
  75. Name2 = rebar_test_utils:create_random_name("relapp2_"),
  76. Vsn2 = rebar_test_utils:create_random_vsn(),
  77. rebar_test_utils:create_app(filename:join([AppDir,"apps",Name2]), Name2, Vsn2, [kernel, stdlib]),
  78. [{app_names, [Name1, Name2]}, {vsns, [Vsn1, Vsn2]}|NewConfig];
  79. init_per_group(checkout_apps, Config) ->
  80. NewConfig = rebar_test_utils:init_rebar_state(Config, "checkout_apps_"),
  81. AppDir = ?config(apps, NewConfig),
  82. CheckoutsDir = ?config(checkouts, NewConfig),
  83. Name1 = rebar_test_utils:create_random_name("checkapp1_"),
  84. Vsn1 = rebar_test_utils:create_random_vsn(),
  85. rebar_test_utils:create_app(AppDir, Name1, Vsn1, [kernel, stdlib]),
  86. Name2 = rebar_test_utils:create_random_name("checkapp2_"),
  87. Vsn2 = rebar_test_utils:create_random_vsn(),
  88. rebar_test_utils:create_app(filename:join([CheckoutsDir,Name2]), Name2, Vsn2, [kernel, stdlib]),
  89. [{app_names, [Name1, Name2]}, {vsns, [Vsn1, Vsn2]}|NewConfig];
  90. init_per_group(checkout_deps, Config) ->
  91. NewConfig = rebar_test_utils:init_rebar_state(Config, "checkout_deps_"),
  92. AppDir = ?config(apps, NewConfig),
  93. CheckoutsDir = ?config(checkouts, NewConfig),
  94. DepsDir = filename:join([AppDir, "_build", "default", "lib"]),
  95. Name1 = rebar_test_utils:create_random_name("checkapp1_"),
  96. Vsn1 = rebar_test_utils:create_random_vsn(),
  97. rebar_test_utils:create_app(AppDir, Name1, Vsn1, [kernel, stdlib]),
  98. Name2 = rebar_test_utils:create_random_name("checkapp2_"),
  99. Vsn2 = rebar_test_utils:create_random_vsn(),
  100. rebar_test_utils:create_app(filename:join([CheckoutsDir,Name2]), Name2, Vsn2, [kernel, stdlib]),
  101. rebar_test_utils:create_app(filename:join([DepsDir,Name2]), Name2, Vsn1, [kernel, stdlib]),
  102. [{app_names, [Name1, Name2]}, {vsns, [Vsn1, Vsn2]}|NewConfig];
  103. init_per_group(Group, Config) when Group == basic_srcdirs; Group == basic_extras ->
  104. NewConfig = rebar_test_utils:init_rebar_state(Config, "basic_srcdirs_"),
  105. AppDir = ?config(apps, NewConfig),
  106. Name = rebar_test_utils:create_random_name("app1_"),
  107. Vsn = rebar_test_utils:create_random_vsn(),
  108. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  109. ExtraSrc = io_lib:format("-module(~ts_extra).\n-export([ok/0]).\nok() -> ok.\n", [Name]),
  110. ok = filelib:ensure_dir(filename:join([AppDir, "extra", "dummy"])),
  111. ok = file:write_file(filename:join([AppDir, "extra", io_lib:format("~ts_extra.erl", [Name])]),
  112. ExtraSrc),
  113. [{app_names, [Name]}, {vsns, [Vsn]}|NewConfig];
  114. init_per_group(Group, Config) when Group == release_srcdirs; Group == release_extras ->
  115. NewConfig = rebar_test_utils:init_rebar_state(Config, "release_srcdirs_"),
  116. AppDir = ?config(apps, NewConfig),
  117. Name1 = rebar_test_utils:create_random_name("relapp1_"),
  118. Vsn1 = rebar_test_utils:create_random_vsn(),
  119. rebar_test_utils:create_app(filename:join([AppDir, "apps", Name1]), Name1, Vsn1, [kernel, stdlib]),
  120. Name2 = rebar_test_utils:create_random_name("relapp2_"),
  121. Vsn2 = rebar_test_utils:create_random_vsn(),
  122. rebar_test_utils:create_app(filename:join([AppDir, "apps", Name2]), Name2, Vsn2, [kernel, stdlib]),
  123. ExtraOne = io_lib:format("-module(~ts_extra).\n-export([ok/0]).\nok() -> ok.\n", [Name1]),
  124. ok = filelib:ensure_dir(filename:join([AppDir, "apps", Name1, "extra", "dummy"])),
  125. ok = file:write_file(filename:join([AppDir, "apps", Name1, "extra",
  126. io_lib:format("~ts_extra.erl", [Name1])]),
  127. ExtraOne),
  128. ExtraTwo = io_lib:format("-module(~ts_extra).\n-export([ok/0]).\nok() -> ok.\n", [Name2]),
  129. ok = filelib:ensure_dir(filename:join([AppDir, "apps", Name2, "extra", "dummy"])),
  130. ok = file:write_file(filename:join([AppDir, "apps", Name2, "extra",
  131. io_lib:format("~ts_extra.erl", [Name2])]),
  132. ExtraTwo),
  133. [{app_names, [Name1, Name2]}, {vsns, [Vsn1, Vsn2]}|NewConfig];
  134. init_per_group(Group, Config) when Group == unbalanced_srcdirs; Group == unbalanced_extras ->
  135. NewConfig = rebar_test_utils:init_rebar_state(Config, "unbalanced_srcdirs_"),
  136. AppDir = ?config(apps, NewConfig),
  137. Name1 = rebar_test_utils:create_random_name("relapp1_"),
  138. Vsn1 = rebar_test_utils:create_random_vsn(),
  139. rebar_test_utils:create_app(filename:join([AppDir, "apps", Name1]), Name1, Vsn1, [kernel, stdlib]),
  140. Name2 = rebar_test_utils:create_random_name("relapp2_"),
  141. Vsn2 = rebar_test_utils:create_random_vsn(),
  142. rebar_test_utils:create_app(filename:join([AppDir, "apps", Name2]), Name2, Vsn2, [kernel, stdlib]),
  143. ExtraOne = io_lib:format("-module(~ts_extra).\n-export([ok/0]).\nok() -> ok.\n", [Name1]),
  144. ok = filelib:ensure_dir(filename:join([AppDir, "apps", Name1, "extra", "dummy"])),
  145. ok = file:write_file(filename:join([AppDir, "apps", Name1, "extra",
  146. io_lib:format("~ts_extra.erl", [Name1])]),
  147. ExtraOne),
  148. [{app_names, [Name1, Name2]}, {vsns, [Vsn1, Vsn2]}|NewConfig];
  149. init_per_group(root_extras, Config) ->
  150. NewConfig = rebar_test_utils:init_rebar_state(Config, "root_extras_"),
  151. AppDir = ?config(apps, NewConfig),
  152. Name1 = rebar_test_utils:create_random_name("relapp1_"),
  153. Vsn1 = rebar_test_utils:create_random_vsn(),
  154. rebar_test_utils:create_app(filename:join([AppDir, "apps", Name1]), Name1, Vsn1, [kernel, stdlib]),
  155. Name2 = rebar_test_utils:create_random_name("relapp2_"),
  156. Vsn2 = rebar_test_utils:create_random_vsn(),
  157. rebar_test_utils:create_app(filename:join([AppDir, "apps", Name2]), Name2, Vsn2, [kernel, stdlib]),
  158. Extra = <<"-module(extra).\n-export([ok/0]).\nok() -> ok.\n">>,
  159. ok = filelib:ensure_dir(filename:join([AppDir, "extra", "dummy"])),
  160. ok = file:write_file(filename:join([AppDir, "extra", "extra.erl"]), Extra),
  161. [{app_names, [Name1, Name2]}, {vsns, [Vsn1, Vsn2]}|NewConfig].
  162. end_per_group(_Group, _Config) ->
  163. ok.
  164. init_per_suite(Config) ->
  165. Config.
  166. end_per_suite(_Config) ->
  167. ok.
  168. init_per_testcase(Test, Config) when
  169. Test == dont_recompile_when_erl_compiler_options_env_does_not_change
  170. orelse
  171. Test == recompile_when_erl_compiler_options_env_changes ->
  172. _ = code:ensure_loaded(os),
  173. UnSetEnv = erlang:function_exported(os, unsetenv, 1),
  174. _ = code:ensure_loaded(compile),
  175. EnvOpts = erlang:function_exported(compile, env_compiler_options, 0),
  176. case {UnSetEnv, EnvOpts} of
  177. {true, true} -> maybe_init_config(Config);
  178. _ -> {skip, "compile:env_compiler_options/0 unavailable"}
  179. end;
  180. init_per_testcase(always_recompile_when_erl_compiler_options_set, Config) ->
  181. _ = code:ensure_loaded(os),
  182. UnSetEnv = erlang:function_exported(os, unsetenv, 1),
  183. _ = code:ensure_loaded(compile),
  184. EnvOpts = erlang:function_exported(compile, env_compiler_options, 0),
  185. case {UnSetEnv, EnvOpts} of
  186. {true, true} -> {skip, "compile:env_compiler_options/0 available"};
  187. {true, false} -> maybe_init_config(Config);
  188. _ -> {skip, "os:unsetenv/1 unavailable"}
  189. end;
  190. init_per_testcase(_, Config) -> maybe_init_config(Config).
  191. maybe_init_config(Config) ->
  192. case ?config(apps, Config) of
  193. undefined -> rebar_test_utils:init_rebar_state(Config);
  194. _ -> Config
  195. end.
  196. end_per_testcase(_, _Config) ->
  197. catch meck:unload().
  198. %% test cases
  199. build_basic_app(Config) ->
  200. [Name] = ?config(app_names, Config),
  201. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}).
  202. build_release_apps(Config) ->
  203. [Name1, Name2] = ?config(app_names, Config),
  204. rebar_test_utils:run_and_check(
  205. Config, [], ["compile"],
  206. {ok, [{app, Name1}, {app, Name2}]}
  207. ).
  208. build_checkout_apps(Config) ->
  209. [Name1, Name2] = ?config(app_names, Config),
  210. rebar_test_utils:run_and_check(
  211. Config, [], ["compile"],
  212. {ok, [{app, Name1}, {checkout, Name2}]}
  213. ).
  214. build_checkout_deps(Config) ->
  215. AppDir = ?config(apps, Config),
  216. [Name1, Name2] = ?config(app_names, Config),
  217. [_, Vsn2] = ?config(vsns, Config),
  218. Deps = [{list_to_atom(Name2), Vsn2, {git, "", ""}}],
  219. {ok, RebarConfig} = file:consult(rebar_test_utils:create_config(AppDir, [{deps, Deps}])),
  220. rebar_test_utils:run_and_check(
  221. Config, RebarConfig, ["compile"],
  222. {ok, [{app, Name1}, {checkout, Name2}]}
  223. ).
  224. build_basic_srcdirs(Config) ->
  225. AppDir = ?config(apps, Config),
  226. [Name] = ?config(app_names, Config),
  227. RebarConfig = [{erl_opts, [{src_dirs, ["src", "extra"]}]}],
  228. %% check a beam corresponding to the src in the extra src_dir exists
  229. ExtraBeam = filename:join([AppDir, "_build", "default", "lib", Name, "ebin",
  230. io_lib:format("~ts_extra.beam", [Name])]),
  231. %% check the extra src_dir was copied/linked into the _build dir
  232. ExtraDir = filename:join([AppDir, "_build", "default", "lib", Name, "extra"]),
  233. rebar_test_utils:run_and_check(
  234. Config, RebarConfig, ["compile"],
  235. {ok, [{app, Name}, {file, ExtraBeam}, {dir, ExtraDir}]}
  236. ).
  237. build_release_srcdirs(Config) ->
  238. AppDir = ?config(apps, Config),
  239. [Name1, Name2] = ?config(app_names, Config),
  240. RebarConfig = [{erl_opts, [{src_dirs, ["src", "extra"]}]}],
  241. %% check a beam corresponding to the src in the extra src_dir exists
  242. Extra1Beam = filename:join([AppDir, "_build", "default", "lib", Name1, "ebin",
  243. io_lib:format("~ts_extra.beam", [Name1])]),
  244. Extra2Beam = filename:join([AppDir, "_build", "default", "lib", Name2, "ebin",
  245. io_lib:format("~ts_extra.beam", [Name2])]),
  246. %% check the extra src_dir was copied/linked into the _build dir
  247. Extra1Dir = filename:join([AppDir, "_build", "default", "lib", Name1, "extra"]),
  248. Extra2Dir = filename:join([AppDir, "_build", "default", "lib", Name2, "extra"]),
  249. rebar_test_utils:run_and_check(
  250. Config, RebarConfig, ["compile"],
  251. {ok, [{app, Name1}, {app, Name2},
  252. {file, Extra1Beam}, {file, Extra2Beam},
  253. {dir, Extra1Dir}, {dir, Extra2Dir}]}
  254. ).
  255. build_unbalanced_srcdirs(Config) ->
  256. AppDir = ?config(apps, Config),
  257. [Name1, Name2] = ?config(app_names, Config),
  258. RebarConfig = [{erl_opts, [{src_dirs, ["src", "extra"]}]}],
  259. %% check a beam corresponding to the src in the extra src_dir exists
  260. Extra1Beam = filename:join([AppDir, "_build", "default", "lib", Name1, "ebin",
  261. io_lib:format("~ts_extra.beam", [Name1])]),
  262. %% check the extra src_dir was copied/linked into the _build dir
  263. Extra1Dir = filename:join([AppDir, "_build", "default", "lib", Name1, "extra"]),
  264. rebar_test_utils:run_and_check(
  265. Config, RebarConfig, ["compile"],
  266. {ok, [{app, Name1}, {app, Name2}, {file, Extra1Beam}, {dir, Extra1Dir}]}
  267. ),
  268. %% check no extra src_dir were copied/linked into the _build dir
  269. Extra2Dir = filename:join([AppDir, "_build", "default", "lib", Name2, "extra"]),
  270. false = filelib:is_dir(Extra2Dir),
  271. %% check only expected beams are in the ebin dir
  272. {ok, Files} = rebar_utils:list_dir(filename:join([AppDir, "_build", "default", "lib", Name2, "ebin"])),
  273. lists:all(fun(Beam) -> lists:member(Beam, [Name2 ++ ".app", "not_a_real_src_" ++ Name2 ++ ".beam"]) end,
  274. Files).
  275. build_basic_extra_dirs(Config) ->
  276. AppDir = ?config(apps, Config),
  277. [Name] = ?config(app_names, Config),
  278. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  279. %% check a beam corresponding to the src in the extra src_dir exists
  280. ExtraBeam = filename:join([AppDir, "_build", "default", "lib", Name, "extra",
  281. io_lib:format("~ts_extra.beam", [Name])]),
  282. rebar_test_utils:run_and_check(
  283. Config, RebarConfig, ["compile"],
  284. {ok, [{app, Name}, {file, ExtraBeam}]}
  285. ).
  286. build_release_extra_dirs(Config) ->
  287. AppDir = ?config(apps, Config),
  288. [Name1, Name2] = ?config(app_names, Config),
  289. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  290. %% check a beam corresponding to the src in the extra src_dir exists
  291. Extra1Beam = filename:join([AppDir, "_build", "default", "lib", Name1, "extra",
  292. io_lib:format("~ts_extra.beam", [Name1])]),
  293. Extra2Beam = filename:join([AppDir, "_build", "default", "lib", Name2, "extra",
  294. io_lib:format("~ts_extra.beam", [Name2])]),
  295. rebar_test_utils:run_and_check(
  296. Config, RebarConfig, ["compile"],
  297. {ok, [{app, Name1}, {app, Name2}, {file, Extra1Beam}, {file, Extra2Beam}]}
  298. ).
  299. build_unbalanced_extra_dirs(Config) ->
  300. AppDir = ?config(apps, Config),
  301. [Name1, Name2] = ?config(app_names, Config),
  302. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  303. %% check a beam corresponding to the src in the extra src_dir exists
  304. Extra1Beam = filename:join([AppDir, "_build", "default", "lib", Name1, "extra",
  305. io_lib:format("~ts_extra.beam", [Name1])]),
  306. rebar_test_utils:run_and_check(
  307. Config, RebarConfig, ["compile"],
  308. {ok, [{app, Name1}, {app, Name2}, {file, Extra1Beam}]}
  309. ),
  310. %% check no extra src_dir were copied/linked into the _build dir
  311. false = filelib:is_dir(filename:join([AppDir, "_build", "default", "lib", Name2, "extra"])),
  312. %% check only expected beams are in the ebin dir
  313. {ok, Files} = rebar_utils:list_dir(filename:join([AppDir, "_build", "default", "lib", Name2, "ebin"])),
  314. lists:all(fun(Beam) -> lists:member(Beam, [Name2 ++ ".app", "not_a_real_src_" ++ Name2 ++ ".beam"]) end,
  315. Files).
  316. build_extra_dirs_in_project_root(Config) ->
  317. AppDir = ?config(apps, Config),
  318. [Name1, Name2] = ?config(app_names, Config),
  319. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  320. %% check a beam corresponding to the src in the extra src_dir exists
  321. ExtraBeam = filename:join([AppDir, "_build", "default", "extras", "extra", "extra.beam"]),
  322. rebar_test_utils:run_and_check(
  323. Config, RebarConfig, ["compile"],
  324. {ok, [{app, Name1}, {app, Name2}, {file, ExtraBeam}]}
  325. ).
  326. paths_basic_app(Config) ->
  327. [Name] = ?config(app_names, Config),
  328. [Vsn] = ?config(vsns, Config),
  329. {ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return),
  330. code:add_paths(rebar_state:code_paths(State, all_deps)),
  331. ok = application:load(list_to_atom(Name)),
  332. Loaded = application:loaded_applications(),
  333. {_, _, Vsn} = lists:keyfind(list_to_atom(Name), 1, Loaded).
  334. paths_release_apps(Config) ->
  335. [Name1, Name2] = ?config(app_names, Config),
  336. [Vsn1, Vsn2] = ?config(vsns, Config),
  337. {ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return),
  338. code:add_paths(rebar_state:code_paths(State, all_deps)),
  339. ok = application:load(list_to_atom(Name1)),
  340. ok = application:load(list_to_atom(Name2)),
  341. Loaded = application:loaded_applications(),
  342. {_, _, Vsn1} = lists:keyfind(list_to_atom(Name1), 1, Loaded),
  343. {_, _, Vsn2} = lists:keyfind(list_to_atom(Name2), 1, Loaded).
  344. paths_checkout_apps(Config) ->
  345. [Name1, _Name2] = ?config(app_names, Config),
  346. [Vsn1, _Vsn2] = ?config(vsns, Config),
  347. {ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return),
  348. code:add_paths(rebar_state:code_paths(State, all_deps)),
  349. ok = application:load(list_to_atom(Name1)),
  350. Loaded = application:loaded_applications(),
  351. {_, _, Vsn1} = lists:keyfind(list_to_atom(Name1), 1, Loaded).
  352. paths_checkout_deps(Config) ->
  353. AppDir = ?config(apps, Config),
  354. [_Name1, Name2] = ?config(app_names, Config),
  355. [_Vsn1, Vsn2] = ?config(vsns, Config),
  356. %% rebar_test_utils:init_rebar_state/1,2 uses rebar_state:new/3 which
  357. %% maybe incorrectly sets deps to [] (based on `rebar.lock`) instead of
  358. %% to the checkapps
  359. %% until that is sorted out the lock file has to be removed before
  360. %% this test will pass
  361. file:delete(filename:join([AppDir, "rebar.lock"])),
  362. {ok, RebarConfig} = file:consult(filename:join([AppDir, "rebar.config"])),
  363. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  364. code:add_paths(rebar_state:code_paths(State, all_deps)),
  365. ok = application:load(list_to_atom(Name2)),
  366. Loaded = application:loaded_applications(),
  367. {_, _, Vsn2} = lists:keyfind(list_to_atom(Name2), 1, Loaded).
  368. paths_basic_srcdirs(Config) ->
  369. AppDir = ?config(apps, Config),
  370. [Name] = ?config(app_names, Config),
  371. RebarConfig = [{erl_opts, [{src_dirs, ["src", "extra"]}]}],
  372. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  373. code:add_paths(rebar_state:code_paths(State, all_deps)),
  374. Mod = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name]))),
  375. {module, Mod} = code:ensure_loaded(Mod),
  376. Expect = filename:join([AppDir, "_build", "default", "lib", Name, "ebin",
  377. io_lib:format("~ts_extra.beam", [Name])]),
  378. Expect = code:which(Mod).
  379. paths_release_srcdirs(Config) ->
  380. AppDir = ?config(apps, Config),
  381. [Name1, Name2] = ?config(app_names, Config),
  382. RebarConfig = [{erl_opts, [{src_dirs, ["src", "extra"]}]}],
  383. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  384. code:add_paths(rebar_state:code_paths(State, all_deps)),
  385. Mod1 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name1]))),
  386. {module, Mod1} = code:ensure_loaded(Mod1),
  387. Mod2 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name2]))),
  388. {module, Mod2} = code:ensure_loaded(Mod2),
  389. ExpectOne = filename:join([AppDir, "_build", "default", "lib", Name1, "ebin",
  390. io_lib:format("~ts_extra.beam", [Name1])]),
  391. ExpectOne = code:which(Mod1),
  392. ExpectTwo = filename:join([AppDir, "_build", "default", "lib", Name2, "ebin",
  393. io_lib:format("~ts_extra.beam", [Name2])]),
  394. ExpectTwo = code:which(Mod2).
  395. paths_unbalanced_srcdirs(Config) ->
  396. AppDir = ?config(apps, Config),
  397. [Name1, Name2] = ?config(app_names, Config),
  398. RebarConfig = [{erl_opts, [{src_dirs, ["src", "extra"]}]}],
  399. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  400. code:add_paths(rebar_state:code_paths(State, all_deps)),
  401. Mod1 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name1]))),
  402. {module, Mod1} = code:ensure_loaded(Mod1),
  403. Mod2 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name2]))),
  404. {error, nofile} = code:ensure_loaded(Mod2),
  405. ExpectOne = filename:join([AppDir, "_build", "default", "lib", Name1, "ebin",
  406. io_lib:format("~ts_extra.beam", [Name1])]),
  407. ExpectOne = code:which(Mod1).
  408. paths_basic_extra_dirs(Config) ->
  409. AppDir = ?config(apps, Config),
  410. [Name] = ?config(app_names, Config),
  411. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  412. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  413. code:add_paths(rebar_state:code_paths(State, all_deps)),
  414. Mod = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name]))),
  415. {module, Mod} = code:ensure_loaded(Mod),
  416. Expect = filename:join([AppDir, "_build", "default", "lib", Name, "extra",
  417. io_lib:format("~ts_extra.beam", [Name])]),
  418. Expect = code:which(Mod).
  419. paths_release_extra_dirs(Config) ->
  420. AppDir = ?config(apps, Config),
  421. [Name1, Name2] = ?config(app_names, Config),
  422. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  423. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  424. code:add_paths(rebar_state:code_paths(State, all_deps)),
  425. Mod1 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name1]))),
  426. {module, Mod1} = code:ensure_loaded(Mod1),
  427. Mod2 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name2]))),
  428. {module, Mod2} = code:ensure_loaded(Mod2),
  429. ExpectOne = filename:join([AppDir, "_build", "default", "lib", Name1, "extra",
  430. io_lib:format("~ts_extra.beam", [Name1])]),
  431. ExpectOne = code:which(Mod1),
  432. ExpectTwo = filename:join([AppDir, "_build", "default", "lib", Name2, "extra",
  433. io_lib:format("~ts_extra.beam", [Name2])]),
  434. ExpectTwo = code:which(Mod2).
  435. paths_unbalanced_extra_dirs(Config) ->
  436. AppDir = ?config(apps, Config),
  437. [Name1, Name2] = ?config(app_names, Config),
  438. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  439. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  440. code:add_paths(rebar_state:code_paths(State, all_deps)),
  441. Mod1 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name1]))),
  442. {module, Mod1} = code:ensure_loaded(Mod1),
  443. Mod2 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name2]))),
  444. {error, nofile} = code:ensure_loaded(Mod2),
  445. ExpectOne = filename:join([AppDir, "_build", "default", "lib", Name1, "extra",
  446. io_lib:format("~ts_extra.beam", [Name1])]),
  447. ExpectOne = code:which(Mod1).
  448. paths_extra_dirs_in_project_root(Config) ->
  449. AppDir = ?config(apps, Config),
  450. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  451. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  452. code:add_paths(rebar_state:code_paths(State, all_deps)),
  453. {module, extra} = code:ensure_loaded(extra),
  454. Expect = filename:join([AppDir, "_build", "default", "extras", "extra", "extra.beam"]),
  455. Expect = code:which(extra).
  456. clean_basic_app(Config) ->
  457. [Name] = ?config(app_names, Config),
  458. rebar_test_utils:run_and_check(Config, [], ["clean"], {ok, [{app, Name, invalid}]}).
  459. clean_release_apps(Config) ->
  460. [Name1, Name2] = ?config(app_names, Config),
  461. rebar_test_utils:run_and_check(Config, [], ["clean"],
  462. {ok, [{app, Name1, invalid}, {app, Name2, invalid}]}).
  463. clean_basic_extra_dirs(Config) ->
  464. AppDir = ?config(apps, Config),
  465. [Name] = ?config(app_names, Config),
  466. rebar_test_utils:run_and_check(Config, [], ["clean"], {ok, [{app, Name, invalid}]}),
  467. Beam = lists:flatten(io_lib:format("~ts_extra", [Name])),
  468. false = ec_file:exists(filename:join([AppDir, "_build", "default", "lib", Name, "extras", Beam])).
  469. clean_release_extra_dirs(Config) ->
  470. AppDir = ?config(apps, Config),
  471. [Name1, Name2] = ?config(app_names, Config),
  472. rebar_test_utils:run_and_check(Config, [], ["clean"],
  473. {ok, [{app, Name1, invalid}, {app, Name2, invalid}]}),
  474. Beam1 = lists:flatten(io_lib:format("~ts_extra", [Name1])),
  475. false = ec_file:exists(filename:join([AppDir, "_build", "default", "lib", Name1, "extras", Beam1])),
  476. Beam2 = lists:flatten(io_lib:format("~ts_extra", [Name2])),
  477. false = ec_file:exists(filename:join([AppDir, "_build", "default", "lib", Name2, "extras", Beam2])).
  478. clean_extra_dirs_in_project_root(Config) ->
  479. AppDir = ?config(apps, Config),
  480. [Name1, Name2] = ?config(app_names, Config),
  481. rebar_test_utils:run_and_check(Config, [], ["clean"],
  482. {ok, [{app, Name1, invalid}, {app, Name2, invalid}]}),
  483. false = ec_file:exists(filename:join([AppDir, "_build", "default", "extras"])).
  484. recompile_when_hrl_changes(Config) ->
  485. AppDir = ?config(apps, Config),
  486. Name = rebar_test_utils:create_random_name("app1_"),
  487. Vsn = rebar_test_utils:create_random_vsn(),
  488. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  489. ExtraSrc = <<"-module(test_header_include).\n"
  490. "-export([main/0]).\n"
  491. "-include(\"test_header_include.hrl\").\n"
  492. "main() -> ?SOME_DEFINE.\n">>,
  493. ExtraHeader = <<"-define(SOME_DEFINE, true).\n">>,
  494. HeaderFile = filename:join([AppDir, "src", "test_header_include.hrl"]),
  495. ok = file:write_file(filename:join([AppDir, "src", "test_header_include.erl"]), ExtraSrc),
  496. ok = file:write_file(HeaderFile, ExtraHeader),
  497. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  498. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  499. {ok, Files} = rebar_utils:list_dir(EbinDir),
  500. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  501. || F <- Files, filename:extension(F) == ".beam"],
  502. timer:sleep(1000),
  503. NewExtraHeader = <<"-define(SOME_DEFINE, false).\n">>,
  504. ok = file:write_file(HeaderFile, NewExtraHeader),
  505. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  506. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  507. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  508. || F <- NewFiles, filename:extension(F) == ".beam"],
  509. ?assert(ModTime =/= NewModTime).
  510. recompile_when_included_hrl_changes(Config) ->
  511. AppDir = ?config(apps, Config),
  512. Name = rebar_test_utils:create_random_name("app1_"),
  513. Vsn = rebar_test_utils:create_random_vsn(),
  514. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  515. ExtraSrc = <<"-module(test_header_include).\n"
  516. "-export([main/0]).\n"
  517. "-include(\"test_header_include.hrl\").\n"
  518. "main() -> ?SOME_DEFINE.\n">>,
  519. ExtraHeader = <<"-define(SOME_DEFINE, true).\n">>,
  520. ok = filelib:ensure_dir(filename:join([AppDir, "include", "dummy"])),
  521. HeaderFile = filename:join([AppDir, "include", "test_header_include.hrl"]),
  522. ok = file:write_file(filename:join([AppDir, "src", "test_header_include.erl"]), ExtraSrc),
  523. ok = file:write_file(HeaderFile, ExtraHeader),
  524. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  525. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  526. {ok, Files} = rebar_utils:list_dir(EbinDir),
  527. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  528. || F <- Files, filename:extension(F) == ".beam"],
  529. timer:sleep(1000),
  530. NewExtraHeader = <<"-define(SOME_DEFINE, false).\n">>,
  531. ok = file:write_file(HeaderFile, NewExtraHeader),
  532. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  533. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  534. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  535. || F <- NewFiles, filename:extension(F) == ".beam"],
  536. ?assert(ModTime =/= NewModTime).
  537. recompile_extra_when_hrl_in_src_changes(Config) ->
  538. AppDir = ?config(apps, Config),
  539. Name = rebar_test_utils:create_random_name("app1_"),
  540. Vsn = rebar_test_utils:create_random_vsn(),
  541. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  542. ExtraSrc = <<"-module(test_header_include).\n"
  543. "-export([main/0]).\n"
  544. "-include(\"test_header_include.hrl\").\n"
  545. "main() -> ?SOME_DEFINE.\n">>,
  546. ExtraHeader = <<"-define(SOME_DEFINE, true).\n">>,
  547. HeaderFile = filename:join([AppDir, "src", "test_header_include.hrl"]),
  548. SrcFile = filename:join([AppDir, "extra", "test_header_include.erl"]),
  549. filelib:ensure_dir(SrcFile),
  550. ok = file:write_file(SrcFile, ExtraSrc),
  551. ok = file:write_file(HeaderFile, ExtraHeader),
  552. RebarCfg = [{extra_src_dirs, ["extra"]}],
  553. rebar_test_utils:run_and_check(Config, RebarCfg, ["compile"],
  554. {ok, [{app, Name}]}),
  555. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "extra"]),
  556. {ok, Files} = rebar_utils:list_dir(EbinDir),
  557. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  558. || F <- Files, filename:extension(F) == ".beam"],
  559. timer:sleep(1000),
  560. NewExtraHeader = <<"-define(SOME_DEFINE, false).\n">>,
  561. ok = file:write_file(HeaderFile, NewExtraHeader, [sync]),
  562. rebar_test_utils:run_and_check(Config, RebarCfg, ["compile"],
  563. {ok, [{app, Name}]}),
  564. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  565. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  566. || F <- NewFiles, filename:extension(F) == ".beam"],
  567. ?assert(ModTime =/= NewModTime).
  568. recompile_when_opts_included_hrl_changes(Config) ->
  569. AppsDir = ?config(apps, Config),
  570. Name = rebar_test_utils:create_random_name("app1_"),
  571. Vsn = rebar_test_utils:create_random_vsn(),
  572. AppDir = filename:join([AppsDir, "apps", Name]),
  573. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  574. ExtraSrc = <<"-module(test_header_include).\n"
  575. "-export([main/0]).\n"
  576. "-include(\"test_header_include.hrl\").\n"
  577. "main() -> ?SOME_DEFINE.\n">>,
  578. ExtraHeader = <<"-define(SOME_DEFINE, true).\n">>,
  579. ok = filelib:ensure_dir(filename:join([AppsDir, "include", "dummy"])),
  580. HeaderFile = filename:join([AppsDir, "include", "test_header_include.hrl"]),
  581. ok = file:write_file(filename:join([AppDir, "src", "test_header_include.erl"]), ExtraSrc),
  582. ok = file:write_file(HeaderFile, ExtraHeader),
  583. %% Using relative path from the project root
  584. RebarConfig = [{erl_opts, [{i, "include/"}]}],
  585. {ok,Cwd} = file:get_cwd(),
  586. ok = file:set_cwd(AppsDir),
  587. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  588. EbinDir = filename:join([AppsDir, "_build", "default", "lib", Name, "ebin"]),
  589. {ok, Files} = rebar_utils:list_dir(EbinDir),
  590. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  591. || F <- Files, filename:extension(F) == ".beam"],
  592. timer:sleep(1000),
  593. NewExtraHeader = <<"-define(SOME_DEFINE, false).\n">>,
  594. ok = file:write_file(HeaderFile, NewExtraHeader),
  595. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  596. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  597. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  598. || F <- NewFiles, filename:extension(F) == ".beam"],
  599. ok = file:set_cwd(Cwd),
  600. ?assert(ModTime =/= NewModTime).
  601. recompile_when_opts_change(Config) ->
  602. AppDir = ?config(apps, Config),
  603. Name = rebar_test_utils:create_random_name("app1_"),
  604. Vsn = rebar_test_utils:create_random_vsn(),
  605. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  606. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  607. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  608. {ok, Files} = rebar_utils:list_dir(EbinDir),
  609. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  610. || F <- Files, filename:extension(F) == ".beam"],
  611. timer:sleep(1000),
  612. rebar_test_utils:create_config(AppDir, [{erl_opts, [{d, some_define}]}]),
  613. rebar_test_utils:run_and_check(Config, [{erl_opts, [{d, some_define}]}], ["compile"], {ok, [{app, Name}]}),
  614. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  615. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  616. || F <- NewFiles, filename:extension(F) == ".beam"],
  617. ?assert(ModTime =/= NewModTime).
  618. dont_recompile_when_opts_dont_change(Config) ->
  619. AppDir = ?config(apps, Config),
  620. Name = rebar_test_utils:create_random_name("app1_"),
  621. Vsn = rebar_test_utils:create_random_vsn(),
  622. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  623. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  624. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  625. {ok, Files} = rebar_utils:list_dir(EbinDir),
  626. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  627. || F <- Files, filename:extension(F) == ".beam"],
  628. timer:sleep(1000),
  629. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  630. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  631. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  632. || F <- NewFiles, filename:extension(F) == ".beam"],
  633. ?assertEqual(ModTime, NewModTime).
  634. dont_recompile_yrl_or_xrl(Config) ->
  635. AppDir = ?config(apps, Config),
  636. Name = rebar_test_utils:create_random_name("app1_"),
  637. Vsn = rebar_test_utils:create_random_vsn(),
  638. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  639. Xrl = filename:join([AppDir, "src", "not_a_real_xrl_" ++ Name ++ ".xrl"]),
  640. ok = filelib:ensure_dir(Xrl),
  641. XrlBody =
  642. "Definitions."
  643. "\n\n"
  644. "D = [0-9]"
  645. "\n\n"
  646. "Rules."
  647. "\n\n"
  648. "{D}+ :"
  649. " {token,{integer,TokenLine,list_to_integer(TokenChars)}}."
  650. "\n\n"
  651. "{D}+\\.{D}+((E|e)(\\+|\\-)?{D}+)? :"
  652. " {token,{float,TokenLine,list_to_float(TokenChars)}}."
  653. "\n\n"
  654. "Erlang code.",
  655. ok = ec_file:write(Xrl, XrlBody),
  656. Yrl = filename:join([AppDir, "src", "not_a_real_yrl_" ++ Name ++ ".yrl"]),
  657. ok = filelib:ensure_dir(Yrl),
  658. YrlBody = ["Nonterminals E T F.\n"
  659. "Terminals '+' '*' '(' ')' number.\n"
  660. "Rootsymbol E.\n"
  661. "E -> E '+' T: {'$2', '$1', '$3'}.\n"
  662. "E -> T : '$1'.\n"
  663. "T -> T '*' F: {'$2', '$1', '$3'}.\n"
  664. "T -> F : '$1'.\n"
  665. "F -> '(' E ')' : '$2'.\n"
  666. "F -> number : '$1'.\n"],
  667. ok = ec_file:write(Yrl, YrlBody),
  668. XrlErl = filename:join([AppDir, "src", filename:basename(Xrl, ".xrl") ++ ".erl"]),
  669. YrlErl = filename:join([AppDir, "src", filename:basename(Yrl, ".yrl") ++ ".erl"]),
  670. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  671. XrlBeam = filename:join([EbinDir, filename:basename(Xrl, ".xrl") ++ ".beam"]),
  672. YrlBeam = filename:join([EbinDir, filename:basename(Yrl, ".yrl") ++ ".beam"]),
  673. Hrl = filename:join([AppDir, "include", "some_header.hrl"]),
  674. ok = filelib:ensure_dir(Hrl),
  675. HrlBody = yeccpre_hrl(),
  676. ok = ec_file:write(Hrl, HrlBody),
  677. RebarConfig = [{yrl_opts, [{includefile, "include/some_header.hrl"}]}],
  678. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  679. XrlModTime = filelib:last_modified(XrlErl),
  680. YrlModTime = filelib:last_modified(YrlErl),
  681. XrlBeamModTime = filelib:last_modified(XrlBeam),
  682. YrlBeamModTime = filelib:last_modified(YrlBeam),
  683. timer:sleep(1000),
  684. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  685. NewXrlModTime = filelib:last_modified(XrlErl),
  686. NewYrlModTime = filelib:last_modified(YrlErl),
  687. NewXrlBeamModTime = filelib:last_modified(XrlBeam),
  688. NewYrlBeamModTime = filelib:last_modified(YrlBeam),
  689. ?assert(XrlBeamModTime == NewXrlBeamModTime),
  690. ?assert(YrlBeamModTime == NewYrlBeamModTime),
  691. ?assert(XrlModTime == NewXrlModTime),
  692. ?assert(YrlModTime == NewYrlModTime).
  693. delete_beam_if_source_deleted(Config) ->
  694. AppDir = ?config(apps, Config),
  695. Name = rebar_test_utils:create_random_name("app1_"),
  696. Vsn = rebar_test_utils:create_random_vsn(),
  697. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  698. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  699. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  700. _SrcDir = filename:join([AppDir, "_build", "default", "lib", Name, "src"]),
  701. ?assert(filelib:is_regular(filename:join(EbinDir, "not_a_real_src_" ++ Name ++ ".beam"))),
  702. file:delete(filename:join([AppDir, "src", "not_a_real_src_" ++ Name ++ ".erl"])),
  703. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  704. ?assertNot(filelib:is_regular(filename:join(EbinDir, "not_a_real_src_" ++ Name ++ ".beam"))).
  705. deps_in_path(Config) ->
  706. AppDir = ?config(apps, Config),
  707. StartPaths = code:get_path(),
  708. Name = rebar_test_utils:create_random_name("app1_"),
  709. Vsn = rebar_test_utils:create_random_vsn(),
  710. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  711. DepName = rebar_test_utils:create_random_name("dep1_"),
  712. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  713. mock_git_resource:mock([]),
  714. mock_pkg_resource:mock([
  715. {pkgdeps, [{{iolist_to_binary(PkgName), iolist_to_binary(Vsn)}, []}]}
  716. ]),
  717. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [
  718. {list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}},
  719. {list_to_atom(PkgName), Vsn}
  720. ]}]),
  721. {ok, RConf} = file:consult(RConfFile),
  722. %% Make sure apps we look for are not visible
  723. %% Hope not to find src name
  724. ?assertEqual([], [Path || Path <- code:get_path(),
  725. {match, _} <- [re:run(Path, DepName)]]),
  726. %% Hope not to find pkg name in there
  727. ?assertEqual([], [Path || Path <- code:get_path(),
  728. {match, _} <- [re:run(Path, PkgName)]]),
  729. %% Build things
  730. {ok, State} = rebar_test_utils:run_and_check(
  731. Config, RConf, ["compile"],
  732. {ok, [{app, Name}, {dep, DepName}, {dep, PkgName}]}
  733. ),
  734. code:add_paths(rebar_state:code_paths(State, all_deps)),
  735. %% Find src name in there
  736. ?assertNotEqual([], [Path || Path <- code:get_path(),
  737. {match, _} <- [re:run(Path, DepName)]]),
  738. %% find pkg name in there
  739. ?assertNotEqual([], [Path || Path <- code:get_path(),
  740. {match, _} <- [re:run(Path, PkgName)]]),
  741. true = code:set_path(lists:filter(fun(P) -> ec_file:exists(P) end, StartPaths)),
  742. %% Make sure apps we look for are not visible again
  743. %% Hope not to find src name
  744. ?assertEqual([], [Path || Path <- code:get_path(),
  745. {match, _} <- [re:run(Path, DepName)]]),
  746. %% Hope not to find pkg name in there
  747. ?assertEqual([], [Path || Path <- code:get_path(),
  748. {match, _} <- [re:run(Path, PkgName)]]),
  749. %% Rebuild
  750. {ok, State1} = rebar_test_utils:run_and_check(
  751. Config, RConf, ["compile"],
  752. {ok, [{app, Name}, {dep, DepName}, {dep, PkgName}]}
  753. ),
  754. %% Find src name in there
  755. code:add_paths(rebar_state:code_paths(State1, all_deps)),
  756. ?assertNotEqual([], [Path || Path <- code:get_path(),
  757. {match, _} <- [re:run(Path, DepName)]]),
  758. %% find pkg name in there
  759. ?assertNotEqual([], [Path || Path <- code:get_path(),
  760. {match, _} <- [re:run(Path, PkgName)]]).
  761. checkout_priority(Config) ->
  762. AppDir = ?config(apps, Config),
  763. CheckoutsDir = ?config(checkouts, Config),
  764. StartPaths = code:get_path(),
  765. Name = rebar_test_utils:create_random_name("app1_"),
  766. Vsn = rebar_test_utils:create_random_vsn(),
  767. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  768. DepName = rebar_test_utils:create_random_name("dep1_"),
  769. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  770. mock_git_resource:mock([]),
  771. mock_pkg_resource:mock([
  772. {pkgdeps, [{{iolist_to_binary(PkgName), iolist_to_binary(Vsn)}, []}]}
  773. ]),
  774. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [
  775. {list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}},
  776. {list_to_atom(PkgName), Vsn}
  777. ]}]),
  778. {ok, RConf} = file:consult(RConfFile),
  779. %% Build with deps.
  780. rebar_test_utils:run_and_check(
  781. Config, RConf, ["compile"],
  782. {ok, [{app, Name}, {dep, DepName}, {dep, PkgName}]}
  783. ),
  784. %% Build two checkout apps similar to dependencies to be fetched,
  785. %% but on a different version
  786. Vsn2 = rebar_test_utils:create_random_vsn(),
  787. rebar_test_utils:create_app(filename:join([CheckoutsDir,DepName]), DepName, Vsn2, [kernel, stdlib]),
  788. rebar_test_utils:create_app(filename:join([CheckoutsDir,PkgName]), PkgName, Vsn2, [kernel, stdlib]),
  789. %% Rebuild and make sure the checkout apps are in path
  790. code:set_path(StartPaths),
  791. {ok, State} = rebar_test_utils:run_and_check(
  792. Config, RConf, ["compile"],
  793. {ok, [{app, Name}, {checkout, DepName}, {checkout, PkgName}]}
  794. ),
  795. code:add_paths(rebar_state:code_paths(State, all_deps)),
  796. [DepPath] = [Path || Path <- code:get_path(),
  797. {match, _} <- [re:run(Path, DepName)]],
  798. [PkgPath] = [Path || Path <- code:get_path(),
  799. {match, _} <- [re:run(Path, PkgName)]],
  800. {ok, [DepApp]} = file:consult(filename:join([DepPath, DepName ++ ".app"])),
  801. {ok, [PkgApp]} = file:consult(filename:join([PkgPath, PkgName ++ ".app"])),
  802. {application, _, DepProps} = DepApp,
  803. {application, _, PkgProps} = PkgApp,
  804. ?assertEqual(Vsn2, proplists:get_value(vsn, DepProps)),
  805. ?assertEqual(Vsn2, proplists:get_value(vsn, PkgProps)).
  806. highest_version_of_pkg_dep(Config) ->
  807. AppDir = ?config(apps, Config),
  808. Name = rebar_test_utils:create_random_name("app1_"),
  809. Vsn = rebar_test_utils:create_random_vsn(),
  810. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  811. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  812. mock_git_resource:mock([]),
  813. mock_pkg_resource:mock([
  814. {pkgdeps, [{{iolist_to_binary(PkgName), <<"0.1.0">>}, []},
  815. {{iolist_to_binary(PkgName), <<"0.0.1">>}, []},
  816. {{iolist_to_binary(PkgName), <<"0.1.3">>}, []},
  817. {{iolist_to_binary(PkgName), <<"0.1.1">>}, []}]}
  818. ]),
  819. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [list_to_atom(PkgName)]}]),
  820. {ok, RConf} = file:consult(RConfFile),
  821. %% Build with deps.
  822. rebar_test_utils:run_and_check(
  823. Config, RConf, ["compile"],
  824. {ok, [{app, Name}, {dep, PkgName, <<"0.1.3">>}]}
  825. ).
  826. parse_transform_test(Config) ->
  827. AppDir = ?config(apps, Config),
  828. RebarConfig = [{erl_opts, [{parse_transform, pascal}]}],
  829. Name = rebar_test_utils:create_random_name("app1_"),
  830. Vsn = rebar_test_utils:create_random_vsn(),
  831. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  832. ExtraSrc = <<"-module(pascal). "
  833. "-export([parse_transform/2]). "
  834. "parse_transform(Forms, _Options) -> "
  835. "Forms.">>,
  836. ok = file:write_file(filename:join([AppDir, "src", "pascal.erl"]), ExtraSrc),
  837. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  838. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  839. true = filelib:is_file(filename:join([EbinDir, "pascal.beam"])).
  840. erl_first_files_test(Config) ->
  841. AppDir = ?config(apps, Config),
  842. RebarConfig = [{erl_opts, [{parse_transform, mark_time}]},
  843. {erl_first_files, ["src/mark_time.erl",
  844. "src/b.erl",
  845. "src/d.erl",
  846. "src/a.erl"]}],
  847. Name = rebar_test_utils:create_random_name("app1_"),
  848. Vsn = rebar_test_utils:create_random_vsn(),
  849. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  850. rebar_test_utils:write_src_file(AppDir, "a.erl"),
  851. rebar_test_utils:write_src_file(AppDir, "b.erl"),
  852. rebar_test_utils:write_src_file(AppDir, "d.erl"),
  853. rebar_test_utils:write_src_file(AppDir, "e.erl"),
  854. ExtraSrc = <<"-module(mark_time). "
  855. "-export([parse_transform/2]). "
  856. "parse_transform([Form={attribute,_,module,Mod}|Forms], Options) -> "
  857. " [Form, {attribute,1,number, os:timestamp()} | Forms];"
  858. "parse_transform([Form|Forms], Options) -> "
  859. " [Form | parse_transform(Forms, Options)].">>,
  860. ok = file:write_file(filename:join([AppDir, "src", "mark_time.erl"]), ExtraSrc),
  861. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  862. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  863. true = filelib:is_file(filename:join([EbinDir, "mark_time.beam"])),
  864. code:load_abs(filename:join([EbinDir, "a"])),
  865. code:load_abs(filename:join([EbinDir, "b"])),
  866. code:load_abs(filename:join([EbinDir, "d"])),
  867. code:load_abs(filename:join([EbinDir, "e"])),
  868. A = proplists:get_value(number, a:module_info(attributes)),
  869. B = proplists:get_value(number, b:module_info(attributes)),
  870. D = proplists:get_value(number, d:module_info(attributes)),
  871. E = proplists:get_value(number, e:module_info(attributes)),
  872. ?assertEqual([B,D,A,E], lists:sort([A,B,D,E])).
  873. mib_test(Config) ->
  874. AppDir = ?config(apps, Config),
  875. RebarConfig = [{mib_first_files, ["mibs/SIMPLE-MIB.mib"]}],
  876. Name = rebar_test_utils:create_random_name("app1_"),
  877. Vsn = rebar_test_utils:create_random_vsn(),
  878. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  879. MibsSrc = <<"-- SIMPLE-MIB.\n"
  880. "-- This is just a simple MIB used for testing!\n"
  881. "--\n"
  882. "SIMPLE-MIB DEFINITIONS ::= BEGIN\n"
  883. "IMPORTS\n"
  884. " MODULE-IDENTITY, enterprises\n"
  885. " FROM SNMPv2-SMI;\n"
  886. "\n"
  887. "ericsson MODULE-IDENTITY\n"
  888. " LAST-UPDATED\n"
  889. " \"201403060000Z\"\n"
  890. " ORGANIZATION\n"
  891. " \"rebar\"\n"
  892. " CONTACT-INFO\n"
  893. " \"rebar <rebar@example.com>\n"
  894. " or\n"
  895. " whoever is currently responsible for the SIMPLE\n"
  896. " enterprise MIB tree branch (enterprises.999).\"\n"
  897. " DESCRIPTION\n"
  898. " \"This very small module is made available\n"
  899. " for mib-compilation testing.\"\n"
  900. " ::= { enterprises 999 }\n"
  901. "END\n">>,
  902. ok = filelib:ensure_dir(filename:join([AppDir, "mibs", "dummy"])),
  903. ok = file:write_file(filename:join([AppDir, "mibs", "SIMPLE-MIB.mib"]), MibsSrc),
  904. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  905. %% check a bin corresponding to the mib in the mibs dir exists in priv/mibs
  906. PrivMibsDir = filename:join([AppDir, "_build", "default", "lib", Name, "priv", "mibs"]),
  907. true = filelib:is_file(filename:join([PrivMibsDir, "SIMPLE-MIB.bin"])),
  908. %% check a hrl corresponding to the mib in the mibs dir exists in include
  909. true = filelib:is_file(filename:join([AppDir, "include", "SIMPLE-MIB.hrl"])),
  910. %% check the mibs dir was linked into the _build dir
  911. true = filelib:is_dir(filename:join([AppDir, "_build", "default", "lib", Name, "mibs"])).
  912. umbrella_mib_first_test(Config) ->
  913. AppsDir = ?config(apps, Config),
  914. Name = rebar_test_utils:create_random_name("app1_"),
  915. Vsn = rebar_test_utils:create_random_vsn(),
  916. AppDir = filename:join([AppsDir, "apps", Name]),
  917. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  918. BExporterSrc = <<"-- BEXPORTER-MIB.\n"
  919. "-- This is just a simple MIB used for testing!\n"
  920. "--\n"
  921. "BEXPORTER-MIB DEFINITIONS ::= BEGIN\n"
  922. "IMPORTS\n"
  923. " TEXTUAL-CONVENTION\n"
  924. " FROM SNMPv2-TC\n"
  925. " MODULE-IDENTITY, enterprises\n"
  926. " FROM SNMPv2-SMI;\n"
  927. "\n"
  928. "ericsson MODULE-IDENTITY\n"
  929. " LAST-UPDATED\n"
  930. " \"201812050000Z\"\n"
  931. " ORGANIZATION\n"
  932. " \"rebar\"\n"
  933. " CONTACT-INFO\n"
  934. " \"rebar <rebar@example.com>\n"
  935. " or\n"
  936. " whoever is currently responsible for the SIMPLE\n"
  937. " enterprise MIB tree branch (enterprises.999).\"\n"
  938. " DESCRIPTION\n"
  939. " \"This very small module is made available\n"
  940. " for mib-compilation testing.\"\n"
  941. " ::= { enterprises 999 }\n"
  942. "\n"
  943. "Something ::= TEXTUAL-CONVENTION\n"
  944. " STATUS current\n"
  945. " DESCRIPTION \"\"\n"
  946. " SYNTAX OCTET STRING (SIZE (4))\n"
  947. "END\n">>,
  948. AImporterSrc = <<"-- AIMPORTER-MIB.\n"
  949. "-- This is just a simple MIB used for testing!\n"
  950. "--\n"
  951. "AIMPORTER-MIB DEFINITIONS ::= BEGIN\n"
  952. "IMPORTS\n"
  953. " Something\n"
  954. " FROM BEXPORTER-MIB\n"
  955. " MODULE-IDENTITY, enterprises\n"
  956. " FROM SNMPv2-SMI;\n"
  957. "\n"
  958. "ericsson MODULE-IDENTITY\n"
  959. " LAST-UPDATED\n"
  960. " \"201812050000Z\"\n"
  961. " ORGANIZATION\n"
  962. " \"rebar\"\n"
  963. " CONTACT-INFO\n"
  964. " \"rebar <rebar@example.com>\n"
  965. " or\n"
  966. " whoever is currently responsible for the SIMPLE\n"
  967. " enterprise MIB tree branch (enterprises.999).\"\n"
  968. " DESCRIPTION\n"
  969. " \"This very small module is made available\n"
  970. " for mib-compilation testing.\"\n"
  971. " ::= { enterprises 1000 }\n"
  972. "END\n">>,
  973. ok = filelib:ensure_dir(filename:join([AppDir, "mibs", "dummy"])),
  974. ok = file:write_file(filename:join([AppDir, "mibs", "AIMPORTER-MIB.mib"]), AImporterSrc),
  975. ok = file:write_file(filename:join([AppDir, "mibs", "BEXPORTER-MIB.mib"]), BExporterSrc),
  976. FailureRebarConfig = [{mib_first_files, ["mibs/AIMPORTER-MIB.mib"]}],
  977. SuccessRebarConfig = [{mib_first_files, ["mibs/BEXPORTER-MIB.mib"]}],
  978. PrivMibsDir = filename:join([AppsDir, "_build", "default", "lib", Name, "priv", "mibs"]),
  979. FailureRebarConfig = [{mib_first_files, ["mibs/AIMPORTER-MIB.mib"]}],
  980. catch (
  981. rebar_test_utils:run_and_check(Config, FailureRebarConfig, ["compile"], {ok, [{app, Name}]}) ),
  982. %% check that the bin file was NOT cretated
  983. false = filelib:is_file(filename:join([PrivMibsDir, "AIMPORTER-MIB.bin"])),
  984. SuccessRebarConfig = [{mib_first_files, ["mibs/BEXPORTER-MIB.mib"]}],
  985. rebar_test_utils:run_and_check(Config, SuccessRebarConfig, ["compile"], {ok, [{app, Name}]}),
  986. %% check a bin corresponding to the mib in the mibs dir exists in priv/mibs
  987. true = filelib:is_file(filename:join([PrivMibsDir, "AIMPORTER-MIB.bin"])),
  988. %% check a hrl corresponding to the mib in the mibs dir exists in include
  989. true = filelib:is_file(filename:join([AppDir, "include", "AIMPORTER-MIB.hrl"])),
  990. %% check the mibs dir was linked into the _build dir
  991. true = filelib:is_dir(filename:join([AppsDir, "_build", "default", "lib", Name, "mibs"])).
  992. only_default_transitive_deps(Config) ->
  993. AppDir = ?config(apps, Config),
  994. Name = rebar_test_utils:create_random_name("app1_"),
  995. Vsn = rebar_test_utils:create_random_vsn(),
  996. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  997. GitDeps = rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}]),
  998. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  999. {SrcDeps, _} = rebar_test_utils:flat_deps(GitDeps),
  1000. mock_git_resource:mock([{deps, SrcDeps},
  1001. {config, [{profiles, [{test, [{deps, [list_to_atom(PkgName)]}]}]}]}]),
  1002. mock_pkg_resource:mock([{pkgdeps, [{{iolist_to_binary(PkgName), <<"0.1.0">>}, []}]}]),
  1003. Deps = rebar_test_utils:top_level_deps(GitDeps),
  1004. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, Deps}]),
  1005. {ok, RConf} = file:consult(RConfFile),
  1006. %% Build with deps.
  1007. rebar_test_utils:run_and_check(
  1008. Config, RConf, ["as", "test", "compile"],
  1009. {ok, [{app, Name}, {dep, "a", <<"1.0.0">>}, {dep_not_exist, PkgName}]}
  1010. ).
  1011. clean_all(Config) ->
  1012. AppDir = ?config(apps, Config),
  1013. Name = rebar_test_utils:create_random_name("app1_"),
  1014. Vsn = rebar_test_utils:create_random_vsn(),
  1015. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1016. DepName = rebar_test_utils:create_random_name("dep1_"),
  1017. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  1018. mock_git_resource:mock([]),
  1019. mock_pkg_resource:mock([
  1020. {pkgdeps, [{{iolist_to_binary(PkgName), iolist_to_binary(Vsn)}, []}]}
  1021. ]),
  1022. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [
  1023. {list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}},
  1024. {list_to_atom(PkgName), Vsn}
  1025. ]}]),
  1026. {ok, RConf} = file:consult(RConfFile),
  1027. %% Build things
  1028. rebar_test_utils:run_and_check(
  1029. Config, RConf, ["compile"],
  1030. {ok, [{app, Name}, {app, DepName}, {app, PkgName}]}
  1031. ),
  1032. %% Clean all
  1033. rebar_test_utils:run_and_check(Config, [], ["clean", "--all"],
  1034. {ok, [{app, Name, invalid},
  1035. {app, DepName, invalid},
  1036. {app, PkgName, invalid}]}).
  1037. clean_specific(Config) ->
  1038. AppDir = ?config(apps, Config),
  1039. Name = rebar_test_utils:create_random_name("app1_"),
  1040. Vsn = rebar_test_utils:create_random_vsn(),
  1041. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1042. DepName = rebar_test_utils:create_random_name("dep1_"),
  1043. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  1044. mock_git_resource:mock([]),
  1045. mock_pkg_resource:mock([
  1046. {pkgdeps, [{{iolist_to_binary(PkgName), iolist_to_binary(Vsn)}, []}]}
  1047. ]),
  1048. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [
  1049. {list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}},
  1050. {list_to_atom(PkgName), Vsn}
  1051. ]}]),
  1052. {ok, RConf} = file:consult(RConfFile),
  1053. %% Build things
  1054. rebar_test_utils:run_and_check(
  1055. Config, RConf, ["compile"],
  1056. {ok, [{app, Name}, {app, DepName}, {app, PkgName}]}
  1057. ),
  1058. %% Clean all
  1059. rebar_test_utils:run_and_check(Config, [], ["clean", "--apps="++DepName++","++Name],
  1060. {ok, [{app, Name, invalid},
  1061. {app, DepName, invalid},
  1062. {app, PkgName, valid}]}).
  1063. override_deps(Config) ->
  1064. Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]),
  1065. TopDeps = rebar_test_utils:top_level_deps(Deps),
  1066. {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
  1067. mock_git_resource:mock([{deps, SrcDeps}]),
  1068. RebarConfig = [
  1069. {deps, TopDeps},
  1070. {overrides, [
  1071. {override, some_dep, [
  1072. {deps, []}
  1073. ]}
  1074. ]}
  1075. ],
  1076. rebar_test_utils:run_and_check(
  1077. Config, RebarConfig, ["compile"],
  1078. {ok, [{dep, "some_dep"},
  1079. {dep_not_exist, "other_dep"}]}
  1080. ).
  1081. override_add_deps(Config) ->
  1082. Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]),
  1083. TopDeps = rebar_test_utils:top_level_deps(Deps),
  1084. DepA = {dep_a, "0.0.1", {git, "http://site.com/dep_a.git", {tag, "0.0.1"}}},
  1085. DepB = {dep_b, "0.0.1", {git, "http://site.com/dep_b.git", {tag, "0.0.1"}}},
  1086. DepC = {dep_c, "0.0.1", {git, "http://site.com/dep_c.git", {tag, "0.0.1"}}},
  1087. {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
  1088. mock_git_resource:mock([{deps, [DepA, DepB, DepC | SrcDeps]}]),
  1089. RebarConfig = [
  1090. {deps, TopDeps},
  1091. {overrides, [
  1092. {add, some_dep, [
  1093. {deps, [DepA, DepB]}
  1094. ]},
  1095. {add, [
  1096. {deps, [DepC]}
  1097. ]}
  1098. ]}
  1099. ],
  1100. rebar_test_utils:run_and_check(
  1101. Config, RebarConfig, ["compile"],
  1102. {ok, [{dep, "some_dep"},
  1103. {dep, "other_dep"},
  1104. {dep, "dep_a"},
  1105. {dep, "dep_b"},
  1106. {dep, "dep_c"}]}
  1107. ).
  1108. override_del_deps(Config) ->
  1109. Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"dep_a", "0.0.1", []},
  1110. {"dep_b", "0.0.1", []},
  1111. {"dep_c", "0.0.1", []}]},
  1112. {"other_dep", "0.0.1", [{"dep_c", "0.0.1", []},
  1113. {"dep_d", "0.0.1", []}]}]),
  1114. TopDeps = rebar_test_utils:top_level_deps(Deps),
  1115. DepA = {dep_a, "0.0.1", {git, "https://example.org/user/dep_a.git", {tag, "0.0.1"}}},
  1116. DepB = {dep_b, "0.0.1", {git, "https://example.org/user/dep_b.git", {tag, "0.0.1"}}},
  1117. DepC = {dep_c, "0.0.1", {git, "https://example.org/user/dep_c.git", {tag, "0.0.1"}}},
  1118. {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
  1119. mock_git_resource:mock([{deps, SrcDeps}]),
  1120. RebarConfig = [
  1121. {deps, TopDeps},
  1122. {overrides, [
  1123. {del, some_dep, [
  1124. {deps, [DepA, DepB]}
  1125. ]},
  1126. {del, [
  1127. {deps, [DepC]}
  1128. ]}
  1129. ]}
  1130. ],
  1131. rebar_test_utils:run_and_check(
  1132. Config, RebarConfig, ["compile"],
  1133. {ok, [{dep, "some_dep"},
  1134. {dep, "other_dep"},
  1135. {dep_not_exist, "dep_a"},
  1136. {dep_not_exist, "dep_b"},
  1137. {dep_not_exist, "dep_c"},
  1138. {dep, "dep_d"}]}
  1139. ).
  1140. override_opts(Config) ->
  1141. AppsDir = ?config(apps, Config),
  1142. Name = rebar_test_utils:create_random_name("app1_"),
  1143. Vsn = rebar_test_utils:create_random_vsn(),
  1144. AppDir = filename:join([AppsDir, "apps", Name]),
  1145. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1146. RebarConfig = [
  1147. {erl_opts, [
  1148. compressed,
  1149. warn_missing_spec
  1150. ]},
  1151. {overrides, [
  1152. {override, [
  1153. {erl_opts, [compressed]}
  1154. ]}
  1155. ]}
  1156. ],
  1157. rebar_test_utils:create_config(AppsDir, RebarConfig),
  1158. rebar_test_utils:run_and_check(
  1159. Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  1160. Path = filename:join([AppsDir, "_build", "default", "lib", Name, "ebin"]),
  1161. code:add_patha(Path),
  1162. Mod = list_to_atom("not_a_real_src_" ++ Name),
  1163. true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])),
  1164. false = lists:member(warn_missing_spec, proplists:get_value(options, Mod:module_info(compile), [])).
  1165. %% test for fix of https://github.com/erlang/rebar3/issues/1801
  1166. %% only apply overrides once
  1167. %% verify by having an override add the macro TEST to the dep some_dep
  1168. %% building under `ct` will fail if the `add` is applied more than once
  1169. apply_overrides_exactly_once(Config) ->
  1170. AppDir = ?config(apps, Config),
  1171. Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]),
  1172. TopDeps = rebar_test_utils:top_level_deps(Deps),
  1173. {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
  1174. mock_git_resource:mock([{deps, SrcDeps}]),
  1175. Name = rebar_test_utils:create_random_name("app1_"),
  1176. Vsn = rebar_test_utils:create_random_vsn(),
  1177. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1178. RebarConfig = [{deps, TopDeps},
  1179. {overrides, [
  1180. {add, some_dep, [
  1181. {erl_opts, [{d, 'TEST'}]}
  1182. ]}
  1183. ]}],
  1184. rebar_test_utils:create_config(AppDir, RebarConfig),
  1185. rebar_test_utils:run_and_check(
  1186. Config, RebarConfig, ["ct", "--compile_only"], {ok, [{app, Name}, {dep, "some_dep"}], "test"}).
  1187. override_only_deps(Config) ->
  1188. AppDir = ?config(apps, Config),
  1189. Name = rebar_test_utils:create_random_name("app1_"),
  1190. Vsn = rebar_test_utils:create_random_vsn(),
  1191. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1192. RebarConfig = [
  1193. {deps, []}, %% with deps enabled, this test fails
  1194. {overrides, [
  1195. {add, [
  1196. {erl_opts, [{d, bad, a}, {d, bad, b}]}
  1197. ]}
  1198. ]}
  1199. ],
  1200. rebar_test_utils:create_config(AppDir, RebarConfig),
  1201. rebar_test_utils:run_and_check(
  1202. Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  1203. ok.
  1204. override_add_opts(Config) ->
  1205. AppsDir = ?config(apps, Config),
  1206. Name = rebar_test_utils:create_random_name("app1_"),
  1207. Vsn = rebar_test_utils:create_random_vsn(),
  1208. AppDir = filename:join([AppsDir, "apps", Name]),
  1209. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1210. RebarConfig = [
  1211. {erl_opts, [
  1212. warn_missing_spec
  1213. ]},
  1214. {overrides, [
  1215. {add, [
  1216. {erl_opts, [compressed]}
  1217. ]}
  1218. ]}
  1219. ],
  1220. rebar_test_utils:create_config(AppsDir, RebarConfig),
  1221. rebar_test_utils:run_and_check(
  1222. Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  1223. Path = filename:join([AppsDir, "_build", "default", "lib", Name, "ebin"]),
  1224. code:add_patha(Path),
  1225. Mod = list_to_atom("not_a_real_src_" ++ Name),
  1226. true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])),
  1227. true = lists:member(warn_missing_spec, proplists:get_value(options, Mod:module_info(compile), [])).
  1228. override_del_opts(Config) ->
  1229. AppsDir = ?config(apps, Config),
  1230. Name = rebar_test_utils:create_random_name("app1_"),
  1231. Vsn = rebar_test_utils:create_random_vsn(),
  1232. AppDir = filename:join([AppsDir, "apps", Name]),
  1233. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1234. RebarConfig = [
  1235. {erl_opts, [
  1236. compressed,
  1237. warn_missing_spec
  1238. ]},
  1239. {overrides, [
  1240. {del, [
  1241. {erl_opts, [warn_missing_spec]}
  1242. ]}
  1243. ]}
  1244. ],
  1245. rebar_test_utils:create_config(AppsDir, RebarConfig),
  1246. rebar_test_utils:run_and_check(
  1247. Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  1248. Path = filename:join([AppsDir, "_build", "default", "lib", Name, "ebin"]),
  1249. code:add_patha(Path),
  1250. Mod = list_to_atom("not_a_real_src_" ++ Name),
  1251. true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])),
  1252. false = lists:member(warn_missing_spec, proplists:get_value(options, Mod:module_info(compile), [])),
  1253. ok.
  1254. profile_override_deps(Config) ->
  1255. Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]),
  1256. TopDeps = rebar_test_utils:top_level_deps(Deps),
  1257. {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
  1258. mock_git_resource:mock([{deps, SrcDeps}]),
  1259. RebarConfig = [
  1260. {deps, TopDeps},
  1261. {profiles, [
  1262. {a, [
  1263. {overrides, [
  1264. {override, some_dep, [
  1265. {deps, []}
  1266. ]}
  1267. ]}
  1268. ]}
  1269. ]}],
  1270. rebar_test_utils:run_and_check(
  1271. Config, RebarConfig, ["as", "a", "compile"],
  1272. {ok, [{dep, "some_dep"},
  1273. {dep_not_exist, "other_dep"}]}
  1274. ).
  1275. profile_override_add_deps(Config) ->
  1276. Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]),
  1277. TopDeps = rebar_test_utils:top_level_deps(Deps),
  1278. DepA = {dep_a, "0.0.1", {git, "http://site.com/dep_a.git", {tag, "0.0.1"}}},
  1279. DepB = {dep_b, "0.0.1", {git, "http://site.com/dep_b.git", {tag, "0.0.1"}}},
  1280. DepC = {dep_c, "0.0.1", {git, "http://site.com/dep_c.git", {tag, "0.0.1"}}},
  1281. {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
  1282. mock_git_resource:mock([{deps, [DepA, DepB, DepC | SrcDeps]}]),
  1283. RebarConfig = [
  1284. {deps, TopDeps},
  1285. {profiles, [
  1286. {a, [
  1287. {overrides, [
  1288. {add, some_dep, [
  1289. {deps, [DepA, DepB]}
  1290. ]},
  1291. {add, [
  1292. {deps, [DepC]}
  1293. ]}
  1294. ]}
  1295. ]}
  1296. ]}
  1297. ],
  1298. rebar_test_utils:run_and_check(
  1299. Config, RebarConfig, ["as", "a", "compile"],
  1300. {ok, [{dep, "some_dep"},
  1301. {dep, "other_dep"},
  1302. {dep, "dep_a"},
  1303. {dep, "dep_b"},
  1304. {dep, "dep_c"}]}
  1305. ).
  1306. profile_override_del_deps(Config) ->
  1307. Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"dep_a", "0.0.1", []},
  1308. {"dep_b", "0.0.1", []},
  1309. {"dep_c", "0.0.1", []}]},
  1310. {"other_dep", "0.0.1", [{"dep_c", "0.0.1", []},
  1311. {"dep_d", "0.0.1", []}]}]),
  1312. TopDeps = rebar_test_utils:top_level_deps(Deps),
  1313. DepA = {dep_a, "0.0.1", {git, "https://example.org/user/dep_a.git", {tag, "0.0.1"}}},
  1314. DepB = {dep_b, "0.0.1", {git, "https://example.org/user/dep_b.git", {tag, "0.0.1"}}},
  1315. DepC = {dep_c, "0.0.1", {git, "https://example.org/user/dep_c.git", {tag, "0.0.1"}}},
  1316. {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
  1317. mock_git_resource:mock([{deps, SrcDeps}]),
  1318. RebarConfig = [
  1319. {deps, TopDeps},
  1320. {profiles, [
  1321. {a, [
  1322. {overrides, [
  1323. {del, some_dep, [
  1324. {deps, [DepA, DepB]}
  1325. ]},
  1326. {del, [
  1327. {deps, [DepC]}
  1328. ]}
  1329. ]}
  1330. ]}
  1331. ]}
  1332. ],
  1333. rebar_test_utils:run_and_check(
  1334. Config, RebarConfig, ["as", "a", "compile"],
  1335. {ok, [{dep, "some_dep"},
  1336. {dep, "other_dep"},
  1337. {dep_not_exist, "dep_a"},
  1338. {dep_not_exist, "dep_b"},
  1339. {dep_not_exist, "dep_c"},
  1340. {dep, "dep_d"}]}
  1341. ).
  1342. profile_override_opts(Config) ->
  1343. AppsDir = ?config(apps, Config),
  1344. Name = rebar_test_utils:create_random_name("app1_"),
  1345. Vsn = rebar_test_utils:create_random_vsn(),
  1346. AppDir = filename:join([AppsDir, "apps", Name]),
  1347. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1348. RebarConfig = [
  1349. {erl_opts, [
  1350. compressed,
  1351. warn_missing_spec
  1352. ]},
  1353. {profiles, [
  1354. {a, [
  1355. {overrides, [
  1356. {override, [
  1357. {erl_opts, [compressed]}
  1358. ]}
  1359. ]}
  1360. ]}
  1361. ]}
  1362. ],
  1363. rebar_test_utils:create_config(AppsDir, RebarConfig),
  1364. rebar_test_utils:run_and_check(
  1365. Config, RebarConfig, ["as", "a", "compile"], {ok, [{app, Name}]}),
  1366. Path = filename:join([AppsDir, "_build", "a", "lib", Name, "ebin"]),
  1367. code:add_patha(Path),
  1368. Mod = list_to_atom("not_a_real_src_" ++ Name),
  1369. true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])),
  1370. false = lists:member(warn_missing_spec, proplists:get_value(options, Mod:module_info(compile), [])).
  1371. profile_override_add_opts(Config) ->
  1372. AppsDir = ?config(apps, Config),
  1373. Name = rebar_test_utils:create_random_name("app1_"),
  1374. Vsn = rebar_test_utils:create_random_vsn(),
  1375. AppDir = filename:join([AppsDir, "apps", Name]),
  1376. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1377. RebarConfig = [
  1378. {erl_opts, [
  1379. warn_missing_spec
  1380. ]},
  1381. {profiles, [
  1382. {a, [
  1383. {overrides, [
  1384. {add, [
  1385. {erl_opts, [compressed]}
  1386. ]}
  1387. ]}
  1388. ]}
  1389. ]}
  1390. ],
  1391. rebar_test_utils:create_config(AppsDir, RebarConfig),
  1392. rebar_test_utils:run_and_check(
  1393. Config, RebarConfig, ["as", "a", "compile"], {ok, [{app, Name}]}),
  1394. Path = filename:join([AppsDir, "_build", "a", "lib", Name, "ebin"]),
  1395. code:add_patha(Path),
  1396. Mod = list_to_atom("not_a_real_src_" ++ Name),
  1397. true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])),
  1398. true = lists:member(warn_missing_spec, proplists:get_value(options, Mod:module_info(compile), [])).
  1399. profile_override_del_opts(Config) ->
  1400. AppsDir = ?config(apps, Config),
  1401. Name = rebar_test_utils:create_random_name("app1_"),
  1402. Vsn = rebar_test_utils:create_random_vsn(),
  1403. AppDir = filename:join([AppsDir, "apps", Name]),
  1404. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1405. RebarConfig = [
  1406. {erl_opts, [
  1407. compressed,
  1408. warn_missing_spec
  1409. ]},
  1410. {profiles, [
  1411. {a, [
  1412. {overrides, [
  1413. {del, [
  1414. {erl_opts, [warn_missing_spec]}
  1415. ]}
  1416. ]}
  1417. ]}
  1418. ]}
  1419. ],
  1420. rebar_test_utils:create_config(AppsDir, RebarConfig),
  1421. rebar_test_utils:run_and_check(
  1422. Config, RebarConfig, ["as", "a", "compile"], {ok, [{app, Name}]}),
  1423. Path = filename:join([AppsDir, "_build", "a", "lib", Name, "ebin"]),
  1424. code:add_patha(Path),
  1425. Mod = list_to_atom("not_a_real_src_" ++ Name),
  1426. true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])),
  1427. false = lists:member(warn_missing_spec, proplists:get_value(options, Mod:module_info(compile), [])),
  1428. ok.
  1429. profile_deps(Config) ->
  1430. Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]),
  1431. TopDeps = rebar_test_utils:top_level_deps(Deps),
  1432. {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
  1433. mock_git_resource:mock([{deps, SrcDeps}]),
  1434. RebarConfig = [
  1435. {deps, TopDeps},
  1436. {profiles, [{a, []}]}],
  1437. rebar_test_utils:run_and_check(
  1438. Config, RebarConfig, ["as", "a", "compile"],
  1439. {ok, [{dep, "some_dep"},{dep, "other_dep"}]}
  1440. ).
  1441. only_deps(Config) ->
  1442. AppDir = ?config(apps, Config),
  1443. Name = rebar_test_utils:create_random_name("app1_"),
  1444. Vsn = rebar_test_utils:create_random_vsn(),
  1445. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1446. Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]),
  1447. TopDeps = rebar_test_utils:top_level_deps(Deps),
  1448. {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
  1449. mock_git_resource:mock([{deps, SrcDeps}]),
  1450. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, TopDeps}]),
  1451. {ok, RConf} = file:consult(RConfFile),
  1452. rebar_test_utils:run_and_check(
  1453. Config, RConf, ["compile", "--deps_only"],
  1454. {ok, [{app_not_exist, Name}, {dep, "some_dep"},{dep, "other_dep"}]}
  1455. ).
  1456. %% verify a deps prod profile is used
  1457. %% tested by checking prod hooks run and outputs to default profile dir for dep
  1458. %% and prod deps are installed for dep
  1459. deps_build_in_prod(Config) ->
  1460. AppDir = ?config(apps, Config),
  1461. Name = rebar_test_utils:create_random_name("app1_"),
  1462. Vsn = rebar_test_utils:create_random_vsn(),
  1463. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1464. GitDeps = rebar_test_utils:expand_deps(git, [{"asdf", "1.0.0", []}]),
  1465. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  1466. {SrcDeps, _} = rebar_test_utils:flat_deps(GitDeps),
  1467. mock_git_resource:mock([{deps, SrcDeps},
  1468. {config, [{profiles, [{prod, [{pre_hooks, [{compile, "echo whatsup > randomfile"}]},
  1469. {deps, [list_to_atom(PkgName)]}]}]}]}]),
  1470. mock_pkg_resource:mock([{pkgdeps, [{{iolist_to_binary(PkgName), <<"0.1.0">>}, []}]}]),
  1471. Deps = rebar_test_utils:top_level_deps(GitDeps),
  1472. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, Deps}]),
  1473. {ok, RConf} = file:consult(RConfFile),
  1474. %% Build with deps.
  1475. rebar_test_utils:run_and_check(
  1476. Config, RConf, ["compile"],
  1477. {ok, [{app, Name}, {dep, "asdf", <<"1.0.0">>}, {dep, PkgName},
  1478. {file, filename:join([AppDir, "_build", "default", "lib", "asdf", "randomfile"])}]}
  1479. ).
  1480. %% verify that the proper include path is defined
  1481. %% according the erlang doc which states:
  1482. %% If the filename File is absolute (possibly after variable substitution),
  1483. %% the include file with that name is included. Otherwise, the specified file
  1484. %% is searched for in the following directories, and in this order:
  1485. %% * The current working directory
  1486. %% * The directory where the module is being compiled
  1487. %% * The directories given by the include option
  1488. include_file_relative_to_working_directory(Config) ->
  1489. AppDir = ?config(apps, Config),
  1490. Name = rebar_test_utils:create_random_name("app1_"),
  1491. Vsn = rebar_test_utils:create_random_vsn(),
  1492. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1493. Src = <<"-module(test).\n"
  1494. "\n"
  1495. "-include(\"include/test.hrl\").\n"
  1496. "\n"
  1497. "test() -> ?TEST_MACRO.\n"
  1498. "\n">>,
  1499. Include = <<"-define(TEST_MACRO, test).\n">>,
  1500. ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])),
  1501. ok = file:write_file(filename:join([AppDir, "src", "test.erl"]), Src),
  1502. ok = filelib:ensure_dir(filename:join([AppDir, "include", "dummy"])),
  1503. ok = file:write_file(filename:join([AppDir, "include", "test.hrl"]), Include),
  1504. RebarConfig = [],
  1505. rebar_test_utils:run_and_check(Config, RebarConfig,
  1506. ["compile"],
  1507. {ok, [{app, Name}]}).
  1508. include_file_in_src(Config) ->
  1509. AppDir = ?config(apps, Config),
  1510. Name = rebar_test_utils:create_random_name("app1_"),
  1511. Vsn = rebar_test_utils:create_random_vsn(),
  1512. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1513. Src = <<"-module(test).\n"
  1514. "\n"
  1515. "-include(\"test.hrl\").\n"
  1516. "\n"
  1517. "test() -> ?TEST_MACRO.\n"
  1518. "\n">>,
  1519. Include = <<"-define(TEST_MACRO, test).\n">>,
  1520. ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])),
  1521. ok = file:write_file(filename:join([AppDir, "src", "test.erl"]), Src),
  1522. ok = file:write_file(filename:join([AppDir, "src", "test.hrl"]), Include),
  1523. RebarConfig = [],
  1524. rebar_test_utils:run_and_check(Config, RebarConfig,
  1525. ["compile"],
  1526. {ok, [{app, Name}]}).
  1527. %% verify that the proper include path is defined
  1528. %% according the erlang doc which states:
  1529. %% If the filename File is absolute (possibly after variable substitution),
  1530. %% the include file with that name is included. Otherwise, the specified file
  1531. %% is searched for in the following directories, and in this order:
  1532. %% * The current working directory
  1533. %% * The directory where the module is being compiled
  1534. %% * The directories given by the include option
  1535. %%
  1536. %% This test ensures that things keep working when additional directories
  1537. %% are used for apps, such as the test/ directory within the test profile.
  1538. include_file_relative_to_working_directory_test(Config) ->
  1539. AppDir = ?config(apps, Config),
  1540. Name = rebar_test_utils:create_random_name("app1_"),
  1541. Vsn = rebar_test_utils:create_random_vsn(),
  1542. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1543. Src = <<"-module(test).\n"
  1544. "\n"
  1545. "-include(\"include/test.hrl\").\n"
  1546. "\n"
  1547. "test() -> ?TEST_MACRO.\n"
  1548. "\n">>,
  1549. Include = <<"-define(TEST_MACRO, test).\n">>,
  1550. ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])),
  1551. ok = filelib:ensure_dir(filename:join([AppDir, "test", "dummy"])),
  1552. ok = file:write_file(filename:join([AppDir, "test", "test.erl"]), Src),
  1553. ok = filelib:ensure_dir(filename:join([AppDir, "include", "dummy"])),
  1554. ok = file:write_file(filename:join([AppDir, "include", "test.hrl"]), Include),
  1555. RebarConfig = [],
  1556. rebar_test_utils:run_and_check(Config, RebarConfig,
  1557. ["as", "test", "compile"],
  1558. {ok, [{app, Name}]}).
  1559. %% Same as `include_file_in_src/1' but using the `test/' directory
  1560. %% within the test profile.
  1561. include_file_in_src_test(Config) ->
  1562. AppDir = ?config(apps, Config),
  1563. Name = rebar_test_utils:create_random_name("app1_"),
  1564. Vsn = rebar_test_utils:create_random_vsn(),
  1565. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1566. Src = <<"-module(test).\n"
  1567. "\n"
  1568. "-include(\"test.hrl\").\n"
  1569. "\n"
  1570. "test() -> ?TEST_MACRO.\n"
  1571. "\n">>,
  1572. Include = <<"-define(TEST_MACRO, test).\n">>,
  1573. ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])),
  1574. ok = filelib:ensure_dir(filename:join([AppDir, "test", "dummy"])),
  1575. ok = file:write_file(filename:join([AppDir, "test", "test.erl"]), Src),
  1576. ok = file:write_file(filename:join([AppDir, "src", "test.hrl"]), Include),
  1577. RebarConfig = [],
  1578. rebar_test_utils:run_and_check(Config, RebarConfig,
  1579. ["as", "test", "compile"],
  1580. {ok, [{app, Name}]}).
  1581. %% Same as `include_file_in_src_test/1' but using multiple top-level
  1582. %% apps as dependencies.
  1583. include_file_in_src_test_multiapp(Config) ->
  1584. Name1 = rebar_test_utils:create_random_name("app2_"),
  1585. Name2 = rebar_test_utils:create_random_name("app1_"),
  1586. AppDir1 = filename:join([?config(apps, Config), "lib", Name1]),
  1587. AppDir2 = filename:join([?config(apps, Config), "lib", Name2]),
  1588. Vsn = rebar_test_utils:create_random_vsn(),
  1589. rebar_test_utils:create_app(AppDir1, Name1, Vsn, [kernel, stdlib, list_to_atom(Name2)]),
  1590. rebar_test_utils:create_app(AppDir2, Name2, Vsn, [kernel, stdlib]),
  1591. Src = "-module(test).\n"
  1592. "\n"
  1593. "-include_lib(\"" ++ Name2 ++ "/include/test.hrl\").\n"
  1594. "\n"
  1595. "test() -> ?TEST_MACRO.\n"
  1596. "\n",
  1597. Include = <<"-define(TEST_MACRO, test).\n">>,
  1598. ok = filelib:ensure_dir(filename:join([AppDir1, "src", "dummy"])),
  1599. ok = filelib:ensure_dir(filename:join([AppDir1, "test", "dummy"])),
  1600. ok = filelib:ensure_dir(filename:join([AppDir2, "src", "dummy"])),
  1601. ok = filelib:ensure_dir(filename:join([AppDir2, "include", "dummy"])),
  1602. ok = file:write_file(filename:join([AppDir1, "test", "test.erl"]), Src),
  1603. ok = file:write_file(filename:join([AppDir2, "include", "test.hrl"]), Include),
  1604. RebarConfig = [],
  1605. rebar_test_utils:run_and_check(Config, RebarConfig,
  1606. ["as", "test", "compile"],
  1607. {ok, [{app, Name1}]}),
  1608. ok.
  1609. %% this test sets the env var, compiles, records the file last modified timestamp,
  1610. %% recompiles and compares the file last modified timestamp to ensure it hasn't
  1611. %% changed. this test should run on 19.x+
  1612. dont_recompile_when_erl_compiler_options_env_does_not_change(Config) ->
  1613. %% save existing env to restore after test
  1614. ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"),
  1615. AppDir = ?config(apps, Config),
  1616. Name = rebar_test_utils:create_random_name("erl_compiler_options_"),
  1617. Vsn = rebar_test_utils:create_random_vsn(),
  1618. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1619. true = os:unsetenv("ERL_COMPILER_OPTIONS"),
  1620. true = os:putenv("ERL_COMPILER_OPTIONS", "[{d, some_macro}]"),
  1621. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1622. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1623. {ok, Files} = rebar_utils:list_dir(EbinDir),
  1624. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1625. || F <- Files, filename:extension(F) == ".beam"],
  1626. timer:sleep(1000),
  1627. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1628. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  1629. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1630. || F <- NewFiles, filename:extension(F) == ".beam"],
  1631. ?assert(ModTime == NewModTime),
  1632. %% restore existing env
  1633. case ExistingEnv of
  1634. false -> ok;
  1635. _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv)
  1636. end.
  1637. %% this test compiles, records the file last modified timestamp, sets the env
  1638. %% var, recompiles and compares the file last modified timestamp to ensure it
  1639. %% has changed. this test should run on 19.x+
  1640. recompile_when_erl_compiler_options_env_changes(Config) ->
  1641. %% save existing env to restore after test
  1642. ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"),
  1643. AppDir = ?config(apps, Config),
  1644. Name = rebar_test_utils:create_random_name("erl_compiler_options_"),
  1645. Vsn = rebar_test_utils:create_random_vsn(),
  1646. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1647. true = os:unsetenv("ERL_COMPILER_OPTIONS"),
  1648. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1649. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1650. {ok, Files} = rebar_utils:list_dir(EbinDir),
  1651. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1652. || F <- Files, filename:extension(F) == ".beam"],
  1653. timer:sleep(1000),
  1654. true = os:putenv("ERL_COMPILER_OPTIONS", "[{d, some_macro}]"),
  1655. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1656. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  1657. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1658. || F <- NewFiles, filename:extension(F) == ".beam"],
  1659. ?assert(ModTime =/= NewModTime),
  1660. %% restore existing env
  1661. case ExistingEnv of
  1662. false -> ok;
  1663. _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv)
  1664. end.
  1665. rebar_config_os_var(Config) ->
  1666. AppDir = ?config(apps, Config),
  1667. Name = rebar_test_utils:create_random_name("rebar_config_os_var_"),
  1668. Vsn = rebar_test_utils:create_random_vsn(),
  1669. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1670. rebar_test_utils:create_config(AppDir, [{erl_opts, []}]),
  1671. AltConfig = filename:join(AppDir, "test.rebar.config"),
  1672. file:write_file(AltConfig, "{erl_opts, [compressed]}."),
  1673. true = os:putenv("REBAR_CONFIG", AltConfig),
  1674. rebar_test_utils:run_and_check(Config, ["compile"], {ok, [{app, Name}]}),
  1675. Path = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1676. code:add_patha(Path),
  1677. Mod = list_to_atom("not_a_real_src_" ++ Name),
  1678. true = lists:member(compressed, proplists:get_value(options, Mod:module_info(compile), [])),
  1679. ok.
  1680. %% this test sets the env var, compiles, records the file last modified
  1681. %% timestamp, recompiles and compares the file last modified timestamp to
  1682. %% ensure it has changed. this test should run on 18.x
  1683. always_recompile_when_erl_compiler_options_set(Config) ->
  1684. %% save existing env to restore after test
  1685. ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"),
  1686. AppDir = ?config(apps, Config),
  1687. Name = rebar_test_utils:create_random_name("erl_compiler_options_"),
  1688. Vsn = rebar_test_utils:create_random_vsn(),
  1689. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1690. true = os:unsetenv("ERL_COMPILER_OPTIONS"),
  1691. true = os:putenv("ERL_COMPILER_OPTIONS", "[{d, some_macro}]"),
  1692. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1693. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1694. {ok, Files} = rebar_utils:list_dir(EbinDir),
  1695. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1696. || F <- Files, filename:extension(F) == ".beam"],
  1697. timer:sleep(1000),
  1698. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1699. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  1700. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1701. || F <- NewFiles, filename:extension(F) == ".beam"],
  1702. ?assert(ModTime =/= NewModTime),
  1703. %% restore existing env
  1704. case ExistingEnv of
  1705. false -> ok;
  1706. _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv)
  1707. end.
  1708. recompile_when_parse_transform_inline_changes(Config) ->
  1709. AppDir = ?config(apps, Config),
  1710. Name = rebar_test_utils:create_random_name("parse_transform_inline_"),
  1711. Vsn = rebar_test_utils:create_random_vsn(),
  1712. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1713. ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])),
  1714. ModSrc = <<"-module(example).\n"
  1715. "-export([foo/2]).\n"
  1716. "-compile([{parse_transform, example_parse_transform}]).\n"
  1717. "foo(_, _) -> ok.">>,
  1718. ok = file:write_file(filename:join([AppDir, "src", "example.erl"]),
  1719. ModSrc),
  1720. ParseTransform = <<"-module(example_parse_transform).\n"
  1721. "-export([parse_transform/2]).\n"
  1722. "parse_transform(AST, _) -> AST.\n">>,
  1723. ok = file:write_file(filename:join([AppDir, "src", "example_parse_transform.erl"]),
  1724. ParseTransform),
  1725. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1726. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1727. {ok, Files} = rebar_utils:list_dir(EbinDir),
  1728. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1729. || F <- Files, filename:basename(F, ".beam") == "example"],
  1730. timer:sleep(1000),
  1731. NewParseTransform = <<"-module(example_parse_transform).\n"
  1732. "-export([parse_transform/2]).\n"
  1733. "parse_transform(AST, _) -> identity(AST).\n"
  1734. "identity(AST) -> AST.\n">>,
  1735. ok = file:write_file(filename:join([AppDir, "src", "example_parse_transform.erl"]),
  1736. NewParseTransform),
  1737. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1738. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  1739. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1740. || F <- NewFiles, filename:basename(F, ".beam") == "example"],
  1741. ?assert(ModTime =/= NewModTime).
  1742. recompile_when_parse_transform_as_opt_changes(Config) ->
  1743. AppDir = ?config(apps, Config),
  1744. Name = rebar_test_utils:create_random_name("parse_transform_opt_"),
  1745. Vsn = rebar_test_utils:create_random_vsn(),
  1746. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1747. ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])),
  1748. ModSrc = <<"-module(example).\n"
  1749. "-export([foo/2]).\n"
  1750. "foo(_, _) -> ok.">>,
  1751. ok = file:write_file(filename:join([AppDir, "src", "example.erl"]),
  1752. ModSrc),
  1753. ParseTransform = <<"-module(example_parse_transform).\n"
  1754. "-export([parse_transform/2]).\n"
  1755. "parse_transform(AST, _) -> AST.">>,
  1756. ok = file:write_file(filename:join([AppDir, "src", "example_parse_transform.erl"]),
  1757. ParseTransform),
  1758. RebarConfig = [{erl_opts, [{parse_transform, example_parse_transform}]}],
  1759. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  1760. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1761. {ok, Files} = rebar_utils:list_dir(EbinDir),
  1762. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1763. || F <- Files, filename:basename(F, ".beam") == "example"],
  1764. timer:sleep(1000),
  1765. NewParseTransform = <<"-module(example_parse_transform).\n"
  1766. "-export([parse_transform/2]).\n"
  1767. "parse_transform(AST, _) -> identity(AST).\n"
  1768. "identity(AST) -> AST.">>,
  1769. ok = file:write_file(filename:join([AppDir, "src", "example_parse_transform.erl"]),
  1770. NewParseTransform),
  1771. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  1772. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  1773. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1774. || F <- NewFiles, filename:basename(F, ".beam") == "example"],
  1775. ?assert(ModTime =/= NewModTime).
  1776. recursive(Config) ->
  1777. AppDir = ?config(apps, Config),
  1778. Name = rebar_test_utils:create_random_name("app1_"),
  1779. Vsn = rebar_test_utils:create_random_vsn(),
  1780. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1781. rebar_test_utils:write_src_file(filename:join(AppDir,src),"rec.erl"),
  1782. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1783. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1784. {ok, Files} = rebar_utils:list_dir(EbinDir),
  1785. ?assert(lists:member("rec.beam",Files)),
  1786. %% check that rec is in modules list of .app file
  1787. AppFile = filename:join(EbinDir, Name++".app"),
  1788. {ok, [{application, _, List}]} = file:consult(AppFile),
  1789. {modules, Modules} = lists:keyfind(modules, 1, List),
  1790. ?assert(lists:member(rec, Modules)).
  1791. no_recursive(Config) ->
  1792. AppDir = ?config(apps, Config),
  1793. Name = rebar_test_utils:create_random_name("app1_"),
  1794. Vsn = rebar_test_utils:create_random_vsn(),
  1795. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1796. rebar_test_utils:write_src_file(filename:join(AppDir,src),"rec.erl"),
  1797. RebarConfig1 = [{erlc_compiler,[{recursive,false}]}],
  1798. rebar_test_utils:run_and_check(Config, RebarConfig1, ["compile"],
  1799. {ok, [{app, Name}]}),
  1800. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1801. {ok, Files1} = rebar_utils:list_dir(EbinDir),
  1802. ?assert(false==lists:member("rec.beam",Files1)),
  1803. RebarConfig2 = [{src_dirs,[{"src",[{recursive,false}]}]}],
  1804. rebar_test_utils:run_and_check(Config, RebarConfig2, ["compile"],
  1805. {ok, [{app, Name}]}),
  1806. {ok, Files2} = rebar_utils:list_dir(EbinDir),
  1807. ?assert(false==lists:member("rec.beam",Files2)),
  1808. ok.
  1809. regex_filter_skip(Config) ->
  1810. AppDir = ?config(apps, Config),
  1811. Name = rebar_test_utils:create_random_name("regex_skip"),
  1812. Vsn = rebar_test_utils:create_random_vsn(),
  1813. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1814. rebar_test_utils:write_src_file(filename:join(AppDir,src),"._rec.erl"),
  1815. Expected = filename:join([AppDir, "_build", "default", "lib", Name, "ebin","._rec.beam"]),
  1816. RebarConfig = [],
  1817. try
  1818. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"],
  1819. {ok, [{file, Expected}]}),
  1820. throw(should_not_be_found)
  1821. catch
  1822. %% the file was not found, as desired!
  1823. error:{assertion_failed,_} -> %% OTP =< 17
  1824. ok;
  1825. error:{assert,_} -> %% OTP >= 18
  1826. ok
  1827. end.
  1828. regex_filter_regression(Config) ->
  1829. AppDir = ?config(apps, Config),
  1830. Name = rebar_test_utils:create_random_name("regex_regression"),
  1831. Vsn = rebar_test_utils:create_random_vsn(),
  1832. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1833. rebar_test_utils:write_src_file(filename:join(AppDir,src),"r_f.erl"),
  1834. Expected = filename:join([AppDir, "_build", "default", "lib", Name, "ebin","r_f.beam"]),
  1835. RebarConfig = [],
  1836. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"],
  1837. {ok, [{file, Expected}]}),
  1838. ok.
  1839. app_file_linting(Config) ->
  1840. meck:new(rebar_log, [no_link, passthrough]),
  1841. AppDir = ?config(apps, Config),
  1842. Name = rebar_test_utils:create_random_name("app_file_linting"),
  1843. Vsn = rebar_test_utils:create_random_vsn(),
  1844. rebar_test_utils:create_app(AppDir, Name, Vsn, [foo]),
  1845. _ = rebar_test_utils:run_and_check(Config, [], ["compile"], return),
  1846. History = meck:history(rebar_log),
  1847. Warnings = [{Str, Args} || {_, {rebar_log, log, [warn, Str, Args]}, _} <- History],
  1848. ?assert(none /= proplists:lookup("~p is missing description entry", Warnings)),
  1849. ?assert(none /= proplists:lookup("~p is missing kernel from applications list", Warnings)),
  1850. ?assert(none /= proplists:lookup("~p is missing stdlib from applications list", Warnings)).
  1851. %%
  1852. %% a copy of lib/parsetools/include/yeccpre.hrl so we can test yrl includefile
  1853. yeccpre_hrl() ->
  1854. <<"-type yecc_ret() :: {'error', _} | {'ok', _}.
  1855. -spec parse(Tokens :: list()) -> yecc_ret().
  1856. parse(Tokens) ->
  1857. yeccpars0(Tokens, {no_func, no_line}, 0, [], []).
  1858. -spec parse_and_scan({function() | {atom(), atom()}, [_]}
  1859. | {atom(), atom(), [_]}) -> yecc_ret().
  1860. parse_and_scan({F, A}) ->
  1861. yeccpars0([], {{F, A}, no_line}, 0, [], []);
  1862. parse_and_scan({M, F, A}) ->
  1863. Arity = length(A),
  1864. yeccpars0([], {{fun M:F/Arity, A}, no_line}, 0, [], []).
  1865. -spec format_error(any()) -> [char() | list()].
  1866. format_error(Message) ->
  1867. case io_lib:deep_char_list(Message) of
  1868. true ->
  1869. Message;
  1870. _ ->
  1871. io_lib:write(Message)
  1872. end.
  1873. %% To be used in grammar files to throw an error message to the parser
  1874. %% toplevel. Doesn't have to be exported!
  1875. -compile({nowarn_unused_function, return_error/2}).
  1876. -spec return_error(integer(), any()) -> no_return().
  1877. return_error(Line, Message) ->
  1878. throw({error, {Line, ?MODULE, Message}}).
  1879. -define(CODE_VERSION, \"1.4\").
  1880. yeccpars0(Tokens, Tzr, State, States, Vstack) ->
  1881. try yeccpars1(Tokens, Tzr, State, States, Vstack)
  1882. catch
  1883. error:Error ->
  1884. try yecc_error_type(Error, []) of
  1885. Desc ->
  1886. erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc},
  1887. [])
  1888. catch _:_ -> erlang:raise(error, Error, [])
  1889. end;
  1890. %% Probably thrown from return_error/2:
  1891. throw: {error, {_Line, ?MODULE, _M}} = Error ->
  1892. Error
  1893. end.
  1894. yecc_error_type(function_clause, _) ->
  1895. not_implemented.
  1896. yeccpars1([Token | Tokens], Tzr, State, States, Vstack) ->
  1897. yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens, Tzr);
  1898. yeccpars1([], {{F, A},_Line}, State, States, Vstack) ->
  1899. case apply(F, A) of
  1900. {ok, Tokens, Endline} ->
  1901. yeccpars1(Tokens, {{F, A}, Endline}, State, States, Vstack);
  1902. {eof, Endline} ->
  1903. yeccpars1([], {no_func, Endline}, State, States, Vstack);
  1904. {error, Descriptor, _Endline} ->
  1905. {error, Descriptor}
  1906. end;
  1907. yeccpars1([], {no_func, no_line}, State, States, Vstack) ->
  1908. Line = 999999,
  1909. yeccpars2(State, '$end', States, Vstack, yecc_end(Line), [],
  1910. {no_func, Line});
  1911. yeccpars1([], {no_func, Endline}, State, States, Vstack) ->
  1912. yeccpars2(State, '$end', States, Vstack, yecc_end(Endline), [],
  1913. {no_func, Endline}).
  1914. %% yeccpars1/7 is called from generated code.
  1915. %%
  1916. %% When using the {includefile, Includefile} option, make sure that
  1917. %% yeccpars1/7 can be found by parsing the file without following
  1918. %% include directives. yecc will otherwise assume that an old
  1919. %% yeccpre.hrl is included (one which defines yeccpars1/5).
  1920. yeccpars1(State1, State, States, Vstack, Token0, [Token | Tokens], Tzr) ->
  1921. yeccpars2(State, element(1, Token), [State1 | States],
  1922. [Token0 | Vstack], Token, Tokens, Tzr);
  1923. yeccpars1(State1, State, States, Vstack, Token0, [], {{_F,_A}, _Line}=Tzr) ->
  1924. yeccpars1([], Tzr, State, [State1 | States], [Token0 | Vstack]);
  1925. yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, no_line}) ->
  1926. Line = yecctoken_end_location(Token0),
  1927. yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack],
  1928. yecc_end(Line), [], {no_func, Line});
  1929. yeccpars1(State1, State, States, Vstack, Token0, [], {no_func, Line}) ->
  1930. yeccpars2(State, '$end', [State1 | States], [Token0 | Vstack],
  1931. yecc_end(Line), [], {no_func, Line}).
  1932. %% For internal use only.
  1933. yecc_end({Line,_Column}) ->
  1934. {'$end', Line};
  1935. yecc_end(Line) ->
  1936. {'$end', Line}.
  1937. yecctoken_end_location(Token) ->
  1938. try erl_anno:end_location(element(2, Token)) of
  1939. undefined -> yecctoken_location(Token);
  1940. Loc -> Loc
  1941. catch _:_ -> yecctoken_location(Token)
  1942. end.
  1943. -compile({nowarn_unused_function, yeccerror/1}).
  1944. yeccerror(Token) ->
  1945. Text = yecctoken_to_string(Token),
  1946. Location = yecctoken_location(Token),
  1947. {error, {Location, ?MODULE, [\"syntax error before: \", Text]}}.
  1948. -compile({nowarn_unused_function, yecctoken_to_string/1}).
  1949. yecctoken_to_string(Token) ->
  1950. try erl_scan:text(Token) of
  1951. undefined -> yecctoken2string(Token);
  1952. Txt -> Txt
  1953. catch _:_ -> yecctoken2string(Token)
  1954. end.
  1955. yecctoken_location(Token) ->
  1956. try erl_scan:location(Token)
  1957. catch _:_ -> element(2, Token)
  1958. end.
  1959. -compile({nowarn_unused_function, yecctoken2string/1}).
  1960. yecctoken2string({atom, _, A}) -> io_lib:write_atom(A);
  1961. yecctoken2string({integer,_,N}) -> io_lib:write(N);
  1962. yecctoken2string({float,_,F}) -> io_lib:write(F);
  1963. yecctoken2string({char,_,C}) -> io_lib:write_char(C);
  1964. yecctoken2string({var,_,V}) -> io_lib:format(\"~s\", [V]);
  1965. yecctoken2string({string,_,S}) -> io_lib:write_string(S);
  1966. yecctoken2string({reserved_symbol, _, A}) -> io_lib:write(A);
  1967. yecctoken2string({_Cat, _, Val}) -> io_lib:format(\"~p\", [Val]);
  1968. yecctoken2string({dot, _}) -> \"'.'\";
  1969. yecctoken2string({'$end', _}) -> [];
  1970. yecctoken2string({Other, _}) when is_atom(Other) ->
  1971. io_lib:write_atom(Other);
  1972. yecctoken2string(Other) ->
  1973. io_lib:format(\"~p\", [Other]).
  1974. ">>.