You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1657 line
67 KiB

10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
  1. -module(rebar_compile_SUITE).
  2. -export([suite/0,
  3. init_per_suite/1,
  4. end_per_suite/1,
  5. init_per_testcase/2,
  6. end_per_testcase/2,
  7. init_per_group/2,
  8. end_per_group/2,
  9. all/0,
  10. groups/0,
  11. build_basic_app/1, paths_basic_app/1, clean_basic_app/1,
  12. build_release_apps/1, paths_release_apps/1, clean_release_apps/1,
  13. build_checkout_apps/1, paths_checkout_apps/1,
  14. build_checkout_deps/1, paths_checkout_deps/1,
  15. build_basic_srcdirs/1, paths_basic_srcdirs/1,
  16. build_release_srcdirs/1, paths_release_srcdirs/1,
  17. build_unbalanced_srcdirs/1, paths_unbalanced_srcdirs/1,
  18. build_basic_extra_dirs/1, paths_basic_extra_dirs/1, clean_basic_extra_dirs/1,
  19. build_release_extra_dirs/1, paths_release_extra_dirs/1, clean_release_extra_dirs/1,
  20. build_unbalanced_extra_dirs/1, paths_unbalanced_extra_dirs/1,
  21. build_extra_dirs_in_project_root/1,
  22. paths_extra_dirs_in_project_root/1,
  23. clean_extra_dirs_in_project_root/1,
  24. recompile_when_hrl_changes/1,
  25. recompile_when_included_hrl_changes/1,
  26. recompile_when_opts_change/1,
  27. dont_recompile_when_opts_dont_change/1,
  28. dont_recompile_yrl_or_xrl/1,
  29. deps_in_path/1,
  30. delete_beam_if_source_deleted/1,
  31. checkout_priority/1,
  32. highest_version_of_pkg_dep/1,
  33. parse_transform_test/1,
  34. erl_first_files_test/1,
  35. mib_test/1,
  36. umbrella_mib_first_test/1,
  37. only_default_transitive_deps/1,
  38. clean_all/1,
  39. override_deps/1,
  40. profile_override_deps/1,
  41. deps_build_in_prod/1,
  42. include_file_relative_to_working_directory/1,
  43. include_file_in_src/1,
  44. include_file_relative_to_working_directory_test/1,
  45. include_file_in_src_test/1,
  46. dont_recompile_when_erl_compiler_options_env_does_not_change/1,
  47. recompile_when_erl_compiler_options_env_changes/1,
  48. always_recompile_when_erl_compiler_options_set/1,
  49. recompile_when_parse_transform_inline_changes/1,
  50. recompile_when_parse_transform_as_opt_changes/1,
  51. recursive/1,no_recursive/1]).
  52. -include_lib("common_test/include/ct.hrl").
  53. -include_lib("eunit/include/eunit.hrl").
  54. -include_lib("kernel/include/file.hrl").
  55. suite() ->
  56. [].
  57. all() ->
  58. [{group, basic_app}, {group, release_apps},
  59. {group, checkout_apps}, {group, checkout_deps},
  60. {group, basic_srcdirs}, {group, release_srcdirs}, {group, unbalanced_srcdirs},
  61. {group, basic_extras}, {group, release_extras}, {group, unbalanced_extras},
  62. {group, root_extras},
  63. recompile_when_hrl_changes, recompile_when_included_hrl_changes,
  64. recompile_when_opts_change,
  65. dont_recompile_when_opts_dont_change, dont_recompile_yrl_or_xrl,
  66. delete_beam_if_source_deleted,
  67. deps_in_path, checkout_priority, highest_version_of_pkg_dep,
  68. parse_transform_test, erl_first_files_test, mib_test,
  69. umbrella_mib_first_test, only_default_transitive_deps,
  70. clean_all, override_deps, profile_override_deps, deps_build_in_prod,
  71. include_file_relative_to_working_directory, include_file_in_src,
  72. include_file_relative_to_working_directory_test, include_file_in_src_test,
  73. recompile_when_parse_transform_as_opt_changes,
  74. recompile_when_parse_transform_inline_changes,
  75. %% recompile behaviour when `ERL_COMPILER_OPTIONS` differs prior to 19.x
  76. recursive, no_recursive] ++ recompile_when_env_changes_test().
  77. recompile_when_env_changes_test() ->
  78. _ = code:ensure_loaded(os),
  79. UnSetEnv = erlang:function_exported(os, unsetenv, 1),
  80. _ = code:ensure_loaded(compile),
  81. EnvOpts = erlang:function_exported(compile, env_compiler_options, 0),
  82. case {UnSetEnv, EnvOpts} of
  83. {true, true} ->
  84. [dont_recompile_when_erl_compiler_options_env_does_not_change,
  85. recompile_when_erl_compiler_options_env_changes];
  86. {true, false} -> [always_recompile_when_erl_compiler_options_set];
  87. {false, _} -> []
  88. end.
  89. groups() ->
  90. [{basic_app, [], [build_basic_app, paths_basic_app, clean_basic_app]},
  91. {release_apps, [], [build_release_apps, paths_release_apps, clean_release_apps]},
  92. {checkout_apps, [], [build_checkout_apps, paths_checkout_apps]},
  93. {checkout_deps, [], [build_checkout_deps, paths_checkout_deps]},
  94. {basic_srcdirs, [], [build_basic_srcdirs, paths_basic_srcdirs]},
  95. {release_srcdirs, [], [build_release_srcdirs,
  96. paths_release_srcdirs]},
  97. {unbalanced_srcdirs, [], [build_unbalanced_srcdirs,
  98. paths_unbalanced_srcdirs]},
  99. {basic_extras, [], [build_basic_extra_dirs,
  100. paths_basic_extra_dirs,
  101. clean_basic_extra_dirs]},
  102. {release_extras, [], [build_release_extra_dirs,
  103. paths_release_extra_dirs,
  104. clean_release_extra_dirs]},
  105. {unbalanced_extras, [], [build_unbalanced_extra_dirs,
  106. paths_unbalanced_extra_dirs]},
  107. {root_extras, [], [build_extra_dirs_in_project_root,
  108. paths_extra_dirs_in_project_root,
  109. clean_extra_dirs_in_project_root]}].
  110. init_per_group(basic_app, Config) ->
  111. NewConfig = rebar_test_utils:init_rebar_state(Config, "basic_app_"),
  112. AppDir = ?config(apps, NewConfig),
  113. Name = rebar_test_utils:create_random_name("app1"),
  114. Vsn = rebar_test_utils:create_random_vsn(),
  115. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  116. [{app_names, [Name]}, {vsns, [Vsn]}|NewConfig];
  117. init_per_group(release_apps, Config) ->
  118. NewConfig = rebar_test_utils:init_rebar_state(Config, "release_apps_"),
  119. AppDir = ?config(apps, NewConfig),
  120. Name1 = rebar_test_utils:create_random_name("relapp1_"),
  121. Vsn1 = rebar_test_utils:create_random_vsn(),
  122. rebar_test_utils:create_app(filename:join([AppDir,"apps",Name1]), Name1, Vsn1, [kernel, stdlib]),
  123. Name2 = rebar_test_utils:create_random_name("relapp2_"),
  124. Vsn2 = rebar_test_utils:create_random_vsn(),
  125. rebar_test_utils:create_app(filename:join([AppDir,"apps",Name2]), Name2, Vsn2, [kernel, stdlib]),
  126. [{app_names, [Name1, Name2]}, {vsns, [Vsn1, Vsn2]}|NewConfig];
  127. init_per_group(checkout_apps, Config) ->
  128. NewConfig = rebar_test_utils:init_rebar_state(Config, "checkout_apps_"),
  129. AppDir = ?config(apps, NewConfig),
  130. CheckoutsDir = ?config(checkouts, NewConfig),
  131. Name1 = rebar_test_utils:create_random_name("checkapp1_"),
  132. Vsn1 = rebar_test_utils:create_random_vsn(),
  133. rebar_test_utils:create_app(AppDir, Name1, Vsn1, [kernel, stdlib]),
  134. Name2 = rebar_test_utils:create_random_name("checkapp2_"),
  135. Vsn2 = rebar_test_utils:create_random_vsn(),
  136. rebar_test_utils:create_app(filename:join([CheckoutsDir,Name2]), Name2, Vsn2, [kernel, stdlib]),
  137. [{app_names, [Name1, Name2]}, {vsns, [Vsn1, Vsn2]}|NewConfig];
  138. init_per_group(checkout_deps, Config) ->
  139. NewConfig = rebar_test_utils:init_rebar_state(Config, "checkout_deps_"),
  140. AppDir = ?config(apps, NewConfig),
  141. CheckoutsDir = ?config(checkouts, NewConfig),
  142. DepsDir = filename:join([AppDir, "_build", "default", "lib"]),
  143. Name1 = rebar_test_utils:create_random_name("checkapp1_"),
  144. Vsn1 = rebar_test_utils:create_random_vsn(),
  145. rebar_test_utils:create_app(AppDir, Name1, Vsn1, [kernel, stdlib]),
  146. Name2 = rebar_test_utils:create_random_name("checkapp2_"),
  147. Vsn2 = rebar_test_utils:create_random_vsn(),
  148. rebar_test_utils:create_app(filename:join([CheckoutsDir,Name2]), Name2, Vsn2, [kernel, stdlib]),
  149. rebar_test_utils:create_app(filename:join([DepsDir,Name2]), Name2, Vsn1, [kernel, stdlib]),
  150. [{app_names, [Name1, Name2]}, {vsns, [Vsn1, Vsn2]}|NewConfig];
  151. init_per_group(Group, Config) when Group == basic_srcdirs; Group == basic_extras ->
  152. NewConfig = rebar_test_utils:init_rebar_state(Config, "basic_srcdirs_"),
  153. AppDir = ?config(apps, NewConfig),
  154. Name = rebar_test_utils:create_random_name("app1_"),
  155. Vsn = rebar_test_utils:create_random_vsn(),
  156. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  157. ExtraSrc = io_lib:format("-module(~ts_extra).\n-export([ok/0]).\nok() -> ok.\n", [Name]),
  158. ok = filelib:ensure_dir(filename:join([AppDir, "extra", "dummy"])),
  159. ok = file:write_file(filename:join([AppDir, "extra", io_lib:format("~ts_extra.erl", [Name])]),
  160. ExtraSrc),
  161. [{app_names, [Name]}, {vsns, [Vsn]}|NewConfig];
  162. init_per_group(Group, Config) when Group == release_srcdirs; Group == release_extras ->
  163. NewConfig = rebar_test_utils:init_rebar_state(Config, "release_srcdirs_"),
  164. AppDir = ?config(apps, NewConfig),
  165. Name1 = rebar_test_utils:create_random_name("relapp1_"),
  166. Vsn1 = rebar_test_utils:create_random_vsn(),
  167. rebar_test_utils:create_app(filename:join([AppDir, "apps", Name1]), Name1, Vsn1, [kernel, stdlib]),
  168. Name2 = rebar_test_utils:create_random_name("relapp2_"),
  169. Vsn2 = rebar_test_utils:create_random_vsn(),
  170. rebar_test_utils:create_app(filename:join([AppDir, "apps", Name2]), Name2, Vsn2, [kernel, stdlib]),
  171. ExtraOne = io_lib:format("-module(~ts_extra).\n-export([ok/0]).\nok() -> ok.\n", [Name1]),
  172. ok = filelib:ensure_dir(filename:join([AppDir, "apps", Name1, "extra", "dummy"])),
  173. ok = file:write_file(filename:join([AppDir, "apps", Name1, "extra",
  174. io_lib:format("~ts_extra.erl", [Name1])]),
  175. ExtraOne),
  176. ExtraTwo = io_lib:format("-module(~ts_extra).\n-export([ok/0]).\nok() -> ok.\n", [Name2]),
  177. ok = filelib:ensure_dir(filename:join([AppDir, "apps", Name2, "extra", "dummy"])),
  178. ok = file:write_file(filename:join([AppDir, "apps", Name2, "extra",
  179. io_lib:format("~ts_extra.erl", [Name2])]),
  180. ExtraTwo),
  181. [{app_names, [Name1, Name2]}, {vsns, [Vsn1, Vsn2]}|NewConfig];
  182. init_per_group(Group, Config) when Group == unbalanced_srcdirs; Group == unbalanced_extras ->
  183. NewConfig = rebar_test_utils:init_rebar_state(Config, "unbalanced_srcdirs_"),
  184. AppDir = ?config(apps, NewConfig),
  185. Name1 = rebar_test_utils:create_random_name("relapp1_"),
  186. Vsn1 = rebar_test_utils:create_random_vsn(),
  187. rebar_test_utils:create_app(filename:join([AppDir, "apps", Name1]), Name1, Vsn1, [kernel, stdlib]),
  188. Name2 = rebar_test_utils:create_random_name("relapp2_"),
  189. Vsn2 = rebar_test_utils:create_random_vsn(),
  190. rebar_test_utils:create_app(filename:join([AppDir, "apps", Name2]), Name2, Vsn2, [kernel, stdlib]),
  191. ExtraOne = io_lib:format("-module(~ts_extra).\n-export([ok/0]).\nok() -> ok.\n", [Name1]),
  192. ok = filelib:ensure_dir(filename:join([AppDir, "apps", Name1, "extra", "dummy"])),
  193. ok = file:write_file(filename:join([AppDir, "apps", Name1, "extra",
  194. io_lib:format("~ts_extra.erl", [Name1])]),
  195. ExtraOne),
  196. [{app_names, [Name1, Name2]}, {vsns, [Vsn1, Vsn2]}|NewConfig];
  197. init_per_group(root_extras, Config) ->
  198. NewConfig = rebar_test_utils:init_rebar_state(Config, "root_extras_"),
  199. AppDir = ?config(apps, NewConfig),
  200. Name1 = rebar_test_utils:create_random_name("relapp1_"),
  201. Vsn1 = rebar_test_utils:create_random_vsn(),
  202. rebar_test_utils:create_app(filename:join([AppDir, "apps", Name1]), Name1, Vsn1, [kernel, stdlib]),
  203. Name2 = rebar_test_utils:create_random_name("relapp2_"),
  204. Vsn2 = rebar_test_utils:create_random_vsn(),
  205. rebar_test_utils:create_app(filename:join([AppDir, "apps", Name2]), Name2, Vsn2, [kernel, stdlib]),
  206. Extra = <<"-module(extra).\n-export([ok/0]).\nok() -> ok.\n">>,
  207. ok = filelib:ensure_dir(filename:join([AppDir, "extra", "dummy"])),
  208. ok = file:write_file(filename:join([AppDir, "extra", "extra.erl"]), Extra),
  209. [{app_names, [Name1, Name2]}, {vsns, [Vsn1, Vsn2]}|NewConfig].
  210. end_per_group(_Group, _Config) ->
  211. ok.
  212. init_per_suite(Config) ->
  213. Config.
  214. end_per_suite(_Config) ->
  215. ok.
  216. init_per_testcase(_, Config) ->
  217. case ?config(apps, Config) of
  218. undefined -> rebar_test_utils:init_rebar_state(Config);
  219. _ -> Config
  220. end.
  221. end_per_testcase(_, _Config) ->
  222. catch meck:unload().
  223. %% test cases
  224. build_basic_app(Config) ->
  225. [Name] = ?config(app_names, Config),
  226. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}).
  227. build_release_apps(Config) ->
  228. [Name1, Name2] = ?config(app_names, Config),
  229. rebar_test_utils:run_and_check(
  230. Config, [], ["compile"],
  231. {ok, [{app, Name1}, {app, Name2}]}
  232. ).
  233. build_checkout_apps(Config) ->
  234. [Name1, Name2] = ?config(app_names, Config),
  235. rebar_test_utils:run_and_check(
  236. Config, [], ["compile"],
  237. {ok, [{app, Name1}, {checkout, Name2}]}
  238. ).
  239. build_checkout_deps(Config) ->
  240. AppDir = ?config(apps, Config),
  241. [Name1, Name2] = ?config(app_names, Config),
  242. [_, Vsn2] = ?config(vsns, Config),
  243. Deps = [{list_to_atom(Name2), Vsn2, {git, "", ""}}],
  244. {ok, RebarConfig} = file:consult(rebar_test_utils:create_config(AppDir, [{deps, Deps}])),
  245. rebar_test_utils:run_and_check(
  246. Config, RebarConfig, ["compile"],
  247. {ok, [{app, Name1}, {checkout, Name2}]}
  248. ).
  249. build_basic_srcdirs(Config) ->
  250. AppDir = ?config(apps, Config),
  251. [Name] = ?config(app_names, Config),
  252. RebarConfig = [{erl_opts, [{src_dirs, ["src", "extra"]}]}],
  253. %% check a beam corresponding to the src in the extra src_dir exists
  254. ExtraBeam = filename:join([AppDir, "_build", "default", "lib", Name, "ebin",
  255. io_lib:format("~ts_extra.beam", [Name])]),
  256. %% check the extra src_dir was copied/linked into the _build dir
  257. ExtraDir = filename:join([AppDir, "_build", "default", "lib", Name, "extra"]),
  258. rebar_test_utils:run_and_check(
  259. Config, RebarConfig, ["compile"],
  260. {ok, [{app, Name}, {file, ExtraBeam}, {dir, ExtraDir}]}
  261. ).
  262. build_release_srcdirs(Config) ->
  263. AppDir = ?config(apps, Config),
  264. [Name1, Name2] = ?config(app_names, Config),
  265. RebarConfig = [{erl_opts, [{src_dirs, ["src", "extra"]}]}],
  266. %% check a beam corresponding to the src in the extra src_dir exists
  267. Extra1Beam = filename:join([AppDir, "_build", "default", "lib", Name1, "ebin",
  268. io_lib:format("~ts_extra.beam", [Name1])]),
  269. Extra2Beam = filename:join([AppDir, "_build", "default", "lib", Name2, "ebin",
  270. io_lib:format("~ts_extra.beam", [Name2])]),
  271. %% check the extra src_dir was copied/linked into the _build dir
  272. Extra1Dir = filename:join([AppDir, "_build", "default", "lib", Name1, "extra"]),
  273. Extra2Dir = filename:join([AppDir, "_build", "default", "lib", Name2, "extra"]),
  274. rebar_test_utils:run_and_check(
  275. Config, RebarConfig, ["compile"],
  276. {ok, [{app, Name1}, {app, Name2},
  277. {file, Extra1Beam}, {file, Extra2Beam},
  278. {dir, Extra1Dir}, {dir, Extra2Dir}]}
  279. ).
  280. build_unbalanced_srcdirs(Config) ->
  281. AppDir = ?config(apps, Config),
  282. [Name1, Name2] = ?config(app_names, Config),
  283. RebarConfig = [{erl_opts, [{src_dirs, ["src", "extra"]}]}],
  284. %% check a beam corresponding to the src in the extra src_dir exists
  285. Extra1Beam = filename:join([AppDir, "_build", "default", "lib", Name1, "ebin",
  286. io_lib:format("~ts_extra.beam", [Name1])]),
  287. %% check the extra src_dir was copied/linked into the _build dir
  288. Extra1Dir = filename:join([AppDir, "_build", "default", "lib", Name1, "extra"]),
  289. rebar_test_utils:run_and_check(
  290. Config, RebarConfig, ["compile"],
  291. {ok, [{app, Name1}, {app, Name2}, {file, Extra1Beam}, {dir, Extra1Dir}]}
  292. ),
  293. %% check no extra src_dir were copied/linked into the _build dir
  294. Extra2Dir = filename:join([AppDir, "_build", "default", "lib", Name2, "extra"]),
  295. false = filelib:is_dir(Extra2Dir),
  296. %% check only expected beams are in the ebin dir
  297. {ok, Files} = rebar_utils:list_dir(filename:join([AppDir, "_build", "default", "lib", Name2, "ebin"])),
  298. lists:all(fun(Beam) -> lists:member(Beam, [Name2 ++ ".app", "not_a_real_src_" ++ Name2 ++ ".beam"]) end,
  299. Files).
  300. build_basic_extra_dirs(Config) ->
  301. AppDir = ?config(apps, Config),
  302. [Name] = ?config(app_names, Config),
  303. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  304. %% check a beam corresponding to the src in the extra src_dir exists
  305. ExtraBeam = filename:join([AppDir, "_build", "default", "lib", Name, "extra",
  306. io_lib:format("~ts_extra.beam", [Name])]),
  307. rebar_test_utils:run_and_check(
  308. Config, RebarConfig, ["compile"],
  309. {ok, [{app, Name}, {file, ExtraBeam}]}
  310. ).
  311. build_release_extra_dirs(Config) ->
  312. AppDir = ?config(apps, Config),
  313. [Name1, Name2] = ?config(app_names, Config),
  314. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  315. %% check a beam corresponding to the src in the extra src_dir exists
  316. Extra1Beam = filename:join([AppDir, "_build", "default", "lib", Name1, "extra",
  317. io_lib:format("~ts_extra.beam", [Name1])]),
  318. Extra2Beam = filename:join([AppDir, "_build", "default", "lib", Name2, "extra",
  319. io_lib:format("~ts_extra.beam", [Name2])]),
  320. rebar_test_utils:run_and_check(
  321. Config, RebarConfig, ["compile"],
  322. {ok, [{app, Name1}, {app, Name2}, {file, Extra1Beam}, {file, Extra2Beam}]}
  323. ).
  324. build_unbalanced_extra_dirs(Config) ->
  325. AppDir = ?config(apps, Config),
  326. [Name1, Name2] = ?config(app_names, Config),
  327. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  328. %% check a beam corresponding to the src in the extra src_dir exists
  329. Extra1Beam = filename:join([AppDir, "_build", "default", "lib", Name1, "extra",
  330. io_lib:format("~ts_extra.beam", [Name1])]),
  331. rebar_test_utils:run_and_check(
  332. Config, RebarConfig, ["compile"],
  333. {ok, [{app, Name1}, {app, Name2}, {file, Extra1Beam}]}
  334. ),
  335. %% check no extra src_dir were copied/linked into the _build dir
  336. false = filelib:is_dir(filename:join([AppDir, "_build", "default", "lib", Name2, "extra"])),
  337. %% check only expected beams are in the ebin dir
  338. {ok, Files} = rebar_utils:list_dir(filename:join([AppDir, "_build", "default", "lib", Name2, "ebin"])),
  339. lists:all(fun(Beam) -> lists:member(Beam, [Name2 ++ ".app", "not_a_real_src_" ++ Name2 ++ ".beam"]) end,
  340. Files).
  341. build_extra_dirs_in_project_root(Config) ->
  342. AppDir = ?config(apps, Config),
  343. [Name1, Name2] = ?config(app_names, Config),
  344. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  345. %% check a beam corresponding to the src in the extra src_dir exists
  346. ExtraBeam = filename:join([AppDir, "_build", "default", "extras", "extra", "extra.beam"]),
  347. rebar_test_utils:run_and_check(
  348. Config, RebarConfig, ["compile"],
  349. {ok, [{app, Name1}, {app, Name2}, {file, ExtraBeam}]}
  350. ).
  351. paths_basic_app(Config) ->
  352. [Name] = ?config(app_names, Config),
  353. [Vsn] = ?config(vsns, Config),
  354. {ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return),
  355. code:add_paths(rebar_state:code_paths(State, all_deps)),
  356. ok = application:load(list_to_atom(Name)),
  357. Loaded = application:loaded_applications(),
  358. {_, _, Vsn} = lists:keyfind(list_to_atom(Name), 1, Loaded).
  359. paths_release_apps(Config) ->
  360. [Name1, Name2] = ?config(app_names, Config),
  361. [Vsn1, Vsn2] = ?config(vsns, Config),
  362. {ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return),
  363. code:add_paths(rebar_state:code_paths(State, all_deps)),
  364. ok = application:load(list_to_atom(Name1)),
  365. ok = application:load(list_to_atom(Name2)),
  366. Loaded = application:loaded_applications(),
  367. {_, _, Vsn1} = lists:keyfind(list_to_atom(Name1), 1, Loaded),
  368. {_, _, Vsn2} = lists:keyfind(list_to_atom(Name2), 1, Loaded).
  369. paths_checkout_apps(Config) ->
  370. [Name1, _Name2] = ?config(app_names, Config),
  371. [Vsn1, _Vsn2] = ?config(vsns, Config),
  372. {ok, State} = rebar_test_utils:run_and_check(Config, [], ["compile"], return),
  373. code:add_paths(rebar_state:code_paths(State, all_deps)),
  374. ok = application:load(list_to_atom(Name1)),
  375. Loaded = application:loaded_applications(),
  376. {_, _, Vsn1} = lists:keyfind(list_to_atom(Name1), 1, Loaded).
  377. paths_checkout_deps(Config) ->
  378. AppDir = ?config(apps, Config),
  379. [_Name1, Name2] = ?config(app_names, Config),
  380. [_Vsn1, Vsn2] = ?config(vsns, Config),
  381. %% rebar_test_utils:init_rebar_state/1,2 uses rebar_state:new/3 which
  382. %% maybe incorrectly sets deps to [] (based on `rebar.lock`) instead of
  383. %% to the checkapps
  384. %% until that is sorted out the lock file has to be removed before
  385. %% this test will pass
  386. file:delete(filename:join([AppDir, "rebar.lock"])),
  387. {ok, RebarConfig} = file:consult(filename:join([AppDir, "rebar.config"])),
  388. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  389. code:add_paths(rebar_state:code_paths(State, all_deps)),
  390. ok = application:load(list_to_atom(Name2)),
  391. Loaded = application:loaded_applications(),
  392. {_, _, Vsn2} = lists:keyfind(list_to_atom(Name2), 1, Loaded).
  393. paths_basic_srcdirs(Config) ->
  394. AppDir = ?config(apps, Config),
  395. [Name] = ?config(app_names, Config),
  396. RebarConfig = [{erl_opts, [{src_dirs, ["src", "extra"]}]}],
  397. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  398. code:add_paths(rebar_state:code_paths(State, all_deps)),
  399. Mod = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name]))),
  400. {module, Mod} = code:ensure_loaded(Mod),
  401. Expect = filename:join([AppDir, "_build", "default", "lib", Name, "ebin",
  402. io_lib:format("~ts_extra.beam", [Name])]),
  403. Expect = code:which(Mod).
  404. paths_release_srcdirs(Config) ->
  405. AppDir = ?config(apps, Config),
  406. [Name1, Name2] = ?config(app_names, Config),
  407. RebarConfig = [{erl_opts, [{src_dirs, ["src", "extra"]}]}],
  408. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  409. code:add_paths(rebar_state:code_paths(State, all_deps)),
  410. Mod1 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name1]))),
  411. {module, Mod1} = code:ensure_loaded(Mod1),
  412. Mod2 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name2]))),
  413. {module, Mod2} = code:ensure_loaded(Mod2),
  414. ExpectOne = filename:join([AppDir, "_build", "default", "lib", Name1, "ebin",
  415. io_lib:format("~ts_extra.beam", [Name1])]),
  416. ExpectOne = code:which(Mod1),
  417. ExpectTwo = filename:join([AppDir, "_build", "default", "lib", Name2, "ebin",
  418. io_lib:format("~ts_extra.beam", [Name2])]),
  419. ExpectTwo = code:which(Mod2).
  420. paths_unbalanced_srcdirs(Config) ->
  421. AppDir = ?config(apps, Config),
  422. [Name1, Name2] = ?config(app_names, Config),
  423. RebarConfig = [{erl_opts, [{src_dirs, ["src", "extra"]}]}],
  424. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  425. code:add_paths(rebar_state:code_paths(State, all_deps)),
  426. Mod1 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name1]))),
  427. {module, Mod1} = code:ensure_loaded(Mod1),
  428. Mod2 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name2]))),
  429. {error, nofile} = code:ensure_loaded(Mod2),
  430. ExpectOne = filename:join([AppDir, "_build", "default", "lib", Name1, "ebin",
  431. io_lib:format("~ts_extra.beam", [Name1])]),
  432. ExpectOne = code:which(Mod1).
  433. paths_basic_extra_dirs(Config) ->
  434. AppDir = ?config(apps, Config),
  435. [Name] = ?config(app_names, Config),
  436. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  437. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  438. code:add_paths(rebar_state:code_paths(State, all_deps)),
  439. Mod = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name]))),
  440. {module, Mod} = code:ensure_loaded(Mod),
  441. Expect = filename:join([AppDir, "_build", "default", "lib", Name, "extra",
  442. io_lib:format("~ts_extra.beam", [Name])]),
  443. Expect = code:which(Mod).
  444. paths_release_extra_dirs(Config) ->
  445. AppDir = ?config(apps, Config),
  446. [Name1, Name2] = ?config(app_names, Config),
  447. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  448. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  449. code:add_paths(rebar_state:code_paths(State, all_deps)),
  450. Mod1 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name1]))),
  451. {module, Mod1} = code:ensure_loaded(Mod1),
  452. Mod2 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name2]))),
  453. {module, Mod2} = code:ensure_loaded(Mod2),
  454. ExpectOne = filename:join([AppDir, "_build", "default", "lib", Name1, "extra",
  455. io_lib:format("~ts_extra.beam", [Name1])]),
  456. ExpectOne = code:which(Mod1),
  457. ExpectTwo = filename:join([AppDir, "_build", "default", "lib", Name2, "extra",
  458. io_lib:format("~ts_extra.beam", [Name2])]),
  459. ExpectTwo = code:which(Mod2).
  460. paths_unbalanced_extra_dirs(Config) ->
  461. AppDir = ?config(apps, Config),
  462. [Name1, Name2] = ?config(app_names, Config),
  463. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  464. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  465. code:add_paths(rebar_state:code_paths(State, all_deps)),
  466. Mod1 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name1]))),
  467. {module, Mod1} = code:ensure_loaded(Mod1),
  468. Mod2 = list_to_atom(lists:flatten(io_lib:format("~ts_extra", [Name2]))),
  469. {error, nofile} = code:ensure_loaded(Mod2),
  470. ExpectOne = filename:join([AppDir, "_build", "default", "lib", Name1, "extra",
  471. io_lib:format("~ts_extra.beam", [Name1])]),
  472. ExpectOne = code:which(Mod1).
  473. paths_extra_dirs_in_project_root(Config) ->
  474. AppDir = ?config(apps, Config),
  475. RebarConfig = [{erl_opts, [{extra_src_dirs, ["extra"]}]}],
  476. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], return),
  477. code:add_paths(rebar_state:code_paths(State, all_deps)),
  478. {module, extra} = code:ensure_loaded(extra),
  479. Expect = filename:join([AppDir, "_build", "default", "extras", "extra", "extra.beam"]),
  480. Expect = code:which(extra).
  481. clean_basic_app(Config) ->
  482. [Name] = ?config(app_names, Config),
  483. rebar_test_utils:run_and_check(Config, [], ["clean"], {ok, [{app, Name, invalid}]}).
  484. clean_release_apps(Config) ->
  485. [Name1, Name2] = ?config(app_names, Config),
  486. rebar_test_utils:run_and_check(Config, [], ["clean"],
  487. {ok, [{app, Name1, invalid}, {app, Name2, invalid}]}).
  488. clean_basic_extra_dirs(Config) ->
  489. AppDir = ?config(apps, Config),
  490. [Name] = ?config(app_names, Config),
  491. rebar_test_utils:run_and_check(Config, [], ["clean"], {ok, [{app, Name, invalid}]}),
  492. Beam = lists:flatten(io_lib:format("~ts_extra", [Name])),
  493. false = ec_file:exists(filename:join([AppDir, "_build", "default", "lib", Name, "extras", Beam])).
  494. clean_release_extra_dirs(Config) ->
  495. AppDir = ?config(apps, Config),
  496. [Name1, Name2] = ?config(app_names, Config),
  497. rebar_test_utils:run_and_check(Config, [], ["clean"],
  498. {ok, [{app, Name1, invalid}, {app, Name2, invalid}]}),
  499. Beam1 = lists:flatten(io_lib:format("~ts_extra", [Name1])),
  500. false = ec_file:exists(filename:join([AppDir, "_build", "default", "lib", Name1, "extras", Beam1])),
  501. Beam2 = lists:flatten(io_lib:format("~ts_extra", [Name2])),
  502. false = ec_file:exists(filename:join([AppDir, "_build", "default", "lib", Name2, "extras", Beam2])).
  503. clean_extra_dirs_in_project_root(Config) ->
  504. AppDir = ?config(apps, Config),
  505. [Name1, Name2] = ?config(app_names, Config),
  506. rebar_test_utils:run_and_check(Config, [], ["clean"],
  507. {ok, [{app, Name1, invalid}, {app, Name2, invalid}]}),
  508. false = ec_file:exists(filename:join([AppDir, "_build", "default", "extras"])).
  509. recompile_when_hrl_changes(Config) ->
  510. AppDir = ?config(apps, Config),
  511. Name = rebar_test_utils:create_random_name("app1_"),
  512. Vsn = rebar_test_utils:create_random_vsn(),
  513. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  514. ExtraSrc = <<"-module(test_header_include).\n"
  515. "-export([main/0]).\n"
  516. "-include(\"test_header_include.hrl\").\n"
  517. "main() -> ?SOME_DEFINE.\n">>,
  518. ExtraHeader = <<"-define(SOME_DEFINE, true).\n">>,
  519. HeaderFile = filename:join([AppDir, "src", "test_header_include.hrl"]),
  520. ok = file:write_file(filename:join([AppDir, "src", "test_header_include.erl"]), ExtraSrc),
  521. ok = file:write_file(HeaderFile, ExtraHeader),
  522. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  523. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  524. {ok, Files} = rebar_utils:list_dir(EbinDir),
  525. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  526. || F <- Files, filename:extension(F) == ".beam"],
  527. timer:sleep(1000),
  528. NewExtraHeader = <<"-define(SOME_DEFINE, false).\n">>,
  529. ok = file:write_file(HeaderFile, NewExtraHeader),
  530. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  531. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  532. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  533. || F <- NewFiles, filename:extension(F) == ".beam"],
  534. ?assert(ModTime =/= NewModTime).
  535. recompile_when_included_hrl_changes(Config) ->
  536. AppDir = ?config(apps, Config),
  537. Name = rebar_test_utils:create_random_name("app1_"),
  538. Vsn = rebar_test_utils:create_random_vsn(),
  539. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  540. ExtraSrc = <<"-module(test_header_include).\n"
  541. "-export([main/0]).\n"
  542. "-include(\"test_header_include.hrl\").\n"
  543. "main() -> ?SOME_DEFINE.\n">>,
  544. ExtraHeader = <<"-define(SOME_DEFINE, true).\n">>,
  545. ok = filelib:ensure_dir(filename:join([AppDir, "include", "dummy"])),
  546. HeaderFile = filename:join([AppDir, "include", "test_header_include.hrl"]),
  547. ok = file:write_file(filename:join([AppDir, "src", "test_header_include.erl"]), ExtraSrc),
  548. ok = file:write_file(HeaderFile, ExtraHeader),
  549. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  550. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  551. {ok, Files} = rebar_utils:list_dir(EbinDir),
  552. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  553. || F <- Files, filename:extension(F) == ".beam"],
  554. timer:sleep(1000),
  555. NewExtraHeader = <<"-define(SOME_DEFINE, false).\n">>,
  556. ok = file:write_file(HeaderFile, NewExtraHeader),
  557. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  558. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  559. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  560. || F <- NewFiles, filename:extension(F) == ".beam"],
  561. ?assert(ModTime =/= NewModTime).
  562. recompile_when_opts_change(Config) ->
  563. AppDir = ?config(apps, Config),
  564. Name = rebar_test_utils:create_random_name("app1_"),
  565. Vsn = rebar_test_utils:create_random_vsn(),
  566. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  567. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  568. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  569. {ok, Files} = rebar_utils:list_dir(EbinDir),
  570. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  571. || F <- Files, filename:extension(F) == ".beam"],
  572. timer:sleep(1000),
  573. rebar_test_utils:create_config(AppDir, [{erl_opts, [{d, some_define}]}]),
  574. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  575. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  576. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  577. || F <- NewFiles, filename:extension(F) == ".beam"],
  578. ?assert(ModTime =/= NewModTime).
  579. dont_recompile_when_opts_dont_change(Config) ->
  580. AppDir = ?config(apps, Config),
  581. Name = rebar_test_utils:create_random_name("app1_"),
  582. Vsn = rebar_test_utils:create_random_vsn(),
  583. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  584. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  585. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  586. {ok, Files} = rebar_utils:list_dir(EbinDir),
  587. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  588. || F <- Files, filename:extension(F) == ".beam"],
  589. timer:sleep(1000),
  590. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  591. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  592. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  593. || F <- NewFiles, filename:extension(F) == ".beam"],
  594. ?assertEqual(ModTime, NewModTime).
  595. dont_recompile_yrl_or_xrl(Config) ->
  596. AppDir = ?config(apps, Config),
  597. Name = rebar_test_utils:create_random_name("app1_"),
  598. Vsn = rebar_test_utils:create_random_vsn(),
  599. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  600. Xrl = filename:join([AppDir, "src", "not_a_real_xrl_" ++ Name ++ ".xrl"]),
  601. ok = filelib:ensure_dir(Xrl),
  602. XrlBody =
  603. "Definitions."
  604. "\n\n"
  605. "D = [0-9]"
  606. "\n\n"
  607. "Rules."
  608. "\n\n"
  609. "{D}+ :"
  610. " {token,{integer,TokenLine,list_to_integer(TokenChars)}}."
  611. "\n\n"
  612. "{D}+\\.{D}+((E|e)(\\+|\\-)?{D}+)? :"
  613. " {token,{float,TokenLine,list_to_float(TokenChars)}}."
  614. "\n\n"
  615. "Erlang code.",
  616. ok = ec_file:write(Xrl, XrlBody),
  617. XrlBeam = filename:join([AppDir, "ebin", filename:basename(Xrl, ".xrl") ++ ".beam"]),
  618. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  619. ModTime = filelib:last_modified(XrlBeam),
  620. timer:sleep(1000),
  621. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  622. NewModTime = filelib:last_modified(XrlBeam),
  623. ?assert(ModTime == NewModTime).
  624. delete_beam_if_source_deleted(Config) ->
  625. AppDir = ?config(apps, Config),
  626. Name = rebar_test_utils:create_random_name("app1_"),
  627. Vsn = rebar_test_utils:create_random_vsn(),
  628. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  629. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  630. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  631. _SrcDir = filename:join([AppDir, "_build", "default", "lib", Name, "src"]),
  632. ?assert(filelib:is_regular(filename:join(EbinDir, "not_a_real_src_" ++ Name ++ ".beam"))),
  633. file:delete(filename:join([AppDir, "src", "not_a_real_src_" ++ Name ++ ".erl"])),
  634. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  635. ?assertNot(filelib:is_regular(filename:join(EbinDir, "not_a_real_src_" ++ Name ++ ".beam"))).
  636. deps_in_path(Config) ->
  637. AppDir = ?config(apps, Config),
  638. StartPaths = code:get_path(),
  639. Name = rebar_test_utils:create_random_name("app1_"),
  640. Vsn = rebar_test_utils:create_random_vsn(),
  641. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  642. DepName = rebar_test_utils:create_random_name("dep1_"),
  643. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  644. mock_git_resource:mock([]),
  645. mock_pkg_resource:mock([
  646. {pkgdeps, [{{iolist_to_binary(PkgName), iolist_to_binary(Vsn)}, []}]}
  647. ]),
  648. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [
  649. {list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}},
  650. {list_to_atom(PkgName), Vsn}
  651. ]}]),
  652. {ok, RConf} = file:consult(RConfFile),
  653. %% Make sure apps we look for are not visible
  654. %% Hope not to find src name
  655. ?assertEqual([], [Path || Path <- code:get_path(),
  656. {match, _} <- [re:run(Path, DepName)]]),
  657. %% Hope not to find pkg name in there
  658. ?assertEqual([], [Path || Path <- code:get_path(),
  659. {match, _} <- [re:run(Path, PkgName)]]),
  660. %% Build things
  661. {ok, State} = rebar_test_utils:run_and_check(
  662. Config, RConf, ["compile"],
  663. {ok, [{app, Name}, {dep, DepName}, {dep, PkgName}]}
  664. ),
  665. code:add_paths(rebar_state:code_paths(State, all_deps)),
  666. %% Find src name in there
  667. ?assertNotEqual([], [Path || Path <- code:get_path(),
  668. {match, _} <- [re:run(Path, DepName)]]),
  669. %% find pkg name in there
  670. ?assertNotEqual([], [Path || Path <- code:get_path(),
  671. {match, _} <- [re:run(Path, PkgName)]]),
  672. true = code:set_path(lists:filter(fun(P) -> ec_file:exists(P) end, StartPaths)),
  673. %% Make sure apps we look for are not visible again
  674. %% Hope not to find src name
  675. ?assertEqual([], [Path || Path <- code:get_path(),
  676. {match, _} <- [re:run(Path, DepName)]]),
  677. %% Hope not to find pkg name in there
  678. ?assertEqual([], [Path || Path <- code:get_path(),
  679. {match, _} <- [re:run(Path, PkgName)]]),
  680. %% Rebuild
  681. {ok, State1} = rebar_test_utils:run_and_check(
  682. Config, RConf, ["compile"],
  683. {ok, [{app, Name}, {dep, DepName}, {dep, PkgName}]}
  684. ),
  685. %% Find src name in there
  686. code:add_paths(rebar_state:code_paths(State1, all_deps)),
  687. ?assertNotEqual([], [Path || Path <- code:get_path(),
  688. {match, _} <- [re:run(Path, DepName)]]),
  689. %% find pkg name in there
  690. ?assertNotEqual([], [Path || Path <- code:get_path(),
  691. {match, _} <- [re:run(Path, PkgName)]]).
  692. checkout_priority(Config) ->
  693. AppDir = ?config(apps, Config),
  694. CheckoutsDir = ?config(checkouts, Config),
  695. StartPaths = code:get_path(),
  696. Name = rebar_test_utils:create_random_name("app1_"),
  697. Vsn = rebar_test_utils:create_random_vsn(),
  698. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  699. DepName = rebar_test_utils:create_random_name("dep1_"),
  700. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  701. mock_git_resource:mock([]),
  702. mock_pkg_resource:mock([
  703. {pkgdeps, [{{iolist_to_binary(PkgName), iolist_to_binary(Vsn)}, []}]}
  704. ]),
  705. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [
  706. {list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}},
  707. {list_to_atom(PkgName), Vsn}
  708. ]}]),
  709. {ok, RConf} = file:consult(RConfFile),
  710. %% Build with deps.
  711. rebar_test_utils:run_and_check(
  712. Config, RConf, ["compile"],
  713. {ok, [{app, Name}, {dep, DepName}, {dep, PkgName}]}
  714. ),
  715. %% Build two checkout apps similar to dependencies to be fetched,
  716. %% but on a different version
  717. Vsn2 = rebar_test_utils:create_random_vsn(),
  718. rebar_test_utils:create_app(filename:join([CheckoutsDir,DepName]), DepName, Vsn2, [kernel, stdlib]),
  719. rebar_test_utils:create_app(filename:join([CheckoutsDir,PkgName]), PkgName, Vsn2, [kernel, stdlib]),
  720. %% Rebuild and make sure the checkout apps are in path
  721. code:set_path(StartPaths),
  722. {ok, State} = rebar_test_utils:run_and_check(
  723. Config, RConf, ["compile"],
  724. {ok, [{app, Name}, {checkout, DepName}, {checkout, PkgName}]}
  725. ),
  726. code:add_paths(rebar_state:code_paths(State, all_deps)),
  727. [DepPath] = [Path || Path <- code:get_path(),
  728. {match, _} <- [re:run(Path, DepName)]],
  729. [PkgPath] = [Path || Path <- code:get_path(),
  730. {match, _} <- [re:run(Path, PkgName)]],
  731. {ok, [DepApp]} = file:consult(filename:join([DepPath, DepName ++ ".app"])),
  732. {ok, [PkgApp]} = file:consult(filename:join([PkgPath, PkgName ++ ".app"])),
  733. {application, _, DepProps} = DepApp,
  734. {application, _, PkgProps} = PkgApp,
  735. ?assertEqual(Vsn2, proplists:get_value(vsn, DepProps)),
  736. ?assertEqual(Vsn2, proplists:get_value(vsn, PkgProps)).
  737. highest_version_of_pkg_dep(Config) ->
  738. AppDir = ?config(apps, Config),
  739. Name = rebar_test_utils:create_random_name("app1_"),
  740. Vsn = rebar_test_utils:create_random_vsn(),
  741. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  742. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  743. mock_git_resource:mock([]),
  744. mock_pkg_resource:mock([
  745. {pkgdeps, [{{iolist_to_binary(PkgName), <<"0.1.0">>}, []},
  746. {{iolist_to_binary(PkgName), <<"0.0.1">>}, []},
  747. {{iolist_to_binary(PkgName), <<"0.1.3">>}, []},
  748. {{iolist_to_binary(PkgName), <<"0.1.1">>}, []}]}
  749. ]),
  750. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [list_to_atom(PkgName)]}]),
  751. {ok, RConf} = file:consult(RConfFile),
  752. %% Build with deps.
  753. rebar_test_utils:run_and_check(
  754. Config, RConf, ["compile"],
  755. {ok, [{app, Name}, {dep, PkgName, <<"0.1.3">>}]}
  756. ).
  757. parse_transform_test(Config) ->
  758. AppDir = ?config(apps, Config),
  759. RebarConfig = [{erl_opts, [{parse_transform, pascal}]}],
  760. Name = rebar_test_utils:create_random_name("app1_"),
  761. Vsn = rebar_test_utils:create_random_vsn(),
  762. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  763. ExtraSrc = <<"-module(pascal). "
  764. "-export([parse_transform/2]). "
  765. "parse_transform(Forms, _Options) -> "
  766. "Forms.">>,
  767. ok = file:write_file(filename:join([AppDir, "src", "pascal.erl"]), ExtraSrc),
  768. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  769. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  770. true = filelib:is_file(filename:join([EbinDir, "pascal.beam"])).
  771. erl_first_files_test(Config) ->
  772. AppDir = ?config(apps, Config),
  773. RebarConfig = [{erl_opts, [{parse_transform, mark_time}]},
  774. {erl_first_files, ["src/mark_time.erl",
  775. "src/b.erl",
  776. "src/d.erl",
  777. "src/a.erl"]}],
  778. Name = rebar_test_utils:create_random_name("app1_"),
  779. Vsn = rebar_test_utils:create_random_vsn(),
  780. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  781. rebar_test_utils:write_src_file(AppDir, "a.erl"),
  782. rebar_test_utils:write_src_file(AppDir, "b.erl"),
  783. rebar_test_utils:write_src_file(AppDir, "d.erl"),
  784. rebar_test_utils:write_src_file(AppDir, "e.erl"),
  785. ExtraSrc = <<"-module(mark_time). "
  786. "-export([parse_transform/2]). "
  787. "parse_transform([Form={attribute,_,module,Mod}|Forms], Options) -> "
  788. " [Form, {attribute,1,number, os:timestamp()} | Forms];"
  789. "parse_transform([Form|Forms], Options) -> "
  790. " [Form | parse_transform(Forms, Options)].">>,
  791. ok = file:write_file(filename:join([AppDir, "src", "mark_time.erl"]), ExtraSrc),
  792. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  793. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  794. true = filelib:is_file(filename:join([EbinDir, "mark_time.beam"])),
  795. code:load_abs(filename:join([EbinDir, "a"])),
  796. code:load_abs(filename:join([EbinDir, "b"])),
  797. code:load_abs(filename:join([EbinDir, "d"])),
  798. code:load_abs(filename:join([EbinDir, "e"])),
  799. A = proplists:get_value(number, a:module_info(attributes)),
  800. B = proplists:get_value(number, b:module_info(attributes)),
  801. D = proplists:get_value(number, d:module_info(attributes)),
  802. E = proplists:get_value(number, e:module_info(attributes)),
  803. ?assertEqual([B,D,A,E], lists:sort([A,B,D,E])).
  804. mib_test(Config) ->
  805. AppDir = ?config(apps, Config),
  806. RebarConfig = [{mib_first_files, ["mibs/SIMPLE-MIB.mib"]}],
  807. Name = rebar_test_utils:create_random_name("app1_"),
  808. Vsn = rebar_test_utils:create_random_vsn(),
  809. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  810. MibsSrc = <<"-- SIMPLE-MIB.\n"
  811. "-- This is just a simple MIB used for testing!\n"
  812. "--\n"
  813. "SIMPLE-MIB DEFINITIONS ::= BEGIN\n"
  814. "IMPORTS\n"
  815. " MODULE-IDENTITY, enterprises\n"
  816. " FROM SNMPv2-SMI;\n"
  817. "\n"
  818. "ericsson MODULE-IDENTITY\n"
  819. " LAST-UPDATED\n"
  820. " \"201403060000Z\"\n"
  821. " ORGANIZATION\n"
  822. " \"rebar\"\n"
  823. " CONTACT-INFO\n"
  824. " \"rebar <rebar@example.com>\n"
  825. " or\n"
  826. " whoever is currently responsible for the SIMPLE\n"
  827. " enterprise MIB tree branch (enterprises.999).\"\n"
  828. " DESCRIPTION\n"
  829. " \"This very small module is made available\n"
  830. " for mib-compilation testing.\"\n"
  831. " ::= { enterprises 999 }\n"
  832. "END\n">>,
  833. ok = filelib:ensure_dir(filename:join([AppDir, "mibs", "dummy"])),
  834. ok = file:write_file(filename:join([AppDir, "mibs", "SIMPLE-MIB.mib"]), MibsSrc),
  835. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  836. %% check a bin corresponding to the mib in the mibs dir exists in priv/mibs
  837. PrivMibsDir = filename:join([AppDir, "_build", "default", "lib", Name, "priv", "mibs"]),
  838. true = filelib:is_file(filename:join([PrivMibsDir, "SIMPLE-MIB.bin"])),
  839. %% check a hrl corresponding to the mib in the mibs dir exists in include
  840. true = filelib:is_file(filename:join([AppDir, "include", "SIMPLE-MIB.hrl"])),
  841. %% check the mibs dir was linked into the _build dir
  842. true = filelib:is_dir(filename:join([AppDir, "_build", "default", "lib", Name, "mibs"])).
  843. umbrella_mib_first_test(Config) ->
  844. AppsDir = ?config(apps, Config),
  845. Name = rebar_test_utils:create_random_name("app1_"),
  846. Vsn = rebar_test_utils:create_random_vsn(),
  847. AppDir = filename:join([AppsDir, "apps", Name]),
  848. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  849. MibsSrc = <<"-- SIMPLE-MIB.\n"
  850. "-- This is just a simple MIB used for testing!\n"
  851. "--\n"
  852. "SIMPLE-MIB DEFINITIONS ::= BEGIN\n"
  853. "IMPORTS\n"
  854. " MODULE-IDENTITY, enterprises\n"
  855. " FROM SNMPv2-SMI;\n"
  856. "\n"
  857. "ericsson MODULE-IDENTITY\n"
  858. " LAST-UPDATED\n"
  859. " \"201403060000Z\"\n"
  860. " ORGANIZATION\n"
  861. " \"rebar\"\n"
  862. " CONTACT-INFO\n"
  863. " \"rebar <rebar@example.com>\n"
  864. " or\n"
  865. " whoever is currently responsible for the SIMPLE\n"
  866. " enterprise MIB tree branch (enterprises.999).\"\n"
  867. " DESCRIPTION\n"
  868. " \"This very small module is made available\n"
  869. " for mib-compilation testing.\"\n"
  870. " ::= { enterprises 999 }\n"
  871. "END\n">>,
  872. ok = filelib:ensure_dir(filename:join([AppDir, "mibs", "dummy"])),
  873. ok = file:write_file(filename:join([AppDir, "mibs", "SIMPLE-MIB.mib"]), MibsSrc),
  874. RebarConfig = [{mib_first_files, ["mibs/SIMPLE-MIB.mib"]}],
  875. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  876. %% check a bin corresponding to the mib in the mibs dir exists in priv/mibs
  877. PrivMibsDir = filename:join([AppsDir, "_build", "default", "lib", Name, "priv", "mibs"]),
  878. true = filelib:is_file(filename:join([PrivMibsDir, "SIMPLE-MIB.bin"])),
  879. %% check a hrl corresponding to the mib in the mibs dir exists in include
  880. true = filelib:is_file(filename:join([AppDir, "include", "SIMPLE-MIB.hrl"])),
  881. %% check the mibs dir was linked into the _build dir
  882. true = filelib:is_dir(filename:join([AppsDir, "_build", "default", "lib", Name, "mibs"])).
  883. only_default_transitive_deps(Config) ->
  884. AppDir = ?config(apps, Config),
  885. Name = rebar_test_utils:create_random_name("app1_"),
  886. Vsn = rebar_test_utils:create_random_vsn(),
  887. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  888. GitDeps = rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}]),
  889. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  890. {SrcDeps, _} = rebar_test_utils:flat_deps(GitDeps),
  891. mock_git_resource:mock([{deps, SrcDeps},
  892. {config, [{profiles, [{test, [{deps, [list_to_atom(PkgName)]}]}]}]}]),
  893. mock_pkg_resource:mock([{pkgdeps, [{{iolist_to_binary(PkgName), <<"0.1.0">>}, []}]}]),
  894. Deps = rebar_test_utils:top_level_deps(GitDeps),
  895. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, Deps}]),
  896. {ok, RConf} = file:consult(RConfFile),
  897. %% Build with deps.
  898. rebar_test_utils:run_and_check(
  899. Config, RConf, ["as", "test", "compile"],
  900. {ok, [{app, Name}, {dep, "a", <<"1.0.0">>}, {dep_not_exist, PkgName}]}
  901. ).
  902. clean_all(Config) ->
  903. AppDir = ?config(apps, Config),
  904. Name = rebar_test_utils:create_random_name("app1_"),
  905. Vsn = rebar_test_utils:create_random_vsn(),
  906. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  907. DepName = rebar_test_utils:create_random_name("dep1_"),
  908. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  909. mock_git_resource:mock([]),
  910. mock_pkg_resource:mock([
  911. {pkgdeps, [{{iolist_to_binary(PkgName), iolist_to_binary(Vsn)}, []}]}
  912. ]),
  913. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [
  914. {list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}},
  915. {list_to_atom(PkgName), Vsn}
  916. ]}]),
  917. {ok, RConf} = file:consult(RConfFile),
  918. %% Build things
  919. rebar_test_utils:run_and_check(
  920. Config, RConf, ["compile"],
  921. {ok, [{app, Name}, {app, DepName}, {app, PkgName}]}
  922. ),
  923. %% Clean all
  924. rebar_test_utils:run_and_check(Config, [], ["clean", "--all"],
  925. {ok, [{app, Name, invalid},
  926. {app, DepName, invalid},
  927. {app, PkgName, invalid}]}).
  928. override_deps(Config) ->
  929. mock_git_resource:mock([{deps, [{some_dep, "0.0.1"},{other_dep, "0.0.1"}]}]),
  930. Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]),
  931. TopDeps = rebar_test_utils:top_level_deps(Deps),
  932. RebarConfig = [
  933. {deps, TopDeps},
  934. {overrides, [
  935. {override, some_dep, [
  936. {deps, []}
  937. ]}
  938. ]}
  939. ],
  940. rebar_test_utils:run_and_check(
  941. Config, RebarConfig, ["compile"],
  942. {ok, [{dep, "some_dep"},{dep_not_exist, "other_dep"}]}
  943. ).
  944. profile_override_deps(Config) ->
  945. mock_git_resource:mock([{deps, [{some_dep, "0.0.1"},{other_dep, "0.0.1"}]}]),
  946. Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]),
  947. TopDeps = rebar_test_utils:top_level_deps(Deps),
  948. RebarConfig = [
  949. {deps, TopDeps},
  950. {profiles, [{a,
  951. [{overrides, [
  952. {override, some_dep, [
  953. {deps, []}
  954. ]}
  955. ]}
  956. ]}
  957. ]}],
  958. rebar_test_utils:run_and_check(
  959. Config, RebarConfig, ["as", "a", "compile"],
  960. {ok, [{dep, "some_dep"},{dep_not_exist, "other_dep"}]}
  961. ).
  962. %% verify a deps prod profile is used
  963. %% tested by checking prod hooks run and outputs to default profile dir for dep
  964. %% and prod deps are installed for dep
  965. deps_build_in_prod(Config) ->
  966. AppDir = ?config(apps, Config),
  967. Name = rebar_test_utils:create_random_name("app1_"),
  968. Vsn = rebar_test_utils:create_random_vsn(),
  969. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  970. GitDeps = rebar_test_utils:expand_deps(git, [{"asdf", "1.0.0", []}]),
  971. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  972. {SrcDeps, _} = rebar_test_utils:flat_deps(GitDeps),
  973. mock_git_resource:mock([{deps, SrcDeps},
  974. {config, [{profiles, [{prod, [{pre_hooks, [{compile, "echo whatsup > randomfile"}]},
  975. {deps, [list_to_atom(PkgName)]}]}]}]}]),
  976. mock_pkg_resource:mock([{pkgdeps, [{{iolist_to_binary(PkgName), <<"0.1.0">>}, []}]}]),
  977. Deps = rebar_test_utils:top_level_deps(GitDeps),
  978. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, Deps}]),
  979. {ok, RConf} = file:consult(RConfFile),
  980. %% Build with deps.
  981. rebar_test_utils:run_and_check(
  982. Config, RConf, ["compile"],
  983. {ok, [{app, Name}, {dep, "asdf", <<"1.0.0">>}, {dep, PkgName},
  984. {file, filename:join([AppDir, "_build", "default", "lib", "asdf", "randomfile"])}]}
  985. ).
  986. %% verify that the proper include path is defined
  987. %% according the erlang doc which states:
  988. %% If the filename File is absolute (possibly after variable substitution),
  989. %% the include file with that name is included. Otherwise, the specified file
  990. %% is searched for in the following directories, and in this order:
  991. %% * The current working directory
  992. %% * The directory where the module is being compiled
  993. %% * The directories given by the include option
  994. include_file_relative_to_working_directory(Config) ->
  995. AppDir = ?config(apps, Config),
  996. Name = rebar_test_utils:create_random_name("app1_"),
  997. Vsn = rebar_test_utils:create_random_vsn(),
  998. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  999. Src = <<"-module(test).\n"
  1000. "\n"
  1001. "-include(\"include/test.hrl\").\n"
  1002. "\n"
  1003. "test() -> ?TEST_MACRO.\n"
  1004. "\n">>,
  1005. Include = <<"-define(TEST_MACRO, test).\n">>,
  1006. ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])),
  1007. ok = file:write_file(filename:join([AppDir, "src", "test.erl"]), Src),
  1008. ok = filelib:ensure_dir(filename:join([AppDir, "include", "dummy"])),
  1009. ok = file:write_file(filename:join([AppDir, "include", "test.hrl"]), Include),
  1010. RebarConfig = [],
  1011. rebar_test_utils:run_and_check(Config, RebarConfig,
  1012. ["compile"],
  1013. {ok, [{app, Name}]}).
  1014. include_file_in_src(Config) ->
  1015. AppDir = ?config(apps, Config),
  1016. Name = rebar_test_utils:create_random_name("app1_"),
  1017. Vsn = rebar_test_utils:create_random_vsn(),
  1018. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1019. Src = <<"-module(test).\n"
  1020. "\n"
  1021. "-include(\"test.hrl\").\n"
  1022. "\n"
  1023. "test() -> ?TEST_MACRO.\n"
  1024. "\n">>,
  1025. Include = <<"-define(TEST_MACRO, test).\n">>,
  1026. ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])),
  1027. ok = file:write_file(filename:join([AppDir, "src", "test.erl"]), Src),
  1028. ok = file:write_file(filename:join([AppDir, "src", "test.hrl"]), Include),
  1029. RebarConfig = [],
  1030. rebar_test_utils:run_and_check(Config, RebarConfig,
  1031. ["compile"],
  1032. {ok, [{app, Name}]}).
  1033. %% verify that the proper include path is defined
  1034. %% according the erlang doc which states:
  1035. %% If the filename File is absolute (possibly after variable substitution),
  1036. %% the include file with that name is included. Otherwise, the specified file
  1037. %% is searched for in the following directories, and in this order:
  1038. %% * The current working directory
  1039. %% * The directory where the module is being compiled
  1040. %% * The directories given by the include option
  1041. %%
  1042. %% This test ensures that things keep working when additional directories
  1043. %% are used for apps, such as the test/ directory within the test profile.
  1044. include_file_relative_to_working_directory_test(Config) ->
  1045. AppDir = ?config(apps, Config),
  1046. Name = rebar_test_utils:create_random_name("app1_"),
  1047. Vsn = rebar_test_utils:create_random_vsn(),
  1048. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1049. Src = <<"-module(test).\n"
  1050. "\n"
  1051. "-include(\"include/test.hrl\").\n"
  1052. "\n"
  1053. "test() -> ?TEST_MACRO.\n"
  1054. "\n">>,
  1055. Include = <<"-define(TEST_MACRO, test).\n">>,
  1056. ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])),
  1057. ok = filelib:ensure_dir(filename:join([AppDir, "test", "dummy"])),
  1058. ok = file:write_file(filename:join([AppDir, "test", "test.erl"]), Src),
  1059. ok = filelib:ensure_dir(filename:join([AppDir, "include", "dummy"])),
  1060. ok = file:write_file(filename:join([AppDir, "include", "test.hrl"]), Include),
  1061. RebarConfig = [],
  1062. rebar_test_utils:run_and_check(Config, RebarConfig,
  1063. ["as", "test", "compile"],
  1064. {ok, [{app, Name}]}).
  1065. %% Same as `include_file_in_src/1' but using the `test/' directory
  1066. %% within the test profile.
  1067. include_file_in_src_test(Config) ->
  1068. AppDir = ?config(apps, Config),
  1069. Name = rebar_test_utils:create_random_name("app1_"),
  1070. Vsn = rebar_test_utils:create_random_vsn(),
  1071. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1072. Src = <<"-module(test).\n"
  1073. "\n"
  1074. "-include(\"test.hrl\").\n"
  1075. "\n"
  1076. "test() -> ?TEST_MACRO.\n"
  1077. "\n">>,
  1078. Include = <<"-define(TEST_MACRO, test).\n">>,
  1079. ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])),
  1080. ok = filelib:ensure_dir(filename:join([AppDir, "test", "dummy"])),
  1081. ok = file:write_file(filename:join([AppDir, "test", "test.erl"]), Src),
  1082. ok = file:write_file(filename:join([AppDir, "src", "test.hrl"]), Include),
  1083. RebarConfig = [],
  1084. rebar_test_utils:run_and_check(Config, RebarConfig,
  1085. ["as", "test", "compile"],
  1086. {ok, [{app, Name}]}).
  1087. %% this test sets the env var, compiles, records the file last modified timestamp,
  1088. %% recompiles and compares the file last modified timestamp to ensure it hasn't
  1089. %% changed. this test should run on 19.x+
  1090. dont_recompile_when_erl_compiler_options_env_does_not_change(Config) ->
  1091. %% save existing env to restore after test
  1092. ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"),
  1093. AppDir = ?config(apps, Config),
  1094. Name = rebar_test_utils:create_random_name("erl_compiler_options_"),
  1095. Vsn = rebar_test_utils:create_random_vsn(),
  1096. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1097. true = os:unsetenv("ERL_COMPILER_OPTIONS"),
  1098. true = os:putenv("ERL_COMPILER_OPTIONS", "[{d, some_macro}]"),
  1099. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1100. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1101. {ok, Files} = rebar_utils:list_dir(EbinDir),
  1102. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1103. || F <- Files, filename:extension(F) == ".beam"],
  1104. timer:sleep(1000),
  1105. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1106. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  1107. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1108. || F <- NewFiles, filename:extension(F) == ".beam"],
  1109. ?assert(ModTime == NewModTime),
  1110. %% restore existing env
  1111. case ExistingEnv of
  1112. false -> ok;
  1113. _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv)
  1114. end.
  1115. %% this test compiles, records the file last modified timestamp, sets the env
  1116. %% var, recompiles and compares the file last modified timestamp to ensure it
  1117. %% has changed. this test should run on 19.x+
  1118. recompile_when_erl_compiler_options_env_changes(Config) ->
  1119. %% save existing env to restore after test
  1120. ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"),
  1121. AppDir = ?config(apps, Config),
  1122. Name = rebar_test_utils:create_random_name("erl_compiler_options_"),
  1123. Vsn = rebar_test_utils:create_random_vsn(),
  1124. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1125. true = os:unsetenv("ERL_COMPILER_OPTIONS"),
  1126. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1127. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1128. {ok, Files} = rebar_utils:list_dir(EbinDir),
  1129. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1130. || F <- Files, filename:extension(F) == ".beam"],
  1131. timer:sleep(1000),
  1132. true = os:putenv("ERL_COMPILER_OPTIONS", "[{d, some_macro}]"),
  1133. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1134. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  1135. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1136. || F <- NewFiles, filename:extension(F) == ".beam"],
  1137. ?assert(ModTime =/= NewModTime),
  1138. %% restore existing env
  1139. case ExistingEnv of
  1140. false -> ok;
  1141. _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv)
  1142. end.
  1143. %% this test sets the env var, compiles, records the file last modified
  1144. %% timestamp, recompiles and compares the file last modified timestamp to
  1145. %% ensure it has changed. this test should run on 18.x
  1146. always_recompile_when_erl_compiler_options_set(Config) ->
  1147. %% save existing env to restore after test
  1148. ExistingEnv = os:getenv("ERL_COMPILER_OPTIONS"),
  1149. AppDir = ?config(apps, Config),
  1150. Name = rebar_test_utils:create_random_name("erl_compiler_options_"),
  1151. Vsn = rebar_test_utils:create_random_vsn(),
  1152. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1153. true = os:unsetenv("ERL_COMPILER_OPTIONS"),
  1154. true = os:putenv("ERL_COMPILER_OPTIONS", "[{d, some_macro}]"),
  1155. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1156. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1157. {ok, Files} = rebar_utils:list_dir(EbinDir),
  1158. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1159. || F <- Files, filename:extension(F) == ".beam"],
  1160. timer:sleep(1000),
  1161. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1162. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  1163. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1164. || F <- NewFiles, filename:extension(F) == ".beam"],
  1165. ?assert(ModTime =/= NewModTime),
  1166. %% restore existing env
  1167. case ExistingEnv of
  1168. false -> ok;
  1169. _ -> os:putenv("ERL_COMPILER_OPTIONS", ExistingEnv)
  1170. end.
  1171. recompile_when_parse_transform_inline_changes(Config) ->
  1172. AppDir = ?config(apps, Config),
  1173. Name = rebar_test_utils:create_random_name("parse_transform_inline_"),
  1174. Vsn = rebar_test_utils:create_random_vsn(),
  1175. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1176. ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])),
  1177. ModSrc = <<"-module(example).\n"
  1178. "-export([foo/2]).\n"
  1179. "-compile([{parse_transform, example_parse_transform}]).\n"
  1180. "foo(_, _) -> ok.">>,
  1181. ok = file:write_file(filename:join([AppDir, "src", "example.erl"]),
  1182. ModSrc),
  1183. ParseTransform = <<"-module(example_parse_transform).\n"
  1184. "-export([parse_transform/2]).\n"
  1185. "parse_transform(AST, _) -> AST.\n">>,
  1186. ok = file:write_file(filename:join([AppDir, "src", "example_parse_transform.erl"]),
  1187. ParseTransform),
  1188. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1189. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1190. {ok, Files} = rebar_utils:list_dir(EbinDir),
  1191. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1192. || F <- Files, filename:basename(F, ".beam") == "example"],
  1193. timer:sleep(1000),
  1194. NewParseTransform = <<"-module(example_parse_transform).\n"
  1195. "-export([parse_transform/2]).\n"
  1196. "parse_transform(AST, _) -> identity(AST).\n"
  1197. "identity(AST) -> AST.\n">>,
  1198. ok = file:write_file(filename:join([AppDir, "src", "example_parse_transform.erl"]),
  1199. NewParseTransform),
  1200. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1201. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  1202. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1203. || F <- NewFiles, filename:basename(F, ".beam") == "example"],
  1204. ?assert(ModTime =/= NewModTime).
  1205. recompile_when_parse_transform_as_opt_changes(Config) ->
  1206. AppDir = ?config(apps, Config),
  1207. Name = rebar_test_utils:create_random_name("parse_transform_opt_"),
  1208. Vsn = rebar_test_utils:create_random_vsn(),
  1209. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1210. ok = filelib:ensure_dir(filename:join([AppDir, "src", "dummy"])),
  1211. ModSrc = <<"-module(example).\n"
  1212. "-export([foo/2]).\n"
  1213. "foo(_, _) -> ok.">>,
  1214. ok = file:write_file(filename:join([AppDir, "src", "example.erl"]),
  1215. ModSrc),
  1216. ParseTransform = <<"-module(example_parse_transform).\n"
  1217. "-export([parse_transform/2]).\n"
  1218. "parse_transform(AST, _) -> AST.">>,
  1219. ok = file:write_file(filename:join([AppDir, "src", "example_parse_transform.erl"]),
  1220. ParseTransform),
  1221. RebarConfig = [{erl_opts, [{parse_transform, example_parse_transform}]}],
  1222. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  1223. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1224. {ok, Files} = rebar_utils:list_dir(EbinDir),
  1225. ModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1226. || F <- Files, filename:basename(F, ".beam") == "example"],
  1227. timer:sleep(1000),
  1228. NewParseTransform = <<"-module(example_parse_transform).\n"
  1229. "-export([parse_transform/2]).\n"
  1230. "parse_transform(AST, _) -> identity(AST).\n"
  1231. "identity(AST) -> AST.">>,
  1232. ok = file:write_file(filename:join([AppDir, "src", "example_parse_transform.erl"]),
  1233. NewParseTransform),
  1234. rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name}]}),
  1235. {ok, NewFiles} = rebar_utils:list_dir(EbinDir),
  1236. NewModTime = [filelib:last_modified(filename:join([EbinDir, F]))
  1237. || F <- NewFiles, filename:basename(F, ".beam") == "example"],
  1238. ?assert(ModTime =/= NewModTime).
  1239. recursive(Config) ->
  1240. AppDir = ?config(apps, Config),
  1241. Name = rebar_test_utils:create_random_name("app1_"),
  1242. Vsn = rebar_test_utils:create_random_vsn(),
  1243. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1244. rebar_test_utils:write_src_file(filename:join(AppDir,src),"rec.erl"),
  1245. rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}),
  1246. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1247. {ok, Files} = rebar_utils:list_dir(EbinDir),
  1248. ?assert(lists:member("rec.beam",Files)).
  1249. no_recursive(Config) ->
  1250. AppDir = ?config(apps, Config),
  1251. Name = rebar_test_utils:create_random_name("app1_"),
  1252. Vsn = rebar_test_utils:create_random_vsn(),
  1253. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  1254. rebar_test_utils:write_src_file(filename:join(AppDir,src),"rec.erl"),
  1255. RebarConfig1 = [{erlc_compiler,[{recursive,false}]}],
  1256. rebar_test_utils:run_and_check(Config, RebarConfig1, ["compile"],
  1257. {ok, [{app, Name}]}),
  1258. EbinDir = filename:join([AppDir, "_build", "default", "lib", Name, "ebin"]),
  1259. {ok, Files1} = rebar_utils:list_dir(EbinDir),
  1260. ?assert(false==lists:member("rec.beam",Files1)),
  1261. RebarConfig2 = [{src_dirs,[{"src",[{recursive,false}]}]}],
  1262. rebar_test_utils:run_and_check(Config, RebarConfig2, ["compile"],
  1263. {ok, [{app, Name}]}),
  1264. {ok, Files2} = rebar_utils:list_dir(EbinDir),
  1265. ?assert(false==lists:member("rec.beam",Files2)),
  1266. ok.