aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md61
-rw-r--r--build.config2
-rw-r--r--core/core.mk16
-rw-r--r--core/deps.mk47
-rw-r--r--core/erlc.mk22
-rw-r--r--core/test.mk44
-rw-r--r--erlang.mk280
-rw-r--r--plugins/ct.mk60
-rw-r--r--plugins/elvis.mk10
-rw-r--r--plugins/eunit.mk50
-rw-r--r--plugins/triq.mk29
-rw-r--r--test/Makefile20
12 files changed, 428 insertions, 213 deletions
diff --git a/README.md b/README.md
index 4eb666b..c182429 100644
--- a/README.md
+++ b/README.md
@@ -138,6 +138,24 @@ dep_ct_helper = git https://github.com/extend/ct_helper.git master
Please note that the test dependencies will only be compiled once
when they are fetched, unlike the normal dependencies.
+Autopatch
+---------
+
+The autopatch features allows you to automatically fix packages
+that are not compatible with erlang.mk. It can also be used to
+convert compatible packages to use erlang.mk itself for building
+when used as dependency.
+
+The patching occurs only once, immediately after the package has
+been fetched.
+
+erlang.mk defines a number of packages to be patched. You can add
+more packages to the list by appending the `AUTOPATCH` variable.
+
+``` Makefile
+AUTOPATCH += gproc
+```
+
Releases
--------
@@ -215,12 +233,18 @@ Cloning into '/home/essen/ninenines/cowboy/deps/ranch'...
Cloning into '/home/essen/ninenines/cowboy/deps/cowlib'...
```
+The `-O` option will ensure that output from different
+targets is grouped, which is particularly useful when
+running tests with different frameworks at the same time.
+The disadvantage of this option however is that there is
+no output until the target is completed.
+
The``MAKEFLAGS` variable can be used to set it permanently
on your system. It can be set in your `.zshrc`, `.bashrc`
or equivalent file.
``` bash
-MAKEFLAGS=-j32
+MAKEFLAGS="-j32 -O"
```
Core package functionality
@@ -252,6 +276,9 @@ You can change compilation options by setting the `ERLC_OPTS`
variable. It takes the arguments that will then be passed to
`erlc`. For more information, please see `erl -man erlc`.
+Test target compilation options can be specified in `TEST_ERLC_OPTS`.
+It will override `ERLC_OPTS`.
+
You can specify a list of modules to be compiled first using
the `COMPILE_FIRST` variable.
@@ -325,7 +352,10 @@ The defaults are system dependent.
Common_test plugin
------------------
-This plugin is available by default.
+This plugin is available by default. It adds the following
+target:
+
+`ct` runs all test suites for this application.
There is nothing to configure to use it, simply create your
test suites in the `./test/` directory and erlang.mk will
@@ -438,9 +468,8 @@ EUnit plugin
This plugin is available by default. It adds the following
target:
-`eunit` which runs all the EUnit tests found in `ebin` and
-any of the additional EUnit directories specified in
-`EUNIT_DIR`.
+`eunit` which runs all the EUnit tests found in `ebin` or
+the test directory specified in `TEST_DIR`.
`EUNIT_OPTS` can be used to specify EUnit-specific options
(e.g. `verbose`) that will be used when calling
@@ -487,6 +516,28 @@ For more information please see `erl -man erl`.
`SHELL_PATH` adds paths to the shell's library search path. By default
this option sets the paths to `-pa ../$(PROJECT)/ebin $(DEPS_DIR)/*/ebin`.
+Triq plugin
+-----------
+
+This plugin is available by default. It adds the following
+target:
+
+`triq` will check all the properties found in `ebin` or
+the test directory specified in `TEST_DIR`.
+
+You can use the `t` variable to give a specific module
+or function to run, for example:
+
+``` bash
+$ make triq t=cow_http_hd
+```
+
+Or:
+
+``` bash
+$ make triq t=cow_http_hd:prop_parse_accept
+```
+
Contributing
------------
diff --git a/build.config b/build.config
index 8b6e721..7e60d80 100644
--- a/build.config
+++ b/build.config
@@ -5,6 +5,7 @@
core/core
core/deps
core/erlc
+core/test
# Plugins.
#
@@ -20,3 +21,4 @@ plugins/escript
plugins/eunit
plugins/relx
plugins/shell
+plugins/triq
diff --git a/core/core.mk b/core/core.mk
index 95b4c57..8622be2 100644
--- a/core/core.mk
+++ b/core/core.mk
@@ -38,16 +38,20 @@ ifneq ($(words $(MAKECMDGOALS)),1)
.NOTPARALLEL:
endif
-all::
- @$(MAKE) --no-print-directory deps
+all:: deps
@$(MAKE) --no-print-directory app
-# @todo Plugin stuff creeping inside Core, not good.
-ifneq ($(wildcard $(RELX_CONFIG)),)
@$(MAKE) --no-print-directory rel
-endif
-clean::
+# Noop to avoid a Make warning when there's nothing to do.
+rel::
+ @echo -n
+
+clean:: clean-crashdump
+
+clean-crashdump:
+ifneq ($(wildcard erl_crash.dump),)
$(gen_verbose) rm -f erl_crash.dump
+endif
distclean:: clean
diff --git a/core/deps.mk b/core/deps.mk
index 7d4b974..35fefb5 100644
--- a/core/deps.mk
+++ b/core/deps.mk
@@ -5,6 +5,9 @@
# Configuration.
+AUTOPATCH ?= edown gen_leader gproc
+export AUTOPATCH
+
DEPS_DIR ?= $(CURDIR)/deps
export DEPS_DIR
@@ -42,6 +45,41 @@ distclean:: distclean-deps distclean-pkg
# Deps related targets.
+define dep_autopatch
+ $(ERL) -eval " \
+DepDir = \"$(DEPS_DIR)/$(1)/\", \
+fun() -> \
+ {ok, Conf} = file:consult(DepDir ++ \"rebar.config\"), \
+ File = case lists:keyfind(deps, 1, Conf) of false -> []; {_, Deps} -> \
+ [begin {Method, Repo, Commit} = case Repos of \
+ {git, R} -> {git, R, master}; \
+ {M, R, {branch, C}} -> {M, R, C}; \
+ {M, R, {tag, C}} -> {M, R, C}; \
+ {M, R, C} -> {M, R, C} \
+ end, \
+ io_lib:format(\"DEPS += ~s\ndep_~s = ~s ~s ~s~n\", [Name, Name, Method, Repo, Commit]) \
+ end || {Name, _, Repos} <- Deps] \
+ end, \
+ ok = file:write_file(\"$(DEPS_DIR)/$(1)/Makefile\", [\"ERLC_OPTS = +debug_info\n\n\", File, \"\ninclude erlang.mk\"]) \
+end(), \
+AppSrcOut = \"$(DEPS_DIR)/$(1)/src/$(1).app.src\", \
+AppSrcIn = case filelib:is_regular(AppSrcOut) of false -> \"$(DEPS_DIR)/$(1)/ebin/$(1).app\"; true -> AppSrcOut end, \
+fun() -> \
+ {ok, [{application, $(1), L}]} = file:consult(AppSrcIn), \
+ L2 = case lists:keyfind(modules, 1, L) of {_, _} -> L; false -> [{modules, []}|L] end, \
+ L3 = case lists:keyfind(vsn, 1, L2) of {vsn, git} -> lists:keyreplace(vsn, 1, L2, {vsn, \"git\"}); _ -> L2 end, \
+ ok = file:write_file(AppSrcOut, io_lib:format(\"~p.~n\", [{application, $(1), L3}])) \
+end(), \
+case AppSrcOut of AppSrcIn -> ok; _ -> ok = file:delete(AppSrcIn) end, \
+halt()."
+endef
+
+ifeq ($(V),0)
+define dep_autopatch_verbose
+ @echo " PATCH " $(1);
+endef
+endif
+
define dep_fetch
if [ "$$$$VS" = "git" ]; then \
git clone -n -- $$$$REPO $(DEPS_DIR)/$(1); \
@@ -73,6 +111,15 @@ else
COMMIT=$(word 3,$(dep_$(1))); \
$(call dep_fetch,$(1))
endif
+ifneq ($(filter $(1),$(AUTOPATCH)),)
+ $(call dep_autopatch_verbose,$(1)) if [ -f $(DEPS_DIR)/$(1)/rebar.config ]; then \
+ $(call dep_autopatch,$(1)); \
+ cd $(DEPS_DIR)/$(1)/ && ln -s ../../erlang.mk; \
+ elif [ ! -f $(DEPS_DIR)/$(1)/Makefile ]; then \
+ echo "ERLC_OPTS = +debug_info\ninclude erlang.mk" > $(DEPS_DIR)/$(1)/Makefile; \
+ cd $(DEPS_DIR)/$(1)/ && ln -s ../../erlang.mk; \
+ fi
+endif
endef
$(foreach dep,$(DEPS),$(eval $(call dep_target,$(dep))))
diff --git a/core/erlc.mk b/core/erlc.mk
index 8d720aa..e391da8 100644
--- a/core/erlc.mk
+++ b/core/erlc.mk
@@ -31,9 +31,15 @@ xyrl_verbose = $(xyrl_verbose_$(V))
mib_verbose_0 = @echo " MIB " $(filter %.bin %.mib,$(?F));
mib_verbose = $(mib_verbose_$(V))
-# Core targets.
+# Targets.
-app:: erlc-include ebin/$(PROJECT).app
+ifeq ($(wildcard ebin/test),)
+app:: app-build
+else
+app:: clean app-build
+endif
+
+app-build: erlc-include ebin/$(PROJECT).app
$(eval MODULES := $(shell find ebin -type f -name \*.beam \
| sed "s/ebin\//'/;s/\.beam/',/" | sed '$$s/.$$//'))
@if [ -z "$$(grep -E '^[^%]*{modules,' src/$(PROJECT).app.src)" ]; then \
@@ -46,6 +52,11 @@ app:: erlc-include ebin/$(PROJECT).app
| sed "s/{id,[[:space:]]*\"git\"}/{id, \"$(GITDESCRIBE)\"}/" \
> ebin/$(PROJECT).app
+erlc-include:
+ -@if [ -d ebin/ ]; then \
+ find include/ src/ -type f -name \*.hrl -newer ebin -exec touch $(shell find src/ -type f -name "*.erl") \; 2>/dev/null || printf ''; \
+ fi
+
define compile_erl
$(erlc_verbose) erlc -v $(ERLC_OPTS) -o ebin/ \
-pa ebin/ -I include/ $(filter-out $(ERLC_EXCLUDE_PATHS),\
@@ -85,13 +96,6 @@ endif
clean:: clean-app
-# Extra targets.
-
-erlc-include:
- -@if [ -d ebin/ ]; then \
- find include/ src/ -type f -name \*.hrl -newer ebin -exec touch $(shell find src/ -type f -name "*.erl") \; 2>/dev/null || printf ''; \
- fi
-
clean-app:
$(gen_verbose) rm -rf ebin/ priv/mibs/ \
$(addprefix include/,$(addsuffix .hrl,$(notdir $(basename $(wildcard mibs/*.mib)))))
diff --git a/core/test.mk b/core/test.mk
new file mode 100644
index 0000000..d3f49c2
--- /dev/null
+++ b/core/test.mk
@@ -0,0 +1,44 @@
+# Copyright (c) 2015, Loïc Hoguin <[email protected]>
+# This file is part of erlang.mk and subject to the terms of the ISC License.
+
+.PHONY: test-deps test-dir test-build clean-test-dir
+
+# Configuration.
+
+TEST_DIR ?= test
+
+ALL_TEST_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(TEST_DEPS))
+
+TEST_ERLC_OPTS ?= +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard
+TEST_ERLC_OPTS += -DTEST=1
+
+# Targets.
+
+$(foreach dep,$(TEST_DEPS),$(eval $(call dep_target,$(dep))))
+
+test-deps: $(ALL_TEST_DEPS_DIRS)
+ @for dep in $(ALL_TEST_DEPS_DIRS) ; do $(MAKE) -C $$dep; done
+
+ifneq ($(strip $(TEST_DIR)),)
+test-dir:
+ $(gen_verbose) erlc -v $(TEST_ERLC_OPTS) -I include/ -o $(TEST_DIR) \
+ $(wildcard $(TEST_DIR)/*.erl $(TEST_DIR)/*/*.erl) -pa ebin/
+endif
+
+ifeq ($(wildcard ebin/test),)
+test-build: ERLC_OPTS=$(TEST_ERLC_OPTS)
+test-build: clean deps test-deps
+ @$(MAKE) --no-print-directory app-build test-dir ERLC_OPTS="$(TEST_ERLC_OPTS)"
+ $(gen_verbose) touch ebin/test
+else
+test-build: ERLC_OPTS=$(TEST_ERLC_OPTS)
+test-build: deps test-deps
+ @$(MAKE) --no-print-directory app-build test-dir ERLC_OPTS="$(TEST_ERLC_OPTS)"
+endif
+
+clean:: clean-test-dir
+
+clean-test-dir:
+ifneq ($(wildcard $(TEST_DIR)/*.beam),)
+ $(gen_verbose) rm -f $(TEST_DIR)/*.beam
+endif
diff --git a/erlang.mk b/erlang.mk
index dca0aca..6faa659 100644
--- a/erlang.mk
+++ b/erlang.mk
@@ -38,16 +38,20 @@ ifneq ($(words $(MAKECMDGOALS)),1)
.NOTPARALLEL:
endif
-all::
- @$(MAKE) --no-print-directory deps
+all:: deps
@$(MAKE) --no-print-directory app
-# @todo Plugin stuff creeping inside Core, not good.
-ifneq ($(wildcard $(RELX_CONFIG)),)
@$(MAKE) --no-print-directory rel
-endif
-clean::
+# Noop to avoid a Make warning when there's nothing to do.
+rel::
+ @echo -n
+
+clean:: clean-crashdump
+
+clean-crashdump:
+ifneq ($(wildcard erl_crash.dump),)
$(gen_verbose) rm -f erl_crash.dump
+endif
distclean:: clean
@@ -106,6 +110,9 @@ erlang-mk:
# Configuration.
+AUTOPATCH ?= edown gen_leader gproc
+export AUTOPATCH
+
DEPS_DIR ?= $(CURDIR)/deps
export DEPS_DIR
@@ -143,6 +150,41 @@ distclean:: distclean-deps distclean-pkg
# Deps related targets.
+define dep_autopatch
+ $(ERL) -eval " \
+DepDir = \"$(DEPS_DIR)/$(1)/\", \
+fun() -> \
+ {ok, Conf} = file:consult(DepDir ++ \"rebar.config\"), \
+ File = case lists:keyfind(deps, 1, Conf) of false -> []; {_, Deps} -> \
+ [begin {Method, Repo, Commit} = case Repos of \
+ {git, R} -> {git, R, master}; \
+ {M, R, {branch, C}} -> {M, R, C}; \
+ {M, R, {tag, C}} -> {M, R, C}; \
+ {M, R, C} -> {M, R, C} \
+ end, \
+ io_lib:format(\"DEPS += ~s\ndep_~s = ~s ~s ~s~n\", [Name, Name, Method, Repo, Commit]) \
+ end || {Name, _, Repos} <- Deps] \
+ end, \
+ ok = file:write_file(\"$(DEPS_DIR)/$(1)/Makefile\", [\"ERLC_OPTS = +debug_info\n\n\", File, \"\ninclude erlang.mk\"]) \
+end(), \
+AppSrcOut = \"$(DEPS_DIR)/$(1)/src/$(1).app.src\", \
+AppSrcIn = case filelib:is_regular(AppSrcOut) of false -> \"$(DEPS_DIR)/$(1)/ebin/$(1).app\"; true -> AppSrcOut end, \
+fun() -> \
+ {ok, [{application, $(1), L}]} = file:consult(AppSrcIn), \
+ L2 = case lists:keyfind(modules, 1, L) of {_, _} -> L; false -> [{modules, []}|L] end, \
+ L3 = case lists:keyfind(vsn, 1, L2) of {vsn, git} -> lists:keyreplace(vsn, 1, L2, {vsn, \"git\"}); _ -> L2 end, \
+ ok = file:write_file(AppSrcOut, io_lib:format(\"~p.~n\", [{application, $(1), L3}])) \
+end(), \
+case AppSrcOut of AppSrcIn -> ok; _ -> ok = file:delete(AppSrcIn) end, \
+halt()."
+endef
+
+ifeq ($(V),0)
+define dep_autopatch_verbose
+ @echo " PATCH " $(1);
+endef
+endif
+
define dep_fetch
if [ "$$$$VS" = "git" ]; then \
git clone -n -- $$$$REPO $(DEPS_DIR)/$(1); \
@@ -174,6 +216,15 @@ else
COMMIT=$(word 3,$(dep_$(1))); \
$(call dep_fetch,$(1))
endif
+ifneq ($(filter $(1),$(AUTOPATCH)),)
+ $(call dep_autopatch_verbose,$(1)) if [ -f $(DEPS_DIR)/$(1)/rebar.config ]; then \
+ $(call dep_autopatch,$(1)); \
+ cd $(DEPS_DIR)/$(1)/ && ln -s ../../erlang.mk; \
+ elif [ ! -f $(DEPS_DIR)/$(1)/Makefile ]; then \
+ echo "ERLC_OPTS = +debug_info\ninclude erlang.mk" > $(DEPS_DIR)/$(1)/Makefile; \
+ cd $(DEPS_DIR)/$(1)/ && ln -s ../../erlang.mk; \
+ fi
+endif
endef
$(foreach dep,$(DEPS),$(eval $(call dep_target,$(dep))))
@@ -249,9 +300,15 @@ xyrl_verbose = $(xyrl_verbose_$(V))
mib_verbose_0 = @echo " MIB " $(filter %.bin %.mib,$(?F));
mib_verbose = $(mib_verbose_$(V))
-# Core targets.
+# Targets.
-app:: erlc-include ebin/$(PROJECT).app
+ifeq ($(wildcard ebin/test),)
+app:: app-build
+else
+app:: clean app-build
+endif
+
+app-build: erlc-include ebin/$(PROJECT).app
$(eval MODULES := $(shell find ebin -type f -name \*.beam \
| sed "s/ebin\//'/;s/\.beam/',/" | sed '$$s/.$$//'))
@if [ -z "$$(grep -E '^[^%]*{modules,' src/$(PROJECT).app.src)" ]; then \
@@ -264,6 +321,11 @@ app:: erlc-include ebin/$(PROJECT).app
| sed "s/{id,[[:space:]]*\"git\"}/{id, \"$(GITDESCRIBE)\"}/" \
> ebin/$(PROJECT).app
+erlc-include:
+ -@if [ -d ebin/ ]; then \
+ find include/ src/ -type f -name \*.hrl -newer ebin -exec touch $(shell find src/ -type f -name "*.erl") \; 2>/dev/null || printf ''; \
+ fi
+
define compile_erl
$(erlc_verbose) erlc -v $(ERLC_OPTS) -o ebin/ \
-pa ebin/ -I include/ $(filter-out $(ERLC_EXCLUDE_PATHS),\
@@ -303,17 +365,55 @@ endif
clean:: clean-app
-# Extra targets.
-
-erlc-include:
- -@if [ -d ebin/ ]; then \
- find include/ src/ -type f -name \*.hrl -newer ebin -exec touch $(shell find src/ -type f -name "*.erl") \; 2>/dev/null || printf ''; \
- fi
-
clean-app:
$(gen_verbose) rm -rf ebin/ priv/mibs/ \
$(addprefix include/,$(addsuffix .hrl,$(notdir $(basename $(wildcard mibs/*.mib)))))
+# Copyright (c) 2015, Loïc Hoguin <[email protected]>
+# This file is part of erlang.mk and subject to the terms of the ISC License.
+
+.PHONY: test-deps test-dir test-build clean-test-dir
+
+# Configuration.
+
+TEST_DIR ?= test
+
+ALL_TEST_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(TEST_DEPS))
+
+TEST_ERLC_OPTS ?= +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard
+TEST_ERLC_OPTS += -DTEST=1
+
+# Targets.
+
+$(foreach dep,$(TEST_DEPS),$(eval $(call dep_target,$(dep))))
+
+test-deps: $(ALL_TEST_DEPS_DIRS)
+ @for dep in $(ALL_TEST_DEPS_DIRS) ; do $(MAKE) -C $$dep; done
+
+ifneq ($(strip $(TEST_DIR)),)
+test-dir:
+ $(gen_verbose) erlc -v $(TEST_ERLC_OPTS) -I include/ -o $(TEST_DIR) \
+ $(wildcard $(TEST_DIR)/*.erl $(TEST_DIR)/*/*.erl) -pa ebin/
+endif
+
+ifeq ($(wildcard ebin/test),)
+test-build: ERLC_OPTS=$(TEST_ERLC_OPTS)
+test-build: clean deps test-deps
+ @$(MAKE) --no-print-directory app-build test-dir ERLC_OPTS="$(TEST_ERLC_OPTS)"
+ $(gen_verbose) touch ebin/test
+else
+test-build: ERLC_OPTS=$(TEST_ERLC_OPTS)
+test-build: deps test-deps
+ @$(MAKE) --no-print-directory app-build test-dir ERLC_OPTS="$(TEST_ERLC_OPTS)"
+endif
+
+clean:: clean-test-dir
+
+clean-test-dir:
+ifneq ($(wildcard $(TEST_DIR)/*.beam),)
+ $(gen_verbose) rm -f $(TEST_DIR)/*.beam
+endif
+
# Copyright (c) 2014, Loïc Hoguin <[email protected]>
# This file is part of erlang.mk and subject to the terms of the ISC License.
@@ -751,78 +851,56 @@ endif
# Copyright (c) 2013-2014, Loïc Hoguin <[email protected]>
# This file is part of erlang.mk and subject to the terms of the ISC License.
-.PHONY: build-ct-deps build-ct-suites tests-ct clean-ct distclean-ct
+.PHONY: ct distclean-ct
# Configuration.
CT_OPTS ?=
-ifneq ($(wildcard test/),)
- CT_SUITES ?= $(sort $(subst _SUITE.erl,,$(shell find test -type f -name \*_SUITE.erl -exec basename {} \;)))
+ifneq ($(wildcard $(TEST_DIR)),)
+ CT_SUITES ?= $(sort $(subst _SUITE.erl,,$(shell find $(TEST_DIR) -type f -name \*_SUITE.erl -exec basename {} \;)))
else
CT_SUITES ?=
endif
-TEST_ERLC_OPTS ?= +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard
-TEST_ERLC_OPTS += -DTEST=1 -DEXTRA=1 +'{parse_transform, eunit_autoexport}'
-
# Core targets.
-tests:: tests-ct
-
-clean:: clean-ct
+tests:: ct
distclean:: distclean-ct
help::
@printf "%s\n" "" \
+ "Common_test targets:" \
+ " ct Run all the common_test suites for this project" \
+ "" \
"All your common_test suites have their associated targets." \
"A suite named http_SUITE can be ran using the ct-http target."
# Plugin-specific targets.
-ALL_TEST_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(TEST_DEPS))
-
CT_RUN = ct_run \
-no_auto_compile \
-noinput \
- -pa $(realpath ebin) $(DEPS_DIR)/*/ebin \
- -dir test \
+ -pa ebin $(DEPS_DIR)/*/ebin \
+ -dir $(TEST_DIR) \
-logdir logs
-$(foreach dep,$(TEST_DEPS),$(eval $(call dep_target,$(dep))))
-
-build-ct-deps: $(ALL_TEST_DEPS_DIRS)
- @for dep in $(ALL_TEST_DEPS_DIRS) ; do $(MAKE) -C $$dep; done
-
-build-ct-suites: build-ct-deps
- $(gen_verbose) erlc -v $(TEST_ERLC_OPTS) -I include/ -o test/ \
- $(wildcard test/*.erl test/*/*.erl) -pa ebin/
-
-tests-ct: ERLC_OPTS = $(TEST_ERLC_OPTS)
-tests-ct: clean deps app build-ct-suites
- @if [ -d "test" ] ; \
- then \
- mkdir -p logs/ ; \
- $(CT_RUN) -suite $(addsuffix _SUITE,$(CT_SUITES)) $(CT_OPTS) ; \
- fi
- $(gen_verbose) rm -f test/*.beam
+ifeq ($(CT_SUITES),)
+ct:
+else
+ct: test-build
+ @mkdir -p logs/
+ $(gen_verbose) $(CT_RUN) -suite $(addsuffix _SUITE,$(CT_SUITES)) $(CT_OPTS)
+endif
define ct_suite_target
-ct-$(1): ERLC_OPTS = $(TEST_ERLC_OPTS)
-ct-$(1): clean deps app build-ct-suites
- @if [ -d "test" ] ; \
- then \
- mkdir -p logs/ ; \
- $(CT_RUN) -suite $(addsuffix _SUITE,$(1)) $(CT_OPTS) ; \
- fi
- $(gen_verbose) rm -f test/*.beam
+ct-$(1): test-build
+ @mkdir -p logs/
+ $(gen_verbose) $(CT_RUN) -suite $(addsuffix _SUITE,$(1)) $(CT_OPTS)
endef
$(foreach test,$(CT_SUITES),$(eval $(call ct_suite_target,$(test))))
-clean-ct:
- $(gen_verbose) rm -rf test/*.beam
-
distclean-ct:
$(gen_verbose) rm -rf logs/
@@ -920,20 +998,18 @@ help::
"Elvis targets:" \
" elvis Run Elvis using the local elvis.config or download the default otherwise"
-ifneq ($(wildcard $(ELVIS_CONFIG)),)
-rel:: distclean-elvis
-endif
-
distclean:: distclean-elvis
# Plugin-specific targets.
$(ELVIS):
- @$(call core_http_get,$(ELVIS_CONFIG),$(ELVIS_CONFIG_URL))
@$(call core_http_get,$(ELVIS),$(ELVIS_URL))
@chmod +x $(ELVIS)
-elvis: $(ELVIS)
+$(ELVIS_CONFIG):
+ @$(call core_http_get,$(ELVIS_CONFIG),$(ELVIS_CONFIG_URL))
+
+elvis: $(ELVIS) $(ELVIS_CONFIG)
@$(ELVIS) rock -c $(ELVIS_CONFIG) $(ELVIS_OPTS)
distclean-elvis:
@@ -1039,25 +1115,20 @@ distclean-escript:
# Copyright (c) 2014, Enrique Fernandez <[email protected]>
# This file is contributed to erlang.mk and subject to the terms of the ISC License.
-.PHONY: help-eunit build-eunit eunit distclean-eunit
+.PHONY: eunit
# Configuration
-EUNIT_ERLC_OPTS ?= +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard -DTEST=1 -DEXTRA=1
-
-EUNIT_DIR ?=
-EUNIT_DIRS = $(sort $(EUNIT_DIR) ebin)
-
-ifeq ($(strip $(EUNIT_DIR)),)
+ifeq ($(strip $(TEST_DIR)),)
TAGGED_EUNIT_TESTS = {dir,"ebin"}
else
-# All modules in EUNIT_DIR
-EUNIT_DIR_MODS = $(notdir $(basename $(shell find $(EUNIT_DIR) -type f -name *.beam)))
+# All modules in TEST_DIR
+TEST_DIR_MODS = $(notdir $(basename $(shell find $(TEST_DIR) -type f -name *.beam)))
# All modules in 'ebin'
EUNIT_EBIN_MODS = $(notdir $(basename $(shell find ebin -type f -name *.beam)))
-# Only those modules in EUNIT_DIR with no matching module in 'ebin'.
+# Only those modules in TEST_DIR with no matching module in 'ebin'.
# This is done to avoid some tests being executed twice.
-EUNIT_MODS = $(filter-out $(patsubst %,%_tests,$(EUNIT_EBIN_MODS)),$(EUNIT_DIR_MODS))
+EUNIT_MODS = $(filter-out $(patsubst %,%_tests,$(EUNIT_EBIN_MODS)),$(TEST_DIR_MODS))
TAGGED_EUNIT_TESTS = {dir,"ebin"} $(foreach mod,$(EUNIT_MODS),$(shell echo $(mod) | sed -e 's/\(.*\)/{module,\1}/g'))
endif
@@ -1071,42 +1142,23 @@ endef
# Core targets.
-help:: help-eunit
-
tests:: eunit
-clean:: clean-eunit
+help::
+ @printf "%s\n" "" \
+ "EUnit targets:" \
+ " eunit Run all the EUnit tests for this project"
# Plugin-specific targets.
EUNIT_RUN = $(ERL) \
- -no_auto_compile \
- -pa $(realpath $(EUNIT_DIR)) $(DEPS_DIR)/*/ebin \
- -pz $(realpath ebin) \
+ -pa $(TEST_DIR) $(DEPS_DIR)/*/ebin \
+ -pz ebin \
-eval 'case eunit:test([$(call str-join,$(TAGGED_EUNIT_TESTS))], [$(EUNIT_OPTS)]) of ok -> halt(0); error -> halt(1) end.'
-help-eunit:
- @printf "%s\n" "" \
- "EUnit targets:" \
- " eunit Run all the EUnit tests for this project"
-
-ifeq ($(strip $(EUNIT_DIR)),)
-build-eunit:
-else ifeq ($(strip $(EUNIT_DIR)),ebin)
-build-eunit:
-else
-build-eunit:
- $(gen_verbose) erlc -v $(EUNIT_ERLC_OPTS) -I include/ -o $(EUNIT_DIR) \
- $(wildcard $(EUNIT_DIR)/*.erl $(EUNIT_DIR)/*/*.erl) -pa ebin/
-endif
-
-eunit: ERLC_OPTS = $(EUNIT_ERLC_OPTS)
-eunit: clean deps app build-eunit
+eunit: test-build
$(gen_verbose) $(EUNIT_RUN)
-clean-eunit:
- $(gen_verbose) $(foreach dir,$(EUNIT_DIRS),rm -rf $(dir)/*.beam)
-
# Copyright (c) 2013-2014, Loïc Hoguin <[email protected]>
# This file is part of erlang.mk and subject to the terms of the ISC License.
@@ -1184,3 +1236,33 @@ build-shell-deps: $(ALL_SHELL_DEPS_DIRS)
shell: build-shell-deps
$(gen_verbose) erl $(SHELL_PATH) $(SHELL_OPTS)
+
+# Copyright (c) 2015, Loïc Hoguin <[email protected]>
+# This file is part of erlang.mk and subject to the terms of the ISC License.
+
+.PHONY: triq
+
+# Targets.
+
+tests:: triq
+
+define triq_run
+$(ERL) -pa $(CURDIR)/ebin $(DEPS_DIR)/*/ebin \
+ -eval "try $(1) of true -> halt(0); _ -> halt(1) catch error:undef -> io:format(\"Undefined property or module~n\"), halt() end."
+endef
+
+ifdef t
+ifeq (,$(findstring :,$(t)))
+triq: test-build
+ @$(call triq_run,triq:check($(t)))
+else
+triq: test-build
+ @echo Testing $(t)/0
+ @$(call triq_run,triq:check($(t)()))
+endif
+else
+triq: test-build
+ $(eval MODULES := $(shell find ebin -type f -name \*.beam \
+ | sed "s/ebin\//'/;s/\.beam/',/" | sed '$$s/.$$//'))
+ $(gen_verbose) $(call triq_run,[true] =:= lists:usort([triq:check(M) || M <- [$(MODULES)]]))
+endif
diff --git a/plugins/ct.mk b/plugins/ct.mk
index 18d432a..b281842 100644
--- a/plugins/ct.mk
+++ b/plugins/ct.mk
@@ -1,77 +1,55 @@
# Copyright (c) 2013-2014, Loïc Hoguin <[email protected]>
# This file is part of erlang.mk and subject to the terms of the ISC License.
-.PHONY: build-ct-deps build-ct-suites tests-ct clean-ct distclean-ct
+.PHONY: ct distclean-ct
# Configuration.
CT_OPTS ?=
-ifneq ($(wildcard test/),)
- CT_SUITES ?= $(sort $(subst _SUITE.erl,,$(shell find test -type f -name \*_SUITE.erl -exec basename {} \;)))
+ifneq ($(wildcard $(TEST_DIR)),)
+ CT_SUITES ?= $(sort $(subst _SUITE.erl,,$(shell find $(TEST_DIR) -type f -name \*_SUITE.erl -exec basename {} \;)))
else
CT_SUITES ?=
endif
-TEST_ERLC_OPTS ?= +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard
-TEST_ERLC_OPTS += -DTEST=1 -DEXTRA=1 +'{parse_transform, eunit_autoexport}'
-
# Core targets.
-tests:: tests-ct
-
-clean:: clean-ct
+tests:: ct
distclean:: distclean-ct
help::
@printf "%s\n" "" \
+ "Common_test targets:" \
+ " ct Run all the common_test suites for this project" \
+ "" \
"All your common_test suites have their associated targets." \
"A suite named http_SUITE can be ran using the ct-http target."
# Plugin-specific targets.
-ALL_TEST_DEPS_DIRS = $(addprefix $(DEPS_DIR)/,$(TEST_DEPS))
-
CT_RUN = ct_run \
-no_auto_compile \
-noinput \
- -pa $(realpath ebin) $(DEPS_DIR)/*/ebin \
- -dir test \
+ -pa ebin $(DEPS_DIR)/*/ebin \
+ -dir $(TEST_DIR) \
-logdir logs
-$(foreach dep,$(TEST_DEPS),$(eval $(call dep_target,$(dep))))
-
-build-ct-deps: $(ALL_TEST_DEPS_DIRS)
- @for dep in $(ALL_TEST_DEPS_DIRS) ; do $(MAKE) -C $$dep; done
-
-build-ct-suites: build-ct-deps
- $(gen_verbose) erlc -v $(TEST_ERLC_OPTS) -I include/ -o test/ \
- $(wildcard test/*.erl test/*/*.erl) -pa ebin/
-
-tests-ct: ERLC_OPTS = $(TEST_ERLC_OPTS)
-tests-ct: clean deps app build-ct-suites
- @if [ -d "test" ] ; \
- then \
- mkdir -p logs/ ; \
- $(CT_RUN) -suite $(addsuffix _SUITE,$(CT_SUITES)) $(CT_OPTS) ; \
- fi
- $(gen_verbose) rm -f test/*.beam
+ifeq ($(CT_SUITES),)
+ct:
+else
+ct: test-build
+ @mkdir -p logs/
+ $(gen_verbose) $(CT_RUN) -suite $(addsuffix _SUITE,$(CT_SUITES)) $(CT_OPTS)
+endif
define ct_suite_target
-ct-$(1): ERLC_OPTS = $(TEST_ERLC_OPTS)
-ct-$(1): clean deps app build-ct-suites
- @if [ -d "test" ] ; \
- then \
- mkdir -p logs/ ; \
- $(CT_RUN) -suite $(addsuffix _SUITE,$(1)) $(CT_OPTS) ; \
- fi
- $(gen_verbose) rm -f test/*.beam
+ct-$(1): test-build
+ @mkdir -p logs/
+ $(gen_verbose) $(CT_RUN) -suite $(addsuffix _SUITE,$(1)) $(CT_OPTS)
endef
$(foreach test,$(CT_SUITES),$(eval $(call ct_suite_target,$(test))))
-clean-ct:
- $(gen_verbose) rm -rf test/*.beam
-
distclean-ct:
$(gen_verbose) rm -rf logs/
diff --git a/plugins/elvis.mk b/plugins/elvis.mk
index f3e75a8..580e2f5 100644
--- a/plugins/elvis.mk
+++ b/plugins/elvis.mk
@@ -21,20 +21,18 @@ help::
"Elvis targets:" \
" elvis Run Elvis using the local elvis.config or download the default otherwise"
-ifneq ($(wildcard $(ELVIS_CONFIG)),)
-rel:: distclean-elvis
-endif
-
distclean:: distclean-elvis
# Plugin-specific targets.
$(ELVIS):
- @$(call core_http_get,$(ELVIS_CONFIG),$(ELVIS_CONFIG_URL))
@$(call core_http_get,$(ELVIS),$(ELVIS_URL))
@chmod +x $(ELVIS)
-elvis: $(ELVIS)
+$(ELVIS_CONFIG):
+ @$(call core_http_get,$(ELVIS_CONFIG),$(ELVIS_CONFIG_URL))
+
+elvis: $(ELVIS) $(ELVIS_CONFIG)
@$(ELVIS) rock -c $(ELVIS_CONFIG) $(ELVIS_OPTS)
distclean-elvis:
diff --git a/plugins/eunit.mk b/plugins/eunit.mk
index 1b83a0f..ae132ac 100644
--- a/plugins/eunit.mk
+++ b/plugins/eunit.mk
@@ -1,25 +1,20 @@
# Copyright (c) 2014, Enrique Fernandez <[email protected]>
# This file is contributed to erlang.mk and subject to the terms of the ISC License.
-.PHONY: help-eunit build-eunit eunit distclean-eunit
+.PHONY: eunit
# Configuration
-EUNIT_ERLC_OPTS ?= +debug_info +warn_export_vars +warn_shadow_vars +warn_obsolete_guard -DTEST=1 -DEXTRA=1
-
-EUNIT_DIR ?=
-EUNIT_DIRS = $(sort $(EUNIT_DIR) ebin)
-
-ifeq ($(strip $(EUNIT_DIR)),)
+ifeq ($(strip $(TEST_DIR)),)
TAGGED_EUNIT_TESTS = {dir,"ebin"}
else
-# All modules in EUNIT_DIR
-EUNIT_DIR_MODS = $(notdir $(basename $(shell find $(EUNIT_DIR) -type f -name *.beam)))
+# All modules in TEST_DIR
+TEST_DIR_MODS = $(notdir $(basename $(shell find $(TEST_DIR) -type f -name *.beam)))
# All modules in 'ebin'
EUNIT_EBIN_MODS = $(notdir $(basename $(shell find ebin -type f -name *.beam)))
-# Only those modules in EUNIT_DIR with no matching module in 'ebin'.
+# Only those modules in TEST_DIR with no matching module in 'ebin'.
# This is done to avoid some tests being executed twice.
-EUNIT_MODS = $(filter-out $(patsubst %,%_tests,$(EUNIT_EBIN_MODS)),$(EUNIT_DIR_MODS))
+EUNIT_MODS = $(filter-out $(patsubst %,%_tests,$(EUNIT_EBIN_MODS)),$(TEST_DIR_MODS))
TAGGED_EUNIT_TESTS = {dir,"ebin"} $(foreach mod,$(EUNIT_MODS),$(shell echo $(mod) | sed -e 's/\(.*\)/{module,\1}/g'))
endif
@@ -33,38 +28,19 @@ endef
# Core targets.
-help:: help-eunit
-
tests:: eunit
-clean:: clean-eunit
+help::
+ @printf "%s\n" "" \
+ "EUnit targets:" \
+ " eunit Run all the EUnit tests for this project"
# Plugin-specific targets.
EUNIT_RUN = $(ERL) \
- -no_auto_compile \
- -pa $(realpath $(EUNIT_DIR)) $(DEPS_DIR)/*/ebin \
- -pz $(realpath ebin) \
+ -pa $(TEST_DIR) $(DEPS_DIR)/*/ebin \
+ -pz ebin \
-eval 'case eunit:test([$(call str-join,$(TAGGED_EUNIT_TESTS))], [$(EUNIT_OPTS)]) of ok -> halt(0); error -> halt(1) end.'
-help-eunit:
- @printf "%s\n" "" \
- "EUnit targets:" \
- " eunit Run all the EUnit tests for this project"
-
-ifeq ($(strip $(EUNIT_DIR)),)
-build-eunit:
-else ifeq ($(strip $(EUNIT_DIR)),ebin)
-build-eunit:
-else
-build-eunit:
- $(gen_verbose) erlc -v $(EUNIT_ERLC_OPTS) -I include/ -o $(EUNIT_DIR) \
- $(wildcard $(EUNIT_DIR)/*.erl $(EUNIT_DIR)/*/*.erl) -pa ebin/
-endif
-
-eunit: ERLC_OPTS = $(EUNIT_ERLC_OPTS)
-eunit: clean deps app build-eunit
+eunit: test-build
$(gen_verbose) $(EUNIT_RUN)
-
-clean-eunit:
- $(gen_verbose) $(foreach dir,$(EUNIT_DIRS),rm -rf $(dir)/*.beam)
diff --git a/plugins/triq.mk b/plugins/triq.mk
new file mode 100644
index 0000000..8a77c91
--- /dev/null
+++ b/plugins/triq.mk
@@ -0,0 +1,29 @@
+# Copyright (c) 2015, Loïc Hoguin <[email protected]>
+# This file is part of erlang.mk and subject to the terms of the ISC License.
+
+.PHONY: triq
+
+# Targets.
+
+tests:: triq
+
+define triq_run
+$(ERL) -pa $(CURDIR)/ebin $(DEPS_DIR)/*/ebin \
+ -eval "try $(1) of true -> halt(0); _ -> halt(1) catch error:undef -> io:format(\"Undefined property or module~n\"), halt() end."
+endef
+
+ifdef t
+ifeq (,$(findstring :,$(t)))
+triq: test-build
+ @$(call triq_run,triq:check($(t)))
+else
+triq: test-build
+ @echo Testing $(t)/0
+ @$(call triq_run,triq:check($(t)()))
+endif
+else
+triq: test-build
+ $(eval MODULES := $(shell find ebin -type f -name \*.beam \
+ | sed "s/ebin\//'/;s/\.beam/',/" | sed '$$s/.$$//'))
+ $(gen_verbose) $(call triq_run,[true] =:= lists:usort([triq:check(M) || M <- [$(MODULES)]]))
+endif
diff --git a/test/Makefile b/test/Makefile
index c387081..265c67c 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -62,7 +62,7 @@ app: app1
$i "Test 'app' passed."
ct: app1
- $i "ct: Testing tests-ct and related targets."
+ $i "ct: Testing ct and related targets."
$i "Setting up test suite."
$t mkdir -p app1/test
$t printf "%s\n" \
@@ -71,17 +71,17 @@ ct: app1
"all() -> [testcase1]." \
"testcase1(_) -> 2 = m:succ(1)." \
> app1/test/m_SUITE.erl
- $t make -C app1 tests-ct $v
- $i "Checking files created by 'make tests-ct'."
- $t [ ! -e app1/test/m_SUITE.beam ]
+ $t make -C app1 ct $v
+ $i "Checking files created by 'make ct'."
+ $t [ -e app1/test/m_SUITE.beam ]
$t [ -e app1/ebin/m.beam ]
$t [ -e app1/logs ]
- $i "Checking that 'make clean-ct' does not delete logs."
- $t make -C app1 clean-ct $v
+ $i "Checking that 'make clean' does not delete logs."
+ $t make -C app1 clean $v
$t [ -e app1/logs ]
$i "Testing target 'ct-mysuite' where mysuite_SUITE is a test suite."
$t make -C app1 ct-m $v
- $i "Checking that 'make tests-ct' returns non-zero for a failing suite."
+ $i "Checking that 'make ct' returns non-zero for a failing suite."
$t printf "%s\n" \
"-module(failing_SUITE)." \
"-export([all/0, testcase1/1])." \
@@ -89,7 +89,7 @@ ct: app1
"testcase1(_) -> 42 = m:succ(1)." \
> app1/test/failing_SUITE.erl
$t if make -C app1 ct-failing $v ; then false ; fi
- $i "Checking that 'make ct-distclean' deletes logs."
+ $i "Checking that 'make distclean-ct' deletes logs."
$t make -C app1 distclean-ct $v
$t [ ! -e app1/logs ]
$t [ -e app1/ebin/m.beam ]
@@ -131,7 +131,7 @@ eunit: app1
' ?assertEqual(2, t:succ(1)),' \
' os:cmd("echo x_tests >> test-eunit.log").' \
> app1/eunit/x_tests.erl
- $t make -C app1 eunit EUNIT_DIR=eunit $v
+ $t make -C app1 eunit TEST_DIR=eunit $v
$i "Checking that 'make eunit' didn't run the tests in t_tests twice, etc."
$t printf "%s\n" t t_tests x_tests | cmp app1/test-eunit.log -
$t rm app1/test-eunit.log
@@ -143,7 +143,7 @@ eunit: app1
"succ_test() ->" \
" ?assertEqual(42, t:succ(1))." \
> app1/eunit/t_tests.erl
- $t if make -C app1 eunit EUNIT_DIR=eunit $v ; then false ; fi
+ $t if make -C app1 eunit TEST_DIR=eunit $v ; then false ; fi
$t rm -rf app1/eunit app1/src/t.erl app1/test-eunit.log
$i "Test 'eunit' passed."