Allow to use Mix tasks inside Releases
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
a269d77044
commit
01f746a5d2
|
@ -6,12 +6,18 @@ defmodule Mix.Tasks.Mobilizon.Actors do
|
|||
use Mix.Task
|
||||
|
||||
alias Mix.Tasks
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
|
||||
@shortdoc "Manages Mobilizon actors"
|
||||
|
||||
@impl Mix.Task
|
||||
def run(_) do
|
||||
Mix.shell().info("\nAvailable tasks:")
|
||||
Tasks.Help.run(["--search", "mobilizon.actors."])
|
||||
shell_info("\nAvailable tasks:")
|
||||
|
||||
if mix_shell?() do
|
||||
Tasks.Help.run(["--search", "mobilizon.actors."])
|
||||
else
|
||||
show_subtasks_for_module(__MODULE__)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,6 +7,7 @@ defmodule Mix.Tasks.Mobilizon.Actors.Refresh do
|
|||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Storage.Repo
|
||||
import Ecto.Query
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
require Logger
|
||||
|
||||
@shortdoc "Refresh an actor or all actors"
|
||||
|
@ -26,11 +27,11 @@ defmodule Mix.Tasks.Mobilizon.Actors.Refresh do
|
|||
|
||||
verbose = Keyword.get(options, :verbose, false)
|
||||
|
||||
Mix.Task.run("app.start")
|
||||
start_mobilizon()
|
||||
|
||||
total = count_actors()
|
||||
|
||||
Mix.shell().info("""
|
||||
shell_info("""
|
||||
#{total} actors to process
|
||||
""")
|
||||
|
||||
|
@ -62,22 +63,22 @@ defmodule Mix.Tasks.Mobilizon.Actors.Refresh do
|
|||
|
||||
@impl Mix.Task
|
||||
def run([preferred_username]) do
|
||||
Mix.Task.run("app.start")
|
||||
start_mobilizon()
|
||||
|
||||
case ActivityPub.make_actor_from_nickname(preferred_username) do
|
||||
{:ok, %Actor{}} ->
|
||||
Mix.shell().info("""
|
||||
shell_info("""
|
||||
Actor #{preferred_username} refreshed
|
||||
""")
|
||||
|
||||
{:actor, nil} ->
|
||||
Mix.raise("Error: No such actor")
|
||||
shell_error("Error: No such actor")
|
||||
end
|
||||
end
|
||||
|
||||
@impl Mix.Task
|
||||
def run(_) do
|
||||
Mix.raise("mobilizon.actors.refresh requires an username as argument or --all as an option")
|
||||
shell_error("mobilizon.actors.refresh requires an username as argument or --all as an option")
|
||||
end
|
||||
|
||||
@spec make_actor(String.t(), boolean()) :: any()
|
||||
|
|
|
@ -5,16 +5,17 @@ defmodule Mix.Tasks.Mobilizon.Actors.Show do
|
|||
use Mix.Task
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.Actor
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
|
||||
@shortdoc "Show a Mobilizon user details"
|
||||
|
||||
@impl Mix.Task
|
||||
def run([preferred_username]) do
|
||||
Mix.Task.run("app.start")
|
||||
start_mobilizon()
|
||||
|
||||
case {:actor, Actors.get_actor_by_name_with_preload(preferred_username)} do
|
||||
{:actor, %Actor{} = actor} ->
|
||||
Mix.shell().info("""
|
||||
shell_info("""
|
||||
Informations for the actor #{actor.preferred_username}:
|
||||
- Type: #{actor.type}
|
||||
- Domain: #{if is_nil(actor.domain), do: "Local", else: actor.domain}
|
||||
|
@ -24,11 +25,11 @@ defmodule Mix.Tasks.Mobilizon.Actors.Show do
|
|||
""")
|
||||
|
||||
{:actor, nil} ->
|
||||
Mix.raise("Error: No such actor")
|
||||
shell_error("Error: No such actor")
|
||||
end
|
||||
end
|
||||
|
||||
def run(_) do
|
||||
Mix.raise("mobilizon.actors.show requires an username as argument")
|
||||
shell_error("mobilizon.actors.show requires an username as argument")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,32 +8,107 @@ defmodule Mix.Tasks.Mobilizon.Common do
|
|||
Common functions to be reused in mix tasks
|
||||
"""
|
||||
|
||||
def get_option(options, opt, prompt, defval \\ nil, defname \\ nil) do
|
||||
display = if defname || defval, do: "#{prompt} [#{defname || defval}]", else: "#{prompt}"
|
||||
|
||||
Keyword.get(options, opt) ||
|
||||
case Mix.shell().prompt(display) do
|
||||
"\n" ->
|
||||
case defval do
|
||||
nil ->
|
||||
get_option(options, opt, prompt, defval)
|
||||
|
||||
defval ->
|
||||
defval
|
||||
end
|
||||
|
||||
opt ->
|
||||
String.trim(opt)
|
||||
end
|
||||
end
|
||||
|
||||
def start_mobilizon do
|
||||
Application.put_env(:phoenix, :serve_endpoints, false, persistent: true)
|
||||
|
||||
{:ok, _} = Application.ensure_all_started(:mobilizon)
|
||||
end
|
||||
|
||||
def get_option(options, opt, prompt, defval \\ nil, defname \\ nil) do
|
||||
Keyword.get(options, opt) || shell_prompt(prompt, defval, defname)
|
||||
end
|
||||
|
||||
def shell_prompt(prompt, defval \\ nil, defname \\ nil) do
|
||||
prompt_message = "#{prompt} [#{defname || defval}] "
|
||||
|
||||
input =
|
||||
if mix_shell?(),
|
||||
do: Mix.shell().prompt(prompt_message),
|
||||
else: :io.get_line(prompt_message)
|
||||
|
||||
case input do
|
||||
"\n" ->
|
||||
case defval do
|
||||
nil ->
|
||||
shell_prompt(prompt, defval, defname)
|
||||
|
||||
defval ->
|
||||
defval
|
||||
end
|
||||
|
||||
input ->
|
||||
String.trim(input)
|
||||
end
|
||||
end
|
||||
|
||||
def shell_yes?(message) do
|
||||
if mix_shell?(),
|
||||
do: Mix.shell().yes?("Continue?"),
|
||||
else: shell_prompt(message, "Continue?") in ~w(Yn Y y)
|
||||
end
|
||||
|
||||
def shell_info(message) do
|
||||
if mix_shell?(),
|
||||
do: Mix.shell().info(message),
|
||||
else: IO.puts(message)
|
||||
end
|
||||
|
||||
def shell_error(message) do
|
||||
if mix_shell?(),
|
||||
do: Mix.shell().error(message),
|
||||
else: IO.puts(:stderr, message)
|
||||
end
|
||||
|
||||
@doc "Performs a safe check whether `Mix.shell/0` is available (does not raise if Mix is not loaded)"
|
||||
def mix_shell?, do: :erlang.function_exported(Mix, :shell, 0)
|
||||
|
||||
def escape_sh_path(path) do
|
||||
~S(') <> String.replace(path, ~S('), ~S(\')) <> ~S(')
|
||||
end
|
||||
|
||||
@type task_module :: atom
|
||||
|
||||
@doc """
|
||||
Gets the shortdoc for the given task `module`.
|
||||
Returns the shortdoc or `nil`.
|
||||
"""
|
||||
@spec shortdoc(task_module) :: String.t() | nil
|
||||
def shortdoc(module) when is_atom(module) do
|
||||
case List.keyfind(module.__info__(:attributes), :shortdoc, 0) do
|
||||
{:shortdoc, [shortdoc]} -> shortdoc
|
||||
_ -> nil
|
||||
end
|
||||
end
|
||||
|
||||
def show_subtasks_for_module(module_name) do
|
||||
tasks = list_subtasks_for_module(module_name)
|
||||
|
||||
max = Enum.reduce(tasks, 0, fn {name, _doc}, acc -> max(byte_size(name), acc) end)
|
||||
|
||||
Enum.each(tasks, fn {name, doc} ->
|
||||
shell_info("#{String.pad_trailing(name, max + 2)} # #{doc}")
|
||||
end)
|
||||
end
|
||||
|
||||
@spec list_subtasks_for_module(atom()) :: list({String.t(), String.t()})
|
||||
def list_subtasks_for_module(module_name) do
|
||||
Application.load(:mobilizon)
|
||||
{:ok, modules} = :application.get_key(:mobilizon, :modules)
|
||||
module_name = to_string(module_name)
|
||||
|
||||
modules
|
||||
|> Enum.filter(fn module ->
|
||||
String.starts_with?(to_string(module), to_string(module_name)) &&
|
||||
to_string(module) != to_string(module_name)
|
||||
end)
|
||||
|> Enum.map(&format_module/1)
|
||||
end
|
||||
|
||||
defp format_module(module) do
|
||||
{format_name(to_string(module)), shortdoc(module)}
|
||||
end
|
||||
|
||||
defp format_name("Elixir.Mix.Tasks.Mobilizon." <> task_name) do
|
||||
String.downcase(task_name)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,12 +8,13 @@ defmodule Mix.Tasks.Mobilizon.CreateBot do
|
|||
alias Mobilizon.{Actors, Users}
|
||||
alias Mobilizon.Actors.Bot
|
||||
alias Mobilizon.Users.User
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
|
||||
require Logger
|
||||
|
||||
@shortdoc "Create bot"
|
||||
def run([email, name, summary, type, url]) do
|
||||
Mix.Task.run("app.start")
|
||||
start_mobilizon()
|
||||
|
||||
with {:ok, %User{} = user} <- Users.get_user_by_email(email, true),
|
||||
actor <- Actors.register_bot(%{name: name, summary: summary}),
|
||||
|
|
54
lib/mix/tasks/mobilizon/ecto.ex
Normal file
54
lib/mix/tasks/mobilizon/ecto.ex
Normal file
|
@ -0,0 +1,54 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-onl
|
||||
|
||||
defmodule Mix.Tasks.Mobilizon.Ecto do
|
||||
@moduledoc """
|
||||
Provides tools for Ecto-related tasks (such as migrations)
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Ensures the given repository's migrations path exists on the file system.
|
||||
"""
|
||||
@spec ensure_migrations_path(Ecto.Repo.t(), Keyword.t()) :: String.t()
|
||||
def ensure_migrations_path(repo, opts) do
|
||||
path = opts[:migrations_path] || Path.join(source_repo_priv(repo), "migrations")
|
||||
|
||||
path =
|
||||
case Path.type(path) do
|
||||
:relative ->
|
||||
Path.join(Application.app_dir(:mobilizon), path)
|
||||
|
||||
:absolute ->
|
||||
path
|
||||
end
|
||||
|
||||
if not File.dir?(path) do
|
||||
raise_missing_migrations(Path.relative_to_cwd(path), repo)
|
||||
end
|
||||
|
||||
path
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the private repository path relative to the source.
|
||||
"""
|
||||
def source_repo_priv(repo) do
|
||||
config = repo.config()
|
||||
priv = config[:priv] || "priv/#{repo |> Module.split() |> List.last() |> Macro.underscore()}"
|
||||
Path.join(Application.app_dir(:mobilizon), priv)
|
||||
end
|
||||
|
||||
defp raise_missing_migrations(path, repo) do
|
||||
raise("""
|
||||
Could not find migrations directory #{inspect(path)}
|
||||
for repo #{inspect(repo)}.
|
||||
This may be because you are in a new project and the
|
||||
migration directory has not been created yet. Creating an
|
||||
empty directory at the path above will fix this error.
|
||||
If you expected existing migrations to be found, please
|
||||
make sure your repository has been properly configured
|
||||
and the configured path exists.
|
||||
""")
|
||||
end
|
||||
end
|
71
lib/mix/tasks/mobilizon/ecto/migrate.ex
Normal file
71
lib/mix/tasks/mobilizon/ecto/migrate.ex
Normal file
|
@ -0,0 +1,71 @@
|
|||
# Portions of this file are derived from Pleroma:
|
||||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Mobilizon.Ecto.Migrate do
|
||||
use Mix.Task
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
alias Mix.Tasks.Mobilizon.Ecto, as: EctoTask
|
||||
require Logger
|
||||
|
||||
@shortdoc "Wrapper on `ecto.migrate` task."
|
||||
|
||||
@aliases [
|
||||
n: :step,
|
||||
v: :to
|
||||
]
|
||||
|
||||
@switches [
|
||||
all: :boolean,
|
||||
step: :integer,
|
||||
to: :integer,
|
||||
quiet: :boolean,
|
||||
log_sql: :boolean,
|
||||
strict_version_order: :boolean,
|
||||
migrations_path: :string
|
||||
]
|
||||
|
||||
@repo Mobilizon.Storage.Repo
|
||||
|
||||
@moduledoc """
|
||||
Changes `Logger` level to `:info` before start migration.
|
||||
Changes level back when migration ends.
|
||||
|
||||
## Start migration
|
||||
|
||||
mix mobilizon.ecto.migrate [OPTIONS]
|
||||
|
||||
Options:
|
||||
- see https://hexdocs.pm/ecto/2.0.0/Mix.Tasks.Ecto.Migrate.html
|
||||
"""
|
||||
|
||||
@impl true
|
||||
def run(args \\ []) do
|
||||
start_mobilizon()
|
||||
{opts, _} = OptionParser.parse!(args, strict: @switches, aliases: @aliases)
|
||||
|
||||
if Application.get_env(:mobilizon, @repo)[:ssl] do
|
||||
Application.ensure_all_started(:ssl)
|
||||
end
|
||||
|
||||
opts =
|
||||
if opts[:to] || opts[:step] || opts[:all],
|
||||
do: opts,
|
||||
else: Keyword.put(opts, :all, true)
|
||||
|
||||
opts =
|
||||
if opts[:quiet],
|
||||
do: Keyword.merge(opts, log: false, log_sql: false),
|
||||
else: opts
|
||||
|
||||
path = EctoTask.ensure_migrations_path(@repo, opts)
|
||||
|
||||
level = Logger.level()
|
||||
Logger.configure(level: :info)
|
||||
|
||||
{:ok, _, _} = Ecto.Migrator.with_repo(@repo, &Ecto.Migrator.run(&1, path, :up, opts))
|
||||
|
||||
Logger.configure(level: level)
|
||||
end
|
||||
end
|
74
lib/mix/tasks/mobilizon/ecto/rollback.ex
Normal file
74
lib/mix/tasks/mobilizon/ecto/rollback.ex
Normal file
|
@ -0,0 +1,74 @@
|
|||
# Portions of this file are derived from Pleroma:
|
||||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Mobilizon.Ecto.Rollback do
|
||||
use Mix.Task
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
alias Mix.Tasks.Mobilizon.Ecto, as: EctoTask
|
||||
require Logger
|
||||
@shortdoc "Wrapper on `ecto.rollback` task"
|
||||
|
||||
@aliases [
|
||||
n: :step,
|
||||
v: :to
|
||||
]
|
||||
|
||||
@switches [
|
||||
all: :boolean,
|
||||
step: :integer,
|
||||
to: :integer,
|
||||
start: :boolean,
|
||||
quiet: :boolean,
|
||||
log_sql: :boolean,
|
||||
migrations_path: :string
|
||||
]
|
||||
|
||||
@repo Mobilizon.Storage.Repo
|
||||
|
||||
@moduledoc """
|
||||
Changes `Logger` level to `:info` before start rollback.
|
||||
Changes level back when rollback ends.
|
||||
|
||||
## Start rollback
|
||||
|
||||
mix mobilizon.ecto.rollback
|
||||
|
||||
Options:
|
||||
- see https://hexdocs.pm/ecto/2.0.0/Mix.Tasks.Ecto.Rollback.html
|
||||
"""
|
||||
|
||||
@impl true
|
||||
def run(args \\ []) do
|
||||
start_mobilizon()
|
||||
{opts, _} = OptionParser.parse!(args, strict: @switches, aliases: @aliases)
|
||||
|
||||
if Application.get_env(:mobilizon, @repo)[:ssl] do
|
||||
Application.ensure_all_started(:ssl)
|
||||
end
|
||||
|
||||
opts =
|
||||
if opts[:to] || opts[:step] || opts[:all],
|
||||
do: opts,
|
||||
else: Keyword.put(opts, :step, 1)
|
||||
|
||||
opts =
|
||||
if opts[:quiet],
|
||||
do: Keyword.merge(opts, log: false, log_sql: false),
|
||||
else: opts
|
||||
|
||||
path = EctoTask.ensure_migrations_path(@repo, opts)
|
||||
|
||||
level = Logger.level()
|
||||
Logger.configure(level: :info)
|
||||
|
||||
if Mobilizon.Config.get(:env) == :test do
|
||||
Logger.info("Rollback succesfully")
|
||||
else
|
||||
{:ok, _, _} = Ecto.Migrator.with_repo(@repo, &Ecto.Migrator.run(&1, path, :down, opts))
|
||||
end
|
||||
|
||||
Logger.configure(level: level)
|
||||
end
|
||||
end
|
|
@ -6,12 +6,13 @@ defmodule Mix.Tasks.Mobilizon.Groups do
|
|||
use Mix.Task
|
||||
|
||||
alias Mix.Tasks
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
|
||||
@shortdoc "Manages Mobilizon groups"
|
||||
|
||||
@impl Mix.Task
|
||||
def run(_) do
|
||||
Mix.shell().info("\nAvailable tasks:")
|
||||
shell_info("\nAvailable tasks:")
|
||||
Tasks.Help.run(["--search", "mobilizon.groups."])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,12 +6,13 @@ defmodule Mix.Tasks.Mobilizon.Groups.Refresh do
|
|||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Federation.ActivityPub.Refresher
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
|
||||
@shortdoc "Refresh a group private informations from an account member"
|
||||
|
||||
@impl Mix.Task
|
||||
def run([group_url, on_behalf_of]) do
|
||||
Mix.Task.run("app.start")
|
||||
start_mobilizon()
|
||||
|
||||
with %Actor{} = actor <- Actors.get_local_actor_by_name(on_behalf_of) do
|
||||
res = Refresher.fetch_group(group_url, actor)
|
||||
|
@ -20,7 +21,7 @@ defmodule Mix.Tasks.Mobilizon.Groups.Refresh do
|
|||
end
|
||||
|
||||
def run(_) do
|
||||
Mix.raise(
|
||||
shell_error(
|
||||
"mobilizon.groups.refresh requires a group URL and an actor username which is member of the group as arguments"
|
||||
)
|
||||
end
|
||||
|
|
|
@ -29,7 +29,7 @@ defmodule Mix.Tasks.Mobilizon.Instance do
|
|||
|
||||
use Mix.Task
|
||||
|
||||
alias Mix.Tasks.Mobilizon.Common
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
|
||||
@preferred_cli_env "prod"
|
||||
|
||||
|
@ -70,7 +70,7 @@ defmodule Mix.Tasks.Mobilizon.Instance do
|
|||
if proceed? do
|
||||
[domain, port | _] =
|
||||
String.split(
|
||||
Common.get_option(
|
||||
get_option(
|
||||
options,
|
||||
:domain,
|
||||
"What domain will your instance use? (e.g mobilizon.org)"
|
||||
|
@ -79,25 +79,24 @@ defmodule Mix.Tasks.Mobilizon.Instance do
|
|||
) ++ [443]
|
||||
|
||||
name =
|
||||
Common.get_option(
|
||||
get_option(
|
||||
options,
|
||||
:instance_name,
|
||||
"What is the name of your instance? (e.g. Mobilizon)"
|
||||
)
|
||||
|
||||
email =
|
||||
Common.get_option(
|
||||
get_option(
|
||||
options,
|
||||
:admin_email,
|
||||
"What's the address email will be send with?",
|
||||
"noreply@#{domain}"
|
||||
)
|
||||
|
||||
dbhost =
|
||||
Common.get_option(options, :dbhost, "What is the hostname of your database?", "localhost")
|
||||
dbhost = get_option(options, :dbhost, "What is the hostname of your database?", "localhost")
|
||||
|
||||
dbname =
|
||||
Common.get_option(
|
||||
get_option(
|
||||
options,
|
||||
:dbname,
|
||||
"What is the name of your database?",
|
||||
|
@ -105,7 +104,7 @@ defmodule Mix.Tasks.Mobilizon.Instance do
|
|||
)
|
||||
|
||||
dbuser =
|
||||
Common.get_option(
|
||||
get_option(
|
||||
options,
|
||||
:dbuser,
|
||||
"What is the user used to connect to your database?",
|
||||
|
@ -113,7 +112,7 @@ defmodule Mix.Tasks.Mobilizon.Instance do
|
|||
)
|
||||
|
||||
dbpass =
|
||||
Common.get_option(
|
||||
get_option(
|
||||
options,
|
||||
:dbpass,
|
||||
"What is the password used to connect to your database?",
|
||||
|
@ -122,7 +121,7 @@ defmodule Mix.Tasks.Mobilizon.Instance do
|
|||
)
|
||||
|
||||
listen_port =
|
||||
Common.get_option(
|
||||
get_option(
|
||||
options,
|
||||
:listen_port,
|
||||
"What port will the app listen to (leave it if you are using the default setup with nginx)?",
|
||||
|
@ -160,24 +159,24 @@ defmodule Mix.Tasks.Mobilizon.Instance do
|
|||
database_password: dbpass
|
||||
)
|
||||
|
||||
Mix.shell().info("Writing config to #{config_path}.")
|
||||
shell_info("Writing config to #{config_path}.")
|
||||
|
||||
File.write(config_path, result_config)
|
||||
Mix.shell().info("Writing #{psql_path}.")
|
||||
shell_info("Writing #{psql_path}.")
|
||||
File.write(psql_path, result_psql)
|
||||
|
||||
Mix.shell().info(
|
||||
shell_info(
|
||||
"\n" <>
|
||||
"""
|
||||
To get started:
|
||||
1. Check the contents of the generated files.
|
||||
2. Run `sudo -u postgres psql -f #{Common.escape_sh_path(psql_path)} && rm #{
|
||||
Common.escape_sh_path(psql_path)
|
||||
2. Run `sudo -u postgres psql -f #{escape_sh_path(psql_path)} && rm #{
|
||||
escape_sh_path(psql_path)
|
||||
}`.
|
||||
"""
|
||||
)
|
||||
else
|
||||
Mix.shell().error(
|
||||
shell_error(
|
||||
"The task would have overwritten the following files:\n" <>
|
||||
(will_overwrite |> Enum.map(&"- #{&1}\n") |> Enum.join("")) <>
|
||||
"Rerun with `-f/--force` to overwrite them."
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
defmodule Mix.Tasks.Mobilizon.MoveParticipantStats do
|
||||
@moduledoc """
|
||||
Temporary task to move participant stats in the events table
|
||||
|
||||
This task will be removed in version 1.0.0-beta.3
|
||||
"""
|
||||
|
||||
use Mix.Task
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
alias Mobilizon.Events
|
||||
alias Mobilizon.Events.Event
|
||||
alias Mobilizon.Events.ParticipantRole
|
||||
alias Mobilizon.Storage.Repo
|
||||
|
||||
require Logger
|
||||
|
||||
@shortdoc "Move participant stats to events table"
|
||||
def run([]) do
|
||||
Mix.Task.run("app.start")
|
||||
|
||||
events =
|
||||
Event
|
||||
|> preload([e], :tags)
|
||||
|> Repo.all()
|
||||
|
||||
nb_events = length(events)
|
||||
|
||||
IO.puts(
|
||||
"\nStarting inserting participants stats into #{nb_events} events, this can take a while…\n"
|
||||
)
|
||||
|
||||
insert_participants_stats_into_events(events, nb_events)
|
||||
end
|
||||
|
||||
defp insert_participants_stats_into_events([%Event{url: url} = event | events], nb_events) do
|
||||
with roles <- ParticipantRole.__enum_map__(),
|
||||
counts <-
|
||||
Enum.reduce(roles, %{}, fn role, acc ->
|
||||
Map.put(acc, role, count_participants(event, role))
|
||||
end),
|
||||
{:ok, _} <-
|
||||
Events.update_event(event, %{
|
||||
participant_stats: counts
|
||||
}) do
|
||||
Logger.debug("Added participants stats to event #{url}")
|
||||
else
|
||||
{:error, res} ->
|
||||
Logger.error("Error while adding participants stats to event #{url} : #{inspect(res)}")
|
||||
end
|
||||
|
||||
ProgressBar.render(nb_events - length(events), nb_events)
|
||||
|
||||
insert_participants_stats_into_events(events, nb_events)
|
||||
end
|
||||
|
||||
defp insert_participants_stats_into_events([], nb_events) do
|
||||
IO.puts("\nFinished inserting participant stats for #{nb_events} events!\n")
|
||||
end
|
||||
|
||||
defp count_participants(%Event{id: event_id}, role) when is_atom(role) do
|
||||
event_id
|
||||
|> Events.count_participants_query()
|
||||
|> Events.filter_role(role)
|
||||
|> Repo.aggregate(:count, :id)
|
||||
end
|
||||
end
|
|
@ -22,60 +22,19 @@ defmodule Mix.Tasks.Mobilizon.Relay do
|
|||
|
||||
use Mix.Task
|
||||
|
||||
alias Mix.Tasks.Mobilizon.Common
|
||||
|
||||
alias Mobilizon.Federation.ActivityPub.Relay
|
||||
alias Mix.Tasks
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
|
||||
@shortdoc "Manages remote relays"
|
||||
def run(["follow", target]) do
|
||||
Common.start_mobilizon()
|
||||
|
||||
case Relay.follow(target) do
|
||||
{:ok, _activity, _follow} ->
|
||||
# put this task to sleep to allow the genserver to push out the messages
|
||||
:timer.sleep(500)
|
||||
@impl Mix.Task
|
||||
def run(_) do
|
||||
shell_info("\nAvailable tasks:")
|
||||
|
||||
{:error, e} ->
|
||||
IO.puts(:stderr, "Error while following #{target}: #{inspect(e)}")
|
||||
end
|
||||
end
|
||||
|
||||
def run(["unfollow", target]) do
|
||||
Common.start_mobilizon()
|
||||
|
||||
case Relay.unfollow(target) do
|
||||
{:ok, _activity, _follow} ->
|
||||
# put this task to sleep to allow the genserver to push out the messages
|
||||
:timer.sleep(500)
|
||||
|
||||
{:error, e} ->
|
||||
IO.puts(:stderr, "Error while unfollowing #{target}: #{inspect(e)}")
|
||||
end
|
||||
end
|
||||
|
||||
def run(["accept", target]) do
|
||||
Common.start_mobilizon()
|
||||
|
||||
case Relay.accept(target) do
|
||||
{:ok, _activity} ->
|
||||
# put this task to sleep to allow the genserver to push out the messages
|
||||
:timer.sleep(500)
|
||||
|
||||
{:error, e} ->
|
||||
IO.puts(:stderr, "Error while accept #{target} follow: #{inspect(e)}")
|
||||
end
|
||||
end
|
||||
|
||||
def run(["refresh", target]) do
|
||||
Common.start_mobilizon()
|
||||
IO.puts("Refreshing #{target}, this can take a while.")
|
||||
|
||||
case Relay.refresh(target) do
|
||||
:ok ->
|
||||
IO.puts("Refreshed #{target}")
|
||||
|
||||
err ->
|
||||
IO.puts(:stderr, "Error while refreshing #{target}: #{inspect(err)}")
|
||||
if mix_shell?() do
|
||||
Tasks.Help.run(["--search", "mobilizon.relay."])
|
||||
else
|
||||
show_subtasks_for_module(__MODULE__)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
28
lib/mix/tasks/mobilizon/relay/accept.ex
Normal file
28
lib/mix/tasks/mobilizon/relay/accept.ex
Normal file
|
@ -0,0 +1,28 @@
|
|||
defmodule Mix.Tasks.Mobilizon.Relay.Accept do
|
||||
@moduledoc """
|
||||
Task to accept an instance follow request
|
||||
"""
|
||||
use Mix.Task
|
||||
alias Mobilizon.Federation.ActivityPub.Relay
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
|
||||
@shortdoc "Accept an instance follow request"
|
||||
|
||||
@impl Mix.Task
|
||||
def run([target]) do
|
||||
start_mobilizon()
|
||||
|
||||
case Relay.accept(target) do
|
||||
{:ok, _activity} ->
|
||||
# put this task to sleep to allow the genserver to push out the messages
|
||||
:timer.sleep(500)
|
||||
|
||||
{:error, e} ->
|
||||
IO.puts(:stderr, "Error while accept #{target} follow: #{inspect(e)}")
|
||||
end
|
||||
end
|
||||
|
||||
def run(_) do
|
||||
shell_error("mobilizon.relay.accept requires an instance hostname as arguments")
|
||||
end
|
||||
end
|
28
lib/mix/tasks/mobilizon/relay/follow.ex
Normal file
28
lib/mix/tasks/mobilizon/relay/follow.ex
Normal file
|
@ -0,0 +1,28 @@
|
|||
defmodule Mix.Tasks.Mobilizon.Relay.Follow do
|
||||
@moduledoc """
|
||||
Task to follow an instance
|
||||
"""
|
||||
use Mix.Task
|
||||
alias Mobilizon.Federation.ActivityPub.Relay
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
|
||||
@shortdoc "Follow an instance"
|
||||
|
||||
@impl Mix.Task
|
||||
def run([target]) do
|
||||
start_mobilizon()
|
||||
|
||||
case Relay.follow(target) do
|
||||
{:ok, _activity, _follow} ->
|
||||
# put this task to sleep to allow the genserver to push out the messages
|
||||
:timer.sleep(500)
|
||||
|
||||
{:error, e} ->
|
||||
IO.puts(:stderr, "Error while following #{target}: #{inspect(e)}")
|
||||
end
|
||||
end
|
||||
|
||||
def run(_) do
|
||||
shell_error("mobilizon.relay.follow requires an instance hostname as arguments")
|
||||
end
|
||||
end
|
28
lib/mix/tasks/mobilizon/relay/refresh.ex
Normal file
28
lib/mix/tasks/mobilizon/relay/refresh.ex
Normal file
|
@ -0,0 +1,28 @@
|
|||
defmodule Mix.Tasks.Mobilizon.Relay.Refresh do
|
||||
@moduledoc """
|
||||
Task to refresh an instance details
|
||||
"""
|
||||
use Mix.Task
|
||||
alias Mobilizon.Federation.ActivityPub.Relay
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
|
||||
@shortdoc "Refresh an instance informations and crawl their outbox"
|
||||
|
||||
@impl Mix.Task
|
||||
def run([target]) do
|
||||
start_mobilizon()
|
||||
IO.puts("Refreshing #{target}, this can take a while.")
|
||||
|
||||
case Relay.refresh(target) do
|
||||
:ok ->
|
||||
IO.puts("Refreshed #{target}")
|
||||
|
||||
err ->
|
||||
IO.puts(:stderr, "Error while refreshing #{target}: #{inspect(err)}")
|
||||
end
|
||||
end
|
||||
|
||||
def run(_) do
|
||||
shell_error("mobilizon.relay.refresh requires an instance hostname as arguments")
|
||||
end
|
||||
end
|
28
lib/mix/tasks/mobilizon/relay/unfollow.ex
Normal file
28
lib/mix/tasks/mobilizon/relay/unfollow.ex
Normal file
|
@ -0,0 +1,28 @@
|
|||
defmodule Mix.Tasks.Mobilizon.Relay.Unfollow do
|
||||
@moduledoc """
|
||||
Task to unfollow an instance
|
||||
"""
|
||||
use Mix.Task
|
||||
alias Mobilizon.Federation.ActivityPub.Relay
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
|
||||
@shortdoc "Unfollow an instance"
|
||||
|
||||
@impl Mix.Task
|
||||
def run([target]) do
|
||||
start_mobilizon()
|
||||
|
||||
case Relay.unfollow(target) do
|
||||
{:ok, _activity, _follow} ->
|
||||
# put this task to sleep to allow the genserver to push out the messages
|
||||
:timer.sleep(500)
|
||||
|
||||
{:error, e} ->
|
||||
IO.puts(:stderr, "Error while unfollowing #{target}: #{inspect(e)}")
|
||||
end
|
||||
end
|
||||
|
||||
def run(_) do
|
||||
shell_error("mobilizon.relay.unfollow requires an instance hostname as arguments")
|
||||
end
|
||||
end
|
|
@ -1,50 +0,0 @@
|
|||
defmodule Mix.Tasks.Mobilizon.SetupSearch do
|
||||
@moduledoc """
|
||||
Temporary task to insert search data from existing events
|
||||
|
||||
This task will be removed in version 1.0.0-beta.3
|
||||
"""
|
||||
|
||||
use Mix.Task
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
alias Mobilizon.Events.Event
|
||||
alias Mobilizon.Service.Workers
|
||||
alias Mobilizon.Storage.Repo
|
||||
|
||||
require Logger
|
||||
|
||||
@shortdoc "Insert search data"
|
||||
def run([]) do
|
||||
Mix.Task.run("app.start")
|
||||
|
||||
events =
|
||||
Event
|
||||
|> preload([e], :tags)
|
||||
|> Repo.all()
|
||||
|
||||
nb_events = length(events)
|
||||
|
||||
IO.puts("\nStarting setting up search for #{nb_events} events, this can take a while…\n")
|
||||
insert_search_event(events, nb_events)
|
||||
end
|
||||
|
||||
defp insert_search_event([%Event{url: url} = event | events], nb_events) do
|
||||
case Workers.BuildSearch.insert_search_event(event) do
|
||||
{:ok, _} ->
|
||||
Logger.debug("Added event #{url} to the search")
|
||||
|
||||
{:error, res} ->
|
||||
Logger.error("Error while adding event #{url} to the search: #{inspect(res)}")
|
||||
end
|
||||
|
||||
ProgressBar.render(nb_events - length(events), nb_events)
|
||||
|
||||
insert_search_event(events, nb_events)
|
||||
end
|
||||
|
||||
defp insert_search_event([], nb_events) do
|
||||
IO.puts("\nFinished setting up search for #{nb_events} events!\n")
|
||||
end
|
||||
end
|
|
@ -4,7 +4,7 @@ defmodule Mix.Tasks.Mobilizon.SiteMap do
|
|||
"""
|
||||
use Mix.Task
|
||||
|
||||
alias Mix.Tasks.Mobilizon.Common
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
alias Mobilizon.Service.SiteMap
|
||||
alias Mobilizon.Web.Endpoint
|
||||
|
||||
|
@ -12,10 +12,10 @@ defmodule Mix.Tasks.Mobilizon.SiteMap do
|
|||
|
||||
@shortdoc "Generates a new Sitemap"
|
||||
def run(["generate"]) do
|
||||
Common.start_mobilizon()
|
||||
start_mobilizon()
|
||||
|
||||
with {:ok, :ok} <- SiteMap.generate_sitemap() do
|
||||
Mix.shell().info("Sitemap saved to #{Endpoint.url()}/sitemap.xml")
|
||||
shell_info("Sitemap saved to #{Endpoint.url()}/sitemap.xml")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
defmodule Mix.Tasks.Mobilizon.Toot do
|
||||
@moduledoc """
|
||||
Creates a bot from a source.
|
||||
"""
|
||||
|
||||
use Mix.Task
|
||||
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.Actor
|
||||
|
||||
alias Mobilizon.GraphQL.API.Comments
|
||||
|
||||
require Logger
|
||||
|
||||
@shortdoc "Toot to an user"
|
||||
def run([from, text]) do
|
||||
Mix.Task.run("app.start")
|
||||
|
||||
with {:local_actor, %Actor{} = actor} <- {:local_actor, Actors.get_local_actor_by_name(from)},
|
||||
{:ok, _, _} <- Comments.create_comment(%{actor: actor, text: text}) do
|
||||
Mix.shell().info("Tooted")
|
||||
else
|
||||
{:local_actor, _, _} ->
|
||||
Mix.shell().error("Failed to toot.\nActor #{from} doesn't exist")
|
||||
|
||||
_ ->
|
||||
Mix.shell().error("Failed to toot.")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,12 +6,18 @@ defmodule Mix.Tasks.Mobilizon.Users do
|
|||
use Mix.Task
|
||||
|
||||
alias Mix.Tasks
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
|
||||
@shortdoc "Manages Mobilizon users"
|
||||
|
||||
@impl Mix.Task
|
||||
def run(_) do
|
||||
Mix.shell().info("\nAvailable tasks:")
|
||||
Tasks.Help.run(["--search", "mobilizon.users."])
|
||||
shell_info("\nAvailable tasks:")
|
||||
|
||||
if mix_shell?() do
|
||||
Tasks.Help.run(["--search", "mobilizon.users."])
|
||||
else
|
||||
show_subtasks_for_module(__MODULE__)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ defmodule Mix.Tasks.Mobilizon.Users.Delete do
|
|||
use Mix.Task
|
||||
alias Mobilizon.Users
|
||||
alias Mobilizon.Users.User
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
|
||||
@shortdoc "Deletes a Mobilizon user"
|
||||
|
||||
|
@ -26,25 +27,25 @@ defmodule Mix.Tasks.Mobilizon.Users.Delete do
|
|||
assume_yes? = Keyword.get(options, :assume_yes, false)
|
||||
keep_email? = Keyword.get(options, :keep_email, false)
|
||||
|
||||
Mix.Task.run("app.start")
|
||||
start_mobilizon()
|
||||
|
||||
with {:ok, %User{} = user} <- Users.get_user_by_email(email),
|
||||
true <- assume_yes? or Mix.shell().yes?("Continue with deleting user #{user.email}?"),
|
||||
true <- assume_yes? or shell_yes?("Continue with deleting user #{user.email}?"),
|
||||
{:ok, %User{} = user} <-
|
||||
Users.delete_user(user, reserve_email: keep_email?) do
|
||||
Mix.shell().info("""
|
||||
shell_info("""
|
||||
The user #{user.email} has been deleted
|
||||
""")
|
||||
else
|
||||
{:error, :user_not_found} ->
|
||||
Mix.raise("Error: No such user")
|
||||
shell_error("Error: No such user")
|
||||
|
||||
_ ->
|
||||
Mix.raise("User has not been deleted.")
|
||||
shell_error("User has not been deleted.")
|
||||
end
|
||||
end
|
||||
|
||||
def run(_) do
|
||||
Mix.raise("mobilizon.users.delete requires an email as argument")
|
||||
shell_error("mobilizon.users.delete requires an email as argument")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,6 +3,7 @@ defmodule Mix.Tasks.Mobilizon.Users.Modify do
|
|||
Task to modify an existing Mobilizon user
|
||||
"""
|
||||
use Mix.Task
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
alias Mobilizon.Users
|
||||
alias Mobilizon.Users.User
|
||||
|
||||
|
@ -31,10 +32,10 @@ defmodule Mix.Tasks.Mobilizon.Users.Modify do
|
|||
new_email = Keyword.get(options, :email)
|
||||
|
||||
if disable? && enable? do
|
||||
Mix.raise("Can't use both --enabled and --disable options at the same time.")
|
||||
shell_error("Can't use both --enabled and --disable options at the same time.")
|
||||
end
|
||||
|
||||
Mix.Task.run("app.start")
|
||||
start_mobilizon()
|
||||
|
||||
with {:ok, %User{} = user} <- Users.get_user_by_email(email),
|
||||
attrs <- %{},
|
||||
|
@ -53,7 +54,7 @@ defmodule Mix.Tasks.Mobilizon.Users.Modify do
|
|||
),
|
||||
{:makes_changes, true} <- {:makes_changes, attrs != %{}},
|
||||
{:ok, %User{} = user} <- Users.update_user(user, attrs) do
|
||||
Mix.shell().info("""
|
||||
shell_info("""
|
||||
An user has been modified with the following information:
|
||||
- email: #{user.email}
|
||||
- Role: #{user.role}
|
||||
|
@ -61,23 +62,23 @@ defmodule Mix.Tasks.Mobilizon.Users.Modify do
|
|||
""")
|
||||
else
|
||||
{:makes_changes, false} ->
|
||||
Mix.shell().info("No change has been made")
|
||||
shell_info("No change has been made")
|
||||
|
||||
{:error, :user_not_found} ->
|
||||
Mix.raise("Error: No such user")
|
||||
shell_error("Error: No such user")
|
||||
|
||||
{:error, %Ecto.Changeset{errors: errors}} ->
|
||||
Mix.shell().error(inspect(errors))
|
||||
Mix.raise("User has not been modified because of the above reason.")
|
||||
shell_error(inspect(errors))
|
||||
shell_error("User has not been modified because of the above reason.")
|
||||
|
||||
err ->
|
||||
Mix.shell().error(inspect(err))
|
||||
Mix.raise("User has not been modified because of an unknown reason.")
|
||||
shell_error(inspect(err))
|
||||
shell_error("User has not been modified because of an unknown reason.")
|
||||
end
|
||||
end
|
||||
|
||||
def run(_) do
|
||||
Mix.raise("mobilizon.users.new requires an email as argument")
|
||||
shell_error("mobilizon.users.new requires an email as argument")
|
||||
end
|
||||
|
||||
@spec process_new_value(map(), atom(), any(), any()) :: map()
|
||||
|
|
|
@ -3,6 +3,7 @@ defmodule Mix.Tasks.Mobilizon.Users.New do
|
|||
Task to create a new user
|
||||
"""
|
||||
use Mix.Task
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
alias Mobilizon.Users
|
||||
alias Mobilizon.Users.User
|
||||
|
||||
|
@ -40,7 +41,7 @@ defmodule Mix.Tasks.Mobilizon.Users.New do
|
|||
:crypto.strong_rand_bytes(16) |> Base.encode64() |> binary_part(0, 16)
|
||||
)
|
||||
|
||||
Mix.Task.run("app.start")
|
||||
start_mobilizon()
|
||||
|
||||
case Users.register(%{
|
||||
email: email,
|
||||
|
@ -51,7 +52,7 @@ defmodule Mix.Tasks.Mobilizon.Users.New do
|
|||
confirmation_token: nil
|
||||
}) do
|
||||
{:ok, %User{} = user} ->
|
||||
Mix.shell().info("""
|
||||
shell_info("""
|
||||
An user has been created with the following information:
|
||||
- email: #{user.email}
|
||||
- password: #{password}
|
||||
|
@ -60,16 +61,16 @@ defmodule Mix.Tasks.Mobilizon.Users.New do
|
|||
""")
|
||||
|
||||
{:error, %Ecto.Changeset{errors: errors}} ->
|
||||
Mix.shell().error(inspect(errors))
|
||||
Mix.raise("User has not been created because of the above reason.")
|
||||
shell_error(inspect(errors))
|
||||
shell_error("User has not been created because of the above reason.")
|
||||
|
||||
err ->
|
||||
Mix.shell().error(inspect(err))
|
||||
Mix.raise("User has not been created because of an unknown reason.")
|
||||
shell_error(inspect(err))
|
||||
shell_error("User has not been created because of an unknown reason.")
|
||||
end
|
||||
end
|
||||
|
||||
def run(_) do
|
||||
Mix.raise("mobilizon.users.new requires an email as argument")
|
||||
shell_error("mobilizon.users.new requires an email as argument")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ defmodule Mix.Tasks.Mobilizon.Users.Show do
|
|||
"""
|
||||
|
||||
use Mix.Task
|
||||
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Users
|
||||
alias Mobilizon.Users.User
|
||||
|
@ -13,11 +13,11 @@ defmodule Mix.Tasks.Mobilizon.Users.Show do
|
|||
|
||||
@impl Mix.Task
|
||||
def run([email]) do
|
||||
Mix.Task.run("app.start")
|
||||
start_mobilizon()
|
||||
|
||||
with {:ok, %User{} = user} <- Users.get_user_by_email(email),
|
||||
actors <- Users.get_actors_for_user(user) do
|
||||
Mix.shell().info("""
|
||||
shell_info("""
|
||||
Informations for the user #{user.email}:
|
||||
- Activated: #{user.confirmed_at}
|
||||
- Disabled: #{user.disabled}
|
||||
|
@ -26,12 +26,12 @@ defmodule Mix.Tasks.Mobilizon.Users.Show do
|
|||
""")
|
||||
else
|
||||
{:error, :user_not_found} ->
|
||||
Mix.raise("Error: No such user")
|
||||
shell_error("Error: No such user")
|
||||
end
|
||||
end
|
||||
|
||||
def run(_) do
|
||||
Mix.raise("mobilizon.users.show requires an email as argument")
|
||||
shell_error("mobilizon.users.show requires an email as argument")
|
||||
end
|
||||
|
||||
defp display_actors([]), do: ""
|
||||
|
|
|
@ -1,11 +1,53 @@
|
|||
# Portions of this file are derived from Pleroma:
|
||||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mobilizon.CLI do
|
||||
@app :mobilizon
|
||||
@moduledoc """
|
||||
CLI wrapper for releases
|
||||
"""
|
||||
alias Mix.Tasks.Mobilizon.Ecto.{Migrate, Rollback}
|
||||
|
||||
def migrate do
|
||||
Application.load(@app)
|
||||
def run(args) do
|
||||
[task | args] = String.split(args)
|
||||
|
||||
for repo <- Application.fetch_env!(@app, :ecto_repos) do
|
||||
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
|
||||
case task do
|
||||
"migrate" -> migrate(args)
|
||||
"rollback" -> rollback(args)
|
||||
task -> mix_task(task, args)
|
||||
end
|
||||
end
|
||||
|
||||
defp mix_task(task, args) do
|
||||
Application.load(:mobilizon)
|
||||
{:ok, modules} = :application.get_key(:mobilizon, :modules)
|
||||
|
||||
module =
|
||||
Enum.find(modules, fn module ->
|
||||
module = Module.split(module)
|
||||
|
||||
case module do
|
||||
["Mix", "Tasks", "Mobilizon" | rest] ->
|
||||
String.downcase(Enum.join(rest, ".")) == task
|
||||
|
||||
_ ->
|
||||
false
|
||||
end
|
||||
end)
|
||||
|
||||
if module do
|
||||
module.run(args)
|
||||
else
|
||||
IO.puts("The task #{task} does not exist")
|
||||
end
|
||||
end
|
||||
|
||||
def migrate(args) do
|
||||
Migrate.run(args)
|
||||
end
|
||||
|
||||
def rollback(args) do
|
||||
Rollback.run(args)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -48,7 +48,9 @@ defmodule Mix.Tasks.Mobilizon.ActorsTest do
|
|||
end
|
||||
|
||||
test "show non-existing actor" do
|
||||
assert_raise Mix.Error, "Error: No such actor", fn -> Show.run([@username]) end
|
||||
Show.run([@username])
|
||||
assert_received {:mix_shell, :error, [message]}
|
||||
assert message =~ "Error: No such actor"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,6 +9,7 @@ defmodule Mix.Tasks.Mobilizon.RelayTest do
|
|||
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.{Actor, Follower}
|
||||
alias Mix.Tasks.Mobilizon.Relay.{Follow, Unfollow}
|
||||
|
||||
alias Mobilizon.Federation.ActivityPub.Relay
|
||||
|
||||
|
@ -17,7 +18,7 @@ defmodule Mix.Tasks.Mobilizon.RelayTest do
|
|||
use_cassette "relay/fetch_relay_follow" do
|
||||
target_instance = "mobilizon1.com"
|
||||
|
||||
Mix.Tasks.Mobilizon.Relay.run(["follow", target_instance])
|
||||
Follow.run([target_instance])
|
||||
|
||||
local_actor = Relay.get_actor()
|
||||
assert local_actor.url =~ "/relay"
|
||||
|
@ -35,7 +36,7 @@ defmodule Mix.Tasks.Mobilizon.RelayTest do
|
|||
use_cassette "relay/fetch_relay_unfollow" do
|
||||
target_instance = "mobilizon1.com"
|
||||
|
||||
Mix.Tasks.Mobilizon.Relay.run(["follow", target_instance])
|
||||
Follow.run([target_instance])
|
||||
|
||||
%Actor{} = local_actor = Relay.get_actor()
|
||||
|
||||
|
@ -44,7 +45,7 @@ defmodule Mix.Tasks.Mobilizon.RelayTest do
|
|||
|
||||
assert %Follower{} = Actors.is_following(local_actor, target_actor)
|
||||
|
||||
Mix.Tasks.Mobilizon.Relay.run(["unfollow", target_instance])
|
||||
Unfollow.run([target_instance])
|
||||
|
||||
refute Actors.is_following(local_actor, target_actor)
|
||||
end
|
||||
|
|
|
@ -42,9 +42,15 @@ defmodule Mix.Tasks.Mobilizon.UsersTest do
|
|||
test "create with already used email" do
|
||||
insert(:user, email: @email)
|
||||
|
||||
assert_raise Mix.Error, "User has not been created because of the above reason.", fn ->
|
||||
New.run([@email])
|
||||
end
|
||||
New.run([@email])
|
||||
# Debug message
|
||||
assert_received {:mix_shell, :error, [message]}
|
||||
|
||||
assert message =~
|
||||
"[email: {\"This email is already used.\", [constraint: :unique, constraint_name: \"users_email_index\"]}]"
|
||||
|
||||
assert_received {:mix_shell, :error, [message]}
|
||||
assert message =~ "User has not been created because of the above reason."
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -62,7 +68,9 @@ defmodule Mix.Tasks.Mobilizon.UsersTest do
|
|||
end
|
||||
|
||||
test "delete non-existing user" do
|
||||
assert_raise Mix.Error, "Error: No such user", fn -> Delete.run([@email, "-y"]) end
|
||||
Delete.run([@email, "-y"])
|
||||
assert_received {:mix_shell, :error, [message]}
|
||||
assert message =~ "Error: No such user"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -87,7 +95,9 @@ defmodule Mix.Tasks.Mobilizon.UsersTest do
|
|||
end
|
||||
|
||||
test "show non-existing user" do
|
||||
assert_raise Mix.Error, "Error: No such user", fn -> Show.run([@email]) end
|
||||
Show.run([@email])
|
||||
assert_received {:mix_shell, :error, [message]}
|
||||
assert message =~ "Error: No such user"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -160,11 +170,9 @@ defmodule Mix.Tasks.Mobilizon.UsersTest do
|
|||
end
|
||||
|
||||
test "enable and disable at the same time" do
|
||||
assert_raise Mix.Error,
|
||||
"Can't use both --enabled and --disable options at the same time.",
|
||||
fn ->
|
||||
Modify.run([@email, "--disable", "--enable"])
|
||||
end
|
||||
Modify.run([@email, "--disable", "--enable"])
|
||||
assert_received {:mix_shell, :error, [message]}
|
||||
assert message =~ "Can't use both --enabled and --disable options at the same time."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue