diff options
-rw-r--r-- | components/storage.rb | 7 | ||||
-rw-r--r-- | components/stream.rb | 37 | ||||
-rw-r--r-- | controllers/cartridges.rb | 52 | ||||
-rw-r--r-- | controllers/instance.rb | 13 | ||||
-rw-r--r-- | ports/dsl/nano-bots.rb | 8 |
5 files changed, 109 insertions, 8 deletions
diff --git a/components/storage.rb b/components/storage.rb index bdf0efe..d34dac7 100644 --- a/components/storage.rb +++ b/components/storage.rb @@ -29,6 +29,13 @@ module NanoBot path end + def self.cartridges_path + [ + ENV.fetch('NANO_BOTS_CARTRIDGES_DIRECTORY', nil), + "#{user_home!.sub(%r{/$}, '')}/.local/share/nano-bots/cartridges" + ].uniq.filter { |path| File.directory?(path) }.compact.first + end + def self.cartridge_path(path) partial = File.join(File.dirname(path), File.basename(path, File.extname(path))) diff --git a/components/stream.rb b/components/stream.rb new file mode 100644 index 0000000..45c4a2b --- /dev/null +++ b/components/stream.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'stringio' + +module NanoBot + module Components + class Stream < StringIO + def write(*args) + if @callback + @accumulated += args.first + @callback.call(@accumulated, args.first, false) + end + super + end + + def callback=(block) + @accumulated = '' + @callback = block + end + + def finish + flush + result = string.clone + truncate(0) + rewind + + if @callback + @callback.call(@accumulated, nil, true) + @callback = nil + @accumulated = nil + end + + result + end + end + end +end diff --git a/controllers/cartridges.rb b/controllers/cartridges.rb new file mode 100644 index 0000000..3e3b192 --- /dev/null +++ b/controllers/cartridges.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require_relative '../components/storage' +require_relative '../logic/helpers/hash' +require_relative '../logic/cartridge/default' + +module NanoBot + module Controllers + class Cartridges + def self.all + files = {} + + path = Components::Storage.cartridges_path + + Dir.glob("#{path}/**/*.{yml,yaml}").each do |file| + files[Pathname.new(file).realpath] = { + base: path, + path: Pathname.new(file).realpath + } + end + + cartridges = [] + + files.values.uniq.map do |file| + cartridge = Logic::Helpers::Hash.symbolize_keys( + YAML.safe_load(File.read(file[:path]), permitted_classes: [Symbol]) + ).merge({ + system: { + id: file[:path].to_s.sub(/^#{Regexp.escape(file[:base])}/, '').sub(%r{^/}, '').sub(/\.[^.]+\z/, + ''), + path: file[:path], + base: file[:base] + } + }) + + next if cartridge[:meta][:name].nil? + + cartridges << cartridge + # rescue StandardError => _e + end + + cartridges.sort_by { |cartridge| cartridge[:meta][:name] } + + cartridges.prepend( + { system: { id: '-' }, meta: { name: 'Default', symbol: '🤖' } } + ) + + cartridges + end + end + end +end diff --git a/controllers/instance.rb b/controllers/instance.rb index 80ac9be..e0729e6 100644 --- a/controllers/instance.rb +++ b/controllers/instance.rb @@ -5,6 +5,7 @@ require 'yaml' require_relative '../logic/helpers/hash' require_relative '../components/provider' require_relative '../components/storage' +require_relative '../components/stream' require_relative './interfaces/repl' require_relative './interfaces/eval' require_relative './session' @@ -30,16 +31,14 @@ module NanoBot @session.state end - def eval(input) + def eval(input, &block) + @stream.callback = block if block && @stream.is_a?(Components::Stream) + Interfaces::Eval.evaluate(input, @cartridge, @session) - return unless @stream.is_a?(StringIO) + return unless @stream.is_a?(Components::Stream) - @stream.flush - result = @stream.string.clone - @stream.truncate(0) - @stream.rewind - result + @stream.finish end def repl diff --git a/ports/dsl/nano-bots.rb b/ports/dsl/nano-bots.rb index 40bed1d..89da466 100644 --- a/ports/dsl/nano-bots.rb +++ b/ports/dsl/nano-bots.rb @@ -3,12 +3,18 @@ require 'dotenv/load' require_relative '../../static/gem' +require_relative '../../controllers/cartridges' require_relative '../../controllers/instance' require_relative '../../controllers/interfaces/cli' +require_relative '../../components/stream' module NanoBot def self.new(cartridge: '-', state: '-') - Controllers::Instance.new(cartridge_path: cartridge, state:, stream: StringIO.new) + Controllers::Instance.new(cartridge_path: cartridge, state:, stream: Components::Stream.new) + end + + def self.cartridges + Controllers::Cartridges.all end def self.cli |