Add ISC license and Cowboy based web service template
This commit is contained in:
parent
7ce93df72e
commit
312db0e63c
@ -332,7 +332,12 @@ done({error, Info, Code}) ->
|
|||||||
ok = zx_daemon:idle(),
|
ok = zx_daemon:idle(),
|
||||||
Message = "Operation failed with: ~160tp",
|
Message = "Operation failed with: ~160tp",
|
||||||
ok = tell(error, Message, [Info]),
|
ok = tell(error, Message, [Info]),
|
||||||
init:stop(Code).
|
init:stop(Code);
|
||||||
|
done({error, Class, Error, Stacktrace}) ->
|
||||||
|
ok = zx_daemon:idle(),
|
||||||
|
Message = "Execution failed with: ~tp: ~tp~nStacktrace:~n~tp",
|
||||||
|
ok = tell(error, Message, [Class, Error, Stacktrace]),
|
||||||
|
init:stop(1).
|
||||||
|
|
||||||
|
|
||||||
-spec not_done(outcome()) -> ok | no_return().
|
-spec not_done(outcome()) -> ok | no_return().
|
||||||
@ -442,7 +447,10 @@ start(LogPath) ->
|
|||||||
overload_kill_qlen => 20000,
|
overload_kill_qlen => 20000,
|
||||||
overload_kill_restart_after => 5000,
|
overload_kill_restart_after => 5000,
|
||||||
sync_mode_qlen => 10,
|
sync_mode_qlen => 10,
|
||||||
type => {file, LogPath}},
|
type => file,
|
||||||
|
file => LogPath,
|
||||||
|
max_no_bytes => 10000000,
|
||||||
|
max_no_files => 10},
|
||||||
filter_default =>
|
filter_default =>
|
||||||
stop,
|
stop,
|
||||||
filters =>
|
filters =>
|
||||||
@ -468,8 +476,8 @@ trim_logs(LogDir) ->
|
|||||||
{ok, Origin} = file:get_cwd(),
|
{ok, Origin} = file:get_cwd(),
|
||||||
ok = file:set_cwd(LogDir),
|
ok = file:set_cwd(LogDir),
|
||||||
{ok, Files} = file:list_dir("."),
|
{ok, Files} = file:list_dir("."),
|
||||||
Desc = fun(A, B) -> A > B end,
|
Descending = fun(A, B) -> A > B end,
|
||||||
Sorted = lists:sort(Desc, Files),
|
Sorted = lists:sort(Descending, Files),
|
||||||
ok =
|
ok =
|
||||||
case length(Sorted) =< 10 of
|
case length(Sorted) =< 10 of
|
||||||
true -> ok;
|
true -> ok;
|
||||||
@ -873,6 +881,11 @@ search_xdg([]) ->
|
|||||||
%% procedure the runtime will halt with an error message.
|
%% procedure the runtime will halt with an error message.
|
||||||
|
|
||||||
run(PackageString, RunArgs) ->
|
run(PackageString, RunArgs) ->
|
||||||
|
try run1(PackageString, RunArgs)
|
||||||
|
catch C:E:S -> {error, C, E, S}
|
||||||
|
end.
|
||||||
|
|
||||||
|
run1(PackageString, RunArgs) ->
|
||||||
case zx_lib:package_id(PackageString) of
|
case zx_lib:package_id(PackageString) of
|
||||||
{ok, {"otpr", "zomp", Version}} -> run2_maybe(Version, RunArgs);
|
{ok, {"otpr", "zomp", Version}} -> run2_maybe(Version, RunArgs);
|
||||||
{ok, FuzzyID} -> run2(FuzzyID, RunArgs);
|
{ok, FuzzyID} -> run2(FuzzyID, RunArgs);
|
||||||
@ -969,6 +982,11 @@ resolve_version(PackageID = {Realm, Name, _}) ->
|
|||||||
%% and use zx commands to add or drop dependencies made available via zomp.
|
%% and use zx commands to add or drop dependencies made available via zomp.
|
||||||
|
|
||||||
run_local(RunArgs) ->
|
run_local(RunArgs) ->
|
||||||
|
try run_local1(RunArgs)
|
||||||
|
catch C:E:S -> {error, C, E, S}
|
||||||
|
end.
|
||||||
|
|
||||||
|
run_local1(RunArgs) ->
|
||||||
{ok, ProjectDir} = file:get_cwd(),
|
{ok, ProjectDir} = file:get_cwd(),
|
||||||
run_project(ProjectDir, ProjectDir, RunArgs).
|
run_project(ProjectDir, ProjectDir, RunArgs).
|
||||||
|
|
||||||
@ -978,6 +996,11 @@ run_local(RunArgs) ->
|
|||||||
RunArgs :: [string()].
|
RunArgs :: [string()].
|
||||||
|
|
||||||
run_dir(TargetDir, RunArgs) ->
|
run_dir(TargetDir, RunArgs) ->
|
||||||
|
try run_dir1(TargetDir, RunArgs)
|
||||||
|
catch C:E:S -> {error, C, E, S}
|
||||||
|
end.
|
||||||
|
|
||||||
|
run_dir1(TargetDir, RunArgs) ->
|
||||||
{ok, ExecDir} = file:get_cwd(),
|
{ok, ExecDir} = file:get_cwd(),
|
||||||
case file:set_cwd(TargetDir) of
|
case file:set_cwd(TargetDir) of
|
||||||
ok ->
|
ok ->
|
||||||
@ -1009,9 +1032,13 @@ run_project(ProjectDir, ExecDir, RunArgs, Meta) ->
|
|||||||
case prepare(Deps) of
|
case prepare(Deps) of
|
||||||
ok ->
|
ok ->
|
||||||
ok = file:set_cwd(ProjectDir),
|
ok = file:set_cwd(ProjectDir),
|
||||||
ok = zx_lib:build(),
|
case zx_lib:build() of
|
||||||
|
ok ->
|
||||||
ok = file:set_cwd(ExecDir),
|
ok = file:set_cwd(ExecDir),
|
||||||
execute(Type, PackageID, Meta, ProjectDir, NewArgs);
|
execute(Type, PackageID, Meta, ProjectDir, NewArgs);
|
||||||
|
error ->
|
||||||
|
{error, build_failed}
|
||||||
|
end;
|
||||||
Error ->
|
Error ->
|
||||||
Error
|
Error
|
||||||
end;
|
end;
|
||||||
@ -1077,8 +1104,10 @@ is_local(_, []) -> false.
|
|||||||
%% Execution prep common to all packages.
|
%% Execution prep common to all packages.
|
||||||
|
|
||||||
prepare(Deps) ->
|
prepare(Deps) ->
|
||||||
ok = ensure(Deps),
|
case ensure(Deps) of
|
||||||
make(Deps).
|
ok -> make(Deps);
|
||||||
|
Error -> Error
|
||||||
|
end.
|
||||||
|
|
||||||
ensure([{fetch, Dep} | Rest]) ->
|
ensure([{fetch, Dep} | Rest]) ->
|
||||||
case filelib:is_dir(zx_lib:ppath(lib, Dep)) of
|
case filelib:is_dir(zx_lib:ppath(lib, Dep)) of
|
||||||
@ -1115,9 +1144,13 @@ make([{local, _, Dir} | Rest]) ->
|
|||||||
{ok, WorkingDir} = file:get_cwd(),
|
{ok, WorkingDir} = file:get_cwd(),
|
||||||
case file:set_cwd(Dir) of
|
case file:set_cwd(Dir) of
|
||||||
ok ->
|
ok ->
|
||||||
ok = zx_lib:build(),
|
case zx_lib:build() of
|
||||||
|
ok ->
|
||||||
ok = file:set_cwd(WorkingDir),
|
ok = file:set_cwd(WorkingDir),
|
||||||
make(Rest);
|
make(Rest);
|
||||||
|
error ->
|
||||||
|
{error, build_failed}
|
||||||
|
end;
|
||||||
Error = {error, enoent} ->
|
Error = {error, enoent} ->
|
||||||
ok = tell(error, "Dir ~p does not exist!", [Dir]),
|
ok = tell(error, "Dir ~p does not exist!", [Dir]),
|
||||||
Error
|
Error
|
||||||
|
|||||||
@ -92,10 +92,14 @@ initialize(P = #project{id = none}) ->
|
|||||||
initialize(P#project{id = ID, appmod = Name});
|
initialize(P#project{id = ID, appmod = Name});
|
||||||
initialize(P = #project{type = app, id = {_, Name, _}, prefix = none}) ->
|
initialize(P = #project{type = app, id = {_, Name, _}, prefix = none}) ->
|
||||||
initialize(P#project{prefix = ask_prefix(Name)});
|
initialize(P#project{prefix = ask_prefix(Name)});
|
||||||
|
initialize(P = #project{type = web, id = {_, Name, _}, prefix = none}) ->
|
||||||
|
initialize(P#project{prefix = ask_prefix(Name)});
|
||||||
initialize(P = #project{type = gui, id = {_, Name, _}, prefix = none}) ->
|
initialize(P = #project{type = gui, id = {_, Name, _}, prefix = none}) ->
|
||||||
initialize(P#project{prefix = ask_prefix(Name)});
|
initialize(P#project{prefix = ask_prefix(Name)});
|
||||||
initialize(P = #project{type = app, appmod = none}) ->
|
initialize(P = #project{type = app, appmod = none}) ->
|
||||||
initialize(P#project{appmod = ask_appmod()});
|
initialize(P#project{appmod = ask_appmod()});
|
||||||
|
initialize(P = #project{type = web, appmod = none}) ->
|
||||||
|
initialize(P#project{appmod = ask_appmod()});
|
||||||
initialize(P = #project{type = cli, appmod = none}) ->
|
initialize(P = #project{type = cli, appmod = none}) ->
|
||||||
initialize(P#project{appmod = ask_appmod()});
|
initialize(P#project{appmod = ask_appmod()});
|
||||||
initialize(P = #project{type = gui, appmod = none}) ->
|
initialize(P = #project{type = gui, appmod = none}) ->
|
||||||
@ -190,6 +194,7 @@ initialize(P = #project{type = Type,
|
|||||||
TS =
|
TS =
|
||||||
case Type of
|
case Type of
|
||||||
app -> "Erlang application";
|
app -> "Erlang application";
|
||||||
|
web -> "Web service";
|
||||||
cli -> "CLI/terminal program";
|
cli -> "CLI/terminal program";
|
||||||
gui -> "GUI application"
|
gui -> "GUI application"
|
||||||
end,
|
end,
|
||||||
@ -304,9 +309,10 @@ zompify(P = #project{type = Type,
|
|||||||
prefix => Prefix,
|
prefix => Prefix,
|
||||||
tags => []},
|
tags => []},
|
||||||
Data =
|
Data =
|
||||||
case Type == cli of
|
case Type of
|
||||||
true -> maps:put(mod, Module, Simple);
|
cli -> maps:put(mod, Module, Simple);
|
||||||
false -> Simple
|
web -> Simple#{type := app, deps => cowboy_deps()};
|
||||||
|
_ -> Simple
|
||||||
end,
|
end,
|
||||||
ok = zx_lib:write_project_meta(Data),
|
ok = zx_lib:write_project_meta(Data),
|
||||||
ok = ensure_emakefile(),
|
ok = ensure_emakefile(),
|
||||||
@ -315,6 +321,17 @@ zompify(P = #project{type = Type,
|
|||||||
{ok, PackageString} = zx_lib:package_string(ID),
|
{ok, PackageString} = zx_lib:package_string(ID),
|
||||||
tell("Project ~ts initialized.", [PackageString]).
|
tell("Project ~ts initialized.", [PackageString]).
|
||||||
|
|
||||||
|
cowboy_deps() ->
|
||||||
|
Apps = [{"otpr", N} || N <- ["cowboy", "ranch", "cowlib"]],
|
||||||
|
cowboy_deps(Apps).
|
||||||
|
|
||||||
|
cowboy_deps([App = {Realm, Name} | Apps]) ->
|
||||||
|
{ok, Ref} = zx_daemon:latest(App),
|
||||||
|
{ok, Ver} = zx_daemon:wait_result(Ref),
|
||||||
|
[{Realm, Name, Ver} | cowboy_deps(Apps)];
|
||||||
|
cowboy_deps([]) ->
|
||||||
|
[].
|
||||||
|
|
||||||
|
|
||||||
-spec ensure_emakefile() -> ok.
|
-spec ensure_emakefile() -> ok.
|
||||||
|
|
||||||
@ -347,6 +364,7 @@ ensure_license(#project{name = Name,
|
|||||||
"LGPL-3.0-only" -> "lgpl3.txt";
|
"LGPL-3.0-only" -> "lgpl3.txt";
|
||||||
"LGPL-3.0-or-later" -> "lgpl3.txt";
|
"LGPL-3.0-or-later" -> "lgpl3.txt";
|
||||||
"MIT" -> "mit.txt";
|
"MIT" -> "mit.txt";
|
||||||
|
"ISC" -> "isc.txt";
|
||||||
"MPL-2.0" -> "mpl2.txt";
|
"MPL-2.0" -> "mpl2.txt";
|
||||||
"CC0" -> "cc0.txt"
|
"CC0" -> "cc0.txt"
|
||||||
end,
|
end,
|
||||||
@ -1210,10 +1228,14 @@ create(P = #project{id = none}) ->
|
|||||||
create(P#project{id = ID, appmod = AppMod});
|
create(P#project{id = ID, appmod = AppMod});
|
||||||
create(P = #project{type = app, id = {_, Name, _}, prefix = none}) ->
|
create(P = #project{type = app, id = {_, Name, _}, prefix = none}) ->
|
||||||
create(P#project{prefix = ask_prefix(Name)});
|
create(P#project{prefix = ask_prefix(Name)});
|
||||||
|
create(P = #project{type = web, id = {_, Name, _}, prefix = none}) ->
|
||||||
|
create(P#project{prefix = ask_prefix(Name)});
|
||||||
create(P = #project{type = gui, id = {_, Name, _}, prefix = none}) ->
|
create(P = #project{type = gui, id = {_, Name, _}, prefix = none}) ->
|
||||||
create(P#project{prefix = ask_prefix(Name)});
|
create(P#project{prefix = ask_prefix(Name)});
|
||||||
create(P = #project{type = app, appmod = none}) ->
|
create(P = #project{type = app, appmod = none}) ->
|
||||||
create(P#project{appmod = ask_appmod()});
|
create(P#project{appmod = ask_appmod()});
|
||||||
|
create(P = #project{type = web, appmod = none}) ->
|
||||||
|
create(P#project{appmod = ask_appmod()});
|
||||||
create(P = #project{type = gui, appmod = none}) ->
|
create(P = #project{type = gui, appmod = none}) ->
|
||||||
create(P#project{appmod = ask_appmod()});
|
create(P#project{appmod = ask_appmod()});
|
||||||
create(P = #project{type = cli, module = none}) ->
|
create(P = #project{type = cli, module = none}) ->
|
||||||
@ -1402,6 +1424,7 @@ create(P = #project{type = Type,
|
|||||||
TS =
|
TS =
|
||||||
case Type of
|
case Type of
|
||||||
app -> "Erlang application";
|
app -> "Erlang application";
|
||||||
|
web -> "Web service";
|
||||||
gui -> "GUI application"
|
gui -> "GUI application"
|
||||||
end,
|
end,
|
||||||
Instructions =
|
Instructions =
|
||||||
@ -1648,6 +1671,7 @@ munge_sources(#project{type = Type,
|
|||||||
Template =
|
Template =
|
||||||
case Type of
|
case Type of
|
||||||
app -> "example_server";
|
app -> "example_server";
|
||||||
|
web -> "cowboy_example";
|
||||||
gui -> "hellowx"
|
gui -> "hellowx"
|
||||||
end,
|
end,
|
||||||
TemplateDir = filename:join([os:getenv("ZX_DIR"), "templates", Template]),
|
TemplateDir = filename:join([os:getenv("ZX_DIR"), "templates", Template]),
|
||||||
@ -1716,17 +1740,19 @@ ask_project_type() ->
|
|||||||
"to work, even if it acts in a supporting role.~n"
|
"to work, even if it acts in a supporting role.~n"
|
||||||
"(Note that escripts cannot be packaged.)~n"
|
"(Note that escripts cannot be packaged.)~n"
|
||||||
"[1] Traditional Erlang service application~n"
|
"[1] Traditional Erlang service application~n"
|
||||||
"[2] Library~n"
|
"[2] Cowboy-based web service~n"
|
||||||
"[3] End-user GUI application~n"
|
"[3] Library~n"
|
||||||
"[4] End-user CLI application~n"
|
"[4] End-user GUI application~n"
|
||||||
"[5] Escript~n",
|
"[5] End-user CLI application~n"
|
||||||
|
"[6] Escript~n",
|
||||||
ok = io:format(Instructions),
|
ok = io:format(Instructions),
|
||||||
case zx_tty:get_input() of
|
case zx_tty:get_input() of
|
||||||
"1" -> app;
|
"1" -> app;
|
||||||
"2" -> lib;
|
"2" -> web;
|
||||||
"3" -> gui;
|
"3" -> lib;
|
||||||
"4" -> cli;
|
"4" -> gui;
|
||||||
"5" -> escript;
|
"5" -> cli;
|
||||||
|
"6" -> escript;
|
||||||
_ ->
|
_ ->
|
||||||
ok = zx_tty:derp(),
|
ok = zx_tty:derp(),
|
||||||
ask_project_type()
|
ask_project_type()
|
||||||
@ -2551,6 +2577,7 @@ ask_license() ->
|
|||||||
{"GNU Library (LGPL) v3.0 only", "LGPL-3.0-only"},
|
{"GNU Library (LGPL) v3.0 only", "LGPL-3.0-only"},
|
||||||
{"GNU Library (LGPL) v3.0 or later", "LGPL-3.0-or-later"},
|
{"GNU Library (LGPL) v3.0 or later", "LGPL-3.0-or-later"},
|
||||||
{"MIT license", "MIT"},
|
{"MIT license", "MIT"},
|
||||||
|
{"ISC license", "ISC"},
|
||||||
{"Mozilla Public License 2.0", "MPL-2.0"},
|
{"Mozilla Public License 2.0", "MPL-2.0"},
|
||||||
{"Public Domain/Creative Commons Zero notice", "CC0"},
|
{"Public Domain/Creative Commons Zero notice", "CC0"},
|
||||||
{"[proprietary]", proprietary},
|
{"[proprietary]", proprietary},
|
||||||
|
|||||||
59
zomp/lib/otpr/zx/0.13.0/templates/cowboy_example/appmod.erl
Normal file
59
zomp/lib/otpr/zx/0.13.0/templates/cowboy_example/appmod.erl
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
%%% @doc
|
||||||
|
%%% 〘*PROJECT NAME*〙
|
||||||
|
%%% @end
|
||||||
|
|
||||||
|
-module(〘*APP MOD*〙).
|
||||||
|
-vsn("〘*VERSION*〙").
|
||||||
|
〘*AUTHOR*〙
|
||||||
|
〘*COPYRIGHT*〙
|
||||||
|
〘*LICENSE*〙
|
||||||
|
|
||||||
|
-export([start/0, start/1]).
|
||||||
|
-export([start/2, stop/1]).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-spec start() -> ok.
|
||||||
|
%% @doc
|
||||||
|
%% Start the server in an "ignore" state.
|
||||||
|
|
||||||
|
start() ->
|
||||||
|
ok = application:start(hello_web),
|
||||||
|
io:format("Starting...").
|
||||||
|
|
||||||
|
|
||||||
|
-spec start(PortNum) -> ok
|
||||||
|
when PortNum :: inet:port_number().
|
||||||
|
%% @doc
|
||||||
|
%% Start the server and begin listening immediately. Slightly more convenient when
|
||||||
|
%% playing around in the shell.
|
||||||
|
|
||||||
|
start(PortNum) ->
|
||||||
|
ok = start(),
|
||||||
|
io:format("Startup complete, listening on ~w~n", [PortNum]).
|
||||||
|
|
||||||
|
|
||||||
|
-spec start(normal, term()) -> {ok, pid()}.
|
||||||
|
%% @private
|
||||||
|
%% Called by OTP to kick things off. This is for the use of the "application" part of
|
||||||
|
%% OTP, not to be called by user code.
|
||||||
|
%% See: http://erlang.org/doc/apps/kernel/application.html
|
||||||
|
|
||||||
|
start(normal, _Args) ->
|
||||||
|
ok = application:ensure_started(sasl),
|
||||||
|
{ok, Started} = application:ensure_all_started(cowboy),
|
||||||
|
ok = io:format("Started: ~p~n", [Started]),
|
||||||
|
Routes = [{'_', [{"/", 〘*PREFIX*〙_top, []}]}],
|
||||||
|
Dispatch = cowboy_router:compile(Routes),
|
||||||
|
Env = #{env => #{dispatch => Dispatch}},
|
||||||
|
{ok, _} = cowboy:start_clear(〘*PREFIX*〙_listener, [{port, 8080}], Env),
|
||||||
|
〘*PREFIX*〙_sup:start_link().
|
||||||
|
|
||||||
|
|
||||||
|
-spec stop(term()) -> ok.
|
||||||
|
%% @private
|
||||||
|
%% Similar to start/2 above, this is to be called by the "application" part of OTP,
|
||||||
|
%% not client code. Causes a (hopefully graceful) shutdown of the application.
|
||||||
|
|
||||||
|
stop(_State) ->
|
||||||
|
ok.
|
||||||
119
zomp/lib/otpr/zx/0.13.0/templates/cowboy_example/src/_state.erl
Normal file
119
zomp/lib/otpr/zx/0.13.0/templates/cowboy_example/src/_state.erl
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
%%% @doc
|
||||||
|
%%% 〘*PROJECT NAME*〙 State
|
||||||
|
%%%
|
||||||
|
%%% This template has been generated by the `zx create project' command and is
|
||||||
|
%%% dead simple. You can have it save a value and you can read that value back out.
|
||||||
|
%%% Obviously you will probably want more from a web server than this,
|
||||||
|
%%% so make it your own.
|
||||||
|
%%% @end
|
||||||
|
|
||||||
|
-module(〘*PREFIX*〙_state).
|
||||||
|
-vsn("〘*VERSION*〙").
|
||||||
|
-behavior(gen_server).
|
||||||
|
〘*AUTHOR*〙
|
||||||
|
〘*COPYRIGHT*〙
|
||||||
|
〘*LICENSE*〙
|
||||||
|
|
||||||
|
-export([save/2, read/1]).
|
||||||
|
-export([start_link/0]).
|
||||||
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||||
|
code_change/3, terminate/2]).
|
||||||
|
|
||||||
|
|
||||||
|
%%% Type and Record Definitions
|
||||||
|
|
||||||
|
-record(s,
|
||||||
|
{data = #{} :: #{Key :: term() := Value :: term()}}).
|
||||||
|
|
||||||
|
-type state() :: #s{}.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%% Service Interface
|
||||||
|
|
||||||
|
-spec save(Key, Value) -> ok
|
||||||
|
when Key :: term(),
|
||||||
|
Value :: term().
|
||||||
|
%% @doc
|
||||||
|
%% Save a value.
|
||||||
|
|
||||||
|
save(Key, Value) ->
|
||||||
|
gen_server:cast(?MODULE, {save, Key, Value}).
|
||||||
|
|
||||||
|
|
||||||
|
-spec read(Key) -> {ok, Value} | error
|
||||||
|
when Key :: term(),
|
||||||
|
Value :: term().
|
||||||
|
%% @doc
|
||||||
|
%% Read a value.
|
||||||
|
|
||||||
|
read(ConfKey) ->
|
||||||
|
gen_server:call(?MODULE, {read, ConfKey}).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%% Startup Functions
|
||||||
|
|
||||||
|
-spec start_link() -> Result
|
||||||
|
when Result :: {ok, pid()}
|
||||||
|
| {error, Reason :: term()}.
|
||||||
|
%% @private
|
||||||
|
%% This should only ever be called by hw_sup (the service-level supervisor).
|
||||||
|
|
||||||
|
start_link() ->
|
||||||
|
gen_server:start_link({local, ?MODULE}, ?MODULE, none, []).
|
||||||
|
|
||||||
|
|
||||||
|
-spec init(none) -> {ok, state()}.
|
||||||
|
%% @private
|
||||||
|
%% Called by the supervisor process to give the process a chance to perform any
|
||||||
|
%% preparatory work necessary for proper function.
|
||||||
|
|
||||||
|
init(none) ->
|
||||||
|
State = #s{},
|
||||||
|
{ok, State}.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%% gen_server Message Handling Callbacks
|
||||||
|
|
||||||
|
handle_call({read, ConfKey}, _, State) ->
|
||||||
|
Value = do_read(ConfKey, State),
|
||||||
|
{reply, Value, State};
|
||||||
|
handle_call(Unexpected, From, State) ->
|
||||||
|
ok = io:format("~p Unexpected call from ~tp: ~tp~n", [self(), From, Unexpected]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
handle_cast({save, ConfKey, Value}, State) ->
|
||||||
|
NewState = do_save(ConfKey, Value, State),
|
||||||
|
{noreply, NewState};
|
||||||
|
handle_cast(Unexpected, State) ->
|
||||||
|
ok = io:format("~p Unexpected cast: ~tp~n", [self(), Unexpected]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
handle_info(Unexpected, State) ->
|
||||||
|
ok = io:format("~p Unexpected info: ~tp~n", [self(), Unexpected]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%% OTP Service Functions
|
||||||
|
|
||||||
|
code_change(_, State, _) ->
|
||||||
|
{ok, State}.
|
||||||
|
|
||||||
|
|
||||||
|
terminate(_, _) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%% Doer Functions
|
||||||
|
|
||||||
|
do_save(Key, Value, State = #s{data = Data}) ->
|
||||||
|
NewData = maps:put(Key, Value, Data),
|
||||||
|
State#s{data = NewData}.
|
||||||
|
|
||||||
|
|
||||||
|
do_read(Key, #s{data = Data}) ->
|
||||||
|
maps:find(Key, Data).
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
%%% @doc
|
||||||
|
%%% 〘*PROJECT NAME*〙 Top-level Supervisor
|
||||||
|
%%%
|
||||||
|
%%% The very top level supervisor in the system.
|
||||||
|
%%% There is only one stateful worker defined by default here, simple
|
||||||
|
%%% called [project]_state. Make it yours.
|
||||||
|
%%%
|
||||||
|
%%% See: http://erlang.org/doc/design_principles/applications.html
|
||||||
|
%%% See: http://zxq9.com/archives/1311
|
||||||
|
%%% @end
|
||||||
|
|
||||||
|
-module(〘*PREFIX*〙_sup).
|
||||||
|
-vsn("〘*VERSION*〙").
|
||||||
|
-behaviour(supervisor).
|
||||||
|
〘*AUTHOR*〙
|
||||||
|
〘*COPYRIGHT*〙
|
||||||
|
〘*LICENSE*〙
|
||||||
|
|
||||||
|
-export([start_link/0]).
|
||||||
|
-export([init/1]).
|
||||||
|
|
||||||
|
|
||||||
|
-spec start_link() -> {ok, pid()}.
|
||||||
|
%% @private
|
||||||
|
%% This supervisor's own start function.
|
||||||
|
|
||||||
|
start_link() ->
|
||||||
|
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||||
|
|
||||||
|
|
||||||
|
-spec init([]) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
|
||||||
|
%% @private
|
||||||
|
%% The OTP init/1 function.
|
||||||
|
|
||||||
|
init([]) ->
|
||||||
|
RestartStrategy = {one_for_one, 1, 60},
|
||||||
|
State = {〘*PREFIX*〙_state,
|
||||||
|
{〘*PREFIX*〙_state, start_link, []},
|
||||||
|
permanent,
|
||||||
|
5000,
|
||||||
|
worker,
|
||||||
|
[〘*PREFIX*〙_state]},
|
||||||
|
Children = [State],
|
||||||
|
{ok, {RestartStrategy, Children}}.
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
%%% @doc
|
||||||
|
%%% 〘*PROJECT NAME*〙 top-level HTTP request handler.
|
||||||
|
%%% @end
|
||||||
|
|
||||||
|
-module(〘*PREFIX*〙_top).
|
||||||
|
-vsn("〘*VERSION*〙").
|
||||||
|
-behavior(cowboy_handler).
|
||||||
|
〘*AUTHOR*〙
|
||||||
|
〘*COPYRIGHT*〙
|
||||||
|
〘*LICENSE*〙
|
||||||
|
|
||||||
|
-export([init/2]).
|
||||||
|
|
||||||
|
|
||||||
|
-spec init(Req, State) -> Result
|
||||||
|
when Req :: cowboy_req:req(),
|
||||||
|
State :: any(),
|
||||||
|
Result :: {ok, Reply, NewState}
|
||||||
|
| {module(), Reply, NewState, Options},
|
||||||
|
Reply :: cowboy_req:req(),
|
||||||
|
NewState :: any(),
|
||||||
|
Options :: any().
|
||||||
|
|
||||||
|
init(Req, State) ->
|
||||||
|
Hits =
|
||||||
|
case 〘*PREFIX*〙_state:read(hits) of
|
||||||
|
{ok, N} -> N;
|
||||||
|
error -> 1
|
||||||
|
end,
|
||||||
|
ok = 〘*PREFIX*〙_state:save(hits, Hits + 1),
|
||||||
|
Code = 200,
|
||||||
|
Headers = #{<<"content-type">> => <<"text/plain">>},
|
||||||
|
TextHits = integer_to_binary(Hits),
|
||||||
|
Body =
|
||||||
|
<<"Hello, World!\r\n",
|
||||||
|
"We've had ", TextHits/binary, " hits so far.">>,
|
||||||
|
Reply = cowboy_req:reply(Code, Headers, Body, Req),
|
||||||
|
{ok, Reply, State}.
|
||||||
@ -1,4 +1,4 @@
|
|||||||
To the extent possible under law, 〘\*COPYRIGHT HOLDER\*〙 has waived all copyright and related or neighboring rights to 〘\*PROJECT NAME\*〙.
|
To the extent possible under law, 〘*COPYRIGHT HOLDER*〙 has waived all copyright and related or neighboring rights to 〘*PROJECT NAME*〙.
|
||||||
|
|
||||||
A more complete reference for the reasoning and formulation of this waiver of property rights is available at the Creative Commons Zero ("CC0") page:
|
A more complete reference for the reasoning and formulation of this waiver of property rights is available at the Creative Commons Zero ("CC0") page:
|
||||||
https://creativecommons.org/share-your-work/public-domain/cc0/
|
https://creativecommons.org/share-your-work/public-domain/cc0/
|
||||||
|
|||||||
14
zomp/lib/otpr/zx/0.13.0/templates/licenses/isc.txt
Normal file
14
zomp/lib/otpr/zx/0.13.0/templates/licenses/isc.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
Copyright 〘*YEAR*〙 〘*COPYRIGHT HOLDER*〙
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user