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.

396 lines
16 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. -module(rebar_plugins_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. all/0,
  8. compile_plugins/1,
  9. compile_global_plugins/1,
  10. complex_plugins/1,
  11. list/1,
  12. upgrade/1,
  13. upgrade_project_plugin/1,
  14. sub_app_plugins/1,
  15. sub_app_plugin_overrides/1,
  16. project_plugins/1,
  17. use_checkout_plugins/1]).
  18. -include_lib("common_test/include/ct.hrl").
  19. -include_lib("eunit/include/eunit.hrl").
  20. -include_lib("kernel/include/file.hrl").
  21. suite() ->
  22. [].
  23. init_per_suite(Config) ->
  24. Config.
  25. end_per_suite(_Config) ->
  26. ok.
  27. init_per_testcase(_, Config) ->
  28. rebar_test_utils:init_rebar_state(Config).
  29. end_per_testcase(_, _Config) ->
  30. catch meck:unload().
  31. all() ->
  32. [compile_plugins, compile_global_plugins, complex_plugins, list, upgrade, upgrade_project_plugin,
  33. sub_app_plugins, sub_app_plugin_overrides, project_plugins, use_checkout_plugins].
  34. %% Tests that compiling a project installs and compiles the plugins of deps
  35. compile_plugins(Config) ->
  36. AppDir = ?config(apps, Config),
  37. Name = rebar_test_utils:create_random_name("app1_"),
  38. Vsn = rebar_test_utils:create_random_vsn(),
  39. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  40. DepName = rebar_test_utils:create_random_name("dep1_"),
  41. PluginName = rebar_test_utils:create_random_name("plugin1_"),
  42. Plugins = rebar_test_utils:expand_deps(git, [{PluginName, Vsn, []}]),
  43. {SrcDeps, _} = rebar_test_utils:flat_deps(Plugins),
  44. mock_git_resource:mock([{deps, SrcDeps}]),
  45. mock_pkg_resource:mock([{pkgdeps, [{{list_to_binary(DepName), list_to_binary(Vsn)}, []}]},
  46. {config, [{plugins, [
  47. {list_to_atom(PluginName),
  48. {git, "http://site.com/user/"++PluginName++".git",
  49. {tag, Vsn}}}]}]}]),
  50. RConfFile =
  51. rebar_test_utils:create_config(AppDir,
  52. [{deps, [
  53. list_to_atom(DepName)
  54. ]}]),
  55. {ok, RConf} = file:consult(RConfFile),
  56. %% Build with deps.
  57. rebar_test_utils:run_and_check(
  58. Config, RConf, ["compile"],
  59. {ok, [{app, Name}, {plugin, PluginName}, {dep, DepName}]}
  60. ).
  61. %% Tests that compiling a project installs and compiles the global plugins
  62. compile_global_plugins(Config) ->
  63. AppDir = ?config(apps, Config),
  64. GlobalDir = filename:join(AppDir, "global"),
  65. GlobalConfigDir = filename:join([GlobalDir, ".config", "rebar3"]),
  66. GlobalConfig = filename:join([GlobalDir, ".config", "rebar3", "rebar.config"]),
  67. meck:new(rebar_dir, [passthrough]),
  68. meck:expect(rebar_dir, global_config, fun() -> GlobalConfig end),
  69. meck:expect(rebar_dir, global_cache_dir, fun(_) -> GlobalDir end),
  70. Name = rebar_test_utils:create_random_name("app1_"),
  71. Vsn = rebar_test_utils:create_random_vsn(),
  72. Vsn2 = rebar_test_utils:create_random_vsn(),
  73. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  74. DepName = rebar_test_utils:create_random_name("dep1_"),
  75. PluginName = rebar_test_utils:create_random_name("plugin1_"),
  76. mock_git_resource:mock([{deps, [{list_to_atom(PluginName), Vsn},
  77. {list_to_atom(PluginName), Vsn2},
  78. {{iolist_to_binary(DepName), iolist_to_binary(Vsn)}, []}]}]),
  79. rebar_test_utils:create_config(GlobalConfigDir,
  80. [{plugins, [
  81. {list_to_atom(PluginName), {git, "http://site.com/user/"++PluginName++".git", {tag, Vsn}}}
  82. ]}]),
  83. RConfFile =
  84. rebar_test_utils:create_config(AppDir,
  85. [{deps, [
  86. {list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}}
  87. ]},
  88. {plugins, [
  89. {list_to_atom(PluginName), {git, "http://site.com/user/"++PluginName++".git", {tag, Vsn2}}}
  90. ]}]),
  91. {ok, RConf} = file:consult(RConfFile),
  92. %% Runs global plugin install
  93. rebar3:init_config(),
  94. %% Build with deps.
  95. rebar_test_utils:run_and_check(
  96. Config, RConf, ["compile"],
  97. {ok, [{app, Name},
  98. {global_plugin, PluginName, Vsn},
  99. {plugin, PluginName, Vsn2},
  100. {dep, DepName}]}
  101. ),
  102. meck:unload(rebar_dir).
  103. %% Tests installing of plugin with transitive deps
  104. complex_plugins(Config) ->
  105. AppDir = ?config(apps, Config),
  106. meck:new(rebar_dir, [passthrough]),
  107. Name = rebar_test_utils:create_random_name("app1_"),
  108. Vsn = rebar_test_utils:create_random_vsn(),
  109. Vsn2 = rebar_test_utils:create_random_vsn(),
  110. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  111. DepName = rebar_test_utils:create_random_name("dep1_"),
  112. DepName2 = rebar_test_utils:create_random_name("dep2_"),
  113. DepName3 = rebar_test_utils:create_random_name("dep3_"),
  114. PluginName = rebar_test_utils:create_random_name("plugin1_"),
  115. Deps = rebar_test_utils:expand_deps(git, [{PluginName, Vsn2, [{DepName2, Vsn,
  116. [{DepName3, Vsn, []}]}]}
  117. ,{DepName, Vsn, []}]),
  118. {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
  119. mock_git_resource:mock([{deps, SrcDeps}]),
  120. RConfFile =
  121. rebar_test_utils:create_config(AppDir,
  122. [{deps, [
  123. {list_to_atom(DepName), {git, "http://site.com/user/"++DepName++".git", {tag, Vsn}}}
  124. ]},
  125. {plugins, [
  126. {list_to_atom(PluginName), {git, "http://site.com/user/"++PluginName++".git", {tag, Vsn2}}}
  127. ]}]),
  128. {ok, RConf} = file:consult(RConfFile),
  129. %% Build with deps.
  130. rebar_test_utils:run_and_check(
  131. Config, RConf, ["compile"],
  132. {ok, [{app, Name},
  133. {plugin, PluginName, Vsn2},
  134. {plugin, DepName2},
  135. {plugin, DepName3},
  136. {dep, DepName}]}
  137. ),
  138. meck:unload(rebar_dir).
  139. list(Config) ->
  140. rebar_test_utils:run_and_check(
  141. Config, [], ["plugins", "list"],
  142. {ok, []}
  143. ).
  144. upgrade(Config) ->
  145. AppDir = ?config(apps, Config),
  146. Name = rebar_test_utils:create_random_name("app1_"),
  147. Vsn = rebar_test_utils:create_random_vsn(),
  148. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  149. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  150. mock_git_resource:mock([]),
  151. mock_pkg_resource:mock([
  152. {pkgdeps, [{{iolist_to_binary(PkgName), <<"0.1.0">>}, []},
  153. {{iolist_to_binary(PkgName), <<"0.0.1">>}, []},
  154. {{iolist_to_binary(PkgName), <<"0.1.1">>}, []}]}
  155. ]),
  156. RConfFile = rebar_test_utils:create_config(AppDir, [{plugins, [list_to_atom(PkgName)]}]),
  157. {ok, RConf} = file:consult(RConfFile),
  158. %% Build with deps.
  159. rebar_test_utils:run_and_check(
  160. Config, RConf, ["compile"],
  161. {ok, [{app, Name}, {plugin, PkgName, <<"0.1.1">>}]}
  162. ),
  163. catch mock_pkg_resource:unmock(),
  164. mock_pkg_resource:mock([
  165. {pkgdeps, [{{iolist_to_binary(PkgName), <<"0.1.0">>}, []},
  166. {{iolist_to_binary(PkgName), <<"0.0.1">>}, []},
  167. {{iolist_to_binary(PkgName), <<"0.1.3">>}, []},
  168. {{iolist_to_binary(PkgName), <<"0.1.1">>}, []}]},
  169. {upgrade, [PkgName]}
  170. ]),
  171. %% Build with deps.
  172. rebar_test_utils:run_and_check(
  173. Config, RConf, ["plugins", "upgrade", PkgName],
  174. {ok, [{app, Name}, {plugin, PkgName, <<"0.1.3">>}]}
  175. ).
  176. upgrade_project_plugin(Config) ->
  177. AppDir = ?config(apps, Config),
  178. Name = rebar_test_utils:create_random_name("app1_"),
  179. Vsn = rebar_test_utils:create_random_vsn(),
  180. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  181. PkgName = rebar_test_utils:create_random_name("pkg1_"),
  182. mock_git_resource:mock([]),
  183. mock_pkg_resource:mock([
  184. {pkgdeps, [{{iolist_to_binary(PkgName), <<"0.1.0">>}, []},
  185. {{iolist_to_binary(PkgName), <<"0.0.1">>}, []},
  186. {{iolist_to_binary(PkgName), <<"0.1.1">>}, []}]}
  187. ]),
  188. RConfFile = rebar_test_utils:create_config(AppDir, [{project_plugins, [list_to_atom(PkgName)]}]),
  189. {ok, RConf} = file:consult(RConfFile),
  190. %% Build with deps.
  191. rebar_test_utils:run_and_check(
  192. Config, RConf, ["compile"],
  193. {ok, [{app, Name}, {plugin, PkgName, <<"0.1.1">>}]}
  194. ),
  195. catch mock_pkg_resource:unmock(),
  196. mock_pkg_resource:mock([
  197. {pkgdeps, [{{iolist_to_binary(PkgName), <<"0.1.0">>}, []},
  198. {{iolist_to_binary(PkgName), <<"0.0.1">>}, []},
  199. {{iolist_to_binary(PkgName), <<"0.1.3">>}, []},
  200. {{iolist_to_binary(PkgName), <<"0.1.1">>}, []}]},
  201. {upgrade, [PkgName]}
  202. ]),
  203. %% Build with deps.
  204. rebar_test_utils:run_and_check(
  205. Config, RConf, ["plugins", "upgrade", PkgName],
  206. {ok, [{app, Name}, {plugin, PkgName, <<"0.1.3">>}]}
  207. ).
  208. sub_app_plugins(Config) ->
  209. AppDir = ?config(apps, Config),
  210. Name = rebar_test_utils:create_random_name("sub_app1_"),
  211. Vsn = rebar_test_utils:create_random_vsn(),
  212. DepName = rebar_test_utils:create_random_name("dep1_"),
  213. PluginName = rebar_test_utils:create_random_name("plugin1_"),
  214. mock_pkg_resource:mock([{pkgdeps, [{{list_to_binary(DepName), list_to_binary(Vsn)}, []},
  215. {{list_to_binary(PluginName), list_to_binary(Vsn)}, []}]}]),
  216. SubAppsDir = filename:join([AppDir, "apps", Name]),
  217. rebar_test_utils:create_app(SubAppsDir, Name, Vsn, [kernel, stdlib]),
  218. rebar_test_utils:create_config(SubAppsDir, [{deps, [{list_to_binary(DepName), list_to_binary(Vsn)}]},
  219. {plugins, [list_to_atom(PluginName)]}]),
  220. RConfFile =
  221. rebar_test_utils:create_config(AppDir,
  222. [{deps, [
  223. list_to_atom(DepName)
  224. ]}]),
  225. {ok, RConf} = file:consult(RConfFile),
  226. %% Build with deps.
  227. rebar_test_utils:run_and_check(
  228. Config, RConf, ["compile"],
  229. {ok, [{app, Name}, {dep, DepName}, {plugin, PluginName}]}
  230. ).
  231. %% Tests that overrides in a dep that includes a plugin are applied to plugin fetching
  232. sub_app_plugin_overrides(Config) ->
  233. AppDir = ?config(apps, Config),
  234. Name = rebar_test_utils:create_random_name("sub_app1_"),
  235. Vsn = rebar_test_utils:create_random_vsn(),
  236. Dep2Name = rebar_test_utils:create_random_name("dep2_"),
  237. DepName = rebar_test_utils:create_random_name("dep1_"),
  238. PluginName = rebar_test_utils:create_random_name("plugin1_"),
  239. Vsn2 = rebar_test_utils:create_random_vsn(),
  240. Deps = rebar_test_utils:expand_deps(git, [{PluginName, Vsn, [{DepName, Vsn, []}]},
  241. {DepName, Vsn, []}]),
  242. {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
  243. mock_git_resource:mock([{deps, SrcDeps}]),
  244. mock_pkg_resource:mock([{pkgdeps, [{{list_to_binary(Dep2Name), list_to_binary(Vsn)}, []}]},
  245. {config, [{plugins, [{list_to_atom(PluginName),
  246. {git, "http://site.com/user/"++PluginName++".git",
  247. {tag, Vsn}}}]},
  248. %% Dep2 overrides the plugin's deps to have vsn2 of dep1
  249. {overrides, [{override, list_to_atom(PluginName),
  250. [{deps, [{list_to_atom(DepName),
  251. {git, "http://site.com/user/"++DepName++".git",
  252. {tag, Vsn2}}}]}]}]}]}]),
  253. SubAppsDir = filename:join([AppDir, "apps", Name]),
  254. rebar_test_utils:create_app(SubAppsDir, Name, Vsn, [kernel, stdlib]),
  255. RConfFile = rebar_test_utils:create_config(AppDir, [{deps, [{list_to_binary(Dep2Name), list_to_binary(Vsn)}]}]),
  256. {ok, RConf} = file:consult(RConfFile),
  257. %% Build with deps.
  258. rebar_test_utils:run_and_check(
  259. Config, RConf, ["compile"],
  260. {ok, [{app, Name}, {dep, Dep2Name, Vsn}, {plugin, DepName, Vsn2}, {plugin, PluginName}]}
  261. ).
  262. %% Check that project plugins are first in providers even if they override defaults but that
  263. %% normal plugins do not
  264. project_plugins(Config) ->
  265. AppDir = ?config(apps, Config),
  266. Name = rebar_test_utils:create_random_name("app1_"),
  267. Vsn = rebar_test_utils:create_random_vsn(),
  268. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  269. DepName = rebar_test_utils:create_random_name("dep1_"),
  270. PluginName = "compile_plugin",
  271. PluginName2 = "release",
  272. Plugins = rebar_test_utils:expand_deps(git, [{PluginName, Vsn, []}, {PluginName2, Vsn, []}]),
  273. {SrcDeps, _} = rebar_test_utils:flat_deps(Plugins),
  274. mock_git_resource:mock([{deps, SrcDeps}], create_plugin),
  275. mock_pkg_resource:mock([{pkgdeps, [{{list_to_binary(DepName), list_to_binary(Vsn)}, []}]},
  276. {config, [{plugins, [
  277. {list_to_atom(PluginName),
  278. {git, "http://site.com/user/"++PluginName++".git",
  279. {tag, Vsn}}}]}]}]),
  280. RConfFile =
  281. rebar_test_utils:create_config(AppDir,
  282. [{deps, [
  283. list_to_atom(DepName)
  284. ]},
  285. {project_plugins, [
  286. {list_to_atom(PluginName2),
  287. {git, "http://site.com/user/"++PluginName2++".git",
  288. {tag, Vsn}}}]}]),
  289. {ok, RConf} = file:consult(RConfFile),
  290. %% Build with deps.
  291. {ok, State} = rebar_test_utils:run_and_check(
  292. Config, RConf, ["compile"],
  293. {ok, [{app, Name}, {plugin, PluginName}, {plugin, PluginName2}, {dep, DepName}]}
  294. ),
  295. %% Should have 2 release providers but only 1 compile provider
  296. Release = [P || P <- rebar_state:providers(State), providers:impl(P) =:= release, providers:namespace(P) =:= default],
  297. Compile = [P || P <- rebar_state:providers(State), providers:impl(P) =:= compile, providers:namespace(P) =:= default],
  298. ?assertEqual(length(Release), 2),
  299. ?assertEqual(length(Compile), 1).
  300. use_checkout_plugins(Config) ->
  301. AppDir = ?config(apps, Config),
  302. Name = rebar_test_utils:create_random_name("app1_"),
  303. Vsn = rebar_test_utils:create_random_vsn(),
  304. rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
  305. PluginName = "checkedout",
  306. CheckoutsDir = filename:join(AppDir, "_checkouts/checkedout"),
  307. rebar_test_utils:create_plugin(CheckoutsDir, PluginName, "1.0.0", []),
  308. RConfFile =
  309. rebar_test_utils:create_config(AppDir,
  310. [{deps, []},
  311. {plugins, [list_to_atom(PluginName)]}]),
  312. {ok, RConf} = file:consult(RConfFile),
  313. %% Verify we can run the plugin
  314. ?assertMatch({ok, _}, rebar_test_utils:run_and_check(
  315. Config, RConf, ["checkedout"],
  316. {ok, []}
  317. )).