From 6ab7a40f92b1a715a45545db08bb5faccab3c974 Mon Sep 17 00:00:00 2001 From: Roman Chvanikov Date: Fri, 17 Jul 2020 23:29:26 +0300 Subject: refactor frontend task --- lib/mix/tasks/pleroma/frontend.ex | 223 +++++++++++++------------------------- 1 file changed, 73 insertions(+), 150 deletions(-) (limited to 'lib') diff --git a/lib/mix/tasks/pleroma/frontend.ex b/lib/mix/tasks/pleroma/frontend.ex index 658b981b2..c7de5d217 100644 --- a/lib/mix/tasks/pleroma/frontend.ex +++ b/lib/mix/tasks/pleroma/frontend.ex @@ -3,6 +3,32 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Mix.Tasks.Pleroma.Frontend do + @doc """ + Scenario 1: + - clone repo to /frontends/fe/_src_tmp + - build fe + - move built files into /frontends/fe + - remove frontends/fe/_src_tmp + + Scenario 2: + - download bundle from CI to /frontends/fe/_src_tmp + - move build files + - remove tmp + + Scenario 3: + - move built files from _path to /frontends/fe + + Pleroma: + /dist + Kenoma: + /build + Fedi: + /dist + Admin: + /dist + Mastodon + /public + """ use Mix.Task import Mix.Pleroma @@ -12,17 +38,15 @@ defmodule Mix.Tasks.Pleroma.Frontend do @shortdoc "Manages bundled Pleroma frontends" @moduledoc File.read!("docs/administration/CLI_tasks/frontend.md") - @pleroma_gitlab_host "git.pleroma.social" @frontends %{ "admin" => %{"project" => "pleroma/admin-fe"}, "kenoma" => %{"project" => "lambadalambda/kenoma"}, "mastodon" => %{"project" => "pleroma/mastofe"}, - "pleroma" => %{"project" => "pleroma/pleroma-fe"} + "pleroma" => %{"project" => "pleroma/pleroma-fe"}, + "fedi" => %{"project" => "dockyard/fedi-fe"} } @known_frontends Map.keys(@frontends) - @ref_stable "__stable__" - @ref_develop "__develop__" @ref_local "__local__" def run(["install", "none" | _args]) do @@ -52,175 +76,74 @@ defmodule Mix.Tasks.Pleroma.Frontend do ] ) - ref = - cond do - options[:ref] -> - options[:ref] - - options[:develop] -> - @ref_develop - - options[:path] -> - @ref_local - - true -> - @ref_stable - end - - %{"name" => bundle_name, "url" => bundle_url} = - case options[:path] do - nil -> - get_bundle_meta(ref, @frontends[frontend]["project"]) - - path -> - version = - path - |> File.read!() - |> Jason.decode!() - |> Map.get("version") - - %{"name" => version, "url" => {:local, path}} - end - - shell_info("Installing frontend #{frontend}, version: #{bundle_name}") + path = options[:path] + ref = local_path_frontend_ref(path) dest = Path.join([ Pleroma.Config.get!([:instance, :static_dir]), "frontends", frontend, - bundle_name + ref ]) - with :ok <- download_bundle(bundle_url, dest), - :ok <- install_bundle(frontend, dest) do - shell_info("Installed!") - else - {:error, error} -> - shell_error("Error: #{inspect(error)}") - end - - Logger.configure(level: log_level) - end - - defp get_bundle_meta(@ref_develop, project) do - url = "#{gitlab_api_url(project)}/repository/branches" - - %{status: 200, body: json} = Tesla.get!(http_client(), url) - - %{"name" => name, "commit" => %{"short_id" => last_commit_ref}} = - Enum.find(json, & &1["default"]) - - %{ - "name" => name, - "url" => build_url(project, last_commit_ref) - } - end + shell_info("Installing frontend #{frontend} (#{ref}) from local path") - defp get_bundle_meta(@ref_stable, project) do - url = "#{gitlab_api_url(project)}/releases" - %{status: 200, body: json} = Tesla.get!(http_client(), url) - - [%{"commit" => %{"short_id" => commit_id}, "name" => name} | _] = - Enum.sort(json, fn r1, r2 -> - {:ok, date1, _offset} = DateTime.from_iso8601(r1["created_at"]) - {:ok, date2, _offset} = DateTime.from_iso8601(r2["created_at"]) - DateTime.compare(date1, date2) != :lt - end) - - %{ - "name" => name, - "url" => build_url(project, commit_id) - } - end + install_bundle(frontend, path, dest) + shell_info("Frontend #{frontend} (#{ref}) installed to #{dest}") - defp get_bundle_meta(ref, project) do - %{ - "name" => ref, - "url" => build_url(project, ref) - } + Logger.configure(level: log_level) end - defp download_bundle({:local, _path}, _dir), do: :ok - - defp download_bundle(bundle_url, dir) do - http_client = http_client() - - with {:ok, %{status: 200, body: zip_body}} <- Tesla.get(http_client, bundle_url), - {:ok, unzipped} <- :zip.unzip(zip_body, [:memory]), - filtered = - Enum.filter(unzipped, fn - {[?d, ?i, ?s, ?t, ?/ | _rest], _data} -> true - _ -> false - end), - true <- length(filtered) > 0 do - File.rm_rf!(dir) - - Enum.each(unzipped, fn {[?d, ?i, ?s, ?t, ?/ | path], data} -> - file_path = Path.join(dir, path) - - file_path - |> Path.dirname() - |> File.mkdir_p!() - - File.write!(file_path, data) - end) - else - {:ok, %{status: 404}} -> - {:error, "Bundle not found"} - - false -> - {:error, "Zip archive must contain \"dist\" folder"} - - error -> - {:error, error} + 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 install_bundle("mastodon", base_path) do - File.ls!(base_path) |> IO.inspect() - required_paths = ["public/assets/sw.js", "public/packs"] - - with false <- Enum.all?(required_paths, &([base_path, &1] |> Path.join() |> File.exists?())) do - build_bundle!("mastodon", base_path) - end - - with :ok <- File.rename("#{base_path}/public/assets/sw.js", "#{base_path}/sw.js"), - :ok <- File.rename("#{base_path}/public/packs", "#{base_path}/packs"), - {:ok, _deleted_files} <- File.rm_rf("#{base_path}/public") do - :ok - else - error -> - {:error, error} - end - end + defp post_install("mastodon", path) do + File.rename!("#{path}/assets/sw.js", "#{path}/sw.js") - defp install_bundle(_fe_name, _base_path), do: :ok + {:ok, files} = File.ls(path) - defp build_bundle!("mastodon", base_path) do - Pleroma.Utils.command_required!("yarn") - {_out, 0} = System.cmd("yarn", ["install"], cd: base_path) - {_out, 0} = System.cmd("yarn", ["run", "build"], cd: base_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 build_bundle!(_frontend, base_path) do - Pleroma.Utils.command_required!("yarn") - {_out, 0} = System.cmd("yarn", [], cd: base_path) - {_out, 0} = System.cmd("npm", ["run", "build"], cd: base_path) + defp post_install(_frontend, _path) do + :ok end - defp gitlab_api_url(project), - do: "https://#{@pleroma_gitlab_host}/api/v4/projects/#{URI.encode_www_form(project)}" + defp install_bundle(frontend, source, dest) do + from = + case frontend do + "mastodon" -> + "public" - defp build_url(project, ref), - do: "https://#{@pleroma_gitlab_host}/#{project}/-/jobs/artifacts/#{ref}/download?job=build" + "kenoma" -> + "build" - defp http_client do - middleware = [ - Tesla.Middleware.FollowRedirects, - Tesla.Middleware.JSON - ] + _ -> + "dist" + end - Tesla.client(middleware) + File.mkdir_p!(dest) + File.cp_r!(Path.join([source, from]), dest) + post_install(frontend, dest) + :ok end end -- cgit v1.2.3