boom 0.1.2 → 0.2.0

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,6 +2,16 @@
2
2
 
3
3
  ## head
4
4
 
5
+ ## 0.2.0
6
+ - Add Keychain storage to store Boom data securely in OS X's Keychain.app.
7
+ Thanks, [@davidtrogers](https://github.com/davidtrogers)!
8
+ - Switch from yajl-ruby because [OS X isn't for
9
+ developers](http://zachholman.com/2011/03/osx-isnt-for-developers/). Thanks
10
+ for finishing it up, [@antonlindstrom](https://github.com/antonlindstrom).
11
+ - Move dependencies to Bundler, because it's the One True Way™ at this point.
12
+ - Some README updates.
13
+ - `boom -v`.
14
+
5
15
  ## 0.1.2
6
16
  - Copy to clipboard doesn't hang anymore. Sweet. Thanks,
7
17
  [mcollina](https://github.com/mcollina).
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,18 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ boom (0.1.2)
5
+ json_pure (~> 1.5.1)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ json_pure (1.5.1)
11
+ mocha (0.9.12)
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ boom!
18
+ mocha (~> 0.9.9)
data/README.markdown CHANGED
@@ -13,12 +13,30 @@ For more details about what boom is and how it works, check out
13
13
 
14
14
  gem install boom
15
15
 
16
+ ## Quick and Dirty
17
+
18
+ $ boom gifs
19
+ Boom! Created a new list called "gifs".
20
+
21
+ $ boom gifs melissa http://cl.ly/3pAn/animated.gif
22
+ Boom! "melissa" in "gifs" is "http://cl.ly/3pAn/animated.gif". Got it.
23
+
24
+ $ boom melissa
25
+ Boom! Just copied http://cl.ly/3pAn/animated.gif to your clipboard.
26
+
27
+ And that's just a taste! I know, you're salivating, I can hear you from here.
28
+ (Why your saliva is noisy is beyond me.) Check out the [full list of
29
+ commands](https://github.com/holman/boom/wiki/Commands).
30
+
16
31
  ## Contribute
17
32
 
18
- I'd love to include your contributions, friend. Make sure your methods are
19
- [TomDoc](http://tomdoc.org)'d properly, that existing tests pass (`rake`), and
20
- that any new functionality includes appropriate tests. Bonus points if you're
21
- not updating the gemspec or bumping boom's version.
33
+ I'd love to include your contributions, friend.
34
+
35
+ Clone this repository, then run `bundle install`. That'll install all the gem
36
+ dependencies. Make sure your methods are [TomDoc](http://tomdoc.org)'d
37
+ properly, that existing tests pass (`rake`), and that any new functionality
38
+ includes appropriate tests. Bonus points if you're not updating the gemspec or
39
+ bumping boom's version.
22
40
 
23
41
  All good? Cool! Then [send me a pull request](https://github.com/holman/boom/pull/new/master)!
24
42
 
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.1.2'
17
- s.date = '2011-03-11'
16
+ s.version = '0.2.0'
17
+ s.date = '2011-04-11'
18
18
  s.rubyforge_project = 'boom'
19
19
 
20
20
  ## Make sure your summary is short. The description may be as long
@@ -54,7 +54,7 @@ Gem::Specification.new do |s|
54
54
 
55
55
  ## List your runtime dependencies here. Runtime dependencies are those
56
56
  ## that are needed for an end user to actually USE your code.
57
- s.add_dependency('yajl-ruby', "~> 0.7.8")
57
+ s.add_dependency('json_pure', "~> 1.5.1")
58
58
 
59
59
  ## List your development dependencies here. Development dependencies are
60
60
  ## those that are only needed during development
@@ -66,6 +66,8 @@ Gem::Specification.new do |s|
66
66
  # = MANIFEST =
67
67
  s.files = %w[
68
68
  CHANGELOG.markdown
69
+ Gemfile
70
+ Gemfile.lock
69
71
  LICENSE.markdown
70
72
  README.markdown
71
73
  Rakefile
@@ -84,6 +86,7 @@ Gem::Specification.new do |s|
84
86
  lib/boom/storage.rb
85
87
  lib/boom/storage/base.rb
86
88
  lib/boom/storage/json.rb
89
+ lib/boom/storage/keychain.rb
87
90
  lib/boom/storage/mongodb.rb
88
91
  lib/boom/storage/redis.rb
89
92
  test/examples/config_json.json
data/lib/boom.rb CHANGED
@@ -6,7 +6,7 @@ rescue LoadError
6
6
  end
7
7
 
8
8
  require 'fileutils'
9
- require 'yajl'
9
+ require 'json/pure'
10
10
 
11
11
  $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
12
12
 
@@ -21,11 +21,12 @@ require 'boom/storage/base'
21
21
  require 'boom/storage/json'
22
22
  require 'boom/storage/redis'
23
23
  require 'boom/storage/mongodb'
24
+ require 'boom/storage/keychain'
24
25
 
25
26
  require 'boom/core_ext/symbol'
26
27
 
27
28
  module Boom
28
- VERSION = '0.1.2'
29
+ VERSION = '0.2.0'
29
30
 
30
31
  extend self
31
32
 
data/lib/boom/command.rb CHANGED
@@ -76,12 +76,14 @@ module Boom
76
76
  #
77
77
  # Returns output based on method calls.
78
78
  def delegate(command, major, minor)
79
- return all if command == 'all'
80
- return edit if command == 'edit'
81
- return switch(major) if command == 'switch'
82
- return show_storage if command == 'storage'
83
- return help if command == 'help'
84
- return help if command[0] == 45 || command[0] == '-' # any - dash options are pleas for help
79
+ return all if command == 'all'
80
+ return edit if command == 'edit'
81
+ return switch(major) if command == 'switch'
82
+ return show_storage if command == 'storage'
83
+ return version if command == "-v"
84
+ return version if command == "--version"
85
+ return help if command == 'help'
86
+ return help if command[0] == 45 || command[0] == '-' # any - dash options are pleas for help
85
87
  return echo(major,minor) if command == 'echo' || command == 'e'
86
88
  return open(major,minor) if command == 'open' || command == 'o'
87
89
 
@@ -278,6 +280,13 @@ module Boom
278
280
  storage.save
279
281
  end
280
282
 
283
+ # Public: the version of boom that you're currently running.
284
+ #
285
+ # Returns a String identifying the version number.
286
+ def version
287
+ output "You're running boom #{Boom::VERSION}. Congratulations!"
288
+ end
289
+
281
290
  # Public: launches JSON file in an editor for you to edit manually. Uses
282
291
  # the $EDITOR environment variable for editing.
283
292
  #
data/lib/boom/config.rb CHANGED
@@ -74,14 +74,14 @@ module Boom
74
74
  #
75
75
  # Returns nothing.
76
76
  def load_attributes
77
- @attributes = Yajl::Parser.new.parse(File.new(file, 'r'))
77
+ @attributes = JSON.parse(File.new(file, 'r').read)
78
78
  end
79
79
 
80
80
  # Public: writes the in-memory JSON Hash to disk.
81
81
  #
82
82
  # Returns nothing.
83
83
  def save
84
- json = Yajl::Encoder.encode(attributes, :pretty => true)
84
+ json = JSON.generate(attributes)
85
85
  File.open(file, 'w') {|f| f.write(json) }
86
86
  end
87
87
 
@@ -32,7 +32,7 @@ module Boom
32
32
  #
33
33
  # Returns nothing.
34
34
  def populate
35
- storage = Yajl::Parser.new.parse(File.new(json_file, 'r'))
35
+ storage = JSON.parse(File.new(json_file, 'r').read)
36
36
 
37
37
  storage['lists'].each do |lists|
38
38
  lists.each do |list_name, items|
@@ -61,7 +61,7 @@ module Boom
61
61
  #
62
62
  # Returns a String Json representation of its Lists and their Items.
63
63
  def to_json
64
- Yajl::Encoder.encode(to_hash, :pretty => true)
64
+ JSON.generate(to_hash)
65
65
  end
66
66
 
67
67
  end
@@ -0,0 +1,129 @@
1
+ # coding: utf-8
2
+
3
+ # Keychain provides methods for using Mac OS X's Keychain as a storage option.
4
+ # It saves lists as Keychain files in ~/Library/Keychains with the filename
5
+ # format being: "Boom.list.mylist.keychain"
6
+ #
7
+ module Boom
8
+ module Storage
9
+ class Keychain < Base
10
+
11
+ KEYCHAIN_FORMAT = %r{Boom\.list\.(.+)\.keychain}
12
+
13
+ # Opens Keychain app when json_file is called during `boom edit`
14
+ #
15
+ # Returns nothing
16
+ def open_keychain_app
17
+ `open /Applications/Utilities/'Keychain Access.app' &`
18
+ end
19
+
20
+ alias_method :json_file, :open_keychain_app
21
+
22
+ # Boostraps Keychain by asking if you're using Mac OS X which is a prereq
23
+ #
24
+ # Returns true on a Mac
25
+ def bootstrap
26
+ raise RuntimeError unless Boom::Platform.darwin?
27
+ true
28
+ rescue
29
+ puts(e 'No Keychain utility to access, maybe try another storage option?')
30
+ false
31
+ end
32
+
33
+ # Populate the in-memory store with all the lists and items from Keychain
34
+ #
35
+ # Returns Array of keychain names, i.e. ["Boom.list.mylist.keychain"]
36
+ def populate
37
+ stored_keychain_lists.each do |keychain|
38
+ @lists << list = List.new(keychain.scan(KEYCHAIN_FORMAT).flatten.first)
39
+ extract_keychain_items(keychain).each do |name|
40
+ list.add_item(Item.new(name, extract_keychain_value(name, keychain)))
41
+ end
42
+ end
43
+ end
44
+
45
+ # Saves the data from memory to the correct Keychain
46
+ #
47
+ # Returns nothing
48
+ def save
49
+ @lists.each do |list|
50
+ keychain_name = list_to_filename(list.name)
51
+ create_keychain_list(keychain_name) unless stored_keychain_lists.include?(keychain_name)
52
+ unless list.items.empty?
53
+ list.items.each do |item|
54
+ store_item(item, keychain_name)
55
+ end
56
+ end
57
+ delete_unwanted_items(list)
58
+ end
59
+ delete_unwanted_lists
60
+ rescue RuntimeError
61
+ puts(e "Couldn't save to your keychain, check Console.app or above for relevant messages")
62
+ end
63
+
64
+
65
+ private
66
+
67
+ # Returns an Array of keychains stored in ~/Library/Keychains:
68
+ # => ["Boom.list.mylist.keychain"]
69
+ def stored_keychain_lists
70
+ @stored_keychain_lists ||= `security -q list-keychains |grep Boom.list` \
71
+ .split(/[\/\n\"]/).select {|kc| kc =~ KEYCHAIN_FORMAT}
72
+ end
73
+
74
+ # Create the keychain list "Boom.list.mylist.keychain" in ~/Library/Keychains
75
+ def create_keychain_list(keychain_name)
76
+ `security -q create-keychain #{keychain_name}`
77
+ end
78
+
79
+ # Saves the individual item's value to the right list/keychain
80
+ def store_item(item, keychain_name)
81
+ `security 2>/dev/null -q add-generic-password -a '#{item.name}' -s '#{item.name}' -w '#{item.value}' #{keychain_name}`
82
+ end
83
+
84
+ # Retrieves the value of a particular item in a list
85
+ def extract_keychain_value(item_name, keychain)
86
+ `security 2>&1 >/dev/null find-generic-password -ga '#{item_name}' #{keychain}`.chomp.split('"').last
87
+ end
88
+
89
+ # Gets all items in a particular list
90
+ def extract_keychain_items(keychain_name)
91
+ @stored_items ||= {}
92
+ @stored_items[keychain_name] ||= `security dump-keychain -a #{keychain_name} |grep acct` \
93
+ .split(/\s|\\n|\\"|acct|<blob>=|\"/).reject {|f| f.empty?}
94
+ end
95
+
96
+ # Converts list name to the corresponding keychain filename format based
97
+ # on the KEYCHAIN_FORMAT
98
+ def list_to_filename(list_name)
99
+ KEYCHAIN_FORMAT.source.gsub(/\(\.\+\)/, list_name).gsub('\\','')
100
+ end
101
+
102
+ # Delete's a keychain file
103
+ def delete_list(keychain_filename)
104
+ `security delete-keychain #{keychain_filename}`
105
+ end
106
+
107
+ # Delete's all keychain files you don't want anymore
108
+ def delete_unwanted_lists
109
+ (stored_keychain_lists - @lists.map {|list| list_to_filename(list.name)}).each do |filename|
110
+ delete_list(filename)
111
+ end
112
+ end
113
+
114
+ # Removes unwanted items in a list
115
+ # security util doesn't have a delete password option so we'll have to
116
+ # drop it and recreate it with what is in memory
117
+ def delete_unwanted_items(list)
118
+ filename = list_to_filename(list.name)
119
+ if (list.items.size < extract_keychain_items(filename).size)
120
+ delete_list(filename)
121
+ create_keychain_list(filename)
122
+ list.items.each do |item|
123
+ store_item(item, filename)
124
+ end unless list.items.empty?
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -3,7 +3,6 @@
3
3
  # Storage adapter that saves data from boom to MongoDB instead of JSON file.
4
4
  begin
5
5
  require 'mongo'
6
- require 'json/pure' # Will be here for now See Issue#21
7
6
  rescue LoadError
8
7
  end
9
8
 
data/test/test_command.rb CHANGED
@@ -161,4 +161,11 @@ class TestCommand < Test::Unit::TestCase
161
161
  assert_match /We've switched you over to redis/, command('switch redis')
162
162
  end
163
163
 
164
+ def test_version_switch
165
+ assert_match /#{Boom::VERSION}/, command('-v')
166
+ end
167
+
168
+ def test_version_long
169
+ assert_match /#{Boom::VERSION}/, command('--version')
170
+ end
164
171
  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: 31
5
- prerelease: false
4
+ hash: 23
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
9
8
  - 2
10
- version: 0.1.2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Zach Holman
@@ -15,23 +15,23 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-11 00:00:00 -08:00
18
+ date: 2011-04-11 00:00:00 -07:00
19
19
  default_executable: boom
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: yajl-ruby
22
+ name: json_pure
23
23
  prerelease: false
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- hash: 19
29
+ hash: 1
30
30
  segments:
31
- - 0
32
- - 7
33
- - 8
34
- version: 0.7.8
31
+ - 1
32
+ - 5
33
+ - 1
34
+ version: 1.5.1
35
35
  type: :runtime
36
36
  version_requirements: *id001
37
37
  - !ruby/object:Gem::Dependency
@@ -68,6 +68,8 @@ extra_rdoc_files:
68
68
  - LICENSE.markdown
69
69
  files:
70
70
  - CHANGELOG.markdown
71
+ - Gemfile
72
+ - Gemfile.lock
71
73
  - LICENSE.markdown
72
74
  - README.markdown
73
75
  - Rakefile
@@ -86,6 +88,7 @@ files:
86
88
  - lib/boom/storage.rb
87
89
  - lib/boom/storage/base.rb
88
90
  - lib/boom/storage/json.rb
91
+ - lib/boom/storage/keychain.rb
89
92
  - lib/boom/storage/mongodb.rb
90
93
  - lib/boom/storage/redis.rb
91
94
  - test/examples/config_json.json
@@ -126,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
129
  requirements: []
127
130
 
128
131
  rubyforge_project: boom
129
- rubygems_version: 1.3.7
132
+ rubygems_version: 1.6.2
130
133
  signing_key:
131
134
  specification_version: 2
132
135
  summary: boom lets you access text snippets over your command line.