Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85651063
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
11 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Aug 30, 11:17 AM (1 d, 21 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1737938
Default Alt Text
(11 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline
Log In to Comment