bombshell 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +0 -3
- data/README.markdown +157 -0
- data/Rakefile +1 -19
- data/VERSION +1 -1
- data/bombshell.gemspec +4 -13
- data/lib/bombshell/completor.rb +3 -1
- data/lib/bombshell/irb.rb +2 -2
- data/lib/bombshell/shell.rb +2 -2
- data/lib/bombshell/shell/commands.rb +1 -1
- metadata +8 -54
- data/README.rdoc +0 -19
data/Gemfile
CHANGED
@@ -6,8 +6,5 @@ source "http://rubygems.org"
|
|
6
6
|
# Add dependencies to develop your gem here.
|
7
7
|
# Include everything needed to run rake, tests, features, etc.
|
8
8
|
group :development do
|
9
|
-
gem "rspec", "~> 2.3.0"
|
10
|
-
gem "bundler", "~> 1.0.0"
|
11
9
|
gem "jeweler", "~> 1.5.2"
|
12
|
-
gem "rcov", ">= 0"
|
13
10
|
end
|
data/README.markdown
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
# bombshell
|
2
|
+
|
3
|
+
Ever wanted to give dudes the ability to explore your library interactively? Like, with a custom IRB-like shell/console?
|
4
|
+
|
5
|
+
Really, you did? Weird.
|
6
|
+
|
7
|
+
## Simple example
|
8
|
+
|
9
|
+
`pizza/bin/pizza`:
|
10
|
+
|
11
|
+
#!/usr/bin/env ruby
|
12
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
|
13
|
+
|
14
|
+
require 'rubygems'
|
15
|
+
require 'pizza'
|
16
|
+
Bombshell.launch(Pizza::Shell)
|
17
|
+
|
18
|
+
`pizza/lib/pizza/shell.rb`:
|
19
|
+
|
20
|
+
require 'bombshell'
|
21
|
+
|
22
|
+
module Pizza
|
23
|
+
class Shell < Bombshell::Environment
|
24
|
+
include Bombshell::Shell
|
25
|
+
|
26
|
+
prompt_with 'pizzabot'
|
27
|
+
|
28
|
+
def order(size)
|
29
|
+
Pizza::Order.new(:size => size).place!
|
30
|
+
puts 'Your pizza has been ordered! Super!'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Let's try it out:
|
36
|
+
|
37
|
+
$ pizza
|
38
|
+
pizzabot> order 'large'
|
39
|
+
Your pizza has been ordered! Super!
|
40
|
+
pizzabot>
|
41
|
+
|
42
|
+
## Prompts
|
43
|
+
|
44
|
+
You set your prompt like this:
|
45
|
+
|
46
|
+
prompt_with 'pizza_bot_loves_you'
|
47
|
+
|
48
|
+
Or like this:
|
49
|
+
|
50
|
+
prompt_with do
|
51
|
+
"pizza_bot / #{Time.now}" # binding is on your shell *class*
|
52
|
+
end
|
53
|
+
|
54
|
+
Or even like this:
|
55
|
+
|
56
|
+
prompt_with do |shell|
|
57
|
+
"pizza_bot / #{shell.size}" # the block gets the shell *instance* when it asks for it
|
58
|
+
end
|
59
|
+
|
60
|
+
## Callbacks
|
61
|
+
|
62
|
+
You can set callbacks like this:
|
63
|
+
|
64
|
+
before_launch do
|
65
|
+
init # binding is on your shell *class*
|
66
|
+
end
|
67
|
+
|
68
|
+
before_launch do |size|
|
69
|
+
Pizza.default_size = size # the block gets as many command-line parameters as you ask for
|
70
|
+
end
|
71
|
+
|
72
|
+
having_launched do
|
73
|
+
puts size if size # binding is on your shell *instance*
|
74
|
+
end
|
75
|
+
|
76
|
+
## Subshells
|
77
|
+
|
78
|
+
If you dump all of your functionality into one shell, things could get a little messy. That's why we have *subshells*:
|
79
|
+
|
80
|
+
`pizza/lib/pizza/shell.rb`:
|
81
|
+
|
82
|
+
require 'bombshell'
|
83
|
+
|
84
|
+
module Pizza
|
85
|
+
class Shell < Bombshell::Environment
|
86
|
+
include Bombshell::Shell
|
87
|
+
prompt_with 'pizzabot'
|
88
|
+
|
89
|
+
def pizza
|
90
|
+
Order.launch
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
`pizza/lib/pizza/shell/order.rb`:
|
96
|
+
|
97
|
+
require 'bombshell'
|
98
|
+
|
99
|
+
module Pizza
|
100
|
+
class Shell
|
101
|
+
class Order < Bombshell::Environment
|
102
|
+
include Bombshell::Shell
|
103
|
+
prompt_with 'new order'
|
104
|
+
|
105
|
+
def size(s)
|
106
|
+
@size = s
|
107
|
+
puts 'You got it!'
|
108
|
+
end
|
109
|
+
|
110
|
+
def topping(t)
|
111
|
+
@toppings ||= []
|
112
|
+
@toppings << t
|
113
|
+
puts "Added #{t}"
|
114
|
+
end
|
115
|
+
|
116
|
+
def order
|
117
|
+
Pizza::Order.new :size => @size, :toppings => @toppings
|
118
|
+
puts 'Coming right up!'
|
119
|
+
quit
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
Let's try it out:
|
126
|
+
|
127
|
+
pizzabot> pizza
|
128
|
+
new order> size 'large'
|
129
|
+
You got it!
|
130
|
+
new order> topping 'pepperoni'
|
131
|
+
Added pepperoni
|
132
|
+
new order> order
|
133
|
+
Coming right up!
|
134
|
+
pizzabot>
|
135
|
+
|
136
|
+
## Tab completion
|
137
|
+
|
138
|
+
It's there. Give it a whirl with TAB.
|
139
|
+
|
140
|
+
## To use:
|
141
|
+
|
142
|
+
* Create a class for your shell and `include Bombshell::Shell`. You should also set this class to inherit from `Bombshell::Environment` as that will ensure your shell doesn't have any extraneous "commands" (i.e. methods) inherited from Object. (If you'd rather use a different basis--like `CleanSlate`--or `undef` methods yourself, go right ahead.)
|
143
|
+
|
144
|
+
* Define your commands as instance methods on this class. There's nothing *too* funny going on here, it's just Ruby.
|
145
|
+
|
146
|
+
* Kick off the shell with `Bombshell.launch(YourShellClass)`. It's possible to do this from IRB but it's kind of messy (constant reassignment warnings). Instead, set up a "binary" for yourself like `pizza/bin/pizza` at the top of this file.
|
147
|
+
|
148
|
+
## Hints:
|
149
|
+
|
150
|
+
* Give your users a `help` command!
|
151
|
+
* Use subshells for hierarchical interactivity!
|
152
|
+
* Provide as thin of a wrapper you can above your library! We want to see what's going on!
|
153
|
+
|
154
|
+
## Copyright
|
155
|
+
|
156
|
+
Copyright (c) 2011 Andy Rossmeissl. See LICENSE.txt for
|
157
|
+
further details.
|
data/Rakefile
CHANGED
@@ -11,34 +11,16 @@ require 'rake'
|
|
11
11
|
|
12
12
|
require 'jeweler'
|
13
13
|
Jeweler::Tasks.new do |gem|
|
14
|
-
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
14
|
gem.name = "bombshell"
|
16
15
|
gem.homepage = "http://github.com/rossmeissl/bombshell"
|
17
16
|
gem.license = "MIT"
|
18
17
|
gem.summary = %Q{Custom IRB consoles made easy}
|
19
|
-
gem.description = %Q{
|
18
|
+
gem.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.}
|
20
19
|
gem.email = "andy@rossmeissl.net"
|
21
20
|
gem.authors = ["Andy Rossmeissl"]
|
22
|
-
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
-
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
-
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
25
|
-
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
26
21
|
end
|
27
22
|
Jeweler::RubygemsDotOrgTasks.new
|
28
23
|
|
29
|
-
require 'rspec/core'
|
30
|
-
require 'rspec/core/rake_task'
|
31
|
-
RSpec::Core::RakeTask.new(:spec) do |spec|
|
32
|
-
spec.pattern = FileList['spec/**/*_spec.rb']
|
33
|
-
end
|
34
|
-
|
35
|
-
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
36
|
-
spec.pattern = 'spec/**/*_spec.rb'
|
37
|
-
spec.rcov = true
|
38
|
-
end
|
39
|
-
|
40
|
-
task :default => :spec
|
41
|
-
|
42
24
|
require 'rake/rdoctask'
|
43
25
|
Rake::RDocTask.new do |rdoc|
|
44
26
|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
data/bombshell.gemspec
CHANGED
@@ -5,23 +5,23 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bombshell}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Andy Rossmeissl"]
|
12
12
|
s.date = %q{2011-03-07}
|
13
|
-
s.description = %q{
|
13
|
+
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.}
|
14
14
|
s.email = %q{andy@rossmeissl.net}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE.txt",
|
17
|
-
"README.
|
17
|
+
"README.markdown"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
21
|
".rspec",
|
22
22
|
"Gemfile",
|
23
23
|
"LICENSE.txt",
|
24
|
-
"README.
|
24
|
+
"README.markdown",
|
25
25
|
"Rakefile",
|
26
26
|
"VERSION",
|
27
27
|
"bombshell.gemspec",
|
@@ -50,21 +50,12 @@ Gem::Specification.new do |s|
|
|
50
50
|
s.specification_version = 3
|
51
51
|
|
52
52
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
53
|
-
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
54
|
-
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
55
53
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
56
|
-
s.add_development_dependency(%q<rcov>, [">= 0"])
|
57
54
|
else
|
58
|
-
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
59
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
60
55
|
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
61
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
62
56
|
end
|
63
57
|
else
|
64
|
-
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
65
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
66
58
|
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
67
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
68
59
|
end
|
69
60
|
end
|
70
61
|
|
data/lib/bombshell/completor.rb
CHANGED
@@ -11,7 +11,9 @@ module Bombshell
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.filter(m)
|
14
|
-
m - Bombshell::Environment.instance_methods - Bombshell::Shell::Commands::HIDE
|
14
|
+
(m - Bombshell::Environment.instance_methods - Bombshell::Shell::Commands::HIDE).reject do |m|
|
15
|
+
m =~ /^_/
|
16
|
+
end
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
data/lib/bombshell/irb.rb
CHANGED
@@ -12,14 +12,14 @@ module IRB
|
|
12
12
|
|
13
13
|
workspace = WorkSpace.new(binding)
|
14
14
|
|
15
|
-
@CONF[:PROMPT][:
|
15
|
+
@CONF[:PROMPT][:BOMBSHELL] = {
|
16
16
|
:PROMPT_I => "%m> ",
|
17
17
|
:PROMPT_S => "%m\"> ",
|
18
18
|
:PROMPT_C => "%m…>",
|
19
19
|
:PROMPT_N => "%m→>",
|
20
20
|
:RETURN => ''
|
21
21
|
}
|
22
|
-
@CONF[:PROMPT_MODE] = :
|
22
|
+
@CONF[:PROMPT_MODE] = :BOMBSHELL
|
23
23
|
|
24
24
|
irb = Irb.new(workspace)
|
25
25
|
|
data/lib/bombshell/shell.rb
CHANGED
@@ -30,11 +30,11 @@ module Bombshell
|
|
30
30
|
end
|
31
31
|
|
32
32
|
module ClassMethods
|
33
|
-
def launch(arguments
|
33
|
+
def launch(*arguments)
|
34
34
|
@bombshell_callbacks[:before_launch].each do |callback|
|
35
35
|
callback.call(*arguments.first(callback.arity))
|
36
36
|
end
|
37
|
-
shell = new
|
37
|
+
shell = new(*arguments)
|
38
38
|
@bombshell_callbacks[:having_launched].each do |callback|
|
39
39
|
shell.instance_eval &callback
|
40
40
|
end
|
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:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Andy Rossmeissl
|
@@ -18,43 +18,11 @@ cert_chain: []
|
|
18
18
|
date: 2011-03-07 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
22
|
-
type: :development
|
23
|
-
prerelease: false
|
24
|
-
name: rspec
|
25
|
-
version_requirements: &id001 !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
|
-
requirements:
|
28
|
-
- - ~>
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
hash: 3
|
31
|
-
segments:
|
32
|
-
- 2
|
33
|
-
- 3
|
34
|
-
- 0
|
35
|
-
version: 2.3.0
|
36
|
-
requirement: *id001
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
type: :development
|
39
|
-
prerelease: false
|
40
|
-
name: bundler
|
41
|
-
version_requirements: &id002 !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
|
-
requirements:
|
44
|
-
- - ~>
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
hash: 23
|
47
|
-
segments:
|
48
|
-
- 1
|
49
|
-
- 0
|
50
|
-
- 0
|
51
|
-
version: 1.0.0
|
52
|
-
requirement: *id002
|
53
21
|
- !ruby/object:Gem::Dependency
|
54
22
|
type: :development
|
55
23
|
prerelease: false
|
56
24
|
name: jeweler
|
57
|
-
version_requirements: &
|
25
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
58
26
|
none: false
|
59
27
|
requirements:
|
60
28
|
- - ~>
|
@@ -65,22 +33,8 @@ dependencies:
|
|
65
33
|
- 5
|
66
34
|
- 2
|
67
35
|
version: 1.5.2
|
68
|
-
requirement: *
|
69
|
-
|
70
|
-
type: :development
|
71
|
-
prerelease: false
|
72
|
-
name: rcov
|
73
|
-
version_requirements: &id004 !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
|
-
requirements:
|
76
|
-
- - ">="
|
77
|
-
- !ruby/object:Gem::Version
|
78
|
-
hash: 3
|
79
|
-
segments:
|
80
|
-
- 0
|
81
|
-
version: "0"
|
82
|
-
requirement: *id004
|
83
|
-
description: Custom IRB consoles made easy
|
36
|
+
requirement: *id001
|
37
|
+
description: 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.
|
84
38
|
email: andy@rossmeissl.net
|
85
39
|
executables: []
|
86
40
|
|
@@ -88,13 +42,13 @@ extensions: []
|
|
88
42
|
|
89
43
|
extra_rdoc_files:
|
90
44
|
- LICENSE.txt
|
91
|
-
- README.
|
45
|
+
- README.markdown
|
92
46
|
files:
|
93
47
|
- .document
|
94
48
|
- .rspec
|
95
49
|
- Gemfile
|
96
50
|
- LICENSE.txt
|
97
|
-
- README.
|
51
|
+
- README.markdown
|
98
52
|
- Rakefile
|
99
53
|
- VERSION
|
100
54
|
- bombshell.gemspec
|
data/README.rdoc
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
= bombshell
|
2
|
-
|
3
|
-
Description goes here.
|
4
|
-
|
5
|
-
== Contributing to bombshell
|
6
|
-
|
7
|
-
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
8
|
-
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
|
-
* Fork the project
|
10
|
-
* Start a feature/bugfix branch
|
11
|
-
* Commit and push until you are happy with your contribution
|
12
|
-
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
-
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
-
|
15
|
-
== Copyright
|
16
|
-
|
17
|
-
Copyright (c) 2011 Andy Rossmeissl. See LICENSE.txt for
|
18
|
-
further details.
|
19
|
-
|