bombshell 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/bombshell.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
 
9
9
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
10
  s.authors = ["Andy Rossmeissl"]
11
- s.date = %q{2011-03-31}
11
+ s.date = "2011-04-20"
12
12
  s.description = %q{Give your application or gem an interactive shell, complete with custom prompts, tab completion, and various callbacks. Commands are defined as Ruby methods and can be grouped into logical subshells.}
13
13
  s.email = %q{andy@rossmeissl.net}
14
14
  s.extra_rdoc_files = [
@@ -5,6 +5,6 @@ require 'rspec/expectations'
5
5
  require 'bombshell'
6
6
 
7
7
  Before do
8
- @aruba_io_wait_seconds = 2
8
+ @aruba_io_wait_seconds = 3
9
9
  @dirs = [File.join(ENV['HOME'], 'bombshell_features')]
10
10
  end
data/lib/bombshell.rb CHANGED
@@ -5,7 +5,15 @@ require 'bombshell/completor'
5
5
  require 'bombshell/environment'
6
6
  require 'bombshell/irb'
7
7
 
8
+ # Bombshell enables the lickety-split creation of interactive consoles
9
+ # (really just boring old custom IRB sessions).
10
+ # As a Ruby library developer, you may want to build a little shell into
11
+ # your library so that other developers can play around with it before
12
+ # adding it to their applications. In the past this has been a real PITA.
13
+ # With Bombshell it's a little easier.
8
14
  module Bombshell
15
+ # Launch a shell. This is typically called from a "gem binary" executable Ruby script as described in the README.
16
+ # @param [Class] shell The shell class to launch. Must include <tt>Bombshell::Shell</tt>.
9
17
  def launch(shell)
10
18
  begin
11
19
  failure = shell.launch(ARGV.dup)
@@ -1,15 +1,20 @@
1
1
  module Bombshell
2
+ # A class used by <tt>IRB.start_session</tt> to handle tab completion.
2
3
  class Completor
4
+ # Always initialize Completor with the shell it's completing for.
3
5
  def initialize(shell)
4
6
  @shell = shell
5
7
  end
6
8
 
7
9
  attr_reader :shell
8
10
 
11
+ # Provide completion for a given fragment.
12
+ # @param [String] fragment the fragment to complete for
9
13
  def complete(fragment)
10
14
  self.class.filter(shell.instance_methods).grep Regexp.new(Regexp.quote(fragment))
11
15
  end
12
16
 
17
+ # Filter out irrelevant methods that shouldn't appear in a completion list.
13
18
  def self.filter(m)
14
19
  (m - Bombshell::Environment.instance_methods - Bombshell::Shell::Commands::HIDE).reject do |m|
15
20
  m =~ /^_/
@@ -1,4 +1,7 @@
1
1
  module Bombshell
2
+ # A (mostly) blank class like Ruby's own CleanSlate. We leave a few important methods in here; your shell shouldn't redefine them.
3
+ # It's best practice to set your shell classes to inherit from <tt>Bombshell::Environment</tt>. See the README for more details.
4
+ # @see file:README.markdown
2
5
  class Environment
3
6
  instance_methods.each do |m|
4
7
  undef_method m if m.to_s !~ /(?:^__|^nil\?$|^send$|^instance_eval$|^define_method$|^class$|^object_id|^instance_methods$)/
data/lib/bombshell/irb.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  # encoding: utf-8
2
2
 
3
+ # We have to monkey patch a method into IRB here. I've tried extending it, and it doesn't work.
3
4
  module IRB
5
+ # Launch a custom IRB session with the given binding, set up the prompt, and define tab completion.
6
+ # @param [Binding] binding Your shell's binding
4
7
  def self.start_session(binding)
5
8
  unless @__initialized
6
9
  args = ARGV
@@ -1,18 +1,28 @@
1
1
  require 'bombshell/shell/commands'
2
2
 
3
3
  module Bombshell
4
+ # Classes include this module to become Bombshell shells.
4
5
  module Shell
6
+ # Add class methods and a callback hash to your shell.
5
7
  def self.included(base)
6
8
  base.extend ClassMethods
7
9
  base.instance_variable_set :@bombshell_callbacks, :before_launch => [], :having_launched => []
8
10
  end
9
11
 
12
+ # IRB has pretty limited hooks for defining prompts, so we have to piggyback on your
13
+ # shell's <tt>#to_s</tt>. Hope you don't need it for something else.
10
14
  def to_s
11
15
  _prompt
12
16
  end
13
17
 
14
18
  include Commands
15
19
 
20
+ # Render and return your shell's prompt.
21
+ #
22
+ # You can define the prompt with <tt>MyShell.prompt_with</tt> and access it without rendering with <tt>MyShell.bombshell_prompt</tt>.
23
+ # @see ClassMethods#prompt_with
24
+ # @see ClassMethods#bombshell_prompt
25
+ # @return String
16
26
  def _prompt
17
27
  if self.class.bombshell_prompt.is_a? String
18
28
  self.class.bombshell_prompt
@@ -25,11 +35,22 @@ module Bombshell
25
35
  end
26
36
  end
27
37
 
38
+ # Returns your shell's binding, which IRB needs (desperately).
39
+ # @return Binding
28
40
  def get_binding
29
41
  binding
30
42
  end
31
43
 
44
+ # Class methods for your shell
32
45
  module ClassMethods
46
+ # Launch the shell.
47
+ #
48
+ # You should generally call <tt>Bombshell.launch(MyShell)</tt> instead
49
+ # of <tt>MyShell.launch</tt> directly, as the former approach will handle
50
+ # exits correctly and pass command-line parameters as arguments.
51
+ # @param [Array] arguments An array of arguments that, eventually, callbacks
52
+ # might use. If you're using the <tt>Bombshell.launch</tt> wrapper, these
53
+ # will be command-line parameters.
33
54
  def launch(*arguments)
34
55
  @bombshell_callbacks[:before_launch].each do |callback|
35
56
  callback.call(*arguments.first(callback.arity > -1 ? callback.arity : 0))
@@ -41,18 +62,63 @@ module Bombshell
41
62
  ::IRB.start_session(shell.get_binding)
42
63
  end
43
64
 
65
+ # Define a callback that will get called before your shell is instantiated (and
66
+ # therefore before it is handed over to IRB).
67
+ #
68
+ # This is a great place to
69
+ # dynamically define additional instance methods on your class. If your callback
70
+ # proc asks for blockvars, Bombshell will give it as many command-line parameters
71
+ # as it needs to. Within the callback, <tt>self</tt> is your shell <i>class</i>.
72
+ # @see #having_launched
73
+ # @example
74
+ # class MyShell < Bombshell::Environment
75
+ # include Bombshell::Shell
76
+ # before_launch do
77
+ # define_method :foo
78
+ # puts 'bar'
79
+ # end
80
+ # end
81
+ # end
82
+ # @example
83
+ # class MyShell < Bombshell::Environment
84
+ # include Bombshell::Shell
85
+ # before_launch do |first_command_line_parameter, second_command_line_parameter|
86
+ # define_method :display_first_command_line_parameter
87
+ # puts first_command_line_parameter
88
+ # end
89
+ # end
90
+ # end
44
91
  def before_launch(&callback)
45
92
  @bombshell_callbacks[:before_launch] << callback
46
93
  end
47
94
 
95
+ # Define a callback that will get called <i>after</i> your shell is instantiated,
96
+ # but <i>before</i> its binding is handed over to IRB. Within the callback, <tt>self</tt> is your shell <i>instance</i>.
97
+ # @see #before_launch
48
98
  def having_launched(&callback)
49
99
  @bombshell_callbacks[:having_launched] << callback
50
100
  end
51
101
 
102
+ # Define your shell's prompt.
103
+ #
104
+ # You can either set your prompt to a static string, or use a Proc for a dynamic prompt.
105
+ # @param [String] p a string to be used as your shell's prompt.
106
+ # @param [Proc] prompt a Proc to be rendered whenever your shell's prompt needs to be
107
+ # displayed. Within the callback, <tt>self</tt> is your shell <i>class</i>. If your
108
+ # proc asks for a blockvar, it will be given your shell <i>instance</i>.
109
+ # @see Bombshell::Shell#_prompt
110
+ # @see #bombshell_prompt
52
111
  def prompt_with(p = nil, &prompt)
53
112
  @bombshell_prompt = p || prompt
54
113
  end
55
114
 
115
+ # Read your shell's prompt
116
+ #
117
+ # Note that this method returns an <i>unrendered</i> prompt. That is, if it's defined as
118
+ # a Proc, you'll get a Proc back. If you want to get the rendered prompt, use <tt>#_prompt</tt>
119
+ # on your shell instance.
120
+ # @see #prompt_with
121
+ # @see Bombshell::Shell#_prompt
56
122
  def bombshell_prompt
57
123
  @bombshell_prompt
58
124
  end
@@ -1,11 +1,16 @@
1
1
  module Bombshell
2
2
  module Shell
3
+ # Standard commands that show up in all Bombshell shells.
3
4
  module Commands
5
+ # An explicit list of commands to hide from tab completion.
4
6
  HIDE = [:method_missing, :get_binding, :_prompt, :to_s]
5
7
 
8
+ # Exit safely, accounting for the fact that we might be inside a subshell.
6
9
  def quit
7
10
  throw :IRB_EXIT
8
11
  end
12
+
13
+ # Provide an error message for unknown commands rather than raise an exception.
9
14
  def method_missing(*args)
10
15
  return if [:extend, :respond_to?].include? args.first
11
16
  puts "Unknown command #{args.first}"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bombshell
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 4
10
- version: 0.1.4
9
+ - 5
10
+ version: 0.1.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andy Rossmeissl
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-31 00:00:00 -04:00
18
+ date: 2011-04-20 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency