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.

128 lines
5.3 KiB

преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 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).