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.

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