diff options
35 files changed, 575 insertions, 76 deletions
@@ -61,3 +61,10 @@ clean: docs: $(MAKE) -f core/core.mk -f core/docs.mk -f plugins/asciidoc.mk asciidoc + +up: + git clone [email protected]:ninenines/erlang.mk.git gh-pages + cd gh-pages && git checkout gh-pages + cd gh-pages && make + cd gh-pages && git push origin gh-pages + rm -rf gh-pages diff --git a/core/compat.mk b/core/compat.mk index 89607ab..eff4915 100644 --- a/core/compat.mk +++ b/core/compat.mk @@ -14,11 +14,18 @@ $(if $(filter-out -Werror,$1),\ $(shell echo $1 | cut -b 2-))) endef +define compat_erlc_opts_to_list +[$(call comma_list,$(foreach o,$(call compat_prepare_erlc_opts,$1),$(call compat_convert_erlc_opts,$o)))] +endef + define compat_rebar_config -{deps, [$(call comma_list,$(foreach d,$(DEPS),\ - {$(call dep_name,$d),".*",{git,"$(call dep_repo,$d)","$(call dep_commit,$d)"}}))]}. -{erl_opts, [$(call comma_list,$(foreach o,$(call compat_prepare_erlc_opts,$(ERLC_OPTS)),\ - $(call compat_convert_erlc_opts,$o)))]}. +{deps, [ +$(call comma_list,$(foreach d,$(DEPS),\ + $(if $(filter hex,$(call dep_fetch,$d)),\ + {$(call dep_name,$d)$(comma)"$(call dep_repo,$d)"},\ + {$(call dep_name,$d)$(comma)".*"$(comma){git,"$(call dep_repo,$d)"$(comma)"$(call dep_commit,$d)"}}))) +]}. +{erl_opts, $(call compat_erlc_opts_to_list,$(ERLC_OPTS))}. endef $(eval _compat_rebar_config = $$(compat_rebar_config)) diff --git a/core/deps.mk b/core/deps.mk index 1be270b..16a2f88 100644 --- a/core/deps.mk +++ b/core/deps.mk @@ -314,9 +314,9 @@ define dep_autopatch_rebar.erl [] -> ok; _ -> Write("\npre-app::\n\t$$\(MAKE) -f c_src/Makefile.erlang.mk\n"), - PortSpecWrite(io_lib:format("ERL_CFLAGS = -finline-functions -Wall -fPIC -I ~s/erts-~s/include -I ~s\n", + PortSpecWrite(io_lib:format("ERL_CFLAGS = -finline-functions -Wall -fPIC -I \\"~s/erts-~s/include\\" -I \\"~s\\"\n", [code:root_dir(), erlang:system_info(version), code:lib_dir(erl_interface, include)])), - PortSpecWrite(io_lib:format("ERL_LDFLAGS = -L ~s -lerl_interface -lei\n", + PortSpecWrite(io_lib:format("ERL_LDFLAGS = -L \\"~s\\" -lerl_interface -lei\n", [code:lib_dir(erl_interface, lib)])), [PortSpecWrite(["\n", E, "\n"]) || E <- OsEnv], FilterEnv = fun(Env) -> diff --git a/core/erlc.mk b/core/erlc.mk index 2297047..dc98bb3 100644 --- a/core/erlc.mk +++ b/core/erlc.mk @@ -244,7 +244,7 @@ ifeq ($(wildcard src/$(PROJECT).app.src),) $(app_verbose) printf "$(subst $(newline),\n,$(subst ",\",$(call app_file,$(GITDESCRIBE),$(MODULES))))" \ > ebin/$(PROJECT).app else - $(verbose) if [ -z "$$(grep -E '^[^%]*{\s*modules\s*,' src/$(PROJECT).app.src)" ]; then \ + $(verbose) if [ -z "$$(grep -e '^[^%]*{\s*modules\s*,' src/$(PROJECT).app.src)" ]; then \ echo "Empty modules entry not found in $(PROJECT).app.src. Please consult the erlang.mk README for instructions." >&2; \ exit 1; \ fi diff --git a/doc/src/guide/asciidoc.asciidoc b/doc/src/guide/asciidoc.asciidoc index 2fca131..cc8336b 100644 --- a/doc/src/guide/asciidoc.asciidoc +++ b/doc/src/guide/asciidoc.asciidoc @@ -1,6 +1,82 @@ [[asciidoc]] -== Asciidoc documentation +== AsciiDoc documentation -// @todo Write it. +Erlang.mk provides rules for generating documentation from +AsciiDoc files. It can automatically build a user guide PDF, +chunked HTML documentation and Unix manual pages. -Placeholder chapter. +=== Requirements + +It is necessary to have http://asciidoc.org/[AsciiDoc], +http://xmlsoft.org/XSLT/xsltproc2.html[xsltproc] and +http://dblatex.sourceforge.net/[dblatex] installed on your +system for Erlang.mk to generate documentation from AsciiDoc sources. + +=== Writing AsciiDoc documentation + +http://asciidoc.org/[AsciiDoc] is a text document format for +writing notes, documentation, articles, books, ebooks, slideshows, +web pages, man pages and blogs. AsciiDoc files can be translated +to many formats including HTML, PDF, EPUB, man page. + +The http://asciidoc.org/userguide.html[AsciiDoc user guide] +describes the AsciiDoc syntax. + +The https://github.com/ninenines/erlang.mk/tree/master/doc/src/guide[Erlang.mk user guide] +is written in AsciiDoc and can be used as an example. The entry +file is https://github.com/ninenines/erlang.mk/blob/master/doc/src/guide/book.asciidoc[book.asciidoc]. + +Erlang.mk expects you to put your documentation in a specific +location. This is 'doc/src/guide/' for the user guide, and +'doc/src/manual/' for the function reference. In the case of +the user guide, the entry point is always 'doc/src/guide/book.asciidoc'. + +For manual pages, it is good practice to use section 3 for +modules, and section 7 for the application itself. + +=== Configuration + +All of the AsciiDoc related configuration can be done directly +inside the files themselves. + +=== Usage + +To build all documentation: + +[source,bash] +$ make docs + +To build only the AsciiDoc documentation: + +[source,bash] +$ make asciidoc + +To build only the user guide: + +[source,bash] +$ make asciidoc-guide + +To build only the manual: + +[source,bash] +$ make asciidoc-manual + +To install man pages on Unix: + +[source,bash] +$ make install-docs + +Erlang.mk allows customizing the installation path and sections +of the man pages to be installed. The `MAN_INSTALL_PATH` variable +defines where man pages will be installed. It defaults to +'/usr/local/share/man'. The `MAN_SECTIONS` variable defines +which manual sections are to be installed. It defaults to `3 7`. + +To install man pages to a custom location: + +[source,bash] +$ make install-docs MAN_INSTALL_PATH=/opt/share/man + +Note that you may need to run the install commands using +`sudo` or equivalent if the location is not writeable by +your user. diff --git a/doc/src/guide/book.asciidoc b/doc/src/guide/book.asciidoc index ebef8b7..a39b907 100644 --- a/doc/src/guide/book.asciidoc +++ b/doc/src/guide/book.asciidoc @@ -46,8 +46,6 @@ include::eunit.asciidoc[EUnit] include::common_test.asciidoc[Common Test] -include::property_based_testing.asciidoc[Property based testing] - include::coverage.asciidoc[Code coverage] include::ci.asciidoc[Continuous integration] diff --git a/doc/src/guide/contributing.asciidoc b/doc/src/guide/contributing.asciidoc index 968ea3e..58e5de6 100644 --- a/doc/src/guide/contributing.asciidoc +++ b/doc/src/guide/contributing.asciidoc @@ -100,7 +100,8 @@ this is a bug. You can either open a ticket or send a pull request. To make sure that the documentation changes work, install -Asciidoc on your system and run `make docs`. +the listed xref:asciidoc[Requirements] on your system and +run `make docs`. === Feature requests diff --git a/doc/src/guide/deps.asciidoc b/doc/src/guide/deps.asciidoc index be7ed52..eb6f2f0 100644 --- a/doc/src/guide/deps.asciidoc +++ b/doc/src/guide/deps.asciidoc @@ -334,7 +334,7 @@ Erlang.mk will also export the `REBAR_DEPS_DIR` variable for compatibility with Rebar build tools, as long as they are recent enough. -=== Dependencies local to the repository +=== Many applications in one repository In addition to the dependencies that are fetched, Erlang.mk also allows you to have dependencies local to your repository. diff --git a/doc/src/guide/edoc.asciidoc b/doc/src/guide/edoc.asciidoc index 7827692..9fc1a74 100644 --- a/doc/src/guide/edoc.asciidoc +++ b/doc/src/guide/edoc.asciidoc @@ -1,6 +1,48 @@ [[edoc]] == EDoc comments -// @todo Write it. +Erlang.mk provides a thin wrapper on top of EDoc, an application +that generates documentation based on comments found in modules. -Placeholder chapter. +=== Writing EDoc comments + +The http://www.erlang.org/doc/apps/edoc/chapter.html[EDoc user guide] +explains everything you need to know about EDoc comments. + +=== Configuration + +The `EDOC_OPTS` variable allows you to specify additional +EDoc options. Options are documented in the +http://www.erlang.org/doc/man/edoc.html#run-2[EDoc manual]. + +A common use for this variable is to enable Markdown in doc +comments, using the `edown` application: + +[source,make] +DOC_DEPS = edown +EDOC_OPTS = {doclet, edown_doclet} + +=== Usage + +To build all documentation, you would typically use: + +[source,bash] +$ make docs + +Do note, however, that EDoc comments will only be generated +automatically if the 'doc/overview.edoc' file exists. If you +do not want that file and still want to generate doc comments, +two solutions are available. + +You can generate EDoc documentation directly: + +[source,bash] +$ make edoc + +You can enable automatic generation on `make docs` by adding +the following to your Makefile: + +[source,make] +---- +docs:: edoc +---- diff --git a/doc/src/guide/external_plugins_list.asciidoc b/doc/src/guide/external_plugins_list.asciidoc index 9d38f8d..f30797f 100644 --- a/doc/src/guide/external_plugins_list.asciidoc +++ b/doc/src/guide/external_plugins_list.asciidoc @@ -4,6 +4,11 @@ This is a non-exhaustive list of Erlang.mk plugins, sorted alphabetically. +=== efene.mk + +An https://github.com/ninenines/efene.mk[Efene plugin] for Erlang.mk. +http://efene.org/[Efene] is an alternative language for the BEAM. + === elixir.mk An https://github.com/botsunit/elixir.mk[Elixir plugin] for @@ -32,6 +37,12 @@ An https://github.com/ninenines/lfe.mk[LFE plugin] for Erlang.mk. LFE, or http://lfe.io/[Lisp Flavoured Erlang], is an alternative language for the BEAM. +=== mix.mk + +A https://github.com/botsunit/mix.mk[Mix plugin] for Erlang.mk, +to generate a compatible configuration file for +http://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html[Mix]. + === reload.mk A https://github.com/bullno1/reload.mk[live reload plugin] for Erlang.mk. diff --git a/doc/src/guide/getting_started.asciidoc b/doc/src/guide/getting_started.asciidoc index 04147b0..ef2f6e8 100644 --- a/doc/src/guide/getting_started.asciidoc +++ b/doc/src/guide/getting_started.asciidoc @@ -237,6 +237,23 @@ $ make All that's left to do is to open it in your favorite editor and make it do something! +=== Hiding Erlang.mk from git + +Erlang.mk is a large text file. It can easily take a large part of +a `git diff` or a `git grep` command. You can avoid this by telling +Git that 'erlang.mk' is a binary file. + +Add this to your '.gitattributes' file. This is a file that you +can create at the root of your repository: + +---- +erlang.mk -diff +---- + +The 'erlang.mk' file will still appear in diffs and greps, but +as a binary file, meaning its contents won't be shown by default +anymore. + === Getting help During development, if you don't remember the name of a target, diff --git a/doc/src/guide/overview.asciidoc b/doc/src/guide/overview.asciidoc index 3e22790..8fa57fe 100644 --- a/doc/src/guide/overview.asciidoc +++ b/doc/src/guide/overview.asciidoc @@ -68,9 +68,7 @@ The xref:shell[make shell] command allows you to test your project manually. You can automate these unit tests with xref:eunit[EUnit] and test your entire system with xref:ct[Common Test]. -xref:property_based_testing[Property based testing] -with Triq is a strong alternative to writing unit tests -manually. xref:coverage[Code coverage] can of course +xref:coverage[Code coverage] can of course be enabled during tests. Erlang.mk comes with features to make your life easier when diff --git a/doc/src/guide/property_based_testing.asciidoc b/doc/src/guide/property_based_testing.asciidoc deleted file mode 100644 index 0adacbd..0000000 --- a/doc/src/guide/property_based_testing.asciidoc +++ /dev/null @@ -1,6 +0,0 @@ -[[property_based_testing]] -== Property based testing - -// @todo Write it. - -Placeholder chapter. diff --git a/index/bitcask.mk b/index/bitcask.mk index 2bc7af8..31930f3 100644 --- a/index/bitcask.mk +++ b/index/bitcask.mk @@ -4,4 +4,4 @@ pkg_bitcask_description = because you need another a key/value storage engine pkg_bitcask_homepage = https://github.com/basho/bitcask pkg_bitcask_fetch = git pkg_bitcask_repo = https://github.com/basho/bitcask -pkg_bitcask_commit = master +pkg_bitcask_commit = develop diff --git a/index/brod.mk b/index/brod.mk new file mode 100644 index 0000000..2650f2c --- /dev/null +++ b/index/brod.mk @@ -0,0 +1,7 @@ +PACKAGES += brod +pkg_brod_name = brod +pkg_brod_description = Kafka client in Erlang +pkg_brod_homepage = https://github.com/klarna/brod +pkg_brod_fetch = git +pkg_brod_repo = https://github.com/klarna/brod.git +pkg_brod_commit = master diff --git a/index/geode.mk b/index/geode.mk new file mode 100644 index 0000000..4eaec34 --- /dev/null +++ b/index/geode.mk @@ -0,0 +1,7 @@ +PACKAGES += geode +pkg_geode_name = geode +pkg_geode_description = geohash/proximity lookup in pure, uncut erlang. +pkg_geode_homepage = https://github.com/bradfordw/geode +pkg_geode_fetch = git +pkg_geode_repo = https://github.com/bradfordw/geode +pkg_geode_commit = master diff --git a/index/jesse.mk b/index/jesse.mk index ae96908..b36b699 100644 --- a/index/jesse.mk +++ b/index/jesse.mk @@ -1,7 +1,7 @@ PACKAGES += jesse pkg_jesse_name = jesse pkg_jesse_description = jesse (JSon Schema Erlang) is an implementation of a json schema validator for Erlang. -pkg_jesse_homepage = https://github.com/klarna/jesse +pkg_jesse_homepage = https://github.com/for-GET/jesse pkg_jesse_fetch = git -pkg_jesse_repo = https://github.com/klarna/jesse +pkg_jesse_repo = https://github.com/for-GET/jesse pkg_jesse_commit = master diff --git a/index/jsone.mk b/index/jsone.mk new file mode 100644 index 0000000..cf7378e --- /dev/null +++ b/index/jsone.mk @@ -0,0 +1,7 @@ +PACKAGES += jsone +pkg_jsone_name = jsone +pkg_jsone_description = An Erlang library for encoding, decoding JSON data. +pkg_jsone_homepage = https://github.com/sile/jsone.git +pkg_jsone_fetch = git +pkg_jsone_repo = https://github.com/sile/jsone.git +pkg_jsone_commit = master diff --git a/index/kafka_protocol.mk b/index/kafka_protocol.mk new file mode 100644 index 0000000..8a9fb2f --- /dev/null +++ b/index/kafka_protocol.mk @@ -0,0 +1,7 @@ +PACKAGES += kafka_protocol +pkg_kafka_protocol_name = kafka_protocol +pkg_kafka_protocol_description = Kafka protocol Erlang library +pkg_kafka_protocol_homepage = https://github.com/klarna/kafka_protocol +pkg_kafka_protocol_fetch = git +pkg_kafka_protocol_repo = https://github.com/klarna/kafka_protocol.git +pkg_kafka_protocol_commit = master diff --git a/index/slack.mk b/index/slack.mk new file mode 100644 index 0000000..f01bd1c --- /dev/null +++ b/index/slack.mk @@ -0,0 +1,7 @@ +PACKAGES += slack +pkg_slack_name = slack +pkg_slack_description = Minimal slack notification OTP library. +pkg_slack_homepage = https://github.com/DonBranson/slack +pkg_slack_fetch = git +pkg_slack_repo = https://github.com/DonBranson/slack.git +pkg_slack_commit = 1.0.0 diff --git a/index/supervisor3.mk b/index/supervisor3.mk new file mode 100644 index 0000000..09356f6 --- /dev/null +++ b/index/supervisor3.mk @@ -0,0 +1,7 @@ +PACKAGES += supervisor3 +pkg_supervisor3_name = supervisor3 +pkg_supervisor3_description = OTP supervisor with additional strategies +pkg_supervisor3_homepage = https://github.com/klarna/supervisor3 +pkg_supervisor3_fetch = git +pkg_supervisor3_repo = https://github.com/klarna/supervisor3.git +pkg_supervisor3_commit = master diff --git a/plugins/asciidoc.mk b/plugins/asciidoc.mk index baf4d3b..ab7fa4b 100644 --- a/plugins/asciidoc.mk +++ b/plugins/asciidoc.mk @@ -8,12 +8,12 @@ MAN_SECTIONS ?= 3 7 docs:: asciidoc -asciidoc: distclean-asciidoc doc-deps asciidoc-guide asciidoc-manual +asciidoc: asciidoc-guide asciidoc-manual ifeq ($(wildcard doc/src/guide/book.asciidoc),) asciidoc-guide: else -asciidoc-guide: +asciidoc-guide: distclean-asciidoc doc-deps a2x -v -f pdf doc/src/guide/book.asciidoc && mv doc/src/guide/book.pdf doc/guide.pdf a2x -v -f chunked doc/src/guide/book.asciidoc && mv doc/src/guide/book.chunked/ doc/html/ endif @@ -21,7 +21,7 @@ endif ifeq ($(wildcard doc/src/manual/*.asciidoc),) asciidoc-manual: else -asciidoc-manual: +asciidoc-manual: distclean-asciidoc doc-deps for f in doc/src/manual/*.asciidoc ; do \ a2x -v -f manpage $$f ; \ done @@ -36,7 +36,7 @@ install-docs:: install-asciidoc install-asciidoc: asciidoc-manual for s in $(MAN_SECTIONS); do \ mkdir -p $(MAN_INSTALL_PATH)/man$$s/ ; \ - install -g 0 -o 0 -m 0644 doc/man$$s/*.gz $(MAN_INSTALL_PATH)/man$$s/ ; \ + install -g `id -u` -o `id -g` -m 0644 doc/man$$s/*.gz $(MAN_INSTALL_PATH)/man$$s/ ; \ done endif diff --git a/plugins/bootstrap.mk b/plugins/bootstrap.mk index 4aa1052..d608d28 100644 --- a/plugins/bootstrap.mk +++ b/plugins/bootstrap.mk @@ -11,8 +11,8 @@ help:: " bootstrap Generate a skeleton of an OTP application" \ " bootstrap-lib Generate a skeleton of an OTP library" \ " bootstrap-rel Generate the files needed to build a release" \ - " new-app n=NAME Create a new local OTP application NAME" \ - " new-lib n=NAME Create a new local OTP library NAME" \ + " new-app in=NAME Create a new local OTP application NAME" \ + " new-lib in=NAME Create a new local OTP library NAME" \ " new t=TPL n=NAME Generate a module NAME based on the template TPL" \ " new t=T n=N in=APP Generate a module NAME based on the template TPL in APP" \ " list-templates List available templates" @@ -172,6 +172,11 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. endef +define tpl_module +-module($(n)). +-export([]). +endef + define tpl_cowboy_http -module($(n)). -behaviour(cowboy_http_handler). diff --git a/plugins/c_src.mk b/plugins/c_src.mk index 87fd32f..518ba9e 100644 --- a/plugins/c_src.mk +++ b/plugins/c_src.mk @@ -30,6 +30,7 @@ ifeq ($(PLATFORM),msys2) # We hardcode the compiler used on MSYS2. The default CC=cc does # not produce working code. The "gcc" MSYS2 package also doesn't. CC = /mingw64/bin/gcc + export CC CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes CXXFLAGS ?= -O3 -finline-functions -Wall else ifeq ($(PLATFORM),darwin) diff --git a/plugins/ct.mk b/plugins/ct.mk index 2d45032..4d0c020 100644 --- a/plugins/ct.mk +++ b/plugins/ct.mk @@ -31,7 +31,7 @@ help:: CT_RUN = ct_run \ -no_auto_compile \ -noinput \ - -pa $(CURDIR)/ebin $(DEPS_DIR)/*/ebin $(TEST_DIR) \ + -pa $(CURDIR)/ebin $(DEPS_DIR)/*/ebin $(APPS_DIR)/*/ebin $(TEST_DIR) \ -dir $(TEST_DIR) \ -logdir $(CURDIR)/logs @@ -40,12 +40,18 @@ ct: $(if $(IS_APP),,apps-ct) else ct: test-build $(if $(IS_APP),,apps-ct) $(verbose) mkdir -p $(CURDIR)/logs/ - $(gen_verbose) $(CT_RUN) -suite $(addsuffix _SUITE,$(CT_SUITES)) $(CT_OPTS) + $(gen_verbose) $(CT_RUN) -sname ct_$(PROJECT) -suite $(addsuffix _SUITE,$(CT_SUITES)) $(CT_OPTS) endif ifneq ($(ALL_APPS_DIRS),) -apps-ct: - $(verbose) for app in $(ALL_APPS_DIRS); do $(MAKE) -C $$app ct IS_APP=1; done +define ct_app_target +apps-ct-$1: + $(MAKE) -C $1 ct IS_APP=1 +endef + +$(foreach app,$(ALL_APPS_DIRS),$(eval $(call ct_app_target,$(app)))) + +apps-ct: test-build $(addprefix apps-ct-,$(ALL_APPS_DIRS)) endif ifndef t @@ -62,7 +68,7 @@ endif define ct_suite_target ct-$(1): test-build $(verbose) mkdir -p $(CURDIR)/logs/ - $(gen_verbose) $(CT_RUN) -suite $(addsuffix _SUITE,$(1)) $(CT_EXTRA) $(CT_OPTS) + $(gen_verbose) $(CT_RUN) -sname ct_$(PROJECT) -suite $(addsuffix _SUITE,$(1)) $(CT_EXTRA) $(CT_OPTS) endef $(foreach test,$(CT_SUITES),$(eval $(call ct_suite_target,$(test)))) diff --git a/plugins/edoc.mk b/plugins/edoc.mk index 6f0a82d..7b4331b 100644 --- a/plugins/edoc.mk +++ b/plugins/edoc.mk @@ -9,13 +9,15 @@ EDOC_OPTS ?= # Core targets. -docs:: distclean-edoc edoc +ifneq ($(wildcard doc/overview.edoc),) +docs:: edoc +endif distclean:: distclean-edoc # Plugin-specific targets. -edoc: doc-deps +edoc: distclean-edoc doc-deps $(gen_verbose) $(ERL) -eval 'edoc:application($(PROJECT), ".", [$(EDOC_OPTS)]), halt().' distclean-edoc: diff --git a/plugins/escript.mk b/plugins/escript.mk index 42133eb..16f8ba6 100644 --- a/plugins/escript.mk +++ b/plugins/escript.mk @@ -6,6 +6,8 @@ # Configuration. ESCRIPT_NAME ?= $(PROJECT) +ESCRIPT_FILE ?= $(ESCRIPT_NAME) + ESCRIPT_COMMENT ?= This is an -*- erlang -*- file ESCRIPT_BEAMS ?= "ebin/*", "deps/*/ebin/*" @@ -51,7 +53,7 @@ define ESCRIPT_RAW ' ]),'\ ' file:change_mode(Escript, 8#755)'\ 'end,'\ -'Ez("$(ESCRIPT_NAME)"),'\ +'Ez("$(ESCRIPT_FILE)"),'\ 'halt().' endef diff --git a/plugins/eunit.mk b/plugins/eunit.mk index f6afa34..a2e22ff 100644 --- a/plugins/eunit.mk +++ b/plugins/eunit.mk @@ -52,8 +52,9 @@ eunit: test-build $(gen_verbose) $(call erlang,$(call eunit.erl,fun $(t)/0),$(EUNIT_ERL_OPTS)) endif else -EUNIT_EBIN_MODS = $(notdir $(basename $(call core_find,ebin/,*.beam))) -EUNIT_TEST_MODS = $(notdir $(basename $(call core_find,$(TEST_DIR)/,*.beam))) +EUNIT_EBIN_MODS = $(notdir $(basename $(ERL_FILES) $(BEAM_FILES))) +EUNIT_TEST_MODS = $(notdir $(basename $(call core_find,$(TEST_DIR)/,*.erl))) + EUNIT_MODS = $(foreach mod,$(EUNIT_EBIN_MODS) $(filter-out \ $(patsubst %,%_tests,$(EUNIT_EBIN_MODS)),$(EUNIT_TEST_MODS)),'$(mod)') diff --git a/test/Makefile b/test/Makefile index 728d751..f01e3ab 100644 --- a/test/Makefile +++ b/test/Makefile @@ -303,9 +303,9 @@ endef # The following tests are slowly being converted. # Do NOT use -j with legacy tests. -.PHONY: legacy clean-legacy tests-cover docs +.PHONY: legacy clean-legacy tests-cover -legacy: clean-legacy tests-cover docs pkgs +legacy: clean-legacy tests-cover clean-legacy: $t rm -rf app1 @@ -345,29 +345,6 @@ tests-cover: app1 $t $(MAKE) -C app1 clean $v $i "Test 'tests-cover' passed." -docs: app1 - $i "docs: Testing EDoc including DOC_DEPS." - $t printf "%s\n" \ - "PROJECT = app1" \ - "DOC_DEPS = edown" \ - "dep_edown = git https://github.com/uwiger/edown.git 0.7" \ - "EDOC_OPTS = {doclet, edown_doclet}" \ - "include erlang.mk" \ - "distclean:: distclean-doc-md" \ - "distclean-doc-md:" \ - " rm -rf doc/*.md" \ - > app1/Makefile-doc - $i "Downloading doc deps (edown) and building docs." - $t $(MAKE) -C app1 -f Makefile-doc docs $v - $i "Checking that '$(MAKE) docs' using edown generated a markdown file." - $t [ -e app1/doc/m.md ] - $i "Checking that '$(MAKE) distclean' deletes all generated doc files." - $t $(MAKE) -C app1 -f Makefile-doc distclean $v - $t [ "`ls app1/doc/`" = "" ] - $i "Cleaning up test data." - $t rm app1/Makefile-doc - $i "Test 'docs' passed." - define app1_setup $i "Setting up app." $t mkdir -p app1 diff --git a/test/core_compat.mk b/test/core_compat.mk index 73a9da1..8d6cabc 100644 --- a/test/core_compat.mk +++ b/test/core_compat.mk @@ -2,10 +2,11 @@ # # Note: autopatch functionality is covered separately. -CORE_COMPAT_CASES = auto-rebar rebar rebar-deps rebar-deps-pkg rebar-erlc-opts rebar-pt +CORE_COMPAT_CASES = auto-rebar rebar rebar-deps-git rebar-deps-hex rebar-deps-pkg rebar-erlc-opts rebar-pt CORE_COMPAT_TARGETS = $(addprefix core-compat-,$(CORE_COMPAT_CASES)) 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) @@ -92,7 +93,7 @@ core-compat-rebar: build clean $i "Use rebar to build the application" $t cd $(APP) && ./rebar compile $v -core-compat-rebar-deps: build clean +core-compat-rebar-deps-git: build clean $i "Bootstrap a new OTP library named $(APP)" $t mkdir $(APP)/ @@ -124,6 +125,38 @@ core-compat-rebar-deps: build clean $i "Use rebar to build the application" $t cd $(APP) && ./rebar get-deps compile $v +core-compat-rebar-deps-hex: build clean + + $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 = hex 1.0.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" + $t $(ERL) -eval " \ + {ok, C} = file:consult(\"$(APP)/rebar.config\"), \ + {_, [{cowboy, \"1.0.0\"}]} = lists:keyfind(deps, 1, C), \ + halt()" + + $i "Distclean the application" + $t $(MAKE) -C $(APP) distclean $v + + $i "Download rebar3" + $t curl -s -L -o $(APP)/rebar3 $(REBAR3_BINARY) + $t chmod +x $(APP)/rebar3 + + $i "Use rebar to build the application" + $t cd $(APP) && ./rebar3 compile $v + core-compat-rebar-deps-pkg: build clean $i "Bootstrap a new OTP library named $(APP)" diff --git a/test/core_deps.mk b/test/core_deps.mk index c383d94..f145754 100644 --- a/test/core_deps.mk +++ b/test/core_deps.mk @@ -591,7 +591,7 @@ core-deps-doc: build clean halt()" $i "Build the application documentation" - $t $(MAKE) -C $(APP) docs $v + $t $(MAKE) -C $(APP) edoc $v $i "Check that documentation dependencies were fetched" $t test -d $(APP)/deps/edown diff --git a/test/plugin_asciidoc.mk b/test/plugin_asciidoc.mk new file mode 100644 index 0000000..a583585 --- /dev/null +++ b/test/plugin_asciidoc.mk @@ -0,0 +1,158 @@ +# AsciiDoc plugin. + +ASCIIDOC_CASES = build docs guide install manual +ASCIIDOC_TARGETS = $(addprefix asciidoc-,$(ASCIIDOC_CASES)) + +.PHONY: asciidoc $(ASCIIDOC_TARGETS) + +asciidoc: $(ASCIIDOC_TARGETS) + +asciidoc-build: build clean + + $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 "Only enable man pages section 3" + $t perl -ni.bak -e 'print;if ($$.==1) {print "MAN_SECTIONS = 3\n"}' $(APP)/Makefile + + $i "Run AsciiDoc" + $t $(MAKE) -C $(APP) asciidoc $v + + $i "Check that no documentation was generated" + $t test ! -e $(APP)/doc/guide.pdf + $t test ! -e $(APP)/doc/html/ + $t test ! -e $(APP)/doc/man3/ + + $i "Generate AsciiDoc documentation" + $t mkdir -p $(APP)/doc/src/guide/ $(APP)/doc/src/manual/ + $t printf "%s\n" \ + "= Erlang.mk tests" "" \ + "Hello world!" > $(APP)/doc/src/guide/book.asciidoc + $t printf "%s\n" \ + "= erlang_mk(3)" "" \ + "== Name" "" \ + "erlang_mk - Erlang.mk test" "" \ + "== Description" "" \ + "Hello world!" > $(APP)/doc/src/manual/erlang_mk.asciidoc + + $i "Run AsciiDoc" + $t $(MAKE) -C $(APP) asciidoc $v + + $i "Check that the documentation was generated" + $t test -f $(APP)/doc/guide.pdf + $t test -d $(APP)/doc/html/ + $t test -f $(APP)/doc/man3/erlang_mk.3.gz + + $i "Distclean the application" + $t $(MAKE) -C $(APP) distclean $v + + $i "Check that the generated documentation was removed" + $t test ! -e $(APP)/doc/guide.pdf + $t test ! -e $(APP)/doc/html/ + $t test ! -e $(APP)/doc/man3/ + + $i "Generate an invalid AsciiDoc file" + $t printf "%s\n" \ + "= fail(3)" "" \ + "This will fail because the Name section is missing." > $(APP)/doc/src/manual/fail.asciidoc + + $i "Check that AsciiDoc errors out" + $t ! $(MAKE) -C $(APP) asciidoc $v + +asciidoc-docs: build clean + + $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 AsciiDoc documentation" + $t mkdir -p $(APP)/doc/src/guide/ + $t printf "%s\n" \ + "= Erlang.mk tests" "" \ + "Hello world!" > $(APP)/doc/src/guide/book.asciidoc + + $i "Check that AsciiDoc runs on 'make docs'" + $t $(MAKE) -C $(APP) docs $v + $t test -f $(APP)/doc/guide.pdf + $t test -d $(APP)/doc/html/ + +asciidoc-guide: build clean + + $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 AsciiDoc documentation" + $t mkdir -p $(APP)/doc/src/guide/ $(APP)/doc/src/manual/ + $t printf "%s\n" \ + "= Erlang.mk tests" "" \ + "Hello world!" > $(APP)/doc/src/guide/book.asciidoc + $t printf "%s\n" \ + "= erlang_mk(3)" "" \ + "== Name" "" \ + "erlang_mk - Erlang.mk test" "" \ + "== Description" "" \ + "Hello world!" > $(APP)/doc/src/manual/erlang_mk.asciidoc + + $i "Check that only the guide is generated on 'make asciidoc-guide'" + $t $(MAKE) -C $(APP) asciidoc-guide $v + $t test -f $(APP)/doc/guide.pdf + $t test -d $(APP)/doc/html/ + $t test ! -e $(APP)/doc/man3/ + +asciidoc-install: build clean + + $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 "Only enable man pages section 3" + $t perl -ni.bak -e 'print;if ($$.==1) {print "MAN_SECTIONS = 3\n"}' $(APP)/Makefile + + $i "Generate AsciiDoc documentation" + $t mkdir -p $(APP)/doc/src/manual/ + $t printf "%s\n" \ + "= erlang_mk(3)" "" \ + "== Name" "" \ + "erlang_mk - Erlang.mk test" "" \ + "== Description" "" \ + "Hello world!" > $(APP)/doc/src/manual/erlang_mk.asciidoc + + $i "Build and install the man pages to $(APP)/installed/" + $t $(MAKE) -C $(APP) install-docs MAN_INSTALL_PATH=installed/share $v + + $i "Check that the documentation was installed properly" + $t test -f $(APP)/installed/share/man3/erlang_mk.3.gz + +asciidoc-manual: build clean + + $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 "Only enable man pages section 3" + $t perl -ni.bak -e 'print;if ($$.==1) {print "MAN_SECTIONS = 3\n"}' $(APP)/Makefile + + $i "Generate AsciiDoc documentation" + $t mkdir -p $(APP)/doc/src/guide/ $(APP)/doc/src/manual/ + $t printf "%s\n" \ + "= Erlang.mk tests" "" \ + "Hello world!" > $(APP)/doc/src/guide/book.asciidoc + $t printf "%s\n" \ + "= erlang_mk(3)" "" \ + "== Name" "" \ + "erlang_mk - Erlang.mk test" "" \ + "== Description" "" \ + "Hello world!" > $(APP)/doc/src/manual/erlang_mk.asciidoc + + $i "Check that only the manual is generated on 'make asciidoc-manual'" + $t $(MAKE) -C $(APP) asciidoc-manual $v + $t test ! -e $(APP)/doc/guide.pdf + $t test ! -e $(APP)/doc/html/ + $t test -f $(APP)/doc/man3/erlang_mk.3.gz diff --git a/test/plugin_bootstrap.mk b/test/plugin_bootstrap.mk index ebfa6e7..2b62b6f 100644 --- a/test/plugin_bootstrap.mk +++ b/test/plugin_bootstrap.mk @@ -190,6 +190,7 @@ bootstrap-templates: build clean $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=ranch_protocol n=my_protocol + $t $(MAKE) -C $(APP) --no-print-directory new t=module n=my_module # Here we disable warnings because templates contain missing behaviors. $i "Build the application" @@ -200,11 +201,12 @@ bootstrap-templates: build clean $t test -f $(APP)/ebin/my_fsm.beam $t test -f $(APP)/ebin/my_server.beam $t test -f $(APP)/ebin/my_sup.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_protocol, my_rest, my_server, my_sup, my_ws]} \ + {ok, Mods = [my_fsm, my_http, my_loop, my_module, my_protocol, my_rest, my_server, my_sup, my_ws]} \ = application:get_key($(APP), modules), \ [{module, M} = code:load_file(M) || M <- Mods], \ halt()" diff --git a/test/plugin_ct.mk b/test/plugin_ct.mk index dd36801..c32fa36 100644 --- a/test/plugin_ct.mk +++ b/test/plugin_ct.mk @@ -63,6 +63,12 @@ ct-apps-only: build clean $i "Create a new library named my_lib" $t $(MAKE) -C $(APP) new-lib in=my_lib $v + $i "Populate my_lib" + $t printf "%s\n" \ + "-module(my_lib)." \ + "-export([random_int/0])." \ + "random_int() -> 4." > $(APP)/apps/my_lib/src/my_lib.erl + $i "Check that Common Test detects no tests" $t $(MAKE) -C $(APP) ct | grep -q "Nothing to be done for 'ct'." @@ -70,9 +76,10 @@ ct-apps-only: build clean $t mkdir $(APP)/apps/my_app/test $t printf "%s\n" \ "-module(my_app_SUITE)." \ - "-export([all/0, ok/1])." \ - "all() -> [ok]." \ - "ok(_) -> ok." > $(APP)/apps/my_app/test/my_app_SUITE.erl + "-export([all/0, ok/1, call_my_lib/1])." \ + "all() -> [ok, call_my_lib]." \ + "ok(_) -> ok." \ + "call_my_lib(_) -> 4 = my_lib:random_int()." > $(APP)/apps/my_app/test/my_app_SUITE.erl $i "Generate a Common Test suite in my_lib" $t mkdir $(APP)/apps/my_lib/test diff --git a/test/plugin_edoc.mk b/test/plugin_edoc.mk new file mode 100644 index 0000000..33f3d0f --- /dev/null +++ b/test/plugin_edoc.mk @@ -0,0 +1,112 @@ +# EDoc plugin. + +EDOC_CASES = build docs no-overview opts +EDOC_TARGETS = $(addprefix edoc-,$(EDOC_CASES)) + +.PHONY: edoc $(EDOC_TARGETS) + +edoc: $(EDOC_TARGETS) + +edoc-build: build clean + + $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 EDoc" + $t $(MAKE) -C $(APP) edoc $v + + $i "Check that documentation was generated" + $t test -f $(APP)/doc/index.html + $t test -f $(APP)/doc/$(APP)_app.html + $t test -f $(APP)/doc/$(APP)_sup.html + + $i "Distclean the application" + $t $(MAKE) -C $(APP) distclean $v + + $i "Check that the generated documentation was removed" + $t test ! -e $(APP)/doc/index.html + $t test ! -e $(APP)/doc/$(APP)_app.html + $t test ! -e $(APP)/doc/$(APP)_sup.html + + $i "Generate a module with EDoc comments" + $t printf "%s\n" \ + "%% @doc erlang-mk-edoc-module" \ + "-module($(APP))." \ + "-export([ok/0])." \ + "" \ + "%% @doc erlang-mk-edoc-function" \ + "ok() -> ok." > $(APP)/src/$(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-module $(APP)/doc/$(APP).html + $t grep -q erlang-mk-edoc-function $(APP)/doc/$(APP).html + + $i "Generate a module with an invalid EDoc comment" + $t printf "%s\n" \ + "-module($(APP)_fail)." \ + "-export([fail/0])." \ + "%% @spec lol" \ + "fail() -> fail." > $(APP)/src/$(APP)_fail.erl + + $i "Check that EDoc errors out" + $t ! $(MAKE) -C $(APP) edoc $v + +edoc-docs: build clean + + $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 doc/overview.edoc file" + $t mkdir $(APP)/doc + $t printf "%s\n" \ + "@author R. J. Hacker <[email protected]>" \ + "@copyright 2007 R. J. Hacker" \ + "@version 1.0.0" \ + "@title Welcome to the 'frob' application!" \ + "@doc 'frob' is a highly advanced frobnicator with low latency," > $(APP)/doc/overview.edoc + + $i "Check that EDoc runs on 'make docs'" + $t $(MAKE) -C $(APP) docs $v + $t test -f $(APP)/doc/index.html + + $i "Check that the overview.edoc file was used" + $t grep -q frobnicator $(APP)/doc/overview-summary.html + +edoc-no-overview: build clean + + $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 "Check that EDoc doesn't run on 'make docs'" + $t $(MAKE) -C $(APP) docs $v + $t test ! -e $(APP)/doc/index.html + +edoc-opts: build clean + + $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 edown doclet for EDoc" + $t perl -ni.bak -e 'print;if ($$.==1) {print "DOC_DEPS = edown\nEDOC_OPTS = {doclet, edown_doclet}\n"}' $(APP)/Makefile + + $i "Run EDoc" + $t $(MAKE) -C $(APP) edoc $v + + $i "Check that the Markdown documentation was generated" + $t test -f $(APP)/doc/README.md + $t test -f $(APP)/doc/$(APP)_app.md + $t test -f $(APP)/doc/$(APP)_sup.md |