boom 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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