koi 0.2.1
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/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.md +56 -0
- data/Rakefile +31 -0
- data/VERSION +1 -0
- data/bin/koi +26 -0
- data/koi.gemspec +59 -0
- data/lib/koi.rb +281 -0
- data/spec/koi_spec.rb +78 -0
- data/spec/spec_helper.rb +9 -0
- metadata +86 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 cloudhead
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
koi
|
2
|
+
===
|
3
|
+
|
4
|
+
minimal task management for hackers.
|
5
|
+
|
6
|
+
$ sudo gem install koi -s http://gemcutter.org
|
7
|
+
|
8
|
+
_Note: this project is still under heavy development!_
|
9
|
+
|
10
|
+
Synopsis
|
11
|
+
--------
|
12
|
+
|
13
|
+
Start by creating a new project folder
|
14
|
+
|
15
|
+
$ mkdir project/
|
16
|
+
$ cd project/
|
17
|
+
|
18
|
+
**koi** uses folders as projects, in the same way as **git**. We start by initializing our project, and adding two tasks.
|
19
|
+
|
20
|
+
$ koi init
|
21
|
+
$ koi add "refactor spaghetti code"
|
22
|
+
$ koi add "find a better name"
|
23
|
+
|
24
|
+
Let's see what we've got now with `list`:
|
25
|
+
|
26
|
+
$ koi list
|
27
|
+
|
28
|
+
[0] refactor spaghetti code
|
29
|
+
[1] find a better name
|
30
|
+
|
31
|
+
Tasks can be refered to by index `1`, `2` or by name. You don't have to type in the full name though:
|
32
|
+
|
33
|
+
$ koi tag spaghetti #R
|
34
|
+
$ koi done 1
|
35
|
+
|
36
|
+
I just went ahead and tagged my first task with `#R`, and completed my 2nd one. Here's the new list:
|
37
|
+
|
38
|
+
$ koi list
|
39
|
+
|
40
|
+
[0] refactor spaghetti code #R
|
41
|
+
|
42
|
+
# recently completed
|
43
|
+
- find a better name
|
44
|
+
|
45
|
+
You can also specify tags when adding new tasks:
|
46
|
+
|
47
|
+
$ koi add "make pasta" #food #yum #kitchen
|
48
|
+
|
49
|
+
And remove tasks:
|
50
|
+
|
51
|
+
$ koi remove pasta
|
52
|
+
|
53
|
+
**koi** creates an _.koi_ folder in the directory you initialize your project in. Inside that folder is a _database.yml_ with all your tasks for that project.
|
54
|
+
|
55
|
+
|
56
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "koi"
|
8
|
+
gem.summary = %Q{minimal task management for hackers}
|
9
|
+
gem.description = %Q{minimalist console-based task management for hackers}
|
10
|
+
gem.email = "self@cloudhead.net"
|
11
|
+
gem.homepage = "http://github.com/cloudhead/koi"
|
12
|
+
gem.authors = ["cloudhead"]
|
13
|
+
gem.add_development_dependency "rspec"
|
14
|
+
gem.add_dependency "mutter", ">= 0.4"
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'spec/rake/spectask'
|
22
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
23
|
+
spec.libs << 'lib' << 'spec'
|
24
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
25
|
+
spec.spec_opts = ['--color', '--format=specdoc']
|
26
|
+
end
|
27
|
+
|
28
|
+
task :spec => :check_dependencies
|
29
|
+
|
30
|
+
task :default => :spec
|
31
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.1
|
data/bin/koi
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
$:.unshift File.dirname(__FILE__) + "/../lib"
|
5
|
+
|
6
|
+
require 'koi'
|
7
|
+
|
8
|
+
args = ARGV.dup
|
9
|
+
|
10
|
+
options = {verbose: false, silent: false}
|
11
|
+
|
12
|
+
OptionParser.new do |o|
|
13
|
+
o.banner = "usage: it COMMAND [ARGS]"
|
14
|
+
o.separator ""
|
15
|
+
|
16
|
+
o.on_tail("-s", "--silent", "turn output off") do
|
17
|
+
options[:silent] = true
|
18
|
+
end
|
19
|
+
|
20
|
+
o.on_tail("-v", "--verbose", "enable verbose mode") do
|
21
|
+
options[:verbose] = true
|
22
|
+
end
|
23
|
+
end.parse!(args)
|
24
|
+
|
25
|
+
Koi::Command.new(args[0] || :status, args[1] || nil, args[2] || [], options).run
|
26
|
+
|
data/koi.gemspec
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{koi}
|
8
|
+
s.version = "0.2.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["cloudhead"]
|
12
|
+
s.date = %q{2009-10-20}
|
13
|
+
s.default_executable = %q{koi}
|
14
|
+
s.description = %q{minimalist console-based task management for hackers}
|
15
|
+
s.email = %q{self@cloudhead.net}
|
16
|
+
s.executables = ["koi"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
19
|
+
"README.md"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
".gitignore",
|
24
|
+
"LICENSE",
|
25
|
+
"README.md",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"bin/koi",
|
29
|
+
"koi.gemspec",
|
30
|
+
"lib/koi.rb",
|
31
|
+
"spec/koi_spec.rb",
|
32
|
+
"spec/spec_helper.rb"
|
33
|
+
]
|
34
|
+
s.homepage = %q{http://github.com/cloudhead/koi}
|
35
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
36
|
+
s.require_paths = ["lib"]
|
37
|
+
s.rubygems_version = %q{1.3.5}
|
38
|
+
s.summary = %q{minimal task management for hackers}
|
39
|
+
s.test_files = [
|
40
|
+
"spec/koi_spec.rb",
|
41
|
+
"spec/spec_helper.rb"
|
42
|
+
]
|
43
|
+
|
44
|
+
if s.respond_to? :specification_version then
|
45
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
46
|
+
s.specification_version = 3
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
50
|
+
s.add_runtime_dependency(%q<mutter>, [">= 0.4"])
|
51
|
+
else
|
52
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
53
|
+
s.add_dependency(%q<mutter>, [">= 0.4"])
|
54
|
+
end
|
55
|
+
else
|
56
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
57
|
+
s.add_dependency(%q<mutter>, [">= 0.4"])
|
58
|
+
end
|
59
|
+
end
|
data/lib/koi.rb
ADDED
@@ -0,0 +1,281 @@
|
|
1
|
+
|
2
|
+
require 'yaml'
|
3
|
+
require 'mutter'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
module Koi
|
7
|
+
|
8
|
+
Path = {root: ".koi", db: ".koi/database.yml"}
|
9
|
+
|
10
|
+
def self.init dir = Dir.pwd
|
11
|
+
unless init?
|
12
|
+
FileUtils.mkdir File.join(dir, Path[:root])
|
13
|
+
FileUtils.touch File.join(dir, Path[:db])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.init! dir = Dir.pwd
|
18
|
+
FileUtils.rm_rf File.join(dir, Path[:root])
|
19
|
+
init dir
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.init? dir = root
|
23
|
+
File.exist? File.join(dir, Path[:root]) if dir
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.run *args
|
27
|
+
cmd = Command.new(*args)
|
28
|
+
cmd[:silent] = true
|
29
|
+
cmd.run
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.version
|
33
|
+
File.read(File.join(File.dirname(__FILE__), '..', 'VERSION')).strip
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.root
|
37
|
+
path = Dir.pwd.split('/').reject {|d| d.empty? }
|
38
|
+
(path.size + 1).times do
|
39
|
+
if Koi.init? (sub = File.join('/', *path))
|
40
|
+
return sub
|
41
|
+
end
|
42
|
+
path.pop
|
43
|
+
end
|
44
|
+
return nil
|
45
|
+
end
|
46
|
+
|
47
|
+
class Command
|
48
|
+
Commands = [
|
49
|
+
:init, :add, :list, :tag,
|
50
|
+
:done, :did, :log, :status,
|
51
|
+
:remove, :float, :sink,
|
52
|
+
:ls, :rm
|
53
|
+
]
|
54
|
+
Initializers = [:init, :add]
|
55
|
+
Special = {"!" => :done, "?" => :status}
|
56
|
+
|
57
|
+
def initialize *all
|
58
|
+
cmd, param, args, options = all
|
59
|
+
@command = Special[cmd] || cmd.to_sym
|
60
|
+
@args = [args || []].flatten
|
61
|
+
@param = param =~ /^\d+$/ ? param.to_i : param
|
62
|
+
@options = options || {}
|
63
|
+
@db = Koi.init?? Database.new(File.join(Koi.root, Path[:db])) : Database.new
|
64
|
+
@mut = Mutter.new(blue: '#', underline: "''", cyan: '@@', green: '!!', yellow: '^').clear(:default)
|
65
|
+
end
|
66
|
+
|
67
|
+
def run
|
68
|
+
if Commands.include? @command
|
69
|
+
if Koi.init? or Initializers.include? @command
|
70
|
+
if !@param or @command == :add or @param = @db.find(@param)
|
71
|
+
if send(@command, *[@param, *@args].compact.flatten)
|
72
|
+
save
|
73
|
+
else
|
74
|
+
err "error running #@command"
|
75
|
+
end
|
76
|
+
else
|
77
|
+
err "task wasn't found"
|
78
|
+
end
|
79
|
+
else
|
80
|
+
err "'it' is not initialized here, please run `it init`"
|
81
|
+
end
|
82
|
+
else
|
83
|
+
err "#{@command} is not a valid command."
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def []= key, val
|
88
|
+
@options[key] = val
|
89
|
+
end
|
90
|
+
|
91
|
+
def [] key
|
92
|
+
@options[key]
|
93
|
+
end
|
94
|
+
|
95
|
+
def init
|
96
|
+
unless Koi.init
|
97
|
+
err "'it' has already been initialized here"
|
98
|
+
else
|
99
|
+
true
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def status
|
104
|
+
out "in the water (#{@db.select {|e| e.new? }.size})"
|
105
|
+
|
106
|
+
self.list 5
|
107
|
+
|
108
|
+
out "recently fished (#{@db.select {|e| e.completed? }.size})"
|
109
|
+
|
110
|
+
@db.select {|e| e[:status] == :completed }.
|
111
|
+
sort_by {|e| e[:completed_at] }[0..3].reverse.each do |e|
|
112
|
+
out "- !!#{e[:title]}!!"
|
113
|
+
end
|
114
|
+
|
115
|
+
out
|
116
|
+
true
|
117
|
+
end
|
118
|
+
|
119
|
+
#
|
120
|
+
# List current tasks
|
121
|
+
#
|
122
|
+
def list count = 10, index = -1
|
123
|
+
out
|
124
|
+
|
125
|
+
@db.select {|e| e.new? }[0..count].each do |e|
|
126
|
+
out "#[#{index += 1}]# ''#{e[:title]}'' @@#{e[:tags].join(' ')}@@" unless e[:status] == :removed
|
127
|
+
end.tap do |list|
|
128
|
+
out " !!nothing left to do!!" if list.size.zero?
|
129
|
+
end
|
130
|
+
|
131
|
+
out
|
132
|
+
end
|
133
|
+
alias :ls list
|
134
|
+
|
135
|
+
def float
|
136
|
+
end
|
137
|
+
|
138
|
+
def sink
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# Show task history
|
143
|
+
#
|
144
|
+
def log
|
145
|
+
@db.map do |entity|
|
146
|
+
Entity::Status.map do |status|
|
147
|
+
{ title: entity[:title],
|
148
|
+
action: status,
|
149
|
+
time: entity[:"#{status}_at"]
|
150
|
+
} if entity[:"#{status}_at"]
|
151
|
+
end.compact
|
152
|
+
end.flatten.sort_by {|e| e[:time]}.reverse.each do |entry|
|
153
|
+
out "##{entry[:time]}# ^#{entry[:action]}^ ''#{entry[:title]}''"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def out obj = ""
|
158
|
+
if obj.is_a? Hash
|
159
|
+
puts "#{obj[:title]} : #{obj[:status]}"
|
160
|
+
else
|
161
|
+
@mut.say obj.to_s
|
162
|
+
end unless @options[:silent]
|
163
|
+
end
|
164
|
+
|
165
|
+
def err str
|
166
|
+
@options[:silent] ? abort : abort(str)
|
167
|
+
end
|
168
|
+
|
169
|
+
def add entry, *args
|
170
|
+
Koi.init
|
171
|
+
target = args.find {|a| a.start_with? '@' }[1..-1] rescue nil
|
172
|
+
tags = args.select {|a| a.start_with? '#' }
|
173
|
+
@db << Entity.new(title: entry, tags: tags, target: target)
|
174
|
+
end
|
175
|
+
|
176
|
+
def tag entry, tags
|
177
|
+
entry[:tags] << tags
|
178
|
+
end
|
179
|
+
|
180
|
+
def did entry = 0
|
181
|
+
entry.status = :completed
|
182
|
+
entry[:completed_by] = ENV['USER']
|
183
|
+
end
|
184
|
+
alias :done did
|
185
|
+
alias :fish did
|
186
|
+
|
187
|
+
def save
|
188
|
+
File.open(File.join(Koi.root, Path[:db]), 'w') {|f| f.write @db.to_yaml }
|
189
|
+
end
|
190
|
+
|
191
|
+
#
|
192
|
+
# Mark task as :removed (doesn't show up anywhere)
|
193
|
+
#
|
194
|
+
def remove entry
|
195
|
+
entry.status = :removed
|
196
|
+
end
|
197
|
+
alias :rm remove
|
198
|
+
alias :kill remove
|
199
|
+
end
|
200
|
+
|
201
|
+
class Database
|
202
|
+
include Enumerable
|
203
|
+
|
204
|
+
def initialize path = nil
|
205
|
+
if @path = path
|
206
|
+
self.load path
|
207
|
+
else
|
208
|
+
@data = []
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def find key
|
213
|
+
if key.is_a? String
|
214
|
+
@data.find {|e| e[:title].include? key }
|
215
|
+
elsif key.is_a? Fixnum
|
216
|
+
@data.select {|e| e[:status] == :created}[key]
|
217
|
+
else
|
218
|
+
raise ArgumentError, "key must be a String or Fixnum, but is #{key.class}"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
alias :[] find
|
222
|
+
|
223
|
+
def load path = @path || Path[:db]
|
224
|
+
@data = if db = YAML.load_file(path)
|
225
|
+
db.map {|e| Entity.new(e) }
|
226
|
+
else
|
227
|
+
[]
|
228
|
+
end
|
229
|
+
self
|
230
|
+
end
|
231
|
+
|
232
|
+
def each &blk
|
233
|
+
@data.each &blk
|
234
|
+
end
|
235
|
+
|
236
|
+
def << entry
|
237
|
+
@data << (entry.is_a?(Entity) ? entry : Entity.new(entry))
|
238
|
+
end
|
239
|
+
|
240
|
+
def to_yaml *args, &blk
|
241
|
+
@data.to_yaml *args, &blk
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
class Entity < Hash
|
246
|
+
Status = [:created, :completed, :removed]
|
247
|
+
|
248
|
+
def initialize data = {}
|
249
|
+
self.replace status: :created,
|
250
|
+
created_at: Time.now,
|
251
|
+
owner: ENV['USER'],
|
252
|
+
velocity: 0,
|
253
|
+
freshness: 0,
|
254
|
+
depth: 0,
|
255
|
+
tags: []
|
256
|
+
merge!(data)
|
257
|
+
end
|
258
|
+
|
259
|
+
def new?
|
260
|
+
self[:status] == :created
|
261
|
+
end
|
262
|
+
|
263
|
+
def status= st
|
264
|
+
self[:status] = st
|
265
|
+
self[:"#{st}_at"] = Time.now
|
266
|
+
end
|
267
|
+
|
268
|
+
#
|
269
|
+
# Handle things like `self.removed?`
|
270
|
+
#
|
271
|
+
def method_missing meth, *args, &blk
|
272
|
+
if meth.to_s.end_with?('?') && Status.include?(s = meth.to_s.chop.to_sym)
|
273
|
+
self[:status] == s
|
274
|
+
else
|
275
|
+
super
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
|
data/spec/koi_spec.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Koi do
|
4
|
+
TASK = "buy milk"
|
5
|
+
|
6
|
+
context "in a new project" do
|
7
|
+
before(:each) do
|
8
|
+
FileUtils.rm_rf(Koi::Path[:root])
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should initialize the directory" do
|
12
|
+
Koi.run(:init)
|
13
|
+
File.exist?(Koi::Path[:root]).should be_true
|
14
|
+
File.exist?(Koi::Path[:db]).should be_true
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should warn that the project isn't initialized" do
|
18
|
+
-> {Koi.run(:list)}.should raise_error(SystemExit)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "in an existing project" do
|
23
|
+
before(:all) do
|
24
|
+
Koi.init!
|
25
|
+
end
|
26
|
+
|
27
|
+
context "with no tasks" do
|
28
|
+
it "shouldn't try to init" do
|
29
|
+
-> {Koi.run(:init)}.should raise_error(SystemExit)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should warn about invalid commands" do
|
33
|
+
-> {Koi.run(:choo)}.should raise_error(SystemExit)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should add tasks" do
|
37
|
+
if Koi.run(:add, TASK)
|
38
|
+
e = Koi::Database.new(Koi::Path[:db]).find(TASK)
|
39
|
+
e.should be_a(Koi::Entity)
|
40
|
+
e[:status].should == :created
|
41
|
+
e[:tags].should == []
|
42
|
+
else
|
43
|
+
fail
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "with a couple tasks" do
|
49
|
+
TASKS = ["milk", "eggs", "bananas"]
|
50
|
+
before(:each) do
|
51
|
+
Koi.init!
|
52
|
+
TASKS.each do |t|
|
53
|
+
Koi.run(:add, t)
|
54
|
+
end
|
55
|
+
@db = Koi::Database.new(Koi::Path[:db])
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should remove tasks" do
|
59
|
+
Koi.run(:remove, TASKS.last)
|
60
|
+
@db.load.find(TASKS.last)[:status].should == :removed
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should complete tasks" do
|
64
|
+
Koi.run(:did, TASKS.first)
|
65
|
+
@db.load.find(TASKS.first)[:status].should == :completed
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should tag tasks" do
|
69
|
+
Koi.run(:tag, TASKS[1], ["food"])
|
70
|
+
@db.load.find(TASKS[1])[:tags].should include("food")
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should warn when the task wasn't found" do
|
74
|
+
-> {Koi.run(:did, "celery")}.should raise_error(SystemExit)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: koi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- cloudhead
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-20 00:00:00 -04:00
|
13
|
+
default_executable: koi
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: mutter
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0.4"
|
34
|
+
version:
|
35
|
+
description: minimalist console-based task management for hackers
|
36
|
+
email: self@cloudhead.net
|
37
|
+
executables:
|
38
|
+
- koi
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- LICENSE
|
43
|
+
- README.md
|
44
|
+
files:
|
45
|
+
- .document
|
46
|
+
- .gitignore
|
47
|
+
- LICENSE
|
48
|
+
- README.md
|
49
|
+
- Rakefile
|
50
|
+
- VERSION
|
51
|
+
- bin/koi
|
52
|
+
- koi.gemspec
|
53
|
+
- lib/koi.rb
|
54
|
+
- spec/koi_spec.rb
|
55
|
+
- spec/spec_helper.rb
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://github.com/cloudhead/koi
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options:
|
62
|
+
- --charset=UTF-8
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: "0"
|
76
|
+
version:
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.3.5
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: minimal task management for hackers
|
84
|
+
test_files:
|
85
|
+
- spec/koi_spec.rb
|
86
|
+
- spec/spec_helper.rb
|