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.

1522 lines
61 KiB

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