boom 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG.markdown CHANGED
@@ -2,7 +2,16 @@
2
2
 
3
3
  ## head
4
4
 
5
- ## 0.2.0
5
+ ## 0.2.1 (July 16, 2011)
6
+ - boom displays colors thanks to [@dandorman](https://github.com/dandorman).
7
+ - Windows support, brah. [@tombell](https://github.com/tombell).
8
+ - boom accepts piped-in data (like `cat admins.txt | boom groups admins`).
9
+ Thanks [@brettbuddin](https://github.com/brettbuddin) and
10
+ [@antonlindstrom](https://github.com/antonlindstrom). Tag-team action.
11
+ - `boom <newlist> <item> <value>` will actually create the list and item now.
12
+ [@jmazzi](https://github.com/jmazzi).
13
+
14
+ ## 0.2.0 (April 12, 2011)
6
15
  - Add Keychain storage to store Boom data securely in OS X's Keychain.app.
7
16
  Thanks, [@davidtrogers](https://github.com/davidtrogers)!
8
17
  - Switch from yajl-ruby because [OS X isn't for
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- boom (0.1.2)
4
+ boom (0.2.0)
5
5
  json_pure (~> 1.5.1)
6
6
 
7
7
  GEM
data/README.markdown CHANGED
@@ -30,7 +30,9 @@ commands](https://github.com/holman/boom/wiki/Commands).
30
30
 
31
31
  ## Contribute
32
32
 
33
- I'd love to include your contributions, friend.
33
+ Want to join the [Pantheon of
34
+ Boom'ers](https://github.com/holman/boom/contributors)? I'd love to include
35
+ your contributions, friend.
34
36
 
35
37
  Clone this repository, then run `bundle install`. That'll install all the gem
36
38
  dependencies. Make sure your methods are [TomDoc](http://tomdoc.org)'d
data/boom.gemspec CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
13
13
  ## If your rubyforge_project name is different, then edit it and comment out
14
14
  ## the sub! line in the Rakefile
15
15
  s.name = 'boom'
16
- s.version = '0.2.0'
17
- s.date = '2011-04-11'
16
+ s.version = '0.2.1'
17
+ s.date = '2011-07-16'
18
18
  s.rubyforge_project = 'boom'
19
19
 
20
20
  ## Make sure your summary is short. The description may be as long
@@ -77,6 +77,7 @@ Gem::Specification.new do |s|
77
77
  completion/boom.bash
78
78
  completion/boom.zsh
79
79
  lib/boom.rb
80
+ lib/boom/color.rb
80
81
  lib/boom/command.rb
81
82
  lib/boom/config.rb
82
83
  lib/boom/core_ext/symbol.rb
@@ -93,10 +94,12 @@ Gem::Specification.new do |s|
93
94
  test/examples/test_json.json
94
95
  test/examples/urls.json
95
96
  test/helper.rb
97
+ test/test_color.rb
96
98
  test/test_command.rb
97
99
  test/test_config.rb
98
100
  test/test_item.rb
99
101
  test/test_list.rb
102
+ test/test_platform.rb
100
103
  ]
101
104
  # = MANIFEST =
102
105
 
data/lib/boom/color.rb ADDED
@@ -0,0 +1,46 @@
1
+ module Boom
2
+ # Color collects some methods for colorizing terminal output.
3
+ module Color
4
+ extend self
5
+
6
+ CODES = {
7
+ :reset => "\e[0m",
8
+
9
+ :cyan => "\e[36m",
10
+ :magenta => "\e[35m",
11
+ :red => "\e[31m",
12
+ :yellow => "\e[33m"
13
+ }
14
+
15
+ # Tries to enable Windows support if on that platform.
16
+ #
17
+ # Returns nothing.
18
+ def self.included(other)
19
+ if RUBY_PLATFORM =~ /win32/ || RUBY_PLATFORM =~ /mingw32/
20
+ require 'Win32/Console/ANSI'
21
+ end
22
+ rescue LoadError
23
+ # Oh well, we tried.
24
+ end
25
+
26
+ # Wraps the given string in ANSI color codes
27
+ #
28
+ # string - The String to wrap.
29
+ # color_code - The String representing he ANSI color code
30
+ #
31
+ # Examples
32
+ #
33
+ # colorize("Boom!", :magenta)
34
+ # # => "\e[35mBoom!\e[0m"
35
+ #
36
+ # Returns the wrapped String.
37
+ def colorize(string, color_code)
38
+ "#{CODES[color_code] || color_code}#{string}#{CODES[:reset]}"
39
+ end
40
+
41
+ # Set up shortcut methods to all the codes define in CODES.
42
+ self.class_eval(CODES.keys.reject {|color| color == :reset }.map do |color|
43
+ "def #{color}(string); colorize(string, :#{color}); end"
44
+ end.join("\n"))
45
+ end
46
+ end
data/lib/boom/command.rb CHANGED
@@ -11,6 +11,7 @@
11
11
  module Boom
12
12
  class Command
13
13
  class << self
14
+ include Boom::Color
14
15
 
15
16
  # Public: accesses the in-memory JSON representation.
16
17
  #
@@ -42,6 +43,14 @@ module Boom
42
43
  puts(s)
43
44
  end
44
45
 
46
+ # Public: gets $stdin.
47
+ #
48
+ # Returns the $stdin object. This method exists to help with easy mocking
49
+ # or overriding.
50
+ def stdin
51
+ $stdin
52
+ end
53
+
45
54
  # Public: prints a tidy overview of your Lists in descending order of
46
55
  # number of Items.
47
56
  #
@@ -93,6 +102,7 @@ module Boom
93
102
  return detail_list(command) unless major
94
103
  unless minor == 'delete'
95
104
  return add_item(command,major,minor) if minor
105
+ return add_item(command,major,stdin.read) if stdin.stat.size > 0
96
106
  return search_list_for_item(command, major)
97
107
  end
98
108
  end
@@ -103,7 +113,7 @@ module Boom
103
113
  return delete_item(command, major)
104
114
  end
105
115
 
106
- return create_list(command)
116
+ return create_list(command, major, minor)
107
117
  end
108
118
 
109
119
  # Public: shows the current user's storage.
@@ -144,10 +154,10 @@ module Boom
144
154
  if storage.list_exists?(major)
145
155
  list = List.find(major)
146
156
  list.items.each { |item| Platform.open(item) }
147
- output "Boom! We just opened all of \"#{major}\" for you."
157
+ output "#{cyan("Boom!")} We just opened all of #{yellow(major)} for you."
148
158
  else
149
159
  item = storage.items.detect { |item| item.name == major }
150
- output Platform.open(item)
160
+ output "#{cyan("Boom!")} We just opened #{yellow(Platform.open(item))} for you."
151
161
  end
152
162
  end
153
163
 
@@ -161,29 +171,33 @@ module Boom
161
171
  item = storage.items.detect do |item|
162
172
  item.name == major
163
173
  end
164
- return output "\"#{major}\" not found" unless item
174
+ return output "#{yellow(major)} #{red("not found")}" unless item
165
175
  else
166
176
  list = List.find(major)
167
177
  item = list.find_item(minor)
168
- return output "\"#{minor}\" not found in \"#{major}\"" unless item
178
+ return output "#{yellow(minor)} #{red("not found in")} #{yellow(major)}" unless item
169
179
  end
170
180
  output item.value
171
181
  end
172
182
 
173
183
  # Public: add a new List.
174
184
  #
175
- # name - the String name of the List.
185
+ # name - the String name of the List.
186
+ # item - the String name of the Item
187
+ # value - the String value of Item
176
188
  #
177
189
  # Example
178
190
  #
179
191
  # Commands.list_create("snippets")
192
+ # Commands.list_create("hotness", "item", "value")
180
193
  #
181
- # Returns the newly created List.
182
- def create_list(name)
194
+ # Returns the newly created List and creates an item when asked.
195
+ def create_list(name, item = nil, value = nil)
183
196
  lists = (storage.lists << List.new(name))
184
197
  storage.lists = lists
185
- output "Boom! Created a new list called \"#{name}\"."
198
+ output "#{cyan("Boom!")} Created a new list called #{yellow(name)}."
186
199
  save
200
+ add_item(name, item, value) unless value.nil?
187
201
  end
188
202
 
189
203
  # Public: remove a named List.
@@ -196,10 +210,10 @@ module Boom
196
210
  #
197
211
  # Returns nothing.
198
212
  def delete_list(name)
199
- output "You sure you want to delete everything in \"#{name}\"? (y/n):"
213
+ output "You sure you want to delete everything in #{yellow(name)}? (y/n):"
200
214
  if $stdin.gets.chomp == 'y'
201
215
  List.delete(name)
202
- output "Boom! Deleted all your #{name}."
216
+ output "#{cyan("Boom!")} Deleted all your #{yellow(name)}."
203
217
  save
204
218
  else
205
219
  output "Just kidding then."
@@ -220,7 +234,7 @@ module Boom
220
234
  def add_item(list,name,value)
221
235
  list = List.find(list)
222
236
  list.add_item(Item.new(name,value))
223
- output "Boom! \"#{name}\" in \"#{list.name}\" is \"#{value}\". Got it."
237
+ output "#{cyan("Boom!")} #{yellow(name)} in #{yellow(list.name)} is #{yellow(value)}. Got it."
224
238
  save
225
239
  end
226
240
 
@@ -237,7 +251,7 @@ module Boom
237
251
  def delete_item(list_name,name)
238
252
  list = List.find(list_name)
239
253
  list.delete_item(name)
240
- output "Boom! \"#{name}\" is gone forever."
254
+ output "#{cyan("Boom!")} #{yellow(name)} is gone forever."
241
255
  save
242
256
  end
243
257
 
@@ -252,7 +266,7 @@ module Boom
252
266
  item.name == name
253
267
  end
254
268
 
255
- output Platform.copy(item)
269
+ output "#{cyan("Boom!")} We just copied #{yellow(Platform.copy(item))} to your clipboard."
256
270
  end
257
271
 
258
272
  # Public: search for an Item in a particular list by name. Drops the
@@ -267,9 +281,9 @@ module Boom
267
281
  item = list.find_item(item_name)
268
282
 
269
283
  if item
270
- output Platform.copy(item)
284
+ output "#{cyan("Boom!")} We just copied #{yellow(Platform.copy(item))} to your clipboard."
271
285
  else
272
- output "\"#{item_name}\" not found in \"#{list_name}\""
286
+ output "#{yellow(item_name)} #{red("not found in")} #{yellow(list_name)}"
273
287
  end
274
288
  end
275
289
 
@@ -287,13 +301,11 @@ module Boom
287
301
  output "You're running boom #{Boom::VERSION}. Congratulations!"
288
302
  end
289
303
 
290
- # Public: launches JSON file in an editor for you to edit manually. Uses
291
- # the $EDITOR environment variable for editing.
304
+ # Public: launches JSON file in an editor for you to edit manually.
292
305
  #
293
306
  # Returns nothing.
294
307
  def edit
295
- system "`echo $EDITOR` #{storage.json_file} &"
296
- output "Boom! Make your edits, and do be sure to save."
308
+ output "#{cyan("Boom!")} #{Platform.edit(storage.json_file)}"
297
309
  end
298
310
 
299
311
  # Public: prints all the commands of boom.
data/lib/boom/platform.rb CHANGED
@@ -10,7 +10,6 @@
10
10
  module Boom
11
11
  class Platform
12
12
  class << self
13
-
14
13
  # Public: tests if currently running on darwin.
15
14
  #
16
15
  # Returns true if running on darwin (MacOS X), else false
@@ -18,6 +17,15 @@ module Boom
18
17
  !!(RUBY_PLATFORM =~ /darwin/)
19
18
  end
20
19
 
20
+ # Public: tests if currently running on windows.
21
+ #
22
+ # Apparently Windows RUBY_PLATFORM can be 'win32' or 'mingw32'
23
+ #
24
+ # Returns true if running on windows (win32/mingw32), else false
25
+ def windows?
26
+ !!(RUBY_PLATFORM =~ /win|mingw/)
27
+ end
28
+
21
29
  # Public: returns the command used to open a file or URL
22
30
  # for the current platform.
23
31
  #
@@ -25,29 +33,70 @@ module Boom
25
33
  #
26
34
  # Returns a String with the bin
27
35
  def open_command
28
- darwin? ? 'open' : 'xdg-open'
36
+ if darwin?
37
+ 'open'
38
+ elsif windows?
39
+ 'start'
40
+ else
41
+ 'xdg-open'
42
+ end
29
43
  end
30
44
 
31
45
  # Public: opens a given Item's value in the browser. This
32
46
  # method is designed to handle multiple platforms.
33
47
  #
34
- # Returns a String explaining what was done
48
+ # Returns a String of the Item value.
35
49
  def open(item)
36
- `#{open_command} '#{item.url.gsub("\'","\\'")}'`
50
+ unless windows?
51
+ system("#{open_command} '#{item.url.gsub("\'","\\'")}'")
52
+ else
53
+ system("#{open_command} #{item.url.gsub("\'","\\'")}")
54
+ end
37
55
 
38
- "Boom! We just opened #{item.value} for you."
56
+ item.value
39
57
  end
40
58
 
59
+ # Public: returns the command used to copy a given Item's value to the
60
+ # clipboard for the current platform.
61
+ #
62
+ # Returns a String with the bin
63
+ def copy_command
64
+ if darwin?
65
+ 'pbcopy'
66
+ elsif windows?
67
+ 'clip'
68
+ else
69
+ 'xclip -selection clipboard'
70
+ end
71
+ end
72
+
41
73
  # Public: copies a given Item's value to the clipboard. This method is
42
74
  # designed to handle multiple platforms.
43
75
  #
44
- # Returns a String explaining what was done
76
+ # Returns the String value of the Item.
45
77
  def copy(item)
46
- copy_command = darwin? ? "pbcopy" : "xclip -selection clipboard"
78
+ unless windows?
79
+ system("printf '#{item.value.gsub("\'","\\'")}' | #{copy_command}")
80
+ else
81
+ system("echo #{item.value.gsub("\'","\\'")} | #{copy_command}")
82
+ end
47
83
 
48
- Kernel.system("echo '#{item.value.gsub("\'","\\'")}' | tr -d \"\n\" | #{copy_command}")
84
+ item.value
85
+ end
86
+
87
+ # Public: opens the JSON file in an editor for you to edit. Uses the
88
+ # $EDITOR environment variable, or %EDITOR% on Windows for editing.
89
+ # This method is designed to handle multiple platforms.
90
+ #
91
+ # Returns a String with a helpful message.
92
+ def edit(json_file)
93
+ unless windows?
94
+ system("`echo $EDITOR` #{json_file} &")
95
+ else
96
+ system("start %EDITOR% #{json_file}")
97
+ end
49
98
 
50
- "Boom! We just copied #{item.value} to your clipboard."
99
+ "Make your edits, and do be sure to save."
51
100
  end
52
101
  end
53
102
  end
data/lib/boom.rb CHANGED
@@ -10,6 +10,7 @@ require 'json/pure'
10
10
 
11
11
  $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
12
12
 
13
+ require 'boom/color'
13
14
  require 'boom/platform'
14
15
  require 'boom/command'
15
16
  require 'boom/config'
@@ -26,7 +27,7 @@ require 'boom/storage/keychain'
26
27
  require 'boom/core_ext/symbol'
27
28
 
28
29
  module Boom
29
- VERSION = '0.2.0'
30
+ VERSION = '0.2.1'
30
31
 
31
32
  extend self
32
33
 
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+
3
+ require 'helper'
4
+
5
+ class TestColor < Test::Unit::TestCase
6
+
7
+ def test_colorize
8
+ assert_equal "\e[35mBoom!\e[0m",
9
+ Boom::Color.colorize("Boom!", :magenta)
10
+ end
11
+
12
+ def test_magenta
13
+ assert_equal "\e[35mMagenta!\e[0m",
14
+ Boom::Color.magenta("Magenta!")
15
+ end
16
+
17
+ def test_red
18
+ assert_equal "\e[31mRed!\e[0m",
19
+ Boom::Color.red("Red!")
20
+ end
21
+
22
+ def test_yellow
23
+ assert_equal "\e[33mYellow!\e[0m",
24
+ Boom::Color.yellow("Yellow!")
25
+ end
26
+ end
data/test/test_command.rb CHANGED
@@ -33,7 +33,8 @@ class TestCommand < Test::Unit::TestCase
33
33
  cmd = cmd.split(' ') if cmd
34
34
  Boom::Command.capture_output
35
35
  Boom::Command.execute(*cmd)
36
- Boom::Command.captured_output
36
+ output = Boom::Command.captured_output
37
+ output.gsub(/\e\[\d\d?m/, '')
37
38
  end
38
39
 
39
40
  def test_overview_for_empty
@@ -58,7 +59,11 @@ class TestCommand < Test::Unit::TestCase
58
59
  end
59
60
 
60
61
  def test_list_creation
61
- assert_match /a new list called "newlist"/, command('newlist')
62
+ assert_match /a new list called newlist/, command('newlist')
63
+ end
64
+
65
+ def test_list_creation_with_item
66
+ assert_match /a new list called newlist.* item in newlist/, command('newlist item blah')
62
67
  end
63
68
 
64
69
  def test_item_access
@@ -72,24 +77,22 @@ class TestCommand < Test::Unit::TestCase
72
77
  end
73
78
 
74
79
  def test_item_open_url
75
- Boom::Platform.stubs(:open_command).returns("echo")
76
- assert_match /opened https:\/\/github\.com for you/,
77
- command('open github')
80
+ Boom::Platform.stubs(:system).returns('')
81
+ assert_match /opened https:\/\/github\.com for you/, command('open github')
78
82
  end
79
83
 
80
84
  def test_item_open_lists
81
- Boom::Platform.stubs(:open_command).returns("echo")
82
- assert_match /opened all of \"urls\" for you/,
83
- command('open urls')
85
+ Boom::Platform.stubs(:system).returns('')
86
+ assert_match /opened all of urls for you/, command('open urls')
84
87
  end
85
88
 
86
89
  def test_item_creation
87
- assert_match /"twitter" in "urls"/,
90
+ assert_match /twitter in urls/,
88
91
  command('urls twitter http://twitter.com/holman')
89
92
  end
90
93
 
91
94
  def test_item_creation_long_value
92
- assert_match /is "tanqueray hendricks bombay"/,
95
+ assert_match /is tanqueray hendricks bombay/,
93
96
  command('urls gins tanqueray hendricks bombay')
94
97
  end
95
98
 
@@ -104,11 +107,11 @@ class TestCommand < Test::Unit::TestCase
104
107
  end
105
108
 
106
109
  def test_item_deletion
107
- assert_match /"github" is gone forever/, command('urls github delete')
110
+ assert_match /github is gone forever/, command('urls github delete')
108
111
  end
109
112
 
110
113
  def test_edit
111
- Boom::Command.stubs(:system).returns('')
114
+ Boom::Platform.stubs(:system).returns('')
112
115
  assert_match 'Make your edits', command('edit')
113
116
  end
114
117
 
@@ -124,7 +127,7 @@ class TestCommand < Test::Unit::TestCase
124
127
  end
125
128
 
126
129
  def test_nonexistent_item_access_scoped_by_list
127
- assert_match /"twitter" not found in "urls"/, command('urls twitter')
130
+ assert_match /twitter not found in urls/, command('urls twitter')
128
131
  end
129
132
 
130
133
  def test_echo_item
@@ -136,7 +139,7 @@ class TestCommand < Test::Unit::TestCase
136
139
  end
137
140
 
138
141
  def test_echo_item_does_not_exist
139
- assert_match /"wrong" not found/, command('echo wrong')
142
+ assert_match /wrong not found/, command('echo wrong')
140
143
  end
141
144
 
142
145
  def test_echo_list_item
@@ -144,10 +147,11 @@ class TestCommand < Test::Unit::TestCase
144
147
  end
145
148
 
146
149
  def test_echo_list_item_does_not_exist
147
- assert_match /"wrong" not found in "urls"/, command('echo urls wrong')
150
+ assert_match /wrong not found in urls/, command('echo urls wrong')
148
151
  end
149
152
 
150
153
  def test_show_storage
154
+ Boom::Config.any_instance.stubs(:attributes).returns('backend' => 'json')
151
155
  assert_match /You're currently using json/, command('storage')
152
156
  end
153
157
 
@@ -168,4 +172,12 @@ class TestCommand < Test::Unit::TestCase
168
172
  def test_version_long
169
173
  assert_match /#{Boom::VERSION}/, command('--version')
170
174
  end
175
+
176
+ def test_stdin_pipes
177
+ stub = Object.new
178
+ stub.stubs(:stat).returns([1,2])
179
+ stub.stubs(:read).returns("http://twitter.com")
180
+ Boom::Command.stubs(:stdin).returns(stub)
181
+ assert_match /twitter in urls/, command('urls twitter')
182
+ end
171
183
  end
@@ -0,0 +1,15 @@
1
+ require 'helper'
2
+
3
+ class TestPlatform < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_darwin
9
+ assert_equal Boom::Platform.darwin?, RUBY_PLATFORM.include?('darwin')
10
+ end
11
+
12
+ def test_windows
13
+ assert_equal Boom::Platform.windows?, true if RUBY_PLATFORM =~ /win|mingw/
14
+ end
15
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: boom
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 0
10
- version: 0.2.0
9
+ - 1
10
+ version: 0.2.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Zach Holman
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-11 00:00:00 -07:00
18
+ date: 2011-07-16 00:00:00 +09:00
19
19
  default_executable: boom
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -79,6 +79,7 @@ files:
79
79
  - completion/boom.bash
80
80
  - completion/boom.zsh
81
81
  - lib/boom.rb
82
+ - lib/boom/color.rb
82
83
  - lib/boom/command.rb
83
84
  - lib/boom/config.rb
84
85
  - lib/boom/core_ext/symbol.rb
@@ -95,10 +96,12 @@ files:
95
96
  - test/examples/test_json.json
96
97
  - test/examples/urls.json
97
98
  - test/helper.rb
99
+ - test/test_color.rb
98
100
  - test/test_command.rb
99
101
  - test/test_config.rb
100
102
  - test/test_item.rb
101
103
  - test/test_list.rb
104
+ - test/test_platform.rb
102
105
  has_rdoc: true
103
106
  homepage: https://github.com/holman/boom
104
107
  licenses: []
@@ -134,7 +137,9 @@ signing_key:
134
137
  specification_version: 2
135
138
  summary: boom lets you access text snippets over your command line.
136
139
  test_files:
140
+ - test/test_color.rb
137
141
  - test/test_command.rb
138
142
  - test/test_config.rb
139
143
  - test/test_item.rb
140
144
  - test/test_list.rb
145
+ - test/test_platform.rb