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.

644 lines
25 KiB

  1. -module(rebar_profiles_SUITE).
  2. -export([init_per_suite/1,
  3. end_per_suite/1,
  4. init_per_testcase/2,
  5. end_per_testcase/2,
  6. all/0,
  7. profile_new_key/1,
  8. profile_merge_keys/1,
  9. profile_merge_umbrella_keys/1,
  10. explicit_profile_deduplicate_deps/1,
  11. implicit_profile_deduplicate_deps/1,
  12. all_deps_code_paths/1,
  13. profile_merges/1,
  14. same_profile_deduplication/1,
  15. stack_deduplication/1,
  16. add_to_profile/1,
  17. add_to_existing_profile/1,
  18. profiles_remain_applied_with_config_present/1,
  19. deduplicated_paths/1,
  20. test_profile_applied_at_completion/1,
  21. test_profile_applied_before_compile/1,
  22. test_profile_applied_before_eunit/1,
  23. test_profile_applied_to_apps/1,
  24. test_profile_erl_opts_order_1/1,
  25. test_profile_erl_opts_order_2/1,
  26. test_profile_erl_opts_order_3/1,
  27. test_profile_erl_opts_order_4/1,
  28. test_profile_erl_opts_order_5/1,
  29. test_erl_opts_debug_info/1,
  30. test_profile_erl_opts_precedence/1,
  31. first_files_exception/1]).
  32. -include_lib("common_test/include/ct.hrl").
  33. -include_lib("eunit/include/eunit.hrl").
  34. -include_lib("kernel/include/file.hrl").
  35. all() ->
  36. [profile_new_key, profile_merge_keys, profile_merge_umbrella_keys,
  37. all_deps_code_paths, profile_merges,
  38. explicit_profile_deduplicate_deps, implicit_profile_deduplicate_deps,
  39. same_profile_deduplication, stack_deduplication,
  40. add_to_profile, add_to_existing_profile,
  41. profiles_remain_applied_with_config_present,
  42. deduplicated_paths,
  43. test_profile_applied_at_completion,
  44. test_profile_applied_before_compile,
  45. test_profile_applied_before_eunit,
  46. test_profile_applied_to_apps,
  47. test_profile_erl_opts_order_1,
  48. test_profile_erl_opts_order_2,
  49. test_profile_erl_opts_order_3,
  50. test_profile_erl_opts_order_4,
  51. test_profile_erl_opts_order_5,
  52. test_erl_opts_debug_info,
  53. test_profile_erl_opts_precedence,
  54. first_files_exception].
  55. init_per_suite(Config) ->
  56. application:start(meck),
  57. Config.
  58. end_per_suite(_Config) ->
  59. application:stop(meck).
  60. init_per_testcase(_, Config) ->
  61. rebar_test_utils:init_rebar_state(Config, "profiles_").
  62. end_per_testcase(_, Config) ->
  63. meck:unload(),
  64. Config.
  65. profile_new_key(Config) ->
  66. AppDir = ?config(apps, Config),
  67. AllDeps = rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}
  68. ,{"b", "1.0.0", []}]),
  69. {SrcDeps, []} = rebar_test_utils:flat_deps(AllDeps),
  70. mock_git_resource:mock([{deps, SrcDeps}]),
  71. Name = rebar_test_utils:create_random_name("profile_new_key_"),
  72. Vsn = rebar_test_utils:create_random_vsn(),
  73. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  74. Deps = rebar_test_utils:top_level_deps(
  75. rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}
  76. ,{"b", "1.0.0", []}])),
  77. ct:pal("Deps ~p", [Deps]),
  78. RebarConfig = [{profiles,
  79. [{ct,
  80. [{deps, Deps}]}]}],
  81. rebar_test_utils:run_and_check(Config, RebarConfig,
  82. ["as", "ct", "compile"], {ok, [{app, Name}
  83. ,{dep, "a", "1.0.0"}
  84. ,{dep, "b", "1.0.0"}]}).
  85. profile_merge_keys(Config) ->
  86. AppDir = ?config(apps, Config),
  87. AllDeps = rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}
  88. ,{"b", "1.0.0", []}
  89. ,{"b", "2.0.0", []}]),
  90. {SrcDeps, []} = rebar_test_utils:flat_deps(AllDeps),
  91. mock_git_resource:mock([{deps, SrcDeps}]),
  92. Name = rebar_test_utils:create_random_name("profile_new_key_"),
  93. Vsn = rebar_test_utils:create_random_vsn(),
  94. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  95. Deps = rebar_test_utils:top_level_deps(
  96. rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}
  97. ,{"b", "1.0.0", []}])),
  98. ProfileDeps = rebar_test_utils:top_level_deps(
  99. rebar_test_utils:expand_deps(git, [{"b", "2.0.0", []}])),
  100. RebarConfig = [{deps, Deps},
  101. {profiles,
  102. [{ct,
  103. [{deps, ProfileDeps}]}]}],
  104. rebar_test_utils:run_and_check(Config, RebarConfig,
  105. ["as", "ct", "compile"], {ok, [{app, Name}
  106. ,{dep, "a", "1.0.0"}
  107. ,{dep, "b", "2.0.0"}]}).
  108. profile_merge_umbrella_keys(Config) ->
  109. AppDir = ?config(apps, Config),
  110. ct:pal("Path: ~s", [AppDir]),
  111. Name = rebar_test_utils:create_random_name("profile_merge_umbrella_keys"),
  112. Vsn = rebar_test_utils:create_random_vsn(),
  113. SubAppDir = filename:join([AppDir, "apps", Name]),
  114. RebarConfig = [{vals, [{a,1},{b,1}]},
  115. {profiles,
  116. [{ct,
  117. [{vals, [{a,1},{b,2}]}]}]}],
  118. SubRebarConfig = [{vals, []},
  119. {profiles, [{ct, [{vals, [{c,1}]}]}]}],
  120. rebar_test_utils:create_app(SubAppDir, Name, Vsn, [kernel, stdlib]),
  121. rebar_test_utils:create_config(SubAppDir, SubRebarConfig),
  122. {ok, RebarConfigRead} = file:consult(rebar_test_utils:create_config(AppDir, RebarConfig)),
  123. {ok, State} = rebar_test_utils:run_and_check(
  124. Config, RebarConfigRead, ["as", "ct", "compile"], return
  125. ),
  126. [ProjectApp] = rebar_state:project_apps(State),
  127. ?assertEqual(Name, binary_to_list(rebar_app_info:name(ProjectApp))),
  128. Opts = rebar_app_info:opts(ProjectApp),
  129. ?assertEqual([{a,1},{b,2},{b,1},{c,1}], dict:fetch(vals, Opts)),
  130. ok.
  131. explicit_profile_deduplicate_deps(Config) ->
  132. AppDir = ?config(apps, Config),
  133. AllDeps = rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}
  134. ,{"a", "2.0.0", []}
  135. ,{"b", "1.0.0", []}
  136. ,{"b", "2.0.0", []}]),
  137. {SrcDeps, []} = rebar_test_utils:flat_deps(AllDeps),
  138. mock_git_resource:mock([{deps, SrcDeps}]),
  139. Name = rebar_test_utils:create_random_name("explicit_profile_deduplicate_deps_"),
  140. Vsn = rebar_test_utils:create_random_vsn(),
  141. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  142. FooDeps = rebar_test_utils:top_level_deps(
  143. rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []},
  144. {"b", "2.0.0", []}])),
  145. BarDeps = rebar_test_utils:top_level_deps(
  146. rebar_test_utils:expand_deps(git, [{"b", "1.0.0", []}])),
  147. RebarConfig = [{profiles,
  148. [{foo,
  149. [{deps, FooDeps}]},
  150. {bar,
  151. [{deps, BarDeps}]}]}],
  152. rebar_test_utils:run_and_check(Config, RebarConfig,
  153. ["as", "bar,foo,bar", "compile"], {ok, [{app, Name}
  154. ,{dep, "a", "1.0.0"}
  155. ,{dep, "b", "1.0.0"}]}).
  156. implicit_profile_deduplicate_deps(Config) ->
  157. AppDir = ?config(apps, Config),
  158. AllDeps = rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}
  159. ,{"a", "2.0.0", []}
  160. ,{"b", "1.0.0", []}
  161. ,{"b", "2.0.0", []}]),
  162. {SrcDeps, []} = rebar_test_utils:flat_deps(AllDeps),
  163. mock_git_resource:mock([{deps, SrcDeps}]),
  164. Name = rebar_test_utils:create_random_name("implicit_profile_deduplicate_deps_"),
  165. Vsn = rebar_test_utils:create_random_vsn(),
  166. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  167. TestDeps = rebar_test_utils:top_level_deps(
  168. rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []},
  169. {"b", "2.0.0", []}])),
  170. ProfileDeps = rebar_test_utils:top_level_deps(
  171. rebar_test_utils:expand_deps(git, [{"b", "1.0.0", []}])),
  172. RebarConfig = [{profiles,
  173. [{test,
  174. [{deps, TestDeps}]},
  175. {bar,
  176. [{deps, ProfileDeps}]}]}],
  177. rebar_test_utils:run_and_check(Config, RebarConfig,
  178. ["as", "test,bar", "eunit"], {ok, [{app, Name}
  179. ,{dep, "a", "1.0.0"}
  180. ,{dep, "b", "1.0.0"}]}).
  181. all_deps_code_paths(Config) ->
  182. AppDir = ?config(apps, Config),
  183. AllDeps = rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}
  184. ,{"b", "2.0.0", []}]),
  185. {SrcDeps, []} = rebar_test_utils:flat_deps(AllDeps),
  186. mock_git_resource:mock([{deps, SrcDeps}]),
  187. Name = rebar_test_utils:create_random_name("all_deps_code_paths"),
  188. Vsn = rebar_test_utils:create_random_vsn(),
  189. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  190. Deps = rebar_test_utils:top_level_deps(
  191. rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}])),
  192. ProfileDeps = rebar_test_utils:top_level_deps(
  193. rebar_test_utils:expand_deps(git, [{"b", "2.0.0", []}])),
  194. RebarConfig = [{deps, Deps},
  195. {profiles,
  196. [{all_deps_test,
  197. [{deps, ProfileDeps}]}]}],
  198. os:putenv("REBAR_PROFILE", "all_deps_test"),
  199. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig,
  200. ["compile"], {ok, [{app, Name}
  201. ,{dep, "a", "1.0.0"}
  202. ,{dep, "b", "2.0.0"}]}),
  203. os:putenv("REBAR_PROFILE", ""),
  204. Paths = rebar_state:code_paths(State, all_deps),
  205. Path = lists:reverse(["_build", "all_deps_test", "lib", "b", "ebin"]),
  206. ?assert(lists:any(fun(X) ->
  207. Path =:= lists:sublist(lists:reverse(filename:split(X)), 5)
  208. end, Paths)).
  209. profile_merges(_Config) ->
  210. RebarConfig = [{test1, [{key1, 1, 2}, key2]},
  211. {test2, "hello"},
  212. {test3, [key3]},
  213. {test4, "oldvalue"},
  214. {test5, [{key5, true}]},
  215. {test6, [{key6, false}]},
  216. {profiles,
  217. [{profile1,
  218. [{test1, [{key3, 5}, key1]}]},
  219. {profile2, [{test2, "goodbye"},
  220. {test3, []},
  221. {test4, []},
  222. {test5, [{key5, false}]},
  223. {test6, [{key6, true}]}
  224. ]}]}],
  225. State = rebar_state:new(RebarConfig),
  226. State1 = rebar_state:apply_profiles(State, [profile1, profile2]),
  227. %% Combine lists
  228. ?assertEqual(lists:sort([key1, key2, {key1, 1, 2}, {key3, 5}]),
  229. lists:sort(rebar_state:get(State1, test1))),
  230. %% Use new value for strings
  231. "goodbye" = rebar_state:get(State1, test2),
  232. %% Check that a newvalue of []/"" doesn't override non-string oldvalues
  233. [key3] = rebar_state:get(State1, test3),
  234. [] = rebar_state:get(State1, test4),
  235. [{key5, false}, {key5, true}] = rebar_state:get(State1, test5),
  236. [{key6, true}, {key6, false}] = rebar_state:get(State1, test6).
  237. same_profile_deduplication(_Config) ->
  238. RebarConfig = [{test1, [{key1, 1, 2}, key2]},
  239. {test2, [foo]},
  240. {test3, [key3]},
  241. {profiles,
  242. [{profile1,
  243. [{test1, [{key3, 5}, {key2, "hello"}]},
  244. {test2, [bar]},
  245. {test3, []}
  246. ]}]
  247. }],
  248. State = rebar_state:new(RebarConfig),
  249. State1 = rebar_state:apply_profiles(State, [profile1, profile1, profile1]),
  250. ?assertEqual([default, profile1], rebar_state:current_profiles(State1)),
  251. Test1 = rebar_state:get(State1, test1),
  252. %% Combine lists
  253. ?assertEqual(lists:sort([key2, {key1, 1, 2}, {key3, 5}, {key2, "hello"}]),
  254. lists:sort(Test1)),
  255. %% Key2 from profile1 overrides key2 from default profile
  256. ?assertEqual("hello", proplists:get_value(key2, Test1)),
  257. %% Check that a newvalue of []/"" doesn't override non-string oldvalues
  258. ?assertEqual([key3], rebar_state:get(State1, test3)),
  259. ?assertEqual([bar, foo], rebar_state:get(State1, test2)).
  260. stack_deduplication(_Config) ->
  261. RebarConfig = [
  262. {test_key, default},
  263. {test_list, [ {foo, default} ]},
  264. {profiles, [
  265. {a, [
  266. {test_key, a},
  267. {test_list, [ {foo, a} ]}
  268. ]},
  269. {b, [
  270. {test_key, b},
  271. {test_list, [ {foo, b} ]}
  272. ]},
  273. {c, [
  274. {test_key, c},
  275. {test_list, [ {foo, c} ]}
  276. ]},
  277. {d, [
  278. {test_key, d},
  279. {test_list, [ {foo, d} ]}
  280. ]},
  281. {e, [
  282. {test_key, e},
  283. {test_list, [ {foo, e} ]}
  284. ]}
  285. ]}
  286. ],
  287. State = rebar_state:new(RebarConfig),
  288. State1 = rebar_state:apply_profiles(State, [a, b, c, d, e, a, e, b]),
  289. ?assertEqual(b, rebar_state:get(State1, test_key)),
  290. TestList = rebar_state:get(State1, test_list),
  291. ?assertEqual(
  292. [{foo, b}, {foo, e}, {foo, a}, {foo, d}, {foo, c}, {foo, default} ],
  293. TestList
  294. ),
  295. ?assertEqual(b, proplists:get_value(foo, TestList)).
  296. add_to_profile(_Config) ->
  297. RebarConfig = [{foo, true}, {bar, false}],
  298. State = rebar_state:new(RebarConfig),
  299. State1 = rebar_state:add_to_profile(State, test, [{foo, false}]),
  300. State2 = rebar_state:apply_profiles(State1, test),
  301. Opts = rebar_state:opts(State2),
  302. lists:map(fun(K) -> false = dict:fetch(K, Opts) end, [foo, bar]).
  303. add_to_existing_profile(_Config) ->
  304. RebarConfig = [{foo, true}, {bar, false}, {profiles, [
  305. {test, [{foo, false}]}
  306. ]}],
  307. State = rebar_state:new(RebarConfig),
  308. State1 = rebar_state:add_to_profile(State, test, [{baz, false}]),
  309. State2 = rebar_state:apply_profiles(State1, test),
  310. Opts = rebar_state:opts(State2),
  311. lists:map(fun(K) -> false = dict:fetch(K, Opts) end, [foo, bar, baz]).
  312. profiles_remain_applied_with_config_present(Config) ->
  313. AppDir = ?config(apps, Config),
  314. Name = rebar_test_utils:create_random_name("profiles_remain_applied_"),
  315. Vsn = rebar_test_utils:create_random_vsn(),
  316. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  317. RebarConfig = [{erl_opts, []}, {profiles, [
  318. {not_ok, [{erl_opts, [{d, not_ok}]}]}
  319. ]}],
  320. rebar_test_utils:create_config(AppDir, RebarConfig),
  321. rebar_test_utils:run_and_check(Config, RebarConfig,
  322. ["as", "not_ok", "compile"], {ok, [{app, Name}]}),
  323. Path = filename:join([AppDir, "_build", "not_ok", "lib", Name, "ebin"]),
  324. code:add_patha(Path),
  325. Mod = list_to_atom("not_a_real_src_" ++ Name),
  326. true = lists:member({d, not_ok}, proplists:get_value(options, Mod:module_info(compile), [])).
  327. deduplicated_paths(Config) ->
  328. AppDir = ?config(apps, Config),
  329. Name = rebar_test_utils:create_random_name("deduplicated_paths_"),
  330. Vsn = rebar_test_utils:create_random_vsn(),
  331. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  332. RebarConfig = [],
  333. rebar_test_utils:create_config(AppDir, RebarConfig),
  334. rebar_test_utils:run_and_check(Config, RebarConfig,
  335. ["as", "a,b,c,d,e,a,e,b", "compile"],
  336. {ok, [{app, Name}]}),
  337. Path = filename:join([AppDir, "_build", "c+d+a+e+b", "lib", Name, "ebin"]),
  338. ?assert(filelib:is_dir(Path)).
  339. test_profile_applied_at_completion(Config) ->
  340. AppDir = ?config(apps, Config),
  341. Name = rebar_test_utils:create_random_name("test_profile_at_completion_"),
  342. Vsn = rebar_test_utils:create_random_vsn(),
  343. rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]),
  344. RebarConfig = [{erl_opts, [{d, some_define}]}],
  345. rebar_test_utils:create_config(AppDir, RebarConfig),
  346. {ok, State} = rebar_test_utils:run_and_check(Config,
  347. RebarConfig,
  348. ["eunit"],
  349. return),
  350. [App] = rebar_state:project_apps(State),
  351. ErlOpts = rebar_app_info:get(App, erl_opts),
  352. true = lists:member({d, 'TEST'}, ErlOpts).
  353. test_profile_applied_before_compile(Config) ->
  354. AppDir = ?config(apps, Config),
  355. Name = rebar_test_utils:create_random_name("test_profile_before_compile_"),
  356. Vsn = rebar_test_utils:create_random_vsn(),
  357. rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]),
  358. RebarConfig = [{erl_opts, [{d, some_define}]}],
  359. rebar_test_utils:create_config(AppDir, RebarConfig),
  360. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["eunit"], {ok, [{app, Name}]}),
  361. code:add_paths(rebar_state:code_paths(State, all_deps)),
  362. S = list_to_atom("not_a_real_src_" ++ Name),
  363. true = lists:member({d, 'TEST'}, proplists:get_value(options, S:module_info(compile), [])).
  364. test_profile_applied_before_eunit(Config) ->
  365. AppDir = ?config(apps, Config),
  366. Name = rebar_test_utils:create_random_name("test_profile_before_eunit_"),
  367. Vsn = rebar_test_utils:create_random_vsn(),
  368. rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]),
  369. RebarConfig = [{erl_opts, [{d, some_define}]}],
  370. rebar_test_utils:create_config(AppDir, RebarConfig),
  371. {ok, State} = rebar_test_utils:run_and_check(Config, RebarConfig, ["eunit"], {ok, [{app, Name}]}),
  372. code:add_paths(rebar_state:code_paths(State, all_deps)),
  373. T = list_to_atom("not_a_real_src_" ++ Name ++ "_tests"),
  374. true = lists:member({d, 'TEST'}, proplists:get_value(options, T:module_info(compile), [])).
  375. test_profile_applied_to_apps(Config) ->
  376. AppDir = ?config(apps, Config),
  377. Name = rebar_test_utils:create_random_name("test_profile_applied_to_apps_"),
  378. Vsn = rebar_test_utils:create_random_vsn(),
  379. rebar_test_utils:create_eunit_app(AppDir, Name, Vsn, [kernel, stdlib]),
  380. RebarConfig = [{erl_opts, [{d, some_define}]}],
  381. rebar_test_utils:create_config(AppDir, RebarConfig),
  382. {ok, State} = rebar_test_utils:run_and_check(Config,
  383. RebarConfig,
  384. ["eunit"],
  385. return),
  386. Apps = rebar_state:project_apps(State),
  387. lists:foreach(fun(App) ->
  388. Opts = rebar_app_info:opts(App),
  389. ErlOpts = dict:fetch(erl_opts, Opts),
  390. true = lists:member({d, 'TEST'}, ErlOpts)
  391. end, Apps).
  392. test_profile_erl_opts_order_1(Config) ->
  393. Opts = get_compiled_profile_erl_opts([default], Config),
  394. Opt = last_erl_opt(Opts, [warn_export_all, nowarn_export_all], undefined),
  395. undefined = Opt.
  396. test_profile_erl_opts_order_2(Config) ->
  397. Opts = get_compiled_profile_erl_opts([strict], Config),
  398. Opt = last_erl_opt(Opts, [warn_export_all, nowarn_export_all], undefined),
  399. warn_export_all = Opt.
  400. test_profile_erl_opts_order_3(Config) ->
  401. Opts = get_compiled_profile_erl_opts([loose], Config),
  402. Opt = last_erl_opt(Opts, [warn_export_all, nowarn_export_all], undefined),
  403. nowarn_export_all = Opt.
  404. test_profile_erl_opts_order_4(Config) ->
  405. Opts = get_compiled_profile_erl_opts([strict, loose], Config),
  406. Opt = last_erl_opt(Opts, [warn_export_all, nowarn_export_all], undefined),
  407. nowarn_export_all = Opt.
  408. test_profile_erl_opts_order_5(Config) ->
  409. Opts = get_compiled_profile_erl_opts([loose, strict], Config),
  410. Opt = last_erl_opt(Opts, [warn_export_all, nowarn_export_all], undefined),
  411. warn_export_all = Opt.
  412. test_erl_opts_debug_info(_Config) ->
  413. ToOpts = fun(List) -> rebar_opts:erl_opts(dict:from_list([{erl_opts, List}])) end,
  414. ?assertEqual([debug_info,a,b,c],
  415. ToOpts([a,b,c])),
  416. ?assertEqual([{debug_info,{mod,123}},a,b,c,debug_info],
  417. ToOpts([{debug_info,{mod,123}},a,b,c,debug_info])),
  418. ?assertEqual([a,b,debug_info,c],
  419. ToOpts([no_debug_info,a,b,debug_info,c])),
  420. ?assertEqual([a,b,c],
  421. ToOpts([debug_info,a,b,no_debug_info,c])),
  422. ?assertEqual([a,b,c,debug_info],
  423. ToOpts([{debug_info_key, "12345"},a,b,
  424. no_debug_info,c,debug_info])),
  425. ?assertEqual([a,b,c],
  426. ToOpts([{debug_info,{mod,123}},{debug_info_key, "12345"},
  427. a,no_debug_info,b,c,debug_info,no_debug_info])),
  428. ?assertEqual([a,b,c,{debug_info_key,"123"}],
  429. ToOpts([{debug_info_key, "12345"},a,b,no_debug_info,debug_info,
  430. c,{debug_info_key, "123"}])),
  431. ?assertEqual([{debug_info_key,"12345"},a,b,c,{debug_info,{mod,"123"}}],
  432. ToOpts([debug_info,{debug_info_key,"12345"},a,
  433. no_debug_info,b,c,{debug_info,{mod,"123"}}])),
  434. ok.
  435. test_profile_erl_opts_precedence(Config) ->
  436. AppDir = ?config(apps, Config),
  437. Name = rebar_test_utils:create_random_name("profile_new_key_"),
  438. Vsn = rebar_test_utils:create_random_vsn(),
  439. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  440. RebarConfig = [{erl_opts, [no_debug_info]},
  441. {profiles, [
  442. {test, [{erl_opts, [debug_info, {d,'HI'}]}]},
  443. {other, [{erl_opts, [debug_info, {d,'HI'}]}]}
  444. ]}],
  445. {ok, State1} = rebar_test_utils:run_and_check(
  446. Config, RebarConfig, ["as", "test", "compile"], return
  447. ),
  448. {ok, State2} = rebar_test_utils:run_and_check(
  449. Config, RebarConfig, ["as", "other", "compile"], return
  450. ),
  451. {ok, State3} = rebar_test_utils:run_and_check(
  452. Config, RebarConfig, ["compile"], return
  453. ),
  454. Opts1 = rebar_state:opts(State1),
  455. Opts2 = rebar_state:opts(State2),
  456. Opts3 = rebar_state:opts(State3),
  457. ErlOpts1 = rebar_opts:erl_opts(Opts1),
  458. ErlOpts2 = rebar_opts:erl_opts(Opts2),
  459. ErlOpts3 = rebar_opts:erl_opts(Opts3),
  460. ?assertEqual([{d,'TEST'}, debug_info, {d,'HI'}], ErlOpts1),
  461. ?assertEqual([debug_info, {d,'HI'}], ErlOpts2),
  462. ?assertEqual([], ErlOpts3),
  463. ok.
  464. first_files_exception(_Config) ->
  465. RebarConfig = [{erl_first_files, ["c","a","b"]},
  466. {mib_first_files, ["c","a","b"]},
  467. {other, ["c","a","b"]},
  468. {profiles,
  469. [{profile2, [{erl_first_files, ["a","e"]},
  470. {mib_first_files, ["a","e"]},
  471. {other, ["a","e"]}
  472. ]}]}],
  473. State = rebar_state:new(RebarConfig),
  474. State1 = rebar_state:apply_profiles(State, [profile2]),
  475. %% Combine lists
  476. ?assertEqual(["a","b","c","e"], rebar_state:get(State1, other)),
  477. %% there is no specific reason not to dedupe "a" here aside from "this is how it is"
  478. ?assertEqual(["c","a","b","a","e"], rebar_state:get(State1, erl_first_files)),
  479. ?assertEqual(["c","a","b","a","e"], rebar_state:get(State1, mib_first_files)),
  480. ok.
  481. get_compiled_profile_erl_opts(Profiles, Config) ->
  482. AppDir = ?config(apps, Config),
  483. PStrs = [atom_to_list(P) || P <- Profiles],
  484. Name = rebar_test_utils:create_random_name(
  485. lists:flatten(["erl_opts_order_" | [[S, $_] || S <- PStrs]])),
  486. Vsn = rebar_test_utils:create_random_vsn(),
  487. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  488. RebarConfig = [
  489. {erl_opts, [warnings_as_errors, {d, profile_default}]},
  490. {profiles, [
  491. {strict, [{erl_opts, [warn_export_all, {d, profile_strict}]}]},
  492. {loose, [{erl_opts, [nowarn_export_all, {d, profile_loose}]}]} ]}],
  493. rebar_test_utils:create_config(AppDir, RebarConfig),
  494. Command = case Profiles of
  495. [] ->
  496. ["compile"];
  497. [default] ->
  498. ["compile"];
  499. _ ->
  500. ["as", rebar_string:join(PStrs, ","), "compile"]
  501. end,
  502. {ok, State} = rebar_test_utils:run_and_check(
  503. Config, RebarConfig, Command, {ok, [{app, Name}]}),
  504. code:add_paths(rebar_state:code_paths(State, all_deps)),
  505. Mod = list_to_atom(Name),
  506. proplists:get_value(options, Mod:module_info(compile), []).
  507. % macro definitions get special handling
  508. last_erl_opt([{d, Macro} = Opt | Opts], Targets, Last) ->
  509. case lists:any(erl_opt_macro_match_fun(Macro), Targets) of
  510. true ->
  511. last_erl_opt(Opts, Targets, Opt);
  512. _ ->
  513. last_erl_opt(Opts, Targets, Last)
  514. end;
  515. last_erl_opt([{d, Macro, _} = Opt | Opts], Targets, Last) ->
  516. case lists:any(erl_opt_macro_match_fun(Macro), Targets) of
  517. true ->
  518. last_erl_opt(Opts, Targets, Opt);
  519. _ ->
  520. last_erl_opt(Opts, Targets, Last)
  521. end;
  522. last_erl_opt([Opt | Opts], Targets, Last) ->
  523. case lists:member(Opt, Targets) of
  524. true ->
  525. last_erl_opt(Opts, Targets, Opt);
  526. _ ->
  527. last_erl_opt(Opts, Targets, Last)
  528. end;
  529. last_erl_opt([], _, Last) ->
  530. Last.
  531. erl_opt_macro_match_fun(Macro) ->
  532. fun({d, M}) ->
  533. M == Macro;
  534. ({d, M, _}) ->
  535. M == Macro;
  536. (_) ->
  537. false
  538. end.