Skip to content

Commit

Permalink
Move templates outside the source .mk files
Browse files Browse the repository at this point in the history
Templates now no longer use Make variables for substitution
but instead replace strings with their equivalent:

  template_name: Corresponds to n=template_name
  project_name:  Corresponds to $(PROJECT) or in=project_name

This allows defining templates outside of Makefiles. For
example an external plugin could define their templates
in templates/my_template.erl and then have the following
in the included Makefile:

  tpl_my_template = $(file < $(THIS)/templates/my_template.erl)

By default the created file will be in src/template_name.erl.
This can be overriden with the tplp_* variable:

  tplp_my_template = src/model/my_template.erl

Substitution is applied both to the template contents and
to its path.

In addition, attempting to overwrite an existing file when
creating a template will result in failure.
  • Loading branch information
essen committed Nov 22, 2024
1 parent ebe31ee commit a6f9a45
Show file tree
Hide file tree
Showing 28 changed files with 488 additions and 425 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
doc/guide.pdf
doc/html
templates.mk
test/logs/
test/packages/
test/test_hex_core_git/
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,11 @@
without an explicit fetch method). Adding "git"
at the beginning of the dep line is the modern
equivalent.

2024/11/22: Templates no longer use Make variables for
substitution. Instead the strings template_name
and project_name get replaced by their equivalent.
Note that using variables in your own templates
should still work, but that this way of doing
things is deprecated. This change makes it
possible to have templates outside of Makefiles.
11 changes: 10 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ ERLANG_MK_VERSION = $(shell git describe --dirty --tags --always)

.PHONY: all check

all:
all: templates.mk
# Temporarily force the printing of the CHANGELOG.
# The required variable hadn't been introduced yet.
#ifdef UPGRADE
Expand All @@ -40,6 +40,15 @@ all:
| sed 's/^ERLANG_MK_VERSION =.*/ERLANG_MK_VERSION = $(ERLANG_MK_VERSION)/' \
| sed 's:^ERLANG_MK_WITHOUT =.*:ERLANG_MK_WITHOUT = $(WITHOUT):' > $(ERLANG_MK)

# Templates that end with .erl have the suffix removed. It is implied.
templates.mk: Makefile templates/*
for f in templates/*; do \
echo define tpl_`basename $$f .erl`; \
cat $$f; \
echo endef; \
echo; \
done > $@

lint: all
$(MAKE) -f erlang.mk --warn-undefined-variables

Expand Down
3 changes: 3 additions & 0 deletions build.config
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ core/rel
core/test
core/compat

# Built-in templates.
templates

# Plugins.
plugins/asciidoc
plugins/bootstrap
Expand Down
28 changes: 26 additions & 2 deletions doc/src/guide/external_plugins.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ help-plugins::
Plugins declared in `DEP_PLUGINS` are loaded near the end of Erlang.mk.
That's why you have access to all previously initialized variables.
However, if you want your plugin to add common dependencies to
your applications, a regular is loaded too late in the process.
your applications, a regular plugin is loaded too late in the process.
You need to use "Early-stage plugins". They are declared using the
`DEP_EARLY_PLUGINS` variable instead. Plugins listed in this variable
are loaded near the beginning of Erlang.mk Otherwise, they work exactly
Expand All @@ -111,7 +111,7 @@ DEPS += cowboy
TEST_DEPS = ct_helper
dep_ct_helper = git https://github.com/ninenines/ct_helper master

=== Loading plugins local to the application
=== Loading plugins local to the application

If the Erlang.mk plugin lives in the same directory or repository as your
application or library, then you can load it exactly like an external
Expand All @@ -138,3 +138,27 @@ your application:
DEP_EARLY_PLUGINS = $(PROJECT)
# Loads ./plugins.mk
DEP_PLUGINS = $(PROJECT)

=== Adding templates via plugins

Plugins may add templates either from within their Makefile or from
an external file. The recommended method is to use an external file;
however do note it only works for Make 4 and above:

[source,make]
THIS := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
tpl_test_mk = $(file < $(THIS)/templates/my_template.erl)

With 'templates/my_template.erl' containing:

[source,erlang]
-module(template_name).

Erlang.mk will do string substitution replacing the following
strings with their equivalent:

* `template_name`: the name provided by the user
* `project_name`: either `$(PROJECT)` or the target application's name
* `template_sp`: internal; propagates whitespace settings to Makefiles
* `rel_deps_dir`: internal; path to deps/* from within an apps/* Makefile
* `rel_root_dir`: internal; path to top-level directory from within an apps/* Makefile
14 changes: 13 additions & 1 deletion doc/src/guide/getting_started.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,20 @@ You can list all available templates with the `list-templates`
target:

[source,bash]
----
$ make list-templates
Available templates: cowboy_http cowboy_loop cowboy_rest cowboy_ws gen_fsm gen_server gen_statem ranch_protocol supervisor
Available templates:
cowboy_http_h
cowboy_loop_h
cowboy_rest_h
cowboy_websocket_h
gen_fsm
gen_server
gen_statem
module
ranch_protocol
supervisor
----

To generate a module, let's say a `gen_server`, all you need to
do is to call `make new` with the appropriate arguments:
Expand Down
Loading

0 comments on commit a6f9a45

Please sign in to comment.