126 lines
4.2 KiB
Elixir
126 lines
4.2 KiB
Elixir
defmodule BDS.Desktop.ShellLive.GitHandler do
|
|
@moduledoc false
|
|
|
|
import Phoenix.Component, only: [assign: 3]
|
|
|
|
alias BDS.Desktop.ShellLive.{SocketState, TabHelpers, UrlState}
|
|
alias BDS.UI.Workbench
|
|
|
|
use Gettext, backend: BDS.Gettext
|
|
|
|
def run_action(socket, event) do
|
|
project_id = current_project_id(socket)
|
|
|
|
{label, result} =
|
|
case event do
|
|
"git_fetch" -> {dgettext("ui", "Fetch"), git_call(project_id, &BDS.Git.fetch/1)}
|
|
"git_pull" -> {dgettext("ui", "Pull"), git_call(project_id, &BDS.Git.pull/1)}
|
|
"git_push" -> {dgettext("ui", "Push"), git_call(project_id, &BDS.Git.push/1)}
|
|
"git_prune_lfs" -> {dgettext("ui", "Prune LFS"), prune_lfs(project_id)}
|
|
end
|
|
|
|
socket
|
|
|> append_git_result(label, result)
|
|
|> SocketState.refresh_sidebar(socket.assigns.workbench)
|
|
end
|
|
|
|
def commit(socket, "") do
|
|
socket
|
|
|> SocketState.append_output_entry(
|
|
dgettext("ui", "Commit"),
|
|
dgettext("ui", "Commit message is required"),
|
|
nil,
|
|
"error"
|
|
)
|
|
|> SocketState.refresh_sidebar(socket.assigns.workbench)
|
|
end
|
|
|
|
def commit(socket, message) do
|
|
case git_call(current_project_id(socket), &BDS.Git.commit_all(&1, message)) do
|
|
{:ok, _result} ->
|
|
workbench = close_git_diff_tabs(socket.assigns.workbench)
|
|
tab_meta = TabHelpers.sync_tab_meta(workbench, socket.assigns[:tab_meta] || %{})
|
|
|
|
socket
|
|
|> assign(:tab_meta, tab_meta)
|
|
|> SocketState.append_output_entry(dgettext("ui", "Commit"), message, nil, "info")
|
|
|> SocketState.refresh_sidebar(workbench)
|
|
|> UrlState.push()
|
|
|
|
{:error, reason} ->
|
|
socket
|
|
|> SocketState.append_output_entry(dgettext("ui", "Commit"), format_git_error(reason), nil, "error")
|
|
|> SocketState.refresh_sidebar(socket.assigns.workbench)
|
|
end
|
|
end
|
|
|
|
def initialize(socket, remote_url) do
|
|
project_id = current_project_id(socket)
|
|
|
|
case git_call(project_id, &BDS.Git.initialize_repo/1) do
|
|
{:ok, _repo} ->
|
|
_ = maybe_set_git_remote(project_id, remote_url)
|
|
|
|
socket
|
|
|> SocketState.append_output_entry(
|
|
dgettext("ui", "Initialize Git"),
|
|
dgettext("ui", "Repository initialized"),
|
|
nil,
|
|
"info"
|
|
)
|
|
|> SocketState.refresh_sidebar(socket.assigns.workbench)
|
|
|
|
{:error, reason} ->
|
|
socket
|
|
|> SocketState.append_output_entry(
|
|
dgettext("ui", "Initialize Git"),
|
|
format_git_error(reason),
|
|
nil,
|
|
"error"
|
|
)
|
|
|> SocketState.refresh_sidebar(socket.assigns.workbench)
|
|
end
|
|
end
|
|
|
|
def normalize_remote_url(value) do
|
|
case value |> to_string() |> String.trim() do
|
|
"" -> nil
|
|
url -> url
|
|
end
|
|
end
|
|
|
|
defp git_call(nil, _fun), do: {:error, :no_project}
|
|
defp git_call("default", _fun), do: {:error, :no_project}
|
|
defp git_call(project_id, fun) when is_binary(project_id), do: fun.(project_id)
|
|
|
|
defp prune_lfs(nil), do: {:error, :no_project}
|
|
defp prune_lfs("default"), do: {:error, :no_project}
|
|
|
|
defp prune_lfs(project_id) when is_binary(project_id),
|
|
do: BDS.Git.prune_lfs_cache(project_id, 10)
|
|
|
|
defp maybe_set_git_remote(_project_id, nil), do: :ok
|
|
defp maybe_set_git_remote(project_id, remote_url), do: BDS.Git.set_remote(project_id, remote_url)
|
|
|
|
defp append_git_result(socket, label, {:ok, _result}) do
|
|
SocketState.append_output_entry(socket, label, dgettext("ui", "Done"), nil, "info")
|
|
end
|
|
|
|
defp append_git_result(socket, label, {:error, reason}) do
|
|
SocketState.append_output_entry(socket, label, format_git_error(reason), nil, "error")
|
|
end
|
|
|
|
defp format_git_error(:no_project), do: dgettext("ui", "No active project")
|
|
defp format_git_error(%{message: message}) when is_binary(message), do: message
|
|
defp format_git_error(%{guidance: guidance}) when is_binary(guidance), do: guidance
|
|
defp format_git_error({:git_failed, message}) when is_binary(message), do: message
|
|
defp format_git_error(reason), do: inspect(reason)
|
|
|
|
defp close_git_diff_tabs(workbench) do
|
|
workbench.tabs
|
|
|> Enum.filter(&(&1.type == :git_diff))
|
|
|> Enum.reduce(workbench, fn tab, wb -> Workbench.close_tab(wb, :git_diff, tab.id) end)
|
|
end
|
|
|
|
defp current_project_id(socket), do: (socket.assigns[:projects] || %{})[:active_project_id]
|
|
end |