diff --git a/lib/maintainers.nix b/lib/maintainers.nix index e0d5b478e86..24e2356c296 100644 --- a/lib/maintainers.nix +++ b/lib/maintainers.nix @@ -118,6 +118,7 @@ gebner = "Gabriel Ebner "; gfxmonk = "Tim Cuthbertson "; giogadi = "Luis G. Torres "; + gleber = "Gleb Peregud "; globin = "Robin Gloster "; goibhniu = "Cillian de RĂ³iste "; gridaphobe = "Eric Seidel "; diff --git a/pkgs/development/erlang-modules/build-erlang.nix b/pkgs/development/erlang-modules/build-erlang.nix new file mode 100644 index 00000000000..19320f0394c --- /dev/null +++ b/pkgs/development/erlang-modules/build-erlang.nix @@ -0,0 +1,65 @@ +{ stdenv, erlang, rebar, openssl, libyaml }: + +{ name, version +, buildInputs ? [], erlangDeps ? [] +, postPatch ? "" +, meta ? {} +, ... }@attrs: + +with stdenv.lib; + +stdenv.mkDerivation (attrs // { + name = "${name}-${version}"; + + buildInputs = buildInputs ++ [ erlang rebar openssl libyaml ]; + + postPatch = '' + rm -f rebar + if [ -e "src/${name}.app.src" ]; then + sed -i -e 's/{ *vsn *,[^}]*}/{vsn, "${version}"}/' "src/${name}.app.src" + fi + ${postPatch} + ''; + + configurePhase = let + getDeps = drv: [drv] ++ (map getDeps drv.erlangDeps); + recursiveDeps = uniqList { + inputList = flatten (map getDeps erlangDeps); + }; + in '' + runHook preConfigure + ${concatMapStrings (dep: '' + header "linking erlang dependency ${dep}" + mkdir deps + ln -s "${dep}" "deps/${dep.packageName}" + stopNest + '') recursiveDeps} + runHook postConfigure + ''; + + buildPhase = '' + runHook preBuild + rebar compile + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + for reldir in src ebin priv include; do + [ -e "$reldir" ] || continue + mkdir "$out" + cp -rt "$out" "$reldir" + success=1 + done + runHook postInstall + ''; + + meta = { + inherit (erlang.meta) platforms; + } // meta; + + passthru = { + packageName = name; + inherit erlangDeps; + }; +}) diff --git a/pkgs/development/erlang-modules/build-hex.nix b/pkgs/development/erlang-modules/build-hex.nix new file mode 100644 index 00000000000..041a7db48a9 --- /dev/null +++ b/pkgs/development/erlang-modules/build-hex.nix @@ -0,0 +1,89 @@ +{ stdenv, erlang, rebar3, openssl, libyaml, fetchHex, fetchFromGitHub, + rebar3-pc }: + +{ name, version, sha256 +, hexPkg ? name +, buildInputs ? [], erlangDeps ? [], pluginDeps ? [] +, postPatch ? "" +, compilePorts ? false +, meta ? {} +, ... }@attrs: + +with stdenv.lib; + +stdenv.mkDerivation (attrs // { + name = "${name}-${version}"; + + buildInputs = buildInputs ++ [ erlang rebar3 openssl libyaml ]; + + src = fetchHex { + pkg = hexPkg; + inherit version; + inherit sha256; + }; + + postPatch = '' + rm -f rebar rebar3 + if [ -e "src/${name}.app.src" ]; then + sed -i -e 's/{ *vsn *,[^}]*}/{vsn, "${version}"}/' "src/${name}.app.src" + fi + + ${if compilePorts then '' + echo "{plugins, [pc]}." >> rebar.config + '' else ''''} + + ${rebar3.setupRegistry} + + ${postPatch} + ''; + + configurePhase = let + plugins = pluginDeps ++ (if compilePorts then [rebar3-pc] else []); + getDeps = drv: [drv] ++ (map getDeps drv.erlangDeps); + recursiveDeps = unique (flatten (map getDeps erlangDeps)); + recursivePluginsDeps = unique (flatten (map getDeps plugins)); + in '' + runHook preConfigure + ${concatMapStrings (dep: '' + header "linking erlang dependency ${dep}" + ln -s "${dep}" "_build/default/lib/${dep.packageName}" + stopNest + '') recursiveDeps} + ${concatMapStrings (dep: '' + header "linking rebar3 plugins ${dep}" + ln -s "${dep}" "_build/default/plugins/${dep.packageName}" + stopNest + '') recursivePluginsDeps} + runHook postConfigure + ''; + + buildPhase = '' + runHook preBuild + HOME=. rebar3 compile + ${if compilePorts then '' + HOME=. rebar3 pc compile + '' else ''''} + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + mkdir "$out" + for reldir in src ebin priv include; do + fd="_build/default/lib/${name}/$reldir" + [ -d "$fd" ] || continue + cp -Hrt "$out" "$fd" + success=1 + done + runHook postInstall + ''; + + meta = { + inherit (erlang.meta) platforms; + } // meta; + + passthru = { + packageName = name; + inherit erlangDeps; + }; +}) diff --git a/pkgs/development/erlang-modules/default.nix b/pkgs/development/erlang-modules/default.nix new file mode 100644 index 00000000000..84590e12a1c --- /dev/null +++ b/pkgs/development/erlang-modules/default.nix @@ -0,0 +1,18 @@ +{ pkgs }: #? import {} }: + +let + callPackage = pkgs.lib.callPackageWith (pkgs // self); + + self = rec { + buildErlang = callPackage ./build-erlang.nix {}; + buildHex = callPackage ./build-hex.nix {}; + + rebar3-pc = callPackage ./hex/rebar3-pc.nix {}; + esqlite = callPackage ./hex/esqlite.nix {}; + goldrush = callPackage ./hex/goldrush.nix {}; + ibrowse = callPackage ./hex/ibrowse.nix {}; + jiffy = callPackage ./hex/jiffy.nix {}; + lager = callPackage ./hex/lager.nix {}; + meck = callPackage ./hex/meck.nix {}; + }; +in self diff --git a/pkgs/development/erlang-modules/hex/esqlite.nix b/pkgs/development/erlang-modules/hex/esqlite.nix new file mode 100644 index 00000000000..1fc3a2e91dc --- /dev/null +++ b/pkgs/development/erlang-modules/hex/esqlite.nix @@ -0,0 +1,8 @@ +{ buildHex, rebar3-pc }: + +buildHex { + name = "esqlite"; + version = "0.2.1"; + sha256 = "1296fn1lz4lz4zqzn4dwc3flgkh0i6n4sydg501faabfbv8d3wkr"; + compilePorts = true; +} diff --git a/pkgs/development/erlang-modules/hex/goldrush.nix b/pkgs/development/erlang-modules/hex/goldrush.nix new file mode 100644 index 00000000000..ddff7f6cc56 --- /dev/null +++ b/pkgs/development/erlang-modules/hex/goldrush.nix @@ -0,0 +1,7 @@ +{ buildHex, fetchurl }: + +buildHex { + name = "goldrush"; + version = "0.1.7"; + sha256 = "1zjgbarclhh10cpgvfxikn9p2ay63rajq96q1sbz9r9w6v6p8jm9"; +} diff --git a/pkgs/development/erlang-modules/hex/ibrowse.nix b/pkgs/development/erlang-modules/hex/ibrowse.nix new file mode 100644 index 00000000000..6ed189eb39d --- /dev/null +++ b/pkgs/development/erlang-modules/hex/ibrowse.nix @@ -0,0 +1,8 @@ +{ buildHex }: + +buildHex { + name = "ibrowse"; + version = "4.2.2"; + sha256 = "1bn0645n95j5zypdsns1w4kgd3q9lz8fj898hg355j5w89scn05q"; +} + diff --git a/pkgs/development/erlang-modules/hex/jiffy.nix b/pkgs/development/erlang-modules/hex/jiffy.nix new file mode 100644 index 00000000000..b9f92c888a4 --- /dev/null +++ b/pkgs/development/erlang-modules/hex/jiffy.nix @@ -0,0 +1,8 @@ +{ buildHex }: + +buildHex { + name = "jiffy"; + version = "0.14.5"; + hexPkg = "barrel_jiffy"; + sha256 = "0iqz8bp0f672c5rfy5dpw9agv2708wzldd00ngbsffglpinlr1wa"; +} diff --git a/pkgs/development/erlang-modules/hex/lager.nix b/pkgs/development/erlang-modules/hex/lager.nix new file mode 100644 index 00000000000..acfefd5757c --- /dev/null +++ b/pkgs/development/erlang-modules/hex/lager.nix @@ -0,0 +1,8 @@ +{ buildHex, goldrush }: + +buildHex { + name = "lager"; + version = "3.0.2"; + sha256 = "0051zj6wfmmvxjn9q0nw8wic13nhbrkyy50cg1lcpdh17qiknzsj"; + erlangDeps = [ goldrush ]; +} diff --git a/pkgs/development/erlang-modules/hex/meck.nix b/pkgs/development/erlang-modules/hex/meck.nix new file mode 100644 index 00000000000..5af8a15a908 --- /dev/null +++ b/pkgs/development/erlang-modules/hex/meck.nix @@ -0,0 +1,13 @@ +{ stdenv, buildHex }: + +buildHex { + name = "meck"; + version = "0.8.3"; + sha256 = "1dh2rhks1xly4f49x89vbhsk8fgwkx5zqp0n98mnng8rs1rkigak"; + + meta = { + description = "A mocking framework for Erlang"; + homepage = "https://github.com/eproxus/meck"; + license = stdenv.lib.licenses.apsl20; + }; +} diff --git a/pkgs/development/erlang-modules/hex/rebar3-pc.nix b/pkgs/development/erlang-modules/hex/rebar3-pc.nix new file mode 100644 index 00000000000..5bc45d3e3ab --- /dev/null +++ b/pkgs/development/erlang-modules/hex/rebar3-pc.nix @@ -0,0 +1,7 @@ +{ buildHex, goldrush }: + +buildHex { + name = "pc"; + version = "1.1.0"; + sha256 = "1br5xfl4b2z70b6a2ccxppn64jvkqgpmy4y9v81kxzb91z0ss9ma"; +} diff --git a/pkgs/development/tools/build-managers/rebar3/default.nix b/pkgs/development/tools/build-managers/rebar3/default.nix new file mode 100644 index 00000000000..c4e256d5873 --- /dev/null +++ b/pkgs/development/tools/build-managers/rebar3/default.nix @@ -0,0 +1,129 @@ +{ stdenv, fetchurl, fetchHex, erlang, tree, fetchFromGitHub }: + + +let + version = "3.0.0-beta.4"; + registrySnapshot = import ./registrySnapshot.nix { inherit fetchFromGitHub; }; + setupRegistry = '' + mkdir -p _build/default/{lib,plugins,packages}/ ./.cache/rebar3/hex/default/ + zcat ${registrySnapshot}/registry.ets.gz > .cache/rebar3/hex/default/registry + ''; + # TODO: all these below probably should go into nixpkgs.erlangModules.sources.* + # {erlware_commons, "0.16.0"}, + erlware_commons = fetchHex { + pkg = "erlware_commons"; + version = "0.16.0"; + sha256 = "0kh24d0001390wfx28d0xa874vrsfvjgj41g315vg4hac632krxx"; + }; + # {ssl_verify_hostname, "1.0.5"}, + ssl_verify_hostname = fetchHex { + pkg = "ssl_verify_hostname"; + version = "1.0.5"; + sha256 = "1gzavzqzljywx4l59gvhkjbr1dip4kxzjjz1s4wsn42f2kk13jzj"; + }; + # {certifi, "0.1.1"}, + certifi = fetchHex { + pkg = "certifi"; + version = "0.1.1"; + sha256 = "0afylwqg74gprbg116asz0my2nipmki0512c8mdiq6xdiyjdvlg6"; + }; + # {providers, "1.5.0"}, + providers = fetchHex { + pkg = "providers"; + version = "1.5.0"; + sha256 = "1hc8sp2l1mmx9dfpmh1f8j9hayfg7541rmx05wb9cmvxvih7zyvf"; + }; + # {getopt, "0.8.2"}, + getopt = fetchHex { + pkg = "getopt"; + version = "0.8.2"; + sha256 = "1xw30h59zbw957cyjd8n50hf9y09jnv9dyry6x3avfwzcyrnsvkk"; + }; + # {bbmustache, "1.0.4"}, + bbmustache = fetchHex { + pkg = "bbmustache"; + version = "1.0.4"; + sha256 = "04lvwm7f78x8bys0js33higswjkyimbygp4n72cxz1kfnryx9c03"; + }; + # {relx, "3.8.0"}, + relx = fetchHex { + pkg = "relx"; + version = "3.8.0"; + sha256 = "0y89iirjz3kc1rzkdvc6p3ssmwcm2hqgkklhgm4pkbc14fcz57hq"; + }; + # {cf, "0.2.1"}, + cf = fetchHex { + pkg = "cf"; + version = "0.2.1"; + sha256 = "19d0yvg8wwa57cqhn3vqfvw978nafw8j2rvb92s3ryidxjkrmvms"; + }; + # {cth_readable, "1.1.0"}, + cth_readable = fetchHex { + pkg = "cth_readable"; + version = "1.0.1"; + sha256 = "1cnc4fbypckqllfi5h73rdb24dz576k3177gzvp1kbymwkp1xcz1"; + }; + # {eunit_formatters, "0.2.0"} + eunit_formatters = fetchHex { + pkg = "eunit_formatters"; + version = "0.2.0"; + sha256 = "03kiszlbgzscfd2ns7na6bzbfzmcqdb5cx3p6qy3657jk2fai332"; + }; + +in +stdenv.mkDerivation { + name = "rebar3-${version}"; + + src = fetchurl { + url = "https://github.com/rebar/rebar3/archive/${version}.tar.gz"; + sha256 = "0px66scjdia9aaa5z36qzxb848r56m0k98g0bxw065a2narsh4xy"; + }; + + patches = [ ./hermetic-bootstrap.patch ]; + + buildInputs = [ erlang + tree + ]; + inherit setupRegistry; + + postPatch = '' + echo postPatch + ${setupRegistry} + mkdir -p _build/default/lib/ + cp --no-preserve=mode -R ${erlware_commons} _build/default/lib/erlware_commons + cp --no-preserve=mode -R ${providers} _build/default/lib/providers + cp --no-preserve=mode -R ${getopt} _build/default/lib/getopt + cp --no-preserve=mode -R ${bbmustache} _build/default/lib/bbmustache + cp --no-preserve=mode -R ${certifi} _build/default/lib/certifi + cp --no-preserve=mode -R ${cf} _build/default/lib/cf + cp --no-preserve=mode -R ${cth_readable} _build/default/lib/cth_readable + cp --no-preserve=mode -R ${eunit_formatters} _build/default/lib/eunit_formatters + cp --no-preserve=mode -R ${relx} _build/default/lib/relx + cp --no-preserve=mode -R ${ssl_verify_hostname} _build/default/lib/ssl_verify_hostname + ''; + + buildPhase = '' + HOME=. escript bootstrap + ''; + installPhase = '' + mkdir -p $out/bin + cp rebar3 $out/bin/rebar3 + ''; + + meta = { + homepage = "https://github.com/rebar/rebar3"; + description = "rebar 3.0 is an 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 = stdenv.lib.platforms.unix; + maintainers = [ stdenv.lib.maintainers.gleber ]; + }; +} diff --git a/pkgs/development/tools/build-managers/rebar3/fetch-hex.nix b/pkgs/development/tools/build-managers/rebar3/fetch-hex.nix new file mode 100644 index 00000000000..1b1378c10cb --- /dev/null +++ b/pkgs/development/tools/build-managers/rebar3/fetch-hex.nix @@ -0,0 +1,34 @@ +{ stdenv, fetchurl }: + +{ pkg, version, sha256 +, meta ? {} +}: + +with stdenv.lib; + +stdenv.mkDerivation ({ + name = "hex-source-${pkg}-${version}"; + + src = fetchurl { + url = "https://s3.amazonaws.com/s3.hex.pm/tarballs/${pkg}-${version}.tar"; + inherit sha256; + }; + + phases = [ "unpackPhase" "installPhase" ]; + + unpackCmd = '' + tar -xf $curSrc contents.tar.gz + mkdir contents + tar -C contents -xzf contents.tar.gz + ''; + + installPhase = '' + runHook preInstall + mkdir "$out" + cp -Hrt "$out" . + success=1 + runHook postInstall + ''; + + inherit meta; +}) diff --git a/pkgs/development/tools/build-managers/rebar3/hermetic-bootstrap.patch b/pkgs/development/tools/build-managers/rebar3/hermetic-bootstrap.patch new file mode 100644 index 00000000000..13d60fdcc91 --- /dev/null +++ b/pkgs/development/tools/build-managers/rebar3/hermetic-bootstrap.patch @@ -0,0 +1,78 @@ +diff --git a/bootstrap b/bootstrap +index 25bd658..b2a986b 100755 +--- a/bootstrap ++++ b/bootstrap +@@ -8,9 +8,6 @@ main(_Args) -> + application:start(asn1), + application:start(public_key), + application:start(ssl), +- inets:start(), +- inets:start(httpc, [{profile, rebar}]), +- set_httpc_options(), + + %% Fetch and build deps required to build rebar3 + BaseDeps = [{providers, []} +@@ -33,7 +30,6 @@ main(_Args) -> + + setup_env(), + os:putenv("REBAR_PROFILE", "bootstrap"), +- rebar3:run(["update"]), + {ok, State} = rebar3:run(["compile"]), + reset_env(), + os:putenv("REBAR_PROFILE", ""), +@@ -71,33 +67,7 @@ fetch_and_compile({Name, ErlFirstFiles}, Deps) -> + compile(Name, ErlFirstFiles). + + fetch({pkg, Name, Vsn}, App) -> +- Dir = filename:join([filename:absname("_build/default/lib/"), App]), +- CDN = "https://s3.amazonaws.com/s3.hex.pm/tarballs", +- Package = binary_to_list(<>), +- Url = string:join([CDN, Package], "/"), +- case request(Url) of +- {ok, Binary} -> +- {ok, Contents} = extract(Binary), +- ok = erl_tar:extract({binary, Contents}, [{cwd, Dir}, compressed]); +- _ -> +- io:format("Error: Unable to fetch package ~p ~p~n", [Name, Vsn]) +- end. +- +-extract(Binary) -> +- {ok, Files} = erl_tar:extract({binary, Binary}, [memory]), +- {"contents.tar.gz", Contents} = lists:keyfind("contents.tar.gz", 1, Files), +- {ok, Contents}. +- +-request(Url) -> +- case httpc:request(get, {Url, []}, +- [{relaxed, true}], +- [{body_format, binary}], +- rebar) of +- {ok, {{_Version, 200, _Reason}, _Headers, Body}} -> +- {ok, Body}; +- Error -> +- Error +- end. ++ ok. + + get_rebar_config() -> + {ok, [[Home]]} = init:get_argument(home), +@@ -109,20 +79,6 @@ get_rebar_config() -> + [] + end. + +-get_http_vars(Scheme) -> +- proplists:get_value(Scheme, get_rebar_config(), []). +- +-set_httpc_options() -> +- set_httpc_options(https_proxy, get_http_vars(https_proxy)), +- set_httpc_options(proxy, get_http_vars(http_proxy)). +- +-set_httpc_options(_, []) -> +- ok; +- +-set_httpc_options(Scheme, Proxy) -> +- {ok, {_, _, Host, Port, _, _}} = http_uri:parse(Proxy), +- httpc:set_options([{Scheme, {{Host, Port}, []}}], rebar). +- + compile(App, FirstFiles) -> + Dir = filename:join(filename:absname("_build/default/lib/"), App), + filelib:ensure_dir(filename:join([Dir, "ebin", "dummy.beam"])), diff --git a/pkgs/development/tools/build-managers/rebar3/registrySnapshot.nix b/pkgs/development/tools/build-managers/rebar3/registrySnapshot.nix new file mode 100644 index 00000000000..8e9c2a292fd --- /dev/null +++ b/pkgs/development/tools/build-managers/rebar3/registrySnapshot.nix @@ -0,0 +1,8 @@ +{ fetchFromGitHub }: + +fetchFromGitHub { + owner = "gleber"; + repo = "hex-pm-registry-snapshots"; + rev = "329ae2b"; + sha256 = "1rs3z8psfvy10mzlfvkdzbflgikcnq08r38kfi0f8p5wvi8f8hmh"; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index d41ee1149b8..a6e5918bbf9 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -5032,6 +5032,10 @@ let erlang_odbc_javac = erlangR18_odbc_javac; rebar = callPackage ../development/tools/build-managers/rebar { }; + rebar3 = callPackage ../development/tools/build-managers/rebar3 { }; + fetchHex = callPackage ../development/tools/build-managers/rebar3/fetch-hex.nix { }; + + erlangPackages = callPackage ../development/erlang-modules { }; elixir = callPackage ../development/interpreters/elixir { };