diff --git a/pkgs/development/beam-modules/build-rebar3.nix b/pkgs/development/beam-modules/build-rebar3.nix index 651c024db095..dc882a133188 100644 --- a/pkgs/development/beam-modules/build-rebar3.nix +++ b/pkgs/development/beam-modules/build-rebar3.nix @@ -1,12 +1,10 @@ -{ stdenv, writeText, erlang, rebar3WithPlugins, openssl, libyaml, - pc, lib }: +{ stdenv, writeText, erlang, rebar3WithPlugins, openssl, libyaml, lib }: { name, version , src , setupHook ? null , buildInputs ? [], beamDeps ? [], buildPlugins ? [] , postPatch ? "" -, compilePorts ? false , installPhase ? null , buildPhase ? null , configurePhase ? null @@ -21,7 +19,6 @@ let rebar3 = rebar3WithPlugins { plugins = buildPlugins; - globalPlugins = (if compilePorts then [pc] else []); }; shell = drv: stdenv.mkDerivation { @@ -52,18 +49,9 @@ let rm -f rebar rebar3 '' + postPatch; - configurePhase = '' - runHook preConfigure - ${erlang}/bin/escript ${rebar3.bootstrapper} ${debugInfoFlag} - runHook postConfigure - ''; - buildPhase = '' runHook preBuild - HOME=. rebar3 compile - ${if compilePorts then '' - HOME=. rebar3 pc compile - '' else ""} + HOME=. rebar3 bare compile -path "" runHook postBuild ''; @@ -71,10 +59,9 @@ let runHook preInstall mkdir -p "$out/lib/erlang/lib/${name}-${version}" for reldir in src ebin priv include; do - fd="_build/default/lib/${name}/$reldir" - [ -d "$fd" ] || continue - cp -Hrt "$out/lib/erlang/lib/${name}-${version}" "$fd" - success=1 + [ -d "$reldir" ] || continue + # $out/lib/erlang/lib is a convention used in nixpkgs for compiled BEAM packages + cp -Hrt "$out/lib/erlang/lib/${name}-${version}" "$reldir" done runHook postInstall ''; diff --git a/pkgs/development/tools/build-managers/rebar3/default.nix b/pkgs/development/tools/build-managers/rebar3/default.nix index 95ffc0c957cc..5867db0b573b 100644 --- a/pkgs/development/tools/build-managers/rebar3/default.nix +++ b/pkgs/development/tools/build-managers/rebar3/default.nix @@ -19,8 +19,6 @@ let sha256 = "1pcy5m79g0l9l3d8lkbx6cq1w87z1g3sa6wwvgbgraj2v3wkyy5g"; }; - bootstrapper = ./rebar3-nix-bootstrap; - buildInputs = [ erlang ]; postPatch = '' @@ -106,7 +104,7 @@ let })); in stdenv.mkDerivation { pname = "rebar3-with-plugins"; - inherit (rebar3) version bootstrapper; + inherit (rebar3) version; nativeBuildInputs = [ erlang makeWrapper ]; unpackPhase = "true"; diff --git a/pkgs/development/tools/build-managers/rebar3/rebar3-nix-bootstrap b/pkgs/development/tools/build-managers/rebar3/rebar3-nix-bootstrap deleted file mode 100755 index 8bfbb8fb6859..000000000000 --- a/pkgs/development/tools/build-managers/rebar3/rebar3-nix-bootstrap +++ /dev/null @@ -1,228 +0,0 @@ -#!/usr/bin/env escript -%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*- -%%! -smp enable -%%% --------------------------------------------------------------------------- -%%% @doc -%%% The purpose of this command is to prepare a rebar3 project so that -%%% rebar3 understands that the dependencies are all already -%%% installed. If you want a hygienic build on nix then you must run -%%% this command before running rebar3. I suggest that you add a -%%% `Makefile` to your project and have the bootstrap command be a -%%% dependency of the build commands. See the nix documentation for -%%% more information. -%%% -%%% This command designed to have as few dependencies as possible so -%%% that it can be a dependency of root level packages like rebar3. To -%%% that end it does many things in a fairly simplistic way. That is -%%% by design. -%%% -%%% ### Assumptions -%%% -%%% This command makes the following assumptions: -%%% -%%% * It is run in a nix-shell or nix-build environment -%%% * that all dependencies have been added to the ERL_LIBS -%%% Environment Variable - --record(data, {version - , debug_info = false - , erl_libs - , root - , name}). - --define(HEX_REGISTRY_PATH, ".cache/rebar3/hex/default/registry"). - -main(Args) -> - {ok, ArgData} = parse_args(Args), - {ok, RequiredData} = gather_required_data_from_the_environment(ArgData), - do_the_bootstrap(RequiredData). - --spec do_the_bootstrap(#data{}) -> ok. -do_the_bootstrap(RequiredData) -> - ok = bootstrap_configs(RequiredData), - ok = bootstrap_libs(RequiredData). - -%% @doc -%% Argument parsing is super simple only because we want to keep the -%% dependencies minimal. For now there can be one entry on the -%% command line: "debug-info" --spec parse_args([string()]) -> #data{}. -parse_args(Args0) -> - PossibleArgs = sets:from_list(["debug-info"]), - Args1 = sets:from_list(Args0), - Result = sets:subtract(Args1, PossibleArgs), - case sets:to_list(Result) of - [] -> - {ok, #data{debug_info = sets:is_element("debug-info", Args1)}}; - UnknownArgs -> - io:format("Unexpected command line arguments passed in: ~p~n", - [UnknownArgs]), - erlang:halt(120) - end. - - --spec bootstrap_configs(#data{}) -> ok. -bootstrap_configs(RequiredData)-> - io:format("Boostrapping app and rebar configurations~n"), - ok = if_single_app_project_update_app_src_version(RequiredData), - ok = if_debug_info_add(RequiredData). - --spec bootstrap_libs(#data{}) -> ok. -bootstrap_libs(#data{erl_libs = ErlLibs}) -> - io:format("Bootstrapping dependent libraries~n"), - Target = "_build/default/lib/", - Paths = string:tokens(ErlLibs, ":"), - CopiableFiles = - lists:foldl(fun(Path, Acc) -> - gather_directory_contents(Path) ++ Acc - end, [], Paths), - lists:foreach(fun (Path) -> - ok = link_app(Path, Target) - end, CopiableFiles). - --spec gather_dependency(string()) -> [{string(), string()}]. -gather_dependency(Path) -> - FullLibrary = filename:join(Path, "lib/erlang/lib/"), - case filelib:is_dir(FullLibrary) of - true -> - gather_directory_contents(FullLibrary); - false -> - [raw_hex(Path)] - end. - --spec raw_hex(string()) -> {string(), string()}. -raw_hex(Path) -> - [_, Name] = re:split(Path, "-hex-source-"), - {Path, erlang:binary_to_list(Name)}. - --spec gather_directory_contents(string()) -> [{string(), string()}]. -gather_directory_contents(Path) -> - {ok, Names} = file:list_dir(Path), - lists:map(fun(AppName) -> - {filename:join(Path, AppName), fixup_app_name(AppName)} - end, Names). - -%% @doc -%% Makes a symlink from the directory pointed at by Path to a -%% directory of the same name in Target. So if we had a Path of -%% {`foo/bar/baz/bash`, `baz`} and a Target of `faz/foo/foos`, the symlink -%% would be `faz/foo/foos/baz`. --spec link_app({string(), string()}, string()) -> ok. -link_app({Path, TargetFile}, TargetDir) -> - Target = filename:join(TargetDir, TargetFile), - make_symlink(Path, Target). - --spec make_symlink(string(), string()) -> ok. -make_symlink(Path, TargetFile) -> - file:delete(TargetFile), - ok = filelib:ensure_dir(TargetFile), - io:format("Making symlink from ~s to ~s~n", [Path, TargetFile]), - ok = file:make_symlink(Path, TargetFile). - -%% @doc -%% This takes an app name in the standard OTP - format -%% and returns just the app name. Why? Because rebar doesn't -%% respect OTP conventions in some cases. --spec fixup_app_name(string()) -> string(). -fixup_app_name(FileName) -> - case string:tokens(FileName, "-") of - [Name] -> Name; - [Name, _Version] -> Name; - [Name, _Version, _Tag] -> Name - end. - --spec gather_required_data_from_the_environment(#data{}) -> {ok, #data{}}. -gather_required_data_from_the_environment(ArgData) -> - {ok, ArgData#data{ version = guard_env("version") - , erl_libs = get_env("ERL_LIBS", []) - , root = code:root_dir() - , name = guard_env("name") - }}. - --spec nix2bool(any()) -> boolean(). -nix2bool("1") -> - true; -nix2bool("") -> - false. - -get_env(Name) -> - os:getenv(Name). -get_env(Name, Def) -> - case get_env(Name) of - false -> Def; - Val -> Val - end. - --spec guard_env(string()) -> string(). -guard_env(Name) -> - case get_env(Name) of - false -> - stderr("Expected Environment variable ~s! Are you sure you are " - "running in a Nix environment? Either a nix-build, " - "nix-shell, etc?~n", [Name]), - erlang:halt(1); - Variable -> - Variable - end. - -%% @doc -%% If debug info is set we need to add debug info to the list of compile options -%% --spec if_debug_info_add(#data{}) -> ok. -if_debug_info_add(#data{debug_info = true}) -> - ConfigTerms = add_debug_info(read_rebar_config()), - Text = lists:map(fun(Term) -> io_lib:format("~tp.~n", [Term]) end, - ConfigTerms), - file:write_file("rebar.config", Text); -if_debug_info_add(_) -> - ok. - --spec add_debug_info([term()]) -> [term()]. -add_debug_info(Config) -> - ExistingOpts = case lists:keysearch(erl_opts, 1, Config) of - {value, {erl_opts, ExistingOptsList}} -> ExistingOptsList; - _ -> [] - end, - case lists:member(debug_info, ExistingOpts) of - true -> - Config; - false -> - lists:keystore(erl_opts, 1, Config, - {erl_opts, [debug_info | ExistingOpts]}) - end. - --spec read_rebar_config() -> [term()]. -read_rebar_config() -> - case file:consult("rebar.config") of - {ok, Terms} -> - Terms; - _ -> - stderr("Unable to read rebar config!", []), - erlang:halt(1) - end. - - --spec if_single_app_project_update_app_src_version(#data{}) -> ok. -if_single_app_project_update_app_src_version(#data{name = Name, - version = Version}) -> - SrcFile = filename:join("src", - lists:concat([Name, ".app.src"])), - - case filelib:is_file(SrcFile) of - true -> - update_app_src_with_version(SrcFile, Version); - false -> - ok - end. - --spec update_app_src_with_version(string(), string()) -> ok. -update_app_src_with_version(SrcFile, Version) -> - {ok, [{application, Name, Details}]} = file:consult(SrcFile), - NewDetails = lists:keyreplace(vsn, 1, Details, {vsn, Version}), - ok = file:write_file(SrcFile, io_lib:fwrite("~p.\n", [{application, Name, NewDetails}])). - -%% @doc -%% Write the result of the format string out to stderr. --spec stderr(string(), [term()]) -> ok. -stderr(FormatStr, Args) -> - io:put_chars(standard_error, io_lib:format(FormatStr, Args)).