|
@@ -256,233 +256,283 @@ help::
|
|
|
|
|
|
# Bootstrap templates.
|
|
|
|
|
|
-bs_appsrc = "{application, $(PROJECT), [" \
|
|
|
- " {description, \"\"}," \
|
|
|
- " {vsn, \"0.1.0\"}," \
|
|
|
- " {modules, []}," \
|
|
|
- " {registered, []}," \
|
|
|
- " {applications, [" \
|
|
|
- " kernel," \
|
|
|
- " stdlib" \
|
|
|
- " ]}," \
|
|
|
- " {mod, {$(PROJECT)_app, []}}," \
|
|
|
- " {env, []}" \
|
|
|
- "]}."
|
|
|
-bs_appsrc_lib = "{application, $(PROJECT), [" \
|
|
|
- " {description, \"\"}," \
|
|
|
- " {vsn, \"0.1.0\"}," \
|
|
|
- " {modules, []}," \
|
|
|
- " {registered, []}," \
|
|
|
- " {applications, [" \
|
|
|
- " kernel," \
|
|
|
- " stdlib" \
|
|
|
- " ]}" \
|
|
|
- "]}."
|
|
|
-bs_Makefile = "PROJECT = $(PROJECT)" \
|
|
|
- "include erlang.mk"
|
|
|
-bs_app = "-module($(PROJECT)_app)." \
|
|
|
- "-behaviour(application)." \
|
|
|
- "" \
|
|
|
- "-export([start/2])." \
|
|
|
- "-export([stop/1])." \
|
|
|
- "" \
|
|
|
- "start(_Type, _Args) ->" \
|
|
|
- " $(PROJECT)_sup:start_link()." \
|
|
|
- "" \
|
|
|
- "stop(_State) ->" \
|
|
|
- " ok."
|
|
|
-bs_relx_config = "{release, {$(PROJECT)_release, \"1\"}, [$(PROJECT)]}." \
|
|
|
- "{extended_start_script, true}." \
|
|
|
- "{sys_config, \"rel/sys.config\"}." \
|
|
|
- "{vm_args, \"rel/vm.args\"}."
|
|
|
-bs_sys_config = "[" \
|
|
|
- "]."
|
|
|
-bs_vm_args = "-name $(PROJECT)@127.0.0.1" \
|
|
|
- "-setcookie $(PROJECT)" \
|
|
|
- "-heart"
|
|
|
+define bs_appsrc
|
|
|
+{application, $(PROJECT), [
|
|
|
+ {description, ""},
|
|
|
+ {vsn, "0.1.0"},
|
|
|
+ {modules, []},
|
|
|
+ {registered, []},
|
|
|
+ {applications, [
|
|
|
+ kernel,
|
|
|
+ stdlib
|
|
|
+ ]},
|
|
|
+ {mod, {$(PROJECT)_app, []}},
|
|
|
+ {env, []}
|
|
|
+]}.
|
|
|
+endef
|
|
|
+
|
|
|
+define bs_appsrc_lib
|
|
|
+{application, $(PROJECT), [
|
|
|
+ {description, ""},
|
|
|
+ {vsn, "0.1.0"},
|
|
|
+ {modules, []},
|
|
|
+ {registered, []},
|
|
|
+ {applications, [
|
|
|
+ kernel,
|
|
|
+ stdlib
|
|
|
+ ]}
|
|
|
+]}.
|
|
|
+endef
|
|
|
+
|
|
|
+define bs_Makefile
|
|
|
+PROJECT = $(PROJECT)
|
|
|
+include erlang.mk
|
|
|
+endef
|
|
|
+
|
|
|
+define bs_app
|
|
|
+-module($(PROJECT)_app).
|
|
|
+-behaviour(application).
|
|
|
+
|
|
|
+-export([start/2]).
|
|
|
+-export([stop/1]).
|
|
|
+
|
|
|
+start(_Type, _Args) ->
|
|
|
+ $(PROJECT)_sup:start_link().
|
|
|
+
|
|
|
+stop(_State) ->
|
|
|
+ ok.
|
|
|
+endef
|
|
|
+
|
|
|
+define bs_relx_config
|
|
|
+{release, {$(PROJECT)_release, "1"}, [$(PROJECT)]}.
|
|
|
+{extended_start_script, true}.
|
|
|
+{sys_config, "rel/sys.config"}.
|
|
|
+{vm_args, "rel/vm.args"}.
|
|
|
+endef
|
|
|
+
|
|
|
+define bs_sys_config
|
|
|
+[
|
|
|
+].
|
|
|
+endef
|
|
|
+
|
|
|
+define bs_vm_args
|
|
|
+-name $(PROJECT)@127.0.0.1
|
|
|
+-setcookie $(PROJECT)
|
|
|
+-heart
|
|
|
+endef
|
|
|
+
|
|
|
# Normal templates.
|
|
|
-tpl_supervisor = "-module($(n))." \
|
|
|
- "-behaviour(supervisor)." \
|
|
|
- "" \
|
|
|
- "-export([start_link/0])." \
|
|
|
- "-export([init/1])." \
|
|
|
- "" \
|
|
|
- "start_link() ->" \
|
|
|
- " supervisor:start_link({local, ?MODULE}, ?MODULE, [])." \
|
|
|
- "" \
|
|
|
- "init([]) ->" \
|
|
|
- " Procs = []," \
|
|
|
- " {ok, {{one_for_one, 1, 5}, Procs}}."
|
|
|
-tpl_gen_server = "-module($(n))." \
|
|
|
- "-behaviour(gen_server)." \
|
|
|
- "" \
|
|
|
- "%% API." \
|
|
|
- "-export([start_link/0])." \
|
|
|
- "" \
|
|
|
- "%% gen_server." \
|
|
|
- "-export([init/1])." \
|
|
|
- "-export([handle_call/3])." \
|
|
|
- "-export([handle_cast/2])." \
|
|
|
- "-export([handle_info/2])." \
|
|
|
- "-export([terminate/2])." \
|
|
|
- "-export([code_change/3])." \
|
|
|
- "" \
|
|
|
- "-record(state, {" \
|
|
|
- "})." \
|
|
|
- "" \
|
|
|
- "%% API." \
|
|
|
- "" \
|
|
|
- "-spec start_link() -> {ok, pid()}." \
|
|
|
- "start_link() ->" \
|
|
|
- " gen_server:start_link(?MODULE, [], [])." \
|
|
|
- "" \
|
|
|
- "%% gen_server." \
|
|
|
- "" \
|
|
|
- "init([]) ->" \
|
|
|
- " {ok, \#state{}}." \
|
|
|
- "" \
|
|
|
- "handle_call(_Request, _From, State) ->" \
|
|
|
- " {reply, ignored, State}." \
|
|
|
- "" \
|
|
|
- "handle_cast(_Msg, State) ->" \
|
|
|
- " {noreply, State}." \
|
|
|
- "" \
|
|
|
- "handle_info(_Info, State) ->" \
|
|
|
- " {noreply, State}." \
|
|
|
- "" \
|
|
|
- "terminate(_Reason, _State) ->" \
|
|
|
- " ok." \
|
|
|
- "" \
|
|
|
- "code_change(_OldVsn, State, _Extra) ->" \
|
|
|
- " {ok, State}."
|
|
|
-tpl_cowboy_http = "-module($(n))." \
|
|
|
- "-behaviour(cowboy_http_handler)." \
|
|
|
- "" \
|
|
|
- "-export([init/3])." \
|
|
|
- "-export([handle/2])." \
|
|
|
- "-export([terminate/3])." \
|
|
|
- "" \
|
|
|
- "-record(state, {" \
|
|
|
- "})." \
|
|
|
- "" \
|
|
|
- "init(_, Req, _Opts) ->" \
|
|
|
- " {ok, Req, \#state{}}." \
|
|
|
- "" \
|
|
|
- "handle(Req, State=\#state{}) ->" \
|
|
|
- " {ok, Req2} = cowboy_req:reply(200, Req)," \
|
|
|
- " {ok, Req2, State}." \
|
|
|
- "" \
|
|
|
- "terminate(_Reason, _Req, _State) ->" \
|
|
|
- " ok."
|
|
|
-tpl_cowboy_loop = "-module($(n))." \
|
|
|
- "-behaviour(cowboy_loop_handler)." \
|
|
|
- "" \
|
|
|
- "-export([init/3])." \
|
|
|
- "-export([info/3])." \
|
|
|
- "-export([terminate/3])." \
|
|
|
- "" \
|
|
|
- "-record(state, {" \
|
|
|
- "})." \
|
|
|
- "" \
|
|
|
- "init(_, Req, _Opts) ->" \
|
|
|
- " {loop, Req, \#state{}, 5000, hibernate}." \
|
|
|
- "" \
|
|
|
- "info(_Info, Req, State) ->" \
|
|
|
- " {loop, Req, State, hibernate}." \
|
|
|
- "" \
|
|
|
- "terminate(_Reason, _Req, _State) ->" \
|
|
|
- " ok."
|
|
|
-tpl_cowboy_rest = "-module($(n))." \
|
|
|
- "" \
|
|
|
- "-export([init/3])." \
|
|
|
- "-export([content_types_provided/2])." \
|
|
|
- "-export([get_html/2])." \
|
|
|
- "" \
|
|
|
- "init(_, _Req, _Opts) ->" \
|
|
|
- " {upgrade, protocol, cowboy_rest}." \
|
|
|
- "" \
|
|
|
- "content_types_provided(Req, State) ->" \
|
|
|
- " {[{{<<\"text\">>, <<\"html\">>, '_'}, get_html}], Req, State}." \
|
|
|
- "" \
|
|
|
- "get_html(Req, State) ->" \
|
|
|
- " {<<\"<html><body>This is REST!</body></html>\">>, Req, State}."
|
|
|
-tpl_cowboy_ws = "-module($(n))." \
|
|
|
- "-behaviour(cowboy_websocket_handler)." \
|
|
|
- "" \
|
|
|
- "-export([init/3])." \
|
|
|
- "-export([websocket_init/3])." \
|
|
|
- "-export([websocket_handle/3])." \
|
|
|
- "-export([websocket_info/3])." \
|
|
|
- "-export([websocket_terminate/3])." \
|
|
|
- "" \
|
|
|
- "-record(state, {" \
|
|
|
- "})." \
|
|
|
- "" \
|
|
|
- "init(_, _, _) ->" \
|
|
|
- " {upgrade, protocol, cowboy_websocket}." \
|
|
|
- "" \
|
|
|
- "websocket_init(_, Req, _Opts) ->" \
|
|
|
- " Req2 = cowboy_req:compact(Req)," \
|
|
|
- " {ok, Req2, \#state{}}." \
|
|
|
- "" \
|
|
|
- "websocket_handle({text, Data}, Req, State) ->" \
|
|
|
- " {reply, {text, Data}, Req, State};" \
|
|
|
- "websocket_handle({binary, Data}, Req, State) ->" \
|
|
|
- " {reply, {binary, Data}, Req, State};" \
|
|
|
- "websocket_handle(_Frame, Req, State) ->" \
|
|
|
- " {ok, Req, State}." \
|
|
|
- "" \
|
|
|
- "websocket_info(_Info, Req, State) ->" \
|
|
|
- " {ok, Req, State}." \
|
|
|
- "" \
|
|
|
- "websocket_terminate(_Reason, _Req, _State) ->" \
|
|
|
- " ok."
|
|
|
-tpl_ranch_protocol = "-module($(n))." \
|
|
|
- "-behaviour(ranch_protocol)." \
|
|
|
- "" \
|
|
|
- "-export([start_link/4])." \
|
|
|
- "-export([init/4])." \
|
|
|
- "" \
|
|
|
- "-type opts() :: []." \
|
|
|
- "-export_type([opts/0])." \
|
|
|
- "" \
|
|
|
- "-record(state, {" \
|
|
|
- " socket :: inet:socket()," \
|
|
|
- " transport :: module()" \
|
|
|
- "})." \
|
|
|
- "" \
|
|
|
- "start_link(Ref, Socket, Transport, Opts) ->" \
|
|
|
- " Pid = spawn_link(?MODULE, init, [Ref, Socket, Transport, Opts])," \
|
|
|
- " {ok, Pid}." \
|
|
|
- "" \
|
|
|
- "-spec init(ranch:ref(), inet:socket(), module(), opts()) -> ok." \
|
|
|
- "init(Ref, Socket, Transport, _Opts) ->" \
|
|
|
- " ok = ranch:accept_ack(Ref)," \
|
|
|
- " loop(\#state{socket=Socket, transport=Transport})." \
|
|
|
- "" \
|
|
|
- "loop(State) ->" \
|
|
|
- " loop(State)."
|
|
|
+define tpl_supervisor
|
|
|
+-module($(n)).
|
|
|
+-behaviour(supervisor).
|
|
|
+
|
|
|
+-export([start_link/0]).
|
|
|
+-export([init/1]).
|
|
|
+
|
|
|
+start_link() ->
|
|
|
+ supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
|
|
+
|
|
|
+init([]) ->
|
|
|
+ Procs = [],
|
|
|
+ {ok, {{one_for_one, 1, 5}, Procs}}.
|
|
|
+endef
|
|
|
+
|
|
|
+define tpl_gen_server
|
|
|
+-module($(n)).
|
|
|
+-behaviour(gen_server).
|
|
|
+
|
|
|
+%% API.
|
|
|
+-export([start_link/0]).
|
|
|
+
|
|
|
+%% gen_server.
|
|
|
+-export([init/1]).
|
|
|
+-export([handle_call/3]).
|
|
|
+-export([handle_cast/2]).
|
|
|
+-export([handle_info/2]).
|
|
|
+-export([terminate/2]).
|
|
|
+-export([code_change/3]).
|
|
|
+
|
|
|
+-record(state, {
|
|
|
+}).
|
|
|
+
|
|
|
+%% API.
|
|
|
+
|
|
|
+-spec start_link() -> {ok, pid()}.
|
|
|
+start_link() ->
|
|
|
+ gen_server:start_link(?MODULE, [], []).
|
|
|
+
|
|
|
+%% gen_server.
|
|
|
+
|
|
|
+init([]) ->
|
|
|
+ {ok, #state{}}.
|
|
|
+
|
|
|
+handle_call(_Request, _From, State) ->
|
|
|
+ {reply, ignored, State}.
|
|
|
+
|
|
|
+handle_cast(_Msg, State) ->
|
|
|
+ {noreply, State}.
|
|
|
+
|
|
|
+handle_info(_Info, State) ->
|
|
|
+ {noreply, State}.
|
|
|
+
|
|
|
+terminate(_Reason, _State) ->
|
|
|
+ ok.
|
|
|
+
|
|
|
+code_change(_OldVsn, State, _Extra) ->
|
|
|
+ {ok, State}.
|
|
|
+endef
|
|
|
+
|
|
|
+define tpl_cowboy_http
|
|
|
+-module($(n)).
|
|
|
+-behaviour(cowboy_http_handler).
|
|
|
+
|
|
|
+-export([init/3]).
|
|
|
+-export([handle/2]).
|
|
|
+-export([terminate/3]).
|
|
|
+
|
|
|
+-record(state, {
|
|
|
+}).
|
|
|
+
|
|
|
+init(_, Req, _Opts) ->
|
|
|
+ {ok, Req, #state{}}.
|
|
|
+
|
|
|
+handle(Req, State=#state{}) ->
|
|
|
+ {ok, Req2} = cowboy_req:reply(200, Req),
|
|
|
+ {ok, Req2, State}.
|
|
|
+
|
|
|
+terminate(_Reason, _Req, _State) ->
|
|
|
+ ok.
|
|
|
+endef
|
|
|
+
|
|
|
+define tpl_cowboy_loop
|
|
|
+-module($(n)).
|
|
|
+-behaviour(cowboy_loop_handler).
|
|
|
+
|
|
|
+-export([init/3]).
|
|
|
+-export([info/3]).
|
|
|
+-export([terminate/3]).
|
|
|
+
|
|
|
+-record(state, {
|
|
|
+}).
|
|
|
+
|
|
|
+init(_, Req, _Opts) ->
|
|
|
+ {loop, Req, #state{}, 5000, hibernate}.
|
|
|
+
|
|
|
+info(_Info, Req, State) ->
|
|
|
+ {loop, Req, State, hibernate}.
|
|
|
+
|
|
|
+terminate(_Reason, _Req, _State) ->
|
|
|
+ ok.
|
|
|
+endef
|
|
|
+
|
|
|
+define tpl_cowboy_rest
|
|
|
+-module($(n)).
|
|
|
+
|
|
|
+-export([init/3]).
|
|
|
+-export([content_types_provided/2]).
|
|
|
+-export([get_html/2]).
|
|
|
+
|
|
|
+init(_, _Req, _Opts) ->
|
|
|
+ {upgrade, protocol, cowboy_rest}.
|
|
|
+
|
|
|
+content_types_provided(Req, State) ->
|
|
|
+ {[{{<<"text">>, <<"html">>, '_'}, get_html}], Req, State}.
|
|
|
+
|
|
|
+get_html(Req, State) ->
|
|
|
+ {<<"<html><body>This is REST!</body></html>">>, Req, State}.
|
|
|
+endef
|
|
|
+
|
|
|
+define tpl_cowboy_ws
|
|
|
+-module($(n)).
|
|
|
+-behaviour(cowboy_websocket_handler).
|
|
|
+
|
|
|
+-export([init/3]).
|
|
|
+-export([websocket_init/3]).
|
|
|
+-export([websocket_handle/3]).
|
|
|
+-export([websocket_info/3]).
|
|
|
+-export([websocket_terminate/3]).
|
|
|
+
|
|
|
+-record(state, {
|
|
|
+}).
|
|
|
+
|
|
|
+init(_, _, _) ->
|
|
|
+ {upgrade, protocol, cowboy_websocket}.
|
|
|
+
|
|
|
+websocket_init(_, Req, _Opts) ->
|
|
|
+ Req2 = cowboy_req:compact(Req),
|
|
|
+ {ok, Req2, #state{}}.
|
|
|
+
|
|
|
+websocket_handle({text, Data}, Req, State) ->
|
|
|
+ {reply, {text, Data}, Req, State};
|
|
|
+websocket_handle({binary, Data}, Req, State) ->
|
|
|
+ {reply, {binary, Data}, Req, State};
|
|
|
+websocket_handle(_Frame, Req, State) ->
|
|
|
+ {ok, Req, State}.
|
|
|
+
|
|
|
+websocket_info(_Info, Req, State) ->
|
|
|
+ {ok, Req, State}.
|
|
|
+
|
|
|
+websocket_terminate(_Reason, _Req, _State) ->
|
|
|
+ ok.
|
|
|
+endef
|
|
|
+
|
|
|
+define tpl_ranch_protocol
|
|
|
+-module($(n)).
|
|
|
+-behaviour(ranch_protocol).
|
|
|
+
|
|
|
+-export([start_link/4]).
|
|
|
+-export([init/4]).
|
|
|
+
|
|
|
+-type opts() :: [].
|
|
|
+-export_type([opts/0]).
|
|
|
+
|
|
|
+-record(state, {
|
|
|
+ socket :: inet:socket(),
|
|
|
+ transport :: module()
|
|
|
+}).
|
|
|
+
|
|
|
+start_link(Ref, Socket, Transport, Opts) ->
|
|
|
+ Pid = spawn_link(?MODULE, init, [Ref, Socket, Transport, Opts]),
|
|
|
+ {ok, Pid}.
|
|
|
+
|
|
|
+-spec init(ranch:ref(), inet:socket(), module(), opts()) -> ok.
|
|
|
+init(Ref, Socket, Transport, _Opts) ->
|
|
|
+ ok = ranch:accept_ack(Ref),
|
|
|
+ loop(#state{socket=Socket, transport=Transport}).
|
|
|
+
|
|
|
+loop(State) ->
|
|
|
+ loop(State).
|
|
|
+endef
|
|
|
|
|
|
# Plugin-specific targets.
|
|
|
|
|
|
+define render_template
|
|
|
+ @echo '$(subst $(newline),\n,${1})' > $(2)
|
|
|
+endef
|
|
|
+
|
|
|
+define newline
|
|
|
+
|
|
|
+
|
|
|
+endef
|
|
|
+
|
|
|
bootstrap:
|
|
|
ifneq ($(wildcard src/),)
|
|
|
$(error Error: src/ directory already exists)
|
|
|
endif
|
|
|
- @printf "%s\n" $(bs_Makefile) > Makefile
|
|
|
+ $(call render_template,$(bs_Makefile),Makefile)
|
|
|
@mkdir src/
|
|
|
- @printf "%s\n" $(bs_appsrc) > src/$(PROJECT).app.src
|
|
|
- @printf "%s\n" $(bs_app) > src/$(PROJECT)_app.erl
|
|
|
+ $(call render_template,$(bs_appsrc),src/$(PROJECT).app.src)
|
|
|
+ $(call render_template,$(bs_app),src/$(PROJECT)_app.erl)
|
|
|
$(eval n := $(PROJECT)_sup)
|
|
|
- @printf "%s\n" $(tpl_supervisor) > src/$(PROJECT)_sup.erl
|
|
|
+ $(call render_template,$(tpl_supervisor),src/$(PROJECT)_sup.erl)
|
|
|
|
|
|
bootstrap-lib:
|
|
|
ifneq ($(wildcard src/),)
|
|
|
$(error Error: src/ directory already exists)
|
|
|
endif
|
|
|
- @printf "%s\n" $(bs_Makefile) > Makefile
|
|
|
+ $(call render_template,$(bs_Makefile),Makefile)
|
|
|
@mkdir src/
|
|
|
- @printf "%s\n" $(bs_appsrc_lib) > src/$(PROJECT).app.src
|
|
|
+ $(call render_template,$(bs_appsrc_lib),src/$(PROJECT).app.src)
|
|
|
|
|
|
bootstrap-rel:
|
|
|
ifneq ($(wildcard relx.config),)
|
|
@@ -491,10 +541,10 @@ endif
|
|
|
ifneq ($(wildcard rel/),)
|
|
|
$(error Error: rel/ directory already exists)
|
|
|
endif
|
|
|
- @printf "%s\n" $(bs_relx_config) > relx.config
|
|
|
+ $(call render_template,$(bs_relx_config),relx.config)
|
|
|
@mkdir rel/
|
|
|
- @printf "%s\n" $(bs_sys_config) > rel/sys.config
|
|
|
- @printf "%s\n" $(bs_vm_args) > rel/vm.args
|
|
|
+ $(call render_template,$(bs_sys_config),rel/sys.config)
|
|
|
+ $(call render_template,$(bs_vm_args),rel/vm.args)
|
|
|
|
|
|
new:
|
|
|
ifeq ($(wildcard src/),)
|
|
@@ -509,7 +559,7 @@ endif
|
|
|
ifndef n
|
|
|
$(error Usage: make new t=TEMPLATE n=NAME)
|
|
|
endif
|
|
|
- @printf "%s\n" $(tpl_$(t)) > src/$(n).erl
|
|
|
+ $(call render_template,$(tpl_$(t)),src/$(n).erl)
|
|
|
|
|
|
list-templates:
|
|
|
@echo Available templates: $(sort $(patsubst tpl_%,%,$(filter tpl_%,$(.VARIABLES))))
|