Merge master into staging-next

This commit is contained in:
github-actions[bot]
2021-05-11 00:48:15 +00:00
committed by GitHub
69 changed files with 4881 additions and 8823 deletions
@@ -1,71 +1,104 @@
{ lib, stdenv, fetchFromGitHub,
fetchHex, erlang,
tree }:
fetchHex, erlang, makeWrapper }:
let
version = "3.15.1";
# Dependencies should match the ones in:
# https://github.com/erlang/rebar3/blob/${version}/rebar.lock
# `sha256` could also be taken from https://hex.pm - Checksum
owner = "erlang";
deps = import ./rebar-deps.nix { inherit fetchHex; };
in
stdenv.mkDerivation rec {
pname = "rebar3";
inherit version erlang;
rebar3 = stdenv.mkDerivation rec {
pname = "rebar3";
inherit version erlang;
# How to obtain `sha256`:
# nix-prefetch-url --unpack https://github.com/erlang/rebar3/archive/${version}.tar.gz
src = fetchFromGitHub {
inherit owner;
repo = pname;
rev = version;
sha256 = "1pcy5m79g0l9l3d8lkbx6cq1w87z1g3sa6wwvgbgraj2v3wkyy5g";
};
bootstrapper = ./rebar3-nix-bootstrap;
buildInputs = [ erlang ];
postPatch = ''
mkdir -p _checkouts _build/default/lib/
${toString (lib.mapAttrsToList (k: v: ''
cp -R --no-preserve=mode ${v} _checkouts/${k}
'') deps)}
# Bootstrap script expects the dependencies in _build/default/lib
# TODO: Make it accept checkouts?
for i in _checkouts/* ; do
ln -s $(pwd)/$i $(pwd)/_build/default/lib/
done
'';
buildPhase = ''
HOME=. escript bootstrap
'';
installPhase = ''
mkdir -p $out/bin
cp rebar3 $out/bin/rebar3
'';
meta = {
homepage = "https://github.com/rebar/rebar3";
description = "Erlang build tool that makes it easy to compile and test Erlang applications, port drivers and releases";
longDescription = ''
rebar is a self-contained Erlang script, so it's easy to distribute or
even embed directly in a project. Where possible, rebar uses standard
Erlang/OTP conventions for project structures, thus minimizing the amount
of build configuration work. rebar also provides dependency management,
enabling application writers to easily re-use common libraries from a
variety of locations (hex.pm, git, hg, and so on).
'';
platforms = lib.platforms.unix;
maintainers = lib.teams.beam.members;
license = lib.licenses.asl20;
};
# How to obtain `sha256`:
# nix-prefetch-url --unpack https://github.com/erlang/rebar3/archive/${version}.tar.gz
src = fetchFromGitHub {
owner = "erlang";
repo = pname;
rev = version;
sha256 = "1pcy5m79g0l9l3d8lkbx6cq1w87z1g3sa6wwvgbgraj2v3wkyy5g";
};
rebar3WithPlugins = { plugins ? [ ], globalPlugins ? [ ] }:
let
pluginLibDirs = map (p: "${p}/lib/erlang/lib") (lib.unique (plugins ++ globalPlugins));
globalPluginNames = lib.unique (map (p: p.packageName) globalPlugins);
rebar3Patched = (rebar3.overrideAttrs (old: {
bootstrapper = ./rebar3-nix-bootstrap;
# skip-plugins.patch is necessary because otherwise rebar3 will always
# try to fetch plugins if they are not already present in _build.
#
# global-deps.patch makes it possible to use REBAR_GLOBAL_PLUGINS to
# instruct rebar3 to always load a certain plugin. It is necessary since
# REBAR_GLOBAL_CONFIG_DIR doesn't seem to work for this.
patches = [ ./skip-plugins.patch ./global-plugins.patch ];
}));
in stdenv.mkDerivation {
pname = "rebar3-with-plugins";
inherit (rebar3) version bootstrapper;
nativeBuildInputs = [ erlang makeWrapper ];
unpackPhase = "true";
buildInputs = [ erlang tree ];
# Here we extract the rebar3 escript (like `rebar3_prv_local_install.erl`) and
# add plugins to the code path.
postPatch = ''
mkdir -p _checkouts
mkdir -p _build/default/lib/
${toString (lib.mapAttrsToList (k: v: ''
cp -R --no-preserve=mode ${v} _checkouts/${k}
'') deps)}
# Bootstrap script expects the dependencies in _build/default/lib
# TODO: Make it accept checkouts?
for i in _checkouts/* ; do
ln -s $(pwd)/$i $(pwd)/_build/default/lib/
done
'';
buildPhase = ''
HOME=. escript bootstrap
'';
installPhase = ''
mkdir -p $out/bin
cp rebar3 $out/bin/rebar3
'';
meta = {
homepage = "https://github.com/rebar/rebar3";
description = "Erlang build tool that makes it easy to compile and test Erlang applications, port drivers and releases";
longDescription = ''
rebar is a self-contained Erlang script, so it's easy to distribute or
even embed directly in a project. Where possible, rebar uses standard
Erlang/OTP conventions for project structures, thus minimizing the amount
of build configuration work. rebar also provides dependency management,
enabling application writers to easily re-use common libraries from a
variety of locations (hex.pm, git, hg, and so on).
installPhase = ''
erl -noshell -eval '
{ok, Escript} = escript:extract("${rebar3Patched}/bin/rebar3", []),
{archive, Archive} = lists:keyfind(archive, 1, Escript),
{ok, _} = zip:extract(Archive, [{cwd, "'$out/lib'"}]),
init:stop(0)
'
mkdir -p $out/bin
makeWrapper ${erlang}/bin/erl $out/bin/rebar3 \
--set REBAR_GLOBAL_PLUGINS "${toString globalPluginNames}" \
--suffix-each ERL_LIBS ":" "$out/lib ${toString pluginLibDirs}" \
--add-flags "+sbtu +A1 -noshell -boot start_clean -s rebar3 main -extra"
'';
platforms = lib.platforms.unix;
maintainers = lib.teams.beam.members;
license = lib.licenses.asl20;
};
}
};
in { inherit rebar3 rebar3WithPlugins; }
@@ -0,0 +1,14 @@
diff --git a/src/rebar_plugins.erl b/src/rebar_plugins.erl
index f2d22233..bee2cf18 100644
--- a/src/rebar_plugins.erl
+++ b/src/rebar_plugins.erl
@@ -30,7 +30,8 @@ project_plugins_install(State) ->
top_level_install(State) ->
Profiles = rebar_state:current_profiles(State),
lists:foldl(fun(Profile, StateAcc) ->
- Plugins = rebar_state:get(State, {plugins, Profile}, []),
+ Plugins = rebar_state:get(State, {plugins, Profile}, [])
+ ++ [list_to_atom(P) || P <- string:lexemes(os:getenv("REBAR_GLOBAL_PLUGINS", ""), " ")],
handle_plugins(Profile, Plugins, StateAcc)
end, State, Profiles).
@@ -26,9 +26,7 @@
-record(data, {version
, debug_info = false
, compile_ports
, erl_libs
, plugins
, root
, name}).
@@ -42,7 +40,6 @@ main(Args) ->
-spec do_the_bootstrap(#data{}) -> ok.
do_the_bootstrap(RequiredData) ->
ok = bootstrap_configs(RequiredData),
ok = bootstrap_plugins(RequiredData),
ok = bootstrap_libs(RequiredData).
%% @doc
@@ -68,22 +65,8 @@ parse_args(Args0) ->
bootstrap_configs(RequiredData)->
io:format("Boostrapping app and rebar configurations~n"),
ok = if_single_app_project_update_app_src_version(RequiredData),
ok = if_compile_ports_add_pc_plugin(RequiredData),
ok = if_debug_info_add(RequiredData).
-spec bootstrap_plugins(#data{}) -> ok.
bootstrap_plugins(#data{plugins = Plugins}) ->
io:format("Bootstrapping rebar3 plugins~n"),
Target = "_build/default/plugins/",
Paths = string:tokens(Plugins, " "),
CopiableFiles =
lists:foldl(fun(Path, Acc) ->
gather_dependency(Path) ++ Acc
end, [], Paths),
lists:foreach(fun (Path) ->
ok = link_app(Path, Target)
end, CopiableFiles).
-spec bootstrap_libs(#data{}) -> ok.
bootstrap_libs(#data{erl_libs = ErlLibs}) ->
io:format("Bootstrapping dependent libraries~n"),
@@ -152,10 +135,9 @@ fixup_app_name(FileName) ->
gather_required_data_from_the_environment(ArgData) ->
{ok, ArgData#data{ version = guard_env("version")
, erl_libs = get_env("ERL_LIBS", [])
, plugins = get_env("buildPlugins", [])
, root = code:root_dir()
, name = guard_env("name")
, compile_ports = nix2bool(get_env("compilePorts", ""))}}.
}}.
-spec nix2bool(any()) -> boolean().
nix2bool("1") ->
@@ -209,27 +191,6 @@ add_debug_info(Config) ->
{erl_opts, [debug_info | ExistingOpts]})
end.
%% @doc
%% If the compile ports flag is set, rewrite the rebar config to
%% include the 'pc' plugin.
-spec if_compile_ports_add_pc_plugin(#data{}) -> ok.
if_compile_ports_add_pc_plugin(#data{compile_ports = true}) ->
ConfigTerms = add_pc_to_plugins(read_rebar_config()),
Text = lists:map(fun(Term) -> io_lib:format("~tp.~n", [Term]) end,
ConfigTerms),
file:write_file("rebar.config", Text);
if_compile_ports_add_pc_plugin(_) ->
ok.
-spec add_pc_to_plugins([term()]) -> [term()].
add_pc_to_plugins(Config) ->
PluginList = case lists:keysearch(plugins, 1, Config) of
{value, {plugins, ExistingPluginList}} -> ExistingPluginList;
_ -> []
end,
lists:keystore(plugins, 1, Config, {plugins, [pc | PluginList]}).
-spec read_rebar_config() -> [term()].
read_rebar_config() ->
case file:consult("rebar.config") of
@@ -0,0 +1,54 @@
diff --git a/src/rebar_plugins.erl b/src/rebar_plugins.erl
index f2d22233..c61fa553 100644
--- a/src/rebar_plugins.erl
+++ b/src/rebar_plugins.erl
@@ -106,31 +106,9 @@ handle_plugins(Profile, Plugins, State, Upgrade) ->
State3 = rebar_state:set(State2, deps_dir, DepsDir),
rebar_state:lock(State3, Locks).
-handle_plugin(Profile, Plugin, State, Upgrade) ->
+handle_plugin(_Profile, Plugin, State, _Upgrade) ->
try
- {Apps, State2} = rebar_prv_install_deps:handle_deps_as_profile(Profile, State, [Plugin], Upgrade),
- {no_cycle, Sorted} = rebar_prv_install_deps:find_cycles(Apps),
- ToBuild = rebar_prv_install_deps:cull_compile(Sorted, []),
-
- %% Add already built plugin deps to the code path
- ToBuildPaths = [rebar_app_info:ebin_dir(A) || A <- ToBuild],
- PreBuiltPaths = [Ebin || A <- Apps,
- Ebin <- [rebar_app_info:ebin_dir(A)],
- not lists:member(Ebin, ToBuildPaths)],
- code:add_pathsa(PreBuiltPaths),
-
- %% Build plugin and its deps
- build_plugins(ToBuild, Apps, State2),
-
- %% Add newly built deps and plugin to code path
- State3 = rebar_state:update_all_plugin_deps(State2, Apps),
- NewCodePaths = [rebar_app_info:ebin_dir(A) || A <- ToBuild],
-
- %% Store plugin code paths so we can remove them when compiling project apps
- State4 = rebar_state:update_code_paths(State3, all_plugin_deps, PreBuiltPaths++NewCodePaths),
- rebar_paths:set_paths([plugins], State4),
-
- {plugin_providers(Plugin), State4}
+ {plugin_providers(Plugin), State}
catch
?WITH_STACKTRACE(C,T,S)
?DEBUG("~p ~p ~p", [C, T, S]),
@@ -138,15 +116,6 @@ handle_plugin(Profile, Plugin, State, Upgrade) ->
{[], State}
end.
-build_plugins(MustBuildApps, AllApps, State) ->
- State1 = rebar_state:deps_to_build(State, MustBuildApps),
- State2 = rebar_state:all_deps(State1, AllApps),
- State3 = rebar_state:set(State2, deps_dir, ?DEFAULT_PLUGINS_DIR),
- {Args, Extra} = rebar_state:command_parsed_args(State),
- State4 = rebar_state:command_parsed_args(State3, {[{deps_only, true}|Args], Extra}),
- rebar_prv_compile:do(State4),
- ok.
-
plugin_providers({Plugin, _, _, _}) when is_atom(Plugin) ->
validate_plugin(Plugin);
plugin_providers({Plugin, _, _}) when is_atom(Plugin) ->