Add helpers to IRB console?

I was looking to add a couple of helper methods (aka the same way you can call app, reload, etc.) directly to the Hanami console (using IRB), and I couldn’t find an official API for that so I hacked something together in config/app.rb. Example:

module BtCommands
  def site = Bridgetown::Current.site
  def collections = site.collections
end

Hanami::CLI::Repl::Irb.class_eval do
  alias_method :__old__start__, :start
  def start
    TOPLEVEL_BINDING.eval("self").extend(BtCommands)
    __old__start__
  end
end

Is there any better way to do this? If not, any thoughts on the idea that an API for this could be a feature? tysm

Hanami’s REPL environment is pretty bare-bones, you could do like I did and just make your own.

I used Pry but you can see the process:

# frozen_string_literal: true

require "hanami/cli"
require "hanami/cli/repl/pry"

def formatted_env
  case Hanami.env
  when :production
    Pry::Helpers::Text.red("PRODUCTION")
  when :staging
    Pry::Helpers::Text.yellow("staging")
  when :development
    Pry::Helpers::Text.green("development")
  else
    Hanami.env
  end
end

Pry::Prompt.add(:cerberus, "Cerberus custom prompt", [">", "*"]) do |obj, nest, _, sep|
  "🐶🐶🐶 #{formatted_env} #{obj}:#{nest}#{sep} "
end

module Cerberus
  class Repl < Hanami::CLI::Commands::App::Command
    desc "Start app console (REPL)"

    class Context
      def to_s = "root"
    end

    def call(**opts)
      ::Pry.config.prompt = ::Pry::Prompt[:cerberus]

      context = Hanami::Console::Context.new(app)
      context = Context.new.extend(context)

      ::Pry.start(context)
    end
  end
end

Hanami::CLI.instance_eval do
  register "console", Cerberus::Repl
end

Thanks @jaredwhite for raising this! I’d love for the framework to provide a way to make console customisations straightforward.

Initial idea: a config/console.rb that provides the place to put this stuff? It could either contain direct code or include bigger pieces of code that you put into lib/.

@alassek — Thanks for sharing your own customisations :slight_smile: Just for the record, is this code from a bin/hanami inside your app, which you invoke instead of bundle exec hanami?

1 Like

Mine is implemented as bin/hanami that requires and extends the framework version, although I bet that’s not actually necessary.

1 Like

That seems reasonable, or even something you could do through app config or settings. FWIW, Bridgetown’s console lets you include a mixin, but I could understand an approach that’s based around a class.

2 Likes

Binding context is ultimately just an Object, so I could see an argument for registering one or more mixin modules via configuration.

RSpec’s config.include feels like a good analogue for this. Would be happy for us to do similar :+1:

1 Like

Support for this has been merged. Will be available in the forthcoming 2.3 release!

5 Likes