koi 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/VERSION +1 -1
  2. data/bin/koi +9 -5
  3. data/koi.gemspec +2 -2
  4. data/lib/koi.rb +37 -22
  5. data/spec/koi_spec.rb +14 -1
  6. metadata +2 -2
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.4
1
+ 0.3.0
data/bin/koi CHANGED
@@ -3,24 +3,28 @@ require 'optparse'
3
3
 
4
4
  $:.unshift File.dirname(__FILE__) + "/../lib"
5
5
 
6
+ if RUBY_VERSION.split('.')[1].to_i < 9
7
+ abort "ruby 1.9 is required to run koi"
8
+ end
9
+
6
10
  require 'koi'
7
11
 
8
12
  args = ARGV.dup
9
13
 
10
- options = {verbose: false, silent: false}
14
+ options = {:verbose => false, :silent => false}
11
15
 
12
16
  OptionParser.new do |o|
13
- o.banner = "usage: it COMMAND [ARGS]"
17
+ o.banner = "usage: koi COMMAND [ARGS]"
14
18
  o.separator ""
15
-
19
+
16
20
  o.on_tail("-s", "--silent", "turn output off") do
17
21
  options[:silent] = true
18
22
  end
19
-
23
+
20
24
  o.on_tail("-v", "--verbose", "enable verbose mode") do
21
25
  options[:verbose] = true
22
26
  end
23
27
  end.parse!(args)
24
28
 
25
- Koi::Command.new(args[0] || :status, args[1] || nil, args[2] || [], options).run
29
+ Koi::Command.new(args[0] || :status, args[1..-1], options).run
26
30
 
data/koi.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{koi}
8
- s.version = "0.2.4"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["cloudhead"]
12
- s.date = %q{2010-03-07}
12
+ s.date = %q{2010-03-10}
13
13
  s.default_executable = %q{koi}
14
14
  s.description = %q{minimalist console-based task management for hackers}
15
15
  s.email = %q{self@cloudhead.net}
data/lib/koi.rb CHANGED
@@ -28,7 +28,7 @@ module Koi
28
28
  end
29
29
 
30
30
  def self.run *args
31
- cmd = Command.new(*args)
31
+ cmd = Command.new(args.first, args[1..-1])
32
32
  cmd[:silent] = true
33
33
  cmd.run
34
34
  end
@@ -53,16 +53,15 @@ module Koi
53
53
  :init, :add, :list, :tag,
54
54
  :done, :did, :log, :status,
55
55
  :remove, :float, :sink,
56
- :ls, :rm, :rise, :x
56
+ :ls, :rm, :rise, :x, :show
57
57
  ]
58
58
  Initializers = [:init, :add]
59
59
  Special = {"!" => :done, "?" => :status, "+" => :float}
60
60
 
61
61
  def initialize *all
62
- cmd, param, args, options = all
62
+ cmd, args, options = all
63
63
  @command = Special[cmd] || cmd.to_sym
64
- @args = [args || []].flatten
65
- @param = param =~ /^\d+$/ ? param.to_i : param
64
+ @args = (args || []).map {|a| a =~ /^\d+$/ ? a.to_i : a }
66
65
  @options = options || {}
67
66
  @db = Koi.init?? Database.new(File.join(Koi.root, Path[:db])) : Database.new
68
67
  end
@@ -70,15 +69,12 @@ module Koi
70
69
  def run
71
70
  if Commands.include? @command
72
71
  if Koi.init? or Initializers.include? @command
73
- if !@param or @command == :add or @param = @db.find(@param)
74
- @param ||= @db.last if [:float, :sink, :rm, :tag, :done].include? @command
75
- if send(@command, *[@param, *@args].compact.flatten)
72
+ send(@command, *(@args.length == 1 ? @args.first : @args)).tap do |result|
73
+ if result
76
74
  save
77
75
  else
78
76
  err "error running #@command"
79
77
  end
80
- else
81
- err "task wasn't found"
82
78
  end
83
79
  else
84
80
  err "'koi' is not initialized here, please run `koi init`"
@@ -86,6 +82,8 @@ module Koi
86
82
  else
87
83
  err "#{@command} is not a valid command."
88
84
  end
85
+ rescue Database::EntityNotFound
86
+ err "the koi wasn't found"
89
87
  end
90
88
 
91
89
  def []= key, val
@@ -104,10 +102,11 @@ module Koi
104
102
  end
105
103
  end
106
104
 
107
- def status
108
- out "#{@db.select {|e| e.new? }.size} koi in the water"
105
+ def status options = {}
106
+ todo = @db.select {|e| e.new? }.size
107
+ out "#{todo} koi in the water" unless todo.zero?
109
108
 
110
- self.list 5
109
+ self.list @db.list[0..5]
111
110
 
112
111
  @db.select {|e| e[:status] == :completed }.
113
112
  sort_by {|e| e[:completed_at] }[0..3].reverse.each do |e|
@@ -117,27 +116,33 @@ module Koi
117
116
  true
118
117
  end
119
118
 
119
+ def show tags
120
+ tags = [tags].flatten
121
+ self.list @db.select {|e| e if (tags & e[:tags]).any? }
122
+ end
123
+
120
124
  #
121
125
  # List current tasks
122
126
  #
123
- def list count = 10, index = -1
127
+ def list entities = @db.list[0..10]
124
128
  out
125
129
 
126
- @db.list[0..count].reject {|e| e[:status] == :removed }.each do |e|
127
- out " [#{index += 1}]".blue +
130
+ entities.reject {|e| e[:status] == :removed }.each_with_index do |e, i|
131
+ out " [#{i}]".blue +
128
132
  "#{e.sticky?? " + ".bold : " "}" +
129
- e[:title].underline +
133
+ e[:title].underline +
130
134
  " #{e[:tags].join(' ')}".cyan
131
135
  end.tap do |list|
132
- out " nothing left to do".green if list.size.zero?
136
+ out " there are no koi in the water".green if list.size.zero?
133
137
  end
134
138
 
135
139
  out
136
- true
140
+ entities
137
141
  end
138
142
  alias :ls list
139
143
 
140
144
  def swim entry, n
145
+ entry = @db.find(entry)
141
146
  v = @db.index(entry) + @db.size / 3 * n
142
147
  @db.delete entry
143
148
  @db.insert([[v, 0].max, @db.size].min, entry)
@@ -152,6 +157,7 @@ module Koi
152
157
  end
153
158
 
154
159
  def float entry
160
+ entry = @db.find(entry)
155
161
  entry[:sticky] = ! entry[:sticky]
156
162
  true
157
163
  end
@@ -191,11 +197,17 @@ module Koi
191
197
  @db << Entity.new(title: entry, tags: tags, target: target)
192
198
  end
193
199
 
194
- def tag entry, tags
195
- entry[:tags] << tags
200
+ def tag *args
201
+ entry, *tags = args
202
+ entry = @db.find(entry)
203
+ entry[:tags] += tags
204
+ entry[:tags].uniq!
205
+
206
+ true
196
207
  end
197
208
 
198
209
  def did entry = 0
210
+ entry = @db.find(entry)
199
211
  entry.status = :completed
200
212
  entry[:completed_by] = ENV['USER']
201
213
  end
@@ -211,7 +223,7 @@ module Koi
211
223
  # Mark task as :removed (doesn't show up anywhere)
212
224
  #
213
225
  def remove entry
214
- entry.status = :removed
226
+ @db.find(entry).status = :removed
215
227
  end
216
228
  alias :rm remove
217
229
  alias :kill remove
@@ -219,6 +231,7 @@ module Koi
219
231
 
220
232
  class Database
221
233
  include Enumerable
234
+ EntityNotFound = Class.new(RuntimeError)
222
235
 
223
236
  def initialize path = nil
224
237
  if @path = path
@@ -236,6 +249,8 @@ module Koi
236
249
  (entities.select(&:sticky?) + entities.reject(&:sticky?))[key]
237
250
  else
238
251
  raise ArgumentError, "key must be a String or Fixnum, but is #{key.class}"
252
+ end.tap do |result|
253
+ raise EntityNotFound if result.nil?
239
254
  end
240
255
  end
241
256
  alias :[] find
data/spec/koi_spec.rb CHANGED
@@ -2,6 +2,9 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe Koi do
4
4
  TASK = "buy milk"
5
+ Koi::Path[:root] = '._koi'
6
+ Koi::Path[:db] = '._koi/database.yml'
7
+ Koi::Path[:paths] = '._koi/paths'
5
8
 
6
9
  context "in a new project" do
7
10
  before(:each) do
@@ -75,7 +78,7 @@ describe Koi do
75
78
  end
76
79
 
77
80
  it "should tag tasks" do
78
- Koi.run(:tag, TASKS[1], ["food"])
81
+ Koi.run(:tag, TASKS[1], "food")
79
82
  @db.load.find(TASKS[1])[:tags].should include("food")
80
83
  end
81
84
 
@@ -89,6 +92,11 @@ describe Koi do
89
92
  @db.load.last[:title].should == TASKS[1]
90
93
  end
91
94
 
95
+ it "should show tasks with specific tags" do
96
+ Koi.run(:tag, TASKS[1], "#food")
97
+ Koi.run(:show, ["#food"]).first[:title].should == TASKS[1]
98
+ end
99
+
92
100
  it "should sticky tasks" do
93
101
  Koi.run(:float, TASKS[2])
94
102
  @db.load.list[0][:title].should == TASKS[2]
@@ -100,5 +108,10 @@ describe Koi do
100
108
  end
101
109
  end
102
110
  end
111
+
112
+ after(:all) do
113
+ FileUtils.rm_rf(Koi::Path[:root])
114
+ FileUtils.rm_rf(File.join(ENV['HOME'], Koi::Path[:root]))
115
+ end
103
116
  end
104
117
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: koi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - cloudhead
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-03-07 00:00:00 -05:00
12
+ date: 2010-03-10 00:00:00 -05:00
13
13
  default_executable: koi
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency