boom 0.2.4 → 0.3.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.
@@ -1,5 +1,14 @@
1
1
  # boom changes
2
2
  ## head
3
+
4
+ ## 0.3.0
5
+ - 0.3 removes all the Storage nonsense in favor of clean and easy JSON. Less
6
+ code is best code.
7
+ - It also removes all the Ruby tests and instead does them in shell with roundup.
8
+ - It also changes delete to use `--delete` so there's conceptually less of a
9
+ problem.
10
+
11
+ ## 0.2.4
3
12
  - [@Dlom](https://github.com/Dlom) fixed some troubles in #49.
4
13
  - Some additional test coverage added by
5
14
  [@nickhammond](https://github.com/nickhammond).
@@ -66,8 +75,8 @@
66
75
  scripts and junk! Thanks [bschaeffer](https://github.com/bschaeffer).
67
76
 
68
77
  ## 0.0.9
69
- - Backport `Symbol#to_proc` for 1.8.6 support (thanks
70
- [kastner](https://github.com/kastner) and
78
+ - Backport `Symbol#to_proc` for 1.8.6 support (thanks
79
+ [kastner](https://github.com/kastner) and
71
80
  [DeMarko](https://github.com/DeMarko)).
72
81
 
73
82
  ## 0.0.8
@@ -81,7 +90,7 @@
81
90
  (thanks [jimmycuadra](https://github.com/jimmycuadra)).
82
91
  - Output is a bit cleaner with a constrained `name` column.
83
92
  - Adds items from stdin (thanks
84
- [MichaelXavier](https://github.com/MichaelXavier)).
93
+ [MichaelXavier](https://github.com/MichaelXavier)).
85
94
 
86
95
  ## 0.0.5
87
96
  - Item deletes are now scoped by list rather than GLOBAL DESTRUCTION! (thanks
data/Gemfile.lock CHANGED
@@ -1,17 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- boom (0.2.3)
5
- json_pure (~> 1.5.3)
6
- multi_json (~> 1.0.3)
4
+ boom (0.2.4)
5
+ yajl-ruby (~> 1.1.0)
7
6
 
8
7
  GEM
9
8
  remote: http://rubygems.org/
10
9
  specs:
11
- json_pure (1.5.3)
12
10
  mocha (0.9.12)
13
- multi_json (1.0.3)
14
11
  rake (0.9.2)
12
+ yajl-ruby (1.1.0)
15
13
 
16
14
  PLATFORMS
17
15
  ruby
File without changes
@@ -2,12 +2,12 @@
2
2
 
3
3
  ## About
4
4
 
5
- boom manages your text snippets. On the command line. I just blew your mind.
5
+ boom manages your text snippets on your command line. You can stash away text
6
+ like URLs, canned responses, and important notes and then quickly copy them
7
+ onto your clipboard, ready for pasting.
6
8
 
7
9
  For more details about what boom is and how it works, check out
8
- [boom's website](http://holman.github.com/boom). For full usage details
9
- (including a complete list of commands), check out
10
- [boom's wiki](https://github.com/holman/boom/wiki).
10
+ [boom's website](http://holman.github.com/boom).
11
11
 
12
12
  ## Install
13
13
 
@@ -18,11 +18,11 @@ For more details about what boom is and how it works, check out
18
18
  $ boom gifs
19
19
  Boom! Created a new list called "gifs".
20
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.
21
+ $ boom gifs shirt http://cl.ly/NwCS/shirt.gif
22
+ Boom! "shirt" in "gifs" is "http://cl.ly/NwCS/shirt.gif". Got it.
23
23
 
24
- $ boom melissa
25
- Boom! Just copied http://cl.ly/3pAn/animated.gif to your clipboard.
24
+ $ boom shirt
25
+ Boom! Just copied http://cl.ly/NwCS/shirt.gif to your clipboard.
26
26
 
27
27
  And that's just a taste! I know, you're salivating, I can hear you from here.
28
28
  (Why your saliva is noisy is beyond me.) Check out the [full list of
@@ -37,8 +37,11 @@ your contributions, friend.
37
37
  Clone this repository, then run `bundle install`. That'll install all the gem
38
38
  dependencies. Make sure your methods are [TomDoc](http://tomdoc.org)'d
39
39
  properly, that existing tests pass (`rake`), and that any new functionality
40
- includes appropriate tests. Bonus points if you're not updating the gemspec or
41
- bumping boom's version.
40
+ includes appropriate tests.
41
+
42
+ The tests are written in shell for
43
+ [roundup](https://github.com/bmizerany/roundup), since boom is basically just
44
+ Ruby pretending to be shell. `rake` should run them all for you just fine.
42
45
 
43
46
  All good? Cool! Then [send me a pull request](https://github.com/holman/boom/pull/new/master)!
44
47
 
@@ -48,4 +51,4 @@ All good? Cool! Then [send me a pull request](https://github.com/holman/boom/pul
48
51
  [@holman](http://twitter.com/holman) — if you're having issues, want me to
49
52
  merge in your pull request, or are using boom in a cool way. I'm kind of hoping
50
53
  this is generic enough that people do some fun things with it. First one to use
51
- `boom` to calculate their tax liability wins.
54
+ `boom` to calculate their tax liability wins.
data/Rakefile CHANGED
@@ -45,11 +45,9 @@ end
45
45
 
46
46
  task :default => :test
47
47
 
48
- require 'rake/testtask'
49
- Rake::TestTask.new(:test) do |test|
50
- test.libs << 'lib' << 'test'
51
- test.pattern = 'test/**/test_*.rb'
52
- test.verbose = true
48
+ desc "Run tests for boom"
49
+ task :test do
50
+ exec "test/run"
53
51
  end
54
52
 
55
53
  desc "Open an irb session preloaded with this library"
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.4'
17
- s.date = '2013-03-15'
16
+ s.version = '0.3.0'
17
+ s.date = '2013-03-29'
18
18
  s.rubyforge_project = 'boom'
19
19
 
20
20
  ## Make sure your summary is short. The description may be as long
@@ -32,7 +32,7 @@ Gem::Specification.new do |s|
32
32
  ## better to set the email to an email list or something. If you don't have
33
33
  ## a custom homepage, consider using your GitHub URL or the like.
34
34
  s.authors = ["Zach Holman"]
35
- s.email = 'github.com@zachholman.com'
35
+ s.email = 'zach@zachholman.com'
36
36
  s.homepage = 'https://github.com/holman/boom'
37
37
 
38
38
  ## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
@@ -50,12 +50,11 @@ Gem::Specification.new do |s|
50
50
  ## Specify any RDoc options here. You'll want to add your README and
51
51
  ## LICENSE files to the extra_rdoc_files list.
52
52
  s.rdoc_options = ["--charset=UTF-8"]
53
- s.extra_rdoc_files = %w[README.markdown LICENSE.markdown]
53
+ s.extra_rdoc_files = %w[README.md LICENSE.md]
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('multi_json', "~> 1.0.3")
58
- s.add_dependency('json_pure', "~> 1.5.3")
57
+ s.add_dependency('yajl-ruby', "~> 1.1.0")
59
58
 
60
59
  ## List your development dependencies here. Development dependencies are
61
60
  ## those that are only needed during development
@@ -67,11 +66,11 @@ Gem::Specification.new do |s|
67
66
  ## THE MANIFEST COMMENTS, they are used as delimiters by the task.
68
67
  # = MANIFEST =
69
68
  s.files = %w[
70
- CHANGELOG.markdown
69
+ CHANGELOG.md
71
70
  Gemfile
72
71
  Gemfile.lock
73
- LICENSE.markdown
74
- README.markdown
72
+ LICENSE.md
73
+ README.md
75
74
  Rakefile
76
75
  bin/boom
77
76
  boom.gemspec
@@ -81,28 +80,17 @@ Gem::Specification.new do |s|
81
80
  lib/boom.rb
82
81
  lib/boom/color.rb
83
82
  lib/boom/command.rb
84
- lib/boom/config.rb
85
83
  lib/boom/core_ext/symbol.rb
86
84
  lib/boom/item.rb
87
85
  lib/boom/list.rb
88
86
  lib/boom/platform.rb
89
87
  lib/boom/storage.rb
90
- lib/boom/storage/base.rb
91
- lib/boom/storage/gist.rb
92
- lib/boom/storage/json.rb
93
- lib/boom/storage/keychain.rb
94
- lib/boom/storage/mongodb.rb
95
- lib/boom/storage/redis.rb
96
- test/examples/config_json.json
97
- test/examples/test_json.json
98
- test/examples/urls.json
99
- test/helper.rb
100
- test/test_color.rb
101
- test/test_command.rb
102
- test/test_config.rb
103
- test/test_item.rb
104
- test/test_list.rb
105
- test/test_platform.rb
88
+ test/cli.sh
89
+ test/examples/data.json
90
+ test/item.sh
91
+ test/list.sh
92
+ test/roundup
93
+ test/run
106
94
  ]
107
95
  # = MANIFEST =
108
96
 
data/lib/boom/command.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
 
3
3
  # Command is the main point of entry for boom commands; shell arguments are
4
- # passd through to Command, which then filters and parses through individual
4
+ # passed through to Command, which then filters and parses through individual
5
5
  # commands and reroutes them to constituent object classes.
6
6
  #
7
7
  # Command also keeps track of one connection to Storage, which is how new data
@@ -87,8 +87,6 @@ module Boom
87
87
  def delegate(command, major, minor)
88
88
  return all if command == 'all'
89
89
  return edit if command == 'edit'
90
- return switch(major) if command == 'switch'
91
- return show_storage if command == 'storage'
92
90
  return version if command == "-v"
93
91
  return version if command == "--version"
94
92
  return help if command == 'help'
@@ -99,16 +97,16 @@ module Boom
99
97
 
100
98
  # if we're operating on a List
101
99
  if storage.list_exists?(command)
102
- return delete_list(command) if major == 'delete'
100
+ return delete_list(command) if major == '--delete'
103
101
  return detail_list(command) unless major
104
- unless minor == 'delete'
102
+ unless minor == '--delete'
105
103
  return add_item(command,major,minor) if minor
106
104
  return add_item(command,major,stdin.read) if stdin.stat.size > 0
107
105
  return search_list_for_item(command, major)
108
106
  end
109
107
  end
110
108
 
111
- if minor == 'delete' and storage.item_exists?(major)
109
+ if minor == '--delete' and storage.item_exists?(major)
112
110
  return delete_item(command, major)
113
111
  end
114
112
 
@@ -118,25 +116,6 @@ module Boom
118
116
  return create_list(command, major, minor)
119
117
  end
120
118
 
121
- # Public: shows the current user's storage.
122
- #
123
- # Returns nothing.
124
- def show_storage
125
- output "You're currently using #{Boom.config.attributes['backend']}."
126
- end
127
-
128
- # Public: switch to a new backend.
129
- #
130
- # backend - the String of the backend desired
131
- #
132
- # Returns nothing.
133
- def switch(backend)
134
- Storage.backend = backend
135
- output "We've switched you over to #{backend}."
136
- rescue NameError
137
- output "We couldn't find that storage engine. Check the name and try again."
138
- end
139
-
140
119
  # Public: prints all Items over a List.
141
120
  #
142
121
  # name - the List object to iterate over
@@ -234,7 +213,7 @@ module Boom
234
213
  #
235
214
  # Returns nothing.
236
215
  def delete_list(name)
237
- output "You sure you want to delete everything in #{yellow(name)}? (y/n):"
216
+ printf "You sure you want to delete everything in #{yellow(name)}? (y/n): "
238
217
  if $stdin.gets.chomp == 'y'
239
218
  List.delete(name)
240
219
  output "#{cyan("Boom!")} Deleted all your #{yellow(name)}."
@@ -336,11 +315,7 @@ module Boom
336
315
  #
337
316
  # Returns nothing.
338
317
  def edit
339
- if storage.respond_to?("json_file")
340
- output "#{cyan("Boom!")} #{Platform.edit(storage.json_file)}"
341
- else
342
- output "This storage backend does not store #{cyan("Boom!")} data on your computer"
343
- end
318
+ output "#{cyan("Boom!")} #{Platform.edit(storage.json_file)}"
344
319
  end
345
320
 
346
321
  # Public: prints all the commands of boom.
@@ -354,12 +329,10 @@ module Boom
354
329
  boom all show all items in all lists
355
330
  boom edit edit the boom JSON file in $EDITOR
356
331
  boom help this help text
357
- boom storage shows which storage backend you're using
358
- boom switch <storage> switches to a different storage backend
359
332
 
360
333
  boom <list> create a new list
361
334
  boom <list> show items for a list
362
- boom <list> delete deletes a list
335
+ boom <list> --delete deletes a list
363
336
 
364
337
  boom <list> <name> <value> create a new list item
365
338
  boom <name> copy item's value to clipboard
@@ -370,7 +343,7 @@ module Boom
370
343
  boom random <list> open a random item's url for a list in browser
371
344
  boom echo <name> echo the item's value without copying
372
345
  boom echo <list> <name> echo the item's value without copying
373
- boom <list> <name> delete deletes an item
346
+ boom <list> <name> --delete deletes an item
374
347
 
375
348
  all other documentation is located at:
376
349
  https://github.com/holman/boom
data/lib/boom/item.rb CHANGED
@@ -6,7 +6,6 @@
6
6
  #
7
7
  module Boom
8
8
  class Item
9
-
10
9
  # Public: the String name of the Item
11
10
  attr_accessor :name
12
11
 
@@ -54,7 +53,7 @@ module Boom
54
53
  end
55
54
 
56
55
  # Public: only return url part of value - if no url has been
57
- # detected returns value.
56
+ # detected it'll return the value.
58
57
  #
59
58
  # Returns a String which preferably is a URL.
60
59
  def url
@@ -67,6 +66,5 @@ module Boom
67
66
  def to_hash
68
67
  { @name => @value }
69
68
  end
70
-
71
69
  end
72
- end
70
+ end
data/lib/boom/list.rb CHANGED
@@ -81,7 +81,7 @@ module Boom
81
81
  #
82
82
  # name - String name of the Item to find
83
83
  #
84
- # Returns the found item
84
+ # Returns the found item.
85
85
  def find_item(name)
86
86
  items.find do |item|
87
87
  item.name == name ||
data/lib/boom/storage.rb CHANGED
@@ -1,22 +1,124 @@
1
- # coding: utf-8
2
-
3
1
  #
4
2
  # Storage is the interface between multiple Backends. You can use Storage
5
3
  # directly without having to worry about which Backend is in use.
6
4
  #
7
5
  module Boom
8
- module Storage
9
-
10
- def self.backend=(backend)
11
- backend = backend.capitalize
12
- Boom::Storage.const_get(backend)
13
- Boom.config.attributes['backend'] = backend.downcase
14
- Boom.config.save
6
+ class Storage
7
+ JSON_FILE = "#{ENV['HOME']}/.boom"
8
+
9
+ # Public: the path to the Json file used by boom.
10
+ #
11
+ # Returns the String path of boom's Json representation.
12
+ def json_file
13
+ ENV['BOOMFILE'] || JSON_FILE
14
+ end
15
+
16
+ # Public: initializes a Storage instance by loading in your persisted data from adapter.
17
+ #
18
+ # Returns the Storage instance.
19
+ def initialize
20
+ @lists = []
21
+ bootstrap
22
+ populate
23
+ end
24
+
25
+ # Public: the in-memory collection of all Lists attached to this Storage
26
+ # instance.
27
+ #
28
+ # lists - an Array of individual List items
29
+ #
30
+ # Returns nothing.
31
+ attr_writer :lists
32
+
33
+ # Public: the list of Lists in your JSON data, sorted by number of items
34
+ # descending.
35
+ #
36
+ # Returns an Array of List objects.
37
+ def lists
38
+ @lists.sort_by { |list| -list.items.size }
39
+ end
40
+
41
+ # Public: tests whether a named List exists.
42
+ #
43
+ # name - the String name of a List
44
+ #
45
+ # Returns true if found, false if not.
46
+ def list_exists?(name)
47
+ @lists.detect { |list| list.name == name }
48
+ end
49
+
50
+ # Public: all Items in storage.
51
+ #
52
+ # Returns an Array of all Items.
53
+ def items
54
+ @lists.collect(&:items).flatten
15
55
  end
16
56
 
17
- def self.backend
18
- Boom::Storage.const_get(Boom.config.attributes['backend'].capitalize).new
57
+ # Public: tests whether a named Item exists.
58
+ #
59
+ # name - the String name of an Item
60
+ #
61
+ # Returns true if found, false if not.
62
+ def item_exists?(name)
63
+ items.detect { |item| item.name == name }
19
64
  end
20
65
 
66
+ # Public: creates a Hash of the representation of the in-memory data
67
+ # structure. This percolates down to Items by calling to_hash on the List,
68
+ # which in tern calls to_hash on individual Items.
69
+ #
70
+ # Returns a Hash of the entire data set.
71
+ def to_hash
72
+ { :lists => lists.collect(&:to_hash) }
73
+ end
74
+
75
+ # Takes care of bootstrapping the Json file, both in terms of creating the
76
+ # file and in terms of creating a skeleton Json schema.
77
+ #
78
+ # Return true if successfully saved.
79
+ def bootstrap
80
+ return if File.exist?(json_file)
81
+ FileUtils.touch json_file
82
+ File.open(json_file, 'w') {|f| f.write(to_json) }
83
+ save
84
+ end
85
+
86
+ # Take a JSON representation of data and explode it out into the consituent
87
+ # Lists and Items for the given Storage instance.
88
+ #
89
+ # Returns nothing.
90
+ def populate
91
+ file = File.new(json_file, 'r')
92
+ storage = Yajl::Parser.parse(file)
93
+
94
+ storage['lists'].each do |lists|
95
+ lists.each do |list_name, items|
96
+ @lists << list = List.new(list_name)
97
+
98
+ items.each do |item|
99
+ item.each do |name,value|
100
+ list.add_item(Item.new(name,value))
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ # Public: persists your in-memory objects to disk in Json format.
108
+ #
109
+ # lists_Json - list in Json format
110
+ #
111
+ # Returns true if successful, false if unsuccessful.
112
+ def save
113
+ File.open(json_file, 'w') {|f| f.write(to_json) }
114
+ end
115
+
116
+ # Public: the Json representation of the current List and Item assortment
117
+ # attached to the Storage instance.
118
+ #
119
+ # Returns a String Json representation of its Lists and their Items.
120
+ def to_json
121
+ Yajl::Encoder.encode(to_hash, :pretty => true)
122
+ end
21
123
  end
22
- end
124
+ end
data/lib/boom.rb CHANGED
@@ -6,38 +6,23 @@ rescue LoadError
6
6
  end
7
7
 
8
8
  require 'fileutils'
9
- require 'multi_json'
9
+ require 'yajl'
10
10
 
11
11
  $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
12
12
 
13
13
  require 'boom/color'
14
14
  require 'boom/platform'
15
15
  require 'boom/command'
16
- require 'boom/config'
17
16
  require 'boom/item'
18
17
  require 'boom/list'
19
-
20
18
  require 'boom/storage'
21
- require 'boom/storage/base'
22
- require 'boom/storage/json'
23
- require 'boom/storage/redis'
24
- require 'boom/storage/mongodb'
25
- require 'boom/storage/keychain'
26
- require 'boom/storage/gist'
27
19
 
28
20
  require 'boom/core_ext/symbol'
29
21
 
30
22
  module Boom
31
- VERSION = '0.2.4'
32
-
33
- extend self
34
-
35
- def storage
36
- @storage ||= Boom::Storage.backend
37
- end
23
+ VERSION = '0.3.0'
38
24
 
39
- def config
40
- @config ||= Boom::Config.new
25
+ def self.storage
26
+ @storage ||= Storage.new
41
27
  end
42
-
43
- end
28
+ end
data/test/cli.sh ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env roundup
2
+ export BOOMFILE=test/examples/data.json
3
+ boom="./bin/boom"
4
+
5
+ describe "cli"
6
+
7
+ it_shows_help() {
8
+ $boom help | grep "boom: help"
9
+ }
10
+
11
+ it_shows_a_version() {
12
+ $boom --version | grep "running boom"
13
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "lists": [
3
+ {
4
+ "urls": [
5
+ { "blog": "https://github.com/holman" },
6
+ { "twitter": "https://twitter.com/holman"},
7
+ { "site": "http://zachholman.com"}
8
+ ]
9
+ },
10
+ {
11
+ "jokes": [
12
+ { "none": "What do you call a cow with no legs? Ground beef." },
13
+ { "three": "What do you call a cow with three legs? Lean beef." }
14
+ ]
15
+ }
16
+ ]
17
+ }
data/test/item.sh ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env roundup
2
+ export BOOMFILE=test/examples/data.json
3
+ boom="./bin/boom"
4
+
5
+ describe "items"
6
+
7
+ it_adds_an_item() {
8
+ $boom urls google 'http://google.com'
9
+ $boom urls | grep google.com
10
+ }
11
+
12
+ it_deletes_an_item() {
13
+ yes | $boom urls google --delete | grep 'gone forever'
14
+ $boom urls google | grep 'not found'
15
+ }
16
+
17
+ it_echos_an_item() {
18
+ $boom echo site | grep 'zachholman.com'
19
+ }
data/test/list.sh ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env roundup
2
+ export BOOMFILE=test/examples/data.json
3
+ boom="./bin/boom"
4
+
5
+ describe "lists"
6
+
7
+ it_shows_all_lists_by_default() {
8
+ $boom | grep "urls"
9
+ $boom | grep "jokes"
10
+ }
11
+
12
+ it_adds_a_list() {
13
+ $boom enemies | grep "Created a new list"
14
+ $boom | grep "enemies (0)"
15
+ }
16
+
17
+ it_adds_a_list_with_a_duplicate_name() {
18
+ $boom urls github 'http://github.com/about'
19
+ $boom github | grep '/about'
20
+ }
21
+
22
+ it_shows_a_list() {
23
+ $boom urls | grep 'zachholman'
24
+ }
25
+
26
+ it_deletes_a_list() {
27
+ $boom | grep "enemies"
28
+ yes | $boom enemies --delete | grep "Deleted"
29
+ ! $boom | grep "enemies"
30
+ }