cue 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c3e67b30c304c9b38c0b750b943c045b8f5ccd20
4
+ data.tar.gz: 1f4757388541654942e0adee30d1aadc051f5bc4
5
+ SHA512:
6
+ metadata.gz: 0c64eede657d74523a8390aced2eefc1f0a7ede4f02e55c3268c34f7decedcb105b4fde9d069d4f7f8c6533e9cbf64dd7a0778e1d8e79784477b3f2c81946b7c
7
+ data.tar.gz: 2922380a75b9823bec5a02ab0bc730c00f1b672c6937531d02f5b5deff50121f07edf5c70a36d591c87cbaa9a418dfc47962ff5d18d74a6b1f5bd4f181e4fc59
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) arcsum42@gmail.com
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1 @@
1
+ # cue
data/bin/cue ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ args = ARGV.dup
4
+ subcommand = args.first
5
+
6
+ if subcommand.nil?
7
+ system('cue-list')
8
+ elsif subcommand == 'rm'
9
+ args.shift
10
+ system('cue-delete', *args)
11
+ elsif ['add', 'clear', 'delete', 'list', 'show', 'toggle'].include?(subcommand)
12
+ args.shift
13
+ system("cue-#{subcommand}", *args)
14
+ else
15
+ abort "cue: #{subcommand} is not a cue command."
16
+ end
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join(__dir__, '..', 'lib')
3
+ require 'cue/command/add'
4
+ Cue::Command::Add.new(ARGV).execute
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join(__dir__, '..', 'lib')
3
+ require 'cue/command/clear'
4
+ Cue::Command::Clear.new(ARGV).execute
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join(__dir__, '..', 'lib')
3
+ require 'cue/command/delete'
4
+ Cue::Command::Delete.new(ARGV).execute
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join(__dir__, '..', 'lib')
3
+ require 'cue/command/list'
4
+ Cue::Command::List.new(ARGV).execute
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join(__dir__, '..', 'lib')
3
+ require 'cue/command/show'
4
+ Cue::Command::Show.new(ARGV).execute
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join(__dir__, '..', 'lib')
3
+ require 'cue/command/toggle'
4
+ Cue::Command::Toggle.new(ARGV).execute
@@ -0,0 +1,25 @@
1
+ module ColorFool
2
+ COLORS = %i(green red)
3
+
4
+ CODES = {
5
+ black: 30,
6
+ red: 31,
7
+ green: 32,
8
+ yellow: 33,
9
+ blue: 34,
10
+ magenta: 35,
11
+ cyan: 36,
12
+ white: 37
13
+ }
14
+
15
+ def code(color)
16
+ CODES[color]
17
+ end
18
+
19
+ def colorize(color, &block)
20
+ code = code(color)
21
+ content = block.call.to_s
22
+
23
+ "\e[#{code}m#{content}\e[0m"
24
+ end
25
+ end
@@ -0,0 +1,2 @@
1
+ module Cue
2
+ end
@@ -0,0 +1,27 @@
1
+ require 'cue/command/base'
2
+ require 'cue/command/utils/editor'
3
+
4
+ module Cue
5
+ module Command
6
+ class Add < Base
7
+ def initialize(args)
8
+ super(args)
9
+
10
+ if @args.size == 1
11
+ @content = @args.first
12
+ else
13
+ @content = Utils::Editor.new.read
14
+ end
15
+ end
16
+
17
+ def execute
18
+ item = Cue::Item.new(@content)
19
+ item.save(options.store)
20
+ end
21
+
22
+ def nargs
23
+ (0..1)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,98 @@
1
+ require 'cue/store/redis'
2
+ require 'json'
3
+ require 'ostruct'
4
+ require 'optparse'
5
+
6
+ module Cue
7
+ module Command
8
+ class Base
9
+ attr_reader :options
10
+
11
+ def initialize(args)
12
+ @options = OpenStruct.new.tap do |opts|
13
+ opts.store = Cue::Store::Redis.new
14
+ end
15
+
16
+ @args = parser.parse(args)
17
+ configure_store
18
+ check_num_arguments
19
+ end
20
+
21
+ def find_key(key_prefix)
22
+ keys = options.store.keys
23
+ item_ids = keys.select { |id| id.start_with?(key_prefix) }
24
+
25
+ if item_ids.size > 1
26
+ parser.abort "#{key_prefix} is too ambiguous."
27
+ end
28
+
29
+ item_id = item_ids.first
30
+
31
+ parser.abort("Couldn't find item #{key_prefix}.") unless item_id
32
+ item_id
33
+ end
34
+
35
+ def find_item(key_prefix)
36
+ options.store.read(find_key(key_prefix))
37
+ end
38
+
39
+ def nargs
40
+ 0
41
+ end
42
+
43
+ def parser
44
+ @parser ||= OptionParser.new do |opts|
45
+ opts.banner = "Usage: #{File.basename($0)} [options]"
46
+
47
+ opts.on('-s', '--store [STORE]', 'Specify the store adapter') do |store|
48
+ begin
49
+ require "cue/store/#{store}"
50
+ klass = store.split('_').map(&:capitalize).join
51
+ options.store = Cue.const_get("Store::#{klass}").new
52
+ rescue LoadError
53
+ opts.abort "Couldn't find the store adapter \"#{store}\"."
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def check_num_arguments
62
+ case nargs
63
+ when Range
64
+ parser.abort('Invalid number of arguments.') unless nargs.cover?(@args.size)
65
+ else
66
+ parser.abort('Invalid number of arguments.') if @args.size != nargs
67
+ end
68
+ end
69
+
70
+ def config_path
71
+ File.join(ENV['HOME'], '.cue', 'config.json')
72
+ end
73
+
74
+ def configure_redis
75
+ get_config(:redis) do |config|
76
+ Cue::Store::Redis.configure do |rconfig|
77
+ opts = config.select { |k,_| [:host, :port, :password].include?(k) }
78
+ rconfig.redis = Redis.new(opts)
79
+ end
80
+ end
81
+ end
82
+
83
+ def configure_store
84
+ case options.store
85
+ when Cue::Store::Redis
86
+ configure_redis
87
+ end
88
+ end
89
+
90
+ def get_config(key=nil, &block)
91
+ return unless File.exists?(config_path)
92
+
93
+ json = JSON.parse(File.read(config_path), symbolize_names: true)
94
+ key.nil? ? yield(json) : yield(json[key])
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,11 @@
1
+ require 'cue/command/base'
2
+
3
+ module Cue
4
+ module Command
5
+ class Clear < Base
6
+ def execute
7
+ options.store.clear
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ require 'cue/command/base'
2
+
3
+ module Cue
4
+ module Command
5
+ class Delete < Base
6
+ def initialize(args)
7
+ super(args)
8
+ @sha = @args.first
9
+ end
10
+
11
+ def execute
12
+ item_key = find_key(@sha)
13
+ options.store.delete(item_key)
14
+ end
15
+
16
+ def nargs
17
+ 1
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,12 @@
1
+ require 'cue'
2
+ require 'cue/command/base'
3
+
4
+ module Cue
5
+ module Command
6
+ class List < Base
7
+ def execute
8
+ options.store.each(&method(:puts))
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ require 'cue/command/base'
2
+
3
+ module Cue
4
+ module Command
5
+ class Show < Base
6
+ def initialize(args)
7
+ super(args)
8
+ @sha = @args.first
9
+ end
10
+
11
+ def execute
12
+ item = find_item(@sha)
13
+ puts item
14
+ end
15
+
16
+ def nargs
17
+ 1
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ require 'cue/command/base'
2
+
3
+ module Cue
4
+ module Command
5
+ class Toggle < Base
6
+ def initialize(args)
7
+ super(args)
8
+ @sha = @args.first
9
+ end
10
+
11
+ def execute
12
+ find_item(@sha).tap do |item|
13
+ item.toggle!
14
+ item.save(options.store)
15
+ end
16
+ end
17
+
18
+ def nargs
19
+ 1
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,40 @@
1
+ require 'tempfile'
2
+
3
+ module Cue
4
+ module Command
5
+ module Utils
6
+ class Editor
7
+ def basename
8
+ 'cue'
9
+ end
10
+
11
+ def command
12
+ ENV['EDITOR'] || default_editor
13
+ end
14
+
15
+ def read
16
+ Process.wait(spawn([command, path].join(' ')))
17
+ content = File.read(path)
18
+
19
+ File.delete(path)
20
+
21
+ content
22
+ end
23
+
24
+ def dir
25
+ '/tmp'
26
+ end
27
+
28
+ def path
29
+ @path ||= File.expand_path(Dir::Tmpname::make_tmpname(basename, nil), dir)
30
+ end
31
+
32
+ private
33
+
34
+ def default_editor
35
+ 'vi'
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,17 @@
1
+ require 'forwardable'
2
+
3
+ module Cue
4
+ class Group
5
+ extend Forwardable
6
+
7
+ def_delegators :items, :<<, :[], :each, :size
8
+
9
+ def items
10
+ @items ||= []
11
+ end
12
+
13
+ def to_s
14
+ items.map(&:to_s).join("\n")
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,39 @@
1
+ require 'colorfool'
2
+
3
+ module Cue
4
+ class Indicator
5
+ include ColorFool
6
+
7
+ attr_reader :state
8
+
9
+ def initialize(state)
10
+ @state = state
11
+ end
12
+
13
+ def color
14
+ case state
15
+ when :complete
16
+ :green
17
+ when :incomplete
18
+ :red
19
+ else
20
+ :none
21
+ end
22
+ end
23
+
24
+ def symbol
25
+ case state
26
+ when :complete
27
+ '✓'
28
+ when :incomplete
29
+ '✗'
30
+ else
31
+ '?'
32
+ end
33
+ end
34
+
35
+ def to_s
36
+ colorize(color) { symbol }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,79 @@
1
+ require 'colorfool'
2
+ require 'cue/indicator'
3
+ require 'digest'
4
+
5
+ module Cue
6
+ class Item
7
+ include ColorFool
8
+ include Comparable
9
+
10
+ attr_accessor :content
11
+ attr_reader :created_at, :state
12
+
13
+ def initialize(content, attrs={})
14
+ self.content = content
15
+
16
+ attrs.each do |k, v|
17
+ setter = "#{k}="
18
+ if respond_to?(setter, true)
19
+ send(setter, v)
20
+ end
21
+ end
22
+
23
+ self.state = self.state || :incomplete
24
+ end
25
+
26
+ def <=>(other)
27
+ created_at <=> other.created_at
28
+ end
29
+
30
+ def ==(other)
31
+ content == other.content
32
+ end
33
+
34
+ def complete!
35
+ self.state = :complete
36
+ end
37
+
38
+ def complete?
39
+ self.state == :complete
40
+ end
41
+
42
+ def hash
43
+ Digest::SHA1.hexdigest(content)
44
+ end
45
+
46
+ def in_store?(store)
47
+ !store.read(hash).nil?
48
+ end
49
+
50
+ def incomplete!
51
+ self.state = :incomplete
52
+ end
53
+
54
+ def incomplete?
55
+ self.state == :incomplete
56
+ end
57
+
58
+ def save(store)
59
+ self.created_at = Time.now unless in_store?(store)
60
+ store.write(hash, self)
61
+ true
62
+ end
63
+
64
+ def to_s
65
+ i = Indicator.new(state)
66
+ h = colorize(:cyan) { hash[0..6] }
67
+ "#{h} #{i} #{content}"
68
+ end
69
+
70
+ def toggle!
71
+ complete? ? incomplete! : complete!
72
+ self
73
+ end
74
+
75
+ private
76
+
77
+ attr_writer :created_at, :state
78
+ end
79
+ end
@@ -0,0 +1,129 @@
1
+ require 'cue/item'
2
+ require 'fileutils'
3
+ require 'zlib'
4
+
5
+ module Cue
6
+ module Store
7
+ class File
8
+ include Enumerable
9
+
10
+ def initialize(root_path=nil)
11
+ @root_path = root_path
12
+ FileUtils.mkdir_p(items_path)
13
+ end
14
+
15
+ def clear
16
+ keys.each { |key| delete(key) }
17
+ end
18
+
19
+ def delete(key)
20
+ FileUtils.rm_r(item_path(key))
21
+ key_dir = dir_for(key)
22
+ FileUtils.rm_r(key_dir) if Dir[::File.join(key_dir, '*')].empty?
23
+ end
24
+
25
+ def each
26
+ items = keys.map(&method(:read)).sort
27
+ yield(items)
28
+ end
29
+
30
+ def keys
31
+ keys = []
32
+
33
+ Dir.glob(::File.join(items_path, '*')).each do |prefix_dir|
34
+ prefix = ::File.basename(prefix_dir)
35
+ Dir.glob(::File.join(prefix_dir, '*')).each do |suffix_file|
36
+ suffix = ::File.basename(suffix_file)
37
+ keys << (prefix + suffix)
38
+ end
39
+ end
40
+
41
+ keys
42
+ end
43
+
44
+ def read(key)
45
+ return nil unless ::File.exists?(item_path(key))
46
+
47
+ data = nil
48
+ file_for_reading(item_path(key)) do |file|
49
+ data = uncompress(file.read)
50
+ end
51
+ return data if data.nil?
52
+
53
+ deserialize(data)
54
+ end
55
+
56
+ def write(key, item)
57
+ FileUtils.mkdir_p(dir_for(key))
58
+ file_for_writing(item_path(key)) do |file|
59
+ data = compress(serialize(item))
60
+ file.write(data)
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def root_path
67
+ @root_path ||= ::File.join(ENV['HOME'], '.cue')
68
+ end
69
+
70
+ def compress(data)
71
+ Zlib::Deflate.deflate(data)
72
+ end
73
+
74
+ def deserialize(data)
75
+ created_at, state, content = data.unpack('Z*Z*Z*')
76
+ Cue::Item.new(content, created_at: created_at, state: state.to_sym)
77
+ end
78
+
79
+ def dir_for(key)
80
+ ::File.join(items_path, prefix(key))
81
+ end
82
+
83
+ def file_for_writing(path, &block)
84
+ ::File.open(path, mode_for_writing) { |file| yield(file) }
85
+ end
86
+
87
+ def file_for_reading(path, &block)
88
+ ::File.open(path, mode_for_reading) { |file| yield(file) }
89
+ end
90
+
91
+ def item_path(key)
92
+ ::File.join(dir_for(key), suffix(key))
93
+ end
94
+
95
+ def items_path
96
+ @items_path ||= ::File.join(root_path, 'items')
97
+ end
98
+
99
+ def keys_path
100
+ @keys_path ||= ::File.join(root_path, 'keys')
101
+ end
102
+
103
+ def mode_for_reading
104
+ ::File::RDONLY
105
+ end
106
+
107
+ def mode_for_writing
108
+ ::File::CREAT | ::File::WRONLY | ::File::TRUNC
109
+ end
110
+
111
+ def prefix(key)
112
+ key[0..1]
113
+ end
114
+
115
+ def serialize(item)
116
+ data = [item.created_at.to_i.to_s, item.state.to_s, item.content.to_s]
117
+ data.pack('Z*Z*Z*')
118
+ end
119
+
120
+ def suffix(key)
121
+ key[2...(key.size)]
122
+ end
123
+
124
+ def uncompress(data)
125
+ Zlib::Inflate.inflate(data)
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,38 @@
1
+ module Cue
2
+ module Store
3
+ class Memory
4
+ include Enumerable
5
+
6
+ def clear
7
+ @store = {}
8
+ end
9
+
10
+ def delete(key)
11
+ store.delete(key)
12
+ end
13
+
14
+ def each
15
+ items = keys.map(&method(:read)).sort
16
+ yield(items)
17
+ end
18
+
19
+ def keys
20
+ store.keys
21
+ end
22
+
23
+ def read(key)
24
+ store[key]
25
+ end
26
+
27
+ def write(key, item)
28
+ store[key] = item.dup
29
+ end
30
+
31
+ private
32
+
33
+ def store
34
+ @store ||= {}
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,110 @@
1
+ require 'cue/item'
2
+ require 'redis'
3
+ require 'time'
4
+
5
+ module Cue
6
+ module Store
7
+ class Redis
8
+ include Enumerable
9
+
10
+ class << self
11
+ attr_writer :namespace, :redis
12
+
13
+ def configure(&block)
14
+ self.tap { |klass| yield(klass) }
15
+ end
16
+
17
+ def namespace
18
+ @namespace ||= 'cue'
19
+ end
20
+
21
+ def redis
22
+ @redis ||= ::Redis.new
23
+ end
24
+ end
25
+
26
+ def clear
27
+ item_keys = redis.smembers(redis_key('keys'))
28
+ keys_key = redis_key('keys')
29
+
30
+ redis.del(item_keys, keys_key)
31
+ end
32
+
33
+ def delete(key)
34
+ item_key = item_key(key)
35
+
36
+ redis.del(item_key)
37
+ redis.srem(redis_key('keys'), item_key)
38
+ end
39
+
40
+ def each
41
+ items = keys.map(&method(:read)).sort
42
+ yield(items)
43
+ end
44
+
45
+ def keys
46
+ redis.smembers(redis_key('keys')).map do |redis_key|
47
+ redis_key.split(':').last
48
+ end
49
+ end
50
+
51
+ def read(key)
52
+ item_hash = redis.hgetall(item_key(key))
53
+ return nil if item_hash.empty?
54
+
55
+ deserialize(item_hash)
56
+ end
57
+
58
+ def write(key, item)
59
+ add_key(key)
60
+ add_item(key, item)
61
+ end
62
+
63
+ private
64
+
65
+ def add_item(key, item)
66
+ redis.mapped_hmset(item_key(key), serialize(item))
67
+ end
68
+
69
+ def add_key(key)
70
+ redis.sadd(redis_key('keys'), item_key(key))
71
+ end
72
+
73
+ def deserialize(item_hash)
74
+ content = item_hash['content']
75
+ created_at = Time.parse(item_hash['created_at']) if item_hash['created_at']
76
+ state = item_hash['state'].to_sym
77
+
78
+ Cue::Item.new(content, created_at: created_at, state: state)
79
+ end
80
+
81
+ def item_key(key)
82
+ redis_key('item', key)
83
+ end
84
+
85
+ def namespace
86
+ self.class.namespace
87
+ end
88
+
89
+ def redis
90
+ self.class.redis
91
+ end
92
+
93
+ def redis_key(*components)
94
+ key = *components
95
+ key.unshift(namespace)
96
+
97
+ key.join(':')
98
+ end
99
+
100
+ def serialize(item)
101
+ {
102
+ 'state' => item.state.to_s,
103
+ 'content' => item.content
104
+ }.tap do |hash|
105
+ hash['created_at'] = item.created_at.to_s if item.created_at
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,3 @@
1
+ module Cue
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cue
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - John Doe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: redis
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 3.0.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 3.0.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Cue is a simple command line tool for keeping track of stuff.
42
+ email: arcsum42@gmail.com
43
+ executables:
44
+ - cue
45
+ - cue-add
46
+ - cue-clear
47
+ - cue-delete
48
+ - cue-list
49
+ - cue-show
50
+ - cue-toggle
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - README.md
55
+ - LICENSE.md
56
+ - lib/colorfool.rb
57
+ - lib/cue/command/add.rb
58
+ - lib/cue/command/base.rb
59
+ - lib/cue/command/clear.rb
60
+ - lib/cue/command/delete.rb
61
+ - lib/cue/command/list.rb
62
+ - lib/cue/command/show.rb
63
+ - lib/cue/command/toggle.rb
64
+ - lib/cue/command/utils/editor.rb
65
+ - lib/cue/group.rb
66
+ - lib/cue/indicator.rb
67
+ - lib/cue/item.rb
68
+ - lib/cue/store/file.rb
69
+ - lib/cue/store/memory.rb
70
+ - lib/cue/store/redis.rb
71
+ - lib/cue/version.rb
72
+ - lib/cue.rb
73
+ - bin/cue
74
+ - bin/cue-add
75
+ - bin/cue-clear
76
+ - bin/cue-delete
77
+ - bin/cue-list
78
+ - bin/cue-show
79
+ - bin/cue-toggle
80
+ homepage: https://github.com/arcsum/cue
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.0.0
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: keep track of stuff
104
+ test_files: []