Page MenuHomePhorge

No OneTemporary

Size
11 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/mix/tasks/pleroma/frontend.ex b/lib/mix/tasks/pleroma/frontend.ex
index 7ddd9360a..865daf3bb 100644
--- a/lib/mix/tasks/pleroma/frontend.ex
+++ b/lib/mix/tasks/pleroma/frontend.ex
@@ -1,265 +1,264 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mix.Tasks.Pleroma.Frontend do
use Mix.Task
import Mix.Pleroma
@shortdoc "Manages bundled Pleroma frontends"
@moduledoc File.read!("docs/administration/CLI_tasks/frontend.md")
@frontends %{
"admin" => %{"project" => "pleroma/admin-fe"},
"kenoma" => %{"project" => "lambadalambda/kenoma"},
"mastodon" => %{"project" => "pleroma/mastofe"},
"pleroma" => %{"project" => "pleroma/pleroma-fe"},
"fedi" => %{"project" => "dockyard/fedi-fe"}
}
@known_frontends Map.keys(@frontends)
@ref_local "__local__"
@ref_develop "__develop__"
@ref_stable "__stable__"
@pleroma_gitlab_host "git.pleroma.social"
def run(["install", "none" | _args]) do
shell_info("Skipping frontend installation because none was requested")
"none"
end
def run(["install", "all"]) do
{:ok, _} = Application.ensure_all_started(:pleroma)
configs = Pleroma.Config.get(:frontends, %{})
- with config <- configs[:primary],
- frontend <- config["name"],
+ with config when not is_nil(config) <- configs[:primary],
ref when ref != "none" <- config["ref"] do
- run(["install", frontend, "--ref", ref])
+ run(["install", config["name"], "--ref", ref])
end
- with config <- configs[:mastodon],
+ with config when not is_nil(config) <- configs[:mastodon],
ref when ref != "none" <- config["ref"] do
run(["install", "mastodon", "--ref", ref])
end
- with config <- configs[:admin],
+ with config when not is_nil(config) <- configs[:admin],
ref when ref != "none" <- config["ref"] do
run(["install", "admin", "--ref", ref])
end
end
def run(["install", unknown_fe | _args]) when unknown_fe not in @known_frontends do
shell_error(
"Frontend \"#{unknown_fe}\" is not known. Known frontends are: #{
Enum.join(@known_frontends, ", ")
}"
)
end
def run(["install", frontend | args]) do
log_level = Logger.level()
Logger.configure(level: :warn)
{:ok, _} = Application.ensure_all_started(:pleroma)
{options, [], []} =
OptionParser.parse(
args,
strict: [
ref: :string,
path: :string,
develop: :boolean,
static_dir: :string
]
)
instance_static_dir =
with nil <- options[:static_dir] do
Pleroma.Config.get!([:instance, :static_dir])
end
ref =
case options[:path] do
nil ->
ref0 =
cond do
options[:ref] -> options[:ref]
options[:develop] -> @ref_develop
true -> @ref_stable
end
web_frontend_ref(frontend, ref0)
path ->
local_path_frontend_ref(path)
end
dest =
Path.join([
instance_static_dir,
"frontends",
frontend,
ref
])
fe_label = "#{frontend} (#{ref})"
from =
with nil <- options[:path] do
Pleroma.Utils.command_required!("yarn")
url = archive_url(frontend, ref)
tmp_dir = Path.join(dest, "tmp/src")
shell_info("Downloading #{fe_label} to #{tmp_dir}")
:ok = download_frontend(url, tmp_dir)
shell_info("Building #{fe_label} (this will take some time)")
:ok = build_frontend(frontend, tmp_dir)
tmp_dir
end
shell_info("Installing #{fe_label} to #{dest}")
:ok = install_frontend(frontend, from, dest)
shell_info("Frontend #{fe_label} installed to #{dest}")
Logger.configure(level: log_level)
ref
end
defp download_frontend(url, dest) do
with {:ok, %{status: 200, body: zip_body}} <-
Pleroma.HTTP.get(url, [], timeout: 120_000, recv_timeout: 120_000),
{:ok, unzipped} <- :zip.unzip(zip_body, [:memory]) do
File.rm_rf!(dest)
File.mkdir_p!(dest)
Enum.each(unzipped, fn {filename, data} ->
[_root | paths] = Path.split(filename)
path = Enum.join(paths, "/")
new_file_path = Path.join(dest, path)
new_file_path
|> Path.dirname()
|> File.mkdir_p!()
File.write!(new_file_path, data)
end)
else
{:ok, %{status: 404}} ->
{:error, "Bundle not found"}
false ->
{:error, "Zip archive must contain \"dist\" folder"}
error ->
{:error, error}
end
end
defp build_frontend("admin", path) do
yarn = Pleroma.Config.get(:yarn, "yarn")
{_out, 0} = System.cmd(yarn, [], cd: path)
{_out, 0} = System.cmd(yarn, ["build:prod"], cd: path)
:ok
end
defp build_frontend(_frontend, path) do
yarn = Pleroma.Config.get(:yarn, "yarn")
{_out, 0} = System.cmd(yarn, [], cd: path)
{_out, 0} = System.cmd(yarn, ["build"], cd: path)
:ok
end
defp web_frontend_ref(frontend, @ref_develop) do
url = project_url(frontend) <> "/repository/branches"
{:ok, %{status: 200, body: body}} =
Pleroma.HTTP.get(url, [], timeout: 120_000, recv_timeout: 120_000)
json = Jason.decode!(body)
%{"commit" => %{"short_id" => last_commit_ref}} = Enum.find(json, & &1["default"])
last_commit_ref
end
# fallback to develop version if compatible stable ref is not defined in
# mix.exs for the given frontend
defp web_frontend_ref(frontend, @ref_stable) do
case Map.get(Pleroma.Application.frontends(), frontend) do
nil ->
web_frontend_ref(frontend, @ref_develop)
ref ->
ref
end
end
defp web_frontend_ref(_frontend, ref), do: ref
defp project_url(frontend),
do:
"https://#{@pleroma_gitlab_host}/api/v4/projects/#{
URI.encode_www_form(@frontends[frontend]["project"])
}"
defp archive_url(frontend, ref),
do: "https://#{@pleroma_gitlab_host}/#{@frontends[frontend]["project"]}/-/archive/#{ref}.zip"
defp local_path_frontend_ref(path) do
path
|> Path.join("package.json")
|> File.read()
|> case do
{:ok, bin} ->
bin
|> Jason.decode!()
|> Map.get("version", @ref_local)
_ ->
@ref_local
end
end
defp post_install("mastodon", path) do
File.rename!("#{path}/assets/sw.js", "#{path}/sw.js")
{:ok, files} = File.ls(path)
Enum.each(files, fn file ->
with false <- file in ~w(packs sw.js) do
[path, file]
|> Path.join()
|> File.rm_rf!()
end
end)
end
defp post_install(_frontend, _path) do
:ok
end
defp install_frontend(frontend, source, dest) do
from =
case frontend do
"mastodon" ->
"public"
"kenoma" ->
"build"
_ ->
"dist"
end
File.mkdir_p!(dest)
File.cp_r!(Path.join([source, from]), dest)
post_install(frontend, dest)
end
end
diff --git a/test/tasks/frontend_test.exs b/test/tasks/frontend_test.exs
index 6c67255e5..f2893b725 100644
--- a/test/tasks/frontend_test.exs
+++ b/test/tasks/frontend_test.exs
@@ -1,138 +1,145 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mix.Tasks.Pleroma.FrontendTest do
use ExUnit.Case
use Pleroma.Tests.Helpers
import Tesla.Mock, only: [mock_global: 1, json: 1]
@bundle_zip_path Path.absname("test/fixtures/tesla_mock/fe-bundle.zip")
@tmp "test/tmp"
@dir "#{@tmp}/instance_static"
setup_all do
Mix.shell(Mix.Shell.Process)
on_exit(fn ->
Mix.shell(Mix.Shell.IO)
end)
:ok
end
setup do
mock_global(fn
%{method: :get, url: "https://git.pleroma.social/api/v4/projects/" <> rest} ->
if String.ends_with?(rest, "repository/branches") do
"test/fixtures/tesla_mock/gitlab-api-pleroma-fe-branches.json"
else
"test/fixtures/tesla_mock/gitlab-api-pleroma-fe-releases.json"
end
|> Path.absname()
|> File.read!()
|> Jason.decode!()
|> json()
%{method: :get, url: _download_url} ->
%Tesla.Env{status: 200, body: File.read!(@bundle_zip_path)}
end)
File.mkdir_p!(@dir)
on_exit(fn -> File.rm_rf(@dir) end)
clear_config([:instance, :static_dir], @dir)
:ok
end
describe "Installations from local path" do
test "Frontends with standard dist structure" do
~w(pleroma kenoma admin)
|> Enum.each(fn frontend ->
path = "test/fixtures/frontends/#{frontend}"
Mix.Tasks.Pleroma.Frontend.run(~w(install #{frontend} --path #{path}))
assert File.exists?("#{@dir}/frontends/#{frontend}/42/index.html")
refute File.exists?("#{@dir}/frontends/#{frontend}/42/package.json")
end)
end
test "Mastodon" do
path = "test/fixtures/frontends/mastodon"
Mix.Tasks.Pleroma.Frontend.run(~w(install mastodon --path #{path}))
assert File.exists?("#{@dir}/frontends/mastodon/__local__/sw.js")
assert File.exists?("#{@dir}/frontends/mastodon/__local__/packs/locales.js")
refute File.exists?("#{@dir}/frontends/mastodon/__local__/unused_file")
refute File.exists?("#{@dir}/frontends/mastodon/__local__/unused_dir")
end
end
describe "Installation from web source" do
test "develop" do
if Pleroma.Utils.command_available?("yarn") do
Mix.Tasks.Pleroma.Frontend.run([
"install",
"pleroma",
"--develop"
])
assert File.exists?(Path.join([@dir, "frontends/pleroma/d5457c32/index.html"]))
end
end
test "stable" do
if Pleroma.Utils.command_available?("yarn") do
Mix.Tasks.Pleroma.Frontend.run(["install", "pleroma"])
assert File.exists?(Path.join([@dir, "frontends/pleroma/5d49edc8/index.html"]))
end
end
test "ref" do
if Pleroma.Utils.command_available?("yarn") do
Mix.Tasks.Pleroma.Frontend.run([
"install",
"pleroma",
"--ref",
"1.2.3"
])
assert File.exists?(Path.join([@dir, "frontends/pleroma/1.2.3/index.html"]))
end
end
end
describe "Install all" do
test "Normal config" do
config = [
primary: %{"name" => "pleroma", "ref" => "1.2.3"},
mastodon: %{"name" => "mastodon", "ref" => "2.3.4"},
admin: %{"name" => "admin", "ref" => "3.4.5"}
]
clear_config(:frontends, config)
Mix.Tasks.Pleroma.Frontend.run(["install", "all"])
assert File.exists?(Path.join([@dir, "frontends/pleroma/1.2.3/index.html"]))
assert File.exists?(Path.join([@dir, "frontends/mastodon/2.3.4/sw.js"]))
assert File.exists?(Path.join([@dir, "frontends/admin/3.4.5/index.html"]))
end
test "Unconfigured frontends" do
config = [
primary: %{"name" => "none", "ref" => "1.2.3"},
mastodon: %{"name" => "mastodon", "ref" => "none"},
admin: %{"name" => "admin", "ref" => "none"}
]
clear_config(:frontends, config)
Mix.Tasks.Pleroma.Frontend.run(["install", "all"])
assert {:ok, []} == File.ls(@dir)
end
+
+ test "Missing configs" do
+ clear_config(:frontends, [])
+ Mix.Tasks.Pleroma.Frontend.run(["install", "all"])
+
+ assert {:ok, []} == File.ls(@dir)
+ end
end
end

File Metadata

Mime Type
text/x-diff
Expires
Sun, Aug 30, 11:17 AM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1737938
Default Alt Text
(11 KB)

Event Timeline