aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CHANGELOG.asciidoc80
-rw-r--r--Makefile8
-rw-r--r--core/core.mk6
-rw-r--r--core/deps.mk186
-rw-r--r--core/erlc.mk7
-rw-r--r--core/kerl.mk25
-rw-r--r--doc/src/guide/ci.asciidoc11
-rw-r--r--doc/src/guide/common_test.asciidoc6
-rw-r--r--doc/src/guide/coverage.asciidoc11
-rw-r--r--doc/src/guide/deps.asciidoc20
-rw-r--r--doc/src/guide/installation.asciidoc2
-rw-r--r--doc/src/guide/ports.asciidoc2
-rw-r--r--doc/src/guide/releases.asciidoc19
-rw-r--r--doc/src/guide/xref.asciidoc181
-rw-r--r--index/actordb_core.mk7
-rw-r--r--index/actordb_thrift.mk7
-rw-r--r--index/amqp_client.mk7
-rw-r--r--index/antidote.mk7
-rw-r--r--index/azdht.mk7
-rw-r--r--index/beanstalk.mk7
-rw-r--r--index/bitstore.mk7
-rw-r--r--index/carotene.mk7
-rw-r--r--index/chronos.mk2
-rw-r--r--index/cloudi_service_db.mk7
-rw-r--r--index/cloudi_service_db_cassandra.mk7
-rw-r--r--index/cloudi_service_db_cassandra_cql.mk7
-rw-r--r--index/cloudi_service_db_couchdb.mk7
-rw-r--r--index/cloudi_service_db_elasticsearch.mk7
-rw-r--r--index/cloudi_service_db_memcached.mk7
-rw-r--r--index/cloudi_service_db_riak.mk7
-rw-r--r--index/cloudi_service_db_tokyotyrant.mk7
-rw-r--r--index/cloudi_service_timers.mk7
-rw-r--r--index/decimal.mk4
-rw-r--r--index/detest.mk7
-rw-r--r--index/dns.mk2
-rw-r--r--index/dnssd.mk7
-rw-r--r--index/edis.mk7
-rw-r--r--index/ehsa.mk8
-rw-r--r--index/eleveldb.mk2
-rw-r--r--index/elixir.mk2
-rw-r--r--index/elli.mk2
-rw-r--r--index/emysql.mk7
-rw-r--r--index/eredis_pool.mk7
-rw-r--r--index/erlang_cep.mk7
-rw-r--r--index/erlang_js.mk7
-rw-r--r--index/erlasticsearch.mk7
-rw-r--r--index/erldns.mk2
-rw-r--r--index/erlport.mk7
-rw-r--r--index/erwa.mk7
-rw-r--r--index/exs64.mk7
-rw-r--r--index/exsplus128.mk7
-rw-r--r--index/ezmq.mk7
-rw-r--r--index/folsomite.mk7
-rw-r--r--index/gold_fever.mk7
-rw-r--r--index/gut.mk7
-rw-r--r--index/hanoidb.mk7
-rw-r--r--index/ierlang.mk7
-rw-r--r--index/iota.mk7
-rw-r--r--index/jerg.mk7
-rw-r--r--index/jobs.mk6
-rw-r--r--index/json.mk7
-rw-r--r--index/jsonerl.mk7
-rw-r--r--index/kafka.mk7
-rw-r--r--index/kafka_protocol.mk4
-rw-r--r--index/kdht.mk7
-rw-r--r--index/kinetic.mk2
-rw-r--r--index/lager_amqp_backend.mk7
-rw-r--r--index/lambdapad.mk7
-rw-r--r--index/lasp.mk7
-rw-r--r--index/lethink.mk7
-rw-r--r--index/ling.mk7
-rw-r--r--index/lmq.mk7
-rw-r--r--index/luwak.mk7
-rw-r--r--index/machi.mk7
-rw-r--r--index/mc_erl.mk7
-rw-r--r--index/mcd.mk7
-rw-r--r--index/mcerlang.mk7
-rw-r--r--index/memo.mk7
-rw-r--r--index/merge_index.mk7
-rw-r--r--index/mixer.mk2
-rw-r--r--index/mochiweb.mk2
-rw-r--r--index/newrelic.mk7
-rw-r--r--index/nkbase.mk7
-rw-r--r--index/nkdocker.mk7
-rw-r--r--index/oauth.mk2
-rw-r--r--index/of_protocol.mk7
-rw-r--r--index/opencouch.mk7
-rw-r--r--index/pgo.mk2
-rw-r--r--index/plumtree.mk7
-rw-r--r--index/push_service.mk7
-rw-r--r--index/rabbit.mk7
-rw-r--r--index/rafter.mk7
-rw-r--r--index/re2.mk7
-rw-r--r--index/rebar.mk7
-rw-r--r--index/relx.mk2
-rw-r--r--index/riak_control.mk7
-rw-r--r--index/riak_core.mk2
-rw-r--r--index/riak_ensemble.mk2
-rw-r--r--index/riak_kv.mk2
-rw-r--r--index/riak_pg.mk7
-rw-r--r--index/riak_pipe.mk2
-rw-r--r--index/riak_test.mk7
-rw-r--r--index/riakhttpc.mk7
-rw-r--r--index/riaknostic.mk7
-rw-r--r--index/riakpool.mk7
-rw-r--r--index/rivus_cep.mk7
-rw-r--r--index/service.mk7
-rw-r--r--index/sidejob.mk2
-rw-r--r--index/sighandler.mk7
-rw-r--r--index/smother.mk7
-rw-r--r--index/spapi_router.mk7
-rw-r--r--index/statebox_riak.mk7
-rw-r--r--index/stripe.mk7
-rw-r--r--index/surrogate.mk7
-rw-r--r--index/ticktick.mk7
-rw-r--r--index/transit.mk7
-rw-r--r--index/twerl.mk7
-rw-r--r--index/twitter_erlang.mk7
-rw-r--r--index/ucol_nif.mk7
-rw-r--r--index/vert.mk7
-rw-r--r--index/vmq_acl.mk7
-rw-r--r--index/vmq_graphite.mk7
-rw-r--r--index/vmq_passwd.mk7
-rw-r--r--index/vmq_server.mk7
-rw-r--r--index/vmq_snmp.mk7
-rw-r--r--index/vmq_systree.mk7
-rw-r--r--index/worker_pool.mk2
-rw-r--r--index/zab_engine.mk7
-rw-r--r--index/zabbix_sender.mk7
-rw-r--r--index/zeta.mk7
-rw-r--r--index/zraft_lib.mk7
-rwxr-xr-xpkg_add.sh2
-rw-r--r--plugins/asciidoc.mk4
-rw-r--r--plugins/bootstrap.mk4
-rw-r--r--plugins/c_src.mk32
-rw-r--r--plugins/ci.mk24
-rw-r--r--plugins/cover.mk24
-rw-r--r--plugins/ct.mk6
-rw-r--r--plugins/dialyzer.mk4
-rw-r--r--plugins/edoc.mk6
-rw-r--r--plugins/escript.mk12
-rw-r--r--plugins/eunit.mk3
-rw-r--r--plugins/proper.mk4
-rw-r--r--plugins/protobuffs.mk5
-rw-r--r--plugins/relx.mk104
-rw-r--r--plugins/triq.mk4
-rw-r--r--plugins/xref.mk223
-rwxr-xr-xscrape_hexpm.sh48
-rw-r--r--test/Makefile131
-rw-r--r--test/core_app.mk56
-rw-r--r--test/core_apps.mk2
-rw-r--r--test/core_compat.mk73
-rw-r--r--test/core_deps.mk167
-rw-r--r--test/core_makedep.mk20
-rw-r--r--test/core_query.mk2
-rw-r--r--test/hexpm_packages.txt1876
-rw-r--r--test/plugin_c_src.mk71
-rw-r--r--test/plugin_cover.mk83
-rw-r--r--test/plugin_edoc.mk63
-rw-r--r--test/plugin_escript.mk37
-rw-r--r--test/plugin_eunit.mk21
-rw-r--r--test/plugin_protobuffs.mk30
-rw-r--r--test/plugin_relx.mk171
-rw-r--r--test/plugin_xref.mk312
165 files changed, 3895 insertions, 1017 deletions
diff --git a/.gitignore b/.gitignore
index c1573e7..f2ca659 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ doc/guide.pdf
doc/html
test/logs/
test/packages/
+test/test_rebar_git/
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index f237592..6a38a21 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -1,29 +1,51 @@
-2018/12/03: Relx has been updated to v3.27.0.
-
-2018/12/03: Dependencies are no longer always rebuilt by
- default. Please check the documentation for
- information. A quick fix if this causes an
- issue is to add `FULL = 1` at the top of your
- Makefile.
-
-2018/12/06: Change the default COVER_DATA_DIR to be the
- same as COVER_REPORT_DIR.
-
-2019/06/20: `list-deps` now includes local applications
- found in the `APPS_DIR` directory.
-
-2020/03/25: The `-lerl_interface` argument has been removed
- from the default `LDLIBS`. This is an old library
- that is getting removed in OTP-23 and should no
- longer be used. Note that the default still includes
- `-lei` which is part of the Erlang/OTP Erl_Interface
- *application* but is built as a separate C library.
- The removal only applies to `-lerl_interface` itself.
-
-2020/06/18: Concuerror integration has been added. It is
- currently minimal but usable. Experimentation
- and feedback is welcome.
-
-2020/11/30: Support for publishing Hex releases and docs
- has been added. It is currently experimental.
- Feedback is more than welcome.
+2022/03/25: The -Wrace_conditions Dialyzer flag was removed
+ as it is no longer available starting from OTP 25.
+
+2022/05/20: Relx has been updated to v4. Relx v4 is no longer
+ an escript, therefore breaking changes were
+ introduced. The `RELX`, `RELX_URL` and `RELX_OPTS`
+ variables were removed. The `relx` project must
+ be added as a `DEPS`, `BUILD_DEPS` or `REL_DEPS`
+ dependency to enable building releases. For example:
+ `REL_DEPS = relx`. Relx itself has had some
+ additional changes: the `start` command has
+ been replaced by `daemon`, and configuration
+ defaults have changed so that you may need
+ to add the following to your relx.config file:
+
+ ``` erlang
+ {dev_mode, false}.
+ {include_erts, true}.
+ ```
+
+2022/05/31: Xref support has been rewritten. Erlang.mk no
+ longer uses the xref_runner, instead implementing
+ its own interface. This new interface is more
+ flexible and more powerful: it supports both
+ checks and informational analyses as well as
+ the Xref query functions that use the powerful
+ Xref language to perform custom queries. Erlang.mk
+ can also run analyses and queries against all
+ dependencies as well as Erlang/OTP applications.
+
+2023/05/12: Rebar3 is now used for autopatch instead of
+ Rebar2. `make distclean` or `rm -rf .erlang.mk`
+ might be required after updating Erlang.mk.
+ Moving to Rebar3 increases compatibility now
+ that few maintained projects are using Rebar2.
+ For compatibility reasons the variables to
+ point to a different rebar are now REBAR3_GIT
+ and REBAR3_COMMIT.
+
+2023/05/12: A number of broken packages have been removed.
+ They were all unmaintained and there's a low
+ chance that this will break anyone's project.
+
+2023/05/15: Protobuff compilation with `gpb` now uses the
+ `{use_packages, true}` option.
+
+2023/05/15: Experimental support for caching git and
+ hex dependencies has been added. Set
+ `CACHE_DEPS=1` to enable.
+
+2023/05/16: Remove support for HiPE and ErlLLVM.
diff --git a/Makefile b/Makefile
index b6b245c..f6d4287 100644
--- a/Makefile
+++ b/Makefile
@@ -50,6 +50,10 @@ MAKEOVERRIDES := $(filter-out p=$p,$(MAKEOVERRIDES))
check:
$(MAKE) -C test pkg-$p KEEP_BUILDS=1
else
+ifdef hp
+check:
+ $(MAKE) -C test hexpm-pkg-$(hp) KEEP_BUILDS=1 HEXPM=1
+else
ifdef c
check:
$(MAKE) -C test $c c=
@@ -58,10 +62,14 @@ check:
$(MAKE) -C test
endif
endif
+endif
packages:
$(MAKE) -C test packages
+hexpm-packages:
+ $(MAKE) -C test hexpm-packages HEXPM=1
+
summary:
@mkdir -p test/logs/
@touch test/logs/latest.log test/packages/errors.log
diff --git a/core/core.mk b/core/core.mk
index 77adc2e..250a2eb 100644
--- a/core/core.mk
+++ b/core/core.mk
@@ -171,7 +171,7 @@ endef
# Adding erlang.mk to make Erlang scripts who call init:get_plain_arguments() happy.
define erlang
-$(ERL) $2 -pz $(ERLANG_MK_TMP)/rebar/ebin -eval "$(subst $(newline),,$(call escape_dquotes,$1))" -- erlang.mk
+$(ERL) $2 -pz $(ERLANG_MK_TMP)/rebar3/_build/prod/lib/*/ebin/ -eval "$(subst $(newline),,$(call escape_dquotes,$1))" -- erlang.mk
endef
ifeq ($(PLATFORM),msys2)
@@ -184,8 +184,8 @@ core_http_get = curl -Lf$(if $(filter-out 0,$(V)),,s)o $(call core_native_path,$
core_eq = $(and $(findstring $(1),$(2)),$(findstring $(2),$(1)))
-# We skip files that contain spaces because they end up causing issues.
-core_find = $(if $(wildcard $1),$(shell find $(1:%/=%) \( -type l -o -type f \) -name $(subst *,\*,$2) | grep -v " "))
+# We skip files that contain spaces or '#' because they end up causing issues.
+core_find = $(if $(wildcard $1),$(shell find $(1:%/=%) \( -type l -o -type f \) -name $(subst *,\*,$2) -not -name "*[ \#]*"))
core_lc = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$(1)))))))))))))))))))))))))))
diff --git a/core/deps.mk b/core/deps.mk
index 6d6623b..610f642 100644
--- a/core/deps.mk
+++ b/core/deps.mk
@@ -21,8 +21,13 @@ export DEPS_DIR
REBAR_DEPS_DIR = $(DEPS_DIR)
export REBAR_DEPS_DIR
-REBAR_GIT ?= https://github.com/rebar/rebar
-REBAR_COMMIT ?= 576e12171ab8d69b048b827b92aa65d067deea01
+REBAR3_GIT ?= https://github.com/erlang/rebar3
+REBAR3_COMMIT ?= 06aaecd51b0ce828b66bb65a74d3c1fd7833a4ba # 3.22.1 + OTP-27 fixes
+
+CACHE_DEPS ?= 0
+
+CACHE_DIR ?= $(if $(XDG_CACHE_HOME),$(XDG_CACHE_HOME),$(HOME)/.cache)/erlang.mk
+export CACHE_DIR
# External "early" plugins (see core/plugins.mk for regular plugins).
# They both use the core_dep_plugin macro.
@@ -206,6 +211,9 @@ ifneq ($(ALL_DEPS_DIRS),)
echo $$dep >> $(ERLANG_MK_TMP)/deps.log; \
if [ -z "$(strip $(FULL))" ] $(if $(force_rebuild_dep),&& ! ($(call force_rebuild_dep,$$dep)),) && [ ! -L $$dep ] && [ -f $$dep/ebin/dep_built ]; then \
:; \
+ elif [ "$$dep" = "$(DEPS_DIR)/hut" -a "$(HUT_PATCH)" ]; then \
+ $(MAKE) -C $$dep app IS_DEP=1; \
+ if [ ! -L $$dep ] && [ -d $$dep/ebin ]; then touch $$dep/ebin/dep_built; fi; \
elif [ -f $$dep/GNUmakefile ] || [ -f $$dep/makefile ] || [ -f $$dep/Makefile ]; then \
$(MAKE) -C $$dep IS_DEP=1; \
if [ ! -L $$dep ] && [ -d $$dep/ebin ]; then touch $$dep/ebin/dep_built; fi; \
@@ -301,10 +309,10 @@ define dep_autopatch_fetch_rebar
endef
define dep_autopatch_fetch_rebar2
- if [ ! -d $(ERLANG_MK_TMP)/rebar ]; then \
- git clone -q -n -- $(REBAR_GIT) $(ERLANG_MK_TMP)/rebar; \
- cd $(ERLANG_MK_TMP)/rebar; \
- git checkout -q $(REBAR_COMMIT); \
+ if [ ! -d $(ERLANG_MK_TMP)/rebar3 ]; then \
+ git clone -q -n -- $(REBAR3_GIT) $(ERLANG_MK_TMP)/rebar3; \
+ cd $(ERLANG_MK_TMP)/rebar3; \
+ git checkout -q $(REBAR3_COMMIT); \
./bootstrap; \
cd -; \
fi
@@ -321,7 +329,7 @@ endef
define dep_autopatch_rebar.erl
application:load(rebar),
application:set_env(rebar, log_level, debug),
- rmemo:start(),
+ {module, rebar3} = c:l(rebar3),
Conf1 = case file:consult("$(call core_native_path,$(DEPS_DIR)/$1/rebar.config)") of
{ok, Conf0} -> Conf0;
_ -> []
@@ -355,7 +363,7 @@ define dep_autopatch_rebar.erl
(V) when is_list(V) -> "'\\"" ++ V ++ "\\"'"
end,
fun() ->
- Write("ERLC_OPTS = +debug_info\nexport ERLC_OPTS\n"),
+ Write("ERLC_OPTS = +debug_info\n"),
case lists:keyfind(erl_opts, 1, Conf) of
false -> ok;
{_, ErlOpts} ->
@@ -378,12 +386,23 @@ define dep_autopatch_rebar.erl
end,
Write("\n")
end(),
- GetHexVsn = fun(N, NP) ->
+ GetHexVsn2 = fun(N, NP) ->
case file:consult("$(call core_native_path,$(DEPS_DIR)/$1/rebar.lock)") of
{ok, Lock} ->
io:format("~p~n", [Lock]),
- case lists:keyfind("1.1.0", 1, Lock) of
- {_, LockPkgs} ->
+ LockPkgs = case lists:keyfind("1.2.0", 1, Lock) of
+ {_, LP} ->
+ LP;
+ _ ->
+ case lists:keyfind("1.1.0", 1, Lock) of
+ {_, LP} ->
+ LP;
+ _ ->
+ false
+ end
+ end,
+ if
+ is_list(LockPkgs) ->
io:format("~p~n", [LockPkgs]),
case lists:keyfind(atom_to_binary(N, latin1), 1, LockPkgs) of
{_, {pkg, _, Vsn}, _} ->
@@ -392,35 +411,46 @@ define dep_autopatch_rebar.erl
_ ->
false
end;
- _ ->
+ true ->
false
end;
_ ->
false
end
end,
- SemVsn = fun
- ("~>" ++ S0) ->
- S = case S0 of
- " " ++ S1 -> S1;
- _ -> S0
- end,
- case length([ok || $$. <- S]) of
- 0 -> S ++ ".0.0";
- 1 -> S ++ ".0";
- _ -> S
- end;
- (S) -> S
+ GetHexVsn3Common = fun(N, NP, S0) ->
+ case GetHexVsn2(N, NP) of
+ false ->
+ S2 = case S0 of
+ " " ++ S1 -> S1;
+ _ -> S0
+ end,
+ S = case length([ok || $$. <- S2]) of
+ 0 -> S2 ++ ".0.0";
+ 1 -> S2 ++ ".0";
+ _ -> S2
+ end,
+ {N, {hex, NP, S}};
+ NameSource ->
+ NameSource
+ end
+ end,
+ GetHexVsn3 = fun
+ (N, NP, "~>" ++ S0) ->
+ GetHexVsn3Common(N, NP, S0);
+ (N, NP, ">=" ++ S0) ->
+ GetHexVsn3Common(N, NP, S0);
+ (N, NP, S) -> {N, {hex, NP, S}}
end,
fun() ->
File = case lists:keyfind(deps, 1, Conf) of
false -> [];
{_, Deps} ->
[begin case case Dep of
- N when is_atom(N) -> GetHexVsn(N, N);
- {N, S} when is_atom(N), is_list(S) -> {N, {hex, N, SemVsn(S)}};
- {N, {pkg, NP}} when is_atom(N) -> GetHexVsn(N, NP);
- {N, S, {pkg, NP}} -> {N, {hex, NP, S}};
+ N when is_atom(N) -> GetHexVsn2(N, N);
+ {N, S} when is_atom(N), is_list(S) -> GetHexVsn3(N, N, S);
+ {N, {pkg, NP}} when is_atom(N) -> GetHexVsn2(N, NP);
+ {N, S, {pkg, NP}} -> GetHexVsn3(N, NP, S);
{N, S} when is_tuple(S) -> {N, S};
{N, _, S} -> {N, S};
{N, _, S, _} -> {N, S};
@@ -443,13 +473,16 @@ define dep_autopatch_rebar.erl
fun() ->
case lists:keyfind(erl_first_files, 1, Conf) of
false -> ok;
- {_, Files} ->
+ {_, Files0} ->
+ Files = [begin
+ hd(filelib:wildcard("$(call core_native_path,$(DEPS_DIR)/$1/src/)**/" ++ filename:rootname(F) ++ ".*rl"))
+ end || "src/" ++ F <- Files0],
Names = [[" ", case lists:reverse(F) of
"lre." ++ Elif -> lists:reverse(Elif);
"lrx." ++ Elif -> lists:reverse(Elif);
"lry." ++ Elif -> lists:reverse(Elif);
Elif -> lists:reverse(Elif)
- end] || "src/" ++ F <- Files],
+ end] || "$(call core_native_path,$(DEPS_DIR)/$1/src/)" ++ F <- Files],
Write(io_lib:format("COMPILE_FIRST +=~s\n", [Names]))
end
end(),
@@ -476,6 +509,8 @@ define dep_autopatch_rebar.erl
Write("\npre-deps::\n\t" ++ PatchHook(Cmd) ++ "\n");
{compile, Cmd} ->
Write("\npre-app::\n\tCC=$$\(CC) " ++ PatchHook(Cmd) ++ "\n");
+ {{pc, compile}, Cmd} ->
+ Write("\npre-app::\n\tCC=$$\(CC) " ++ PatchHook(Cmd) ++ "\n");
{Regex, compile, Cmd} ->
case rebar_utils:is_arch(Regex) of
true -> Write("\npre-app::\n\tCC=$$\(CC) " ++ PatchHook(Cmd) ++ "\n");
@@ -566,9 +601,11 @@ define dep_autopatch_rebar.erl
[[Output, ": ", K, " += ", ShellToMk(V), "\n"] || {K, V} <- lists:reverse(MergeEnv(FilterEnv(Env)))],
Output, ": $$\(foreach ext,.c .C .cc .cpp,",
"$$\(patsubst %$$\(ext),%.o,$$\(filter %$$\(ext),$$\(wildcard", Input, "))))\n",
- "\t$$\(CC) -o $$\@ $$\? $$\(LDFLAGS) $$\(ERL_LDFLAGS) $$\(DRV_LDFLAGS) $$\(EXE_LDFLAGS)",
+ "\t$$\(CC) -o $$\@ $$\? $$\(LDFLAGS) $$\(ERL_LDFLAGS) $$\(DRV_LDFLAGS) $$\(LDLIBS) $$\(EXE_LDFLAGS)",
case {filename:extension(Output), $(PLATFORM)} of
{[], _} -> "\n";
+ {".so", darwin} -> " -shared\n";
+ {".dylib", darwin} -> " -shared\n";
{_, darwin} -> "\n";
_ -> " -shared\n"
end])
@@ -638,9 +675,12 @@ endef
define dep_autopatch_appsrc_script.erl
AppSrc = "$(call core_native_path,$(DEPS_DIR)/$1/src/$1.app.src)",
AppSrcScript = AppSrc ++ ".script",
- {ok, Conf0} = file:consult(AppSrc),
+ Conf1 = case file:consult(AppSrc) of
+ {ok, Conf0} -> Conf0;
+ {error, enoent} -> []
+ end,
Bindings0 = erl_eval:new_bindings(),
- Bindings1 = erl_eval:add_binding('CONFIG', Conf0, Bindings0),
+ Bindings1 = erl_eval:add_binding('CONFIG', Conf1, Bindings0),
Bindings = erl_eval:add_binding('SCRIPT', AppSrcScript, Bindings1),
Conf = case file:script(AppSrcScript, Bindings) of
{ok, [C]} -> C;
@@ -670,9 +710,39 @@ define dep_autopatch_appsrc.erl
halt()
endef
+ifeq ($(CACHE_DEPS),1)
+
+define dep_cache_fetch_git
+ mkdir -p $(CACHE_DIR)/git; \
+ if test -d "$(join $(CACHE_DIR)/git/,$(call dep_name,$1))"; then \
+ cd $(join $(CACHE_DIR)/git/,$(call dep_name,$1)); \
+ if ! git checkout -q $(call dep_commit,$1); then \
+ git remote set-url origin $(call dep_repo,$1) && \
+ git pull --all && \
+ git cat-file -e $(call dep_commit,$1) 2>/dev/null; \
+ fi; \
+ else \
+ git clone -q -n -- $(call dep_repo,$1) $(join $(CACHE_DIR)/git/,$(call dep_name,$1)); \
+ fi; \
+ git clone -q --branch $(call dep_commit,$1) --single-branch -- $(join $(CACHE_DIR)/git/,$(call dep_name,$1)) $2
+endef
+
+define dep_fetch_git
+ $(call dep_cache_fetch_git,$1,$(DEPS_DIR)/$(call dep_name,$1));
+endef
+
+define dep_fetch_git-subfolder
+ mkdir -p $(ERLANG_MK_TMP)/git-subfolder; \
+ $(call dep_cache_fetch_git,$1,$(ERLANG_MK_TMP)/git-subfolder/$(call dep_name,$1)); \
+ ln -s $(ERLANG_MK_TMP)/git-subfolder/$(call dep_name,$1)/$(word 4,$(dep_$1)) \
+ $(DEPS_DIR)/$(call dep_name,$1);
+endef
+
+else
+
define dep_fetch_git
- git clone -q -n -- $(call dep_repo,$(1)) $(DEPS_DIR)/$(call dep_name,$(1)); \
- cd $(DEPS_DIR)/$(call dep_name,$(1)) && git checkout -q $(call dep_commit,$(1));
+ git clone -q -n -- $(call dep_repo,$1) $(DEPS_DIR)/$(call dep_name,$1); \
+ cd $(DEPS_DIR)/$(call dep_name,$1) && git checkout -q $(call dep_commit,$1);
endef
define dep_fetch_git-subfolder
@@ -681,10 +751,12 @@ define dep_fetch_git-subfolder
$(ERLANG_MK_TMP)/git-subfolder/$(call dep_name,$1); \
cd $(ERLANG_MK_TMP)/git-subfolder/$(call dep_name,$1) \
&& git checkout -q $(call dep_commit,$1); \
- ln -s $(ERLANG_MK_TMP)/git-subfolder/$(call dep_name,$1)/$(word 4,$(dep_$(1))) \
+ ln -s $(ERLANG_MK_TMP)/git-subfolder/$(call dep_name,$1)/$(word 4,$(dep_$1)) \
$(DEPS_DIR)/$(call dep_name,$1);
endef
+endif
+
define dep_fetch_git-submodule
git submodule update --init -- $(DEPS_DIR)/$1;
endef
@@ -706,6 +778,19 @@ define dep_fetch_ln
ln -s $(call dep_repo,$(1)) $(DEPS_DIR)/$(call dep_name,$(1));
endef
+ifeq ($(CACHE_DEPS),1)
+
+# Hex only has a package version. No need to look in the Erlang.mk packages.
+define dep_fetch_hex
+ mkdir -p $(CACHE_DIR)/hex $(DEPS_DIR)/$1; \
+ $(eval hex_tar_name=$(if $(word 3,$(dep_$1)),$(word 3,$(dep_$1)),$1)-$(strip $(word 2,$(dep_$1))).tar) \
+ $(if $(wildcard $(CACHE_DIR)/hex/$(hex_tar_name)),,$(call core_http_get,$(CACHE_DIR)/hex/$(hex_tar_name),\
+ https://repo.hex.pm/tarballs/$(hex_tar_name);)) \
+ tar -xOf $(CACHE_DIR)/hex/$(hex_tar_name) contents.tar.gz | tar -C $(DEPS_DIR)/$1 -xzf -;
+endef
+
+else
+
# Hex only has a package version. No need to look in the Erlang.mk packages.
define dep_fetch_hex
mkdir -p $(ERLANG_MK_TMP)/hex $(DEPS_DIR)/$1; \
@@ -714,6 +799,8 @@ define dep_fetch_hex
tar -xOf $(ERLANG_MK_TMP)/hex/$1.tar contents.tar.gz | tar -C $(DEPS_DIR)/$1 -xzf -;
endef
+endif
+
define dep_fetch_fail
echo "Error: Unknown or invalid dependency: $(1)." >&2; \
exit 78;
@@ -752,22 +839,7 @@ endif
.PHONY: autopatch-$(call dep_name,$1)
autopatch-$(call dep_name,$1)::
- $(verbose) if [ "$(1)" = "amqp_client" -a "$(RABBITMQ_CLIENT_PATCH)" ]; then \
- if [ ! -d $(DEPS_DIR)/rabbitmq-codegen ]; then \
- echo " PATCH Downloading rabbitmq-codegen"; \
- git clone https://github.com/rabbitmq/rabbitmq-codegen.git $(DEPS_DIR)/rabbitmq-codegen; \
- fi; \
- if [ ! -d $(DEPS_DIR)/rabbitmq-server ]; then \
- echo " PATCH Downloading rabbitmq-server"; \
- git clone https://github.com/rabbitmq/rabbitmq-server.git $(DEPS_DIR)/rabbitmq-server; \
- fi; \
- ln -s $(DEPS_DIR)/amqp_client/deps/rabbit_common-0.0.0 $(DEPS_DIR)/rabbit_common; \
- elif [ "$(1)" = "rabbit" -a "$(RABBITMQ_SERVER_PATCH)" ]; then \
- if [ ! -d $(DEPS_DIR)/rabbitmq-codegen ]; then \
- echo " PATCH Downloading rabbitmq-codegen"; \
- git clone https://github.com/rabbitmq/rabbitmq-codegen.git $(DEPS_DIR)/rabbitmq-codegen; \
- fi \
- elif [ "$1" = "elixir" -a "$(ELIXIR_PATCH)" ]; then \
+ $(verbose) if [ "$1" = "elixir" -a "$(ELIXIR_PATCH)" ]; then \
ln -s lib/elixir/ebin $(DEPS_DIR)/elixir/; \
else \
$$(call dep_autopatch,$(call dep_name,$1)) \
@@ -799,6 +871,16 @@ distclean-deps:
$(gen_verbose) rm -rf $(DEPS_DIR)
endif
+ifeq ($(CACHE_DEPS),1)
+cacheclean:: cacheclean-git cacheclean-hex
+
+cacheclean-git:
+ $(gen_verbose) rm -rf $(CACHE_DIR)/git
+
+cacheclean-hex:
+ $(gen_verbose) rm -rf $(CACHE_DIR)/hex
+endif
+
# Forward-declare variables used in core/deps-tools.mk. This is required
# in case plugins use them.
diff --git a/core/erlc.mk b/core/erlc.mk
index 71ba5b9..b8555b7 100644
--- a/core/erlc.mk
+++ b/core/erlc.mk
@@ -65,7 +65,8 @@ define app_file
{id$(comma)$(space)"$(1)"}$(comma))
{modules, [$(call comma_list,$(2))]},
{registered, []},
- {applications, [$(call comma_list,kernel stdlib $(OTP_DEPS) $(LOCAL_DEPS) $(foreach dep,$(DEPS),$(call dep_name,$(dep))))]},
+ {applications, [$(call comma_list,kernel stdlib $(OTP_DEPS) $(LOCAL_DEPS) $(OPTIONAL_DEPS) $(foreach dep,$(DEPS),$(call dep_name,$(dep))))]},
+ {optional_applications, [$(call comma_list,$(OPTIONAL_DEPS))]},
{env, $(subst \,\\,$(PROJECT_ENV))}$(if $(findstring {,$(PROJECT_APP_EXTRA_KEYS)),$(comma)$(newline)$(tab)$(subst \,\\,$(PROJECT_APP_EXTRA_KEYS)),)
]}.
endef
@@ -77,7 +78,8 @@ define app_file
{id$(comma)$(space)"$(1)"}$(comma))
{modules, [$(call comma_list,$(2))]},
{registered, [$(call comma_list,$(PROJECT)_sup $(PROJECT_REGISTERED))]},
- {applications, [$(call comma_list,kernel stdlib $(OTP_DEPS) $(LOCAL_DEPS) $(foreach dep,$(DEPS),$(call dep_name,$(dep))))]},
+ {applications, [$(call comma_list,kernel stdlib $(OTP_DEPS) $(LOCAL_DEPS) $(OPTIONAL_DEPS) $(foreach dep,$(DEPS),$(call dep_name,$(dep))))]},
+ {optional_applications, [$(call comma_list,$(OPTIONAL_DEPS))]},
{mod, {$(PROJECT_MOD), []}},
{env, $(subst \,\\,$(PROJECT_ENV))}$(if $(findstring {,$(PROJECT_APP_EXTRA_KEYS)),$(comma)$(newline)$(tab)$(subst \,\\,$(PROJECT_APP_EXTRA_KEYS)),)
]}.
@@ -222,7 +224,6 @@ define makedep.erl
end,
MakeDepend = fun
(F, Fd, Mod, StartLocation) ->
- {ok, Filename} = file:pid2name(Fd),
case io:parse_erl_form(Fd, undefined, StartLocation) of
{ok, AbsData, EndLocation} ->
case AbsData of
diff --git a/core/kerl.mk b/core/kerl.mk
index eec0712..f6995e9 100644
--- a/core/kerl.mk
+++ b/core/kerl.mk
@@ -28,15 +28,6 @@ $(KERL_INSTALL_DIR)/$(1): $(KERL)
fi
endef
-define kerl_hipe_target
-$(KERL_INSTALL_DIR)/$1-native: $(KERL)
- $(verbose) if [ ! -d $$@ ]; then \
- KERL_CONFIGURE_OPTIONS=--enable-native-libs \
- MAKEFLAGS="$(KERL_MAKEFLAGS)" $(KERL) build git $(OTP_GIT) $1 $1-native; \
- $(KERL) install $1-native $(KERL_INSTALL_DIR)/$1-native; \
- fi
-endef
-
$(KERL): $(KERL_DIR)
$(KERL_DIR): | $(ERLANG_MK_TMP)
@@ -59,10 +50,10 @@ ERLANG_OTP := $(notdir $(lastword $(sort\
endif
ERLANG_OTP ?=
-ERLANG_HIPE ?=
# Use kerl to enforce a specific Erlang/OTP version for a project.
ifneq ($(strip $(ERLANG_OTP)),)
+
export PATH := $(KERL_INSTALL_DIR)/$(ERLANG_OTP)/bin:$(PATH)
SHELL := env PATH=$(PATH) $(SHELL)
$(eval $(call kerl_otp_target,$(ERLANG_OTP)))
@@ -73,18 +64,4 @@ $(info Building Erlang/OTP $(ERLANG_OTP)... Please wait...)
$(shell $(MAKE) $(KERL_INSTALL_DIR)/$(ERLANG_OTP) ERLANG_OTP=$(ERLANG_OTP) BUILD_ERLANG_OTP=1 >&2)
endif
-else
-# Same for a HiPE enabled VM.
-ifneq ($(strip $(ERLANG_HIPE)),)
-export PATH := $(KERL_INSTALL_DIR)/$(ERLANG_HIPE)-native/bin:$(PATH)
-SHELL := env PATH=$(PATH) $(SHELL)
-$(eval $(call kerl_hipe_target,$(ERLANG_HIPE)))
-
-# Build Erlang/OTP only if it doesn't already exist.
-ifeq ($(wildcard $(KERL_INSTALL_DIR)/$(ERLANG_HIPE)-native)$(BUILD_ERLANG_OTP),)
-$(info Building HiPE-enabled Erlang/OTP $(ERLANG_OTP)... Please wait...)
-$(shell $(MAKE) $(KERL_INSTALL_DIR)/$(ERLANG_HIPE)-native ERLANG_HIPE=$(ERLANG_HIPE) BUILD_ERLANG_OTP=1 >&2)
-endif
-
-endif
endif
diff --git a/doc/src/guide/ci.asciidoc b/doc/src/guide/ci.asciidoc
index 2b69e28..2fa5feb 100644
--- a/doc/src/guide/ci.asciidoc
+++ b/doc/src/guide/ci.asciidoc
@@ -10,9 +10,7 @@ section of the xref:kerl[OTP version management] chapter.)
=== Configuring Erlang/OTP versions to test
To use the CI plugin you must first configure which versions
-of Erlang/OTP will be used. Erlang.mk provides three separate
-configuration variables depending on whether you need a normal
-OTP release, a HiPE-enabled release or an ErLLVM-enabled release.
+of Erlang/OTP will be used.
At the time of writing, this is how you would test against all
the most recent patch releases of Erlang/OTP 19 and above:
@@ -20,13 +18,6 @@ the most recent patch releases of Erlang/OTP 19 and above:
[source,make]
CI_OTP = OTP-19.0.7 OTP-19.1.6 OTP-19.2.3 OTP-19.3.6.2 OTP-20.0.4
-If you want to test against HiPE and ErLLVM but only with the
-latest version of Erlang/OTP, the following could work:
-
-[source,make]
-CI_HIPE = $(lastword $(CI_OTP))
-CI_ERLLVM = $(CI_HIPE)
-
Consult the xref:kerl[OTP version management] chapter for more
information about Erlang/OTP versions and customization of the
Erlang/OTP builds.
diff --git a/doc/src/guide/common_test.asciidoc b/doc/src/guide/common_test.asciidoc
index 993bb8c..05e43eb 100644
--- a/doc/src/guide/common_test.asciidoc
+++ b/doc/src/guide/common_test.asciidoc
@@ -99,5 +99,11 @@ the test suite does not group test cases:
[source,bash]
$ make ct-http c=headers_dupe
+A test within a specific subgroup can be run by providing a
+group path:
+
+[source,bash]
+$ make ct-http t=[top_level_group,second_level_group,third_level_group]:my_case
+
Finally, xref:coverage[code coverage] is available,
but covered in its own chapter.
diff --git a/doc/src/guide/coverage.asciidoc b/doc/src/guide/coverage.asciidoc
index 02f8b5b..af159d8 100644
--- a/doc/src/guide/coverage.asciidoc
+++ b/doc/src/guide/coverage.asciidoc
@@ -46,6 +46,17 @@ some applications by defining the `COVER_APPS` variable:
[source,make]
COVER_APPS = presence backend
+=== Removing modules from the cover report
+
+By default Erlang.mk will include all modules in the
+cover report.
+
+To exclude some modules from the report, you can
+define the `COVER_EXCLUDE_MODS` variable:
+
+[source,make]
+COVER_EXCLUDE_MODS = cowboy_app cowboy_sup
+
=== Configuring paths
By default Erlang.mk will store 'coverdata' files and
diff --git a/doc/src/guide/deps.asciidoc b/doc/src/guide/deps.asciidoc
index 081f4f7..c46dce6 100644
--- a/doc/src/guide/deps.asciidoc
+++ b/doc/src/guide/deps.asciidoc
@@ -132,6 +132,18 @@ target `deps::` before including 'erlang.mk', for example:
[source,make]
deps:: $(CURDIR)/deps/triq
+Sometimes dependencies are allowed to be missing. However, your application
+may depend on an optional application being started. To ensure that an
+optional dependency is started before your application, the variable
+`OPTIONAL_DEPS` may be used:
+
+[source,make]
+OPTIONAL_DEPS = quicer
+
+The top-level project can then decide whether to include this
+application by adding it to its `BUILD_DEPS` and including
+it in the release dependencies.
+
==== Modifying the dependency source or version
By default, Erlang.mk will look into its package index to
@@ -154,7 +166,7 @@ DEPS = cowboy
dep_cowboy_commit = 2.0.0-pre.2
Erlang.mk will use the package index to get all information
-about Cowboy, except the commit number which will be overriden.
+about Cowboy, except the commit number which will be overridden.
If you need to set the fetch method or repository information
too, for example because you want to use your own fork, or
@@ -559,10 +571,8 @@ performed:
* Run autopatch on the project
Autopatch first checks if there is any project-specific patch
-enabled. There are currently three: `RABBITMQ_CLIENT_PATCH` for
-the `amqp_client` dependency (before 3.6.0), `RABBITMQ_SERVER_PATCH`
-for the `rabbit` dependency (before 3.6.0) and `ELIXIR_PATCH`
-for the `elixir` dependency.
+enabled. There are currently two: `ELIXIR_PATCH` for the `elixir`
+dependency and `HUT_PATCH` for the `hut` dependency.
Otherwise, autopatch performs different operations depending
on the kind of project it finds the dependency to be.
diff --git a/doc/src/guide/installation.asciidoc b/doc/src/guide/installation.asciidoc
index 0c21fb0..1f7e178 100644
--- a/doc/src/guide/installation.asciidoc
+++ b/doc/src/guide/installation.asciidoc
@@ -134,7 +134,7 @@ C:\> C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syu"
==== Installing the required MSYS2 packages
After following these instructions, you can install GNU Make,
-Git and any other required softwares. From an MSYS2 shell,
+Git and any other required software. From an MSYS2 shell,
you can call `pacman` directly:
[source,bash]
diff --git a/doc/src/guide/ports.asciidoc b/doc/src/guide/ports.asciidoc
index 907ee36..3be5bf2 100644
--- a/doc/src/guide/ports.asciidoc
+++ b/doc/src/guide/ports.asciidoc
@@ -81,7 +81,7 @@ nothing.
Erlang.mk sets appropriate compile and linker flags by default.
These flags vary depending on the platform, and can of course
-be overriden.
+be overridden.
`CC`::
The compiler to be used.
diff --git a/doc/src/guide/releases.asciidoc b/doc/src/guide/releases.asciidoc
index 68174b3..a3bdb10 100644
--- a/doc/src/guide/releases.asciidoc
+++ b/doc/src/guide/releases.asciidoc
@@ -7,8 +7,15 @@ https://erlware.github.io/relx/[Relx website] for more information.
=== Setup
-Erlang.mk will create a release if it detects a Relx configuration
-file in the '$(RELX_CONFIG)' location. This defaults to
+First, `relx` must be added in the dependencies of your
+project. You can add it to `REL_DEPS` so that it is fetched
+whenever you need to build the release:
+
+[source,erlang]
+REL_DEPS = relx
+
+Then, you need to create a 'relx.config' file in the
+'$(RELX_CONFIG)' location. This defaults to
'$(CURDIR)/relx.config'. You can override it by defining
the variable before including Erlang.mk:
@@ -29,14 +36,6 @@ RELX_CONFIG = $(CURDIR)/relx.dev.config
endif
----
-Relx does not need to be installed. Erlang.mk will download
-and build it automatically.
-
-The Relx executable will be saved in the '$(RELX)' file. This
-location defaults to '$(CURDIR)/relx' and can be overriden.
-
-// @todo You can use a custom location by ???
-
=== Configuration
You can specify additional Relx options using the `RELX_OPTS`
diff --git a/doc/src/guide/xref.asciidoc b/doc/src/guide/xref.asciidoc
index 44ed190..07bf05e 100644
--- a/doc/src/guide/xref.asciidoc
+++ b/doc/src/guide/xref.asciidoc
@@ -1,6 +1,183 @@
[[xref]]
== Xref
-// @todo Write it.
+Xref is a cross reference tool for analyzing dependencies
+between functions, modules, applications and releases.
+Erlang.mk provides an interface to analyzing all except
+the releases.
-Placeholder chapter.
+Both predefined checks and custom queries are supported
+in Erlang.mk.
+
+=== Usage
+
+To run Xref with the default predefined checks:
+
+[source,bash]
+$ make xref
+
+Erlang.mk will error out when warnings are found.
+
+The following predefined checks can be used:
+
+* `undefined_function_calls`
+* `undefined_functions` (similar to the previous)
+* `locals_not_used` (detected by the compiler)
+* `exports_not_used`
+* `deprecated_function_calls` (also detected by the compiler)
+* `deprecated_functions` (similar to the previous)
+* `{deprecated_function_calls, Flag}`
+* `{deprecated_functions, Flag}` (similar to the previous)
+
+Erlang.mk will only run the `undefined_function_calls`
+check by default.
+
+To change the check the `XREF_CHECKS` variable can be used:
+
+[source,bash]
+$ make xref XREF_CHECKS=exports_not_used
+
+Multiple checks can be run at once. The checks variable
+must be defined as an Erlang list:
+
+[source,bash]
+$ make xref XREF_CHECKS="[undefined_function_calls, exports_not_used]"
+
+Erlang.mk also supports informational analyses. Those will
+not error out when results are found, since they are not
+errors. To find all modules that call `cowboy_req` functions:
+
+[source,bash]
+$ make xref XREF_CHECKS="{module_use, cowboy_req}"
+
+The following informational checks are supported:
+
+* `{call, MFA}` - functions that MFA calls
+* `{use, MFA}` - functions that call MFA
+* `{module_call, Mod}` - modules that Mod calls (Mod depends on them)
+* `{module_use, Mod}` - modules that call Mod (they depend on Mod)
+* `{application_call, App}` - apps that App calls (App depends on them)
+* `{application_use, App}` - apps that call App (they depend on App)
+
+The scope might need to be increased in order to obtain
+the complete results of informational checks. This is
+especially true for module and applications, with
+application results being dependent on the applications
+being added to the scope to be found.
+
+=== Queries
+
+Erlang.mk provides an interface to the Xref query
+functions. To perform a query, the `q` variable
+must be used instead of `XREF_CHECKS`. For example,
+to obtain all unresolved calls:
+
+[source,bash]
+$ make xref q=UC
+
+The query language is documented at the top of the
+link:https://www.erlang.org/doc/man/xref.html[Xref manual page].
+
+=== Analysis scope
+
+Erlang.mk will set the scope of analysis to the current
+project by default. The scope can be automatically
+extended to the applications from multi-application
+repositories, to dependencies and to the built-in
+Erlang/OTP applications themselves.
+
+To change the scope, the `XREF_SCOPE` variable can be
+set. The variable can either be set in your Makefile
+or from the command line. The following values can
+be defined:
+
+* `app` - the current project
+* `apps` - applications from multi-application repositories
+* `deps` - dependencies
+* `otp` - Erlang/OTP applications
+
+To get the most complete analysis possible they should
+all be added to the variable:
+
+[source,bash]
+----
+$ make xref XREF_CHECKS="{application_use, ssl}" XREF_SCOPE="app apps deps otp"
+Application ssl is used by:
+- my_app
+- diameter
+- eldap
+- ftp
+- inets
+- ssl
+----
+
+Additional applications can be provided using the
+`XREF_EXTRA_APP_DIRS` variable. Note that these
+applications will need to be compiled before they
+can be found by Xref.
+
+Similarly, non-application directories can be
+added using `XREF_EXTRA_DIRS`. The directory
+to be provided must be the one that contains
+the beam files.
+
+=== Ignoring warnings
+
+Sometimes it is necessary to ignore warnings because
+they are expected. This is the case for example
+when multiple Erlang/OTP versions must be supported
+and modules or functions have been added or removed.
+
+Erlang.mk supports both project-wide configuration
+and Rebar-compatible inline ignores. To ignore
+warnings for a function in the current module the
+following line can be added to the source file:
+
+[source,erlang]
+----
+-ignore_xref({log, 1}).
+----
+
+The module name can be specified explicitly:
+
+[source,erlang]
+----
+-ignore_xref({my_mod, log, 1}).
+----
+
+As well as a full module can be ignored:
+
+[source,erlang]
+----
+-ignore_xref(my_mod).
+----
+
+The ignored functions can be provided as a list:
+
+[source,erlang]
+----
+-ignore_xref([{log, 1}, {pretty_print, 1}]).
+----
+
+The `XREF_IGNORE` variable can be used to define
+functions and modules to ignore project-wide. It
+accepts either MFAs or modules:
+
+[source,make]
+XREF_IGNORE = {my_mod, log, 1}
+
+Multiple ignores must be provided as an Erlang
+list:
+
+[source,make]
+XREF_IGNORE = [{my_mod, log, 1}, other_mod]
+
+By default Erlang.mk will ignore unused exports
+for behavior callbacks when the `exports_not_used`
+check is run. It is possible to override this
+behavior, or to ignore the callbacks for queries
+and other checks, by defining the `XREF_IGNORE_CALLBACKS`
+variable:
+
+[source,bash]
+$ make xref XREF_CHECKS=exports_not_used XREF_IGNORE_CALLBACKS=0
diff --git a/index/actordb_core.mk b/index/actordb_core.mk
deleted file mode 100644
index 9e4abc9..0000000
--- a/index/actordb_core.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += actordb_core
-pkg_actordb_core_name = actordb_core
-pkg_actordb_core_description = ActorDB main source
-pkg_actordb_core_homepage = http://www.actordb.com/
-pkg_actordb_core_fetch = git
-pkg_actordb_core_repo = https://github.com/biokoda/actordb_core
-pkg_actordb_core_commit = master
diff --git a/index/actordb_thrift.mk b/index/actordb_thrift.mk
deleted file mode 100644
index f39ac65..0000000
--- a/index/actordb_thrift.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += actordb_thrift
-pkg_actordb_thrift_name = actordb_thrift
-pkg_actordb_thrift_description = Thrift API for ActorDB
-pkg_actordb_thrift_homepage = http://www.actordb.com/
-pkg_actordb_thrift_fetch = git
-pkg_actordb_thrift_repo = https://github.com/biokoda/actordb_thrift
-pkg_actordb_thrift_commit = master
diff --git a/index/amqp_client.mk b/index/amqp_client.mk
deleted file mode 100644
index 13e7f48..0000000
--- a/index/amqp_client.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += amqp_client
-pkg_amqp_client_name = amqp_client
-pkg_amqp_client_description = RabbitMQ Erlang AMQP client
-pkg_amqp_client_homepage = https://www.rabbitmq.com/erlang-client-user-guide.html
-pkg_amqp_client_fetch = git
-pkg_amqp_client_repo = https://github.com/rabbitmq/rabbitmq-erlang-client.git
-pkg_amqp_client_commit = master
diff --git a/index/antidote.mk b/index/antidote.mk
deleted file mode 100644
index ea590b2..0000000
--- a/index/antidote.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += antidote
-pkg_antidote_name = antidote
-pkg_antidote_description = Large-scale computation without synchronisation
-pkg_antidote_homepage = https://syncfree.lip6.fr/
-pkg_antidote_fetch = git
-pkg_antidote_repo = https://github.com/SyncFree/antidote
-pkg_antidote_commit = master
diff --git a/index/azdht.mk b/index/azdht.mk
deleted file mode 100644
index 04e36d9..0000000
--- a/index/azdht.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += azdht
-pkg_azdht_name = azdht
-pkg_azdht_description = Azureus Distributed Hash Table (DHT) in Erlang
-pkg_azdht_homepage = https://github.com/arcusfelis/azdht
-pkg_azdht_fetch = git
-pkg_azdht_repo = https://github.com/arcusfelis/azdht
-pkg_azdht_commit = master
diff --git a/index/beanstalk.mk b/index/beanstalk.mk
deleted file mode 100644
index 799feaa..0000000
--- a/index/beanstalk.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += beanstalk
-pkg_beanstalk_name = beanstalk
-pkg_beanstalk_description = An Erlang client for beanstalkd
-pkg_beanstalk_homepage = https://github.com/tim/erlang-beanstalk
-pkg_beanstalk_fetch = git
-pkg_beanstalk_repo = https://github.com/tim/erlang-beanstalk
-pkg_beanstalk_commit = master
diff --git a/index/bitstore.mk b/index/bitstore.mk
deleted file mode 100644
index 67ec24f..0000000
--- a/index/bitstore.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += bitstore
-pkg_bitstore_name = bitstore
-pkg_bitstore_description = A document based ontology development environment
-pkg_bitstore_homepage = https://github.com/bdionne/bitstore
-pkg_bitstore_fetch = git
-pkg_bitstore_repo = https://github.com/bdionne/bitstore
-pkg_bitstore_commit = master
diff --git a/index/carotene.mk b/index/carotene.mk
deleted file mode 100644
index 9eee089..0000000
--- a/index/carotene.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += carotene
-pkg_carotene_name = carotene
-pkg_carotene_description = Real-time server
-pkg_carotene_homepage = https://github.com/carotene/carotene
-pkg_carotene_fetch = git
-pkg_carotene_repo = https://github.com/carotene/carotene
-pkg_carotene_commit = master
diff --git a/index/chronos.mk b/index/chronos.mk
index b538f1c..5c536fe 100644
--- a/index/chronos.mk
+++ b/index/chronos.mk
@@ -1,6 +1,6 @@
PACKAGES += chronos
pkg_chronos_name = chronos
-pkg_chronos_description = Timer module for Erlang that makes it easy to abstact time out of the tests.
+pkg_chronos_description = Timer module for Erlang that makes it easy to abstract time out of the tests.
pkg_chronos_homepage = https://github.com/lehoff/chronos
pkg_chronos_fetch = git
pkg_chronos_repo = https://github.com/lehoff/chronos
diff --git a/index/cloudi_service_db.mk b/index/cloudi_service_db.mk
deleted file mode 100644
index d8adf91..0000000
--- a/index/cloudi_service_db.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += cloudi_service_db
-pkg_cloudi_service_db_name = cloudi_service_db
-pkg_cloudi_service_db_description = CloudI Database (in-memory/testing/generic)
-pkg_cloudi_service_db_homepage = http://cloudi.org/
-pkg_cloudi_service_db_fetch = git
-pkg_cloudi_service_db_repo = https://github.com/CloudI/cloudi_service_db
-pkg_cloudi_service_db_commit = master
diff --git a/index/cloudi_service_db_cassandra.mk b/index/cloudi_service_db_cassandra.mk
deleted file mode 100644
index e4d1c0b..0000000
--- a/index/cloudi_service_db_cassandra.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += cloudi_service_db_cassandra
-pkg_cloudi_service_db_cassandra_name = cloudi_service_db_cassandra
-pkg_cloudi_service_db_cassandra_description = Cassandra CloudI Service
-pkg_cloudi_service_db_cassandra_homepage = http://cloudi.org/
-pkg_cloudi_service_db_cassandra_fetch = git
-pkg_cloudi_service_db_cassandra_repo = https://github.com/CloudI/cloudi_service_db_cassandra
-pkg_cloudi_service_db_cassandra_commit = master
diff --git a/index/cloudi_service_db_cassandra_cql.mk b/index/cloudi_service_db_cassandra_cql.mk
deleted file mode 100644
index b362832..0000000
--- a/index/cloudi_service_db_cassandra_cql.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += cloudi_service_db_cassandra_cql
-pkg_cloudi_service_db_cassandra_cql_name = cloudi_service_db_cassandra_cql
-pkg_cloudi_service_db_cassandra_cql_description = Cassandra CQL CloudI Service
-pkg_cloudi_service_db_cassandra_cql_homepage = http://cloudi.org/
-pkg_cloudi_service_db_cassandra_cql_fetch = git
-pkg_cloudi_service_db_cassandra_cql_repo = https://github.com/CloudI/cloudi_service_db_cassandra_cql
-pkg_cloudi_service_db_cassandra_cql_commit = master
diff --git a/index/cloudi_service_db_couchdb.mk b/index/cloudi_service_db_couchdb.mk
deleted file mode 100644
index 864a784..0000000
--- a/index/cloudi_service_db_couchdb.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += cloudi_service_db_couchdb
-pkg_cloudi_service_db_couchdb_name = cloudi_service_db_couchdb
-pkg_cloudi_service_db_couchdb_description = CouchDB CloudI Service
-pkg_cloudi_service_db_couchdb_homepage = http://cloudi.org/
-pkg_cloudi_service_db_couchdb_fetch = git
-pkg_cloudi_service_db_couchdb_repo = https://github.com/CloudI/cloudi_service_db_couchdb
-pkg_cloudi_service_db_couchdb_commit = master
diff --git a/index/cloudi_service_db_elasticsearch.mk b/index/cloudi_service_db_elasticsearch.mk
deleted file mode 100644
index b556ee5..0000000
--- a/index/cloudi_service_db_elasticsearch.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += cloudi_service_db_elasticsearch
-pkg_cloudi_service_db_elasticsearch_name = cloudi_service_db_elasticsearch
-pkg_cloudi_service_db_elasticsearch_description = elasticsearch CloudI Service
-pkg_cloudi_service_db_elasticsearch_homepage = http://cloudi.org/
-pkg_cloudi_service_db_elasticsearch_fetch = git
-pkg_cloudi_service_db_elasticsearch_repo = https://github.com/CloudI/cloudi_service_db_elasticsearch
-pkg_cloudi_service_db_elasticsearch_commit = master
diff --git a/index/cloudi_service_db_memcached.mk b/index/cloudi_service_db_memcached.mk
deleted file mode 100644
index 2f28796..0000000
--- a/index/cloudi_service_db_memcached.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += cloudi_service_db_memcached
-pkg_cloudi_service_db_memcached_name = cloudi_service_db_memcached
-pkg_cloudi_service_db_memcached_description = memcached CloudI Service
-pkg_cloudi_service_db_memcached_homepage = http://cloudi.org/
-pkg_cloudi_service_db_memcached_fetch = git
-pkg_cloudi_service_db_memcached_repo = https://github.com/CloudI/cloudi_service_db_memcached
-pkg_cloudi_service_db_memcached_commit = master
diff --git a/index/cloudi_service_db_riak.mk b/index/cloudi_service_db_riak.mk
deleted file mode 100644
index 471fa42..0000000
--- a/index/cloudi_service_db_riak.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += cloudi_service_db_riak
-pkg_cloudi_service_db_riak_name = cloudi_service_db_riak
-pkg_cloudi_service_db_riak_description = Riak CloudI Service
-pkg_cloudi_service_db_riak_homepage = http://cloudi.org/
-pkg_cloudi_service_db_riak_fetch = git
-pkg_cloudi_service_db_riak_repo = https://github.com/CloudI/cloudi_service_db_riak
-pkg_cloudi_service_db_riak_commit = master
diff --git a/index/cloudi_service_db_tokyotyrant.mk b/index/cloudi_service_db_tokyotyrant.mk
deleted file mode 100644
index b2cf9d1..0000000
--- a/index/cloudi_service_db_tokyotyrant.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += cloudi_service_db_tokyotyrant
-pkg_cloudi_service_db_tokyotyrant_name = cloudi_service_db_tokyotyrant
-pkg_cloudi_service_db_tokyotyrant_description = Tokyo Tyrant CloudI Service
-pkg_cloudi_service_db_tokyotyrant_homepage = http://cloudi.org/
-pkg_cloudi_service_db_tokyotyrant_fetch = git
-pkg_cloudi_service_db_tokyotyrant_repo = https://github.com/CloudI/cloudi_service_db_tokyotyrant
-pkg_cloudi_service_db_tokyotyrant_commit = master
diff --git a/index/cloudi_service_timers.mk b/index/cloudi_service_timers.mk
deleted file mode 100644
index 4a6e44d..0000000
--- a/index/cloudi_service_timers.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += cloudi_service_timers
-pkg_cloudi_service_timers_name = cloudi_service_timers
-pkg_cloudi_service_timers_description = Timers CloudI Service
-pkg_cloudi_service_timers_homepage = http://cloudi.org/
-pkg_cloudi_service_timers_fetch = git
-pkg_cloudi_service_timers_repo = https://github.com/CloudI/cloudi_service_timers
-pkg_cloudi_service_timers_commit = master
diff --git a/index/decimal.mk b/index/decimal.mk
index 9b50847..b8879b9 100644
--- a/index/decimal.mk
+++ b/index/decimal.mk
@@ -1,7 +1,7 @@
PACKAGES += decimal
pkg_decimal_name = decimal
pkg_decimal_description = An Erlang decimal arithmetic library
-pkg_decimal_homepage = https://github.com/tim/erlang-decimal
+pkg_decimal_homepage = https://github.com/egobrain/decimal
pkg_decimal_fetch = git
-pkg_decimal_repo = https://github.com/tim/erlang-decimal
+pkg_decimal_repo = https://github.com/egobrain/decimal
pkg_decimal_commit = master
diff --git a/index/detest.mk b/index/detest.mk
deleted file mode 100644
index 36d0f8b..0000000
--- a/index/detest.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += detest
-pkg_detest_name = detest
-pkg_detest_description = Tool for running tests on a cluster of erlang nodes
-pkg_detest_homepage = https://github.com/biokoda/detest
-pkg_detest_fetch = git
-pkg_detest_repo = https://github.com/biokoda/detest
-pkg_detest_commit = master
diff --git a/index/dns.mk b/index/dns.mk
index 0cd1325..27e9a51 100644
--- a/index/dns.mk
+++ b/index/dns.mk
@@ -4,4 +4,4 @@ pkg_dns_description = Erlang DNS library
pkg_dns_homepage = https://github.com/aetrion/dns_erlang
pkg_dns_fetch = git
pkg_dns_repo = https://github.com/aetrion/dns_erlang
-pkg_dns_commit = master
+pkg_dns_commit = main
diff --git a/index/dnssd.mk b/index/dnssd.mk
deleted file mode 100644
index 010d6b2..0000000
--- a/index/dnssd.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += dnssd
-pkg_dnssd_name = dnssd
-pkg_dnssd_description = Erlang interface to Apple's Bonjour D NS Service Discovery implementation
-pkg_dnssd_homepage = https://github.com/benoitc/dnssd_erlang
-pkg_dnssd_fetch = git
-pkg_dnssd_repo = https://github.com/benoitc/dnssd_erlang
-pkg_dnssd_commit = master
diff --git a/index/edis.mk b/index/edis.mk
deleted file mode 100644
index f6d66bd..0000000
--- a/index/edis.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += edis
-pkg_edis_name = edis
-pkg_edis_description = An Erlang implementation of Redis KV Store
-pkg_edis_homepage = http://inaka.github.com/edis/
-pkg_edis_fetch = git
-pkg_edis_repo = https://github.com/inaka/edis
-pkg_edis_commit = master
diff --git a/index/ehsa.mk b/index/ehsa.mk
index 0d1bfac..98c9f8b 100644
--- a/index/ehsa.mk
+++ b/index/ehsa.mk
@@ -1,7 +1,7 @@
PACKAGES += ehsa
pkg_ehsa_name = ehsa
pkg_ehsa_description = Erlang HTTP server basic and digest authentication modules
-pkg_ehsa_homepage = https://bitbucket.org/a12n/ehsa
-pkg_ehsa_fetch = hg
-pkg_ehsa_repo = https://bitbucket.org/a12n/ehsa
-pkg_ehsa_commit = default
+pkg_ehsa_homepage = https://github.com/a12n/ehsa
+pkg_ehsa_fetch = git
+pkg_ehsa_repo = https://github.com/a12n/ehsa
+pkg_ehsa_commit = master
diff --git a/index/eleveldb.mk b/index/eleveldb.mk
index 07d7ceb..f562a56 100644
--- a/index/eleveldb.mk
+++ b/index/eleveldb.mk
@@ -4,4 +4,4 @@ pkg_eleveldb_description = Erlang LevelDB API
pkg_eleveldb_homepage = https://github.com/basho/eleveldb
pkg_eleveldb_fetch = git
pkg_eleveldb_repo = https://github.com/basho/eleveldb
-pkg_eleveldb_commit = master
+pkg_eleveldb_commit = develop
diff --git a/index/elixir.mk b/index/elixir.mk
index d1d4f05..818a4d3 100644
--- a/index/elixir.mk
+++ b/index/elixir.mk
@@ -4,4 +4,4 @@ pkg_elixir_description = Elixir is a dynamic, functional language designed for b
pkg_elixir_homepage = https://elixir-lang.org/
pkg_elixir_fetch = git
pkg_elixir_repo = https://github.com/elixir-lang/elixir
-pkg_elixir_commit = master
+pkg_elixir_commit = main
diff --git a/index/elli.mk b/index/elli.mk
index f76f838..1da1f1c 100644
--- a/index/elli.mk
+++ b/index/elli.mk
@@ -4,4 +4,4 @@ pkg_elli_description = Simple, robust and performant Erlang web server
pkg_elli_homepage = https://github.com/elli-lib/elli
pkg_elli_fetch = git
pkg_elli_repo = https://github.com/elli-lib/elli
-pkg_elli_commit = master
+pkg_elli_commit = main
diff --git a/index/emysql.mk b/index/emysql.mk
deleted file mode 100644
index 5211f5d..0000000
--- a/index/emysql.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += emysql
-pkg_emysql_name = emysql
-pkg_emysql_description = Stable, pure Erlang MySQL driver.
-pkg_emysql_homepage = https://github.com/Eonblast/Emysql
-pkg_emysql_fetch = git
-pkg_emysql_repo = https://github.com/Eonblast/Emysql
-pkg_emysql_commit = master
diff --git a/index/eredis_pool.mk b/index/eredis_pool.mk
deleted file mode 100644
index d10c6fc..0000000
--- a/index/eredis_pool.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += eredis_pool
-pkg_eredis_pool_name = eredis_pool
-pkg_eredis_pool_description = eredis_pool is Pool of Redis clients, using eredis and poolboy.
-pkg_eredis_pool_homepage = https://github.com/hiroeorz/eredis_pool
-pkg_eredis_pool_fetch = git
-pkg_eredis_pool_repo = https://github.com/hiroeorz/eredis_pool
-pkg_eredis_pool_commit = master
diff --git a/index/erlang_cep.mk b/index/erlang_cep.mk
deleted file mode 100644
index 6d8f60f..0000000
--- a/index/erlang_cep.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += erlang_cep
-pkg_erlang_cep_name = erlang_cep
-pkg_erlang_cep_description = A basic CEP package written in erlang
-pkg_erlang_cep_homepage = https://github.com/danmacklin/erlang_cep
-pkg_erlang_cep_fetch = git
-pkg_erlang_cep_repo = https://github.com/danmacklin/erlang_cep
-pkg_erlang_cep_commit = master
diff --git a/index/erlang_js.mk b/index/erlang_js.mk
deleted file mode 100644
index f6953cd..0000000
--- a/index/erlang_js.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += erlang_js
-pkg_erlang_js_name = erlang_js
-pkg_erlang_js_description = A linked-in driver for Erlang to Mozilla's Spidermonkey Javascript runtime.
-pkg_erlang_js_homepage = https://github.com/basho/erlang_js
-pkg_erlang_js_fetch = git
-pkg_erlang_js_repo = https://github.com/basho/erlang_js
-pkg_erlang_js_commit = master
diff --git a/index/erlasticsearch.mk b/index/erlasticsearch.mk
deleted file mode 100644
index 9f72555..0000000
--- a/index/erlasticsearch.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += erlasticsearch
-pkg_erlasticsearch_name = erlasticsearch
-pkg_erlasticsearch_description = Erlang thrift interface to elastic_search
-pkg_erlasticsearch_homepage = https://github.com/dieswaytoofast/erlasticsearch
-pkg_erlasticsearch_fetch = git
-pkg_erlasticsearch_repo = https://github.com/dieswaytoofast/erlasticsearch
-pkg_erlasticsearch_commit = master
diff --git a/index/erldns.mk b/index/erldns.mk
index d5ab604..2d4bf5b 100644
--- a/index/erldns.mk
+++ b/index/erldns.mk
@@ -4,4 +4,4 @@ pkg_erldns_description = DNS server, in erlang.
pkg_erldns_homepage = https://github.com/aetrion/erl-dns
pkg_erldns_fetch = git
pkg_erldns_repo = https://github.com/aetrion/erl-dns
-pkg_erldns_commit = master
+pkg_erldns_commit = main
diff --git a/index/erlport.mk b/index/erlport.mk
deleted file mode 100644
index 81fd3d0..0000000
--- a/index/erlport.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += erlport
-pkg_erlport_name = erlport
-pkg_erlport_description = ErlPort - connect Erlang to other languages
-pkg_erlport_homepage = https://github.com/hdima/erlport
-pkg_erlport_fetch = git
-pkg_erlport_repo = https://github.com/hdima/erlport
-pkg_erlport_commit = master
diff --git a/index/erwa.mk b/index/erwa.mk
deleted file mode 100644
index f865916..0000000
--- a/index/erwa.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += erwa
-pkg_erwa_name = erwa
-pkg_erwa_description = A WAMP router and client written in Erlang.
-pkg_erwa_homepage = https://github.com/bwegh/erwa
-pkg_erwa_fetch = git
-pkg_erwa_repo = https://github.com/bwegh/erwa
-pkg_erwa_commit = master
diff --git a/index/exs64.mk b/index/exs64.mk
deleted file mode 100644
index 3df0de5..0000000
--- a/index/exs64.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += exs64
-pkg_exs64_name = exs64
-pkg_exs64_description = Xorshift64star pseudo random number generator for Erlang.
-pkg_exs64_homepage = https://github.com/jj1bdx/exs64
-pkg_exs64_fetch = git
-pkg_exs64_repo = https://github.com/jj1bdx/exs64
-pkg_exs64_commit = master
diff --git a/index/exsplus128.mk b/index/exsplus128.mk
deleted file mode 100644
index a87a89c..0000000
--- a/index/exsplus128.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += exsplus128
-pkg_exsplus128_name = exsplus128
-pkg_exsplus128_description = Xorshift128plus pseudo random number generator for Erlang.
-pkg_exsplus128_homepage = https://github.com/jj1bdx/exsplus128
-pkg_exsplus128_fetch = git
-pkg_exsplus128_repo = https://github.com/jj1bdx/exsplus128
-pkg_exsplus128_commit = master
diff --git a/index/ezmq.mk b/index/ezmq.mk
deleted file mode 100644
index 9d895b4..0000000
--- a/index/ezmq.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += ezmq
-pkg_ezmq_name = ezmq
-pkg_ezmq_description = zMQ implemented in Erlang
-pkg_ezmq_homepage = https://github.com/RoadRunnr/ezmq
-pkg_ezmq_fetch = git
-pkg_ezmq_repo = https://github.com/RoadRunnr/ezmq
-pkg_ezmq_commit = master
diff --git a/index/folsomite.mk b/index/folsomite.mk
deleted file mode 100644
index 051f25b..0000000
--- a/index/folsomite.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += folsomite
-pkg_folsomite_name = folsomite
-pkg_folsomite_description = blow up your graphite / riemann server with folsom metrics
-pkg_folsomite_homepage = https://github.com/campanja/folsomite
-pkg_folsomite_fetch = git
-pkg_folsomite_repo = https://github.com/campanja/folsomite
-pkg_folsomite_commit = master
diff --git a/index/gold_fever.mk b/index/gold_fever.mk
deleted file mode 100644
index c3d47fd..0000000
--- a/index/gold_fever.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += gold_fever
-pkg_gold_fever_name = gold_fever
-pkg_gold_fever_description = A Treasure Hunt for Erlangers
-pkg_gold_fever_homepage = https://github.com/inaka/gold_fever
-pkg_gold_fever_fetch = git
-pkg_gold_fever_repo = https://github.com/inaka/gold_fever
-pkg_gold_fever_commit = master
diff --git a/index/gut.mk b/index/gut.mk
deleted file mode 100644
index 1873c8e..0000000
--- a/index/gut.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += gut
-pkg_gut_name = gut
-pkg_gut_description = gut is a template printing, aka scaffolding, tool for Erlang. Like rails generate or yeoman
-pkg_gut_homepage = https://github.com/unbalancedparentheses/gut
-pkg_gut_fetch = git
-pkg_gut_repo = https://github.com/unbalancedparentheses/gut
-pkg_gut_commit = master
diff --git a/index/hanoidb.mk b/index/hanoidb.mk
deleted file mode 100644
index 8fd0f73..0000000
--- a/index/hanoidb.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += hanoidb
-pkg_hanoidb_name = hanoidb
-pkg_hanoidb_description = Erlang LSM BTree Storage
-pkg_hanoidb_homepage = https://github.com/krestenkrab/hanoidb
-pkg_hanoidb_fetch = git
-pkg_hanoidb_repo = https://github.com/krestenkrab/hanoidb
-pkg_hanoidb_commit = master
diff --git a/index/ierlang.mk b/index/ierlang.mk
deleted file mode 100644
index a2143eb..0000000
--- a/index/ierlang.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += ierlang
-pkg_ierlang_name = ierlang
-pkg_ierlang_description = An Erlang language kernel for IPython.
-pkg_ierlang_homepage = https://github.com/robbielynch/ierlang
-pkg_ierlang_fetch = git
-pkg_ierlang_repo = https://github.com/robbielynch/ierlang
-pkg_ierlang_commit = master
diff --git a/index/iota.mk b/index/iota.mk
deleted file mode 100644
index cb8e339..0000000
--- a/index/iota.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += iota
-pkg_iota_name = iota
-pkg_iota_description = iota (Inter-dependency Objective Testing Apparatus) - a tool to enforce clean separation of responsibilities in Erlang code
-pkg_iota_homepage = https://github.com/jpgneves/iota
-pkg_iota_fetch = git
-pkg_iota_repo = https://github.com/jpgneves/iota
-pkg_iota_commit = master
diff --git a/index/jerg.mk b/index/jerg.mk
deleted file mode 100644
index 1022457..0000000
--- a/index/jerg.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += jerg
-pkg_jerg_name = jerg
-pkg_jerg_description = JSON Schema to Erlang Records Generator
-pkg_jerg_homepage = https://github.com/ddossot/jerg
-pkg_jerg_fetch = git
-pkg_jerg_repo = https://github.com/ddossot/jerg
-pkg_jerg_commit = master
diff --git a/index/jobs.mk b/index/jobs.mk
index ebe6e74..97d1576 100644
--- a/index/jobs.mk
+++ b/index/jobs.mk
@@ -1,7 +1,7 @@
PACKAGES += jobs
pkg_jobs_name = jobs
-pkg_jobs_description = a Job scheduler for load regulation
-pkg_jobs_homepage = https://github.com/esl/jobs
+pkg_jobs_description = Job scheduler for load regulation
+pkg_jobs_homepage = https://github.com/uwiger/jobs
pkg_jobs_fetch = git
-pkg_jobs_repo = https://github.com/esl/jobs
+pkg_jobs_repo = https://github.com/uwiger/jobs
pkg_jobs_commit = master
diff --git a/index/json.mk b/index/json.mk
deleted file mode 100644
index 0919367..0000000
--- a/index/json.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += json
-pkg_json_name = json
-pkg_json_description = a high level json library for erlang (17.0+)
-pkg_json_homepage = https://github.com/talentdeficit/json
-pkg_json_fetch = git
-pkg_json_repo = https://github.com/talentdeficit/json
-pkg_json_commit = master
diff --git a/index/jsonerl.mk b/index/jsonerl.mk
deleted file mode 100644
index 609340c..0000000
--- a/index/jsonerl.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += jsonerl
-pkg_jsonerl_name = jsonerl
-pkg_jsonerl_description = yet another but slightly different erlang <-> json encoder/decoder
-pkg_jsonerl_homepage = https://github.com/lambder/jsonerl
-pkg_jsonerl_fetch = git
-pkg_jsonerl_repo = https://github.com/lambder/jsonerl
-pkg_jsonerl_commit = master
diff --git a/index/kafka.mk b/index/kafka.mk
deleted file mode 100644
index 0e69514..0000000
--- a/index/kafka.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += kafka
-pkg_kafka_name = kafka
-pkg_kafka_description = Kafka consumer and producer in Erlang
-pkg_kafka_homepage = https://github.com/wooga/kafka-erlang
-pkg_kafka_fetch = git
-pkg_kafka_repo = https://github.com/wooga/kafka-erlang
-pkg_kafka_commit = master
diff --git a/index/kafka_protocol.mk b/index/kafka_protocol.mk
index 8a9fb2f..426e815 100644
--- a/index/kafka_protocol.mk
+++ b/index/kafka_protocol.mk
@@ -1,7 +1,7 @@
PACKAGES += kafka_protocol
pkg_kafka_protocol_name = kafka_protocol
pkg_kafka_protocol_description = Kafka protocol Erlang library
-pkg_kafka_protocol_homepage = https://github.com/klarna/kafka_protocol
+pkg_kafka_protocol_homepage = https://github.com/kafka4beam/kafka_protocol
pkg_kafka_protocol_fetch = git
-pkg_kafka_protocol_repo = https://github.com/klarna/kafka_protocol.git
+pkg_kafka_protocol_repo = https://github.com/kafka4beam/kafka_protocol
pkg_kafka_protocol_commit = master
diff --git a/index/kdht.mk b/index/kdht.mk
deleted file mode 100644
index 97819a0..0000000
--- a/index/kdht.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += kdht
-pkg_kdht_name = kdht
-pkg_kdht_description = kdht is an erlang DHT implementation
-pkg_kdht_homepage = https://github.com/kevinlynx/kdht
-pkg_kdht_fetch = git
-pkg_kdht_repo = https://github.com/kevinlynx/kdht
-pkg_kdht_commit = master
diff --git a/index/kinetic.mk b/index/kinetic.mk
index 869bc4f..8f622b4 100644
--- a/index/kinetic.mk
+++ b/index/kinetic.mk
@@ -4,4 +4,4 @@ pkg_kinetic_description = Erlang Kinesis Client
pkg_kinetic_homepage = https://github.com/AdRoll/kinetic
pkg_kinetic_fetch = git
pkg_kinetic_repo = https://github.com/AdRoll/kinetic
-pkg_kinetic_commit = master
+pkg_kinetic_commit = main
diff --git a/index/lager_amqp_backend.mk b/index/lager_amqp_backend.mk
deleted file mode 100644
index a991688..0000000
--- a/index/lager_amqp_backend.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += lager_amqp_backend
-pkg_lager_amqp_backend_name = lager_amqp_backend
-pkg_lager_amqp_backend_description = AMQP RabbitMQ Lager backend
-pkg_lager_amqp_backend_homepage = https://github.com/jbrisbin/lager_amqp_backend
-pkg_lager_amqp_backend_fetch = git
-pkg_lager_amqp_backend_repo = https://github.com/jbrisbin/lager_amqp_backend
-pkg_lager_amqp_backend_commit = master
diff --git a/index/lambdapad.mk b/index/lambdapad.mk
deleted file mode 100644
index aa28bcc..0000000
--- a/index/lambdapad.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += lambdapad
-pkg_lambdapad_name = lambdapad
-pkg_lambdapad_description = Static site generator using Erlang. Yes, Erlang.
-pkg_lambdapad_homepage = https://github.com/gar1t/lambdapad
-pkg_lambdapad_fetch = git
-pkg_lambdapad_repo = https://github.com/gar1t/lambdapad
-pkg_lambdapad_commit = master
diff --git a/index/lasp.mk b/index/lasp.mk
deleted file mode 100644
index 8f8b4d8..0000000
--- a/index/lasp.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += lasp
-pkg_lasp_name = lasp
-pkg_lasp_description = A Language for Distributed, Eventually Consistent Computations
-pkg_lasp_homepage = http://lasp-lang.org/
-pkg_lasp_fetch = git
-pkg_lasp_repo = https://github.com/lasp-lang/lasp
-pkg_lasp_commit = master
diff --git a/index/lethink.mk b/index/lethink.mk
deleted file mode 100644
index 7737fd1..0000000
--- a/index/lethink.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += lethink
-pkg_lethink_name = lethink
-pkg_lethink_description = erlang driver for rethinkdb
-pkg_lethink_homepage = https://github.com/taybin/lethink
-pkg_lethink_fetch = git
-pkg_lethink_repo = https://github.com/taybin/lethink
-pkg_lethink_commit = master
diff --git a/index/ling.mk b/index/ling.mk
deleted file mode 100644
index 51a2a2e..0000000
--- a/index/ling.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += ling
-pkg_ling_name = ling
-pkg_ling_description = Erlang on Xen
-pkg_ling_homepage = https://github.com/cloudozer/ling
-pkg_ling_fetch = git
-pkg_ling_repo = https://github.com/cloudozer/ling
-pkg_ling_commit = master
diff --git a/index/lmq.mk b/index/lmq.mk
deleted file mode 100644
index 8909bdd..0000000
--- a/index/lmq.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += lmq
-pkg_lmq_name = lmq
-pkg_lmq_description = Lightweight Message Queue
-pkg_lmq_homepage = https://github.com/iij/lmq
-pkg_lmq_fetch = git
-pkg_lmq_repo = https://github.com/iij/lmq
-pkg_lmq_commit = master
diff --git a/index/luwak.mk b/index/luwak.mk
deleted file mode 100644
index 22a4cbe..0000000
--- a/index/luwak.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += luwak
-pkg_luwak_name = luwak
-pkg_luwak_description = Large-object storage interface for Riak
-pkg_luwak_homepage = https://github.com/basho/luwak
-pkg_luwak_fetch = git
-pkg_luwak_repo = https://github.com/basho/luwak
-pkg_luwak_commit = master
diff --git a/index/machi.mk b/index/machi.mk
deleted file mode 100644
index d42030e..0000000
--- a/index/machi.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += machi
-pkg_machi_name = machi
-pkg_machi_description = Machi file store
-pkg_machi_homepage = https://github.com/basho/machi
-pkg_machi_fetch = git
-pkg_machi_repo = https://github.com/basho/machi
-pkg_machi_commit = master
diff --git a/index/mc_erl.mk b/index/mc_erl.mk
deleted file mode 100644
index 400e42f..0000000
--- a/index/mc_erl.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += mc_erl
-pkg_mc_erl_name = mc_erl
-pkg_mc_erl_description = mc-erl is a server for Minecraft 1.4.7 written in Erlang.
-pkg_mc_erl_homepage = https://github.com/clonejo/mc-erl
-pkg_mc_erl_fetch = git
-pkg_mc_erl_repo = https://github.com/clonejo/mc-erl
-pkg_mc_erl_commit = master
diff --git a/index/mcd.mk b/index/mcd.mk
deleted file mode 100644
index 0b52819..0000000
--- a/index/mcd.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += mcd
-pkg_mcd_name = mcd
-pkg_mcd_description = Fast memcached protocol client in pure Erlang
-pkg_mcd_homepage = https://github.com/EchoTeam/mcd
-pkg_mcd_fetch = git
-pkg_mcd_repo = https://github.com/EchoTeam/mcd
-pkg_mcd_commit = master
diff --git a/index/mcerlang.mk b/index/mcerlang.mk
deleted file mode 100644
index 195767a..0000000
--- a/index/mcerlang.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += mcerlang
-pkg_mcerlang_name = mcerlang
-pkg_mcerlang_description = The McErlang model checker for Erlang
-pkg_mcerlang_homepage = https://github.com/fredlund/McErlang
-pkg_mcerlang_fetch = git
-pkg_mcerlang_repo = https://github.com/fredlund/McErlang
-pkg_mcerlang_commit = master
diff --git a/index/memo.mk b/index/memo.mk
deleted file mode 100644
index e41c84a..0000000
--- a/index/memo.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += memo
-pkg_memo_name = memo
-pkg_memo_description = Erlang memoization server
-pkg_memo_homepage = https://github.com/tuncer/memo
-pkg_memo_fetch = git
-pkg_memo_repo = https://github.com/tuncer/memo
-pkg_memo_commit = master
diff --git a/index/merge_index.mk b/index/merge_index.mk
deleted file mode 100644
index d1e6d93..0000000
--- a/index/merge_index.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += merge_index
-pkg_merge_index_name = merge_index
-pkg_merge_index_description = MergeIndex is an Erlang library for storing ordered sets on disk. It is very similar to an SSTable (in Google's Bigtable) or an HFile (in Hadoop).
-pkg_merge_index_homepage = https://github.com/basho/merge_index
-pkg_merge_index_fetch = git
-pkg_merge_index_repo = https://github.com/basho/merge_index
-pkg_merge_index_commit = master
diff --git a/index/mixer.mk b/index/mixer.mk
index 8a84c3a..4eb4105 100644
--- a/index/mixer.mk
+++ b/index/mixer.mk
@@ -4,4 +4,4 @@ pkg_mixer_description = Mix in functions from other modules
pkg_mixer_homepage = https://github.com/chef/mixer
pkg_mixer_fetch = git
pkg_mixer_repo = https://github.com/chef/mixer
-pkg_mixer_commit = master
+pkg_mixer_commit = main
diff --git a/index/mochiweb.mk b/index/mochiweb.mk
index 15df91e..a2a451a 100644
--- a/index/mochiweb.mk
+++ b/index/mochiweb.mk
@@ -4,4 +4,4 @@ pkg_mochiweb_description = MochiWeb is an Erlang library for building lightweigh
pkg_mochiweb_homepage = https://github.com/mochi/mochiweb
pkg_mochiweb_fetch = git
pkg_mochiweb_repo = https://github.com/mochi/mochiweb
-pkg_mochiweb_commit = master
+pkg_mochiweb_commit = main
diff --git a/index/newrelic.mk b/index/newrelic.mk
deleted file mode 100644
index 74274a1..0000000
--- a/index/newrelic.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += newrelic
-pkg_newrelic_name = newrelic
-pkg_newrelic_description = Erlang library for sending metrics to New Relic
-pkg_newrelic_homepage = https://github.com/wooga/newrelic-erlang
-pkg_newrelic_fetch = git
-pkg_newrelic_repo = https://github.com/wooga/newrelic-erlang
-pkg_newrelic_commit = master
diff --git a/index/nkbase.mk b/index/nkbase.mk
deleted file mode 100644
index 68fa4a1..0000000
--- a/index/nkbase.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += nkbase
-pkg_nkbase_name = nkbase
-pkg_nkbase_description = NkBASE distributed database
-pkg_nkbase_homepage = https://github.com/Nekso/nkbase
-pkg_nkbase_fetch = git
-pkg_nkbase_repo = https://github.com/Nekso/nkbase
-pkg_nkbase_commit = develop
diff --git a/index/nkdocker.mk b/index/nkdocker.mk
deleted file mode 100644
index 72a794c..0000000
--- a/index/nkdocker.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += nkdocker
-pkg_nkdocker_name = nkdocker
-pkg_nkdocker_description = Erlang Docker client
-pkg_nkdocker_homepage = https://github.com/Nekso/nkdocker
-pkg_nkdocker_fetch = git
-pkg_nkdocker_repo = https://github.com/Nekso/nkdocker
-pkg_nkdocker_commit = master
diff --git a/index/oauth.mk b/index/oauth.mk
index 93bdd9f..026f7c5 100644
--- a/index/oauth.mk
+++ b/index/oauth.mk
@@ -4,4 +4,4 @@ pkg_oauth_description = An Erlang OAuth 1.0 implementation
pkg_oauth_homepage = https://github.com/tim/erlang-oauth
pkg_oauth_fetch = git
pkg_oauth_repo = https://github.com/tim/erlang-oauth
-pkg_oauth_commit = master
+pkg_oauth_commit = main
diff --git a/index/of_protocol.mk b/index/of_protocol.mk
deleted file mode 100644
index 671d7d7..0000000
--- a/index/of_protocol.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += of_protocol
-pkg_of_protocol_name = of_protocol
-pkg_of_protocol_description = OpenFlow Protocol Library for Erlang
-pkg_of_protocol_homepage = https://github.com/FlowForwarding/of_protocol
-pkg_of_protocol_fetch = git
-pkg_of_protocol_repo = https://github.com/FlowForwarding/of_protocol
-pkg_of_protocol_commit = master
diff --git a/index/opencouch.mk b/index/opencouch.mk
deleted file mode 100644
index 6bbc27f..0000000
--- a/index/opencouch.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += opencouch
-pkg_opencouch_name = couch
-pkg_opencouch_description = A embeddable document oriented database compatible with Apache CouchDB
-pkg_opencouch_homepage = https://github.com/benoitc/opencouch
-pkg_opencouch_fetch = git
-pkg_opencouch_repo = https://github.com/benoitc/opencouch
-pkg_opencouch_commit = master
diff --git a/index/pgo.mk b/index/pgo.mk
index c7cd340..1510d01 100644
--- a/index/pgo.mk
+++ b/index/pgo.mk
@@ -4,4 +4,4 @@ pkg_pgo_description = Erlang Postgres client and connection pool
pkg_pgo_homepage = https://github.com/erleans/pgo.git
pkg_pgo_fetch = git
pkg_pgo_repo = https://github.com/erleans/pgo.git
-pkg_pgo_commit = master
+pkg_pgo_commit = main
diff --git a/index/plumtree.mk b/index/plumtree.mk
deleted file mode 100644
index 435ad58..0000000
--- a/index/plumtree.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += plumtree
-pkg_plumtree_name = plumtree
-pkg_plumtree_description = Epidemic Broadcast Trees
-pkg_plumtree_homepage = https://github.com/helium/plumtree
-pkg_plumtree_fetch = git
-pkg_plumtree_repo = https://github.com/helium/plumtree
-pkg_plumtree_commit = master
diff --git a/index/push_service.mk b/index/push_service.mk
deleted file mode 100644
index e5d5b4c..0000000
--- a/index/push_service.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += push_service
-pkg_push_service_name = push_service
-pkg_push_service_description = Push service
-pkg_push_service_homepage = https://github.com/hairyhum/push_service
-pkg_push_service_fetch = git
-pkg_push_service_repo = https://github.com/hairyhum/push_service
-pkg_push_service_commit = master
diff --git a/index/rabbit.mk b/index/rabbit.mk
deleted file mode 100644
index b9ca63d..0000000
--- a/index/rabbit.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += rabbit
-pkg_rabbit_name = rabbit
-pkg_rabbit_description = RabbitMQ Server
-pkg_rabbit_homepage = https://www.rabbitmq.com/
-pkg_rabbit_fetch = git
-pkg_rabbit_repo = https://github.com/rabbitmq/rabbitmq-server.git
-pkg_rabbit_commit = master
diff --git a/index/rafter.mk b/index/rafter.mk
deleted file mode 100644
index adc9080..0000000
--- a/index/rafter.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += rafter
-pkg_rafter_name = rafter
-pkg_rafter_description = An Erlang library application which implements the Raft consensus protocol
-pkg_rafter_homepage = https://github.com/andrewjstone/rafter
-pkg_rafter_fetch = git
-pkg_rafter_repo = https://github.com/andrewjstone/rafter
-pkg_rafter_commit = master
diff --git a/index/re2.mk b/index/re2.mk
new file mode 100644
index 0000000..03c3f67
--- /dev/null
+++ b/index/re2.mk
@@ -0,0 +1,7 @@
+PACKAGES += re2
+pkg_re2_name = re2
+pkg_re2_description = Erlang NIF bindings for RE2 regex library
+pkg_re2_homepage = https://github.com/dukesoferl/re2
+pkg_re2_fetch = git
+pkg_re2_repo = https://github.com/dukesoferl/re2
+pkg_re2_commit = master
diff --git a/index/rebar.mk b/index/rebar.mk
deleted file mode 100644
index bd4096b..0000000
--- a/index/rebar.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += rebar
-pkg_rebar_name = rebar
-pkg_rebar_description = Erlang build tool that makes it easy to compile and test Erlang applications, port drivers and releases.
-pkg_rebar_homepage = http://www.rebar3.org
-pkg_rebar_fetch = git
-pkg_rebar_repo = https://github.com/rebar/rebar3
-pkg_rebar_commit = master
diff --git a/index/relx.mk b/index/relx.mk
index b12fab7..d9614b0 100644
--- a/index/relx.mk
+++ b/index/relx.mk
@@ -4,4 +4,4 @@ pkg_relx_description = Sane, simple release creation for Erlang
pkg_relx_homepage = https://github.com/erlware/relx
pkg_relx_fetch = git
pkg_relx_repo = https://github.com/erlware/relx
-pkg_relx_commit = master
+pkg_relx_commit = main
diff --git a/index/riak_control.mk b/index/riak_control.mk
deleted file mode 100644
index 49d11a3..0000000
--- a/index/riak_control.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += riak_control
-pkg_riak_control_name = riak_control
-pkg_riak_control_description = Webmachine-based administration interface for Riak.
-pkg_riak_control_homepage = https://github.com/basho/riak_control
-pkg_riak_control_fetch = git
-pkg_riak_control_repo = https://github.com/basho/riak_control
-pkg_riak_control_commit = master
diff --git a/index/riak_core.mk b/index/riak_core.mk
index e3bfcfc..a30d4cd 100644
--- a/index/riak_core.mk
+++ b/index/riak_core.mk
@@ -4,4 +4,4 @@ pkg_riak_core_description = Distributed systems infrastructure used by Riak.
pkg_riak_core_homepage = https://github.com/basho/riak_core
pkg_riak_core_fetch = git
pkg_riak_core_repo = https://github.com/basho/riak_core
-pkg_riak_core_commit = master
+pkg_riak_core_commit = develop
diff --git a/index/riak_ensemble.mk b/index/riak_ensemble.mk
index 24ad92b..f240275 100644
--- a/index/riak_ensemble.mk
+++ b/index/riak_ensemble.mk
@@ -4,4 +4,4 @@ pkg_riak_ensemble_description = Multi-Paxos framework in Erlang
pkg_riak_ensemble_homepage = https://github.com/basho/riak_ensemble
pkg_riak_ensemble_fetch = git
pkg_riak_ensemble_repo = https://github.com/basho/riak_ensemble
-pkg_riak_ensemble_commit = master
+pkg_riak_ensemble_commit = develop
diff --git a/index/riak_kv.mk b/index/riak_kv.mk
index 8b878de..0718f79 100644
--- a/index/riak_kv.mk
+++ b/index/riak_kv.mk
@@ -4,4 +4,4 @@ pkg_riak_kv_description = Riak Key/Value Store
pkg_riak_kv_homepage = https://github.com/basho/riak_kv
pkg_riak_kv_fetch = git
pkg_riak_kv_repo = https://github.com/basho/riak_kv
-pkg_riak_kv_commit = master
+pkg_riak_kv_commit = develop
diff --git a/index/riak_pg.mk b/index/riak_pg.mk
deleted file mode 100644
index 33a6465..0000000
--- a/index/riak_pg.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += riak_pg
-pkg_riak_pg_name = riak_pg
-pkg_riak_pg_description = Distributed process groups with riak_core.
-pkg_riak_pg_homepage = https://github.com/cmeiklejohn/riak_pg
-pkg_riak_pg_fetch = git
-pkg_riak_pg_repo = https://github.com/cmeiklejohn/riak_pg
-pkg_riak_pg_commit = master
diff --git a/index/riak_pipe.mk b/index/riak_pipe.mk
index 7b83b77..f82c6b8 100644
--- a/index/riak_pipe.mk
+++ b/index/riak_pipe.mk
@@ -4,4 +4,4 @@ pkg_riak_pipe_description = Riak Pipelines
pkg_riak_pipe_homepage = https://github.com/basho/riak_pipe
pkg_riak_pipe_fetch = git
pkg_riak_pipe_repo = https://github.com/basho/riak_pipe
-pkg_riak_pipe_commit = master
+pkg_riak_pipe_commit = develop
diff --git a/index/riak_test.mk b/index/riak_test.mk
deleted file mode 100644
index fd7f006..0000000
--- a/index/riak_test.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += riak_test
-pkg_riak_test_name = riak_test
-pkg_riak_test_description = I'm in your cluster, testing your riaks
-pkg_riak_test_homepage = https://github.com/basho/riak_test
-pkg_riak_test_fetch = git
-pkg_riak_test_repo = https://github.com/basho/riak_test
-pkg_riak_test_commit = master
diff --git a/index/riakhttpc.mk b/index/riakhttpc.mk
deleted file mode 100644
index b25d224..0000000
--- a/index/riakhttpc.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += riakhttpc
-pkg_riakhttpc_name = riakhttpc
-pkg_riakhttpc_description = Riak Erlang client using the HTTP interface
-pkg_riakhttpc_homepage = https://github.com/basho/riak-erlang-http-client
-pkg_riakhttpc_fetch = git
-pkg_riakhttpc_repo = https://github.com/basho/riak-erlang-http-client
-pkg_riakhttpc_commit = master
diff --git a/index/riaknostic.mk b/index/riaknostic.mk
deleted file mode 100644
index 1151347..0000000
--- a/index/riaknostic.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += riaknostic
-pkg_riaknostic_name = riaknostic
-pkg_riaknostic_description = A diagnostic tool for Riak installations, to find common errors asap
-pkg_riaknostic_homepage = https://github.com/basho/riaknostic
-pkg_riaknostic_fetch = git
-pkg_riaknostic_repo = https://github.com/basho/riaknostic
-pkg_riaknostic_commit = master
diff --git a/index/riakpool.mk b/index/riakpool.mk
deleted file mode 100644
index 98d2c5a..0000000
--- a/index/riakpool.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += riakpool
-pkg_riakpool_name = riakpool
-pkg_riakpool_description = erlang riak client pool
-pkg_riakpool_homepage = https://github.com/dweldon/riakpool
-pkg_riakpool_fetch = git
-pkg_riakpool_repo = https://github.com/dweldon/riakpool
-pkg_riakpool_commit = master
diff --git a/index/rivus_cep.mk b/index/rivus_cep.mk
deleted file mode 100644
index ab139e1..0000000
--- a/index/rivus_cep.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += rivus_cep
-pkg_rivus_cep_name = rivus_cep
-pkg_rivus_cep_description = Complex event processing in Erlang
-pkg_rivus_cep_homepage = https://github.com/vascokk/rivus_cep
-pkg_rivus_cep_fetch = git
-pkg_rivus_cep_repo = https://github.com/vascokk/rivus_cep
-pkg_rivus_cep_commit = master
diff --git a/index/service.mk b/index/service.mk
deleted file mode 100644
index 7fae811..0000000
--- a/index/service.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += service
-pkg_service_name = service
-pkg_service_description = A minimal Erlang behavior for creating CloudI internal services
-pkg_service_homepage = http://cloudi.org/
-pkg_service_fetch = git
-pkg_service_repo = https://github.com/CloudI/service
-pkg_service_commit = master
diff --git a/index/sidejob.mk b/index/sidejob.mk
index 53001f5..c173e18 100644
--- a/index/sidejob.mk
+++ b/index/sidejob.mk
@@ -4,4 +4,4 @@ pkg_sidejob_description = Parallel worker and capacity limiting library for Erla
pkg_sidejob_homepage = https://github.com/basho/sidejob
pkg_sidejob_fetch = git
pkg_sidejob_repo = https://github.com/basho/sidejob
-pkg_sidejob_commit = master
+pkg_sidejob_commit = develop
diff --git a/index/sighandler.mk b/index/sighandler.mk
deleted file mode 100644
index b4a252c..0000000
--- a/index/sighandler.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += sighandler
-pkg_sighandler_name = sighandler
-pkg_sighandler_description = Handle UNIX signals in Er lang
-pkg_sighandler_homepage = https://github.com/jkingsbery/sighandler
-pkg_sighandler_fetch = git
-pkg_sighandler_repo = https://github.com/jkingsbery/sighandler
-pkg_sighandler_commit = master
diff --git a/index/smother.mk b/index/smother.mk
deleted file mode 100644
index 22175a0..0000000
--- a/index/smother.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += smother
-pkg_smother_name = smother
-pkg_smother_description = Extended code coverage metrics for Erlang.
-pkg_smother_homepage = https://ramsay-t.github.io/Smother/
-pkg_smother_fetch = git
-pkg_smother_repo = https://github.com/ramsay-t/Smother
-pkg_smother_commit = master
diff --git a/index/spapi_router.mk b/index/spapi_router.mk
deleted file mode 100644
index b8c2851..0000000
--- a/index/spapi_router.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += spapi_router
-pkg_spapi_router_name = spapi_router
-pkg_spapi_router_description = Partially-connected Erlang clustering
-pkg_spapi_router_homepage = https://github.com/spilgames/spapi-router
-pkg_spapi_router_fetch = git
-pkg_spapi_router_repo = https://github.com/spilgames/spapi-router
-pkg_spapi_router_commit = master
diff --git a/index/statebox_riak.mk b/index/statebox_riak.mk
deleted file mode 100644
index 5298b81..0000000
--- a/index/statebox_riak.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += statebox_riak
-pkg_statebox_riak_name = statebox_riak
-pkg_statebox_riak_description = Convenience library that makes it easier to use statebox with riak, extracted from best practices in our production code at Mochi Media.
-pkg_statebox_riak_homepage = https://github.com/mochi/statebox_riak
-pkg_statebox_riak_fetch = git
-pkg_statebox_riak_repo = https://github.com/mochi/statebox_riak
-pkg_statebox_riak_commit = master
diff --git a/index/stripe.mk b/index/stripe.mk
deleted file mode 100644
index a5fdbc5..0000000
--- a/index/stripe.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += stripe
-pkg_stripe_name = stripe
-pkg_stripe_description = Erlang interface to the stripe.com API
-pkg_stripe_homepage = https://github.com/mattsta/stripe-erlang
-pkg_stripe_fetch = git
-pkg_stripe_repo = https://github.com/mattsta/stripe-erlang
-pkg_stripe_commit = v1
diff --git a/index/surrogate.mk b/index/surrogate.mk
deleted file mode 100644
index 71c8eac..0000000
--- a/index/surrogate.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += surrogate
-pkg_surrogate_name = surrogate
-pkg_surrogate_description = Proxy server written in erlang. Supports reverse proxy load balancing and forward proxy with http (including CONNECT), socks4, socks5, and transparent proxy modes.
-pkg_surrogate_homepage = https://github.com/skruger/Surrogate
-pkg_surrogate_fetch = git
-pkg_surrogate_repo = https://github.com/skruger/Surrogate
-pkg_surrogate_commit = master
diff --git a/index/ticktick.mk b/index/ticktick.mk
deleted file mode 100644
index ad2856b..0000000
--- a/index/ticktick.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += ticktick
-pkg_ticktick_name = ticktick
-pkg_ticktick_description = Ticktick is an id generator for message service.
-pkg_ticktick_homepage = https://github.com/ericliang/ticktick
-pkg_ticktick_fetch = git
-pkg_ticktick_repo = https://github.com/ericliang/ticktick
-pkg_ticktick_commit = master
diff --git a/index/transit.mk b/index/transit.mk
deleted file mode 100644
index 09c0931..0000000
--- a/index/transit.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += transit
-pkg_transit_name = transit
-pkg_transit_description = transit format for erlang
-pkg_transit_homepage = https://github.com/isaiah/transit-erlang
-pkg_transit_fetch = git
-pkg_transit_repo = https://github.com/isaiah/transit-erlang
-pkg_transit_commit = master
diff --git a/index/twerl.mk b/index/twerl.mk
deleted file mode 100644
index 31e8205..0000000
--- a/index/twerl.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += twerl
-pkg_twerl_name = twerl
-pkg_twerl_description = Erlang client for the Twitter Streaming API
-pkg_twerl_homepage = https://github.com/lucaspiller/twerl
-pkg_twerl_fetch = git
-pkg_twerl_repo = https://github.com/lucaspiller/twerl
-pkg_twerl_commit = oauth
diff --git a/index/twitter_erlang.mk b/index/twitter_erlang.mk
deleted file mode 100644
index abf34ba..0000000
--- a/index/twitter_erlang.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += twitter_erlang
-pkg_twitter_erlang_name = twitter_erlang
-pkg_twitter_erlang_description = An Erlang twitter client
-pkg_twitter_erlang_homepage = https://github.com/ngerakines/erlang_twitter
-pkg_twitter_erlang_fetch = git
-pkg_twitter_erlang_repo = https://github.com/ngerakines/erlang_twitter
-pkg_twitter_erlang_commit = master
diff --git a/index/ucol_nif.mk b/index/ucol_nif.mk
deleted file mode 100644
index 0dd1148..0000000
--- a/index/ucol_nif.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += ucol_nif
-pkg_ucol_nif_name = ucol_nif
-pkg_ucol_nif_description = ICU based collation Erlang module
-pkg_ucol_nif_homepage = https://github.com/refuge/ucol_nif
-pkg_ucol_nif_fetch = git
-pkg_ucol_nif_repo = https://github.com/refuge/ucol_nif
-pkg_ucol_nif_commit = master
diff --git a/index/vert.mk b/index/vert.mk
deleted file mode 100644
index dd8c0f1..0000000
--- a/index/vert.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += vert
-pkg_vert_name = vert
-pkg_vert_description = Erlang binding to libvirt virtualization API
-pkg_vert_homepage = https://github.com/msantos/erlang-libvirt
-pkg_vert_fetch = git
-pkg_vert_repo = https://github.com/msantos/erlang-libvirt
-pkg_vert_commit = master
diff --git a/index/vmq_acl.mk b/index/vmq_acl.mk
deleted file mode 100644
index 98e4c5b..0000000
--- a/index/vmq_acl.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += vmq_acl
-pkg_vmq_acl_name = vmq_acl
-pkg_vmq_acl_description = Component of VerneMQ: A distributed MQTT message broker
-pkg_vmq_acl_homepage = https://verne.mq/
-pkg_vmq_acl_fetch = git
-pkg_vmq_acl_repo = https://github.com/erlio/vmq_acl
-pkg_vmq_acl_commit = master
diff --git a/index/vmq_graphite.mk b/index/vmq_graphite.mk
deleted file mode 100644
index 9676536..0000000
--- a/index/vmq_graphite.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += vmq_graphite
-pkg_vmq_graphite_name = vmq_graphite
-pkg_vmq_graphite_description = Component of VerneMQ: A distributed MQTT message broker
-pkg_vmq_graphite_homepage = https://verne.mq/
-pkg_vmq_graphite_fetch = git
-pkg_vmq_graphite_repo = https://github.com/erlio/vmq_graphite
-pkg_vmq_graphite_commit = master
diff --git a/index/vmq_passwd.mk b/index/vmq_passwd.mk
deleted file mode 100644
index e2f2e81..0000000
--- a/index/vmq_passwd.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += vmq_passwd
-pkg_vmq_passwd_name = vmq_passwd
-pkg_vmq_passwd_description = Component of VerneMQ: A distributed MQTT message broker
-pkg_vmq_passwd_homepage = https://verne.mq/
-pkg_vmq_passwd_fetch = git
-pkg_vmq_passwd_repo = https://github.com/erlio/vmq_passwd
-pkg_vmq_passwd_commit = master
diff --git a/index/vmq_server.mk b/index/vmq_server.mk
deleted file mode 100644
index aac8e9d..0000000
--- a/index/vmq_server.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += vmq_server
-pkg_vmq_server_name = vmq_server
-pkg_vmq_server_description = Component of VerneMQ: A distributed MQTT message broker
-pkg_vmq_server_homepage = https://verne.mq/
-pkg_vmq_server_fetch = git
-pkg_vmq_server_repo = https://github.com/erlio/vmq_server
-pkg_vmq_server_commit = master
diff --git a/index/vmq_snmp.mk b/index/vmq_snmp.mk
deleted file mode 100644
index e3a2ef9..0000000
--- a/index/vmq_snmp.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += vmq_snmp
-pkg_vmq_snmp_name = vmq_snmp
-pkg_vmq_snmp_description = Component of VerneMQ: A distributed MQTT message broker
-pkg_vmq_snmp_homepage = https://verne.mq/
-pkg_vmq_snmp_fetch = git
-pkg_vmq_snmp_repo = https://github.com/erlio/vmq_snmp
-pkg_vmq_snmp_commit = master
diff --git a/index/vmq_systree.mk b/index/vmq_systree.mk
deleted file mode 100644
index db7ee93..0000000
--- a/index/vmq_systree.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += vmq_systree
-pkg_vmq_systree_name = vmq_systree
-pkg_vmq_systree_description = Component of VerneMQ: A distributed MQTT message broker
-pkg_vmq_systree_homepage = https://verne.mq/
-pkg_vmq_systree_fetch = git
-pkg_vmq_systree_repo = https://github.com/erlio/vmq_systree
-pkg_vmq_systree_commit = master
diff --git a/index/worker_pool.mk b/index/worker_pool.mk
index 11e47da..26341f3 100644
--- a/index/worker_pool.mk
+++ b/index/worker_pool.mk
@@ -4,4 +4,4 @@ pkg_worker_pool_description = a simple erlang worker pool
pkg_worker_pool_homepage = https://github.com/inaka/worker_pool
pkg_worker_pool_fetch = git
pkg_worker_pool_repo = https://github.com/inaka/worker_pool
-pkg_worker_pool_commit = master
+pkg_worker_pool_commit = main
diff --git a/index/zab_engine.mk b/index/zab_engine.mk
deleted file mode 100644
index 838121e..0000000
--- a/index/zab_engine.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += zab_engine
-pkg_zab_engine_name = zab_engine
-pkg_zab_engine_description = zab propotocol implement by erlang
-pkg_zab_engine_homepage = https://github.com/xinmingyao/zab_engine
-pkg_zab_engine_fetch = git
-pkg_zab_engine_repo = https://github.com/xinmingyao/zab_engine
-pkg_zab_engine_commit = master
diff --git a/index/zabbix_sender.mk b/index/zabbix_sender.mk
deleted file mode 100644
index 109f85b..0000000
--- a/index/zabbix_sender.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += zabbix_sender
-pkg_zabbix_sender_name = zabbix_sender
-pkg_zabbix_sender_description = Zabbix trapper for sending data to Zabbix in pure Erlang
-pkg_zabbix_sender_homepage = https://github.com/stalkermn/zabbix_sender
-pkg_zabbix_sender_fetch = git
-pkg_zabbix_sender_repo = https://github.com/stalkermn/zabbix_sender.git
-pkg_zabbix_sender_commit = master
diff --git a/index/zeta.mk b/index/zeta.mk
deleted file mode 100644
index 53e066a..0000000
--- a/index/zeta.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += zeta
-pkg_zeta_name = zeta
-pkg_zeta_description = HTTP access log parser in Erlang
-pkg_zeta_homepage = https://github.com/s1n4/zeta
-pkg_zeta_fetch = git
-pkg_zeta_repo = https://github.com/s1n4/zeta
-pkg_zeta_commit = master
diff --git a/index/zraft_lib.mk b/index/zraft_lib.mk
deleted file mode 100644
index 86298f5..0000000
--- a/index/zraft_lib.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PACKAGES += zraft_lib
-pkg_zraft_lib_name = zraft_lib
-pkg_zraft_lib_description = Erlang raft consensus protocol implementation
-pkg_zraft_lib_homepage = https://github.com/dreyk/zraft_lib
-pkg_zraft_lib_fetch = git
-pkg_zraft_lib_repo = https://github.com/dreyk/zraft_lib
-pkg_zraft_lib_commit = master
diff --git a/pkg_add.sh b/pkg_add.sh
index c67b775..1ebc845 100755
--- a/pkg_add.sh
+++ b/pkg_add.sh
@@ -9,7 +9,7 @@ fi
T=`echo "$1" | grep "\." | wc -l `
if [ "$T" -eq "1" ]
then
- echo "Invalid dot character in name. Considere replace by an underscore." 1>&2
+ echo "Invalid dot character in name. Consider replacing with an underscore." 1>&2
exit 1
fi
diff --git a/plugins/asciidoc.mk b/plugins/asciidoc.mk
index f4be7ff..778308b 100644
--- a/plugins/asciidoc.mk
+++ b/plugins/asciidoc.mk
@@ -57,8 +57,8 @@ try
})
end || F <- [$(shell echo $(addprefix $(comma)\",$(addsuffix \",$1)) | sed 's/^.//')]],
halt(0)
-catch C:E ->
- io:format("Exception ~p:~p~nStacktrace: ~p~n", [C, E, erlang:get_stacktrace()]),
+catch C:E$(if $V,:S) ->
+ io:format("Exception: ~p:~p~n$(if $V,Stacktrace: ~p~n)", [C, E$(if $V,$(comma) S)]),
halt(1)
end.
endef
diff --git a/plugins/bootstrap.mk b/plugins/bootstrap.mk
index 23dd238..2e0ad8f 100644
--- a/plugins/bootstrap.mk
+++ b/plugins/bootstrap.mk
@@ -93,6 +93,8 @@ endef
define bs_relx_config
{release, {$p_release, "1"}, [$p, sasl, runtime_tools]}.
+{dev_mode, false}.
+{include_erts, true}.
{extended_start_script, true}.
{sys_config, "config/sys.config"}.
{vm_args, "config/vm.args"}.
@@ -449,6 +451,8 @@ endif
$(verbose) mkdir config/
$(verbose) $(call core_render,bs_sys_config,config/sys.config)
$(verbose) $(call core_render,bs_vm_args,config/vm.args)
+ $(verbose) awk '/^include erlang.mk/ && !ins {print "BUILD_DEPS += relx";ins=1};{print}' Makefile > Makefile.bak
+ $(verbose) mv Makefile.bak Makefile
new-app:
ifndef in
diff --git a/plugins/c_src.mk b/plugins/c_src.mk
index d6d5d15..fd9c2d7 100644
--- a/plugins/c_src.mk
+++ b/plugins/c_src.mk
@@ -15,17 +15,24 @@ C_SRC_TYPE ?= shared
ifeq ($(PLATFORM),msys2)
C_SRC_OUTPUT_EXECUTABLE_EXTENSION ?= .exe
C_SRC_OUTPUT_SHARED_EXTENSION ?= .dll
+ C_SRC_OUTPUT_STATIC_EXTENSION ?= .lib
else
C_SRC_OUTPUT_EXECUTABLE_EXTENSION ?=
C_SRC_OUTPUT_SHARED_EXTENSION ?= .so
+ C_SRC_OUTPUT_STATIC_EXTENSION ?= .a
endif
ifeq ($(C_SRC_TYPE),shared)
C_SRC_OUTPUT_FILE = $(C_SRC_OUTPUT)$(C_SRC_OUTPUT_SHARED_EXTENSION)
+else ifeq ($(C_SRC_TYPE),static)
+ C_SRC_OUTPUT_FILE = $(C_SRC_OUTPUT)$(C_SRC_OUTPUT_STATIC_EXTENSION)
else
C_SRC_OUTPUT_FILE = $(C_SRC_OUTPUT)$(C_SRC_OUTPUT_EXECUTABLE_EXTENSION)
endif
+RANLIB ?= ranlib
+ARFLAGS ?= cr
+
ifeq ($(PLATFORM),msys2)
# We hardcode the compiler used on MSYS2. The default CC=cc does
# not produce working code. The "gcc" MSYS2 package also doesn't.
@@ -35,9 +42,9 @@ ifeq ($(PLATFORM),msys2)
CXXFLAGS ?= -O3 -finline-functions -Wall
else ifeq ($(PLATFORM),darwin)
CC ?= cc
- CFLAGS ?= -O3 -std=c99 -arch x86_64 -Wall -Wmissing-prototypes
- CXXFLAGS ?= -O3 -arch x86_64 -Wall
- LDFLAGS ?= -arch x86_64 -flat_namespace -undefined suppress
+ CFLAGS ?= -O3 -std=c99 -Wall -Wmissing-prototypes
+ CXXFLAGS ?= -O3 -Wall
+ LDFLAGS ?= -flat_namespace -undefined suppress
else ifeq ($(PLATFORM),freebsd)
CC ?= cc
CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes
@@ -53,6 +60,11 @@ ifneq ($(PLATFORM),msys2)
CXXFLAGS += -fPIC
endif
+ifeq ($(C_SRC_TYPE),static)
+ CFLAGS += -DSTATIC_ERLANG_NIF=1
+ CXXFLAGS += -DSTATIC_ERLANG_NIF=1
+endif
+
CFLAGS += -I"$(ERTS_INCLUDE_DIR)" -I"$(ERL_INTERFACE_INCLUDE_DIR)"
CXXFLAGS += -I"$(ERTS_INCLUDE_DIR)" -I"$(ERL_INTERFACE_INCLUDE_DIR)"
@@ -69,6 +81,12 @@ cpp_verbose = $(cpp_verbose_$(V))
link_verbose_0 = @echo " LD " $(@F);
link_verbose = $(link_verbose_$(V))
+ar_verbose_0 = @echo " AR " $(@F);
+ar_verbose = $(ar_verbose_$(V))
+
+ranlib_verbose_0 = @echo " RANLIB" $(@F);
+ranlib_verbose = $(ranlib_verbose_$(V))
+
# Targets.
ifeq ($(wildcard $(C_SRC_DIR)),)
@@ -97,11 +115,19 @@ app:: $(C_SRC_ENV) $(C_SRC_OUTPUT_FILE)
test-build:: $(C_SRC_ENV) $(C_SRC_OUTPUT_FILE)
+ifneq ($(C_SRC_TYPE),static)
$(C_SRC_OUTPUT_FILE): $(OBJECTS)
$(verbose) mkdir -p $(dir $@)
$(link_verbose) $(CC) $(OBJECTS) \
$(LDFLAGS) $(if $(filter $(C_SRC_TYPE),shared),-shared) $(LDLIBS) \
-o $(C_SRC_OUTPUT_FILE)
+else
+$(C_SRC_OUTPUT_FILE): $(OBJECTS)
+ $(verbose) mkdir -p $(dir $@)
+ $(ar_verbose) $(AR) $(ARFLAGS) $(C_SRC_OUTPUT_FILE) $(OBJECTS)
+ $(ranlib_verbose) $(RANLIB) $(C_SRC_OUTPUT_FILE)
+endif
+
$(OBJECTS): $(MAKEFILE_LIST) $(C_SRC_ENV)
diff --git a/plugins/ci.mk b/plugins/ci.mk
index 4b902be..b97c087 100644
--- a/plugins/ci.mk
+++ b/plugins/ci.mk
@@ -4,24 +4,14 @@
.PHONY: ci ci-prepare ci-setup
CI_OTP ?=
-CI_HIPE ?=
-CI_ERLLVM ?=
-
-ifeq ($(CI_VM),native)
-ERLC_OPTS += +native
-TEST_ERLC_OPTS += +native
-else ifeq ($(CI_VM),erllvm)
-ERLC_OPTS += +native +'{hipe, [to_llvm]}'
-TEST_ERLC_OPTS += +native +'{hipe, [to_llvm]}'
-endif
-ifeq ($(strip $(CI_OTP) $(CI_HIPE) $(CI_ERLLVM)),)
+ifeq ($(strip $(CI_OTP)),)
ci::
else
-ci:: $(addprefix ci-,$(CI_OTP) $(addsuffix -native,$(CI_HIPE)) $(addsuffix -erllvm,$(CI_ERLLVM)))
+ci:: $(addprefix ci-,$(CI_OTP))
-ci-prepare: $(addprefix $(KERL_INSTALL_DIR)/,$(CI_OTP) $(addsuffix -native,$(CI_HIPE)))
+ci-prepare: $(addprefix ci-prepare-,$(CI_OTP))
ci-setup::
$(verbose) :
@@ -33,7 +23,10 @@ ci_verbose_0 = @echo " CI " $(1);
ci_verbose = $(ci_verbose_$(V))
define ci_target
-ci-$1: $(KERL_INSTALL_DIR)/$2
+ci-prepare-$1: $(KERL_INSTALL_DIR)/$2
+ $(verbose) :
+
+ci-$1: ci-prepare-$1
$(verbose) $(MAKE) --no-print-directory clean
$(ci_verbose) \
PATH="$(KERL_INSTALL_DIR)/$2/bin:$(PATH)" \
@@ -45,11 +38,8 @@ ci-$1: $(KERL_INSTALL_DIR)/$2
endef
$(foreach otp,$(CI_OTP),$(eval $(call ci_target,$(otp),$(otp),otp)))
-$(foreach otp,$(CI_HIPE),$(eval $(call ci_target,$(otp)-native,$(otp)-native,native)))
-$(foreach otp,$(CI_ERLLVM),$(eval $(call ci_target,$(otp)-erllvm,$(otp)-native,erllvm)))
$(foreach otp,$(filter-out $(ERLANG_OTP),$(CI_OTP)),$(eval $(call kerl_otp_target,$(otp))))
-$(foreach otp,$(filter-out $(ERLANG_HIPE),$(sort $(CI_HIPE) $(CI_ERLLLVM))),$(eval $(call kerl_hipe_target,$(otp))))
help::
$(verbose) printf "%s\n" "" \
diff --git a/plugins/cover.mk b/plugins/cover.mk
index 68f5b98..395e8b8 100644
--- a/plugins/cover.mk
+++ b/plugins/cover.mk
@@ -8,6 +8,7 @@ COVER_DATA_DIR ?= $(COVER_REPORT_DIR)
ifdef COVER
COVER_APPS ?= $(notdir $(ALL_APPS_DIRS))
COVER_DEPS ?=
+COVER_EXCLUDE_MODS ?=
endif
# Code coverage for Common Test.
@@ -23,7 +24,8 @@ $(TEST_DIR)/ct.cover.spec: cover-data-dir
"{incl_dirs, '$(PROJECT)', [\"$(call core_native_path,$(CURDIR)/ebin)\" \
$(foreach a,$(COVER_APPS),$(comma) \"$(call core_native_path,$(APPS_DIR)/$a/ebin)\") \
$(foreach d,$(COVER_DEPS),$(comma) \"$(call core_native_path,$(DEPS_DIR)/$d/ebin)\")]}." \
- '{export,"$(call core_native_path,$(abspath $(COVER_DATA_DIR))/ct.coverdata)"}.' > $@
+ '{export,"$(call core_native_path,$(abspath $(COVER_DATA_DIR))/ct.coverdata)"}.' \
+ "{excl_mods, '$(PROJECT)', [$(call comma_list,$(COVER_EXCLUDE_MODS))]}." > $@
CT_RUN += -cover $(TEST_DIR)/ct.cover.spec
endif
@@ -38,14 +40,18 @@ define cover.erl
Dirs = ["$(call core_native_path,$(CURDIR)/ebin)"
$(foreach a,$(COVER_APPS),$(comma) "$(call core_native_path,$(APPS_DIR)/$a/ebin)")
$(foreach d,$(COVER_DEPS),$(comma) "$(call core_native_path,$(DEPS_DIR)/$d/ebin)")],
- [begin
- case filelib:is_dir(Dir) of
- false -> false;
- true ->
- case cover:compile_beam_directory(Dir) of
- {error, _} -> halt(1);
- _ -> true
- end
+ Excludes = [$(call comma_list,$(foreach e,$(COVER_EXCLUDE_MODS),"$e"))],
+ [case file:list_dir(Dir) of
+ {error, enotdir} -> false;
+ {error, _} -> halt(2);
+ {ok, Files} ->
+ BeamFiles = [filename:join(Dir, File) ||
+ File <- Files,
+ not lists:member(filename:basename(File, ".beam"), Excludes),
+ filename:extension(File) =:= ".beam"],
+ case cover:compile_beam(BeamFiles) of
+ {error, _} -> halt(1);
+ _ -> true
end
end || Dir <- Dirs]
end,
diff --git a/plugins/ct.mk b/plugins/ct.mk
index ba65b2c..820af16 100644
--- a/plugins/ct.mk
+++ b/plugins/ct.mk
@@ -78,9 +78,9 @@ endif
endif
define ct_suite_target
-ct-$(1): test-build
- $(verbose) mkdir -p $(CT_LOGS_DIR)
- $(gen_verbose_esc) $(CT_RUN) -sname ct_$(PROJECT) -suite $(addsuffix _SUITE,$(1)) $(CT_EXTRA) $(CT_OPTS)
+ct-$1: test-build
+ $$(verbose) mkdir -p $$(CT_LOGS_DIR)
+ $$(gen_verbose_esc) $$(CT_RUN) -sname ct_$$(PROJECT) -suite $$(addsuffix _SUITE,$1) $$(CT_EXTRA) $$(CT_OPTS)
endef
$(foreach test,$(CT_SUITES),$(eval $(call ct_suite_target,$(test))))
diff --git a/plugins/dialyzer.mk b/plugins/dialyzer.mk
index 0ac2ef0..bb4723a 100644
--- a/plugins/dialyzer.mk
+++ b/plugins/dialyzer.mk
@@ -10,7 +10,7 @@ export DIALYZER_PLT
PLT_APPS ?=
DIALYZER_DIRS ?= --src -r $(wildcard src) $(ALL_APPS_DIRS)
-DIALYZER_OPTS ?= -Werror_handling -Wrace_conditions -Wunmatched_returns # -Wunderspecs
+DIALYZER_OPTS ?= -Werror_handling -Wunmatched_returns # -Wunderspecs
DIALYZER_PLT_OPTS ?=
# Core targets.
@@ -69,6 +69,6 @@ dialyze: $(if $(filter --src,$(DIALYZER_DIRS)),,deps app)
else
dialyze: $(DIALYZER_PLT)
endif
- $(verbose) dialyzer --no_native `$(ERL) \
+ $(verbose) dialyzer `$(ERL) \
-eval "$(subst $(newline),,$(call escape_dquotes,$(call filter_opts.erl)))" \
-extra $(ERLC_OPTS)` $(DIALYZER_DIRS) $(DIALYZER_OPTS) $(if $(wildcard ebin/),-pa ebin/)
diff --git a/plugins/edoc.mk b/plugins/edoc.mk
index 1d6c0f6..0a0e8eb 100644
--- a/plugins/edoc.mk
+++ b/plugins/edoc.mk
@@ -11,7 +11,11 @@ EDOC_OUTPUT ?= doc
define edoc.erl
SrcPaths = lists:foldl(fun(P, Acc) ->
- filelib:wildcard(atom_to_list(P) ++ "/{src,c_src}") ++ Acc
+ filelib:wildcard(atom_to_list(P) ++ "/{src,c_src}")
+ ++ lists:filter(fun(D) ->
+ filelib:is_dir(D)
+ end, filelib:wildcard(atom_to_list(P) ++ "/{src,c_src}/**"))
+ ++ Acc
end, [], [$(call comma_list,$(patsubst %,'%',$(call core_native_path,$(EDOC_SRC_DIRS))))]),
DefaultOpts = [{dir, "$(EDOC_OUTPUT)"}, {source_path, SrcPaths}, {subpackages, false}],
edoc:application($(1), ".", [$(2)] ++ DefaultOpts),
diff --git a/plugins/escript.mk b/plugins/escript.mk
index 3719684..1790dcb 100644
--- a/plugins/escript.mk
+++ b/plugins/escript.mk
@@ -29,11 +29,11 @@ help::
escript-zip:: FULL=1
escript-zip:: deps app
- $(verbose) mkdir -p $(dir $(ESCRIPT_ZIP))
- $(verbose) rm -f $(ESCRIPT_ZIP_FILE)
- $(gen_verbose) cd .. && $(ESCRIPT_ZIP) $(ESCRIPT_ZIP_FILE) $(PROJECT)/ebin/*
+ $(verbose) mkdir -p $(dir $(abspath $(ESCRIPT_ZIP_FILE)))
+ $(verbose) rm -f $(abspath $(ESCRIPT_ZIP_FILE))
+ $(gen_verbose) cd .. && $(ESCRIPT_ZIP) $(abspath $(ESCRIPT_ZIP_FILE)) $(PROJECT)/ebin/*
ifneq ($(DEPS),)
- $(verbose) cd $(DEPS_DIR) && $(ESCRIPT_ZIP) $(ESCRIPT_ZIP_FILE) \
+ $(verbose) cd $(DEPS_DIR) && $(ESCRIPT_ZIP) $(abspath $(ESCRIPT_ZIP_FILE)) \
$(subst $(DEPS_DIR)/,,$(addsuffix /*,$(wildcard \
$(addsuffix /ebin,$(shell cat $(ERLANG_MK_TMP)/deps.log)))))
endif
@@ -43,8 +43,8 @@ escript:: escript-zip
"#!$(ESCRIPT_SHEBANG)" \
"%% $(ESCRIPT_COMMENT)" \
"%%! $(ESCRIPT_EMU_ARGS)" > $(ESCRIPT_FILE)
- $(verbose) cat $(ESCRIPT_ZIP_FILE) >> $(ESCRIPT_FILE)
+ $(verbose) cat $(abspath $(ESCRIPT_ZIP_FILE)) >> $(ESCRIPT_FILE)
$(verbose) chmod +x $(ESCRIPT_FILE)
distclean-escript:
- $(gen_verbose) rm -f $(ESCRIPT_FILE)
+ $(gen_verbose) rm -f $(ESCRIPT_FILE) $(abspath $(ESCRIPT_ZIP_FILE))
diff --git a/plugins/eunit.mk b/plugins/eunit.mk
index aa4cc9a..211a744 100644
--- a/plugins/eunit.mk
+++ b/plugins/eunit.mk
@@ -8,6 +8,7 @@
EUNIT_OPTS ?=
EUNIT_ERL_OPTS ?=
+EUNIT_TEST_SPEC ?= $1
# Core targets.
@@ -23,7 +24,7 @@ help::
define eunit.erl
$(call cover.erl)
CoverSetup(),
- case eunit:test($1, [$(EUNIT_OPTS)]) of
+ case eunit:test($(call EUNIT_TEST_SPEC,$1), [$(EUNIT_OPTS)]) of
ok -> ok;
error -> halt(2)
end,
diff --git a/plugins/proper.mk b/plugins/proper.mk
index 6262199..55a2788 100644
--- a/plugins/proper.mk
+++ b/plugins/proper.mk
@@ -37,8 +37,8 @@ define proper_check.erl
end of
true -> halt(0);
_ -> halt(1)
- catch error:undef ->
- io:format("Undefined property or module?~n~p~n", [erlang:get_stacktrace()]),
+ catch error:undef$(if $V,:Stacktrace) ->
+ io:format("Undefined property or module?~n$(if $V,~p~n)", [$(if $V,Stacktrace)]),
halt(0)
end.
endef
diff --git a/plugins/protobuffs.mk b/plugins/protobuffs.mk
index 809df42..0ebe159 100644
--- a/plugins/protobuffs.mk
+++ b/plugins/protobuffs.mk
@@ -41,10 +41,13 @@ else
define compile_proto.erl
[begin
gpb_compile:file(F, [
+ $(foreach i,$(sort $(dir $(PROTO_FILES))),{i$(comma) "$i"}$(comma))
{include_as_lib, true},
{module_name_suffix, "_pb"},
{o_hrl, "./include"},
- {o_erl, "./src"}])
+ {o_erl, "./src"},
+ {use_packages, true}
+ ])
end || F <- string:tokens("$1", " ")],
halt().
endef
diff --git a/plugins/relx.mk b/plugins/relx.mk
index 4e29031..cb8f06d 100644
--- a/plugins/relx.mk
+++ b/plugins/relx.mk
@@ -1,15 +1,14 @@
# Copyright (c) 2013-2016, Loïc Hoguin <[email protected]>
# This file is part of erlang.mk and subject to the terms of the ISC License.
+ifeq ($(filter relx,$(BUILD_DEPS) $(DEPS) $(REL_DEPS)),relx)
.PHONY: relx-rel relx-relup distclean-relx-rel run
# Configuration.
-RELX ?= $(ERLANG_MK_TMP)/relx
RELX_CONFIG ?= $(CURDIR)/relx.config
+RELX_CONFIG_SCRIPT ?= $(CURDIR)/relx.config.script
-RELX_URL ?= https://erlang.mk/res/relx-v3.27.0
-RELX_OPTS ?=
RELX_OUTPUT_DIR ?= _rel
RELX_REL_EXT ?=
RELX_TAR ?= 1
@@ -18,16 +17,10 @@ ifdef SFX
RELX_TAR = 1
endif
-ifeq ($(firstword $(RELX_OPTS)),-o)
- RELX_OUTPUT_DIR = $(word 2,$(RELX_OPTS))
-else
- RELX_OPTS += -o $(RELX_OUTPUT_DIR)
-endif
-
# Core targets.
ifeq ($(IS_DEP),)
-ifneq ($(wildcard $(RELX_CONFIG)),)
+ifneq ($(wildcard $(RELX_CONFIG))$(wildcard $(RELX_CONFIG_SCRIPT)),)
rel:: relx-rel
relup:: relx-relup
@@ -38,21 +31,85 @@ distclean:: distclean-relx-rel
# Plugin-specific targets.
-$(RELX): | $(ERLANG_MK_TMP)
- $(gen_verbose) $(call core_http_get,$(RELX),$(RELX_URL))
- $(verbose) chmod +x $(RELX)
+define relx_get_config.erl
+ (fun() ->
+ Config0 =
+ case file:consult("$(call core_native_path,$(RELX_CONFIG))") of
+ {ok, Terms} ->
+ Terms;
+ {error, _} ->
+ []
+ end,
+ case filelib:is_file("$(call core_native_path,$(RELX_CONFIG_SCRIPT))") of
+ true ->
+ Bindings = erl_eval:add_binding('CONFIG', Config0, erl_eval:new_bindings()),
+ {ok, Config1} = file:script("$(call core_native_path,$(RELX_CONFIG_SCRIPT))", Bindings),
+ Config1;
+ false ->
+ Config0
+ end
+ end)()
+endef
-relx-rel: $(RELX) rel-deps app
- $(verbose) $(RELX) $(if $(filter 1,$V),-V 3) -c $(RELX_CONFIG) $(RELX_OPTS) release
+define relx_release.erl
+ Config = $(call relx_get_config.erl),
+ {release, {Name, Vsn0}, _} = lists:keyfind(release, 1, Config),
+ Vsn = case Vsn0 of
+ {cmd, Cmd} -> os:cmd(Cmd);
+ semver -> "";
+ {semver, _} -> "";
+ {git, short} -> string:trim(os:cmd("git rev-parse --short HEAD"), both, "\n");
+ {git, long} -> string:trim(os:cmd("git rev-parse HEAD"), both, "\n");
+ VsnStr -> Vsn0
+ end,
+ {ok, _} = relx:build_release(#{name => Name, vsn => Vsn}, Config ++ [{output_dir, "$(RELX_OUTPUT_DIR)"}]),
+ halt(0).
+endef
+
+define relx_tar.erl
+ Config = $(call relx_get_config.erl),
+ {release, {Name, Vsn0}, _} = lists:keyfind(release, 1, Config),
+ Vsn = case Vsn0 of
+ {cmd, Cmd} -> os:cmd(Cmd);
+ semver -> "";
+ {semver, _} -> "";
+ {git, short} -> string:trim(os:cmd("git rev-parse --short HEAD"), both, "\n");
+ {git, long} -> string:trim(os:cmd("git rev-parse HEAD"), both, "\n");
+ VsnStr -> Vsn0
+ end,
+ {ok, _} = relx:build_tar(#{name => Name, vsn => Vsn}, Config ++ [{output_dir, "$(RELX_OUTPUT_DIR)"}]),
+ halt(0).
+endef
+
+define relx_relup.erl
+ Config = $(call relx_get_config.erl),
+ {release, {Name, Vsn0}, _} = lists:keyfind(release, 1, Config),
+ Vsn = case Vsn0 of
+ {cmd, Cmd} -> os:cmd(Cmd);
+ semver -> "";
+ {semver, _} -> "";
+ {git, short} -> string:trim(os:cmd("git rev-parse --short HEAD"), both, "\n");
+ {git, long} -> string:trim(os:cmd("git rev-parse HEAD"), both, "\n");
+ VsnStr -> Vsn0
+ end,
+ {ok, _} = relx:build_relup(Name, Vsn, undefined, Config ++ [{output_dir, "$(RELX_OUTPUT_DIR)"}]),
+ halt(0).
+endef
+
+relx-rel: rel-deps app
+ $(call erlang,$(call relx_release.erl),-pa ebin/)
$(verbose) $(MAKE) relx-post-rel
ifeq ($(RELX_TAR),1)
- $(verbose) $(RELX) $(if $(filter 1,$V),-V 3) -c $(RELX_CONFIG) $(RELX_OPTS) tar
+ $(call erlang,$(call relx_tar.erl),-pa ebin/)
endif
-relx-relup: $(RELX) rel-deps app
- $(verbose) $(RELX) $(if $(filter 1,$V),-V 3) -c $(RELX_CONFIG) $(RELX_OPTS) release
+relx-relup: rel-deps app
+ $(call erlang,$(call relx_release.erl),-pa ebin/)
$(MAKE) relx-post-rel
- $(verbose) $(RELX) $(if $(filter 1,$V),-V 3) -c $(RELX_CONFIG) $(RELX_OPTS) relup $(if $(filter 1,$(RELX_TAR)),tar)
+ $(call erlang,$(call relx_relup.erl),-pa ebin/)
+ifeq ($(RELX_TAR),1)
+ $(call erlang,$(call relx_tar.erl),-pa ebin/)
+endif
distclean-relx-rel:
$(gen_verbose) rm -rf $(RELX_OUTPUT_DIR)
@@ -63,17 +120,19 @@ relx-post-rel::
# Run target.
-ifeq ($(wildcard $(RELX_CONFIG)),)
+ifeq ($(wildcard $(RELX_CONFIG))$(wildcard $(RELX_CONFIG_SCRIPT)),)
run::
else
define get_relx_release.erl
- {ok, Config} = file:consult("$(call core_native_path,$(RELX_CONFIG))"),
+ Config = $(call relx_get_config.erl),
{release, {Name, Vsn0}, _} = lists:keyfind(release, 1, Config),
Vsn = case Vsn0 of
{cmd, Cmd} -> os:cmd(Cmd);
semver -> "";
{semver, _} -> "";
+ {git, short} -> string:trim(os:cmd("git rev-parse --short HEAD"), both, "\n");
+ {git, long} -> string:trim(os:cmd("git rev-parse HEAD"), both, "\n");
VsnStr -> Vsn0
end,
Extended = case lists:keyfind(extended_start_script, 1, Config) of
@@ -100,7 +159,7 @@ ifdef RELOAD
rel::
$(verbose) $(RELX_OUTPUT_DIR)/$(RELX_REL_NAME)/bin/$(RELX_REL_NAME)$(RELX_REL_EXT) ping
$(verbose) $(RELX_OUTPUT_DIR)/$(RELX_REL_NAME)/bin/$(RELX_REL_NAME)$(RELX_REL_EXT) \
- eval "io:format(\"~p~n\", [c:lm()])"
+ eval "io:format(\"~p~n\", [c:lm()])."
endif
help::
@@ -109,3 +168,4 @@ help::
" run Compile the project, build the release and run it"
endif
+endif
diff --git a/plugins/triq.mk b/plugins/triq.mk
index 8791e2c..6d41376 100644
--- a/plugins/triq.mk
+++ b/plugins/triq.mk
@@ -26,8 +26,8 @@ define triq_check.erl
end of
true -> halt(0);
_ -> halt(1)
- catch error:undef ->
- io:format("Undefined property or module?~n~p~n", [erlang:get_stacktrace()]),
+ catch error:undef$(if $V,:Stacktrace) ->
+ io:format("Undefined property or module?~n$(if $V,~p~n)", [$(if $V,Stacktrace)]),
halt(0)
end.
endef
diff --git a/plugins/xref.mk b/plugins/xref.mk
index 7da0f37..0ecace2 100644
--- a/plugins/xref.mk
+++ b/plugins/xref.mk
@@ -1,39 +1,218 @@
-# Copyright (c) 2016, Loïc Hoguin <[email protected]>
-# Copyright (c) 2015, Erlang Solutions Ltd.
+# Copyright (c) 2022, Loïc Hoguin <[email protected]>
# This file is part of erlang.mk and subject to the terms of the ISC License.
-.PHONY: xref distclean-xref
+.PHONY: xref
# Configuration.
-ifeq ($(XREF_CONFIG),)
- XREFR_ARGS :=
-else
- XREFR_ARGS := -c $(XREF_CONFIG)
-endif
+# We do not use locals_not_used or deprecated_function_calls
+# because the compiler will error out by default in those
+# cases with Erlang.mk. Deprecated functions may make sense
+# in some cases but few libraries define them. We do not
+# use exports_not_used by default because it hinders more
+# than it helps library projects such as Cowboy. Finally,
+# undefined_functions provides little that undefined_function_calls
+# doesn't already provide, so it's not enabled by default.
+XREF_CHECKS ?= [undefined_function_calls]
+
+# Instead of predefined checks a query can be evaluated
+# using the Xref DSL. The $q variable is used in that case.
+
+# The scope is a list of keywords that correspond to
+# application directories, being essentially an easy way
+# to configure which applications to analyze. With:
+#
+# - app: .
+# - apps: $(ALL_APPS_DIRS)
+# - deps: $(ALL_DEPS_DIRS)
+# - otp: Built-in Erlang/OTP applications.
+#
+# The default is conservative (app) and will not be
+# appropriate for all types of queries (for example
+# application_call requires adding all applications
+# that might be called or they will not be found).
+XREF_SCOPE ?= app # apps deps otp
+
+# If the above is not enough, additional application
+# directories can be configured.
+XREF_EXTRA_APP_DIRS ?=
-XREFR ?= $(CURDIR)/xrefr
-export XREFR
+# As well as additional non-application directories.
+XREF_EXTRA_DIRS ?=
-XREFR_URL ?= https://github.com/inaka/xref_runner/releases/download/1.1.0/xrefr
+# Erlang.mk supports -ignore_xref([...]) with forms
+# {M, F, A} | {F, A} | M, the latter ignoring whole
+# modules. Ignores can also be provided project-wide.
+XREF_IGNORE ?= []
+
+# All callbacks may be ignored. Erlang.mk will ignore
+# them automatically for exports_not_used (unless it
+# is explicitly disabled by the user).
+XREF_IGNORE_CALLBACKS ?=
# Core targets.
help::
$(verbose) printf '%s\n' '' \
'Xref targets:' \
- ' xref Run Xrefr using $$XREF_CONFIG as config file if defined'
-
-distclean:: distclean-xref
+ ' xref Analyze the project using Xref' \
+ ' xref q=QUERY Evaluate an Xref query'
# Plugin-specific targets.
-$(XREFR):
- $(gen_verbose) $(call core_http_get,$(XREFR),$(XREFR_URL))
- $(verbose) chmod +x $(XREFR)
-
-xref: deps app $(XREFR)
- $(gen_verbose) $(XREFR) $(XREFR_ARGS)
+define xref.erl
+ {ok, Xref} = xref:start([]),
+ Scope = [$(call comma_list,$(XREF_SCOPE))],
+ AppDirs0 = [$(call comma_list,$(foreach d,$(XREF_EXTRA_APP_DIRS),"$d"))],
+ AppDirs1 = case lists:member(otp, Scope) of
+ false -> AppDirs0;
+ true ->
+ RootDir = code:root_dir(),
+ AppDirs0 ++ [filename:dirname(P) || P <- code:get_path(), lists:prefix(RootDir, P)]
+ end,
+ AppDirs2 = case lists:member(deps, Scope) of
+ false -> AppDirs1;
+ true -> [$(call comma_list,$(foreach d,$(ALL_DEPS_DIRS),"$d"))] ++ AppDirs1
+ end,
+ AppDirs3 = case lists:member(apps, Scope) of
+ false -> AppDirs2;
+ true -> [$(call comma_list,$(foreach d,$(ALL_APPS_DIRS),"$d"))] ++ AppDirs2
+ end,
+ AppDirs = case lists:member(app, Scope) of
+ false -> AppDirs3;
+ true -> ["../$(notdir $(CURDIR))"|AppDirs3]
+ end,
+ [{ok, _} = xref:add_application(Xref, AppDir, [{builtins, true}]) || AppDir <- AppDirs],
+ ExtraDirs = [$(call comma_list,$(foreach d,$(XREF_EXTRA_DIRS),"$d"))],
+ [{ok, _} = xref:add_directory(Xref, ExtraDir, [{builtins, true}]) || ExtraDir <- ExtraDirs],
+ ok = xref:set_library_path(Xref, code:get_path() -- (["ebin", "."] ++ AppDirs ++ ExtraDirs)),
+ Checks = case {$1, is_list($2)} of
+ {check, true} -> $2;
+ {check, false} -> [$2];
+ {query, _} -> [$2]
+ end,
+ FinalRes = [begin
+ IsInformational = case $1 of
+ query -> true;
+ check ->
+ is_tuple(Check) andalso
+ lists:member(element(1, Check),
+ [call, use, module_call, module_use, application_call, application_use])
+ end,
+ {ok, Res0} = case $1 of
+ check -> xref:analyze(Xref, Check);
+ query -> xref:q(Xref, Check)
+ end,
+ Res = case IsInformational of
+ true -> Res0;
+ false ->
+ lists:filter(fun(R) ->
+ {Mod, InMFA, MFA} = case R of
+ {InMFA0 = {M, _, _}, MFA0} -> {M, InMFA0, MFA0};
+ {M, _, _} -> {M, R, R}
+ end,
+ Attrs = try
+ Mod:module_info(attributes)
+ catch error:undef ->
+ []
+ end,
+ InlineIgnores = lists:flatten([
+ [case V of
+ M when is_atom(M) -> {M, '_', '_'};
+ {F, A} -> {Mod, F, A};
+ _ -> V
+ end || V <- Values]
+ || {ignore_xref, Values} <- Attrs]),
+ BuiltinIgnores = [
+ {eunit_test, wrapper_test_exported_, 0}
+ ],
+ DoCallbackIgnores = case {Check, "$(strip $(XREF_IGNORE_CALLBACKS))"} of
+ {exports_not_used, ""} -> true;
+ {_, "0"} -> false;
+ _ -> true
+ end,
+ CallbackIgnores = case DoCallbackIgnores of
+ false -> [];
+ true ->
+ Behaviors = lists:flatten([
+ [BL || {behavior, BL} <- Attrs],
+ [BL || {behaviour, BL} <- Attrs]
+ ]),
+ [{Mod, CF, CA} || B <- Behaviors, {CF, CA} <- B:behaviour_info(callbacks)]
+ end,
+ WideIgnores = if
+ is_list($(XREF_IGNORE)) ->
+ [if is_atom(I) -> {I, '_', '_'}; true -> I end
+ || I <- $(XREF_IGNORE)];
+ true -> [$(XREF_IGNORE)]
+ end,
+ Ignores = InlineIgnores ++ BuiltinIgnores ++ CallbackIgnores ++ WideIgnores,
+ not (lists:member(InMFA, Ignores)
+ orelse lists:member(MFA, Ignores)
+ orelse lists:member({Mod, '_', '_'}, Ignores))
+ end, Res0)
+ end,
+ case Res of
+ [] -> ok;
+ _ when IsInformational ->
+ case Check of
+ {call, {CM, CF, CA}} ->
+ io:format("Functions that ~s:~s/~b calls:~n", [CM, CF, CA]);
+ {use, {CM, CF, CA}} ->
+ io:format("Function ~s:~s/~b is called by:~n", [CM, CF, CA]);
+ {module_call, CMod} ->
+ io:format("Modules that ~s calls:~n", [CMod]);
+ {module_use, CMod} ->
+ io:format("Module ~s is used by:~n", [CMod]);
+ {application_call, CApp} ->
+ io:format("Applications that ~s calls:~n", [CApp]);
+ {application_use, CApp} ->
+ io:format("Application ~s is used by:~n", [CApp]);
+ _ when $1 =:= query ->
+ io:format("Query ~s returned:~n", [Check])
+ end,
+ [case R of
+ {{InM, InF, InA}, {M, F, A}} ->
+ io:format("- ~s:~s/~b called by ~s:~s/~b~n",
+ [M, F, A, InM, InF, InA]);
+ {M, F, A} ->
+ io:format("- ~s:~s/~b~n", [M, F, A]);
+ ModOrApp ->
+ io:format("- ~s~n", [ModOrApp])
+ end || R <- Res],
+ ok;
+ _ ->
+ [case {Check, R} of
+ {undefined_function_calls, {{InM, InF, InA}, {M, F, A}}} ->
+ io:format("Undefined function ~s:~s/~b called by ~s:~s/~b~n",
+ [M, F, A, InM, InF, InA]);
+ {undefined_functions, {M, F, A}} ->
+ io:format("Undefined function ~s:~s/~b~n", [M, F, A]);
+ {locals_not_used, {M, F, A}} ->
+ io:format("Unused local function ~s:~s/~b~n", [M, F, A]);
+ {exports_not_used, {M, F, A}} ->
+ io:format("Unused exported function ~s:~s/~b~n", [M, F, A]);
+ {deprecated_function_calls, {{InM, InF, InA}, {M, F, A}}} ->
+ io:format("Deprecated function ~s:~s/~b called by ~s:~s/~b~n",
+ [M, F, A, InM, InF, InA]);
+ {deprecated_functions, {M, F, A}} ->
+ io:format("Deprecated function ~s:~s/~b~n", [M, F, A]);
+ _ ->
+ io:format("~p: ~p~n", [Check, R])
+ end || R <- Res],
+ error
+ end
+ end || Check <- Checks],
+ stopped = xref:stop(Xref),
+ case lists:usort(FinalRes) of
+ [ok] -> halt(0);
+ _ -> halt(1)
+ end
+endef
-distclean-xref:
- $(gen_verbose) rm -rf $(XREFR)
+xref: deps app
+ifdef q
+ $(verbose) $(call erlang,$(call xref.erl,query,"$q"),-pa ebin/)
+else
+ $(verbose) $(call erlang,$(call xref.erl,check,$(XREF_CHECKS)),-pa ebin/)
+endif
diff --git a/scrape_hexpm.sh b/scrape_hexpm.sh
new file mode 100755
index 0000000..a4a59f7
--- /dev/null
+++ b/scrape_hexpm.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/sh
+
+# This script will scrape packages from hex.pm that are believed to be
+# Erlang packages. We do this by first walking through all packages and
+# then getting the most recent release of each package. If the build tools
+# listed contain "rebar3" or "make" we keep them and write the package
+# name and version to a file.
+#
+# This script should only be run occasionally to refresh the file
+# containing the list of packages.
+#
+# @todo Some of the projects fetched are Elixir despite indicating
+# "rebar3" or "make". We should ignore them here once identified
+# so they don't make it to the output.
+# @todo Probably better to only check "rebar3" since many Elixir
+# projects include "make".
+
+NUM=1
+
+while true; do
+
+ echo "# Packages page $NUM"
+
+ PAGE=$(curl -s "https://hex.pm/api/packages?sort=name&page=$NUM")
+
+ if [ "$PAGE" = "[]" ]; then exit 0; fi
+
+ PACKAGES=$(echo $PAGE | jq -r "map({name: .name, url: .releases[0].url})")
+
+ echo $PACKAGES | jq -r '.[] | [.name, .url] | join(" ")' | while read -r NAMEURL; do
+
+ NAME=$(echo $NAMEURL | awk '{print $1;}')
+ URL=$(echo $NAMEURL | awk '{print $2;}')
+
+ VERSION=$(curl -s "$URL" | jq 'select(.meta.build_tools | index("rebar3") or index("make")) | .version | tostring')
+ VERSION=$(echo $VERSION | tr -d '"')
+
+ if [ -n "$VERSION" ]; then
+ echo "$NAME $VERSION"
+ fi
+
+ done
+
+ NUM=$(expr $NUM + 1)
+
+ sleep 10
+
+done
diff --git a/test/Makefile b/test/Makefile
index 0517684..169cfd0 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -13,6 +13,8 @@ endif
# Temporary application name, taken from rule name.
APP = test_$(subst -,_,$@)
+CACHE_DIR = $(CURDIR)/$(APP)/.cache
+export CACHE_DIR
# Erlang, quickly!
@@ -131,14 +133,14 @@ clean::
init: clean
$i "Prefetch Rebar if necessary"
$t if [ ! -d test_rebar_git ]; then \
- git clone -q -n -- https://github.com/rebar/rebar test_rebar_git; \
+ git clone -q -n -- https://github.com/erlang/rebar3 test_rebar_git; \
fi
$i "Generate a bleeding edge Erlang.mk"
$t cd .. && $(MAKE) $v
-REBAR_GIT = file://$(CURDIR)/test_rebar_git
-export REBAR_GIT
+REBAR3_GIT = file://$(CURDIR)/test_rebar_git
+export REBAR3_GIT
# Core.
@@ -167,7 +169,9 @@ $(eval $(foreach t,$(patsubst %.mk,%,$(patsubst plugin_%,%,$(wildcard plugin_*.m
# Packages.
PACKAGES = $(foreach pkg,$(sort $(wildcard ../index/*.mk)),$(notdir $(basename $(pkg))))
-EXCLUDE_FROM_CHECK = ['ci.erlang.mk', esh_mk, hexer_mk, inaka_mk, 'lfe.mk', rabbitmq_codegen]
+PATCHES = ELIXIR_PATCH=1 HUT_PATCH=1
+EXCLUDE_FROM_CHECK = ['ci.erlang.mk', elvis_mk, esh_mk, hexer_mk, inaka_mk, 'lfe.mk', pmod_transform, rust_mk]
+EXCLUDE_FROM_APP_CHECK = esh_mk pmod_transform rust_mk
packages: $(addprefix pkg-,$(PACKAGES))
@@ -196,12 +200,123 @@ pkg-$1: init
false; \
fi
+ $(if $(filter $1,$(EXCLUDE_FROM_APP_CHECK)),,
$i "Check that $1 has a .app file"
$t if ! test -f packages/$1_pkg/deps/$(APP_NAME)/ebin/$(APP_NAME).app; then \
echo "$1: no .app file" >> packages/errors.log; \
false; \
+ fi)
+
+ $i "Check that all applications and their modules can be loaded"
+ $t if ! ( cd packages/$1_pkg/ && $(ERL) -pa deps/*/ebin/ -eval " \
+ Apps0 = [list_to_atom(App) || \"deps/\" ++ App \
+ <- filelib:wildcard(\"deps/*\")], \
+ Apps = [App || App <- Apps0, not lists:member(App, $(EXCLUDE_FROM_CHECK))], \
+ [begin \
+ io:format(\"Loading application ~p~n\", [App]), \
+ case application:load(App) of \
+ ok -> ok; \
+ {error, {already_loaded, App}} -> ok \
+ end, \
+ {ok, Mods} = application:get_key(App, modules), \
+ [try io:format(\" Loading module ~p~n\", [Mod]), \
+ {module, Mod} = code:load_file(Mod) \
+ catch C:R -> timer:sleep(500), erlang:C(R) \
+ end || Mod <- Mods] \
+ end || App <- Apps], \
+ halt()." ); then \
+ echo "$1: load error" >> packages/errors.log; \
+ false; \
+ fi
+
+ $i "Recompile package $1"
+ $t if ! ( cd packages/$1_pkg/ && $(MAKE) $(PATCHES) FULL=1 $v ); then \
+ echo "$(1): recompile error" >> packages/errors.log; \
+ false; \
+ fi
+
+ $(if $(filter $1,$(EXCLUDE_FROM_APP_CHECK)),,
+ $i "Check that $1 has a .app file"
+ $t if ! test -f packages/$1_pkg/deps/$(APP_NAME)/ebin/$(APP_NAME).app; then \
+ echo "$1: no .app file" >> packages/errors.log; \
+ false; \
+ fi)
+
+ $i "Check that all applications and their modules can still be loaded"
+ $t if ! ( cd packages/$1_pkg/ && $(ERL) -pa deps/*/ebin/ -eval " \
+ Apps0 = [list_to_atom(App) || \"deps/\" ++ App \
+ <- filelib:wildcard(\"deps/*\")], \
+ Apps = [App || App <- Apps0, not lists:member(App, $(EXCLUDE_FROM_CHECK))], \
+ [begin \
+ io:format(\"Loading application ~p~n\", [App]), \
+ case application:load(App) of \
+ ok -> ok; \
+ {error, {already_loaded, App}} -> ok \
+ end, \
+ {ok, Mods} = application:get_key(App, modules), \
+ [try io:format(\" Loading module ~p~n\", [Mod]), \
+ {module, Mod} = code:load_file(Mod) \
+ catch C:R -> timer:sleep(500), erlang:C(R) \
+ end || Mod <- Mods] \
+ end || App <- Apps], \
+ halt()." ); then \
+ echo "$1: recompile+load error" >> packages/errors.log; \
+ false; \
fi
+ $i "Check that no erl_crash.dump file exists"
+ $t if ( ! find packages/$1_pkg/ -type f -name erl_crash.dump ); then \
+ echo "$(1): erl_crash.dump found" >> packages/errors.log; \
+ fi
+
+ $(if $(KEEP_BUILDS),,
+ $i "OK; delete the build directory"
+ $t rm -rf packages/$1_pkg/)
+endef
+
+$(foreach pkg,$(PACKAGES),$(eval $(call pkg_target,$(pkg))))
+
+# Hex.pm packages.
+
+ifdef HEXPM
+
+HEXPM_PACKAGES =
+
+define hexpm_pkg_target
+HEXPM_PACKAGES += $1
+
+.PHONY: hexpm-pkg-$1
+
+hexpm-pkg-$1: init
+
+# Make sure $@ is defined inside the define.
+ $(eval @ = hexpm-pkg-$1)
+
+# @todo Get the real application's name. How?
+ $(eval APP_NAME := $1)
+
+ $i "Bootstrap a new OTP library in packages/$1_pkg"
+ $t mkdir -p packages/$1_pkg/
+ $t cp ../erlang.mk packages/$1_pkg/
+ $t cd packages/$1_pkg/ && $(MAKE) -f erlang.mk bootstrap-lib $v
+
+ $i "Add package $1 to the Makefile"
+ $t perl -ni.bak -e 'print;if ($$$$.==1) {print "DEPS = $1\ndep_$1 = hex $2\n"}' packages/$1_pkg/Makefile
+
+ $i "Compile package $1"
+ $t if ! ( cd packages/$1_pkg/ && $(MAKE) $(PATCHES) $v ); then \
+ echo "$1: compile error" >> packages/errors.log; \
+ false; \
+ fi
+
+# $(if $(filter $1,$(EXCLUDE_FROM_APP_CHECK)),,
+ $i "Check that $1 has a .app file"
+ $t if ! test -f packages/$1_pkg/deps/$(APP_NAME)/ebin/$(APP_NAME).app; then \
+ echo "$1: no .app file" >> packages/errors.log; \
+ false; \
+ fi
+# )
+
$i "Check that all applications and their modules can be loaded"
$t if ! ( cd packages/$1_pkg/ && $(ERL) -pa deps/*/ebin/ -eval " \
Apps0 = [list_to_atom(App) || \"deps/\" ++ App \
@@ -230,11 +345,13 @@ pkg-$1: init
false; \
fi
+# $(if $(filter $1,$(EXCLUDE_FROM_APP_CHECK)),,
$i "Check that $1 has a .app file"
$t if ! test -f packages/$1_pkg/deps/$(APP_NAME)/ebin/$(APP_NAME).app; then \
echo "$1: no .app file" >> packages/errors.log; \
false; \
fi
+# )
$i "Check that all applications and their modules can still be loaded"
$t if ! ( cd packages/$1_pkg/ && $(ERL) -pa deps/*/ebin/ -eval " \
@@ -268,4 +385,8 @@ pkg-$1: init
$t rm -rf packages/$1_pkg/)
endef
-$(foreach pkg,$(PACKAGES),$(eval $(call pkg_target,$(pkg))))
+$(foreach pkg,$(shell grep -v '^#' hexpm_packages.txt | sed 's/ /@/'),$(eval $(call hexpm_pkg_target,$(firstword $(subst @, ,$(pkg))),$(lastword $(subst @, ,$(pkg))))))
+
+hexpm-packages: $(addprefix hexpm-pkg-,$(HEXPM_PACKAGES))
+
+endif
diff --git a/test/core_app.mk b/test/core_app.mk
index effc598..7d270e3 100644
--- a/test/core_app.mk
+++ b/test/core_app.mk
@@ -274,6 +274,59 @@ endif
true = ID =/= [], \
halt()"
+core-app-compile-first: init
+
+ $i "Bootstrap a new OTP library named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
+
+ $i "Generate .erl files"
+ $t echo "-module(boy)." > $(APP)/src/boy.erl
+ $t echo "-module(girl)." > $(APP)/src/girl.erl
+ $t echo "-module(first)." > $(APP)/src/first.erl
+
+ $i "Define COMPILE_FIRST"
+ $t echo "COMPILE_FIRST = first" >> $(APP)/Makefile
+
+ $i "Build the application"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that the application was compiled correctly"
+ $t $(ERL) -pa $(APP)/ebin/ -eval " \
+ ok = application:start($(APP)), \
+ {ok, Mods = [boy, first, girl]} \
+ = application:get_key($(APP), modules), \
+ [{module, M} = code:load_file(M) || M <- Mods], \
+ halt()"
+
+core-app-compile-first-sub-directory: init
+
+ $i "Bootstrap a new OTP library named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
+
+ $i "Generate .erl files"
+ $t echo "-module(boy)." > $(APP)/src/boy.erl
+ $t echo "-module(girl)." > $(APP)/src/girl.erl
+ $t mkdir $(APP)/src/sub/
+ $t echo "-module(first)." > $(APP)/src/sub/first.erl
+
+ $i "Define COMPILE_FIRST with a module in a sub-directory"
+ $t echo "COMPILE_FIRST = sub/first" >> $(APP)/Makefile
+
+ $i "Build the application"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that the application was compiled correctly"
+ $t $(ERL) -pa $(APP)/ebin/ -eval " \
+ ok = application:start($(APP)), \
+ {ok, Mods = [boy, first, girl]} \
+ = application:get_key($(APP), modules), \
+ [{module, M} = code:load_file(M) || M <- Mods], \
+ halt()"
+
ifndef LEGACY
core-app-env: init
@@ -1699,7 +1752,8 @@ core-app-yrl-header: init
$t echo "-export([forty_two/0])." > $(APP)/include/yecc_header.hrl
# A bunch of gobbldygook we don't actually care about, they just
# need to exist so we don't get errors.
- $t echo "-export([yeccpars1/5, yeccerror/1, yeccpars2/7, yeccpars2_0/7, yeccpars2_1/7, yeccpars2_2/7, yeccpars2_3/7, yeccpars2_5/7, yeccpars2_6/7, yeccpars2_7/7, yeccpars2_9/7, yeccpars2_11/7, 'yeccgoto_\'E\''/7, 'yeccgoto_\'F\''/7, 'yeccgoto_\'T\''/7, yeccpars2_9_/1, yeccpars2_11_/1, yeccpars2_7_/1])." >> $(APP)/include/yecc_header.hrl
+ $t echo "-export([yeccpars1/5])." >> $(APP)/include/yecc_header.hrl
+ $t echo "-export([yeccerror/1])." >> $(APP)/include/yecc_header.hrl
$t echo "yeccpars1(_,_,_,_,_) -> throw(not_implemented)." >> $(APP)/include/yecc_header.hrl
$t echo "yeccerror(_) -> throw(not_implemented)." >> $(APP)/include/yecc_header.hrl
# Required bits done, now part we'll actually test for.
diff --git a/test/core_apps.mk b/test/core_apps.mk
index 878bb10..72466b2 100644
--- a/test/core_apps.mk
+++ b/test/core_apps.mk
@@ -477,7 +477,7 @@ core-apps-local-deps: init
$i "Distclean the application"
$t $(MAKE) -C $(APP) distclean $v
- $i "Test after swapping my_app_1 and my_app_2 to make sure lexical ordering didnt incidentally build the correct app first"
+ $i "Test after swapping my_app_1 and my_app_2 to make sure lexical ordering didn't incidentally build the correct app first"
$i "Add my_app_2 to the list of local dependencies of my_app_1, don't add lager, but add the lager parse_transform (this will fail unless my_app_2 was indeed built first)"
$t mv $(APP)/apps/my_app_1/Makefile.bak $(APP)/apps/my_app_1/Makefile
diff --git a/test/core_compat.mk b/test/core_compat.mk
index d9789ec..238d7ad 100644
--- a/test/core_compat.mk
+++ b/test/core_compat.mk
@@ -4,7 +4,6 @@
CORE_COMPAT_TARGETS = $(call list_targets,core-compat)
-REBAR_BINARY = https://github.com/rebar/rebar/releases/download/2.6.0/rebar
REBAR3_BINARY = https://s3.amazonaws.com/rebar3/rebar3
.PHONY: core-compat $(CORE_COMPAT_TARGETS)
@@ -46,12 +45,12 @@ core-compat-auto-rebar: init
$i "Distclean the application"
$t $(MAKE) -C $(APP) distclean $v
- $i "Download rebar"
- $t curl --retry 5 -s -L -o $(APP)/rebar $(REBAR_BINARY)
- $t chmod +x $(APP)/rebar
+ $i "Download rebar3"
+ $t curl --retry 5 -s -L -o $(APP)/rebar3 $(REBAR3_BINARY)
+ $t chmod +x $(APP)/rebar3
- $i "Use rebar to build the application"
- $t cd $(APP) && ./rebar compile $v
+ $i "Use rebar3 to build the application"
+ $t cd $(APP) && ./rebar3 compile $v
core-compat-rebar: init
@@ -85,12 +84,12 @@ core-compat-rebar: init
$i "Distclean the application"
$t $(MAKE) -C $(APP) distclean $v
- $i "Download rebar"
- $t curl --retry 5 -s -L -o $(APP)/rebar $(REBAR_BINARY)
- $t chmod +x $(APP)/rebar
+ $i "Download rebar3"
+ $t curl --retry 5 -s -L -o $(APP)/rebar3 $(REBAR3_BINARY)
+ $t chmod +x $(APP)/rebar3
- $i "Use rebar to build the application"
- $t cd $(APP) && ./rebar compile $v
+ $i "Use rebar3 to build the application"
+ $t cd $(APP) && ./rebar3 compile $v
core-compat-rebar-deps-git: init
@@ -100,7 +99,7 @@ core-compat-rebar-deps-git: init
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
$i "Add Cowboy as a dependency"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowboy\ndep_cowboy = git https://github.com/ninenines/cowboy 1.0.0\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowboy\ndep_cowboy = git https://github.com/ninenines/cowboy 2.9.0\n"}' $(APP)/Makefile
$i "Run 'make rebar.config'"
$t $(MAKE) -C $(APP) rebar.config $v
@@ -111,18 +110,18 @@ core-compat-rebar-deps-git: init
$i "Check that Cowboy is listed in rebar.config"
$t $(ERL) -eval " \
{ok, C} = file:consult(\"$(APP)/rebar.config\"), \
- {_, [{cowboy, _, {git, _, \"1.0.0\"}}]} = lists:keyfind(deps, 1, C), \
+ {_, [{cowboy, _, {git, _, \"2.9.0\"}}]} = lists:keyfind(deps, 1, C), \
halt()"
$i "Distclean the application"
$t $(MAKE) -C $(APP) distclean $v
- $i "Download rebar"
- $t curl --retry 5 -s -L -o $(APP)/rebar $(REBAR_BINARY)
- $t chmod +x $(APP)/rebar
+ $i "Download rebar3"
+ $t curl --retry 5 -s -L -o $(APP)/rebar3 $(REBAR3_BINARY)
+ $t chmod +x $(APP)/rebar3
- $i "Use rebar to build the application"
- $t cd $(APP) && ./rebar get-deps compile $v
+ $i "Use rebar3 to build the application"
+ $t cd $(APP) && ./rebar3 compile $v
core-compat-rebar-deps-hex: init
@@ -153,7 +152,7 @@ core-compat-rebar-deps-hex: init
$t curl --retry 5 -s -L -o $(APP)/rebar3 $(REBAR3_BINARY)
$t chmod +x $(APP)/rebar3
- $i "Use rebar to build the application"
+ $i "Use rebar3 to build the application"
$t cd $(APP) && ./rebar3 compile $v
core-compat-rebar-deps-pkg: init
@@ -181,12 +180,12 @@ core-compat-rebar-deps-pkg: init
$i "Distclean the application"
$t $(MAKE) -C $(APP) distclean $v
- $i "Download rebar"
- $t curl --retry 5 -s -L -o $(APP)/rebar $(REBAR_BINARY)
- $t chmod +x $(APP)/rebar
+ $i "Download rebar3"
+ $t curl --retry 5 -s -L -o $(APP)/rebar3 $(REBAR3_BINARY)
+ $t chmod +x $(APP)/rebar3
- $i "Use rebar to build the application"
- $t cd $(APP) && ./rebar get-deps compile $v
+ $i "Use rebar3 to build the application"
+ $t cd $(APP) && ./rebar3 compile $v
core-compat-rebar-erlc-opts: init
@@ -230,12 +229,12 @@ core-compat-rebar-erlc-opts: init
$i "Distclean the application"
$t $(MAKE) -C $(APP) distclean $v
- $i "Download rebar"
- $t curl --retry 5 -s -L -o $(APP)/rebar $(REBAR_BINARY)
- $t chmod +x $(APP)/rebar
+ $i "Download rebar3"
+ $t curl --retry 5 -s -L -o $(APP)/rebar3 $(REBAR3_BINARY)
+ $t chmod +x $(APP)/rebar3
- $i "Use rebar to build the application"
- $t cd $(APP) && ./rebar compile $v
+ $i "Use rebar3 to build the application"
+ $t cd $(APP) && ./rebar3 compile $v
core-compat-rebar-pt: init
@@ -288,14 +287,14 @@ ifndef LEGACY
$t mv $(APP)/$(APP).app $(APP)/ebin/
endif
- $i "Download rebar"
- $t curl --retry 5 -s -L -o $(APP)/rebar $(REBAR_BINARY)
- $t chmod +x $(APP)/rebar
+ $i "Download rebar3"
+ $t curl --retry 5 -s -L -o $(APP)/rebar3 $(REBAR3_BINARY)
+ $t chmod +x $(APP)/rebar3
- $i "Use rebar to build the application"
- $t cd $(APP) && ./rebar get-deps compile $v
+ $i "Use rebar3 to build the application"
+ $t cd $(APP) && ./rebar3 compile $v
$i "Check that all compiled files exist"
- $t test -f $(APP)/ebin/$(APP).app
- $t test -f $(APP)/ebin/boy.beam
- $t test -f $(APP)/ebin/girl.beam
+ $t test -f $(APP)/_build/default/lib/$(APP)/ebin/$(APP).app
+ $t test -f $(APP)/_build/default/lib/$(APP)/ebin/boy.beam
+ $t test -f $(APP)/_build/default/lib/$(APP)/ebin/girl.beam
diff --git a/test/core_deps.mk b/test/core_deps.mk
index 973ff5d..4d8e161 100644
--- a/test/core_deps.mk
+++ b/test/core_deps.mk
@@ -106,6 +106,119 @@ core-deps-build-js: init
false = lists:member(jquery, Deps), \
halt()"
+core-deps-cache-git: init
+
+ $i "Bootstrap a new OTP library named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
+
+ $i "Add Cowlib to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\n"}' $(APP)/Makefile
+
+ $i "Add CACHE_DEPS = 1 to the Makefile"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "CACHE_DEPS = 1\n"}' $(APP)/Makefile
+
+ $i "Check that the cache doesn't exist yet"
+ $t test ! -d $(CACHE_DIR)
+
+ $i "Build the dependencies"
+ $t $(MAKE) -C $(APP) deps $v
+
+ $i "Check that the cache has been created"
+ $t test -d $(CACHE_DIR)
+
+ $i "Check that Cowlib was cloned in the cache"
+ $t test -d $(CACHE_DIR)/git/cowlib
+
+ $i "Distclean the application"
+ $t $(MAKE) -C $(APP) distclean $v
+
+ $i "Check that Cowlib is still in the cache"
+ $t test -d $(CACHE_DIR)/git/cowlib
+
+ $i "Break the Cowlib git link so we're forced to use the cache"
+ $t echo 'dep_cowlib = git bad_url master' >> $(APP)/Makefile
+
+ $i "Build the dependencies"
+ $t $(MAKE) -C $(APP) deps $v
+
+core-deps-cache-git-reuse: init
+
+ $i "Bootstrap a new OTP library named $(APP)_1"
+ $t mkdir $(APP)_1/
+ $t cp ../erlang.mk $(APP)_1/
+ $t $(MAKE) -C $(APP)_1 -f erlang.mk bootstrap-lib $v
+
+ $i "Add Cowlib 1.0.0 to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\ndep_cowlib = git \$$(pkg_cowlib_repo) 1.0.0\n"}' $(APP)_1/Makefile
+
+ $i "Add CACHE_DEPS = 1 to the Makefile"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "CACHE_DEPS = 1\n"}' $(APP)_1/Makefile
+
+ $i "Bootstrap a new OTP library named $(APP)_2"
+ $t mkdir $(APP)_2/
+ $t cp ../erlang.mk $(APP)_2/
+ $t $(MAKE) -C $(APP)_2 -f erlang.mk bootstrap-lib $v
+
+ $i "Add Cowlib 2.0.0 to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\ndep_cowlib = git \$$(pkg_cowlib_repo) 2.0.0\n"}' $(APP)_2/Makefile
+
+ $i "Add CACHE_DEPS = 1 to the Makefile"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "CACHE_DEPS = 1\n"}' $(APP)_2/Makefile
+
+ $i "Build the dependencies in $(APP)_1"
+ $t $(MAKE) -C $(APP)_1 deps $v
+
+ $i "Check that the cache has been created"
+ $t test -d $(CACHE_DIR)
+
+ $i "Check that Cowlib was cloned in the cache"
+ $t test -d $(CACHE_DIR)/git/cowlib
+
+ $i "Build the dependencies in $(APP)_2"
+ $t $(MAKE) -C $(APP)_2 deps $v
+
+ $i "Check that $(APP)_1 cloned Cowlib 1.0.0"
+ $t test "$$(cat $(APP)_1/deps/cowlib/.git/HEAD)" = "d544a494af4dbc810fc9c15eaf5cc050cced1501"
+
+ $i "Check that $(APP)_2 cloned Cowlib 2.0.0"
+ $t test "$$(cat $(APP)_2/deps/cowlib/.git/HEAD)" = "bd37be4d3b065600c3b76b492535e76e5d413fc1"
+
+core-deps-cache-hex: init
+
+ $i "Bootstrap a new OTP library named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
+
+ $i "Add Cowlib to the list of dependencies using Hex"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\ndep_cowlib = hex 2.12.1\n"}' $(APP)/Makefile
+
+ $i "Add CACHE_DEPS = 1 to the Makefile"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "CACHE_DEPS = 1\n"}' $(APP)/Makefile
+
+ $i "Check that the cache doesn't exist yet"
+ $t test ! -d $(CACHE_DIR)
+
+ $i "Build the dependencies"
+ $t $(MAKE) -C $(APP) deps $v
+
+ $i "Check that the cache has been created"
+ $t test -d $(CACHE_DIR)
+
+ $i "Check that Cowlib was cloned in the cache"
+ $t test -f $(CACHE_DIR)/hex/cowlib-2.12.1.tar
+
+ $i "Distclean the application"
+ $t $(MAKE) -C $(APP) distclean $v
+
+ $i "Check that Cowlib is still in the cache"
+ $t test -f $(CACHE_DIR)/hex/cowlib-2.12.1.tar
+
+ $i "Build the dependencies"
+ $t $(MAKE) -C $(APP) deps $v
+
core-deps-dep-built: init
$i "Bootstrap a new OTP library named $(APP)"
@@ -562,7 +675,7 @@ core-deps-fetch-git-submodule: init
$t mkdir $(APP)/deps
$t cd $(APP) && \
git init -q && \
- git submodule -q add file://$(abspath $(APP)/my_dep) deps/my_dep && \
+ git -c protocol.file.allow=always submodule -q add file://$(abspath $(APP)/my_dep) deps/my_dep && \
git config user.email "[email protected]" && \
git config user.name "test suite" && \
git add . && \
@@ -599,12 +712,12 @@ core-deps-fetch-hex: init
$t cp ../erlang.mk $(APP)/
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
- $i "Add Cowboy 1.0.0 to the list of dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowboy\ndep_cowboy = hex 1.0.0\n"}' $(APP)/Makefile
+ $i "Add Cowboy 1.0.0 and SystemD 0.6.0 to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowboy systemd\ndep_cowboy = hex 1.0.0\ndep_systemd = hex 0.6.0\n"}' $(APP)/Makefile
ifdef LEGACY
- $i "Add Cowboy to the applications key in the .app.src file"
- $t perl -ni.bak -e 'print;if ($$.==7) {print "\t\tcowboy,\n"}' $(APP)/src/$(APP).app.src
+ $i "Add Cowboy and SystemD to the applications key in the .app.src file"
+ $t perl -ni.bak -e 'print;if ($$.==7) {print "\t\tcowboy,\n\t\tsystemd,\n"}' $(APP)/src/$(APP).app.src
endif
$i "Build the application"
@@ -614,13 +727,17 @@ endif
$t test -d $(APP)/deps/cowboy
$t test -d $(APP)/deps/cowlib
$t test -d $(APP)/deps/ranch
+ $t test -d $(APP)/deps/systemd
+ $t test -d $(APP)/deps/enough
$i "Check that the application was compiled correctly"
$t $(ERL) -pa $(APP)/ebin/ $(APP)/deps/*/ebin/ -eval " \
- [ok = application:load(App) || App <- [$(APP), cowboy, cowlib, ranch]], \
+ [ok = application:load(App) || App <- [$(APP), cowboy, cowlib, ranch, systemd, enough]], \
{ok, Deps} = application:get_key($(APP), applications), \
true = lists:member(cowboy, Deps), \
+ true = lists:member(systemd, Deps), \
{ok, \"1.0.0\"} = application:get_key(cowboy, vsn), \
+ {ok, \"0.6.0\"} = application:get_key(systemd, vsn), \
halt()"
# @todo Enable this test again when a host provides Mercurial again.
@@ -1120,6 +1237,32 @@ core-deps-mv-rebar: init
$i "Build the application"
$t $(MAKE) -C $(APP)-moved $v
+ifndef LEGACY
+core-deps-optional: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Add quicer to the list of optional dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "OPTIONAL_DEPS = quicer\n"}' $(APP)/Makefile
+
+ $i "Build the application"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that no dependencies were fetched"
+ $t test ! -e $(APP)/deps
+
+ $i "Check that the application was compiled correctly"
+ $t $(ERL) -pa $(APP)/ebin/ -eval " \
+ ok = application:start($(APP)), \
+ {ok, Deps} = application:get_key($(APP), applications), \
+ true = lists:member(quicer, Deps), \
+ {ok, [quicer]} = application:get_key($(APP), optional_applications), \
+ halt()"
+endif
+
# A lower-level dependency of the first dependency always
# wins over a lower-level dependency of the second dependency.
core-deps-order-first: init
@@ -1270,8 +1413,8 @@ core-deps-rel: init
$i "Build the application and its dependencies"
$t $(MAKE) -C $(APP) deps app $v
- $i "Check that no dependencies were fetched"
- $t test ! -e $(APP)/deps
+ $i "Check that Recon was not fetched"
+ $t test ! -e $(APP)/deps/recon
$i "Check that the application was compiled correctly"
$t $(ERL) -pa $(APP)/ebin/ -eval " \
@@ -1283,7 +1426,7 @@ core-deps-rel: init
$i "Build the release"
$t $(MAKE) -C $(APP) $v
- $i "Check that all dependencies were fetched"
+ $i "Check that Recon was fetched"
$t test -d $(APP)/deps/recon
$i "Check that the application was compiled correctly"
@@ -1298,17 +1441,17 @@ core-deps-rel: init
ifeq ($(PLATFORM),msys2)
# $t $(APP)/_rel/$(APP)_release/bin/$(APP)_release.cmd install $v
# $t $(APP)/_rel/$(APP)_release/bin/$(APP)_release.cmd start $v
-# $t test -n "`$(APP)/_rel/$(APP)_release/bin/$(APP)_release.cmd rpcterms \
+# $t test -n "`$(APP)/_rel/$(APP)_release/bin/$(APP)_release.cmd rpc \
# application loaded_applications | grep recon`"
# $t $(APP)/_rel/$(APP)_release/bin/$(APP)_release.cmd stop $v
# $t $(APP)/_rel/$(APP)_release/bin/$(APP)_release.cmd uninstall $v
else
$i "Start the release and check that Recon is loaded"
- $t $(APP)/_rel/$(APP)_release/bin/$(APP)_release start $v
+ $t $(APP)/_rel/$(APP)_release/bin/$(APP)_release daemon $v
$t apps="Node is not running!"; \
while test "$$apps" = "Node is not running!"; do \
apps=$$($(APP)/_rel/$(APP)_release/bin/$(APP)_release \
- rpcterms \ application loaded_applications); \
+ rpc application loaded_applications); \
done; \
echo "$$apps" | grep -q recon
$t $(APP)/_rel/$(APP)_release/bin/$(APP)_release stop $v
diff --git a/test/core_makedep.mk b/test/core_makedep.mk
index 5a0b02c..f2ab860 100644
--- a/test/core_makedep.mk
+++ b/test/core_makedep.mk
@@ -25,6 +25,26 @@ core-makedep-behavior: init
$t test -f $(APP)/ebin/boy.beam
$t test -f $(APP)/ebin/human.beam
+core-makedep-ignore-special-files: init
+
+ $i "Bootstrap a new OTP library named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
+ $t mkdir $(APP)/src/core
+
+ $i "Generate related .erl files"
+ $t printf "%s\n" "-module(human)." "-export([live/0])." "live() -> ok." > $(APP)/src/core/human.erl
+ $t printf "%s\n" "-module(boy)." "-import(human,[live/0])." > $(APP)/src/boy.erl
+ $t printf "%s\n" "-module(boy)." "-import(human,[live/0])." > $(APP)/src/.#boy.erl
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that all compiled files exist"
+ $t test -f $(APP)/$(APP).d
+ $t test -f $(APP)/ebin/$(APP).app
+ $t test -f $(APP)/ebin/boy.beam
+ $t test -f $(APP)/ebin/human.beam
+
core-makedep-import: init
$i "Bootstrap a new OTP library named $(APP)"
diff --git a/test/core_query.mk b/test/core_query.mk
index 380f4ad..9f348a1 100644
--- a/test/core_query.mk
+++ b/test/core_query.mk
@@ -154,7 +154,7 @@ endif
"farwest: cowlib git https://github.com/ninenines/cowlib master" \
"farwest: cowboy git https://github.com/ninenines/cowboy master" \
"farwest: gun git https://github.com/ninenines/gun master" \
- "gun: cowlib git https://github.com/ninenines/cowlib 2.10.1" \
+ "gun: cowlib git https://github.com/ninenines/cowlib 2.12.1" \
> $(APP)/expected-deps.txt
$t cmp $(APP)/expected-deps.txt $(APP)/.erlang.mk/query-deps.log
diff --git a/test/hexpm_packages.txt b/test/hexpm_packages.txt
new file mode 100644
index 0000000..699d62b
--- /dev/null
+++ b/test/hexpm_packages.txt
@@ -0,0 +1,1876 @@
+# Packages page 1
+abnfc 0.5.4
+accept 0.3.5
+acceptor_pool 1.0.0
+achlys 0.3.3
+acorn128 0.0.1
+active 7.11.0
+# Packages page 2
+aebytecode 2.1.0
+ae_enacl 0.17.4
+ae_enoise 1.0.1
+ae_erl_base58 0.0.3
+aequitas 1.3.0
+aeserialization 0.1.1
+agent 0.1.0
+# Packages page 3
+alcove 0.40.5
+aleppo 0.9.0
+alsa 0.2.3
+altworx_utils 0.0.5
+amf 0.1.4
+amqp10_client 3.12.0-rc.1
+amqp10_common 3.12.0-rc.1
+# Packages page 4
+amqp_client 3.11.13
+amqp_director 1.6.0
+amqp_filter 0.3.11
+anchor 0.3.1
+ansi 0.1.0
+antidotec_pb 0.2.9
+antidote_crdt 0.1.3
+antidote_pb_codec 0.1.2
+apdu 0.2.0
+apns4erl 2.5.0
+# Packages page 5
+aqlc 1.0.2
+argon2 1.0.2
+argparse 1.2.4
+ascii_table 1.1.6
+# Packages page 6
+astranaut 0.10.1
+ast_walk 0.3.1
+aten 0.5.8
+atom_utils 1.0.13
+atomvm_packbeam 0.6.0
+atomvm_rebar3_plugin 0.6.0
+augle 0.3.0
+# Packages page 7
+avlizer 0.4.0
+avm_scene 0.1.0
+aws_cli 0.1.0
+aws_credentials 0.1.11
+aws_erlang 1.0.1
+aws_http 0.2.4
+aws_signature 0.3.1
+b64fast 0.2.3
+b64_nif 0.1.4
+backoff 1.1.6
+backwater 3.5.0
+# Packages page 8
+baleen 1.0.3
+bank 0.2.2
+bare 0.1.1
+barista 0.3.2
+barrel_encoding 0.1.0
+barrel_ibrowse 4.3.1
+barrel_jiffy 0.14.5
+barrel_oauth 1.6.0
+barrel_unofficial 2.15.0
+base16 2.0.1
+base32 0.1.0
+base32_clockwork 2023.1.0
+base45 1.1.0
+base64url 1.0.1
+# Packages page 9
+basexerl 0.1.2
+basho_exometer_core 1.0.5
+basho_folsom 0.7.5
+basho_hamcrest 0.4.1
+basho_poolboy 0.8.4
+basho_stats 1.0.3
+batiscaph_probe 0.1.1
+bbmustache 1.12.2
+bcrypt 1.2.1
+beamoji 0.1.0
+beam_olympics 1.2.3
+beanstalkd_consumer 3.0.5
+bear 1.0.0
+behavior3 2.0.1
+behavior3erl 1.0.0
+bellboy 2.0.0
+# Packages page 10
+bencoding 1.0.0
+bert 0.2.1
+binbo 4.0.3
+binpp 1.1.1
+bitcask 2.0.2
+# Packages page 11
+bit_utils 1.0.7
+blas 1.0.0
+bloodbath 1.0.0
+blume 0.1.1
+# Packages page 12
+bookish_spork 0.5.2
+bootstrap 1.1.0
+boto 0.0.1
+bottomer 0.1.1
+bpe 8.12.1
+branca_erl 0.3.0
+# Packages page 13
+bristow 0.2.2
+brod 3.16.5
+brod_gssapi 0.1.0
+broen 3.0.2
+brotli 0.3.1
+browser_lang 0.1.0
+brucke 1.17.3
+brunhilde 2.0.1
+bson_erlang 0.3.1
+bstr 0.3.0
+bucs 1.1.0
+buffalo 2.1.0
+bugsnag_erl 1.1.6
+bugsnag_erlang 1.1.0
+# Packages page 14
+buoy 0.1.2
+busytone 1.0.0
+cache 2.3.3
+cache_pegb 1.0.1
+cache_service 0.1.0
+cache_tab 1.0.30
+canal 0.4.2
+canister 0.1.1
+# Packages page 15
+cargo 0.1.3
+# Packages page 16
+cerlc 0.2.1
+certifi 2.11.0
+cet 0.3.4
+cf 0.3.1
+cf_client 0.1.6
+cfg 17.12.26
+cf_worker 0.1.6
+cgolam 1.0.1
+cgroups 2.0.5
+channel 0.1.0
+chash 0.1.2
+chatterbox 0.8.0
+# Packages page 17
+choke 1.0.0
+chumak 1.4.0
+claws_fcm 0.1.0
+claws_kafka 0.4.1
+claws_rabbitmq 0.1.0
+claws_rest 0.1.0
+# Packages page 18
+clique 3.0.1
+clje_core_specs_alpha 0.2.56
+clje_spec_alpha 0.2.194
+clje_test_check 1.1.1
+clojerl 0.9.0
+cloudi_core 2.0.5
+cloudi_service_api_batch 2.0.5
+cloudi_service_api_requests 2.0.5
+cloudi_service_cron 2.0.5
+cloudi_service_db_http_elli 1.6.0
+cloudi_service_db_pgsql 2.0.5
+cloudi_service_filesystem 2.0.5
+cloudi_service_funnel 2.0.5
+cloudi_service_health_check 2.0.5
+cloudi_service_http_client 2.0.5
+cloudi_service_http_cowboy 2.0.5
+cloudi_service_http_cowboy1 2.0.5
+cloudi_service_http_elli 2.0.5
+cloudi_service_http_rest 2.0.5
+cloudi_service_map_reduce 2.0.5
+cloudi_service_monitoring 2.0.5
+cloudi_service_null 2.0.5
+cloudi_service_oauth1 2.0.5
+cloudi_service_queue 2.0.5
+cloudi_service_quorum 2.0.5
+cloudi_service_request_rate 2.0.5
+cloudi_service_router 2.0.5
+cloudi_service_send 2.0.5
+cloudi_service_shell 2.0.5
+cloudi_service_tcp 2.0.5
+cloudi_service_udp 2.0.5
+cloudi_service_validate 2.0.5
+cm17a 0.3.1
+cmd 1.0.0
+# Packages page 19
+code_utils 1.1.9
+coers 0.5.0
+coldstrap 0.1.0
+# Packages page 20
+complex_math 0.2.0-rc1
+concha 0.1.0
+concuerror 0.21.0
+conduit_amqp_client 3.6.2
+conduit_rabbit_common 2.7.1
+conf 0.2.6
+conferl 0.0.1
+# Packages page 21
+context 0.1.0
+couchbeam 1.4.2
+couchbeam_amuino 1.4.3-amuino.8
+couchdb 2.1.0-beta
+counters 0.2.1
+countries_erlang 0.5.0
+coveralls 2.2.0
+covertool 2.0.5
+cowbell 1.0.1
+cowboy 2.10.0
+cowboy_oauth 0.2.14
+# Packages page 22
+cowboy_session 1.0.0
+cowboy_swagger 2.5.1
+cowboy_telemetry 0.4.0
+cowlib 2.12.1
+cowmachine 1.10.3
+cpg 2.0.5
+cpool 0.1.1
+cps 0.4.0
+cqerl 2.1.0
+crc 0.10.4
+crc32cer 0.1.10
+cre 0.1.8
+credentials_obfuscation 3.4.0
+crypt 1.0.2
+# Packages page 23
+cryptoapis 1.7.0
+crypto_ext 0.1.4
+crypto_rsassa_pss 2.0.0
+csh2fjhyll_rdb 1.5.6
+csve 3.0.3
+csv_reader 1.0.0
+ctdh 1.0.1
+cth_readable 1.5.1
+cttest 6.0.11
+ctx 0.6.0
+cuckoo_cache 0.1.2
+cuckoo_filter 0.3.1
+cuneiform 3.0.4
+curry_erlang 0.1.0
+# Packages page 24
+customized_hdr_histogram 0.3.2
+cut 1.0.3
+cuttlefish 3.2.0
+damm 0.1.0
+darcy 0.0.8
+dasherl 0.2.15
+datalog 2.0.2
+datum 4.6.1
+# Packages page 25
+dbi 1.1.5
+dbi_mysql 0.1.1
+dbi_pgo 0.1.1
+dbi_pgsql 0.2.1
+dbi_sqlite 0.1.0
+dbschema 0.2.2
+dbus 0.8.0
+dbus_revived 0.8.0
+ddb_client 0.5.9
+ddb_connection 0.4.4
+debbie 1.0.5
+decorator_pt 1.0.3-alertlogic
+decorators 0.1.0
+deeperl 0.10.0
+deigma 1.2.0
+# Packages page 26
+denrei 0.2.5
+depcache 1.10.0
+dflow 0.3.0
+dhcp 1.0.0
+dhcp_lib 1.0.0
+dh_date 1.0.0
+diffy 1.1.2
+digraph_export 1.0.1
+digraph_viewer 0.1.0
+diint_utilites_common_app 1.4.23
+dinerl 1.3.9
+director 18.9.30
+dirent 1.0.5
+# Packages page 27
+discourse_as_sso_erlang 0.7.0
+dispatch_compiler 1.1.0
+dj 0.3.0
+dns_erlang 1.1.0
+do 1.10.2
+docker_compose_cth 0.3.0
+docsh 0.7.2
+doctest_pg 1.2.3
+# Packages page 28
+dogstatsc 0.1.0
+dogstatsde 1.0.0
+doppler 0.1.0
+dorer 0.1.0
+doteki 1.1.0
+dp_decoder 0.2.17
+dproto 0.5.6
+dqe 0.4.15
+dqe_fun 0.2.1
+dqe_idx 0.4.4
+dqe_idx_ddb 0.5.2
+dqe_idx_pg 0.5.7
+# Packages page 29
+dtl 0.12.1
+dtrans 1.2.0
+dtu 0.1.3
+duoweb 1.0.0
+e2qc 1.2.1
+eaglesong 1.0.0
+eauthor 17.12.30
+eavmlib 0.1.0
+eavro 0.0.5
+ebase32 1.0.1-2.86707d9
+ebase58 1.0.0-3.0c1b609
+ebeanstalkd 2.2.1
+ebils 0.1.1
+ebitmap 0.2.3
+eblake2 1.0.0
+eblurhash 1.2.2
+ebpf 0.2.3
+ebs 2.1.0
+ecaptcha 0.2.0
+ecat 1.0.0
+ecc_compact 1.1.1
+echc 0.1.0
+# Packages page 30
+ecimd2 0.0.8
+ecoap 0.1.0
+ecomm 1.0.2
+econfig 0.7.3
+ecpool 0.4.2
+ecql 5.1.3
+ecron 0.6.1
+ecrontab 0.6.1
+ecsv 1.4.2
+# Packages page 31
+# Packages page 32
+ecureuil 1.0.2
+edate 1.0.0
+edbg 0.1.4
+edgar 1.0.2
+ediff 1.0.0
+edis_proto 0.2.0
+edocmermaid 0.1.0
+edown 0.8.4
+educkdb 0.6.0
+eenv 0.1.1
+eesql 0.4.19
+eetcd 0.4.0
+efene 0.99.2
+effi 0.1.6
+efgrep 1.0.0
+efirebirdsql 0.9.3
+eflambe 0.3.1
+efluentc 0.2.0
+efranc 0.0.1
+efrisby 0.2.0
+efuse 1.0.2
+efuse_filter 0.1.0
+egcache 0.1.0
+egeonames 0.1.1
+egetopt 1.2.0
+egithub 0.7.0
+egoc 0.1.1
+egoth 0.1.0
+egssapi 0.1.0
+ehash 0.2.1
+ehashids 0.1.4
+eiconv 1.0.0
+eimp 1.0.22
+eini 1.2.9
+eini_beam 2.2.3
+eipmi 4.0.0
+ejabberd 23.4.0
+ejpet 0.8.0
+ejsonpath 0.2.1
+ejwt 0.1.0
+# Packages page 33
+ekka 0.7.4
+elab 0.1.0
+elb 1.0.1
+eld 1.0.0-beta1
+elector 0.2.2
+eleveldb 2.2.20
+elib 0.0.1
+elibphonenumber 8.13.10
+# Packages page 34
+elli 3.3.0
+elli_basicauth 0.1.0
+elli_cache 1.0.1
+elli_cloudfront 0.3.3
+elli_cookie 0.3.0
+elli_date 1.1.1
+elli_json 0.1.0
+elli_log_exceptions 0.1.0
+elli_otter 0.2.0
+elli_prometheus 0.2.0
+elli_swagger 0.4.1
+elli_websocket 0.1.1
+elli_ws_undertone 0.1.2
+elli_xpblfe 0.2.3
+elmdb 0.4.1
+elocaltime 1.4.1
+elogsene_logger 1.0.0
+elogstash 1.0.0
+elogx 0.0.2
+# Packages page 35
+elru 1.1.0
+elvis 1.1.0
+elvis_core 3.0.0
+em 7.3.0
+email_validator 1.1.0
+emarkdown 0.1.0
+emeter 18.6.13
+eministat 0.10.1
+emmap 2.0.11
+emo 0.3.1
+emodel 1.6.0
+emojipoo 0.1.0
+emon 0.2.1
+emqtt 1.2.1
+emqx_ct_helpers 1.1.4
+emv 0.7.0
+emysql 0.4.1
+emysql_orm 0.0.1
+enacl 1.2.1
+enanoid 0.1.0
+encoding_utils 1.0.7
+eneo4j 1.0.0
+enoise 1.1.0
+enough 0.1.0
+ensq 0.1.7
+entropy_string_erl 1.1.1
+# Packages page 36
+eodbc 0.2.0
+ep 0.2.0
+epam 1.0.14
+epcap_compile 1.0.5
+eper 0.99.1
+epgpool 1.1.1
+epgsql 4.7.0
+epgsql_decimal 1.0.0
+ephemeral 2.0.4
+ephp 0.3.1
+epipe 1.0.0
+epl 0.2.0
+epmdless 0.3.0
+epmdlib 1.0.0
+epns 1.1.0
+epocxy 1.1.0
+epqueue 1.2.5
+epsql 0.1.0
+epubnub 0.1.0
+eql 0.2.0
+equery 0.16.0
+eradius 2.3.1
+erbloom 2.1.0-rc.2
+erc 0.1.1
+eredis 1.7.0
+eredis_cluster 0.9.0
+eredis_pool 2.0.1
+eredis_streams 0.1.0
+eredis_sync 0.1.4
+ereturn 18.6.14
+ergb 0.2.8
+erlando 3.1.1
+erlang_base62 1.0.1
+erlang_behaviour_trees 0.5.22
+erlang_color 1.0.0
+erlang_commons 0.1.0
+erlang_dbus 0.2.0
+erlang_decimal 0.6.2
+erlang_decorators 0.3.1
+erlang_doctor 0.1.0
+erlang_exif 3.0.0
+erlang_json_logger 0.2.0
+erlang_localtime 1.0.0
+erlang_osc 1.0.1
+erlang_pmp 0.1.1
+erlang_psq 1.0.0
+erlang_rethinkdb 0.2.2
+erlang_skiplist 0.3.0
+erlang_svg 0.2.0
+erlang_tc 0.1.0
+erlang_term 2.0.5
+erlang_tls 1.0.3
+erlang_version 0.2.0
+erlang_xxhash 0.2.0
+erlangzmq 1.1.2
+erlastic_search 1.5.0
+erlaudio 0.2.3
+erlavro 2.9.8
+erl_base58 0.0.1
+erl_bencode 1.0.2
+erlbus 0.3.0
+erl_cache 1.7.6
+erlcaptcha 2.0.0
+erlcard 1.1.1
+erlcass 4.1.0
+erl_cbor 2.0.1
+erlchronos 2.0.1
+erl_cidr 1.2.0
+erlcloud 3.6.8
+erlcode 0.1.0
+erlcron 1.2.3
+# Packages page 37
+erl_csv 0.3.1
+erldb 1.0.0
+erldn 1.0.6
+erldns 1.0.0
+erldocs 0.9.6
+erldocs_other 0.9.6
+erldrasil 0.1.0
+erldyn 0.7.2
+erlesy 1.0.3
+erl_eval_records 1.0.0
+erlexec 2.0.2
+erl_exercism 0.1.2
+erlffx 1.2.0
+erlflake 0.1.1
+erlflow 0.1.0
+erlfmt 1.2.0
+erlguten 1.0.0
+erl_hash 1.0.5
+erliam 1.0.1
+erlias 0.1.0
+erljson 0.2.1
+erljwt 2.0.7
+erlkaf 2.1.3
+erllambda 2.2.3
+erlmemfs 0.1.0
+erlmld 1.1.1
+erl_nbt 1.0.0
+erlogger 0.1.0
+erlpass 1.0.5
+erlPass 0.3.0
+erl_pengine 0.1.1
+erlperf 2.2.0
+erl_pipeline 0.2.0
+erlpocket 2.1.0
+erlpool 1.4.3
+erlpop 2.3.1
+erlport 0.10.1
+erlquad 1.1.2
+erlquery 0.4.0
+erlsass 1.1.1
+erlsci_getopt 0.8.4
+erlscrypt 1.2.2
+erl_snowflake 1.1.0
+erlsom 1.5.1
+erl_tcp 0.1.1
+erlte 0.1.0
+erltls 1.4.2
+erl_tools 0.0.1
+erltrace 0.1.6
+erluap 1.2.3
+erluca 0.1.1
+erlup 0.3.0
+erlware_commons 1.6.0
+erlwater 0.1.6
+erl_web_push 0.1.0
+erlxml 1.0.3-beta
+erl_xxhash 0.2.0
+erlydtl 0.14.0
+erlydtl2 0.11.1
+erlyfix 0.1.0
+erlz 0.1.0
+erlzk 0.6.4
+erlzk_pd 0.6.4
+erlzmq 3.0.1
+erlzmq_dnif 4.1.3
+erlzord 1.1.0
+erocksdb 0.4.1
+erpcgen 1.1.1
+erqwest 0.2.4
+errors 0.1.0
+ersip 1.1.0
+erwatch 0.3.0
+esaml 4.5.0
+escalus 4.2.9
+esel 0.1.2
+esimdjson 0.1.0
+esip 1.0.49
+esmpp 0.0.13
+esnowflake 0.4.3
+esockd 5.8.2
+# Packages page 38
+espace 0.8.0
+esq 2.0.6
+esqlcipher 2.0.0-rc.3
+esqlite 0.8.6
+esss 1.0.2
+estdinout 1.0.0
+estore 0.1.10
+etcdc 0.3.1
+etcp 17.9.10
+etest 1.2.1
+etest_http 1.0.2
+etls 1.2.0
+etoml 0.1.0
+etotp 1.0.1-6.c979c63
+etr 1.0.0
+etran 0.5.0
+ets_cas 0.1.1
+etsmgr 0.2.0
+eunicode2gsm 1.1.0
+euniq 1.0.0
+eunit_addons 1.2.0
+eunit_formatters 0.5.0
+eunit_helper 0.0.4
+eunit_sugar 0.1.0
+eunzip 1.0.0
+euri 0.11.0
+evaluator 0.1.3
+evel 0.1.2
+# Packages page 39
+event_store_db_gpb_protobufs 2.3.0
+evews 0.1.9
+evision 0.1.31
+ewc 1.0.0
+ewpcap 1.1.4
+exat 0.1.0
+# Packages page 40
+# Packages page 41
+# Packages page 42
+# Packages page 43
+exe 7.11.0
+exec 1.0.1
+exemplar 0.5.0-rc1
+# Packages page 44
+# Packages page 45
+# Packages page 46
+exodus 0.1.0
+exodus_mysql 0.1.0
+exodus_postgres 0.1.0
+exodus_sqlite3 0.1.0
+exometer_core 1.6.2
+exometer_fetch 0.1.0
+exometer_influxdb 0.6.0
+exometer_report_graphite 1.0.1
+exometer_report_lager 1.0.0
+exor_filter 0.8.2
+# Packages page 47
+# Packages page 48
+# Packages page 49
+# Packages page 50
+# Packages page 51
+ezic 0.2.3
+ezlib 1.0.12
+ezmq 0.2.0
+ezstd 1.0.8
+# Packages page 52
+fake_lager 1.0.0
+fake_turn 0.4.0
+fast_base16 1.1.1
+fast_pbkdf2 1.0.3
+fast_scram 0.5.0
+fast_tls 1.1.16
+fast_xml 1.1.49
+fast_yaml 1.0.36
+fcm 0.1.0
+feeder 2.3.2
+fernet 0.1.0
+# Packages page 53
+fieldmask 0.0.1
+fifocache 1.0.1
+fifo_db 0.2.8
+fifo_dt 0.2.26
+fifo_lager 0.1.8
+fifo_s3 0.2.15
+fifo_spec 0.1.34
+fifo_utils 0.1.53
+file_signatures 0.1.9
+filezcache 1.1.0
+fire 0.1.4
+firebase_admin 0.1.3
+firebase_token 1.1.1
+# Packages page 54
+fixer 0.2.4
+flatlog 0.1.2
+fling 1.0.1
+fn 1.0.0
+# Packages page 55
+foil 0.1.3
+folsom 1.0.0
+folsom_ddb 0.3.1
+folsomite 1.3.0
+form 8.3.0
+forms 0.0.1
+forseti 2.2.0
+freshman_test 0.2.1
+fs 8.6.1
+fs_event 1.0.0
+fs_sync 1.1.3
+fswitch 1.4.1
+ftpfilez 1.3.0
+# Packages page 56
+fusco 0.1.1
+fuse 2.5.0
+gdminus 1.2.0
+geas 2.7.12
+geas_rebar3 1.4.12
+# Packages page 57
+geminic 0.1.0
+gen_batch_server 0.8.8
+gen_cycle 1.0.4
+gen_errand 0.0.1
+gen_flow 0.0.5
+gen_fsm_compat 0.3.0
+gen_fw 18.6.2
+gen_icmp 0.5.6
+gen_ircclient 0.1.1
+gen_leader 0.1.0
+gen_logger 1.2.1
+gen_nbs 0.7.7
+gen_pnet 0.1.7
+gen_rest_client 17.12.24
+gen_rpc 2.1.0
+gen_smtp 1.2.0
+gen_smtp_temp_fix_ssl 0.14.0
+# Packages page 58
+geocoding 0.3.1
+geo_gateway 0.2.0
+geolite2data 1.0.0
+getopt 1.0.2
+gettexter 0.0.7
+ghatest 0.10.0
+gisla 2.1.1
+# Packages page 59
+giza 0.0.1
+gj 0.1.0
+gleam_beam 0.1.0
+gleam_codec 0.2.0
+gleam_decode 1.7.0
+gleam_experimental_stdlib 0.8.0
+gleam_file 0.1.0
+gleam_jsone 0.5.0
+gleam_sentry 0.1.1
+gleam_should_assertions 0.1.0
+gleam_string_builder 0.1.0
+gleam_uuid 0.1.1
+gleam_validator 0.2.0
+glob 1.0.0
+global_flags 1.0.0
+# Packages page 60
+gmo_pg 0.0.1
+goldrush 0.1.9
+# Packages page 61
+# Packages page 62
+# Packages page 63
+google_token 1.0.5
+gpb 4.19.7
+gpio 0.6.3
+gproc 0.9.0
+gradualizer 0.2.0
+granderl 0.1.5
+graphiter 1.0.6
+graphql_erl 0.16.1
+graphql_erlang 0.2.10
+graylog_lager 1.4.5
+grid 0.2.1
+# Packages page 64
+grisp 2.3.0
+grisp_cryptoauth 2.0.1
+grisp_emulation 0.2.0
+grisp_tools 2.5.0
+grpcbox 0.16.0
+grpcbox_plugin 0.9.0
+grpc_cowlib 2.8.1
+grpc_gun 2.0.1
+grpc_lib 0.1.2
+gruff 0.1.0
+gsm_coder 1.0.2
+gtplib 3.2.0
+gun 2.0.1
+gurka 0.1.8
+gustav 0.1.8
+h1 2.3.0
+h3 3.6.4
+hacker_news 0.0.3
+hackney 1.18.1
+hackney_telemetry 0.1.1
+hairnet 1.0.0
+haki 0.3.2
+# Packages page 65
+hamcrest 0.1.3
+haproxy_protocol 0.1.2
+harness_erlang_murmurhash 1.0.0
+harness_ff_erlang_client_api 1.0.0
+harness_ff_erlang_server_sdk 1.0.0
+hasaki_emysql 0.5.1
+hashids_erlang 1.0.5
+hash_ring 0.4.2
+havoc 0.2.3
+hdr_histogram 0.5.0
+# Packages page 66
+heja 0.1.4
+helium 0.1.0
+hello_erl 0.1.2
+heroku_crashdumps 0.1.0
+hex2bin 1.0.0
+hex_core 0.10.0
+hexml 3.3.3
+hkdf_erlang 1.0.0
+hlc 3.0.1
+# Packages page 67
+hoax 0.11.2
+holiday_jp_clje 0.1.1
+homotopy 1.3.1
+hooks 2.1.0
+horatio 0.2.0-rc1
+horus 0.2.3
+host_triple 0.1.0
+hotp 1.0.2
+hpack_erl 0.2.3
+hterl 0.10.0
+htmerl 0.1.0
+htnerlang 0.1.0
+hts 1.3.1
+httpb 0.4.2
+http_cache 0.2.0
+http_cache_store_disk 0.2.0
+http_cache_store_native 0.2.0
+httpc_aws 0.4.2
+# Packages page 68
+http_signature 2.0.0
+hut 1.4.0
+hydro 0.5.0
+hyper 1.0.1
+iam 0.0.1
+iban 0.7.0
+# Packages page 69
+ibrowse 4.4.1
+iconv 1.0.13
+idl 1.0.1
+idna 6.1.1
+idris2 0.2.1-alpha.1
+ierl 0.4.0
+imap_utf7 1.0.0
+inaka_aleppo 1.1.1
+inaka_emysql 0.5.0
+inaka_iso8601 1.1.2
+inaka_mixer 1.2.0
+# Packages page 70
+inert 1.0.4
+inet_ext 1.0.0
+influxdb 0.2.1
+influx_udp 1.1.2
+inotify 0.4.3
+intercept 1.0.0
+interval_tree_clocks 1.0.1
+# Packages page 71
+ip2locationdata 0.0.5
+ip2region_erlang 0.1.0
+ipaddr 0.1.0
+ipinfo 1.0.1
+iptables 0.1.6
+irc_parser 0.1.0
+is_auto_imported_bif 17.8.24
+ishikawa 0.0.3
+iso8583_erl 0.2.0
+iso8601 1.3.3
+# Packages page 72
+iso_erlang 0.11.0
+istype 0.2.3
+itc 0.4.0
+jaeger_passage 0.1.14
+jam 1.0.0
+jason_erl 1.2.2
+jaws3 0.1.1
+jb_private123 0.1.0
+jc 1.2.1
+jch 0.2.3
+jchash 0.1.3
+jesse 1.7.11
+jhn_stdlib 3.6.2
+jiffy 1.1.1
+# Packages page 73
+jobs 0.10.0
+jose 1.11.5
+jpparse 1.3.1
+jsn 2.2.2
+jsone 1.8.0
+jsonlog 0.1.0
+jsx 3.1.0
+jsxd 0.2.4
+jsxrecord 1.2.0
+# Packages page 74
+jun 0.2.6
+jupyter 0.5.0
+justatimer 0.1.2
+jwalk 1.2.0
+jwerl 1.2.0
+jwt 0.1.11
+k6_bytea 1.1.5
+kaa 0.2.26
+kafe 2.2.3
+kafka_protocol 4.1.3
+kafkerl 2.1.0
+kanin 0.6.0
+kashe 1.0.1
+katana 1.0.0
+katana_code 2.0.1
+katana_test 1.0.1
+katipo 1.1.0
+katja 0.10.0
+katja_echo 0.1.1
+katja_vmstats 0.8.2
+katt 1.6.9
+kdtree 1.0.0
+keccak 2.0.0
+# Packages page 75
+keccakf1600 3.0.0
+keccakf1600_diode_fork 2.1.2
+keccakf1600_nash_fork 2.1.2
+keccakf1600_orig 2.1.0
+keccakf1600_otp23 2.0.0
+ken 0.1.1
+kerlberos 2.0.1
+key2value 2.0.5
+keys1value 2.0.5
+keyserver 1.0.0
+kflow 1.1.0
+khepri 0.7.0
+kinetic 1.3.11
+kivra_merlin 2.1.0
+kla 0.8.0-rc4
+# Packages page 76
+kraft 0.1.0
+kube_dist 0.0.2
+kuberl 0.2.0
+kvconf 2023.1.0
+kv_index_tictactree 0.9.4
+kylie 1.0.1
+kyu 2.0.4
+lager 3.9.2
+lager2json 1.0.2
+lager_cloudwatch 0.1.2
+lager_exometer_backend 0.1.0
+lager_folsom 1.0.1
+lager_graylog 1.1.0
+lager_hipchat 0.2.1
+lager_html 0.0.1
+lager_humio_backend 1.3.5
+lager_iowrite_formatter 1.0.0
+lager_json_formatter 0.2.4
+lager_logentries 0.1.0
+lager_logstash 0.1.2
+lager_logstash_backend 0.1.3
+lager_logtail 0.2.0
+lake 0.2.1
+lambda 0.1.1
+lambda_throttle 0.3.0
+lanes 0.1.3
+lanes_barista 0.1.0
+lanes_elli 0.1.3
+# Packages page 77
+lasp 0.10.0
+lasp_bench 0.0.1
+lasp_pb 0.0.4
+lasp_pg 0.1.0
+lasp_support 0.1.0
+launchdarkly_server_sdk 2.0.1
+lazy 0.0.1
+lazy_lists 0.1.0
+lb 17.6.12
+lbm_kv 0.0.2
+lc 0.3.2
+lcfg 0.5.0-rc3
+ldb 0.0.18
+ledis 0.3.0
+lee 0.1.0
+lejson 0.8.0
+levaindoc 0.7.0
+leveled 0.9.4
+lfe 2.1.1
+lfe_machine_tv 3.0.1
+lhttpc 1.6.2
+libchunter 0.1.52
+# Packages page 78
+lib_combin 0.1.5
+lib_conf 0.1.5
+libdecaf 2.1.1
+libdecaf_amend 0.0.1
+lib_dp 0.1.0
+libhowl 0.1.42
+libleofs 0.1.3
+libp2p_crypto 1.4.1
+libp2p_peerbook 0.2.0
+lib_parallel 0.1.1
+libphonenumber_erlang 0.2.0
+libsecp256k1 0.1.10
+libsecp256k1_diode_fork 0.1.14
+libsecp256k1_luisguilhermemsalmeida_fork 0.1.14
+libsecp256k1_nash_fork 0.1.14
+libsecp256k1_nif 0.0.3
+libsnarl 0.3.55
+libsnarlmatch 0.1.8
+libsniffle 0.3.71
+libsodium 2.0.1
+libvxe_erl 0.1.0
+# Packages page 79
+ljson 0.6.0-rc1
+lldp 0.1.0
+llists 1.2.0
+local 0.2.1
+locker 1.0.8
+locks 0.2.0
+locus 2.3.6
+logflare_erl 0.2.0
+logger_colorful 0.1.0
+# Packages page 80
+logger_formatter_json 0.7.0
+logger_journald 0.3.0
+logger_logstash 0.1.3
+logger_webhook_h 1.1.0
+logi 0.5.6
+logi_prometheus 0.1.2
+logi_stdlib 0.1.2
+logjam 1.0.5
+logstasher 1.0.0
+loise 1.3.0-rc5
+lpr 0.1.2
+lric 0.3.0
+lru 2.4.0
+lrw 2.0.1
+ltest 0.13.3
+luaport 1.6.2
+luerl 1.0.0
+# Packages page 81
+lutil 0.13.1
+lxml 0.3.0
+lz4 0.2.4
+lz4b 0.0.9
+lz4_erl 0.2.4
+m3u8 0.2.1
+mach 4.7.0
+mad 7.1.1
+maildir_commander 0.6.5
+# Packages page 82
+mapsd 0.2.0
+map_sets 1.1.0
+maps_in 0.2.0
+maputils 0.4.1
+mapz 2.3.0
+markerl 0.1.0
+# Packages page 83
+match_trie 0.1.0
+mbcs 1.1.1
+mcache 0.3.1
+mc_dactyl 1.0.1
+mc_eredis 2.6.2
+mc_gen_rpc 3.0.1
+mc_lhttpc 4.3.1
+mc_mustache 1.0.1
+mc_pbkdf2 2.2.1
+mc_poolgirl 2.2.1
+mc_sbroker 1.1.1
+mc_small_ints 1.1.1
+mc_vsn_transform 1.1.1
+md2 1.2.0
+# Packages page 84
+mdns_client 0.1.10
+mdns_client_lib 0.1.46
+mdns_server 0.2.0
+mdns_server_lib 0.2.3
+meck 0.9.2
+medoc 1.0.0
+mekao 0.4.3
+# Packages page 85
+memhash 0.1.0
+memstore 0.2.3
+merkerl 1.1.1
+merklet 2.0.0
+merkletree 0.1.0
+mero 1.4.4
+meta 0.1.3
+# Packages page 86
+metal 0.1.1
+metrics 2.5.0
+metrics_reader 0.1.13
+metronome 0.0.2
+mgmepi 0.9.0
+m_http 0.2.2
+midas 0.2.0
+midilib 0.5.0-rc2
+miffy 2.0.0
+milenage 0.2.0
+mime_lookup 0.1.1
+mimerl 1.2.0
+mimetypes 1.1.0
+minikube 1.0.0
+minmay 1.2.0
+# Packages page 87
+mls 0.1.4
+mmath 0.2.26
+mnesplit 0.0.1
+# Packages page 88
+mochicow 0.6.4
+mochiweb 3.1.2
+mochiweb_html 2.15.0
+mochiweb_util 0.1.0
+mockgyver 1.6.0
+mongodb_client 3.2.0
+mongodb_erlang 3.4.0
+mongoose_jid 2.0.0
+# Packages page 89
+mpgit 0.1.1
+mqtree 1.0.15
+mqtt 0.3.3
+mqtt_client 1.0.5
+mqtt_packet_map 1.1.0
+mqtt_sessions 2.1.0
+msgpack 0.7.0
+msgpack_rpc_erlang 0.6.4
+msrpce 0.1.1
+mstore 0.3.7
+mstore_inspector 0.1.1
+mtproto_proxy 0.7.1
+mtxmkt 0.1.0
+multiaddr 1.1.3
+multihash 2.1.0
+# Packages page 90
+mybench 0.0.0
+my_cargo 0.1.3-rc.1
+myesockd 5.9.4
+my_esockd 5.9.4
+mylib 0.1.1
+myproto 0.3.2
+my_rebar3_cargo 0.1.1-rc.1
+myriad 1.0.15
+mysql 1.8.0
+mysql_client 1.2.8
+n2o 10.3.3
+nat 0.4.0
+natserl 0.1.3
+nats_msg 0.4.1
+nat_upnp 0.1.0
+nconf 0.0.1
+nd_index 1.7.1
+ndisc_redis 0.0.4
+nebula 0.1.1
+# Packages page 91
+neo4j 0.3.0
+# Packages page 92
+nested 0.1.2
+netcdf_nif 0.1.2
+netflow 1.0.0
+netlink 1.1.0
+newrelic 0.1.0
+# Packages page 93
+nextroll_erlcloud 3.4.1
+nextroll_lhttpc 1.4.0
+nextroll_rebar3_gpb_plugin 3.0.0
+nextroll_zstd 1.1.0
+niffler 0.3.0
+nifi_s2s 0.0.2
+nif_libsecp256k1 0.0.2
+nitro 8.2.4
+nitro_cache 0.4.1
+nitrogen_core 2.4.0
+nkferl 0.1.2
+nlocks 1.1.2
+noble 0.0.4
+nodefinder 2.0.5
+noise 0.0.5
+nopmd 0.1.0
+# Packages page 94
+nova 0.9.5
+nova_modern 0.1.3
+nprocreg 0.3.0
+nuntius 0.0.3
+oauth 2.1.0
+oauth2c 1.0.1
+oauth2_erlang 0.6.1
+observer_cli 1.7.4
+oc_datadog 0.2.0
+oc_google_reporter 0.4.0
+# Packages page 95
+odi 0.1.0
+oidcc 2.0.0-alpha.2
+oidcc_cowboy 1.5.0
+ojson 1.0.0
+oox 0.1.27
+# Packages page 96
+opcua 0.1.0
+opencensus 0.9.3
+opencensus_cowboy 0.3.0
+opencensus_elli 0.4.0
+opencensus_erlang_prometheus 0.3.2
+opencensus_jaeger 0.0.1
+opencensus_service 0.1.0
+opencensus_telemetry 0.1.0
+opencensus_zipkin 0.3.0
+openroad 1.0.0
+opentelemetry 1.3.0
+opentelemetry_api 1.2.1
+opentelemetry_api_experimental 0.3.0
+opentelemetry_cowboy 0.2.1
+opentelemetry_elli 0.2.0
+opentelemetry_experimental 0.3.0
+opentelemetry_exporter 1.4.1
+opentelemetry_grpcbox 0.2.0
+opentelemetry_logger_metadata 0.1.0
+opentelemetry_logger_metadata_datadog 0.1.0
+opentelemetry_process_propagator 0.2.2
+opentelemetry_semantic_conventions 0.2.0
+opentelemetry_telemetry 1.0.0
+opentelemetry_zipkin 1.1.1
+# Packages page 97
+optic 3.1.0
+osc_lib 2.1.1
+osc_server 2.1.1
+otc 1.0.0
+otel_propagator_instana 1.1.0
+otpcl 0.2.0
+otp_passage 0.1.10
+otp_vsn 2.11.0
+otter 0.4.0
+otter_lib 0.1.1
+otters 0.2.10
+otter_srv 0.1.0
+overworld 1.0.0
+ovsdb 0.3.0
+owoify_erl 1.0.0
+p1_acme 1.0.22
+p1_mysql 1.0.21
+p1_oauth2 0.6.11
+p1_pgsql 1.1.22
+p1_stringprep 1.0.1
+p1_utils 1.0.25
+p1_xml 1.1.1
+p1_xmlrpc 1.15.1
+# Packages page 98
+paillier 1.0.0
+parse_trans 3.4.1
+parsexml 1.0.0
+parthenon 0.8.0
+partial 1.2.0
+# Packages page 99
+partisan 5.0.0-beta.24
+passage 0.2.6
+pbkdf2 2.0.0
+pbkdf2_nif 0.4.0
+pc 1.14.0
+pcsc 1.3.1
+pd_erlzk 0.6.4
+pe4kin 0.2.2
+perc 1.0.1
+# Packages page 100
+pest 0.9.0
+pfcplib 3.0.0
+pgapp 0.0.2
+pgo 0.14.0
+pgpool 2.1.0
+pgsql 26.0.2
+pg_types 0.4.0
+# Packages page 101
+# Packages page 102
+phpass 0.1.0
+picosat 0.1.0
+pipe_line 1.0.0
+# Packages page 103
+pipes 2.0.1
+pkix 1.0.9
+pkt 0.6.0
+pl 18.1.31
+plain_fsm 1.4.2
+plists 1.1.1
+# Packages page 104
+plugerl 1.0.0
+# Packages page 105
+plumtree 0.6.0
+pmbag 1.0.0
+pmod_transform 1.1.0
+png 0.2.1
+pobox 1.2.0
+poolboy 1.5.2
+pooler 1.6.0
+poolgirl 1.3.0
+# Packages page 106
+pop3client 1.3.1
+positive 13.3.7
+posthaste 18.10.14
+postman_smtp 0.0.1
+postman_transport 1.0.0
+pot 1.0.2
+power_shell 1.2.2
+ppg 0.1.3
+ppool 1.1.1
+ppplib 1.0.0
+pp_record 0.1.3
+pqclean 0.0.3
+pqueue 2.0.5
+# Packages page 107
+pretty_print 0.1.0
+priq 0.2.0
+proc 1.1.2
+process_group 1.1.3
+procket 0.9.7
+proj_nif 0.1.4
+prometheus 4.10.0
+prometheus_cowboy 0.1.8
+prometheus_diameter_collector 1.2.1
+prometheus_httpd 2.1.11
+prometheus_process_collector 1.6.0
+promexp 0.4.3
+proper 1.4.0
+proper_contrib 0.3.2
+protobuffs 0.8.4
+# Packages page 108
+protofy_test 1.0.0
+provider_asn1 0.3.0
+providers 1.9.0
+prx 0.16.3
+pulserl 0.1.3
+pure_migrations 1.3.0
+pushover_error_logger 0.1.0
+pynchon 0.5.0
+qdate 0.7.0
+qdate_localtime 1.2.1
+# Packages page 109
+qsp 0.1.0
+quantile_estimator 0.2.1
+quicer 0.0.17
+quickrand 2.0.5
+quintana 0.2.2
+ra 2.5.1
+raabta 0.1.0
+rabbit_common 3.12.0-rc.1
+radius 0.0.13
+# Packages page 110
+ram 0.5.0
+ranch 2.1.0
+ranch_proxy_protocol 2.1.1
+rand_compat 0.0.3
+rand_str 1.0.1
+rankmatcher 0.1.6
+raterl 0.3.1
+rationals 0.2.0
+raven_erlang 0.4.3
+raw_sqlite3 1.0.9
+# Packages page 111
+rcl_bench 0.1.0
+rcl_test 0.2.0
+re2 1.9.8
+realpath 1.3.6
+rebar3_abnf_compiler 0.1.3
+rebar3_applications_plugin 1.0.1
+rebar3_appup_plugin 2.4.4
+rebar3_archive_plugin 0.0.2
+rebar3_asn1_compiler 1.0.0
+rebar3_auto 0.3.3
+rebar3_auto_applications 1.0.0
+rebar3_autotdd 1.1.0
+rebar3_autotest 0.1.1
+rebar3_bench 0.2.2
+rebar3_bitbake 0.1.0
+rebar3_bump 0.1.1
+rebar3_cargo 0.1.1
+rebar3_check_app_calls 0.1.0
+rebar3_check_deps 0.1.0
+rebar3_clojerl 0.8.8
+rebar3_cobertura 0.3.1
+rebar3_codecov 0.4.0
+rebar3_cuttlefish 0.16.0
+rebar3_deb 0.1.1
+rebar3_depup 0.3.1
+rebar3_dialyzer_html 0.3.0
+rebar3_diameter_compiler 0.8.0
+rebar3_docker 0.1.0
+rebar3_docs 0.2.1
+rebar3_edata_plugin 0.1.11
+rebar3_edoc_extensions 1.6.0
+rebar3_eep48 0.1.0
+rebar3_eetcd_plugin 0.3.2
+rebar3_efene 0.1.1
+rebar3_efene_compile 0.2.0
+rebar3_efene_ct 0.1.2
+rebar3_efene_shell 0.1.2
+rebar3_efmt 0.14.1
+rebar3_elixir 0.2.4
+rebar3_elixirc 0.1.0
+rebar3_elixir_compile 1.1.0
+rebar3_elixir_plugin 2.0.0
+rebar3_elvis_plugin 0.0.4
+rebar3_eqc 1.3.0
+# Packages page 112
+rebar3_erlesy 1.0.0
+rebar3_erllambda 1.1.2
+rebar3_erlquery 0.2.2
+rebar3_erlydtl_plugin 0.1.1
+rebar3_ex_doc 0.2.16
+rebar3_external 0.1.0
+rebar3_fmt 1.18.0
+rebar3_format 1.2.1
+rebar3_git_vsn 1.1.1
+rebar3_gpb_plugin 2.22.1
+rebar3_gpb_rpc_plugin 1.3.1
+rebar3_grisp 2.5.0
+rebar3_hank 1.3.0
+rebar3_hex 7.0.6
+rebar3_hterl 0.2.0
+rebar3_idl_compiler 0.5.0
+rebar3_jorel 0.0.1
+rebar3_lfe 0.4.3
+rebar3_lfe_clean 0.4.0-rc2
+rebar3_lfe_compile 0.8.0-rc3
+rebar3_lfe_test 0.4.0-rc4
+rebar3_lfe_version 0.5.0-rc2
+rebar3_lint 3.0.0
+rebar3_local_deps 0.1.2
+rebar3_neotoma_plugin 0.2.0
+rebar3_nova 0.3.4
+rebar3_path_deps 0.4.0
+rebar3_project_utils 0.1.0
+rebar3_proper 0.12.1
+rebar3_protobuffs 0.2.0
+rebar3_proto_plugin 0.1.11
+rebar3_raw_deps 2.0.0
+rebar3_reloader 0.2.0
+rebar3_run 0.4.0
+rebar3_rustler 0.1.1
+rebar3_sbom 0.6.1
+rebar3_scuttler 0.4.1
+rebar3_sheldon 0.4.2
+rebar3_shellcheck 1.0.1
+rebar3_shellrpc 0.1.0
+rebar3_static_deps 2021.1.0
+rebar3_tailwind 1.0.3
+rebar3_tsung 0.1.4
+rebar3_typer 0.0.1
+rebar3_undertone 0.1.0-rc1
+rebar3_vendor 0.4.0
+rebar3_yang_plugin 0.2.1
+rebar3_zig 2022.1.0
+rebar_alias 0.2.0
+rebar_cmd 0.4.0
+rebar_covertool 1.3.0
+rebar_edown_plugin 0.7.0
+rebar_eqc 0.1.0
+rebar_erl_vsn 0.2.2
+rebar_gleam 0.2.0
+rebar_mix 0.5.1
+rebar_protobuffs 0.1.0
+rebar_prv_mlfe 0.3.0
+rebar_raw_resource 0.10.0
+recompile 0.1.0
+recon 2.5.3
+recordset 0.1.0
+redbug 2.0.9
+# Packages page 113
+redis_global 0.0.8
+reg 0.1.0
+regine 1.1.0
+regis 1.0.0
+rekt 0.1.0
+relflow 1.0.6
+relsync 0.1.1
+relsyncd 0.1.2
+relsync_lib 0.1.1
+reltool_util 2.0.5
+relx 4.7.0
+replayq 0.3.7
+# Packages page 114
+repo 0.7.2
+rest 6.11.1
+restc 0.4.1
+results 0.2.0
+re_tuner 0.1.21
+# Packages page 115
+riakc 2.5.3
+riak_client 2.5.3
+riak_core_lite 0.10.4
+riak_core_lite_util 0.1.2
+riak_core_ng 3.1.1
+riak_core_ng_up 2.2.9
+riak_dt 2.1.1
+riak_ensemble 2.1.3
+riak_ensemble_ng 2.4.4
+riak_pb 2.3.2
+riak_sysmon 2.1.7
+riax_hut 1.3.0
+ringbuffer 1.2.0
+rlamb_publishtest 0.1.0
+rlp 1.1.0
+rmpc 18.5.9
+robots 1.1.1
+rocksdb 1.8.0
+rocksdb_cloud 1.0.1
+roni 1.0.1
+roster 3.4.0
+# Packages page 116
+router 1.0.4
+routing_tree 1.0.6
+rpsls 1.0.0
+rs_compile 0.1.0
+rsrc_pool 1.0.3
+rstats 1.0.4
+rtmpmsg 0.2.16
+rtrace 1.0.1-6.bc1a170
+s3filez 1.4.1
+safeio 0.1.6
+safetyvalve 2.5.2
+# Packages page 117
+salt 0.1.3
+samovar 1.0.2
+sanitizer 0.0.2
+sasl_auth 2.0.2
+sbroker 1.0.0
+scheduler_utilization 0.1.1
+# Packages page 118
+scrypt 2.1.0
+segmented_cache 0.2.0
+# Packages page 119
+self_configer 0.1.1
+semver_erl 0.0.1
+serial_framing_protocol 1.1.0
+serverless 0.4.3
+seshat 0.4.0
+setup 2.1.0
+sext 1.8.0
+sfmt 0.14.0
+sf_transform 0.3.1
+sgi 0.6.0
+sha3 2.0.0
+shackle 0.6.15
+# Packages page 120
+shards 1.1.0
+sheldon 0.4.1
+shiguredo_crdt 2022.1.0
+shiguredo_redbug 2022.2.0
+shiguredo_riak_dt 2022.1.0
+shiguredo_sync 2022.1.0
+shine 0.1.0
+shot 1.1.1
+shotgun 0.5.3
+shq 0.1.0
+sidejob 2.1.0
+# Packages page 121
+simdjson 0.1.3
+simdjsone 0.1.0
+simple_bridge 2.3.0
+simple_cache 1.2.0
+simple_global 0.1.4
+simpre 0.1.0
+# Packages page 122
+sleeplocks 1.1.2
+slugerl 1.0.0
+small_ints 0.1.0
+smerl 0.0.1
+smokkfiskur 0.1.4
+# Packages page 123
+snabbkaffe 1.0.1
+snapperl 1.1.3
+snappiest 1.2.0
+snappy 1.1.1
+snappyer 1.2.9
+snappy_nif 1.1.3
+snatch 0.4.6
+snatch_php 0.2.1
+snatch_test_framework 0.6.4
+sockerl 17.9.10
+soda 1.1.1
+soos_sample_project 1.0.0
+soxe 0.1.1
+# Packages page 124
+spartan 0.0.1
+spellerl 1.0.1
+spg 1.1.1
+sphinxsearch_giza 0.0.2
+spi 0.5.0
+spillway 1.3.0
+splay_tree 1.1.0
+splicer 0.5.5
+sql_bridge 0.5.0
+# Packages page 125
+sqlite 2.0.0
+sqlite3 1.1.14
+sqlmig 0.1.5
+sqlparse 4.6.3
+sqlparser 0.3.1
+srly 0.6.4
+ssh_agent 0.1.0
+ssh_signature 0.1.0
+ssl_verify_fun 1.1.6
+ssl_verify_hostname 1.0.6
+stacktrace_compat 1.2.2
+stage 0.2.0
+statman 0.5.0
+statsderl 0.6.1
+statsig 0.0.2
+st_commons 1.2.1
+stdout_formatter 0.2.4
+# Packages page 126
+steady_vector 1.0.1
+steamroller 0.14.3
+stillir 1.1.0
+stout 1.0.0
+stream 0.1.0
+strftimerl 0.1.2
+string_compat 0.0.1
+stringprep 1.0.29
+string_utils 1.1.3
+# Packages page 127
+stun 1.2.7
+subtree 0.1.0
+sui 0.1.0
+sumo_db 0.7.7
+sumo_db_mysql 0.0.2
+sumo_db_pgsql 0.2.0
+sumo_db_riak 0.1.0
+sumo_rest 0.3.4
+supervisor3 1.1.12
+supool 2.0.5
+surreal 1.0.0
+# Packages page 128
+swab 1.0.4
+swear 1.0.0
+swidden 2023.1.0
+switchboard 0.3.2
+syn 3.3.0
+sync 0.4.1
+syscall 0.1.0
+syslog 1.1.0
+syslog_app 4.0.0
+syslogger 0.3.0
+syslog_socket 2.0.5
+sysmon_handler 1.3.0
+systemd 0.6.2
+system_monitor 1.0.1
+t__ 0.1.0
+taglib 0.2.3
+# Packages page 129
+talib_ex_nif 0.1.0
+taskforce 1.2.3
+task_graph 0.3.1
+tcp_client 0.3.0
+tdata 1.1.3
+tdiff 0.1.2
+tdlib 0.0.2
+teacup 0.3.4
+teacup_nats 0.4.1
+teal 0.1.1
+telemetry 1.2.1
+telemetry_influxdb 0.2.0
+telemetry_metrics_telegraf 0.3.0
+# Packages page 130
+telemetry_poller 1.0.0
+telemetry_registry 0.3.1
+teleport 0.6.2
+teleprom 0.1.0
+telex 0.0.2
+template_compiler 2.6.0
+templaterl 0.2.4
+tensorflex 0.1.2
+termcap 0.1.0
+termit 2.0.1
+tesla_api 1.0.0
+test_hex 1.1.2
+# Packages page 131
+test_package 1.0.0
+test_package_nogit 1.0.0
+test_utils 1.1.1
+textual 0.1.1
+tflite_beam 0.3.2
+the_f 1.0.0
+thoas 1.0.0
+thrift_erl 0.13.0
+thrift_protocol 0.1.5
+throwdown 0.2.1
+tiling_game 0.1.0
+time_compat 0.0.1
+# Packages page 132
+time_utils 1.0.15
+tinymt 0.3.2
+tivan 1.2.15
+tivan_rocksdb 1.0.0
+tls_certificate_check 1.18.1
+tomerl 0.5.0
+# Packages page 133
+torchx 0.5.3
+totp 0.0.3
+tqformat 0.1.4
+tql 1.10.0
+tracelog 0.1.0
+traces 1.0.4
+trails 2.3.0
+transbank 0.1.0
+travianmap 0.4.1
+treewalker 0.4.1
+trie 2.0.5
+# Packages page 134
+triq 1.3.0
+trooper 0.3.2
+ts_chatterbox 0.14.0
+tsuru 1.4.1
+tunnerl 1.3.0
+twilio_sms 0.1.1
+typerefl 0.1.1
+types 0.1.8
+# Packages page 135
+u2f 0.1.5
+ua_classifier 1.0.0
+ucl 1.0.0
+ucol 2.0.0
+ucol_nif 1.1.5
+# Packages page 136
+uef 2.6.0
+ui 0.1.1
+uid 1.3.4
+ulitos 0.4.0
+undermidi 0.1.0
+undertheory 0.2.0-rc6
+undertone 0.4.0-rc3
+undertone_lib 0.4.0-rc3
+unicode_util_compat 0.7.0
+unistring 0.1.0
+unite 0.4.0
+# Packages page 137
+uri 0.1.0
+urilib 0.5.0
+url 1.1.0
+usb 0.2.0
+util 1.3.2
+utility 0.1.2
+uuid_erl 2.0.5
+uuidv4 1.0.0
+validerl 2.0.1
+# Packages page 138
+varpool 2.0.5
+vd_inet_ext 0.4.1
+vd_pkt 0.4.5
+vectorclock 0.2.0
+vegrandis 3.1.1
+vent 0.4.2
+verhoeff 0.1.2
+verl 1.1.1
+verx 0.5.4
+vice 0.1.0
+vincenty 1.0.0
+# Packages page 139
+vmq_commons 1.0.0
+vmstats 2.4.0
+vptree 0.0.0
+vsn 1.1.0
+watch 0.2.2
+# Packages page 140
+webdavfilez 1.2.1
+webmachine 1.11.1
+webpage 1.0.0
+websocket_client 1.5.0
+# Packages page 141
+wirerlhair 1.0.0
+wms 0.10.0
+wolff 1.7.4
+wooper 2.0.9
+worker_pool 6.0.1
+workforce 0.1.0
+wts 0.4.0
+# Packages page 142
+xmlrat 0.0.10
+xmpp 1.6.2
+xorf 1.0.0
+xpath 1.0.2
+xprof 2.0.0-rc.5
+xprof_core 2.0.0-rc.5
+xprof_gui 2.0.0-rc.5
+xqerl 0.2.0
+xqerl_merge_index 2.1.0
+xs_regex 0.1.0
+xtea 0.1.2
+xxh3 0.3.3
+yabko 1.0.0
+yaccety_sax 0.3.0
+yamerl 0.10.0
+yamerl_the_fork 0.3.3
+# Packages page 143
+yconf 1.0.15
+yctest 1.2.0
+yes_msg 0.1.0
+yubico 0.1.5
+yval 1.0.10
+zen 0.1.0
+# Packages page 144
+zlist 1.2.1
+zlists 0.0.4
+zotonic_apps 1.0.0-rc.15
+zotonic_core 1.0.0-rc.15
+zotonic_filehandler 1.0.0-rc.15
+zotonic_fileindexer 1.0.0-rc.15
+zotonic_filewatcher 1.0.0-rc.15
+zotonic_launcher 1.0.0-rc.15
+zotonic_listen_http 1.0.0-rc.15
+zotonic_listen_mqtt 1.0.0-rc.15
+zotonic_listen_smtp 1.0.0-rc.15
+zotonic_mod_acl_mock 1.0.0-d1
+zotonic_mod_acl_user_groups 1.0.0-rc.15
+zotonic_mod_admin 1.0.0-rc.15
+zotonic_mod_admin_category 1.0.0-rc.15
+zotonic_mod_admin_config 1.0.0-rc.15
+zotonic_mod_admin_frontend 1.0.0-rc.15
+zotonic_mod_admin_identity 1.0.0-rc.15
+zotonic_mod_admin_merge 1.0.0-rc.15
+zotonic_mod_admin_modules 1.0.0-rc.15
+zotonic_mod_admin_predicate 1.0.0-rc.15
+zotonic_mod_admin_statistics 1.0.0-rc.15
+zotonic_mod_artwork 1.0.0-rc.15
+zotonic_mod_audio 1.0.0-rc.15
+zotonic_mod_auth2fa 1.0.0-rc.15
+zotonic_mod_authentication 1.0.0-rc.15
+zotonic_mod_backup 1.0.0-rc.15
+zotonic_mod_base 1.0.0-rc.15
+zotonic_mod_bootstrap 1.0.0-rc.15
+zotonic_mod_clamav 1.0.0-rc.15
+zotonic_mod_comment 1.0.0-rc.15
+zotonic_mod_contact 1.0.0-rc.15
+zotonic_mod_content_groups 1.0.0-rc.15
+zotonic_mod_cookie_consent 1.0.0-rc.15
+zotonic_mod_cron 1.0.0-rc.15
+zotonic_mod_custom_redirect 1.0.0-rc.15
+zotonic_mod_development 1.0.0-rc.15
+zotonic_mod_ducklog 0.2.0
+zotonic_mod_editor_tinymce 1.0.0-rc.15
+zotonic_mod_email_dkim 1.0.0-rc.15
+zotonic_mod_email_receive 1.0.0-rc.15
+zotonic_mod_email_relay 1.0.0-rc.15
+zotonic_mod_email_status 1.0.0-rc.15
+zotonic_mod_export 1.0.0-rc.15
+zotonic_mod_facebook 1.0.0-rc.15
+zotonic_mod_filestore 1.0.0-rc.15
+zotonic_mod_fileuploader 1.0.0-rc.15
+zotonic_mod_geoip 1.0.0-rc.15
+zotonic_mod_image_edit 1.0.0-rc.15
+zotonic_mod_import_csv 1.0.0-rc.15
+zotonic_mod_import_wordpress 1.0.0-rc.15
+zotonic_mod_l10n 1.0.0-rc.15
+zotonic_mod_linkedin 1.0.0-rc.15
+zotonic_mod_logging 1.0.0-rc.15
+zotonic_mod_mailinglist 1.0.0-rc.15
+zotonic_mod_media_exif 1.0.0-rc.15
+zotonic_mod_menu 1.0.0-rc.15
+zotonic_mod_microsoft 1.0.0-rc.15
+zotonic_mod_mqtt 1.0.0-rc.15
+zotonic_mod_oauth2 1.0.0-rc.15
+zotonic_mod_oembed 1.0.0-rc.15
+zotonic_mod_ratelimit 1.0.0-rc.15
+zotonic_mod_search 1.0.0-rc.15
+zotonic_mod_seo 1.0.0-rc.15
+zotonic_mod_seo_sitemap 1.0.0-rc.15
+zotonic_mod_server_storage 1.0.0-rc.15
+zotonic_mod_signup 1.0.0-rc.15
+zotonic_mod_site_update 1.0.0-rc.15
+zotonic_mod_ssl_ca 1.0.0-rc.15
+zotonic_mod_ssl_letsencrypt 1.0.0-rc.15
+zotonic_mod_survey 1.0.0-rc.15
+zotonic_mod_syslog 1.0.0-rc.15
+zotonic_mod_tkvstore 1.0.0-rc.15
+zotonic_mod_translation 1.0.0-rc.15
+zotonic_mod_twitter 1.0.0-rc.15
+zotonic_mod_video 1.0.0-rc.15
+zotonic_mod_video_embed 1.0.0-rc.15
+zotonic_mod_wires 1.0.0-rc.15
+zotonic_mod_zotonic_site_management 1.0.0-rc.15
+zotonic_notifier 1.0.0-rc.15
+zotonic_rdf 1.0.1
+zotonic_site_status 1.0.0-rc.15
+zotonic_ssl 1.3.0
+zotonic_stdlib 1.14.0
+zstd 0.2.0
+zucchini 0.1.0
+# Packages page 145
+# Packages page 146
diff --git a/test/plugin_c_src.mk b/test/plugin_c_src.mk
index eeee445..91422d3 100644
--- a/test/plugin_c_src.mk
+++ b/test/plugin_c_src.mk
@@ -8,9 +8,11 @@ c-src: $(C_SRC_TARGETS)
c_src: c-src
ifeq ($(PLATFORM),msys2)
-C_SRC_OUTPUT_EXECUTABLE_EXTENSION = .dll
+C_SRC_OUTPUT_SHARED_EXTENSION = .dll
+C_SRC_OUTPUT_STATIC_EXTENSION = .lib
else
-C_SRC_OUTPUT_EXECUTABLE_EXTENSION = .so
+C_SRC_OUTPUT_SHARED_EXTENSION = .so
+C_SRC_OUTPUT_STATIC_EXTENSION = .a
endif
c-src-makefile-change: init
@@ -32,7 +34,7 @@ c-src-makefile-change: init
$(APP)/c_src/$(APP).o \
$(APP)/ebin/$(APP).app \
$(APP)/ebin/$(APP).beam \
- $(APP)/priv/$(APP)$(C_SRC_OUTPUT_EXECUTABLE_EXTENSION) \
+ $(APP)/priv/$(APP)$(C_SRC_OUTPUT_SHARED_EXTENSION) \
$(APP)/src/$(APP).erl | sort > $(APP)/EXPECT
$t $(SLEEP)
$t touch $(APP)/Makefile
@@ -60,7 +62,7 @@ c-src-nif: init
$t test -f $(APP)/c_src/env.mk
$t test -f $(APP)/ebin/$(APP).app
$t test -f $(APP)/ebin/$(APP).beam
- $t test -f $(APP)/priv/$(APP)$(C_SRC_OUTPUT_EXECUTABLE_EXTENSION)
+ $t test -f $(APP)/priv/$(APP)$(C_SRC_OUTPUT_SHARED_EXTENSION)
$i "Check that the application was compiled correctly"
$t $(ERL) -pa $(APP)/ebin/ -eval " \
@@ -81,7 +83,7 @@ c-src-nif: init
$t test -f $(APP)/c_src/env.mk
$t test -f $(APP)/ebin/$(APP).app
$t test -f $(APP)/ebin/$(APP).beam
- $t test -f $(APP)/priv/$(APP)$(C_SRC_OUTPUT_EXECUTABLE_EXTENSION)
+ $t test -f $(APP)/priv/$(APP)$(C_SRC_OUTPUT_SHARED_EXTENSION)
$i "Check that the application was compiled correctly"
$t $(ERL) -pa $(APP)/ebin/ -eval " \
@@ -101,7 +103,7 @@ c-src-nif: init
$t test ! -e $(APP)/c_src/$(APP).o
$t test ! -e $(APP)/ebin/$(APP).app
$t test ! -e $(APP)/ebin/$(APP).beam
- $t test ! -e $(APP)/priv/$(APP)$(C_SRC_OUTPUT_EXECUTABLE_EXTENSION)
+ $t test ! -e $(APP)/priv/$(APP)$(C_SRC_OUTPUT_SHARED_EXTENSION)
$i "Distclean the application"
$t $(MAKE) -C $(APP) distclean $v
@@ -118,3 +120,60 @@ c-src-nif-missing-name: init
$i "Try to generate a NIF without giving it a name"
$t ! $(MAKE) -C $(APP) new-nif $v
+
+c-src-static-nif: init
+
+ $i "Bootstrap a new OTP library named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
+
+ $i "Generate a NIF from templates"
+ $t $(MAKE) -C $(APP) new-nif n=$(APP) $v
+
+ $i "Set C_SRC_TYPE = static in the Makefile"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "C_SRC_TYPE = static\n"}' $(APP)/Makefile
+
+ $i "Build the application"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that all compiled files exist"
+ $t test -f $(APP)/$(APP).d
+ $t test -f $(APP)/c_src/$(APP).o
+ $t test -f $(APP)/c_src/env.mk
+ $t test -f $(APP)/ebin/$(APP).app
+ $t test -f $(APP)/ebin/$(APP).beam
+ $t test -f $(APP)/priv/$(APP)$(C_SRC_OUTPUT_STATIC_EXTENSION)
+
+ $i "Check that the library file contains the expected functions"
+ $t objdump -t $(APP)/priv/test_c_src_static_nif.a | grep -c hello | grep -q 1
+
+ $i "Re-build the application"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that all compiled files exist"
+ $t test -f $(APP)/$(APP).d
+ $t test -f $(APP)/c_src/$(APP).o
+ $t test -f $(APP)/c_src/env.mk
+ $t test -f $(APP)/ebin/$(APP).app
+ $t test -f $(APP)/ebin/$(APP).beam
+ $t test -f $(APP)/priv/$(APP)$(C_SRC_OUTPUT_STATIC_EXTENSION)
+
+ $i "Check that the library file contains the expected functions"
+ $t objdump -t $(APP)/priv/test_c_src_static_nif.a | grep -c hello | grep -q 1
+
+ $i "Clean the application"
+ $t $(MAKE) -C $(APP) clean $v
+
+ $i "Check that all intermediate files were removed"
+ $t test ! -e $(APP)/$(APP).d
+ $t test ! -e $(APP)/c_src/$(APP).o
+ $t test ! -e $(APP)/ebin/$(APP).app
+ $t test ! -e $(APP)/ebin/$(APP).beam
+ $t test ! -e $(APP)/priv/$(APP)$(C_SRC_OUTPUT_STATIC_EXTENSION)
+
+ $i "Distclean the application"
+ $t $(MAKE) -C $(APP) distclean $v
+
+ $i "Check that all files were removed"
+ $t test ! -e $(APP)/c_src/env.mk
diff --git a/test/plugin_cover.mk b/test/plugin_cover.mk
index a1d7e51..2ad8ef4 100644
--- a/test/plugin_cover.mk
+++ b/test/plugin_cover.mk
@@ -33,6 +33,34 @@ cover-ct: init
$t test ! -e $(APP)/cover/ct.coverdata
$t test ! -e $(APP)/test/ct.cover.spec
+cover-ct-excl-mods: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Add supervisor module to the cover exclude module list "
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "COVER_EXCLUDE_MODS = $(APP)_sup \n"}' $(APP)/Makefile
+
+ $i "Generate a Common Test suite"
+ $t mkdir $(APP)/test
+ $t printf "%s\n" \
+ "-module($(APP)_SUITE)." \
+ "-export([all/0, ok/1])." \
+ "all() -> [ok]." \
+ "ok(_) -> application:start($(APP))." > $(APP)/test/$(APP)_SUITE.erl
+
+ $i "Run Common Test with code coverage enabled"
+ $t $(MAKE) -C $(APP) ct COVER=1 $v
+
+ $i "Check that the generated files exist"
+ $t test -f $(APP)/cover/ct.coverdata
+ $t test -f $(APP)/test/ct.cover.spec
+
+ $i "Check that the supervisor module is not included in the cover report"
+ $t ! test -e $(APP)/logs/ct_run.*/$(APP)_sup.COVER.html
+
cover-ct-incl-apps: init
$i "Bootstrap a new OTP application named $(APP)"
@@ -150,6 +178,33 @@ endif
$t test -f $(APP)/logs/ct_run.*/cow_http_hd.COVER.html
$t ! test -e $(APP)/logs/ct_run.*/ranch_app.COVER.html
+cover-ct-single-suite: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Generate a Common Test suite"
+ $t mkdir $(APP)/test
+ $t printf "%s\n" \
+ "-module($(APP)_SUITE)." \
+ "-export([all/0, ok/1])." \
+ "all() -> [ok]." \
+ "ok(_) -> application:start($(APP))." > $(APP)/test/$(APP)_SUITE.erl
+
+ $i "Run Common Test against this specific test suite with code coverage enabled"
+ $t $(MAKE) -C $(APP) ct-$(APP) COVER=1 $v
+
+ $i "Check that the generated files exist"
+ $t test -f $(APP)/cover/ct.coverdata
+ $t test -f $(APP)/test/ct.cover.spec
+
+ $i "Check that the generated files are removed on clean"
+ $t $(MAKE) -C $(APP) clean $v
+ $t test ! -e $(APP)/cover/ct.coverdata
+ $t test ! -e $(APP)/test/ct.cover.spec
+
cover-custom-dir: init
$i "Bootstrap a new OTP application named $(APP)"
@@ -258,6 +313,34 @@ cover-eunit-apps-only: init
$i "Check that the generated file exists"
$t test -f $(APP)/apps/my_app/cover/eunit.coverdata
+cover-eunit-excl-mods: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Add supervisor module to the cover exclude module list "
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "COVER_EXCLUDE_MODS = $(APP)_sup \n"}' $(APP)/Makefile
+
+ $i "Generate a module containing EUnit tests"
+ $t printf "%s\n" \
+ "-module($(APP))." \
+ "-ifdef(TEST)." \
+ "-include_lib(\"eunit/include/eunit.hrl\")." \
+ "ok_test() -> application:ensure_all_started($(APP))." \
+ "-endif." > $(APP)/src/$(APP).erl
+
+ $i "Run EUnit with code coverage enabled"
+ $t $(MAKE) -C $(APP) eunit COVER=1 $v
+
+ $i "Build the cover report"
+ $t $(MAKE) -C $(APP) cover-report $v
+
+ $i "Check that app was covered, but supervisor wasn't"
+ $t test -f $(APP)/cover/$(APP)_app.COVER.html
+ $t ! test -e $(APP)/cover/$(APP)_sup.COVER.html
+
cover-eunit-incl-apps: init
$i "Bootstrap a new OTP application named $(APP)"
diff --git a/test/plugin_edoc.mk b/test/plugin_edoc.mk
index 1779797..575f6df 100644
--- a/test/plugin_edoc.mk
+++ b/test/plugin_edoc.mk
@@ -132,3 +132,66 @@ edoc-src-dirs: init
$t test -f $(APP)/doc/$(APP)_sup.html
$t test -f $(APP)/doc/my_app_app.html
$t test -f $(APP)/doc/my_app_sup.html
+
+edoc-src-subdirs: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Add current directory to the list of EDoc source directories"
+ $t echo 'EDOC_SRC_DIRS = $$(CURDIR)' >> $(APP)/Makefile
+
+ $i "Generate a module in a subdirectory with EDoc comments"
+ $t mkdir $(APP)/src/subdir/
+ $t printf "%s\n" \
+ "%% @doc erlang-mk-edoc-subdir-module" \
+ "-module($(APP))." \
+ "-export([ok/0])." \
+ "" \
+ "%% @doc erlang-mk-edoc-subdir-function" \
+ "ok() -> ok." > $(APP)/src/subdir/$(APP).erl
+
+ $i "Run EDoc"
+ $t $(MAKE) -C $(APP) edoc $v
+
+ $i "Check that the new module's documentation was generated"
+ $t test -f $(APP)/doc/$(APP).html
+
+ $i "Check that the EDoc comments are in the generated documentation"
+ $t grep -q erlang-mk-edoc-subdir-module $(APP)/doc/$(APP).html
+ $t grep -q erlang-mk-edoc-subdir-function $(APP)/doc/$(APP).html
+
+edoc-src-multiapp-subdirs: init
+
+ $i "Bootstrap a multi application repository with a root application"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Create a new application my_app"
+ $t $(MAKE) -C $(APP) new-app in=my_app $v
+
+ $i "Add apps directories to the list of EDoc source directories"
+ $t echo 'EDOC_SRC_DIRS = $$(ALL_APPS_DIRS)' >> $(APP)/Makefile
+
+ $i "Generate a module in a subdirectory with EDoc comments"
+ $t mkdir $(APP)/apps/my_app/src/subdir/
+ $t printf "%s\n" \
+ "%% @doc erlang-mk-edoc-subdir-module" \
+ "-module($(APP))." \
+ "-export([ok/0])." \
+ "" \
+ "%% @doc erlang-mk-edoc-subdir-function" \
+ "ok() -> ok." > $(APP)/apps/my_app/src/subdir/$(APP).erl
+
+ $i "Run EDoc"
+ $t $(MAKE) -C $(APP) edoc $v
+
+ $i "Check that the new module's documentation was generated"
+ $t test -f $(APP)/doc/$(APP).html
+
+ $i "Check that the EDoc comments are in the generated documentation"
+ $t grep -q erlang-mk-edoc-subdir-module $(APP)/doc/$(APP).html
+ $t grep -q erlang-mk-edoc-subdir-function $(APP)/doc/$(APP).html
diff --git a/test/plugin_escript.mk b/test/plugin_escript.mk
index 3949547..6479e3f 100644
--- a/test/plugin_escript.mk
+++ b/test/plugin_escript.mk
@@ -175,3 +175,40 @@ escript-extra: init
$i "Check that the escript contains the extra files"
$t unzip -l $(APP)/$(APP) 2> /dev/null | grep -q Makefile
$t unzip -l $(APP)/$(APP) 2> /dev/null | grep -q erlang.mk
+
+escript-zip-file: init
+
+ $i "Bootstrap a new OTP library named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
+
+ $i "Set ESCRIPT_ZIP_FILE to a custom location"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "ESCRIPT_ZIP_FILE = tmp/my_escript.zip\n"}' $(APP)/Makefile
+
+ $i "Generate a module containing a function main/1"
+ $t printf "%s\n" \
+ "-module($(APP))." \
+ "-export([main/1])." \
+ 'main(_) -> io:format("good~n").' > $(APP)/src/$(APP).erl
+
+ $i "Build the escript"
+ $t $(MAKE) -C $(APP) escript $v
+
+ $i "Check that the file at ESCRIPT_ZIP_FILE exists"
+ $t test -f $(APP)/tmp/my_escript.zip
+
+ $i "Check that the escript exists"
+ $t test -f $(APP)/$(APP)
+
+ $i "Check that the escript runs"
+ $t $(APP)/$(APP) | grep -q good
+
+ $i "Distclean the application"
+ $t $(MAKE) -C $(APP) distclean $v
+
+ $i "Check that the file at ESCRIPT_ZIP_FILE was removed"
+ $t test ! -e $(APP)/tmp/my_escript.zip
+
+ $i "Check that the escript was removed"
+ $t test ! -e $(APP)/$(APP)
diff --git a/test/plugin_eunit.mk b/test/plugin_eunit.mk
index 768358c..823f619 100644
--- a/test/plugin_eunit.mk
+++ b/test/plugin_eunit.mk
@@ -347,6 +347,27 @@ eunit-test-dir: init
$i "Check that tests were both run only once"
$t printf "%s\n" $(APP) $(APP)_tests | cmp $(APP)/eunit.log -
+eunit-test-spec: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Configure EUNIT_TEST_SPEC to run a setup function"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "EUNIT_TEST_SPEC = {setup, fun() -> erlang:display(\"EUNIT_TEST_SPEC\" \"-setup\") end, \$$1} \n"}' $(APP)/Makefile
+
+ $i "Generate a module containing EUnit tests"
+ $t printf "%s\n" \
+ "-module($(APP))." \
+ "-ifdef(TEST)." \
+ "-include_lib(\"eunit/include/eunit.hrl\")." \
+ "ok_test() -> ok." \
+ "-endif." > $(APP)/src/$(APP).erl
+
+ $i "Check that EUnit runs the setup function"
+ $t $(MAKE) -C $(APP) eunit | grep -c "EUNIT_TEST_SPEC-setup" | grep -q 1
+
eunit-tests: init
$i "Bootstrap a new OTP application named $(APP)"
diff --git a/test/plugin_protobuffs.mk b/test/plugin_protobuffs.mk
index f5814e8..31198f5 100644
--- a/test/plugin_protobuffs.mk
+++ b/test/plugin_protobuffs.mk
@@ -15,8 +15,8 @@ protobuffs-compile: init
$t cp ../erlang.mk $(APP)/
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
- $i "Add protobuffs to the list of dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "BUILD_DEPS = protobuffs\n"}' $(APP)/Makefile
+ $i "Add gpb to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "BUILD_DEPS = gpb\n"}' $(APP)/Makefile
$i "Download two proto files"
$t mkdir $(APP)/src/proto/
@@ -40,36 +40,36 @@ protobuffs-compile: init
{ok, [empty_pb, simple_pb]} = application:get_key($(APP), modules), \
halt()"
-protobuffs-compile-with-gpb: init
+protobuffs-compile-imports: init
$i "Bootstrap a new OTP library named $(APP)"
$t mkdir $(APP)/
$t cp ../erlang.mk $(APP)/
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
- $i "Add gpb to the list of dependencies"
+ $i "Add protobuffs to the list of dependencies"
$t perl -ni.bak -e 'print;if ($$.==1) {print "BUILD_DEPS = gpb\n"}' $(APP)/Makefile
- $i "Download two proto files"
+ $i "Download two proto files with an import"
$t mkdir $(APP)/src/proto/
- $t curl -s -o $(APP)/src/proto/empty.proto $(PROTOBUFFS_URL)/proto/empty.proto
- $t curl -s -o $(APP)/src/proto/simple.proto $(PROTOBUFFS_URL)/proto/simple.proto
+ $t curl -s -o $(APP)/src/proto/exports.proto $(PROTOBUFFS_URL)/proto/exports.proto
+ $t curl -s -o $(APP)/src/proto/imports.proto $(PROTOBUFFS_URL)/proto/imports.proto
$i "Build the application"
$t $(MAKE) -C $(APP) $v
$i "Check that an Erlang module was generated and compiled"
- $t test -f $(APP)/src/empty_pb.erl
- $t test -f $(APP)/src/simple_pb.erl
- $t test -f $(APP)/include/empty_pb.hrl
- $t test -f $(APP)/include/simple_pb.hrl
- $t test -f $(APP)/ebin/empty_pb.beam
- $t test -f $(APP)/ebin/simple_pb.beam
+ $t test -f $(APP)/src/exports_pb.erl
+ $t test -f $(APP)/src/imports_pb.erl
+ $t test -f $(APP)/include/exports_pb.hrl
+ $t test -f $(APP)/include/imports_pb.hrl
+ $t test -f $(APP)/ebin/exports_pb.beam
+ $t test -f $(APP)/ebin/imports_pb.beam
$i "Check that the generated modules are included in .app file"
$t $(ERL) -pa $(APP)/ebin/ -eval " \
ok = application:load($(APP)), \
- {ok, [empty_pb, simple_pb]} = application:get_key($(APP), modules), \
+ {ok, [exports_pb, imports_pb]} = application:get_key($(APP), modules), \
halt()"
protobuffs-dont-compile: init
@@ -111,7 +111,7 @@ protobuffs-makefile-change: init
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
$i "Add protobuffs to the list of dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "BUILD_DEPS = protobuffs\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "BUILD_DEPS = gpb\n"}' $(APP)/Makefile
$i "Download two proto files"
$t mkdir $(APP)/src/proto/
diff --git a/test/plugin_relx.mk b/test/plugin_relx.mk
index 2771e8f..7e08fe0 100644
--- a/test/plugin_relx.mk
+++ b/test/plugin_relx.mk
@@ -25,9 +25,6 @@ relx-rel: init
$i "Build the release"
$t $(MAKE) -C $(APP) $v
- $i "Check that relx was downloaded"
- $t test -f $(APP)/.erlang.mk/relx
-
$i "Check that the release was built"
$t test -d $(APP)/_rel
$t test -d $(APP)/_rel/$(APP)_release
@@ -97,9 +94,6 @@ relx-bare-rel: init
$i "Build the release"
$t $(MAKE) -C $(APP) rel $v
- $i "Check that relx was downloaded"
- $t test -f $(APP)/.erlang.mk/relx
-
$i "Check that the release was built"
$t test -d $(APP)/_rel
$t test -d $(APP)/_rel/$(APP)_release
@@ -108,6 +102,23 @@ relx-bare-rel: init
$t test -d $(APP)/_rel/$(APP)_release/releases
$t test -d $(APP)/_rel/$(APP)_release/releases/1
+relx-output-dir: init
+
+ $i "Bootstrap a new release named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap bootstrap-rel $v
+
+ $i "Set RELX_OUTPUT_DIR to _rel2"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "RELX_OUTPUT_DIR = _rel2\n"}' $(APP)/Makefile
+
+ $i "Build the release"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that the release exists in the correct location"
+ $t ! test -d $(APP)/_rel
+ $t test -d $(APP)/_rel2
+
relx-post-rel: init
$i "Bootstrap a new release named $(APP)"
@@ -122,9 +133,6 @@ relx-post-rel: init
$i "Build the release"
$t $(MAKE) -C $(APP) $v
- $i "Check that relx was downloaded"
- $t test -f $(APP)/.erlang.mk/relx
-
$i "Check that the release was built"
$t test -d $(APP)/_rel
$t test -d $(APP)/_rel/$(APP)_release
@@ -154,6 +162,99 @@ relx-post-rel: init
$i "Check that the output directory was removed entirely"
$t test ! -d $(APP)/_rel/
+relx-rel-with-script: init
+
+ $i "Bootstrap a new release named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap bootstrap-rel $v
+
+ $i "Create a relx.config.script file"
+ $t printf "%s\n" \
+ "{release, {App, _Ver}, Apps} = lists:keyfind(release, 1, CONFIG)," \
+ "lists:keyreplace(release, 1, CONFIG, {release, {App, \"ONE\"}, Apps})." \
+ > $(APP)/relx.config.script
+
+ $i "Build the release"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that the release was built"
+ $t test -d $(APP)/_rel
+ $t test -d $(APP)/_rel/$(APP)_release
+ $t test -d $(APP)/_rel/$(APP)_release/bin
+ $t test -d $(APP)/_rel/$(APP)_release/lib
+ $t test -d $(APP)/_rel/$(APP)_release/releases
+ $t test -d $(APP)/_rel/$(APP)_release/releases/ONE
+
+ $i "Clean the application"
+ $t $(MAKE) -C $(APP) clean $v
+
+ $i "Check that the release still exists"
+ $t test -d $(APP)/_rel
+ $t test -d $(APP)/_rel/$(APP)_release
+ $t test -d $(APP)/_rel/$(APP)_release/bin
+ $t test -d $(APP)/_rel/$(APP)_release/lib
+ $t test -d $(APP)/_rel/$(APP)_release/releases
+ $t test -d $(APP)/_rel/$(APP)_release/releases/ONE
+
+ $i "Distclean the application"
+ $t $(MAKE) -C $(APP) distclean $v
+
+ $i "Check that the output directory was removed entirely"
+ $t test ! -d $(APP)/_rel/
+
+define relx-rel-with-only-script-relx.config.script.erl
+endef
+
+relx-rel-with-script-only: init
+
+ $i "Bootstrap a new release named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap bootstrap-rel $v
+
+ $i "Delete relx.config and create a relx.config.script file"
+ $t rm -f $(APP)/relx.config
+ $t printf "%s\n" \
+ "CONFIG = [], %% Assert that config is empty." \
+ "[" \
+ " {release, {$(APP)_release, \"ONE\"}, [$(APP), sasl, runtime_tools]}," \
+ " {dev_mode, false}," \
+ " {include_erts, true}," \
+ " {extended_start_script, true}," \
+ " {sys_config, \"config/sys.config\"}," \
+ " {vm_args, \"config/vm.args\"}" \
+ "| CONFIG]." \
+ > $(APP)/relx.config.script
+
+ $i "Build the release"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that the release was built"
+ $t test -d $(APP)/_rel
+ $t test -d $(APP)/_rel/$(APP)_release
+ $t test -d $(APP)/_rel/$(APP)_release/bin
+ $t test -d $(APP)/_rel/$(APP)_release/lib
+ $t test -d $(APP)/_rel/$(APP)_release/releases
+ $t test -d $(APP)/_rel/$(APP)_release/releases/ONE
+
+ $i "Clean the application"
+ $t $(MAKE) -C $(APP) clean $v
+
+ $i "Check that the release still exists"
+ $t test -d $(APP)/_rel
+ $t test -d $(APP)/_rel/$(APP)_release
+ $t test -d $(APP)/_rel/$(APP)_release/bin
+ $t test -d $(APP)/_rel/$(APP)_release/lib
+ $t test -d $(APP)/_rel/$(APP)_release/releases
+ $t test -d $(APP)/_rel/$(APP)_release/releases/ONE
+
+ $i "Distclean the application"
+ $t $(MAKE) -C $(APP) distclean $v
+
+ $i "Check that the output directory was removed entirely"
+ $t test ! -d $(APP)/_rel/
+
ifneq ($(PLATFORM),msys2)
# This test is currently disabled on Windows because we are
# running into too many issues preventing the test from
@@ -218,11 +319,11 @@ ifeq ($(PLATFORM),msys2)
else
$i "Start initial release and confirm it runs the old code"
endif
- $t $(APP)/tmp/bin/$(APP)_release$(RELX_REL_EXT) start
+ $t $(APP)/tmp/bin/$(APP)_release$(RELX_REL_EXT) daemon
$t sleep 1
ifneq ($(PLATFORM),msys2)
-# On Windows the script does not have the commands rpcterms and versions.
- $t test `$(APP)/tmp/bin/$(APP)_release$(RELX_REL_EXT) rpcterms test test` = old
+# On Windows the script does not have the commands rpc and versions.
+ $t test `$(APP)/tmp/bin/$(APP)_release$(RELX_REL_EXT) rpc test test` = old
$i "Check that it's 1 available version"
$t test `$(APP)/tmp/bin/$(APP)_release$(RELX_REL_EXT) versions | wc -l` = "2"
@@ -246,8 +347,8 @@ else
endif
$t sleep 1
ifneq ($(PLATFORM),msys2)
-# On Windows the script does not have the commands rpcterms and versions.
- $t test `$(APP)/tmp/bin/$(APP)_release$(RELX_REL_EXT) rpcterms test test` = new
+# On Windows the script does not have the commands rpc and versions.
+ $t test `$(APP)/tmp/bin/$(APP)_release$(RELX_REL_EXT) rpc test test` = new
$i "Check that it's 2 available versions"
$t test `$(APP)/tmp/bin/$(APP)_release$(RELX_REL_EXT) versions | wc -l` = "3"
@@ -266,8 +367,8 @@ else
endif
$t sleep 1
ifneq ($(PLATFORM),msys2)
-# On Windows the script does not have the commands rpcterms and versions.
- $t test `$(APP)/tmp/bin/$(APP)_release$(RELX_REL_EXT) rpcterms test test` = old
+# On Windows the script does not have the commands rpc and versions.
+ $t test `$(APP)/tmp/bin/$(APP)_release$(RELX_REL_EXT) rpc test test` = old
endif
$i "Stop the release"
@@ -300,7 +401,7 @@ endif
ifeq ($(PLATFORM),msys2)
$t $(APP)/_rel/$(APP)_release/bin/$(APP)_release$(RELX_REL_EXT) install
endif
- $t $(APP)/_rel/$(APP)_release/bin/$(APP)_release$(RELX_REL_EXT) start
+ $t $(APP)/_rel/$(APP)_release/bin/$(APP)_release$(RELX_REL_EXT) daemon
$i "Ping the release"
$t $(call wait_for_success,$(APP)/_rel/$(APP)_release/bin/$(APP)_release$(RELX_REL_EXT) ping)
@@ -341,7 +442,7 @@ relx-tar: init
$i "Check that tarball exists"
$t test -f $(APP)/_rel/$(APP)_release/$(APP)_release-1.tar.gz
-relx-vsn: init
+relx-vsn-cmd: init
$i "Bootstrap a new release named $(APP)"
$t mkdir $(APP)/
@@ -357,3 +458,37 @@ relx-vsn: init
$i "Check that the correct release exists"
$t ! test -d $(APP)/_rel/$(APP)_release/releases/1
$t test -d $(APP)/_rel/$(APP)_release/releases/2
+
+relx-vsn-git-long: init
+
+ $i "Bootstrap a new release named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap bootstrap-rel $v
+
+ $i "Replace the vsn"
+ $t sed -i.bak s/"\"1\""/"{git, long}"/ $(APP)/relx.config
+
+ $i "Build the release"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that the correct release exists"
+ $t ! test -d $(APP)/_rel/$(APP)_release/releases/1
+ $t test -d $(APP)/_rel/$(APP)_release/releases/$(shell git rev-parse HEAD)
+
+relx-vsn-git-short: init
+
+ $i "Bootstrap a new release named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap bootstrap-rel $v
+
+ $i "Replace the vsn"
+ $t sed -i.bak s/"\"1\""/"{git, short}"/ $(APP)/relx.config
+
+ $i "Build the release"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that the correct release exists"
+ $t ! test -d $(APP)/_rel/$(APP)_release/releases/1
+ $t test -d $(APP)/_rel/$(APP)_release/releases/$(shell git rev-parse --short HEAD)
diff --git a/test/plugin_xref.mk b/test/plugin_xref.mk
new file mode 100644
index 0000000..0246e23
--- /dev/null
+++ b/test/plugin_xref.mk
@@ -0,0 +1,312 @@
+# Xref plugin.
+
+XREF_TARGETS = $(call list_targets,xref)
+
+.PHONY: xref $(XREF_TARGETS)
+
+xref: $(XREF_TARGETS)
+
+xref-check: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Run the Xref plugin"
+ $t $(MAKE) -C $(APP) xref $v
+
+ $i "Create a module with an undefined function call"
+ $t printf "%s\n" \
+ "-module(bad)." \
+ "-export([f/0])." \
+ "f() -> this_module:does_not_exist()." \
+ > $(APP)/src/bad.erl
+
+ $i "Run the Xref plugin again, expect an error"
+ $t ! $(MAKE) -C $(APP) xref $v
+
+xref-check-custom: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Run the Xref plugin with undefined_functions"
+ $t $(MAKE) -C $(APP) xref XREF_CHECKS=undefined_functions $v
+
+ $i "Create a module with an unused export"
+ $t printf "%s\n" \
+ "-module(bad1)." \
+ "-export([f/0])." \
+ "f() -> whereis(user) ! bad_message." \
+ > $(APP)/src/bad1.erl
+
+ $i "Run the Xref plugin with exports_not_used, expect an error"
+ $t ! $(MAKE) -C $(APP) xref XREF_CHECKS=exports_not_used $v
+
+ $i "Run the Xref plugin with multiple checks"
+ $t $(MAKE) -C $(APP) xref XREF_CHECKS="[undefined_function_calls, undefined_functions]" $v
+
+ $i "Create a module with an undefined function call"
+ $t printf "%s\n" \
+ "-module(bad2)." \
+ "-export([f/0])." \
+ "f() -> this_module:does_not_exist()." \
+ > $(APP)/src/bad2.erl
+
+ $i "Run the Xref plugin with multiple checks, expect an error"
+ $t ! $(MAKE) -C $(APP) xref XREF_CHECKS="[undefined_function_calls, undefined_functions]" $v
+
+xref-check-informational: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Run the Xref plugin with module_use"
+ $t $(MAKE) -C $(APP) xref XREF_CHECKS="{module_use, $(APP)_sup}" > $(APP)/output.txt
+
+ $i "Confirm that the module was found"
+ $t grep -q "\- $(APP)_app$$" $(APP)/output.txt
+
+xref-query: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Run the Xref plugin with query XC (external calls)"
+ $t $(MAKE) -C $(APP) xref q="XC" > $(APP)/output.txt
+
+ $i "Confirm that the supervisor:start_link/3 call was found"
+ $t grep -q "\- supervisor:start_link/3 called by $(APP)_sup:start_link/0$$" $(APP)/output.txt
+
+xref-scope-apps: init
+
+ $i "Bootstrap a new OTP library named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
+
+ $i "Create a new library my_app"
+ $t $(MAKE) -C $(APP) new-lib in=my_app $v
+
+ $i "Create a module with an undefined function call inside my_app"
+ $t printf "%s\n" \
+ "-module(bad2)." \
+ "-export([f/0])." \
+ "f() -> this_module:does_not_exist()." \
+ > $(APP)/apps/my_app/src/bad2.erl
+
+ $i "Run the Xref plugin with apps in the scope, expect an error"
+ $t ! $(MAKE) -C $(APP) xref XREF_SCOPE="app apps" $v
+
+xref-scope-deps: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Bootstrap a new OTP library named my_dep inside $(APP)"
+ $t mkdir $(APP)/my_dep
+ $t cp ../erlang.mk $(APP)/my_dep/
+ $t $(MAKE) -C $(APP)/my_dep/ -f erlang.mk bootstrap-lib $v
+
+ $i "Create a module with an undefined function call inside my_dep"
+ $t printf "%s\n" \
+ "-module(bad2)." \
+ "-export([f/0])." \
+ "f() -> this_module:does_not_exist()." \
+ > $(APP)/my_dep/src/bad2.erl
+
+ $i "Add my_dep to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = my_dep\ndep_my_dep = cp $(CURDIR)/$(APP)/my_dep/\n"}' $(APP)/Makefile
+
+ifdef LEGACY
+ $i "Add my_dep to the applications key in the .app.src file"
+ $t perl -ni.bak -e 'print;if ($$.==7) {print "\t\tmy_dep,\n"}' $(APP)/src/$(APP).app.src
+endif
+
+ $i "Run the Xref plugin with deps in the scope, expect an error"
+ $t ! $(MAKE) -C $(APP) xref XREF_SCOPE="app deps" $v
+
+xref-scope-otp: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Run the Xref plugin for module use with OTP in the scope"
+ $t $(MAKE) -C $(APP) xref XREF_CHECKS="{module_use, asn1ct_pretty_format}" \
+ XREF_SCOPE="app otp" > $(APP)/output.txt
+
+ $i "Confirm that the asn1ct_pretty_format module use was analysed"
+ $t grep -q "\- asn1ct_pretty_format$$" $(APP)/output.txt
+
+xref-extra-apps: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Bootstrap a new OTP library named extra_app inside $(APP)"
+ $t mkdir $(APP)/extra_app
+ $t cp ../erlang.mk $(APP)/extra_app/
+ $t $(MAKE) -C $(APP)/extra_app/ -f erlang.mk bootstrap-lib $v
+
+ $i "Create a module in extra_app with a function call to $(APP)"
+ $t printf "%s\n" \
+ "-module(extra)." \
+ "-export([f/0])." \
+ "f() -> $(APP)_sup:init([])." \
+ > $(APP)/extra_app/src/extra.erl
+
+ $i "Build extra_app"
+ $t $(MAKE) -C $(APP)/extra_app $v
+
+ $i "Run the Xref plugin for application use with the extra app"
+ $t $(MAKE) -C $(APP) xref XREF_CHECKS="{application_use, $(APP)}" \
+ XREF_EXTRA_APP_DIRS="extra_app/" > $(APP)/output.txt
+
+ $i "Confirm that the extra_app application call was found"
+ $t grep -q "\- extra_app$$" $(APP)/output.txt
+
+xref-extra-dirs: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Bootstrap a new OTP library named extra_dir inside $(APP)"
+ $t mkdir $(APP)/extra_dir
+ $t cp ../erlang.mk $(APP)/extra_dir/
+ $t $(MAKE) -C $(APP)/extra_dir/ -f erlang.mk bootstrap-lib $v
+
+ $i "Create a module in extra_dir with an undefined function call"
+ $t printf "%s\n" \
+ "-module(bad)." \
+ "-export([f/0])." \
+ "f() -> this_module:does_not_exist()." \
+ > $(APP)/extra_dir/src/bad.erl
+
+ $i "Build extra_dir"
+ $t $(MAKE) -C $(APP)/extra_dir $v
+
+ $i "Run the Xref plugin with the extra dir, expect an error"
+ $t ! $(MAKE) -C $(APP) xref XREF_EXTRA_DIRS="extra_dir/ebin/" $v
+
+xref-ignore-inline-fa: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Create a module with an undefined function call and an inline ignore"
+ $t printf "%s\n" \
+ "-module(bad)." \
+ "-export([f/0])." \
+ "-ignore_xref([{f,0}])." \
+ "f() -> f_module:f_not_exist()." \
+ > $(APP)/src/bad.erl
+
+ $i "Run the Xref plugin, expect success"
+ $t $(MAKE) -C $(APP) xref $v
+
+xref-ignore-inline-mfa: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Create a module with undefined function calls and inline ignores"
+ $t printf "%s\n" \
+ "-module(bad)." \
+ "-export([f/0, g/0])." \
+ "-ignore_xref([{bad,f,0}])." \
+ "-ignore_xref({g_module,g_not_exist,0})." \
+ "f() -> f_module:f_not_exist()." \
+ "g() -> g_module:g_not_exist()." \
+ > $(APP)/src/bad.erl
+
+ $i "Run the Xref plugin, expect success"
+ $t $(MAKE) -C $(APP) xref $v
+
+xref-ignore-inline-mod: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Create a module with undefined function calls and inline ignores"
+ $t printf "%s\n" \
+ "-module(bad)." \
+ "-export([f/0, g/0])." \
+ "-ignore_xref([?MODULE])." \
+ "-ignore_xref(g_module)." \
+ "f() -> f_module:f_not_exist()." \
+ "g() -> g_module:g_not_exist()." \
+ > $(APP)/src/bad.erl
+
+ $i "Run the Xref plugin, expect success"
+ $t $(MAKE) -C $(APP) xref $v
+
+xref-ignore-project-wide-mfa: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Create a module with an undefined function call"
+ $t printf "%s\n" \
+ "-module(bad)." \
+ "-export([f/0])." \
+ "f() -> this_module:does_not_exist()." \
+ > $(APP)/src/bad.erl
+
+ $i "Run the Xref plugin with project-wide ignore, expect success"
+ $t $(MAKE) -C $(APP) xref XREF_IGNORE="{bad,f,0}" $v
+
+xref-ignore-project-wide-mod: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Create a module with an undefined function call"
+ $t printf "%s\n" \
+ "-module(bad)." \
+ "-export([f/0])." \
+ "f() -> this_module:does_not_exist()." \
+ > $(APP)/src/bad.erl
+
+ $i "Run the Xref plugin with project-wide ignore, expect success"
+ $t $(MAKE) -C $(APP) xref XREF_IGNORE="[bad]" $v
+
+xref-ignore-callbacks: init
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Run the Xref plugin for exports_not_used, expect success"
+ $t $(MAKE) -C $(APP) xref XREF_CHECKS="exports_not_used" $v
+
+ $i "Run the Xref plugin again with explicit ignoring of callbacks, expect success"
+ $t $(MAKE) -C $(APP) xref XREF_CHECKS="exports_not_used" XREF_IGNORE_CALLBACKS=1 $v
+
+ $i "Run the Xref plugin again without ignoring callbacks, expect an error"
+ $t ! $(MAKE) -C $(APP) xref XREF_CHECKS="exports_not_used" XREF_IGNORE_CALLBACKS=0 $v