Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

128 строки
5.3 KiB

10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
  1. %% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
  2. %% ex: ts=4 sw=4 et
  3. -module(rebar_prv_update).
  4. -behaviour(provider).
  5. -export([init/1,
  6. do/1,
  7. format_error/1]).
  8. -export([hex_to_index/1]).
  9. -include("rebar.hrl").
  10. -include_lib("providers/include/providers.hrl").
  11. -define(PROVIDER, update).
  12. -define(DEPS, []).
  13. %% ===================================================================
  14. %% Public API
  15. %% ===================================================================
  16. -spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
  17. init(State) ->
  18. State1 = rebar_state:add_provider(State, providers:create([{name, ?PROVIDER},
  19. {module, ?MODULE},
  20. {bare, true},
  21. {deps, ?DEPS},
  22. {example, "rebar3 update"},
  23. {short_desc, "Update package index."},
  24. {desc, "Update package index."},
  25. {opts, []}])),
  26. {ok, State1}.
  27. -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
  28. do(State) ->
  29. try
  30. RegistryDir = rebar_packages:registry_dir(State),
  31. filelib:ensure_dir(filename:join(RegistryDir, "dummy")),
  32. HexFile = filename:join(RegistryDir, "registry"),
  33. ?INFO("Updating package registry...", []),
  34. TmpDir = ec_file:insecure_mkdtemp(),
  35. TmpFile = filename:join(TmpDir, "packages.gz"),
  36. Url = rebar_state:get(State, rebar_packages_cdn, ?DEFAULT_HEX_REGISTRY),
  37. {ok, _RequestId} = httpc:request(get, {Url, []},
  38. [], [{stream, TmpFile}, {sync, true}],
  39. rebar),
  40. {ok, Data} = file:read_file(TmpFile),
  41. Unzipped = zlib:gunzip(Data),
  42. ok = file:write_file(HexFile, Unzipped),
  43. ?INFO("Writing registry to ~s", [HexFile]),
  44. hex_to_index(State),
  45. ok
  46. catch
  47. _E:C ->
  48. ?DEBUG("Error creating package index: ~p ~p", [C, erlang:get_stacktrace()]),
  49. throw(?PRV_ERROR(package_index_write))
  50. end,
  51. {ok, State}.
  52. -spec format_error(any()) -> iolist().
  53. format_error(package_index_write) ->
  54. "Failed to write package index.".
  55. is_supported(<<"make">>) -> true;
  56. is_supported(<<"rebar">>) -> true;
  57. is_supported(<<"rebar3">>) -> true;
  58. is_supported(_) -> false.
  59. hex_to_index(State) ->
  60. RegistryDir = rebar_packages:registry_dir(State),
  61. HexFile = filename:join(RegistryDir, "registry"),
  62. try ets:file2tab(HexFile) of
  63. {ok, Registry} ->
  64. try
  65. PackageIndex = filename:join(RegistryDir, "packages.idx"),
  66. ?INFO("Generating package index...", []),
  67. (catch ets:delete(?PACKAGE_TABLE)),
  68. ets:new(?PACKAGE_TABLE, [named_table, public]),
  69. ets:foldl(fun({{Pkg, PkgVsn}, [Deps, Checksum, BuildTools | _]}, _) when is_list(BuildTools) ->
  70. case lists:any(fun is_supported/1, BuildTools) of
  71. true ->
  72. DepsList = update_deps_list(Deps, Registry, State),
  73. ets:insert(?PACKAGE_TABLE, {{Pkg, PkgVsn}, DepsList, Checksum});
  74. false ->
  75. true
  76. end;
  77. ({Pkg, [Vsns]}, _) when is_binary(Pkg) ->
  78. ets:insert(?PACKAGE_TABLE, {Pkg, Vsns});
  79. (_, _) ->
  80. true
  81. end, true, Registry),
  82. ets:insert(?PACKAGE_TABLE, {package_index_version, ?PACKAGE_INDEX_VERSION}),
  83. ?INFO("Writing index to ~s", [PackageIndex]),
  84. ets:tab2file(?PACKAGE_TABLE, PackageIndex),
  85. true
  86. after
  87. catch ets:delete(Registry)
  88. end;
  89. {error, Reason} ->
  90. ?DEBUG("Error loading package registry: ~p", [Reason]),
  91. false
  92. catch
  93. _:_ ->
  94. fail
  95. end.
  96. update_deps_list(Deps, HexRegistry, State) ->
  97. lists:foldl(fun([Dep, DepVsn, false, _AppName | _], DepsListAcc) ->
  98. case DepVsn of
  99. <<"~> ", Vsn/binary>> ->
  100. case rebar_packages:find_highest_matching(Dep, Vsn, HexRegistry, State) of
  101. {ok, HighestDepVsn} ->
  102. [{Dep, HighestDepVsn} | DepsListAcc];
  103. none ->
  104. ?WARN("Missing registry entry for package ~s. Try to fix with `rebar3 update`", [Dep]),
  105. DepsListAcc
  106. end;
  107. Vsn ->
  108. [{Dep, Vsn} | DepsListAcc]
  109. end;
  110. ([_Dep, _DepVsn, true, _AppName | _], DepsListAcc) ->
  111. DepsListAcc
  112. end, [], Deps).