mirror of
https://github.com/processone/ejabberd.git
synced 2024-10-31 15:21:38 +01:00
70 lines
2.0 KiB
Elixir
70 lines
2.0 KiB
Elixir
defmodule Ejabberd.Config.EjabberdModule do
|
|
@moduledoc """
|
|
Module representing a module block in the configuration file.
|
|
It offers functions for validation and for starting the modules.
|
|
|
|
Warning: The name is EjabberdModule to not collide with
|
|
the already existing Elixir.Module.
|
|
"""
|
|
|
|
@type t :: %{module: atom, attrs: [Attr.t]}
|
|
|
|
defstruct [:module, :attrs]
|
|
|
|
alias Ejabberd.Config.EjabberdModule
|
|
alias Ejabberd.Config.Validation
|
|
|
|
@doc """
|
|
Given a list of modules / single module
|
|
it runs different validators on them.
|
|
|
|
For each module, returns a {:ok, mod} or {:error, mod, errors}
|
|
"""
|
|
def validate(modules) do
|
|
Validation.validate(modules)
|
|
end
|
|
|
|
@doc """
|
|
Given a list of modules, it takes only the ones with
|
|
a git attribute and tries to fetch the repo,
|
|
then, it install them through :ext_mod.install/1
|
|
"""
|
|
@spec fetch_git_repos([EjabberdModule.t]) :: none()
|
|
def fetch_git_repos(modules) do
|
|
modules
|
|
|> Enum.filter(&is_git_module?/1)
|
|
|> Enum.each(&fetch_and_install_git_module/1)
|
|
end
|
|
|
|
# Private API
|
|
|
|
defp is_git_module?(%EjabberdModule{attrs: attrs}) do
|
|
case Keyword.get(attrs, :git) do
|
|
"" -> false
|
|
repo -> String.match?(repo, ~r/((git|ssh|http(s)?)|(git@[\w\.]+))(:(\/\/)?)([\w\.@\:\/\-~]+)(\.git)(\/)?/)
|
|
end
|
|
end
|
|
|
|
defp fetch_and_install_git_module(%EjabberdModule{attrs: attrs}) do
|
|
repo = Keyword.get(attrs, :git)
|
|
mod_name = case Keyword.get(attrs, :name) do
|
|
"" -> infer_mod_name_from_git_url(repo)
|
|
name -> name
|
|
end
|
|
|
|
path = "#{:ext_mod.modules_dir()}/sources/ejabberd-contrib\/#{mod_name}"
|
|
fetch_and_store_repo_source_if_not_exists(path, repo)
|
|
:ext_mod.install(mod_name) # Have to check if overwrites an already present mod
|
|
end
|
|
|
|
defp fetch_and_store_repo_source_if_not_exists(path, repo) do
|
|
unless File.exists?(path) do
|
|
IO.puts "[info] Fetching: #{repo}"
|
|
:os.cmd('git clone #{repo} #{path}')
|
|
end
|
|
end
|
|
|
|
defp infer_mod_name_from_git_url(repo),
|
|
do: String.split(repo, "/") |> List.last |> String.replace(".git", "")
|
|
end
|