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

163 lines
4.2 KiB
Elixir

defmodule Code do
def version, do: "0.9.0.dev"
@doc """
Returns the current ARGV.
"""
def argv do
server_call :argv
end
@doc """
Returns all the loaded files.
"""
def loaded_files do
server_call :loaded
end
@doc """
Registers a function that will be invoked
at the end of program execution. Useful for
invoking a hook on scripted mode.
The function must expect the exit status code
as argument.
"""
def at_exit(fun) when is_function(fun, 1) do
server_call { :at_exit, fun }
end
def append_path(path) do
Erlang.code.add_pathz(to_char_list(path))
end
def prepend_path(path) do
Erlang.code.add_patha(to_char_list(path))
end
@doc """
Evalutes the quotes contents.
## Examples
contents = quote hygiene: false, do: a + b
Code.eval_quoted contents, [a: 1, b: 2], __FILE__, __LINE__ # => { 3, [ {:a, 1}, {:b, 2} ] }
"""
def eval_quoted(quoted, binding, filename, line) do
{ value, binding, _scope } =
Erlang.elixir.eval_quoted [quoted], binding, line, to_char_list(filename)
{ value, binding }
end
@doc """
Loads the given `file`. Accepts `relative_to` as an argument to tell
where the file is located. If the file was already required/loaded,
loads it again. It returns the full path of the loaded file.
When loading a file, you may skip passing .exs as extension as Elixir
automatically adds it for you.
"""
def load_file(file, relative_to // nil) do
load_and_push_file find_file(file, relative_to)
end
@doc """
Requires the given `file`. Accepts `relative_to` as an argument to tell
where the file is located. If the file was already required/loaded,
returns nil, otherwise the full path of the loaded file.
When requiring a file, you may skip passing .exs as extension as
Elixir automatically adds it for you.
"""
def require_file(file, relative_to // nil) do
file = find_file(file, relative_to)
if List.member?(loaded_files, file) do
nil
else:
load_and_push_file file
end
end
@doc """
Compiles `file` and returns a list of tuples where
the first element is the module name and the second
one is its binary.
## Options
Available options are:
* docs - when true, retain documentation in the compiled module;
* debug_info - when true, retain debug information in the compiled module.
Notice debug information can be used to reconstruct the source code;
"""
def compile_file(file, opts // []) do
Erlang.elixir_compiler.with_opts opts, fn ->
Erlang.elixir_compiler.file to_char_list(file)
end
end
@doc """
Compiles `file` and add the result to the given `destination`.
Destination needs to be a directory.
See compile_file/2 for available options.
"""
def compile_file_to_dir(file, destination, opts // []) do
Erlang.elixir_compiler.with_opts opts, fn ->
Erlang.elixir_compiler.file_to_path to_char_list(file), to_char_list(destination)
end
end
@doc """
Get the stacktrace.
"""
def stacktrace do
filter_stacktrace Erlang.erlang.get_stacktrace
end
## Helpers
# Filter stacktrace by removing internal BOOTSTRAP calls.
defp filter_stacktrace([{ Elixir.Builtin, :raise, _, _ }|t]), do: filter_stacktrace(t)
defp filter_stacktrace([{ _mod, :BOOTSTRAP, _, _ }|t]), do: filter_stacktrace(t)
defp filter_stacktrace([{ _mod, :BOOTSTRAP, _ }|t]), do: filter_stacktrace(t)
defp filter_stacktrace([h|t]), do: [h|filter_stacktrace(t)]
defp filter_stacktrace([]), do: []
defp load_and_push_file(file) do
server_call { :loaded, file }
compile_file file
file
end
# Finds the file given the relative_to path.
# If the file is found, returns its path in binary, fails otherwise.
defp find_file(file, relative_to) do
file = to_binary(file)
file = if relative_to do
File.expand_path(file, relative_to)
else:
File.expand_path(file)
end
if File.regular?(file) do
file
else:
file = "#{file}.exs"
if File.regular?(file) do
file
else:
raise ArgumentError, message: "could not load #{file}"
end
end
end
defp server_call(args) do
Erlang.gen_server.call(:elixir_code_server, args)
end
end