Packages
livebook
0.17.3
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook/file_system/utils.ex
defmodule Livebook.FileSystem.Utils do
alias Livebook.FileSystem
@doc """
Asserts that the given path is a directory.
"""
@spec assert_dir_path!(FileSystem.path()) :: :ok
def assert_dir_path!(path) do
unless dir_path?(path) do
raise ArgumentError, "expected a directory path, got: #{inspect(path)}"
end
:ok
end
@doc """
Asserts that the given path is a regular file path.
"""
@spec assert_regular_path!(FileSystem.path()) :: :ok
def assert_regular_path!(path) do
unless regular_path?(path) do
raise ArgumentError, "expected a regular file path, got: #{inspect(path)}"
end
:ok
end
@doc """
Checks if the given path describes a directory.
"""
@spec dir_path?(FileSystem.path()) :: boolean()
def dir_path?(path) do
String.ends_with?(path, "/")
end
@doc """
Checks if the given path describes a regular file.
"""
@spec regular_path?(FileSystem.path()) :: boolean()
def regular_path?(path) do
not String.ends_with?(path, "/")
end
@doc """
Asserts that the given paths are of the same type.
"""
@spec assert_same_type!(FileSystem.path(), FileSystem.path()) :: :ok
def assert_same_type!(path1, path2) do
if dir_path?(path1) != dir_path?(path2) do
raise ArgumentError,
"expected paths of the same type, got: #{inspect(path1)} and #{inspect(path2)}"
end
:ok
end
@doc """
Converts the given path into dir path by appending a trailing
slash if necessary.
"""
@spec ensure_dir_path(String.t()) :: FileSystem.path()
def ensure_dir_path(path) do
if String.ends_with?(path, "/") do
path
else
path <> "/"
end
end
@doc """
Converts the given posix error atom into readable error tuple.
"""
@spec posix_error(atom()) :: {:error, FileSystem.error()}
def posix_error(error) do
message = error |> :file.format_error() |> List.to_string()
{:error, message}
end
@doc """
Implements `Livebook.FileSystem.resolve_path` assuming Unix-like
path conventions.
This function assumes absolute paths to have a leading "/"
and handles sequences such as "." and "..".
"""
@spec resolve_unix_like_path(FileSystem.path(), String.t()) :: FileSystem.t()
def resolve_unix_like_path(relative_to, subject) do
dir_path = relative_to |> Path.dirname() |> ensure_dir_path()
subject =
if Path.basename(subject) in [".", ".."] do
ensure_dir_path(subject)
else
subject
end
absolute_path? = String.starts_with?(subject, "/")
path = if absolute_path?, do: subject, else: dir_path <> subject
path
|> String.split("/")
|> remove_in_middle("")
|> expand_parts([])
|> Enum.join("/")
end
defp remove_in_middle([], _elem), do: []
defp remove_in_middle([head], _elem), do: [head]
defp remove_in_middle([head | tail], elem), do: remove_in_middle(tail, elem, [head])
defp remove_in_middle([head], _elem, acc), do: Enum.reverse([head | acc])
defp remove_in_middle([elem | tail], elem, acc), do: remove_in_middle(tail, elem, acc)
defp remove_in_middle([head | tail], elem, acc), do: remove_in_middle(tail, elem, [head | acc])
defp expand_parts([], acc), do: Enum.reverse(acc)
defp expand_parts(["." | parts], acc), do: expand_parts(parts, acc)
defp expand_parts([".." | parts], [_parent] = acc), do: expand_parts(parts, acc)
defp expand_parts([".." | parts], [_parent | acc]), do: expand_parts(parts, acc)
defp expand_parts([part | parts], acc), do: expand_parts(parts, [part | acc])
end