diff options
Diffstat (limited to 'test')
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 |