aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Makefile178
-rw-r--r--test/core_app.mk62
-rw-r--r--test/core_apps.mk12
-rw-r--r--test/core_autopatch.mk41
-rw-r--r--test/core_compat.mk155
-rw-r--r--test/core_deps.mk279
-rw-r--r--test/core_elixir.mk326
-rw-r--r--test/core_makedep.mk46
-rw-r--r--test/core_misc.mk6
-rw-r--r--test/core_plugins.mk45
-rw-r--r--test/core_query.mk8
-rw-r--r--test/core_upgrade.mk8
-rw-r--r--test/hexpm_packages.txt2052
-rw-r--r--test/plugin_asciidoc.mk6
-rw-r--r--test/plugin_bootstrap.mk24
-rw-r--r--test/plugin_c_src.mk77
-rw-r--r--test/plugin_concuerror.mk6
-rw-r--r--test/plugin_cover.mk97
-rw-r--r--test/plugin_ct.mk6
-rw-r--r--test/plugin_dialyzer.mk27
-rw-r--r--test/plugin_edoc.mk71
-rw-r--r--test/plugin_erlydtl.mk6
-rw-r--r--test/plugin_escript.mk47
-rw-r--r--test/plugin_eunit.mk48
-rw-r--r--test/plugin_hex.mk48
-rw-r--r--test/plugin_proper.mk6
-rw-r--r--test/plugin_protobuffs.mk36
-rw-r--r--test/plugin_relx.mk183
-rw-r--r--test/plugin_shell.mk6
-rw-r--r--test/plugin_sphinx.mk8
-rw-r--r--test/plugin_triq.mk6
-rw-r--r--test/plugin_xref.mk312
32 files changed, 3952 insertions, 286 deletions
diff --git a/test/Makefile b/test/Makefile
index 0517684..9bd9168 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -13,10 +13,12 @@ endif
# Temporary application name, taken from rule name.
APP = test_$(subst -,_,$@)
+CACHE_DIR = $(CURDIR)/$(APP)/.cache
+export CACHE_DIR
# Erlang, quickly!
-ERL = erl +A0 -noinput -boot no_dot_erlang
+ERL = erl -noinput -boot no_dot_erlang -kernel start_distribution false +P 1024 +Q 1024
# Platform detection, condensed version.
@@ -123,32 +125,44 @@ endef
.PHONY: all clean init
-all:: core
+all::
+ $t :
clean::
- $t rm -rf erl_crash.dump packages/ $(filter-out test_rebar_git/,$(wildcard test_*/))
+ $t rm -rf erl_crash.dump packages/ $(filter-out test_hex_core_git/ test_rebar_git/,$(wildcard test_*/))
init: clean
- $i "Prefetch Rebar if necessary"
+ $i "Prefetch hex_core if necessary"
+ $t if [ ! -d test_hex_core_git ]; then \
+ git clone -q -n -- https://github.com/hexpm/hex_core test_hex_core_git; \
+ fi
+
+ $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
+HEX_CORE_GIT = file://$(CURDIR)/test_hex_core_git
+export HEX_CORE_GIT
+
+REBAR3_GIT = file://$(CURDIR)/test_rebar_git
+export REBAR3_GIT
# Core.
.PHONY: core
-define include_core
-core:: core-$1
+CORE_TARGETS :=
+PLUGINS_TARGETS :=
+define include_core
include core_$1.mk
+CORE_TARGETS += $$(core_$1_TARGETS)
+
endef
$(eval $(foreach t,$(patsubst %.mk,%,$(patsubst core_%,%,$(wildcard core_*.mk))),$(call include_core,$t)))
@@ -156,18 +170,24 @@ $(eval $(foreach t,$(patsubst %.mk,%,$(patsubst core_%,%,$(wildcard core_*.mk)))
# Plugins.
define include_plugin
-all:: $1
-
include plugin_$1.mk
+PLUGINS_TARGETS += $$($1_TARGETS)
+
endef
$(eval $(foreach t,$(patsubst %.mk,%,$(patsubst plugin_%,%,$(wildcard plugin_*.mk))),$(call include_plugin,$t)))
+core:: $(CORE_TARGETS)
+
+all:: $(CORE_TARGETS) $(PLUGINS_TARGETS)
+
# 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,11 +216,122 @@ 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 " \
@@ -230,11 +361,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 +401,23 @@ 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
+
+# Templates.
+#
+# apps_Makefile, top_Makefile and vm.args are not currently tested here.
+
+templates: clean
+ $i "Compile Erlang modules"
+ $t mkdir test_templates/
+ $t cd test_templates/ && erlc +no_error_module_mismatch ../../templates/*.erl
+
+ $i "Load Erlang term files"
+ $t $(ERL) -eval '{ok, _} = file:consult("../templates/application.app.src"), halt()'
+ $t $(ERL) -eval '{ok, _} = file:consult("../templates/library.app.src"), halt()'
+ $t $(ERL) -eval '{ok, _} = file:consult("../templates/relx.config"), halt()'
+ $t $(ERL) -eval '{ok, _} = file:consult("../templates/sys.config"), halt()'
diff --git a/test/core_app.mk b/test/core_app.mk
index effc598..7c9c046 100644
--- a/test/core_app.mk
+++ b/test/core_app.mk
@@ -1,10 +1,10 @@
# Core: Building applications.
-CORE_APP_TARGETS = $(call list_targets,core-app)
+core_app_TARGETS = $(call list_targets,core-app)
-.PHONY: core-app $(CORE_APP_TARGETS)
+.PHONY: core-app $(core_app_TARGETS)
-core-app: $(CORE_APP_TARGETS)
+core-app: $(core_app_TARGETS)
ifdef LEGACY
core-app-appsrc-change: init
@@ -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..8e2223e 100644
--- a/test/core_apps.mk
+++ b/test/core_apps.mk
@@ -1,10 +1,10 @@
# Core: Multi-applications.
-CORE_APPS_TARGETS = $(call list_targets,core-apps)
+core_apps_TARGETS = $(call list_targets,core-apps)
-.PHONY: core-apps $(CORE_APPS_TARGETS)
+.PHONY: core-apps $(core_apps_TARGETS)
-core-apps: $(CORE_APPS_TARGETS)
+core-apps: $(core_apps_TARGETS)
core-apps-build: init
@@ -444,7 +444,7 @@ core-apps-local-deps: init
$t $(MAKE) -C $(APP) new-app in=my_app_1 $v
$i "Add Lager to the list of dependencies of my_app_1, and add the lager parse_transform"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lager\nERLC_OPTS+=+{parse_transform,lager_transform}\n"}' $(APP)/apps/my_app_1/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lager\ndep_lager = git https://github.com/erlang-lager/lager master\nERLC_OPTS+=+{parse_transform,lager_transform}\n"}' $(APP)/apps/my_app_1/Makefile
$i "Add a lager:error/2 call to my_app_1_app.erl that will fail if the parse_transform doesn't run"
$t perl -ni.bak -e 'print;if (/^-export/){print "\n-export([log/0]).\n"} if (eof) {print "\nlog() -> lager:error(\"test\", []).\n"}' $(APP)/apps/my_app_1/src/my_app_1_app.erl
@@ -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
@@ -485,7 +485,7 @@ core-apps-local-deps: init
$i "Add Lager to the list of dependencies of my_app_2, and add the lager parse_transform"
$t mv $(APP)/apps/my_app_2/Makefile.bak $(APP)/apps/my_app_2/Makefile
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lager\nERLC_OPTS+=+{parse_transform,lager_transform}\n"}' $(APP)/apps/my_app_2/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lager\ndep_lager = git https://github.com/erlang-lager/lager master\nERLC_OPTS+=+{parse_transform,lager_transform}\n"}' $(APP)/apps/my_app_2/Makefile
$i "Build the application"
$t $(MAKE) -C $(APP) $v
diff --git a/test/core_autopatch.mk b/test/core_autopatch.mk
index 2624f79..7b64269 100644
--- a/test/core_autopatch.mk
+++ b/test/core_autopatch.mk
@@ -1,10 +1,10 @@
# Core: Autopatch.
-CORE_AUTOPATCH_TARGETS = $(call list_targets,core-autopatch)
+core_autopatch_TARGETS = $(call list_targets,core-autopatch)
-.PHONY: core-autopatch $(CORE_AUTOPATCH_TARGETS)
+.PHONY: core-autopatch $(core_autopatch_TARGETS)
-core-autopatch: $(CORE_AUTOPATCH_TARGETS)
+core-autopatch: $(core_autopatch_TARGETS)
core-autopatch-extended: init
@@ -34,7 +34,7 @@ core-autopatch-extended-erlc-opts: init
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
$i "Add couchbeam to the list of dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = couchbeam\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = couchbeam\ndep_couchbeam = git https://github.com/benoitc/couchbeam master\n"}' $(APP)/Makefile
$i "Extend autopatch-couchbeam to add options to its ERLC_OPTS"
$t echo "autopatch-couchbeam:: ; echo >> \$$(DEPS_DIR)/couchbeam/Makefile; echo 'ERLC_OPTS += -DWITH_JIFFY' >> \$$(DEPS_DIR)/couchbeam/Makefile" >> $(APP)/Makefile
@@ -93,7 +93,7 @@ core-autopatch-no-autopatch-erlang-mk: init
# $t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
#
# $i "Add Lager to the list of dependencies and to the NO_AUTOPATCH list"
-# $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lager\nNO_AUTOPATCH = lager\n"}' $(APP)/Makefile
+# $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lager\ndep_lager = git https://github.com/erlang-lager/lager master\nNO_AUTOPATCH = lager\n"}' $(APP)/Makefile
#
# $i "Build the application"
# $t $(MAKE) -C $(APP) $v
@@ -151,7 +151,7 @@ core-autopatch-rebar: init
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
$i "Add erlsha2 to the list of dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = erlsha2\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = erlsha2\ndep_erlsha2 = git https://github.com/vinoski/erlsha2 master\n"}' $(APP)/Makefile
$i "Build the application"
$t $(MAKE) -C $(APP) $v
@@ -163,6 +163,33 @@ ifneq ($(PLATFORM),msys2)
$t test -f $(APP)/deps/erlsha2/priv/erlsha2_nif.so
endif
+core-autopatch-rebar-git_subdir: 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 "Bootstrap application my_dep inside $(APP) that uses rebar"
+ $t mkdir $(APP)/my_dep
+ $t cp ../erlang.mk $(APP)/my_dep/
+ $t $(MAKE) -C $(APP)/my_dep/ -f erlang.mk bootstrap LEGACY=1 $v
+ $t rm $(APP)/my_dep/erlang.mk $(APP)/my_dep/Makefile
+
+ $i "Add a rebar.config file with git_subdir to my_dep"
+ $t echo '{deps, [{eqwalizer_support, {git_subdir, "https://github.com/whatsapp/eqwalizer.git", {branch, "main"}, "eqwalizer_support"}} ]}.' > $(APP)/my_dep/rebar.config
+
+ $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
+
+ $i "Build the application"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that eqwalizer_support was fetched and built"
+ $t test -d $(APP)/deps/eqwalizer_support
+ $t test -f $(APP)/deps/eqwalizer_support/ebin/eqwalizer.beam
+ $t test -f $(APP)/deps/eqwalizer_support/ebin/eqwalizer_specs.beam
+
# This test is expected to fail when run in parallel and flock/lockf is not available.
core-autopatch-two-rebar: init
@@ -172,7 +199,7 @@ core-autopatch-two-rebar: init
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
$i "Add two Rebar projects to the list of dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = epgsql mochiweb\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = epgsql mochiweb\ndep_epgsql = git https://github.com/epgsql/epgsql devel\ndep_mochiweb = git https://github.com/mochi/mochiweb main\n"}' $(APP)/Makefile
$i "Build the application"
$t $(MAKE) -C $(APP) $v
diff --git a/test/core_compat.mk b/test/core_compat.mk
index d9789ec..c8c570d 100644
--- a/test/core_compat.mk
+++ b/test/core_compat.mk
@@ -2,14 +2,13 @@
#
# Note: autopatch functionality is covered separately.
-CORE_COMPAT_TARGETS = $(call list_targets,core-compat)
+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)
+.PHONY: core-compat $(core_compat_TARGETS)
-core-compat: $(CORE_COMPAT_TARGETS)
+core-compat: $(core_compat_TARGETS)
core-compat-auto-rebar: init
@@ -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,14 +84,14 @@ 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
+core-compat-rebar-deps-git-branch: init
$i "Bootstrap a new OTP library named $(APP)"
$t mkdir $(APP)/
@@ -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 master\n"}' $(APP)/Makefile
$i "Run 'make rebar.config'"
$t $(MAKE) -C $(APP) rebar.config $v
@@ -108,21 +107,85 @@ core-compat-rebar-deps-git: init
$i "Check that rebar.config was created"
$t test -f $(APP)/rebar.config
- $i "Check that Cowboy is listed in rebar.config"
+ $i "Check that Cowboy is listed in rebar.config with a branch"
+ $t $(ERL) -eval " \
+ {ok, C} = file:consult(\"$(APP)/rebar.config\"), \
+ {_, [{cowboy, _, {git, _, {branch, \"master\"}}}]} = lists:keyfind(deps, 1, C), \
+ halt()"
+
+ $i "Distclean the application"
+ $t $(MAKE) -C $(APP) distclean $v
+
+ $i "Download rebar3"
+ $t curl --retry 5 -s -L -o $(APP)/rebar3 $(REBAR3_BINARY)
+ $t chmod +x $(APP)/rebar3
+
+ $i "Use rebar3 to build the application"
+ $t cd $(APP) && ./rebar3 compile $v
+
+core-compat-rebar-deps-git-ref: 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 Cowboy as a dependency"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowboy\ndep_cowboy = git https://github.com/ninenines/cowboy 7e160b49\n"}' $(APP)/Makefile
+
+ $i "Run 'make rebar.config'"
+ $t $(MAKE) -C $(APP) rebar.config $v
+
+ $i "Check that rebar.config was created"
+ $t test -f $(APP)/rebar.config
+
+ $i "Check that Cowboy is listed in rebar.config with a branch"
$t $(ERL) -eval " \
{ok, C} = file:consult(\"$(APP)/rebar.config\"), \
- {_, [{cowboy, _, {git, _, \"1.0.0\"}}]} = lists:keyfind(deps, 1, C), \
+ {_, [{cowboy, _, {git, _, {ref, \"7e160b49\"}}}]} = 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-git-tag: 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 Cowboy as a dependency"
+ $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
+
+ $i "Check that rebar.config was created"
+ $t test -f $(APP)/rebar.config
+
+ $i "Check that Cowboy is listed in rebar.config with a tag"
+ $t $(ERL) -eval " \
+ {ok, C} = file:consult(\"$(APP)/rebar.config\"), \
+ {_, [{cowboy, _, {git, _, {tag, \"2.9.0\"}}}]} = lists:keyfind(deps, 1, C), \
+ halt()"
+
+ $i "Distclean the application"
+ $t $(MAKE) -C $(APP) distclean $v
+
+ $i "Download rebar3"
+ $t curl --retry 5 -s -L -o $(APP)/rebar3 $(REBAR3_BINARY)
+ $t chmod +x $(APP)/rebar3
+
+ $i "Use rebar3 to build the application"
+ $t cd $(APP) && ./rebar3 compile $v
core-compat-rebar-deps-hex: init
@@ -132,7 +195,7 @@ core-compat-rebar-deps-hex: 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 = hex 1.0.0\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowboy\ndep_cowboy = hex 2.12.0\n"}' $(APP)/Makefile
$i "Run 'make rebar.config'"
$t $(MAKE) -C $(APP) rebar.config $v
@@ -143,7 +206,7 @@ core-compat-rebar-deps-hex: init
$i "Check that Cowboy is listed in rebar.config"
$t $(ERL) -eval " \
{ok, C} = file:consult(\"$(APP)/rebar.config\"), \
- {_, [{cowboy, \"1.0.0\"}]} = lists:keyfind(deps, 1, C), \
+ {_, [{cowboy, \"2.12.0\"}]} = lists:keyfind(deps, 1, C), \
halt()"
$i "Distclean the application"
@@ -153,7 +216,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
@@ -175,18 +238,18 @@ core-compat-rebar-deps-pkg: init
$i "Check that Cowboy is listed in rebar.config"
$t $(ERL) -eval " \
{ok, C} = file:consult(\"$(APP)/rebar.config\"), \
- {_, [{cowboy, _, {git, \"https://github.com/\" ++ _, _}}]} = lists:keyfind(deps, 1, C), \
+ {_, [{cowboy, _, {git, \"https://github.com/\" ++ _, {branch, _}}}]} = 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-erlc-opts: init
@@ -230,12 +293,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
@@ -249,7 +312,7 @@ core-compat-rebar-pt: init
$t echo "-module(girl)." > $(APP)/src/girl.erl
$i "Add lager to the list of dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lager\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lager\ndep_lager = git https://github.com/erlang-lager/lager master\n"}' $(APP)/Makefile
$i "Add the lager_transform parse_transform to ERLC_OPTS"
$t echo "ERLC_OPTS += +'{parse_transform, lager_transform}' +'{lager_truncation_size, 1234}'" >> $(APP)/Makefile
@@ -288,14 +351,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..dd052e5 100644
--- a/test/core_deps.mk
+++ b/test/core_deps.mk
@@ -1,10 +1,10 @@
# Core: Packages and dependencies.
-CORE_DEPS_TARGETS = $(call list_targets,core-deps)
+core_deps_TARGETS = $(call list_targets,core-deps)
-.PHONY: core-deps $(CORE_DEPS_TARGETS)
+.PHONY: core-deps $(core_deps_TARGETS)
-core-deps: $(CORE_DEPS_TARGETS)
+core-deps: $(core_deps_TARGETS)
ifneq ($(PLATFORM),msys2)
core-deps-build-c-8cc: init
@@ -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)"
@@ -288,8 +401,8 @@ core-deps-dep-commit: 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_commit = 1.0.0\n"}' $(APP)/Makefile
+ $i "Add Cowboy 2.12.0 to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowboy\ndep_cowboy_commit = 2.12.0\n"}' $(APP)/Makefile
ifdef LEGACY
$i "Add Cowboy to the applications key in the .app.src file"
@@ -309,7 +422,7 @@ endif
[ok = application:load(App) || App <- [$(APP), cowboy, cowlib, ranch]], \
{ok, Deps} = application:get_key($(APP), applications), \
true = lists:member(cowboy, Deps), \
- {ok, \"1.0.0\"} = application:get_key(cowboy, vsn), \
+ {ok, \"2.12.0\"} = application:get_key(cowboy, vsn), \
halt()"
core-deps-dir: init
@@ -354,7 +467,7 @@ core-deps-doc: init
$t echo "-module(girl)." > $(APP)/src/girl.erl
$i "Add Edown as a documentation building dependency"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DOC_DEPS = edown\nEDOC_OPTS = {doclet, edown_doclet}\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DOC_DEPS = edown\ndep_edown = git https://github.com/uwiger/edown master\nEDOC_OPTS = {doclet, edown_doclet}\n"}' $(APP)/Makefile
$i "Build the application"
$t $(MAKE) -C $(APP) $v
@@ -473,8 +586,8 @@ core-deps-fetch-git: 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 = git https://github.com/ninenines/cowboy 1.0.0\n"}' $(APP)/Makefile
+ $i "Add Cowboy 2.12.0 to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowboy\ndep_cowboy_commit = 2.12.0\n"}' $(APP)/Makefile
ifdef LEGACY
$i "Add Cowboy to the applications key in the .app.src file"
@@ -494,7 +607,7 @@ endif
[ok = application:load(App) || App <- [$(APP), cowboy, cowlib, ranch]], \
{ok, Deps} = application:get_key($(APP), applications), \
true = lists:member(cowboy, Deps), \
- {ok, \"1.0.0\"} = application:get_key(cowboy, vsn), \
+ {ok, \"2.12.0\"} = application:get_key(cowboy, vsn), \
halt()"
core-deps-fetch-git-subfolder: init
@@ -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 2.12.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 2.12.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), \
- {ok, \"1.0.0\"} = application:get_key(cowboy, vsn), \
+ true = lists:member(systemd, Deps), \
+ {ok, \"2.12.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.
@@ -653,23 +770,6 @@ endif
# {ok, \"4.0.3\"} = application:get_key(ehsa, vsn), \
# halt()"
-# Legacy must fail for the top-level application, but work for dependencies.
-core-deps-fetch-legacy: 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 as a dependency using a non-existing fetch method named oops"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\ndep_cowlib = https://github.com/ninenines/cowlib 1.0.0\n"}' $(APP)/Makefile
-
- $i "Check that building the application fails"
- $t ! $(MAKE) -C $(APP) $v
-
- $i "Check that building the application works with IS_DEP=1"
- $t $(MAKE) -C $(APP) IS_DEP=1 $v
-
core-deps-fetch-ln: init
$i "Bootstrap a new OTP library named $(APP)"
@@ -703,34 +803,35 @@ endif
true = lists:member(my_dep, Deps), \
halt()"
-core-deps-fetch-svn: 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 1.0.0 to the list of dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\ndep_cowlib = svn https://github.com/ninenines/cowlib/tags/1.0.0\n"}' $(APP)/Makefile
-
-ifdef LEGACY
- $i "Add Cowlib to the applications key in the .app.src file"
- $t perl -ni.bak -e 'print;if ($$.==7) {print "\t\tcowlib,\n"}' $(APP)/src/$(APP).app.src
-endif
-
- $i "Build the application"
- $t $(MAKE) -C $(APP) $v
-
- $i "Check that all dependencies were fetched"
- $t test -d $(APP)/deps/cowlib
-
- $i "Check that the application was compiled correctly"
- $t $(ERL) -pa $(APP)/ebin/ $(APP)/deps/*/ebin/ -eval " \
- [ok = application:load(App) || App <- [$(APP), cowlib]], \
- {ok, Deps} = application:get_key($(APP), applications), \
- true = lists:member(cowlib, Deps), \
- {ok, \"1.0.0\"} = application:get_key(cowlib, vsn), \
- halt()"
+# @todo Enable this test again when a host provides Subversion again.
+#core-deps-fetch-svn: 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 1.0.0 to the list of dependencies"
+# $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\ndep_cowlib = svn https://github.com/ninenines/cowlib/tags/1.0.0\n"}' $(APP)/Makefile
+#
+#ifdef LEGACY
+# $i "Add Cowlib to the applications key in the .app.src file"
+# $t perl -ni.bak -e 'print;if ($$.==7) {print "\t\tcowlib,\n"}' $(APP)/src/$(APP).app.src
+#endif
+#
+# $i "Build the application"
+# $t $(MAKE) -C $(APP) $v
+#
+# $i "Check that all dependencies were fetched"
+# $t test -d $(APP)/deps/cowlib
+#
+# $i "Check that the application was compiled correctly"
+# $t $(ERL) -pa $(APP)/ebin/ $(APP)/deps/*/ebin/ -eval " \
+# [ok = application:load(App) || App <- [$(APP), cowlib]], \
+# {ok, Deps} = application:get_key($(APP), applications), \
+# true = lists:member(cowlib, Deps), \
+# {ok, \"1.0.0\"} = application:get_key(cowlib, vsn), \
+# halt()"
core-deps-ignore: init
@@ -1105,7 +1206,7 @@ core-deps-mv-rebar: init
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
$i "Add Lager to the list of dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lager\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lager\ndep_lager = git https://github.com/erlang-lager/lager master\n"}' $(APP)/Makefile
$i "Build the application"
$t $(MAKE) -C $(APP) $v
@@ -1120,6 +1221,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
@@ -1137,8 +1264,8 @@ core-deps-order-first: init
$t cp ../erlang.mk $(APP)/my_dep/
$t $(MAKE) -C $(APP)/my_dep/ -f erlang.mk bootstrap-lib $v
- $i "Add Cowlib 1.0.0 to the list of dependencies for my_dep"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\ndep_cowlib = git https://github.com/ninenines/cowlib 1.0.0\n"}' $(APP)/my_dep/Makefile
+ $i "Add Cowlib 2.0.0 to the list of dependencies for my_dep"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\ndep_cowlib = git https://github.com/ninenines/cowlib 2.0.0\n"}' $(APP)/my_dep/Makefile
ifdef LEGACY
$i "Add Cowboy and my_dep to the applications key in the .app.src file"
@@ -1159,7 +1286,7 @@ endif
[ok = application:load(App) || App <- [$(APP), cowboy, cowlib, my_dep, ranch]], \
{ok, Deps} = application:get_key($(APP), applications), \
true = lists:member(cowboy, Deps), \
- {ok, \"1.0.0\"} = application:get_key(cowlib, vsn), \
+ {ok, \"2.0.0\"} = application:get_key(cowlib, vsn), \
halt()"
# A higher-level dependency always wins.
@@ -1170,8 +1297,8 @@ core-deps-order-top: init
$t cp ../erlang.mk $(APP)/
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib $v
- $i "Add Cowboy package and Cowlib 1.0.0 to the list of dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowboy cowlib\ndep_cowlib = git https://github.com/ninenines/cowlib 1.0.0\n"}' $(APP)/Makefile
+ $i "Add Cowboy package and Cowlib 2.0.0 to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowboy cowlib\ndep_cowlib = git https://github.com/ninenines/cowlib 2.0.0\n"}' $(APP)/Makefile
ifdef LEGACY
$i "Add Cowboy to the applications key in the .app.src file"
@@ -1191,7 +1318,7 @@ endif
[ok = application:load(App) || App <- [$(APP), cowboy, cowlib, ranch]], \
{ok, Deps} = application:get_key($(APP), applications), \
true = lists:member(cowboy, Deps), \
- {ok, \"1.0.0\"} = application:get_key(cowlib, vsn), \
+ {ok, \"2.0.0\"} = application:get_key(cowlib, vsn), \
halt()"
ifndef LEGACY
@@ -1257,7 +1384,7 @@ core-deps-rel: init
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib bootstrap-rel $v
$i "Add Recon to the list of release dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "REL_DEPS = recon\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "REL_DEPS = recon\ndep_recon = git https://github.com/ferd/recon master\n"}' $(APP)/Makefile
$i "Add Recon to the relx.config file"
$t $(ERL) -eval " \
@@ -1270,8 +1397,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 +1410,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 +1425,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_elixir.mk b/test/core_elixir.mk
new file mode 100644
index 0000000..c2cec70
--- /dev/null
+++ b/test/core_elixir.mk
@@ -0,0 +1,326 @@
+# Core: Miscellaneous.
+#
+# The miscellaneous tests use the prefix "core-", not "core-misc-".
+
+CORE_ELIXIR_TARGETS = $(call list_targets,core-elixir)
+
+.PHONY: core-elixir $(CORE_ELIXIR_TARGETS)
+
+core-elixir: $(CORE_ELIXIR_TARGETS)
+
+core-elixir-compile-from-lib: 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 Elixir source file hello.ex"
+ $t mkdir $(APP)/lib
+ $t printf "%s\n" \
+ "defmodule HelloWorld do" \
+ " def hello do" \
+ ' IO.puts("Hello, world!")' \
+ " end" \
+ "end" > $(APP)/lib/hello.ex
+
+ $i "Build the application"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that all compiled files exist"
+ $t test -f $(APP)/ebin/$(APP).app
+ $t test -f $(APP)/ebin/Elixir.HelloWorld.beam
+
+ $i "Check that the application was compiled correctly"
+ $t $(ERL) -pa $(APP)/ebin/ -pa $(APP)/deps/*/ebin -pa $(dir $(shell elixir -e 'IO.puts(:code.lib_dir(:elixir))'))/*/ebin -eval " \
+ ok = application:start($(APP)), \
+ {ok, Mods = ['Elixir.HelloWorld']} \
+ = application:get_key($(APP), modules), \
+ [{module, M} = code:load_file(M) || M <- Mods], \
+ halt()"
+
+core-elixir-compile-from-src: 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 Elixir source file hello.ex"
+ $t printf "%s\n" \
+ "defmodule HelloWorld do" \
+ " def hello do" \
+ ' IO.puts("Hello, world!")' \
+ " end" \
+ "end" > $(APP)/src/hello.ex
+
+ $i "Build the application"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that all compiled files exist"
+ $t test -f $(APP)/ebin/$(APP).app
+ $t test -f $(APP)/ebin/Elixir.HelloWorld.beam
+
+ $i "Check that the application was compiled correctly"
+ $t $(ERL) -pa $(APP)/ebin/ -pa $(APP)/deps/*/ebin -pa $(dir $(shell elixir -e 'IO.puts(:code.lib_dir(:elixir))'))/*/ebin -eval " \
+ ok = application:start($(APP)), \
+ {ok, Mods = ['Elixir.HelloWorld']} \
+ = application:get_key($(APP), modules), \
+ [{module, M} = code:load_file(M) || M <- Mods], \
+ halt()"
+
+core-elixir-disable: 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 Elixir source file hello.ex"
+ $t printf "%s\n" \
+ "defmodule HelloWorld do" \
+ " def hello do" \
+ ' IO.puts("Hello, world!")' \
+ " end" \
+ "end" > $(APP)/src/hello.ex
+
+ $i "Disable Elixir in the Makefile"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "ELIXIR = disable\n"}' $(APP)/Makefile
+
+ $i "Build the application"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that the Elixir file wasn't compiled"
+ $t test -f $(APP)/ebin/$(APP).app
+ $t test ! -e $(APP)/ebin/Elixir.HelloWorld.beam
+
+ $i "Check that the application was compiled correctly"
+ $t $(ERL) -pa $(APP)/ebin/ -pa $(APP)/deps/*/ebin -pa $(dir $(shell elixir -e 'IO.puts(:code.lib_dir(:elixir))'))/*/ebin -eval " \
+ ok = application:start($(APP)), \
+ {ok, Mods = []} \
+ = application:get_key($(APP), modules), \
+ halt()"
+
+core-elixir-disable-autopatch-fail: 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 Jason to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = jason\ndep_jason = git https://github.com/michalmuskala/jason.git master\n"}' $(APP)/Makefile
+
+ $i "Disable Elixir in the Makefile"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "ELIXIR = disable\n"}' $(APP)/Makefile
+
+ $i "Building the application should fail"
+ $t ! $(MAKE) -C $(APP) $v
+
+core-elixir-disable-autopatch-erlang-mk: 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 Jose to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = jose\ndep_jose = git https://github.com/potatosalad/erlang-jose main\n"}' $(APP)/Makefile
+
+ $i "Disable Elixir in the Makefile"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "ELIXIR = disable\n"}' $(APP)/Makefile
+
+ $i "Building the application should work as Jose is Erlang.mk-compatible"
+ $t $(MAKE) -C $(APP) $v
+
+core-elixir-disable-autopatch-make: 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 Reloader to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = reloader\ndep_reloader = git https://github.com/2600hz/erlang-reloader de1e6c74204b61ccf3b3652f05c6a7dec9e8257d\n"}' $(APP)/Makefile
+
+ $i "Disable Elixir in the Makefile"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "ELIXIR = disable\n"}' $(APP)/Makefile
+
+ $i "Building the application should work as Reloader contains a proper Makefile"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Confirm Reloader was built"
+ $t test -f $(APP)/deps/reloader/ebin/dep_built
+ $t test -f $(APP)/deps/reloader/ebin/reloader.app
+ $t test -f $(APP)/deps/reloader/ebin/reloader.beam
+
+core-elixir-disable-autopatch-rebar3: 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 OpenTelemetry_API to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = opentelemetry_api\ndep_opentelemetry_api = hex 1.3.0\n"}' $(APP)/Makefile
+
+ $i "Disable Elixir in the Makefile"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "ELIXIR = disable\n"}' $(APP)/Makefile
+
+ $i "Building the application should work as OpenTelemetry_API is Rebar3-compatible"
+ $t $(MAKE) -C $(APP) $v
+
+core-elixir-disable-by-default-autopatch-rebar3: 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 OpenTelemetry_API to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = opentelemetry_api\ndep_opentelemetry_api = hex 1.3.0\n"}' $(APP)/Makefile
+
+ $i "Building the application should work as OpenTelemetry_API is Rebar3-compatible"
+ $t $(MAKE) -C $(APP) $v
+
+core-elixir-from-dep: 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 Elixir, Lager, Jason, Phoenix to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = elixir lager jason phoenix\ndep_elixir_commit = v1.17.3\ndep_lager = git https://github.com/erlang-lager/lager master\ndep_jason = git https://github.com/michalmuskala/jason.git master\ndep_phoenix = hex 1.7.2\n"}' $(APP)/Makefile
+
+ $i "Add the lager_transform parse_transform to ERLC_OPTS"
+ $t echo "ERLC_OPTS += +'{parse_transform, lager_transform}'" >> $(APP)/Makefile
+
+ifdef LEGACY
+ $i "Add Elixir, Lager, Jason and Phoenix to the applications key in the .app.src file"
+ $t perl -ni.bak -e 'print;if ($$.==7) {print "\t\telixir,\n\t\tlager,\n\t\tjason,\n\t\tphoenix,\n"}' $(APP)/src/$(APP).app.src
+endif
+
+ $i "Build the application"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that all dependencies were fetched and built"
+ $t test -f $(APP)/deps/elixir/ebin/dep_built
+ $t test -f $(APP)/deps/lager/ebin/dep_built
+ $t test -f $(APP)/deps/jason/ebin/dep_built
+ $t test -f $(APP)/deps/phoenix/ebin/dep_built
+
+ $i "Check that the application was compiled correctly"
+ $t cd $(APP); $(ERL) -pa ebin/ -pa deps/*/ebin -pa deps/elixir/lib/*/ebin -eval " \
+ {ok, Apps} = application:ensure_all_started('$(APP)'), \
+ true = lists:member(elixir, Apps), \
+ true = lists:member(lager, Apps), \
+ true = lists:member(jason, Apps), \
+ true = lists:member(phoenix, Apps), \
+ halt()"
+
+ $i "Check that the Jason application depends on Elixir builtins"
+ $t cd $(APP); $(ERL) -pa ebin/ -pa deps/*/ebin -pa deps/elixir/lib/*/ebin -eval " \
+ {ok, Apps} = application:ensure_all_started(jason), \
+ true = lists:member(elixir, Apps), \
+ true = lists:member(eex, Apps), \
+ true = lists:member(logger, Apps), \
+ true = lists:member(mix, Apps), \
+ halt()"
+
+core-elixir-from-system: 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 Lager, Jason, Phoenix to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lager jason phoenix\ndep_lager = git https://github.com/erlang-lager/lager master\ndep_jason = git https://github.com/michalmuskala/jason.git master\ndep_phoenix = hex 1.7.2\nELIXIR = system\n"}' $(APP)/Makefile
+
+ $i "Add the lager_transform parse_transform to ERLC_OPTS"
+ $t echo "ERLC_OPTS += +'{parse_transform, lager_transform}'" >> $(APP)/Makefile
+
+ifdef LEGACY
+ $i "Add Lager, Jason and Phoenix to the applications key in the .app.src file"
+ $t perl -ni.bak -e 'print;if ($$.==7) {print "\t\telixir,\n\t\tlager,\n\t\tjason,\n\t\tphoenix,\n"}' $(APP)/src/$(APP).app.src
+endif
+
+ $i "Build the application"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that all dependencies were fetched and built"
+ $t ! test -e $(APP)/deps/elixir
+ $t test -f $(APP)/deps/lager/ebin/dep_built
+ $t test -f $(APP)/deps/jason/ebin/dep_built
+ $t test -f $(APP)/deps/phoenix/ebin/dep_built
+
+ $i "Check that the application was compiled correctly"
+ $t cd $(APP); $(ERL) -pa ebin/ -pa deps/*/ebin -pa $(dir $(shell elixir -e 'IO.puts(:code.lib_dir(:elixir))'))/*/ebin -eval " \
+ {ok, Apps} = application:ensure_all_started('$(APP)'), \
+ true = lists:member(lager, Apps), \
+ true = lists:member(jason, Apps), \
+ true = lists:member(phoenix, Apps), \
+ halt()"
+
+ $i "Check that the Jason application depends on Elixir builtins"
+ $t cd $(APP); $(ERL) -pa ebin/ -pa deps/*/ebin -pa $(dir $(shell elixir -e 'IO.puts(:code.lib_dir(:elixir))'))/*/ebin -eval " \
+ {ok, Apps} = application:ensure_all_started(jason), \
+ true = lists:member(elixir, Apps), \
+ true = lists:member(eex, Apps), \
+ true = lists:member(logger, Apps), \
+ true = lists:member(mix, Apps), \
+ halt()"
+
+core-elixir-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 "Add Libsalty2 to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = libsalty2\ndep_libsalty2 = git https://github.com/Ianleeclark/libsalty2.git b11e544\nELIXIR = system\n"}' $(APP)/Makefile
+
+ifdef LEGACY
+ $i "Add Libsalty2 to the applications key in the .app.src file"
+ $t perl -ni.bak -e 'print;if ($$.==7) {print "\t\tlibsalty2,\n"}' $(APP)/src/$(APP).app.src
+endif
+
+ $i "Build the application"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that the application was compiled correctly"
+ $t $(ERL) -pa $(APP)/ebin/ -pa $(APP)/deps/*/ebin -pa $(dir $(shell elixir -e 'IO.puts(:code.lib_dir(:elixir))'))/*/ebin -eval " \
+ {ok, Apps} = application:ensure_all_started('$(APP)'), \
+ true = lists:member(libsalty2, Apps), \
+ halt()"
+
+core-elixir-rel: init
+
+ $i "Bootstrap a new release named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap-lib bootstrap-rel $v
+
+ $i "Add Lager, Jason, Phoenix to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lager jason phoenix\ndep_lager = git https://github.com/erlang-lager/lager master\ndep_jason = git https://github.com/michalmuskala/jason.git master\ndep_phoenix = hex 1.7.2\nELIXIR = system\n"}' $(APP)/Makefile
+
+ $i "Add the lager_transform parse_transform to ERLC_OPTS"
+ $t echo "ERLC_OPTS += +'{parse_transform, lager_transform}'" >> $(APP)/Makefile
+
+ifdef LEGACY
+ $i "Add Lager, Jason and Phoenix to the applications key in the .app.src file"
+ $t perl -ni.bak -e 'print;if ($$.==7) {print "\t\tlager,\n\t\tjason,\n\t\tphoenix,\n"}' $(APP)/src/$(APP).app.src
+endif
+
+ $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/1
diff --git a/test/core_makedep.mk b/test/core_makedep.mk
index 5a0b02c..6efb2df 100644
--- a/test/core_makedep.mk
+++ b/test/core_makedep.mk
@@ -1,10 +1,10 @@
# Core: COMPILE_FIRST dependencies generation.
-CORE_MAKEDEP_TARGETS = $(call list_targets,core-makedep)
+core_makedep_TARGETS = $(call list_targets,core-makedep)
-.PHONY: core-makedep $(CORE_MAKEDEP_TARGETS)
+.PHONY: core-makedep $(core_makedep_TARGETS)
-core-makedep: $(CORE_MAKEDEP_TARGETS)
+core-makedep: $(core_makedep_TARGETS)
core-makedep-behavior: init
@@ -25,6 +25,46 @@ core-makedep-behavior: init
$t test -f $(APP)/ebin/boy.beam
$t test -f $(APP)/ebin/human.beam
+core-makedep-ignore-filenames-with-spaces: 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/my\ 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-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_misc.mk b/test/core_misc.mk
index 9b7aa92..3cd8562 100644
--- a/test/core_misc.mk
+++ b/test/core_misc.mk
@@ -2,11 +2,11 @@
#
# The miscellaneous tests use the prefix "core-", not "core-misc-".
-CORE_MISC_TARGETS = $(filter-out core-misc,$(call list_targets,core))
+core_misc_TARGETS = $(filter-out core-misc,$(call list_targets,core))
-.PHONY: core-misc $(CORE_MISC_TARGETS)
+.PHONY: core-misc $(core_misc_TARGETS)
-core-misc: $(CORE_MISC_TARGETS)
+core-misc: $(core_misc_TARGETS)
core-clean-crash-dump: init
diff --git a/test/core_plugins.mk b/test/core_plugins.mk
index f8fbff3..8544945 100644
--- a/test/core_plugins.mk
+++ b/test/core_plugins.mk
@@ -1,10 +1,10 @@
# Core: External plugins.
-CORE_PLUGINS_TARGETS = $(call list_targets,core-plugins)
+core_plugins_TARGETS = $(call list_targets,core-plugins)
-.PHONY: core-plugins $(CORE_PLUGINS_TARGETS)
+.PHONY: core-plugins $(core_plugins_TARGETS)
-core-plugins: $(CORE_PLUGINS_TARGETS)
+core-plugins: $(core_plugins_TARGETS)
core-plugins-all: init
@@ -194,7 +194,7 @@ core-plugins-templates: init
$t mkdir -p $(APP)/plugin_dep
$t printf "%s\n" \
"define tpl_test_mk" \
- "-module(test_mk)." \
+ "-module(template_name)." \
"endef" > $(APP)/plugin_dep/plugins.mk
$t cd $(APP)/plugin_dep && \
git init -q && \
@@ -263,6 +263,43 @@ core-plugins-templates-apps-only: init
$i "Check that the file was compiled correctly"
$t test -f $(APP)/apps/my_app/ebin/test_mk.beam
+core-plugins-templates-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 "Create a local git repository with a plugin containing a template file"
+ $t mkdir -p $(APP)/plugin_dep/templates
+ $t printf "%s\n" "-module(template_name)." > $(APP)/plugin_dep/templates/test_mk.erl
+ $t echo "THIS := \$$(dir \$$(realpath \$$(lastword \$$(MAKEFILE_LIST))))" > $(APP)/plugin_dep/plugins.mk
+ $t printf "%s\n" "tpl_test_mk = \$$(file < \$$(THIS)/templates/test_mk.erl)" >> $(APP)/plugin_dep/plugins.mk
+ $t cd $(APP)/plugin_dep && \
+ git init -q && \
+ git config user.email "[email protected]" && \
+ git config user.name "test suite" && \
+ git add . && \
+ git commit -q --no-gpg-sign -m "Tests"
+
+ $i "Add dependency and plugins to the Makefile"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = plugin_dep\ndep_plugin_dep = git file://$(abspath $(APP)/plugin_dep) master\nDEP_PLUGINS = plugin_dep\n"}' $(APP)/Makefile
+
+ $i "Run 'make list-templates' and check that it prints test_mk"
+ $t $(MAKE) --no-print-directory -C $(APP) list-templates | grep -qw test_mk
+
+ $i "Create a new file using the template"
+ $t $(MAKE) --no-print-directory -C $(APP) new t=test_mk n=test_mk $v
+
+ $i "Confirm the file exists"
+ $t test -f $(APP)/src/test_mk.erl
+
+ $i "Build the application"
+ $t $(MAKE) -C $(APP) $v
+
+ $i "Check that the file was compiled correctly"
+ $t test -f $(APP)/ebin/test_mk.beam
+
core-plugins-test: init
$i "Bootstrap a new OTP library named $(APP)"
diff --git a/test/core_query.mk b/test/core_query.mk
index 380f4ad..394652a 100644
--- a/test/core_query.mk
+++ b/test/core_query.mk
@@ -1,10 +1,10 @@
# Core: Querying dependencies.
-CORE_QUERY_TARGETS = $(call list_targets,core-query)
+core_query_TARGETS = $(call list_targets,core-query)
-.PHONY: core-query $(CORE_QUERY_TARGETS)
+.PHONY: core-query $(core_query_TARGETS)
-core-query: $(CORE_QUERY_TARGETS)
+core-query: $(core_query_TARGETS)
core-query-deps: init
@@ -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 master" \
> $(APP)/expected-deps.txt
$t cmp $(APP)/expected-deps.txt $(APP)/.erlang.mk/query-deps.log
diff --git a/test/core_upgrade.mk b/test/core_upgrade.mk
index 84ff54a..c9fea3d 100644
--- a/test/core_upgrade.mk
+++ b/test/core_upgrade.mk
@@ -1,10 +1,10 @@
# Core: Erlang.mk upgrade.
-CORE_UPGRADE_TARGETS = $(call list_targets,core-upgrade)
+core_upgrade_TARGETS = $(call list_targets,core-upgrade)
-.PHONY: core-upgrade $(CORE_UPGRADE_TARGETS)
+.PHONY: core-upgrade $(core_upgrade_TARGETS)
-core-upgrade: $(CORE_UPGRADE_TARGETS)
+core-upgrade: $(core_upgrade_TARGETS)
core-upgrade-changelog: init
@@ -16,8 +16,6 @@ core-upgrade-changelog: init
$i "Fork erlang.mk locally and set a test CHANGELOG.asciidoc"
$t git clone -q https://github.com/ninenines/erlang.mk $(APP)/alt-erlangmk-repo
$t echo "$(APP)$(APP)" > $(APP)/alt-erlangmk-repo/CHANGELOG.asciidoc
-# Since part of this functionality needs the main Makefile, copy it.
- $t cp ../Makefile $(APP)/alt-erlangmk-repo/
$t (cd $(APP)/alt-erlangmk-repo && \
git config user.email "[email protected]" && \
git config user.name "test suite" && \
diff --git a/test/hexpm_packages.txt b/test/hexpm_packages.txt
new file mode 100644
index 0000000..0a55766
--- /dev/null
+++ b/test/hexpm_packages.txt
@@ -0,0 +1,2052 @@
+# Packages page 1
+abnfc 0.5.4
+accept 0.3.5
+acceptor_pool 1.0.0
+achlys 0.3.3
+acorn128 0.0.1
+# Packages page 2
+active 7.11.0
+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
+aiml_model_wrapper 0.1.0
+alcove 0.40.6
+aleppo 0.9.0
+# Packages page 4
+alsa 0.2.3
+altworx_utils 0.0.5
+amf 0.1.4
+amoc 3.3.0
+amqp10_client 4.0.3
+amqp10_common 4.0.3
+amqp_client 4.0.3
+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
+# Packages page 5
+antidote_pb_codec 0.1.2
+any 0.3.2
+apcl 0.1.0
+apdu 0.2.0
+apns4erl 2.6.0
+aqlc 1.0.2
+# Packages page 6
+argo_graphql 1.0.10
+argon2 1.2.0
+argparse 2.0.0
+ascii_table 1.1.6
+# Packages page 7
+assert 0.1.0
+astranaut 0.10.1
+ast_walk 0.3.1
+aten 0.6.0
+atom_utils 1.0.13
+atomvm_packbeam 0.7.2
+atomvm_rebar3_plugin 0.7.3
+# Packages page 8
+augle 0.3.0
+avlizer 0.4.0
+avm_scene 0.1.0
+aws_cli 0.1.0
+aws_credentials 0.3.2
+aws_erlang 1.0.6
+aws_http 0.2.4
+aws_rds_castore 1.2.2
+aws_signature 0.3.2
+# Packages page 9
+b64fast 0.2.3
+b64_nif 0.1.4
+backoff 1.1.6
+backwater 3.6.0
+baleen 1.0.3
+banana_websocket_client 0.0.2
+bank 0.2.2
+# Packages page 10
+bare 0.1.1
+barista 0.3.4
+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 2.0.0
+base64url 1.0.1
+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
+# Packages page 11
+bcrypt 1.2.2
+beamcache 0.7.9
+beamoji 0.1.0
+beam_olympics 1.2.3
+beanstalkd_consumer 3.0.7
+bear 1.1.0
+behavior3 2.0.1
+behavior3erl 1.0.0
+bellboy 2.0.0
+bencoding 1.0.0
+bert 0.2.1
+betterstack_logger 1.0.2
+# Packages page 12
+binbo 4.0.3
+binpp 1.1.1
+bitcask 2.0.2
+bit_utils 1.0.7
+# Packages page 13
+blas 1.0.0
+blockade 0.2.1
+blockfrost_erlang 0.1.1
+bloodbath 1.0.0
+blume 0.1.1
+# Packages page 14
+bookish_spork 0.5.2
+bootstrap 1.1.0
+boto 0.0.1
+bottomer 0.1.1
+boxer 0.1.0
+bpe 9.9.6
+branca_erl 0.3.0
+# Packages page 15
+bristow 0.2.2
+brod 4.3.2
+brod_gssapi 0.1.3
+brod_oauth 0.1.0
+broen 3.0.3
+brotli 0.3.2
+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 16
+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.31
+# Packages page 17
+canal 0.4.2
+canister 0.1.1
+captcherl 0.1.1
+cargo 0.1.3
+# Packages page 18
+cerck 0.1.5
+cerlc 0.2.1
+certifi 2.13.0
+cet 0.3.4
+cets 0.2.0
+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.7
+# Packages page 19
+channel 0.1.0
+chash 0.1.2
+chatapp 0.1.0
+chatterbox 0.8.0
+choke 1.0.0
+# Packages page 20
+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 21
+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.7
+cloudi_service_api_batch 2.0.7
+cloudi_service_api_requests 2.0.7
+cloudi_service_cron 2.0.7
+cloudi_service_db_http_elli 1.6.0
+cloudi_service_db_pgsql 2.0.7
+cloudi_service_filesystem 2.0.7
+cloudi_service_funnel 2.0.7
+cloudi_service_health_check 2.0.7
+cloudi_service_http_client 2.0.7
+cloudi_service_http_cowboy 2.0.7
+cloudi_service_http_cowboy1 2.0.7
+cloudi_service_http_elli 2.0.7
+cloudi_service_http_rest 2.0.7
+cloudi_service_map_reduce 2.0.7
+cloudi_service_monitoring 2.0.7
+cloudi_service_null 2.0.7
+cloudi_service_oauth1 2.0.7
+cloudi_service_queue 2.0.7
+cloudi_service_quorum 2.0.7
+cloudi_service_request_rate 2.0.7
+cloudi_service_router 2.0.7
+cloudi_service_send 2.0.7
+cloudi_service_shell 2.0.7
+cloudi_service_tcp 2.0.7
+cloudi_service_udp 2.0.7
+cloudi_service_validate 2.0.7
+cloudi_service_validate_config 2.0.7
+cm17a 0.3.2
+cmd 1.0.0
+# Packages page 22
+code_utils 1.1.9
+coers 0.5.0
+coldstrap 0.1.0
+# Packages page 23
+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
+# Packages page 24
+context 0.1.0
+# Packages page 25
+couchbeam 1.5.3
+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.7
+cowbell 1.0.1
+cowboy 2.12.0
+cowboy_graphql 0.2.1
+cowboy_oauth 0.2.14
+cowboy_otel 0.2.0
+cowboy_session 1.0.0
+cowboy_swagger 2.7.0
+cowboy_telemetry 0.4.0
+cowlib 2.13.0
+cowmachine 1.13.0
+cozo 0.1.0
+cozodb 0.1.0
+cpg 2.0.7
+cpool 0.1.1
+cps 0.4.0
+cqerl 2.1.3
+# Packages page 26
+crc 0.10.5
+crc32cer 0.1.11
+cre 0.1.8
+credentials_obfuscation 3.4.0
+crossover_io 0.1.0
+crypt 1.0.3
+cryptoapis 1.7.0
+crypto_ext 0.1.4
+crypto_rsassa_pss 2.0.0
+csh2fjhyll_rdb 1.5.6
+# Packages page 27
+csve 3.0.3
+csv_reader 1.0.0
+ct_containers 0.1.1
+ctdh 1.0.1
+ct_groups_summary_hook 0.1.1
+cth_readable 1.6.0
+cttest 6.0.18
+ctx 0.6.0
+cuckoo_cache 0.1.2
+cuckoo_filter 1.0.1
+cuneiform 3.0.4
+curry_erlang 0.1.0
+customized_hdr_histogram 0.3.2
+cut 1.0.3
+cuttlefish 3.4.0
+# Packages page 28
+damm 0.1.0
+darcy 0.0.8
+dasherl 0.2.15
+datalog 2.0.2
+datum 4.6.1
+# Packages page 29
+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_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 30
+denrei 0.2.5
+depcache 1.10.0
+derby 0.2.0
+dflow 0.3.0
+dhcp 1.0.0
+dhcp_lib 1.0.0
+dh_date 1.0.0
+# Packages page 31
+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
+dirs 0.2.0
+discourse_as_sso_erlang 0.7.0
+dispatch_compiler 1.1.0
+# Packages page 32
+dj 0.3.0
+dll_loader_helper_beam 1.2.2
+dns_erlang 1.1.0
+dnssec 0.1.2
+do 2.0.2
+docker_compose_cth 0.3.0
+dockerexec 2.0.3
+docsh 0.7.2
+doctest 0.9.3
+doctest_pg 1.2.3
+dogstatsc 0.1.0
+dogstatsde 1.0.0
+doppler 0.1.0
+dorer 0.1.0
+doteki 1.1.0
+dotenv_config 2.3.3
+# Packages page 33
+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
+dragon_pubsub 0.0.0
+dragon_routes 0.0.0
+dtl 0.12.1
+dtrans 1.2.0
+dtu 0.1.3
+duoweb 1.0.0
+# Packages page 34
+e2h 0.4.2
+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 3.0.0
+ebils 0.1.1
+ebitmap 0.2.3
+eblake2 1.0.0
+eblurhash 1.2.2
+ebox 1.0.1
+ebpf 0.2.3
+ebs 2.1.0
+ecache 2.14.2
+ecaptcha 0.2.0
+ecat 1.0.0
+ecbor 0.7.1
+ecc_compact 1.1.1
+echc 0.1.0
+ecies 1.1.0
+ecimd2 0.0.8
+ecms 1.0.0
+ecoap 0.1.0
+ecomm 1.0.2
+econfig 0.7.3
+ecpool 0.4.2
+ecql 5.1.3
+ecron 1.0.0
+# Packages page 35
+ecrontab 0.6.1
+ecsv 1.4.2
+# Packages page 36
+# Packages page 37
+ecureuil 1.0.2
+edate 1.0.0
+edbg 0.9.6
+edgar 1.0.2
+edifa 1.0.0
+ediff 1.0.0
+edis_proto 0.2.0
+edocmermaid 0.1.0
+edown 0.9.1
+educkdb 0.7.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.10
+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
+egit 0.1.9
+egithub 0.7.0
+egoc 0.1.1
+egoth 0.1.0
+# Packages page 38
+egssapi 0.1.0
+eharbor 1.0.0
+ehash 0.2.1
+ehashids 0.1.4
+eiconv 1.0.0
+eimp 1.0.23
+eini 1.2.9
+eini_beam 2.2.4
+eipmi 4.1.0
+ejabberd 24.10.0
+ejpet 0.8.0
+ejsonpath 0.2.1
+ejwt 0.1.0
+ekka 0.7.4
+elab 0.1.0
+elb 1.0.1
+eld 1.0.0-beta1
+elector 0.3.0
+eleveldb 2.2.20
+elib 0.0.1
+elibphonenumber 8.13.50
+# Packages page 39
+# Packages page 40
+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.2
+elogstash 1.0.0
+elogx 0.0.2
+elru 1.1.0
+elvis 3.2.6
+elvis_core 3.2.5
+em 7.3.0
+email_validator 1.1.0
+emarkdown 0.1.0
+emeter 18.6.13
+emmap 2.1.1
+emo 0.3.1
+# Packages page 41
+emodel 1.6.0
+emojipoo 0.1.0
+emon 0.2.1
+emqtt 1.11.0
+emqx_ct_helpers 1.1.4
+emsgpack 0.8.0
+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
+enet 1.0.0
+enoise 1.1.0
+enough 0.1.0
+ensq 0.1.7
+entropy_string_erl 1.1.1
+eodbc 0.2.0
+ep 0.2.0
+epam 1.0.14
+epcap 1.1.3
+epcap_compile 1.0.6
+eper 0.99.1
+epgpool 1.1.1
+epgsql 4.7.1
+epgsql_decimal 1.0.0
+ephemeral 2.0.4
+ephp 0.3.1
+epipe 1.0.0
+# Packages page 42
+epl 0.2.0
+epmdless 0.3.0
+epmdlib 1.0.0
+epns 1.1.0
+epocxy 1.1.0
+epqueue 1.2.6
+epsql 0.1.0
+epubnub 0.1.0
+eql 0.2.0
+equery 0.17.2
+eradius 2.3.1
+erbloom 2.1.0-rc.2
+erc 0.1.1
+eredis 1.7.1
+eredis_cluster 0.9.0
+eredis_pool 2.1.0
+eredis_streams 0.1.0
+eredis_sync 0.1.4
+ereturn 18.6.14
+ergb 0.2.8
+erg_unicode 0.1.0
+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.3
+erlang_decorators 0.3.1
+erlang_doctor 0.2.7
+erlang_ds 0.4.1
+erlang_exif 3.0.0
+erlang_json_logger 0.2.0
+erlang_localtime 1.0.0
+erlang_osc 1.0.1
+erlang_pbkdf2 2.0.5
+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.7
+erlang_tls 1.0.3
+erlang_version 0.2.0
+erlang_xxhash 0.2.0
+erlangzmq 1.1.2
+erlastic_search 1.5.0
+erlavro 2.9.10
+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.3
+erl_cbor 2.0.1
+erlchronos 2.0.1
+erl_cidr 1.2.1
+erlcloud 3.8.1
+erlcode 0.1.0
+erlcron 1.2.3
+erl_csv 0.3.2
+erldb 1.0.0
+erldist_filter 1.1.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.7
+erl_exercism 0.2.0
+erlfdb 0.2.1
+erlffx 1.2.0
+erlflake 0.1.1
+# Packages page 43
+erlflow 0.1.0
+erlfmt 1.5.0
+erlguten 1.0.0
+erl_hash 1.0.5
+erliam 1.0.1
+erlias 0.2.0
+erljson 0.2.1
+erljwt 2.1.0
+erlkaf 2.1.6
+erllambda 2.2.3
+erlmemfs 0.1.0
+erlmld 1.2.0
+erl_nbt 1.0.0
+erlogger 0.1.0
+erlogstash 0.10.7
+erlpass 1.0.7
+erlPass 0.3.0
+erl_pengine 0.1.1
+erlperf 2.3.0
+erl_pipeline 0.2.0
+erlpocket 2.1.0
+erlpool 1.4.4
+erlpop 2.3.1
+erlport 0.11.0
+erlquad 1.1.2
+erlquery 0.4.0
+erlsass 1.1.1
+erlsci_getopt 1.1.0
+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.7.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.4
+erlzord 1.1.0
+erocksdb 0.4.1
+erpcgen 1.1.1
+erqwest 0.2.5
+ersip 1.1.0
+erupt 0.1.0
+erupt_mysql 0.1.0
+erupt_postgres 0.1.0
+erupt_sqlite3 0.1.0
+erwatch 0.3.0
+esaml 4.6.0
+esel 0.1.2
+esimdjson 0.1.0
+esip 1.0.56
+esmpp 0.0.13
+esnowflake 0.4.3
+esockd 5.8.2
+espace 0.8.0
+# Packages page 44
+esq 2.0.6
+esqlcipher 2.0.0-rc.3
+esqlite 0.8.8
+esss 1.0.3
+estdinout 1.0.0
+estore 0.1.10
+esvm 1.0.0
+esysevent 1.0.0
+etacacs_plus 0.1.3
+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.2
+etrie 1.1.0
+ets_cas 0.1.1
+etskv 0.2.0
+etsmgr 0.2.0
+euneus 2.4.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
+# Packages page 45
+evaluator 0.1.3
+evel 0.1.2
+event_store_db_gpb_protobufs 2.4.0
+evews 0.1.9
+evision 0.2.9
+ewc 1.0.0
+ewpcap 1.1.5
+# Packages page 46
+exat 0.1.0
+# Packages page 47
+# Packages page 48
+# Packages page 49
+exe 7.11.0
+exec 1.0.1
+exemplar 0.6.0
+exerl 0.2.2
+exerl_build 0.0.2
+exerl_dep 0.0.2
+# Packages page 50
+# Packages page 51
+# Packages page 52
+# Packages page 53
+exodus 0.1.0
+exodus_mysql 0.1.0
+exodus_postgres 0.1.0
+exodus_sqlite3 0.1.0
+exometer_core 2.0.0
+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 54
+# Packages page 55
+# Packages page 56
+# Packages page 57
+# Packages page 58
+# Packages page 59
+ezic 0.2.3
+ezlib 1.0.13
+ezstd 1.1.0
+fake_lager 1.0.0
+fake_turn 0.4.3
+fast_base16 1.1.1
+# Packages page 60
+fast_pbkdf2 1.0.6
+fast_scram 0.6.0
+fast_tls 1.1.22
+fast_xml 1.1.53
+fast_yaml 1.0.37
+fcm 0.1.0
+fernet 0.1.0
+fieldmask 0.0.1
+fifocache 1.0.1
+fifo_db 0.2.8
+# Packages page 61
+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 2.2.0
+fire 0.1.4
+firebase_admin 0.1.3
+firebase_token 1.1.1
+fixer 0.2.4
+# Packages page 62
+flatlog 0.1.2
+fling 1.0.1
+# Packages page 63
+fn 1.0.0
+foil 0.1.3
+folsom 1.0.0
+folsom_ddb 0.3.1
+folsomite 1.3.0
+foodog 0.2.1
+form 8.3.0
+forms 0.0.1
+forseti 2.2.0
+# Packages page 64
+freshman_test 0.2.1
+fs 8.6.1
+fs_erlsci 8.7.1
+fs_event 1.0.0
+fs_sync 1.1.3
+fswitch 1.4.1
+ftpfilez 1.3.0
+fusco 0.1.1
+fuse 2.5.0
+# Packages page 65
+gdminus 1.2.0
+geas 2.8.1
+geas_rebar3 1.4.16
+geminic 0.1.0
+gen_batch_server 0.8.9
+gen_cycle 1.0.4
+gen_errand 0.0.1
+gen_flow 0.0.5
+# Packages page 66
+gen_fsm_compat 0.3.0
+gen_fw 18.6.2
+gen_icmp 0.6.2
+gen_ircclient 0.1.1
+gen_leader 0.1.0
+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
+gen_xml 0.1.0
+geocoding 0.3.1
+geo_gateway 0.2.0
+# Packages page 67
+geolite2data 1.0.0
+getopt 1.0.3
+gettexter 0.1.0
+ghatest 0.10.0
+gisla 2.1.1
+# Packages page 68
+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
+# Packages page 69
+glob 1.0.0
+global_flags 1.0.0
+# Packages page 70
+gmo_pg 0.0.1
+goldrush 0.1.9
+# Packages page 71
+# Packages page 72
+# Packages page 73
+# Packages page 74
+google_token 1.0.5
+gourd 0.1.0
+gpb 4.21.1
+gpio 0.6.3
+gproc 1.0.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 75
+grisp 2.7.0
+grisp_connect 1.1.0
+grisp_cryptoauth 2.4.0
+grisp_emulation 0.2.2
+grisp_tools 2.7.1
+grisp_update_packager 1.0.0
+grisp_updater 2.1.0
+grisp_updater_grisp2 0.2.0
+grpcbox 0.17.1
+grpcbox_plugin 0.9.0
+grpc_cowlib 2.8.1
+grpc_gun 2.0.1
+grpc_lib 0.1.2
+grpc_update 2.0.0
+gruff 0.1.0
+gsm_coder 1.0.2
+gtp 0.2.1
+gtplib 3.4.0
+gun 2.1.0
+# Packages page 76
+gun_update 2.1.0
+gurka 0.1.8
+gustav 0.1.8
+h1 2.3.0
+h3 3.7.2-b
+hacker_news 0.0.3
+hackney 1.20.1
+hackney_telemetry 0.2.0
+hairnet 1.0.0
+haki 0.3.2
+hamcrest 0.1.3
+haproxy_protocol 0.1.2
+harness_erlang_murmurhash 1.0.0
+harness_ff_erlang_client_api 1.0.3
+harness_ff_erlang_server_sdk 3.0.2
+hasaki_emysql 0.5.1
+hashids_erlang 1.0.5
+hash_ring 0.4.2
+# Packages page 77
+havoc 0.2.3
+hdr_histogram 0.5.0
+hearty 0.0.0
+heja 0.1.4
+helium 0.1.0
+hello_erl 0.1.2
+# Packages page 78
+heroku_crashdumps 0.1.0
+hex2bin 1.0.0
+hex_core 0.10.3
+hexml 3.4.1
+hextree 0.1.6
+hkdf_erlang 1.0.0
+hlc 3.0.1
+hoax 0.11.2
+holiday_jp_clje 0.1.1
+# Packages page 79
+homotopy 1.3.1
+hooks 2.1.0
+horatio 0.2.0-rc1
+horus 0.3.0
+host_triple 0.1.0
+hotp 1.0.2
+hpack_erl 0.3.0
+hterl 0.10.0
+htmerl 0.1.0
+htnerlang 0.1.0
+hts 1.3.1
+httpb 0.4.2
+http_cache 0.3.1
+http_cache_store_behaviour 0.3.0
+http_cache_store_disk 0.3.1
+http_cache_store_memory 0.3.1
+http_cache_store_native 0.2.0
+httpc_aws 0.4.2
+# Packages page 80
+http_message_signatures 1.0.0-alpha.1
+http_signature 2.0.0
+hund 0.1.1
+hut 1.4.0
+hydro 0.5.0
+hyper 1.0.1
+iam 0.0.1
+# Packages page 81
+iban 0.7.0
+ibrowse 4.4.2
+iconv 1.0.14
+iconverl 3.0.21
+idl 1.0.1
+idna 6.1.1
+idris2 0.2.1-alpha.1
+ierl 0.4.0
+imap_utf7 1.0.0
+# Packages page 82
+inaka_aleppo 1.1.1
+inaka_emysql 0.5.0
+inaka_iso8601 1.1.2
+inaka_mixer 1.2.0
+inert 1.0.5
+inet_ext 1.0.0
+influxdb 0.2.1
+influx_udp 1.1.2
+inotify 0.4.3
+# Packages page 83
+intercept 1.0.0
+interval_tree_clocks 1.0.1
+ip2locationdata 0.0.5
+ip2region_erlang 0.1.0
+ipaddr 0.1.0
+ipinfo 1.0.2
+iptables 0.1.6
+irc_parser 0.1.0
+is_auto_imported_bif 17.8.24
+ishikawa 0.0.3
+# Packages page 84
+iso8583_erl 0.4.1
+iso8601 1.3.4
+iso_erlang 0.11.0
+istype 0.2.3
+itc 0.4.0
+iterator 0.0.4
+jaeger_passage 0.1.14
+jam 1.0.0
+# Packages page 85
+jargon 1.0.1
+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.4
+jesse 1.8.1
+jhn_stdlib 5.3.2
+jiffy 1.1.2
+jobs 0.10.0
+jose 1.11.10
+jpparse 1.3.1
+# Packages page 86
+jsn 2.2.2
+jsone 1.9.0
+jsonlog 0.1.0
+json_polyfill 0.1.4
+jsonpull 0.1.1
+jsx 3.1.0
+jsxd 0.2.4
+jsxrecord 2.2.0
+jun 0.2.6
+jupyter 0.5.0
+justatimer 0.1.2
+# Packages page 87
+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.10
+kafkerl 2.1.0
+kairos 1.0.1
+kanin 0.6.0
+kashe 1.0.1
+katana 1.0.0
+katana_code 2.2.0
+katana_test 1.0.1
+katipo 1.1.1
+katja 0.10.0
+katja_echo 0.1.1
+katja_vmstats 0.8.2
+katt 1.6.10
+kdtree 1.0.0
+keccak 2.0.0
+keccakf1600 3.0.0
+keccakf1600_diode_fork 3.0.0
+keccakf1600_nash_fork 2.1.2
+keccakf1600_orig 2.1.0
+# Packages page 88
+keccakf1600_otp23 2.0.0
+ken 0.1.1
+kerlberos 2.0.1
+key2value 2.0.7
+keys1value 2.0.7
+keyserver 1.0.0
+keysmith 0.5.0
+kflow 1.1.0
+khepri 0.16.0
+khepri_mnesia_migration 0.7.1
+kinetic 1.3.11
+# Packages page 89
+kivra_merlin 3.0.1
+kla 0.9.1
+kraft 0.1.0
+kube_dist 0.0.2
+kuberl 0.2.0
+kuberlnetes 0.1.0
+# Packages page 90
+kvconf 2024.3.1
+kv_index_tictactree 0.9.4
+kylie 1.0.1
+kyu 2.0.5
+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.3.3
+lanes_barista 0.3.3
+lanes_elli 0.3.3
+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 3.5.0
+lazy 0.0.1
+lazy_lists 0.1.0
+lb 17.6.12
+# Packages page 91
+lbm_kv 0.0.2
+lc 0.3.2
+lcfg 0.5.0-rc3
+lcli 0.1.1
+ldb 0.0.18
+ledis 0.3.0
+lee 0.1.0
+lejson 0.8.0
+levaindoc 0.7.0
+leveled 1.1.0-hex
+leveled_lz4 1.9.4-leveled-hex.4
+leveled_zstd 1.5.4-leveled-hex.2
+lfe 2.1.5
+lfe_dragon 0.0.0
+lfe_http 0.5.4
+lfe_machine_tv 3.0.1
+lfe_yuri 0.3.2
+lhc 0.4.0
+lhttpc 1.7.1
+libchunter 0.1.52
+# Packages page 92
+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.1
+libsecp256k1_nif 0.0.3
+libsnarl 0.3.55
+libsnarlmatch 0.1.8
+libsniffle 0.3.71
+libsodium 2.0.1
+liburi 3.0.1
+libvxe_erl 0.1.0
+# Packages page 93
+ljson 0.6.0-rc1
+lldp 0.1.0
+llists 1.2.0
+# Packages page 94
+lmug 0.2.8
+lmug_inets 0.1.1
+local 0.2.1
+locker 1.0.8
+locks 0.2.0
+locus 2.3.10
+logflare_erl 0.2.0
+logger_colorful 0.1.0
+logger_debug_h 0.2.0
+logger_formatter_json 0.8.4
+logger_journald 0.3.1
+logger_logstash 0.1.3
+logger_webhook_h 1.1.0
+# Packages page 95
+logi 0.5.8
+logi_prometheus 0.1.2
+logi_stdlib 0.1.2
+logjam 1.2.4
+logstasher 1.1.0
+loise 1.3.0
+lpr 0.1.2
+lric 0.3.0
+lru 2.4.0
+lrw 2.0.1
+ltest 0.13.9
+luaport 1.6.3
+luerl 1.2.3
+# Packages page 96
+lutil 0.15.0
+lxml 0.4.3
+lz4 0.2.4
+lz4b 0.0.11
+lz4_erl 0.2.4
+m3u8 0.2.1
+mach 4.7.0
+mad 7.1.1
+maildir_commander 0.6.5
+# Packages page 97
+mapsd 0.2.0
+map_sets 1.1.0
+maps_in 0.2.0
+maputils 0.4.1
+mapz 2.4.0
+markerl 0.1.0
+# Packages page 98
+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.2
+mc_mustache 1.0.1
+# Packages page 99
+mc_pbkdf2 2.2.1
+mc_poolgirl 2.2.1
+mc_sbroker 1.1.2
+mc_small_ints 1.1.1
+mc_vsn_transform 1.1.1
+md2 1.2.0
+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 100
+# Packages page 101
+memdb 0.2.0
+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
+metal 0.1.1
+metrics 2.5.0
+metrics_reader 0.1.13
+metronome 0.0.2
+# Packages page 102
+mgmepi 0.9.0
+m_http 0.2.2
+midilib 0.5.2
+miffy 2.0.0
+milenage 0.2.0
+mime_lookup 0.1.1
+mimerl 1.3.0
+mimetypes 1.1.0
+minikube 1.0.0
+minmay 1.2.0
+mixactions 0.2.0
+# Packages page 103
+mls 0.1.4
+mmath 0.2.26
+mnesplit 0.0.1
+mnkv 0.1.0
+mochicow 0.6.4
+mochiweb 3.2.2
+mochiweb_html 2.15.0
+mochiweb_util 0.1.0
+# Packages page 104
+mockgyver 1.8.0
+mongodb_client 3.2.0
+mongodb_erlang 3.4.0
+mongodriver 1.0.0
+mongoose_jid 2.2.0
+# Packages page 105
+mpgit 0.1.1
+mq 0.4.0
+mqtree 1.0.17
+mqtt 0.3.3
+mqtt_client 1.0.5
+mqtt_packet_map 1.1.0
+mqtt_sessions 2.6.0
+msgpack 0.8.1
+msgpack_rpc_erlang 0.6.4
+msmp 0.1.2
+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 106
+m_unicode 0.1.0
+mutagen 0.1.0
+mybench 0.0.0
+my_cargo 0.1.3-rc.1
+my_cowboy 2.12.0
+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 11.9.6
+# Packages page 107
+narcs 0.1.0
+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
+neo4j 0.3.0
+# Packages page 108
+# Packages page 109
+nested 0.1.2
+netcdf_nif 0.1.2
+netflow 1.0.0
+netlink 1.1.0
+newrelic 0.1.0
+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.2
+nifi_s2s 0.0.2
+nif_libsecp256k1 0.0.2
+# Packages page 110
+nine 0.2.0
+nine_cowboy 0.1.1
+nine_elli 0.1.0
+nitro 9.9.6
+nitro_cache 0.5.0
+nitrogen_core 3.0.0-alpha.13
+nitro_qrcode 1.1.0
+nkferl 0.1.2
+nlocks 1.1.2
+nm 0.0.1
+noble 0.0.4
+nodefinder 2.0.7
+noise 0.0.5
+nopmd 0.1.0
+# Packages page 111
+nova 0.10.2
+nova_modern 0.1.3
+nprocreg 0.3.0
+ns 1.6.4
+nuntius 1.0.0
+oauth 2.1.0
+oauth2c 1.0.1
+oauth2_erlang 0.6.1
+# Packages page 112
+observer_cli 1.8.0
+oc_datadog 0.2.0
+oc_google_reporter 0.4.0
+odi 0.1.0
+oidcc 3.2.6
+oidcc_cowboy 2.0.0
+oidcc_cowboy_session 2.0.0
+ojson 1.0.0
+# Packages page 113
+oox 0.1.27
+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
+# Packages page 114
+openroad 1.0.0
+opentelemetry 1.5.0
+opentelemetry_api 1.4.0
+opentelemetry_api_experimental 0.5.1
+opentelemetry_cowboy 1.0.0
+opentelemetry_elli 0.2.0
+opentelemetry_experimental 0.5.1
+opentelemetry_exporter 1.8.0
+opentelemetry_grpcbox 0.2.0
+opentelemetry_heroku 0.2.0
+opentelemetry_instrumentation_http 0.1.0
+opentelemetry_logger_metadata 0.1.0
+opentelemetry_logger_metadata_datadog 0.1.0
+opentelemetry_process_propagator 0.3.0
+opentelemetry_semantic_conventions 1.27.0
+opentelemetry_telemetry 1.1.2
+opentelemetry_xray 0.7.3
+opentelemetry_zipkin 1.1.1
+optic 3.1.0
+opuntia 1.1.0
+# Packages page 115
+ordered_mutex 0.1.2
+osc_lib 2.1.1
+osc_server 2.1.1
+otc 1.0.0
+otel_http 0.2.0
+otel_propagator_instana 1.1.0
+otpbp 7.6.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 2.0.0
+ovsdb 0.3.0
+owoify_erl 1.1.2
+p1_acme 1.0.24
+p1_mysql 1.0.25
+p1_oauth2 0.6.14
+p1_pgsql 1.1.28
+p1_stringprep 1.0.1
+p1_utils 1.0.26
+p1_xml 1.1.1
+p1_xmlrpc 1.15.1
+# Packages page 116
+pact_erlang 0.2.2
+paillier 1.0.0
+# Packages page 117
+parse_trans 3.4.2
+parsexml 1.0.0
+parthenon 0.10.1
+partial 1.2.0
+partisan 5.0.0-rc.8
+passage 0.2.6
+pbkdf2 2.0.0
+pbkdf2_nif 0.4.0
+pc 1.15.0
+pcsc 1.3.1
+pd_erlzk 0.6.4
+pe4kin 0.2.4
+# Packages page 118
+perc 1.0.2
+pest 0.9.0
+pfcplib 3.0.0
+pgapp 0.0.2
+pge 0.2.6
+pgo 0.14.0
+pgpool 2.1.0
+pgsql 26.0.2
+pg_types 0.4.0
+# Packages page 119
+# Packages page 120
+phpass 0.1.0
+phrase 0.2.1
+# Packages page 121
+picosat 0.1.0
+pipe_line 1.0.0
+pipes 2.0.1
+# Packages page 122
+pkix 1.0.10
+pkt 0.6.0
+pl 18.1.31
+plain_fsm 1.4.5
+platybelodon 0.1.0
+plists 1.1.1
+plottah 0.2.0
+plugerl 1.0.0
+# Packages page 123
+# Packages page 124
+plumtree 0.6.0
+pmbag 1.0.0
+pmod_transform 1.1.0
+png 0.2.1
+pobox 1.2.0
+poise 0.2.0
+# Packages page 125
+poolboy 1.5.2
+pooler 1.6.0
+poolgirl 1.3.0
+pop3client 1.4.0
+porter_stemming 1.0.1
+posthaste 18.10.14
+postman_smtp 0.0.1
+postman_transport 1.0.0
+pot 1.0.2
+power_shell 1.3.0
+ppg 0.1.3
+ppool 1.1.1
+ppplib 1.0.0
+pp_record 0.1.3
+pqclean 0.0.3
+pqueue 2.0.7
+# Packages page 126
+pretty_print 0.1.0
+priq 0.2.0
+proc 1.1.2
+process_group 1.1.3
+procket 0.9.9
+proj_nif 0.1.4
+prometheus 4.11.0
+prometheus_cowboy 0.1.8
+prometheus_diameter_collector 1.2.1
+# Packages page 127
+prometheus_httpd 2.1.11
+prometheus_process_collector 1.6.0
+promexp 0.4.3
+proper 1.4.0
+proper_contrib 0.3.2
+protofy_test 1.0.0
+provider_asn1 0.4.1
+providers 1.9.0
+prx 0.16.4
+pulserl 0.1.3
+# Packages page 128
+pure_migrations 1.3.0
+pushover_error_logger 0.1.0
+pynchon 0.5.0
+qdate 0.7.3
+qdate_localtime 1.2.1
+qsp 0.1.0
+quantile_estimator 0.2.1
+# Packages page 129
+quicer 0.0.308
+quickrand 2.0.7
+quintana 0.2.2
+ra 2.16.0-pre.2
+raabta 0.1.0
+rabbit_common 4.0.3
+radius 0.0.13
+ram 0.5.0
+# Packages page 130
+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.10
+# Packages page 131
+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.6
+rebar3_archive_plugin 0.0.2
+rebar3_asn1_compiler 1.0.0
+rebar3_auto 0.5.1
+rebar3_auto_applications 1.0.0
+rebar3_autotdd 1.1.0
+rebar3_autotest 0.1.1
+rebar3_bench 0.3.0
+rebar3_bitbake 0.1.0
+rebar3_bump 0.1.1
+rebar3_cargo 0.1.1
+rebar3_check_app_calls 0.1.2
+rebar3_check_deps 0.1.0
+rebar3_checkshell 1.2.0
+rebar3_clojerl 0.8.8
+rebar3_cobertura 0.3.1
+rebar3_codecov 0.7.0
+rebar3_cuttlefish 0.16.0
+rebar3_deb 0.1.1
+rebar3_depup 0.4.0
+rebar3_dialyzer_html 0.3.0
+rebar3_diameter_compiler 0.8.0
+rebar3_dirs 0.1.0
+rebar3_docker 0.2.0
+rebar3_docs 0.2.1
+rebar3_dragon 0.0.0
+rebar3_edata_plugin 0.1.11
+rebar3_edoc_extensions 1.6.1
+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.18.3
+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
+rebar3_erlesy 1.0.0
+rebar3_erllambda 1.1.2
+rebar3_erlquery 0.2.2
+rebar3_erlydtl_plugin 0.1.1
+# Packages page 132
+rebar3_ex_doc 0.2.24
+rebar3_external 0.2.0
+rebar3_exunit 0.1.1
+rebar3_fmt 1.19.0
+rebar3_format 1.3.0
+rebar3_git_vsn 1.1.1
+rebar3_gpb_plugin 2.23.2
+rebar3_gpb_rpc_plugin 1.3.1
+rebar3_grisp 2.8.0
+rebar3_grisp_io 0.1.0
+rebar3_hank 1.4.1
+rebar3_hex 7.0.8
+rebar3_hterl 0.2.0
+rebar3_idl_compiler 0.5.0
+rebar3_jorel 0.0.1
+rebar3_lfe 0.4.11
+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.2.6
+rebar3_local_deps 0.1.2
+rebar3_neotoma_plugin 0.2.0
+rebar3_nova 0.4.5
+rebar3_oscmd 0.5.0
+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.15
+rebar3_raw_deps 2.0.0
+rebar3_rdl 0.1.0
+rebar3_reloader 0.2.0
+rebar3_run 0.5.0
+rebar3_rustler 0.1.1
+rebar3_sbom 0.8.0
+rebar3_scuttler 0.4.1
+rebar3_sheldon 0.4.3
+rebar3_shellcheck 1.0.1
+rebar3_shellrpc 0.1.0
+rebar3_sqlc 0.1.0
+rebar3_static_deps 2021.1.0
+rebar3_tailwind 1.0.3
+rebar3_tsung 0.1.4
+rebar3_typer 0.1.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.11.0
+recompile 0.1.0
+recon 2.5.6
+recordset 0.1.0
+redbug 2.1.0
+# Packages page 133
+redbug_clone 2.0.10
+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
+# Packages page 134
+reltool_util 2.0.7
+relx 4.10.0
+remedy_cowlib 2.11.1
+remedy_gun 2.0.1
+replayq 0.3.10
+repo 0.7.2
+rest 6.11.1
+restc 0.4.1
+# Packages page 135
+resulto 0.2.1
+results 0.2.0
+re_tuner 0.1.21
+rfc3394 1.0.1
+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
+# Packages page 136
+rlamb_publishtest 0.1.0
+rlp 1.1.0
+rmpc 18.5.9
+robots 1.1.2
+rocksdb 1.8.0
+rocksdb_cloud 1.0.1
+roni 1.0.1
+roster 3.4.0
+router 1.0.4
+routing_tree 1.0.9
+rpsls 1.0.0
+# Packages page 137
+rs_compile 0.1.0
+rsrc_pool 1.0.3
+rstats 1.0.4
+rtmpmsg 0.2.16
+rtrace 1.0.1-6.bc1a170
+ruapu 0.1.0
+s3filez 1.4.1
+safeio 0.1.6
+safetyvalve 2.5.2
+salt 0.1.3
+samovar 1.0.2
+# Packages page 138
+sanitizer 0.0.2
+sasl_auth 2.3.3
+sbroker 1.0.0
+scheduler_utilization 0.1.1
+# Packages page 139
+scran 0.2.0
+scrypt 2.1.0
+# Packages page 140
+segmented_cache 0.4.0
+self_configer 0.1.1
+semver_erl 0.0.1
+serial_framing_protocol 1.1.0
+serverless 0.4.3
+seshat 0.6.0
+setup 2.2.0
+# Packages page 141
+sext 1.9.0
+sfmt 0.14.0
+sf_transform 0.3.1
+sgi 0.6.0
+sha3 2.0.0
+shackle 0.6.15
+shards 1.1.1
+sheldon 0.4.1
+shiguredo_crdt 2022.1.0
+shiguredo_jesse 2024.1.0
+shiguredo_jsone 2024.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 1.1.0
+shq 0.1.1
+# Packages page 142
+sidejob 2.2.0
+sigma_proplist 0.1.0
+simdjson 0.1.3
+simdjsone 0.4.2
+simple_bridge 2.3.1
+simple_cache 1.2.0
+simple_global 0.1.4
+# Packages page 143
+simpler_cowboy_rest 1.0.0
+simpre 0.1.0
+# Packages page 144
+sleeplocks 1.1.3
+slugerl 1.0.0
+small_ints 0.1.0
+smerl 0.0.1
+smokkfiskur 0.1.4
+snabbkaffe 1.0.10
+snapperl 1.1.3
+snappiest 1.2.0
+snappy 1.1.1
+snappyer 1.2.10
+snappy_nif 1.1.3
+# Packages page 145
+snatch 0.4.6
+snatch_php 0.2.1
+snatch_test_framework 0.6.4
+sntrup761_nif 1.0.0
+sockerl 17.9.10
+soda 1.1.1
+soos_sample_project 1.0.0
+soxe 0.1.1
+# Packages page 146
+sparkler 0.2.0
+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
+spinlock 0.2.1
+splay_tree 1.1.0
+splicer 0.5.5
+# Packages page 147
+sql_bridge 0.5.0
+sqlc 0.1.0
+sqlite 2.0.0
+sqlite3 1.1.15
+sqlmig 0.1.5
+sqlparse 4.6.3
+sqlparser 0.3.1
+srly 0.6.5
+ssh_agent 0.1.0
+ssh_signature 0.1.0
+ssl_verify_fun 1.1.7
+stacktrace_compat 1.2.2
+stage 0.3.0
+# Packages page 148
+statman 0.5.0
+statsderl 0.6.1
+statsig 0.0.3
+st_commons 1.2.1
+stdout_formatter 0.2.4
+steady_vector 1.0.1
+steamroller 0.14.3
+stillir 1.1.0
+stk500 0.2.2
+# Packages page 149
+stout 1.0.0
+strata 0.1.0
+strata_mysql 0.1.0
+strata_postgres 0.1.0
+strata_sqlite3 0.1.0
+stream 0.1.0
+strftimerl 0.1.2
+string_compat 0.0.1
+stringprep 1.0.30
+string_utils 1.1.3
+# Packages page 150
+stun 1.2.15
+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.7
+surreal 2.1.0
+# Packages page 151
+sut 0.2.0
+swab 1.0.4
+swear 1.0.0
+swidden 2024.2.0
+switchboard 0.3.2
+syn 3.3.0
+sync 0.4.1
+syslog 1.1.0
+syslog_app 4.0.0
+syslogger 0.3.0
+syslog_socket 2.0.7
+sysmon_handler 1.3.0
+systemd 0.6.2
+system_monitor 1.0.1
+t__ 0.1.0
+# Packages page 152
+tasker 0.1.0
+taskforce 1.2.3
+task_graph 0.3.1
+tbcd 0.3.6
+tcp_client 0.3.0
+tdata 1.1.3
+tdiff 0.1.2
+teacup 0.3.4
+# Packages page 153
+teacup_nats 0.4.1
+telemetry 1.3.0
+telemetry_poller 1.1.0
+telemetry_registry 0.3.2
+teleport 0.6.2
+teleprom 0.1.0
+telex 0.0.2
+template_compiler 2.10.1
+templaterl 0.2.4
+tempo 0.4.4
+# Packages page 154
+termbox2 0.1.2
+termcap 0.1.0
+termit 2.0.1
+termseal 0.1.1
+tesla_api 1.0.0
+test_hex 1.1.2
+test_package 1.0.0
+test_package_nogit 1.0.0
+testutils 0.0.1
+test_utils 1.1.1
+# Packages page 155
+textual 0.1.1
+tflite_beam 0.3.7
+the_f 1.0.0
+thoas 1.2.1
+thrift_erl 0.13.0
+thrift_protocol 0.1.5
+throwdown 0.2.1
+time_compat 0.0.1
+time_utils 1.0.15
+# Packages page 156
+tivan 1.2.15
+tivan_rocksdb 1.0.0
+tls_certificate_check 1.24.0
+tomerl 0.5.0
+toml_bombadil 0.4.0
+# Packages page 157
+totp 0.0.3
+tqformat 0.1.4
+tql 1.10.0
+tracelog 0.1.0
+trace_runner 1.0.0
+traces 1.0.4
+trails 2.3.1
+travianmap 1.1.0
+# Packages page 158
+treewalker 0.4.1
+trie 2.0.7
+triq 1.3.0
+trooper 0.3.2
+ts_chatterbox 0.15.1
+tsuru 1.4.1
+tunctl 0.3.5
+tunnerl 1.3.0
+# Packages page 159
+twilio_sms 0.1.1
+typerefl 0.1.1
+types 0.1.8
+u2f 0.1.5
+ua_classifier 1.0.0
+ucl 1.1.1
+ucol 2.0.0
+ucol_nif 1.1.5
+# Packages page 160
+# Packages page 161
+uef 2.6.0
+uf2tool 1.1.0
+ui 0.1.1
+uid 1.3.4
+ulitos 0.4.0
+undermidi 0.1.0
+undertheory 0.3.0
+undertone 0.4.0-rc3
+undertone_lib 0.4.0-rc3
+unicode_util_compat 0.7.0
+unistring 0.1.0
+unite 0.4.3
+# Packages page 162
+uri 0.1.0
+urilib 0.5.0
+url 1.1.0
+usb 0.2.0
+util 1.3.4
+utility 0.1.2
+uuid_erl 2.0.7
+uuidv4 1.0.0
+validerl 2.0.1
+# Packages page 163
+varpool 2.0.7
+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
+# Packages page 164
+vincenty 1.0.0
+vmq_commons 1.0.0
+vmstats 2.4.0
+vptree 0.0.0
+vsn 1.1.0
+wait_helper 0.2.1
+# Packages page 165
+watch 0.2.2
+webdavfilez 1.2.1
+webmachine 1.11.1
+webpage 1.0.0
+websocket_client 1.5.0
+# Packages page 166
+wirerlhair 1.0.0
+wms 0.10.0
+wolff 4.0.4
+wooper 2.0.9
+# Packages page 167
+worker_pool 6.4.0
+workforce 0.1.0
+world_geojson 0.0.1
+wts 0.4.0
+xlerl 0.1.0
+# Packages page 168
+xml_builderl 0.1.0
+xmlrat 0.0.10
+xmpp 1.9.0
+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
+xrepl 0.0.0
+xs_regex 0.1.0
+xtea 0.1.2
+xxh3 0.3.6
+yabko 1.0.0
+yaccety_sax 0.3.0
+yamerl 0.10.0
+yamerl_the_fork 0.3.3
+# Packages page 169
+yconf 1.0.16
+yctest 1.2.0
+yes_msg 0.1.0
+yubico 0.1.5
+yval 1.0.10
+zen 0.1.0
+# Packages page 170
+zipper 1.1.0
+zlist 1.3.0
+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
+# Packages page 171
+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.1.0
+zotonic_site_status 1.0.0-rc.15
+zotonic_ssl 1.3.0
+zotonic_stdlib 1.21.0
+zstd 0.2.0
+zucchini 0.1.0
+# Packages page 172
diff --git a/test/plugin_asciidoc.mk b/test/plugin_asciidoc.mk
index 29dfd07..b2240ce 100644
--- a/test/plugin_asciidoc.mk
+++ b/test/plugin_asciidoc.mk
@@ -1,10 +1,10 @@
# AsciiDoc plugin.
-ASCIIDOC_TARGETS = $(call list_targets,asciidoc)
+asciidoc_TARGETS = $(call list_targets,asciidoc)
-.PHONY: asciidoc $(ASCIIDOC_TARGETS)
+.PHONY: asciidoc $(asciidoc_TARGETS)
-asciidoc: $(ASCIIDOC_TARGETS)
+asciidoc: $(asciidoc_TARGETS)
# Disable the Asciidoc tests requiring the DocBook toolchain
# when Asciidoc is not installed. The toolchain is too heavy for CI.
diff --git a/test/plugin_bootstrap.mk b/test/plugin_bootstrap.mk
index 7093fce..aa873a8 100644
--- a/test/plugin_bootstrap.mk
+++ b/test/plugin_bootstrap.mk
@@ -1,10 +1,10 @@
# Bootstrap plugin.
-BOOTSTRAP_TARGETS = $(call list_targets,bootstrap)
+bootstrap_TARGETS = $(call list_targets,bootstrap)
-.PHONY: bootstrap $(BOOTSTRAP_TARGETS)
+.PHONY: bootstrap $(bootstrap_TARGETS)
-bootstrap: $(BOOTSTRAP_TARGETS)
+bootstrap: $(bootstrap_TARGETS)
bootstrap-app: init
@@ -303,13 +303,16 @@ bootstrap-templates: init
$t $(MAKE) -C $(APP) --no-print-directory new t=gen_statem n=my_statem
$t $(MAKE) -C $(APP) --no-print-directory new t=gen_server n=my_server
$t $(MAKE) -C $(APP) --no-print-directory new t=supervisor n=my_sup
- $t $(MAKE) -C $(APP) --no-print-directory new t=cowboy_http n=my_http
- $t $(MAKE) -C $(APP) --no-print-directory new t=cowboy_loop n=my_loop
- $t $(MAKE) -C $(APP) --no-print-directory new t=cowboy_rest n=my_rest
- $t $(MAKE) -C $(APP) --no-print-directory new t=cowboy_ws n=my_ws
+ $t $(MAKE) -C $(APP) --no-print-directory new t=cowboy_http_h n=my_http_h
+ $t $(MAKE) -C $(APP) --no-print-directory new t=cowboy_loop_h n=my_loop_h
+ $t $(MAKE) -C $(APP) --no-print-directory new t=cowboy_rest_h n=my_rest_h
+ $t $(MAKE) -C $(APP) --no-print-directory new t=cowboy_websocket_h n=my_ws_h
$t $(MAKE) -C $(APP) --no-print-directory new t=ranch_protocol n=my_protocol
$t $(MAKE) -C $(APP) --no-print-directory new t=module n=my_module
+ $i "Confirm we can't overwrite existing files"
+ $t ! $(MAKE) -C $(APP) --no-print-directory new t=gen_server n=my_server $v
+
# Here we disable warnings because templates contain missing behaviors.
$i "Build the application"
$t $(MAKE) -C $(APP) ERLC_OPTS=+debug_info $v
@@ -320,12 +323,17 @@ bootstrap-templates: init
$t test -f $(APP)/ebin/my_statem.beam
$t test -f $(APP)/ebin/my_server.beam
$t test -f $(APP)/ebin/my_sup.beam
+ $t test -f $(APP)/ebin/my_http_h.beam
+ $t test -f $(APP)/ebin/my_loop_h.beam
+ $t test -f $(APP)/ebin/my_rest_h.beam
+ $t test -f $(APP)/ebin/my_ws_h.beam
+ $t test -f $(APP)/ebin/my_protocol.beam
$t test -f $(APP)/ebin/my_module.beam
$i "Check that all the modules can be loaded"
$t $(ERL) -pa $(APP)/ebin/ -eval " \
ok = application:start($(APP)), \
- {ok, Mods = [my_fsm, my_http, my_loop, my_module, my_protocol, my_rest, my_server, my_statem, my_sup, my_ws]} \
+ {ok, Mods = [my_fsm, my_http_h, my_loop_h, my_module, my_protocol, my_rest_h, my_server, my_statem, my_sup, my_ws_h]} \
= application:get_key($(APP), modules), \
[{module, M} = code:load_file(M) || M <- Mods], \
halt()"
diff --git a/test/plugin_c_src.mk b/test/plugin_c_src.mk
index eeee445..5330452 100644
--- a/test/plugin_c_src.mk
+++ b/test/plugin_c_src.mk
@@ -1,16 +1,18 @@
# C source plugin.
-C_SRC_TARGETS = $(call list_targets,c-src)
+c_src_TARGETS = $(call list_targets,c-src)
-.PHONY: c-src $(C_SRC_TARGETS)
+.PHONY: c-src $(c_src_TARGETS)
-c-src: $(C_SRC_TARGETS)
+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_concuerror.mk b/test/plugin_concuerror.mk
index f1b9288..5bd4231 100644
--- a/test/plugin_concuerror.mk
+++ b/test/plugin_concuerror.mk
@@ -1,10 +1,10 @@
# Concuerror plugin.
-CONCUERROR_TARGETS = $(call list_targets,concuerror)
+concuerror_TARGETS = $(call list_targets,concuerror)
-.PHONY: concuerror $(CONCUERROR_TARGETS)
+.PHONY: concuerror $(concuerror_TARGETS)
-concuerror: $(CONCUERROR_TARGETS)
+concuerror: $(concuerror_TARGETS)
concuerror-app: init
diff --git a/test/plugin_cover.mk b/test/plugin_cover.mk
index a1d7e51..0883fa0 100644
--- a/test/plugin_cover.mk
+++ b/test/plugin_cover.mk
@@ -1,10 +1,10 @@
# Common Test plugin.
-COVER_TARGETS = $(call list_targets,cover)
+cover_TARGETS = $(call list_targets,cover)
-.PHONY: cover $(COVER_TARGETS)
+.PHONY: cover $(cover_TARGETS)
-cover: $(COVER_TARGETS)
+cover: $(cover_TARGETS)
cover-ct: init
@@ -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)"
@@ -123,8 +151,8 @@ cover-ct-incl-deps: init
$t cp ../erlang.mk $(APP)/
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap $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_commit = 1.0.0\n"}' $(APP)/Makefile
+ $i "Add Cowboy 2.12.0 to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowboy\ndep_cowboy_commit = 2.12.0\n"}' $(APP)/Makefile
ifdef LEGACY
$i "Add Cowboy to the applications key in the .app.src file"
@@ -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)"
@@ -354,8 +437,8 @@ cover-eunit-incl-deps: init
$t cp ../erlang.mk $(APP)/
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap $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_commit = 1.0.0\n"}' $(APP)/Makefile
+ $i "Add Cowboy 2.12.0 to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowboy\ndep_cowboy_commit = 2.12.0\n"}' $(APP)/Makefile
ifdef LEGACY
$i "Add Cowboy to the applications key in the .app.src file"
diff --git a/test/plugin_ct.mk b/test/plugin_ct.mk
index 6c31f49..a1ecf82 100644
--- a/test/plugin_ct.mk
+++ b/test/plugin_ct.mk
@@ -1,10 +1,10 @@
# Common Test plugin.
-CT_TARGETS = $(call list_targets,ct)
+ct_TARGETS = $(call list_targets,ct)
-.PHONY: ct $(CT_TARGETS)
+.PHONY: ct $(ct_TARGETS)
-ct: $(CT_TARGETS)
+ct: $(ct_TARGETS)
ct-all: init
diff --git a/test/plugin_dialyzer.mk b/test/plugin_dialyzer.mk
index 732f568..e4240d7 100644
--- a/test/plugin_dialyzer.mk
+++ b/test/plugin_dialyzer.mk
@@ -1,14 +1,27 @@
# Dialyzer plugin.
-DIALYZER_TARGETS = $(call list_targets,dialyzer)
+dialyzer_TARGETS = $(call list_targets,dialyzer)
+
+dialyzer_TARGETS_SET_1 = dialyzer-app dialyzer-apps-only dialyzer-apps-with-local-deps
+dialyzer_TARGETS_SET_2 = dialyzer-beam dialyzer-check dialyzer-custom-plt dialyzer-deps
+dialyzer_TARGETS_SET_3 = dialyzer-erlc-opts dialyzer-local-deps dialyzer-opts dialyzer-plt-apps
+dialyzer_TARGETS_SET_4 = dialyzer-plt-ebin-only dialyzer-plt-swallow-warnings dialyzer-pt
+
+ifneq ($(filter-out $(dialyzer_TARGETS_SET_1) $(dialyzer_TARGETS_SET_2) $(dialyzer_TARGETS_SET_3) $(dialyzer_TARGETS_SET_4),$(dialyzer_TARGETS)),)
+$(error Dialyzer target missing from dialyzer_TARGETS_SET_* variables.)
+endif
+
+ifdef SET
+dialyzer_TARGETS := $(dialyzer_TARGETS_SET_$(SET))
+endif
ifneq ($(shell which sem 2>/dev/null),)
DIALYZER_MUTEX = sem --fg --id dialyzer
endif
-.PHONY: dialyzer $(DIALYZER_TARGETS)
+.PHONY: dialyzer $(dialyzer_TARGETS)
-dialyzer: $(DIALYZER_TARGETS)
+dialyzer: $(dialyzer_TARGETS)
dialyzer-app: init
@@ -105,7 +118,7 @@ dialyzer-beam: init
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
$i "Add lager to the list of dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lager\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lager\ndep_lager = git https://github.com/erlang-lager/lager master\n"}' $(APP)/Makefile
$i "Add lager_transform to ERLC_OPTS"
$t echo "ERLC_OPTS += +'{parse_transform, lager_transform}'" >> $(APP)/Makefile
@@ -285,6 +298,10 @@ dialyzer-plt-ebin-only: init
$i "Build the application"
$t $(MAKE) -C $(APP) $v
+# @todo Temporary measure to make CACHE_DEPS=1 tests work again.
+ $i "Patch Cowlib's Erlang.mk"
+ $t cp ../erlang.mk $(APP)/deps/cowlib/
+
$i "Build Cowlib for tests to fetch autopatched dependencies"
$t $(MAKE) -C $(APP)/deps/cowlib test-build $v
@@ -308,7 +325,7 @@ dialyzer-plt-swallow-warnings: init
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
$i "Add LFE version referring to a missing function to the list of dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lfe\ndep_lfe_commit = d656987dc5f5e08306531ad1ce13bf9ca9ec9e5a\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = lfe\ndep_lfe = git https://github.com/rvirding/lfe d656987dc5f5e08306531ad1ce13bf9ca9ec9e5a\n"}' $(APP)/Makefile
$i "Create the PLT file"
$t $(DIALYZER_MUTEX) $(MAKE) -C $(APP) plt $v
diff --git a/test/plugin_edoc.mk b/test/plugin_edoc.mk
index 1779797..ca2fce7 100644
--- a/test/plugin_edoc.mk
+++ b/test/plugin_edoc.mk
@@ -1,10 +1,10 @@
# EDoc plugin.
-EDOC_TARGETS = $(call list_targets,edoc)
+edoc_TARGETS = $(call list_targets,edoc)
-.PHONY: edoc $(EDOC_TARGETS)
+.PHONY: edoc $(edoc_TARGETS)
-edoc: $(EDOC_TARGETS)
+edoc: $(edoc_TARGETS)
edoc-build: init
@@ -100,7 +100,7 @@ edoc-opts: init
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
$i "Add edown doclet for EDoc"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DOC_DEPS = edown\nEDOC_OPTS = {doclet, edown_doclet}\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DOC_DEPS = edown\ndep_edown = git https://github.com/uwiger/edown master\nEDOC_OPTS = {doclet, edown_doclet}\n"}' $(APP)/Makefile
$i "Run EDoc"
$t $(MAKE) -C $(APP) edoc $v
@@ -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_erlydtl.mk b/test/plugin_erlydtl.mk
index 1dac6e1..0cc0774 100644
--- a/test/plugin_erlydtl.mk
+++ b/test/plugin_erlydtl.mk
@@ -1,10 +1,10 @@
# ErlyDTL plugin.
-ERLYDTL_TARGETS = $(call list_targets,erlydtl)
+erlydtl_TARGETS = $(call list_targets,erlydtl)
-.PHONY: erlydtl $(ERLYDTL_TARGETS)
+.PHONY: erlydtl $(erlydtl_TARGETS)
-erlydtl: $(ERLYDTL_TARGETS)
+erlydtl: $(erlydtl_TARGETS)
erlydtl-compile: init
diff --git a/test/plugin_escript.mk b/test/plugin_escript.mk
index 3949547..d2dd1e6 100644
--- a/test/plugin_escript.mk
+++ b/test/plugin_escript.mk
@@ -1,10 +1,10 @@
# Escript plugin.
-ESCRIPT_TARGETS = $(call list_targets,escript)
+escript_TARGETS = $(call list_targets,escript)
-.PHONY: escript $(ESCRIPT_TARGETS)
+.PHONY: escript $(escript_TARGETS)
-escript: $(ESCRIPT_TARGETS)
+escript: $(escript_TARGETS)
escript-build: init
@@ -97,8 +97,8 @@ escript-deps-with-deps: 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_commit = 1.0.0\n"}' $(APP)/Makefile
+ $i "Add Cowboy 2.12.0 to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowboy\ndep_cowboy_commit = 2.12.0\n"}' $(APP)/Makefile
$i "Generate a module containing a function main/1"
$t printf "%s\n" \
@@ -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..bd1f0e0 100644
--- a/test/plugin_eunit.mk
+++ b/test/plugin_eunit.mk
@@ -1,10 +1,10 @@
# EUnit plugin.
-EUNIT_TARGETS = $(call list_targets,eunit)
+eunit_TARGETS = $(call list_targets,eunit)
-.PHONY: eunit $(EUNIT_TARGETS)
+.PHONY: eunit $(eunit_TARGETS)
-eunit: $(EUNIT_TARGETS)
+eunit: $(eunit_TARGETS)
eunit-all: init
@@ -235,6 +235,27 @@ eunit-check: init
$i "Check that EUnit runs on 'make check'"
$t $(MAKE) -C $(APP) check | grep -c "Test passed." | grep -q 1
+eunit-disable: 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 "Set EUNIT = disable in the Makefile"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "EUNIT = disable\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 is not run on 'make tests'"
+ $t $(MAKE) -C $(APP) tests | grep -c "Test passed." | grep -q 0
+
eunit-erl-opts: init
$i "Bootstrap a new OTP application named $(APP)"
@@ -347,6 +368,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_hex.mk b/test/plugin_hex.mk
index 66bf6fc..27060b6 100644
--- a/test/plugin_hex.mk
+++ b/test/plugin_hex.mk
@@ -4,11 +4,11 @@
# be started and available on port 4000, and the HEX=1 variable
# must be set.
-HEX_TARGETS = $(call list_targets,hex)
+hex_TARGETS = $(call list_targets,hex)
-.PHONY: hex $(HEX_TARGETS)
+.PHONY: hex $(hex_TARGETS)
-hex: $(HEX_TARGETS)
+hex: $(hex_TARGETS)
ifeq ($(shell netcat -z localhost 4000 && echo ok),ok)
hex-user-create: init
@@ -140,7 +140,7 @@ hex-tarball-create-with-deps: init
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
$i "Add Cowlib to the list of dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\ndep_cowlib_commit = 2.10.1\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\ndep_cowlib_commit = 2.13.0\n"}' $(APP)/Makefile
ifdef LEGACY
$i "Add Cowlib to the applications key in the .app.src file"
@@ -159,7 +159,37 @@ endif
{_, [{<<\"cowlib\">>, Cowlib}]} = lists:keyfind(<<\"requirements\">>, 1, Metadata), \
{_, <<\"cowlib\">>} = lists:keyfind(<<\"app\">>, 1, Cowlib), \
{_, false} = lists:keyfind(<<\"optional\">>, 1, Cowlib), \
- {_, <<\"2.10.1\">>} = lists:keyfind(<<\"requirement\">>, 1, Cowlib), \
+ {_, <<\"2.13.0\">>} = lists:keyfind(<<\"requirement\">>, 1, Cowlib), \
+ halt(0)"
+
+hex-tarball-create-with-req: 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 Cowlib to the list of dependencies"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\ndep_cowlib_commit = 2.13.0\nhex_req_cowlib = ~> 2.13\n"}' $(APP)/Makefile
+
+ifdef LEGACY
+ $i "Add Cowlib to the applications key in the .app.src file"
+ $t perl -ni.bak -e 'print;if ($$.==7) {print "\t\tcowlib,\n"}' $(APP)/src/$(APP).app.src
+endif
+
+ $i "Create a release tarball"
+ $t $(MAKE) -C $(APP) hex-tarball-create $v
+
+ $i "Confirm the tarball contents can be extracted"
+ $t cd $(APP)/.erlang.mk/ && tar xf $(APP).tar
+
+ $i "Confirm the tarball contains a metadata.config file that lists Cowlib as requirement"
+ $t $(ERL) -eval " \
+ {ok, Metadata} = file:consult(\"$(APP)/.erlang.mk/metadata.config\"), \
+ {_, [{<<\"cowlib\">>, Cowlib}]} = lists:keyfind(<<\"requirements\">>, 1, Metadata), \
+ {_, <<\"cowlib\">>} = lists:keyfind(<<\"app\">>, 1, Cowlib), \
+ {_, false} = lists:keyfind(<<\"optional\">>, 1, Cowlib), \
+ {_, <<\"~> 2.13\">>} = lists:keyfind(<<\"requirement\">>, 1, Cowlib), \
halt(0)"
hex-release-publish: init
@@ -187,6 +217,8 @@ hex-release-publish: init
$i "Check that the release exists"
$t curl -sf http://localhost:4000/api/packages/$(APP)/releases/0.1.0 >/dev/null
+# @todo There's a weird ci.erlang.mk related bug with CACHE_DEPS. Fix it.
+ifndef CACHE_DEPS
hex-release-publish-with-deps: init
$i "Bootstrap a new OTP application named $(APP)"
@@ -195,7 +227,7 @@ hex-release-publish-with-deps: init
$t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
$i "Add Cowlib to the list of dependencies"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\ndep_cowlib_commit = 2.10.1\n"}' $(APP)/Makefile
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\ndep_cowlib_commit = 2.13.0\n"}' $(APP)/Makefile
ifdef LEGACY
$i "Add Cowlib to the applications key in the .app.src file"
@@ -221,13 +253,15 @@ endif
$t $(MAKE) -C $(APP) hex-key-add HEX_USERNAME=$(APP) HEX_PASSWORD="1234567" | grep ^Secret: | cut -f2 -d" " > $(APP)/hex.key
$i "Publish the Cowlib release"
- $t $(MAKE) -C $(APP)/deps/cowlib hex-release-publish HEX_SECRET=`cat $(APP)/hex.key` $v
+ $t cp ../erlang.mk $(APP)/deps/cowlib
+ $t $(MAKE) -C $(APP)/deps/cowlib hex-release-publish DEPS_DIR=$(APP)/deps ERLANG_MK_TMP=$(APP)/.erlang.mk HEX_SECRET=`cat $(APP)/hex.key` $v
$i "Publish the release"
$t $(MAKE) -C $(APP) hex-release-publish HEX_SECRET=`cat $(APP)/hex.key` $v
$i "Check that the release exists and includes Cowlib as requirement"
$t curl -sf http://localhost:4000/api/packages/$(APP)/releases/0.1.0 | grep -q cowlib
+endif
hex-release-replace: init
diff --git a/test/plugin_proper.mk b/test/plugin_proper.mk
index 108b6e4..42a324d 100644
--- a/test/plugin_proper.mk
+++ b/test/plugin_proper.mk
@@ -1,10 +1,10 @@
# PropEr plugin.
-PROPER_TARGETS = $(call list_targets,proper)
+proper_TARGETS = $(call list_targets,proper)
-.PHONY: proper $(PROPER_TARGETS)
+.PHONY: proper $(proper_TARGETS)
-proper: $(PROPER_TARGETS)
+proper: $(proper_TARGETS)
proper-test-dir: init
diff --git a/test/plugin_protobuffs.mk b/test/plugin_protobuffs.mk
index f5814e8..2daadf1 100644
--- a/test/plugin_protobuffs.mk
+++ b/test/plugin_protobuffs.mk
@@ -1,10 +1,10 @@
# Protocol buffers plugin.
-PROTOBUFFS_TARGETS = $(call list_targets,protobuffs)
+protobuffs_TARGETS = $(call list_targets,protobuffs)
-.PHONY: protobuffs $(PROTOBUFFS_TARGETS)
+.PHONY: protobuffs $(protobuffs_TARGETS)
-protobuffs: $(PROTOBUFFS_TARGETS)
+protobuffs: $(protobuffs_TARGETS)
PROTOBUFFS_URL = https://raw.githubusercontent.com/basho/erlang_protobuffs/master/test/erlang_protobuffs_SUITE_data
@@ -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,7 +40,7 @@ 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)/
@@ -50,26 +50,26 @@ protobuffs-compile-with-gpb: init
$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"
+ $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
@@ -110,8 +110,8 @@ protobuffs-makefile-change: 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/
diff --git a/test/plugin_relx.mk b/test/plugin_relx.mk
index 2771e8f..c91a26b 100644
--- a/test/plugin_relx.mk
+++ b/test/plugin_relx.mk
@@ -3,9 +3,9 @@
# Sleeps when interacting with relx script are necessary after start and upgrade
# as both of those interactions are not synchronized.
-RELX_TARGETS = $(call list_targets,relx)
+relx_TARGETS = $(call list_targets,relx)
-.PHONY: relx $(RELX_TARGETS)
+.PHONY: relx $(relx_TARGETS)
ifeq ($(PLATFORM),msys2)
RELX_REL_EXT = .cmd
@@ -13,7 +13,7 @@ else
RELX_REL_EXT =
endif
-relx: $(RELX_TARGETS)
+relx: $(relx_TARGETS)
relx-rel: init
@@ -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
@@ -66,8 +63,8 @@ relx-apps-with-deps: init
$i "Include my_app in the release"
$t perl -pi.bak -e 's/$(APP),/$(APP), my_app,/' $(APP)/relx.config
- $i "Add Cowlib to the list of dependencies for my_app"
- $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\n"}' $(APP)/apps/my_app/Makefile
+ $i "Add Cowlib 2.13.0 to the list of dependencies for my_app"
+ $t perl -ni.bak -e 'print;if ($$.==1) {print "DEPS = cowlib\ndep_cowlib_commit = 2.13.0\n"}' $(APP)/apps/my_app/Makefile
ifdef LEGACY
$i "Add Cowlib to the applications key in the my_app.app.src file"
@@ -85,7 +82,7 @@ endif
$t test -f $(APP)/deps/cowlib/ebin/cowlib.app
$i "Check that Cowlib was included in the release"
- $t test -d $(APP)/_rel/test_relx_apps_with_deps_release/lib/cowlib-1.0.2
+ $t test -d $(APP)/_rel/test_relx_apps_with_deps_release/lib/cowlib-2.13.0
relx-bare-rel: init
@@ -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_shell.mk b/test/plugin_shell.mk
index 533f0a7..83b9883 100644
--- a/test/plugin_shell.mk
+++ b/test/plugin_shell.mk
@@ -1,10 +1,10 @@
# Shell plugin.
-SHELL_TARGETS = $(call list_targets,shell)
+shell_TARGETS = $(call list_targets,shell)
-.PHONY: shell $(C_SRC_TARGETS)
+.PHONY: shell $(shell_TARGETS)
-shell: $(SHELL_TARGETS)
+shell: $(shell_TARGETS)
shell-compile: init
diff --git a/test/plugin_sphinx.mk b/test/plugin_sphinx.mk
index 915bf8b..834a273 100644
--- a/test/plugin_sphinx.mk
+++ b/test/plugin_sphinx.mk
@@ -2,14 +2,14 @@
# Disable this test suite when sphinx is not installed.
ifeq ($(shell which sphinx-build),)
-SPHINX_TARGETS =
+sphinx_TARGETS =
else
-SPHINX_TARGETS = $(call list_targets,sphinx)
+sphinx_TARGETS = $(call list_targets,sphinx)
endif
-.PHONY: sphinx $(SPHINX_TARGETS)
+.PHONY: sphinx $(sphinx_TARGETS)
-sphinx: $(SPHINX_TARGETS)
+sphinx: $(sphinx_TARGETS)
sphinx-build: init
diff --git a/test/plugin_triq.mk b/test/plugin_triq.mk
index 58fd217..bf81d98 100644
--- a/test/plugin_triq.mk
+++ b/test/plugin_triq.mk
@@ -1,10 +1,10 @@
# Triq plugin.
-TRIQ_TARGETS = $(call list_targets,triq)
+triq_TARGETS = $(call list_targets,triq)
-.PHONY: triq $(TRIQ_TARGETS)
+.PHONY: triq $(triq_TARGETS)
-triq: $(TRIQ_TARGETS)
+triq: $(triq_TARGETS)
triq-test-dir: init
diff --git a/test/plugin_xref.mk b/test/plugin_xref.mk
new file mode 100644
index 0000000..e98d7d0
--- /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