Files
n8n-openai-adapter/lib/file.ex
T

196 lines
5.2 KiB
Elixir

defexception File.Exception, reason: nil, action: "", path: nil do
def message(exception) do
"could not " <> exception.action <> " " <> exception.path <> ": " <> list_to_binary(:file.format_error(exception.reason))
end
end
defmodule File do
require Erlang.file, as: F
require Erlang.filename, as: FN
require Erlang.filelib, as: FL
def expand_path(path) do
normalize FN.absname(path)
end
def expand_path(path, relative_to) do
normalize FN.absname(FN.absname(path, relative_to))
end
def regular?(filename) do
Erlang.filelib.is_regular(filename)
end
@doc """
Returns the last component of the `filename` or the file
name itself if it does not contain any directory separators.
## Examples
File.basename("foo")
#=> "foo"
File.basename("foo/bar")
#=> "bar"
File.basename("/")
#=> ""
"""
def basename(path) do
FN.basename(path)
end
@doc """
Returns the last component of `filename` with the `extension`
stripped. This function should be used to remove a specific extension
which might, or might not, be there.
## Examples
File.basename("~/foo/bar.ex", ".ex")
#=> "bar"
File.basename("~/foo/bar.exs", ".ex")
#=> "bar.ecs"
File.basename("~/foo/bar.old.ex", ".ex")
#=> "kalle.old"
"""
def basename(path, extension) do
FN.basename(path, extension)
end
@doc """
Returns a string with one or more paths components joint by the path separator.
This function should be used to convert a list of strings in a path.
## Examples
File.join(["~", "foo"])
#=> "~/foo"
File.join(["foo"])
#=> "foo"
File.join(["/", "foo", "bar"])
#=> "/foo/bar"
"""
def join(paths) do
FN.join(paths)
end
@doc """
Returns `{:ok, binary}`, where `binary` is a binary data object that contains the contents
of `filename`, or `{:error, reason}` if an error occurs.
Typical error reasons:
* :enoent - The file does not exist.
* :eacces - Missing permission for reading the file,
or for searching one of the parent directories.
* :eisdir - The named file is a directory.
* :enotdir - A component of the file name is not a directory.
On some platforms, enoent is returned instead.
* :enomem - There is not enough memory for the contents of the file.
You can use `Erlang.file.format_error(reason)` to get a descriptive string of the error.
"""
def read(filename) do
F.read_file(filename)
end
@doc """
Returns binary with the contents of the given filename or raises
File.Exception if an error occurs.
"""
def read!(filename) do
result = read(filename)
case result do
match: { :ok, binary }
binary
match: { :error, reason }
raise File.Exception, reason: reason, action: "read file", path: filename
end
end
@doc """
Returns a list with the path splitted by the path separator. If an empty string
is given, then it returns the root path.
## Examples
File.split("")
#=> ["/"]
File.split("foo")
#=> ["foo"]
File.split("/foo/bar")
#=> ["/", "foo", "bar"]
"""
def split(path) do
FN.split(path)
end
@doc """
Traverses files and directories according to the given glob expression.
The wildcard string looks like an ordinary filename, except that certain
"wildcard characters" are interpreted in a special way. The following
characters are special:
* `?` - Matches one character.
* `*` - Matches any number of characters up to the end of
the filename, the next dot, or the next slash.
* `**` - Two adjacent <c>*</c>'s used as a single pattern will
match all files and zero or more directories and subdirectories.
* `[char1,char2,...]` - Matches any of the characters listed. Two characters
separated by a hyphen will match a range of characters.
* `{item1,item2,...}` - Matches one of the alternatives.
Other characters represent themselves. Only filenames that have exactly
the same character in the same position will match. Note that matching
is case-sensitive; i.e. "a" will not match "A".
## Examples
Imagine you have a directory called `projects` with three Elixir projects
inside of it: `elixir`, `exdoc` and `dynamo`. You can find all `.beam` files
inside their ebin directories all projects as follows:
File.wildcard("projects/*/ebin/**/*.beam")
If you want to search for both `.beam` and `.app` files, you could do:
File.wildcard("projects/*/ebin/**/*.{beam,app}")
"""
def wildcard(glob) when is_binary(glob) do
paths = Erlang.elixir_glob.wildcard binary_to_list(glob)
Enum.map paths, list_to_binary(&1)
end
def wildcard(path) when is_list(path) do
Erlang.elixir_glob.wildcard(path)
end
## Helpers
# Normalize the given path by removing "..".
defp normalize(path), do: normalize(split(path), [])
defp normalize([top|t], [_|acc]) when top == ".." or top == '..' do
normalize t, acc
end
defp normalize([top|t], acc) when top == "." or top == '.' do
normalize t, acc
end
defp normalize([h|t], acc) do
normalize t, [h|acc]
end
defp normalize([], acc) do
join List.reverse(acc)
end
end