Skip to content

Commit

Permalink
mod_admin_modules: show the version of modules in the admin/modules (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
mworrell committed Jan 6, 2023
1 parent d4a8e45 commit 993c4ba
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 19 deletions.
24 changes: 17 additions & 7 deletions modules/mod_admin_modules/templates/admin_modules.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,37 @@
<thead>
<tr>
<th width="1%"></th>
<th width="19%">{_ Title _}</th>
<th width="45%">{_ Description _}</th>
<th width="17%">{_ Title _}</th>
<th width="40%">{_ Description _}</th>
<th width="12%">{_ Version _}</th>
<th width="5%">{_ Prio _}</th>
<th width="30%">{_ Author _}</th>
<th width="25%">{_ Author _}</th>
</tr>
</thead>

<tbody>
{% for sort, prio, module, props in modules %}
{% with m.modules.info[module] as info %}
{% with configurable[module] as config_template %}
{% if config_template %}
{% wire name="dialog-"|append:module action={dialog_open template=config_template title=props.mod_title|default:props.title module=module props=props} %}
{% wire name="dialog-"|append:module action={dialog_open template=config_template title=info.title|default:props.title|escape module=module props=props} %}
{% endif %}
<tr id="{{ #li.module }}" class="{% if not props.is_active %}unpublished{% endif %}" {% if config_template %}data-event="dialog-{{ module }}"{% endif %}>
<td>
{% include "_icon_status.tpl" status_title=status[module] status=status[module] status_id=#status.module %}
</td>
<td>
<strong>{{ props.mod_title|default:props.title }}</strong><br />
<span class="text-muted">{{ module }}</span>
<strong>{{ info.title|default:props.title|escape }}</strong><br>
<span class="text-muted">
{{ module }}
</span>
</td>
<td>{{ info.description|default:props.mod_description|escape|default:"-" }}</td>
<td>
{% if info.version %}
<small>{{ info.version|escape }}</small>
{% endif %}
</td>
<td>{{ props.mod_description|default:"-" }}</td>
<td>{{ prio }}</td>
<td>
<div class="pull-right buttons">
Expand All @@ -61,6 +70,7 @@
</td>
</tr>
{% endwith %}
{% endwith %}
{% empty %}
<tr>
<td colspan="4">
Expand Down
16 changes: 7 additions & 9 deletions src/models/m_modules.erl
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
%% @author Marc Worrell <marc@worrell.nl>
%% @copyright 2010 Marc Worrell
%% Date: 2010-05-05
%%
%% @copyright 2010-2023 Marc Worrell
%% @doc Model for the zotonic modules. List all modules, enabled or disabled.

%% Copyright 2010 Marc Worrell
%% Copyright 2010-2023 Marc Worrell
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -49,11 +47,11 @@ m_find_value(info, #m{value=undefined} = M, _Context) ->
M#m{value=info};
m_find_value(Module, #m{value=info}, Context) ->
M = z_convert:to_atom(Module),
[{enabled, lists:member(M, enabled(Context))},
{active, z_module_manager:active(M, Context)},
{title, z_module_manager:title(M)},
{prio, z_module_manager:prio(M)}].

Info = z_module_manager:mod_info(M),
Info#{
is_enabled => lists:member(M, enabled(Context)),
is_active => z_module_manager:active(M, Context)
}.

%% @doc Transform a m_config value to a list, used for template loops
%% @spec m_to_list(Source, Context) -> List
Expand Down
136 changes: 133 additions & 3 deletions src/support/z_module_manager.erl
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
%% @author Marc Worrell <marc@worrell.nl>
%% @copyright 2009-2015 Marc Worrell

%% @copyright 2009-2023 Marc Worrell
%% @doc Module supervisor. Uses a z_supervisor. Starts/restarts module processes.

%% Copyright 2009-2015 Marc Worrell
%% Copyright 2009-2023 Marc Worrell
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -51,11 +50,13 @@
dependencies/1,
startable/2,
module_exists/1,
mod_info/1,
title/1,
reinstall/2
]).

-include_lib("zotonic.hrl").
-include_lib("zotonic_release.hrl").

%% The default module priority
-define(MOD_PRIO, 500).
Expand Down Expand Up @@ -395,6 +396,103 @@ title(M) ->
_M:_E -> undefined
end.

%% @doc Fetch information about a module or site.
-spec mod_info(Module) -> Info when
Module :: atom(),
Info :: #{
prio := integer(),
version := binary() | undefined,
schema := integer() | undefined,
title := binary() | undefined,
author := binary() | undefined,
description := binary() | undefined,
app_dir := filename:filename_all() | undefined
}.
mod_info(Module) when is_atom(Module) ->
LibDir = case srcdir(Module) of
undefined -> undefined;
Dir -> unicode:characters_to_binary(Dir)
end,
#{
prio => prio(Module),
version => find_version(LibDir),
schema => mod_schema(Module),
title => title(Module),
description => mod_description(Module),
author => mod_author(Module),
app_dir => LibDir
}.

srcdir(M) ->
case module_exists(M) of
true ->
try
{source, Filename} = proplists:lookup(source, M:module_info(compile)),
filename:dirname(Filename)
catch
_:_ -> undefined
end;
false ->
undefined
end.

find_version(undefined) ->
undefined;
find_version(LibDir) ->
case maybe_git_version(LibDir) of
undefined ->
% Could be module in a site or zotonic:
% * mysite/modules/mod_foobar
% * zotonic/modules/mod_admin
case filename:basename(filename:dirname(LibDir)) of
<<"modules">> ->
LibDir1 = filename:dirname(filename:dirname(LibDir)),
Version = case filelib:is_file(filename:join([LibDir1, <<"src">>, <<"zotonic.erl">>])) of
true ->
bin(?ZOTONIC_VERSION);
false ->
case filelib:is_file(filename:join([LibDir1, <<"VERSION">>])) of
true ->
{ok, B} = file:read_file(filename:join([LibDir1, <<"VERSION">>])),
B;
false ->
undefined
end
end,
case maybe_git_version(LibDir1) of
undefined ->
Version;
GitVersion when Version =:= undefined ->
GitVersion;
GitVersion when is_binary(Version) ->
<<Version/binary, "-", GitVersion/binary>>
end;
_ ->
undefined
end;
Version ->
Version
end.

maybe_git_version(undefined) ->
undefined;
maybe_git_version(LibDir) ->
GitDir = filename:join(LibDir, ".git"),
case filelib:is_dir(GitDir) of
true ->
git_version(LibDir);
false ->
undefined
end.

git_version(LibDir) ->
Cmd = "(cd " ++ z_utils:os_filename(LibDir)
++ "; git rev-parse --short HEAD)",
Res = os:cmd(Cmd),
iolist_to_binary([
z_string:trim(unicode:characters_to_binary(Res))
]).


%% @doc Get the schema version of a module.
mod_schema(M) ->
Expand All @@ -405,13 +503,45 @@ mod_schema(M) ->
_M:_E -> undefined
end.

%% @doc Get the description of a module.
-spec mod_description(Module) -> Desc when
Module :: atom(),
Desc :: binary() | undefined.
mod_description(Module) ->
try
Desc = proplists:get_value(mod_description, Module:module_info(attributes), <<>>),
bin(Desc)
catch
_M:_E -> undefined
end.

%% @doc Get the author of a module.
-spec mod_author(Module) -> Author when
Module :: atom(),
Author :: binary() | undefined.
mod_author(Module) ->
try
Author = proplists:get_value(author, Module:module_info(attributes), <<>>),
bin(Author)
catch
_M:_E -> undefined
end.



db_schema_version(M, Context) ->
z_db:q1("SELECT schema_version FROM module WHERE name = $1", [M], Context).

set_db_schema_version(M, V, Context) ->
1 = z_db:q("UPDATE module SET schema_version = $1 WHERE name = $2", [V, M], Context),
ok.

bin(A) when is_atom(A) ->
atom_to_binary(A, utf8);
bin(A) when is_list(A) ->
unicode:characters_to_binary(A);
bin(A) when is_binary(A) ->
A.


%%====================================================================
Expand Down

0 comments on commit 993c4ba

Please sign in to comment.