Files
n8n-openai-adapter/lib/code/init.ex
T
2011-06-04 19:55:17 +02:00

215 lines
4.6 KiB
Elixir

% Responsible for starting Elixir from the command line.
module Code::Init
mixin Code::Formatter
module Config
attr_accessor ['output]
def __bound__()
@('commands: [], 'close: [], 'halt: true, 'output: ".", 'compile: false)
end
def compiling?
@compile
end
def compile!
@('compile, true)
end
def halt?
@halt
end
def no_halt!
@('halt: false)
end
def add_command(c)
@('commands: [c|@commands])
end
def add_close(c)
@('close: [c|@close])
end
def final_commands
@commands.reverse + @close.reverse
end
end
% Invoked directly from erlang boot process. It parses all argv
% options and execute them in the order they are specified.
def process_argv(options)
{ config, argv } = process_options(options, #Code::Init::Config())
GenServer.call('elixir_code_server, { 'argv, argv })
if config.compiling?
Erlang.file.make_dir(config.output.to_char_list)
end
try
[process_command(c, config) for c in config.final_commands]
catch kind: error
if exiting?(kind, error)
halt!(error)
else
io = IO.new('standard_error)
io.puts "** #{kind} #{format_catch(kind, error)}"
print_stacktrace(io, __stacktrace__)
halt!(1)
end
end
if config.halt?
halt!(0)
else
% TODO Is there a better way to suspend the process?
Erlang.timer.sleep('infinity)
end
end
private
def halt!(0)
Erlang.init.stop
end
def halt!(status)
if Erlang.is_number(status)
Erlang.halt(status)
else
Erlang.halt(status.to_char_list)
end
end
def exiting?(kind, error)
kind == 'exit && (Erlang.is_binary(error) || Erlang.is_number(error))
end
def print_stacktrace(io, stacktrace)
stacktrace.each -> (s) io.puts " #{format_stacktrace(s)}"
end
def invalid_option(option)
IO.new('standard_error).puts "Unknown option #{option.to_bin}"
halt!(1)
end
def shared_option?(list, state, callback)
case process_shared(list, state)
match { ~list, _ }
invalid_option list.head
match { new_list, new_state }
callback.(new_list, new_state)
end
end
% Process shared options
def process_shared([$"-v"|_], _)
IO.puts "Elixir #{Code.version}"
halt!(0)
end
def process_shared([$"-e",h|t], state)
process_shared t, state.add_command({'eval, h})
end
def process_shared([$"-pa",h|t], state)
Code.prepend_path(h)
process_shared t, state
end
def process_shared([$"-pz",h|t], state)
Code.append_path(h)
process_shared t, state
end
def process_shared([$"-f",h|t], state)
process_shared t, state.add_close({'eval, h})
end
def process_shared(list, state)
{ list, state }
end
% Process init options
def process_options([$"--no-halt"|t], state)
process_options t, state.no_halt!
end
def process_options([$"--"|t], state)
{ state, t.map(_.to_bin) }
end
def process_options([$"+compile"|t], state)
process_compiler t, state.compile!
end
def process_options([h|t] = list, state)
if h.to_char_list[0] == $-
shared_option? list, state, -> (nl, ns) process_options(nl, ns)
else
{ state.add_command({'load,h}), t.map(_.to_bin) }
end
end
def process_options([], state)
{ state, [] }
end
% Process compiler options
def process_compiler([$"--"|t], state)
{ state, t.map(_.to_bin) }
end
def process_compiler([$"-o",h|t], state)
process_compiler t, state.output(h)
end
def process_compiler([$"-s",h|t], state)
process_compiler t, state.add_command({'compile_spec,h})
end
def process_compiler([h|t] = list, state)
if h.to_char_list[0] == $-
shared_option? list, state, -> (nl, ns) process_compiler(nl, ns)
else
process_compiler t, state.add_command({'compile,h})
end
end
def process_compiler([], state)
{ state, [] }
end
% Process commands
def process_command({'eval, expr}, _state)
Erlang.elixir.eval(expr, [])
end
def process_command({'load, file}, _state)
Code.load_file(file)
end
def process_command({'compile, pattern}, state)
compile_patterns [pattern], state
end
def process_command({'compile_spec, spec}, state)
contents = File.read(spec)
compile_patterns contents.split(~r"\n"), state
end
def compile_patterns(lines, state)
lines = [Erlang.filelib.wildcard(line.to_char_list) for line in lines]
lines.flatten_lists.uniq.each do (file)
IO.puts "Compiling #{file.to_bin}"
Code.compile_file_to_path(file, state.output)
end
end
end