diff --git a/lib/livebook/session.ex b/lib/livebook/session.ex index 97b205f14..058914aad 100644 --- a/lib/livebook/session.ex +++ b/lib/livebook/session.ex @@ -675,7 +675,8 @@ defmodule Livebook.Session do handle_operation(state, {:mark_as_not_dirty, self()}) else {:error, reason} -> - broadcast_error(state.session_id, "failed to save notebook - #{reason}") + message = :file.format_error(reason) + broadcast_error(state.session_id, "failed to save notebook - #{message}") state end else diff --git a/lib/livebook_web/live/home_live.ex b/lib/livebook_web/live/home_live.ex index 26931acae..305543ac0 100644 --- a/lib/livebook_web/live/home_live.ex +++ b/lib/livebook_web/live/home_live.ex @@ -57,10 +57,15 @@ defmodule LivebookWeb.HomeLive do <%= live_patch "Join session", to: Routes.session_path(@socket, :page, session_id_by_path(@path, @session_summaries)), class: "button button-blue" %> <% else %> - <%= content_tag :button, "Open", - class: "button button-blue", - phx_click: "open", - disabled: not path_openable?(@path, @session_summaries) %> + <%= tag :span, if(File.regular?(@path) and not file_writable?(@path), + do: [class: "tooltip top", aria_label: "This file is write-protected, please fork instead"], + else: [] + ) %> + <%= content_tag :button, "Open", + class: "button button-blue", + phx_click: "open", + disabled: not path_openable?(@path, @session_summaries) %> + <% end %> <% end %> @@ -170,7 +175,7 @@ defmodule LivebookWeb.HomeLive do end defp path_openable?(path, session_summaries) do - File.regular?(path) and not path_running?(path, session_summaries) + File.regular?(path) and not path_running?(path, session_summaries) and file_writable?(path) end defp path_running?(path, session_summaries) do @@ -178,6 +183,13 @@ defmodule LivebookWeb.HomeLive do path in running_paths end + defp file_writable?(path) do + case File.stat(path) do + {:ok, stat} -> stat.access in [:read_write, :write] + {:error, _} -> false + end + end + defp create_session(socket, opts \\ []) do case SessionSupervisor.create_session(opts) do {:ok, id} ->