25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

123 satır
4.3 KiB

10 yıl önce
10 yıl önce
10 yıl önce
10 yıl önce
10 yıl önce
10 yıl önce
10 yıl önce
10 yıl önce
10 yıl önce
  1. -module(rebar_prv_plugins_upgrade).
  2. -behaviour(provider).
  3. -export([init/1,
  4. do/1,
  5. format_error/1]).
  6. -include("rebar.hrl").
  7. -include_lib("providers/include/providers.hrl").
  8. -define(PROVIDER, upgrade).
  9. -define(NAMESPACE, plugins).
  10. -define(DEPS, []).
  11. -spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
  12. init(State) ->
  13. State1 = rebar_state:add_provider(
  14. State,
  15. providers:create([
  16. {name, ?PROVIDER},
  17. {module, ?MODULE},
  18. {namespace, ?NAMESPACE},
  19. {bare, true},
  20. {deps, ?DEPS},
  21. {example, "rebar3 plugins upgrade <plugin>"},
  22. {short_desc, "Upgrade plugins"},
  23. {desc, "List or upgrade plugins"},
  24. {opts, [{plugin, undefined, undefined, string,
  25. "Plugin to upgrade"}]}])),
  26. {ok, State1}.
  27. -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
  28. do(State) ->
  29. {Args, _} = rebar_state:command_parsed_args(State),
  30. case proplists:get_value(plugin, Args, none) of
  31. none ->
  32. ?PRV_ERROR(no_plugin_arg);
  33. Plugin ->
  34. upgrade(Plugin, State)
  35. end.
  36. -spec format_error(any()) -> iolist().
  37. format_error(no_plugin_arg) ->
  38. io_lib:format("Must give an installed plugin to upgrade as an argument", []);
  39. format_error({not_found, Plugin}) ->
  40. io_lib:format("Plugin to upgrade not found: ~ts", [Plugin]);
  41. format_error(Reason) ->
  42. io_lib:format("~p", [Reason]).
  43. upgrade(Plugin, State) ->
  44. Profiles = rebar_state:current_profiles(State),
  45. case find_plugin(Plugin, Profiles, State) of
  46. not_found ->
  47. Dep = find_plugin(Plugin, [global], State);
  48. Dep ->
  49. Dep
  50. end,
  51. case Dep of
  52. not_found ->
  53. ?PRV_ERROR({not_found, Plugin});
  54. {ok, P, Profile} ->
  55. State1 = rebar_state:set(State, deps_dir, ?DEFAULT_PLUGINS_DIR),
  56. maybe_update_pkg(P, State1),
  57. {Apps, State2} = rebar_prv_install_deps:handle_deps_as_profile(Profile, State1, [P], true),
  58. {no_cycle, Sorted} = rebar_prv_install_deps:find_cycles(Apps),
  59. ToBuild = rebar_prv_install_deps:cull_compile(Sorted, []),
  60. %% Add already built plugin deps to the code path
  61. CodePaths = [rebar_app_info:ebin_dir(A) || A <- Apps -- ToBuild],
  62. code:add_pathsa(CodePaths),
  63. %% Build plugin and its deps
  64. _ = build_plugin(ToBuild, State2),
  65. {ok, State}
  66. end.
  67. find_plugin(Plugin, Profiles, State) ->
  68. ec_lists:search(fun(Profile) ->
  69. Plugins = rebar_state:get(State, {plugins, Profile}, []) ++
  70. rebar_state:get(State, {project_plugins, Profile}, []),
  71. case rebar_utils:tup_find(list_to_atom(Plugin), Plugins) of
  72. false ->
  73. not_found;
  74. P ->
  75. {ok, P}
  76. end
  77. end, Profiles).
  78. build_plugin(ToBuild, State) ->
  79. Providers = rebar_state:providers(State),
  80. rebar_prv_compile:compile(State, Providers, ToBuild, plugins).
  81. maybe_update_pkg(Tup, State) when is_tuple(Tup) ->
  82. maybe_update_pkg(element(1, Tup), State);
  83. maybe_update_pkg(Name, State) ->
  84. try rebar_app_utils:parse_dep(root, unicode:characters_to_binary(?DEFAULT_PLUGINS_DIR), Name, State, [], 0) of
  85. AppInfo ->
  86. Source = rebar_app_info:source(AppInfo),
  87. case element(1, Source) of
  88. pkg ->
  89. Resources = rebar_state:resources(State),
  90. #{repos := RepoConfigs} = rebar_resource_v2:find_resource_state(pkg, Resources),
  91. PkgName = element(2, Source),
  92. [update_package(PkgName, RepoConfig, State) || RepoConfig <- RepoConfigs];
  93. _ ->
  94. skip
  95. end
  96. catch
  97. throw:?PRV_ERROR({parse_dep, _}) ->
  98. skip
  99. end.
  100. update_package(Name, RepoConfig, State) ->
  101. case rebar_packages:update_package(Name, RepoConfig, State) of
  102. fail ->
  103. ?WARN("Failed to fetch updates for package ~ts from repo ~ts", [Name, maps:get(name, RepoConfig)]);
  104. _ ->
  105. ok
  106. end.