do_stuff 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/do_stuff +59 -0
- data/lib/do_stuff/todolist.rb +72 -0
- data/lib/do_stuff.rb +1 -0
- metadata +48 -0
data/bin/do_stuff
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'optparse'
|
5
|
+
require 'do_stuff'
|
6
|
+
|
7
|
+
DO_STUFFRC = ENV['HOME'] + '/.do_stuffrc'
|
8
|
+
abort "Error: Couldn't find #{DO_STUFFRC}.\nPlease create it and put the " +
|
9
|
+
"path to your todo.txt file in it." unless File.exists?(DO_STUFFRC)
|
10
|
+
|
11
|
+
TODO_FILE = File.expand_path(File.read(DO_STUFFRC).chomp)
|
12
|
+
FileUtils.mkdir_p(File.dirname(TODO_FILE))
|
13
|
+
FileUtils.touch(TODO_FILE)
|
14
|
+
|
15
|
+
program = File.basename($0)
|
16
|
+
USAGE = <<EOS
|
17
|
+
usage: #{program} list unfinished tasks
|
18
|
+
#{program} <task desc> add a new task
|
19
|
+
#{program} <task num> erase task
|
20
|
+
#{program} -e[task num] edit task file and jump to given task
|
21
|
+
#{program} -h show this message
|
22
|
+
EOS
|
23
|
+
|
24
|
+
OptionParser.new do |opts|
|
25
|
+
opts.on('-e [TASK NUM]') do |task_num|
|
26
|
+
TodoList.edit(TODO_FILE)
|
27
|
+
exit
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on('-h', '--help') do
|
31
|
+
puts USAGE
|
32
|
+
exit
|
33
|
+
end
|
34
|
+
end.parse!
|
35
|
+
|
36
|
+
begin
|
37
|
+
todolist = TodoList.new(TODO_FILE)
|
38
|
+
rescue TodoList::ParseError => e
|
39
|
+
abort "Error parsing #{e.file}: #{e.message}"
|
40
|
+
end
|
41
|
+
|
42
|
+
if ARGV.length == 0
|
43
|
+
todolist.tasks.each do |num, task|
|
44
|
+
puts "#{num}. #{task}"
|
45
|
+
end
|
46
|
+
elsif ARGV.length == 1 && ARGV[0] =~ /^\d+$/
|
47
|
+
task_num = ARGV[0].to_i
|
48
|
+
task = todolist.get(task_num)
|
49
|
+
abort "There is no task ##{task_num}." unless task
|
50
|
+
todolist.erase(task_num)
|
51
|
+
todolist.write!
|
52
|
+
puts "Erased ##{task_num}: #{task}"
|
53
|
+
else
|
54
|
+
# If nothing else matches, treat the arguments as a task description.
|
55
|
+
task = ARGV.join(' ')
|
56
|
+
task_num = todolist.add(task)
|
57
|
+
todolist.write!
|
58
|
+
puts "Added ##{task_num}: #{task}"
|
59
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
class TodoList
|
2
|
+
def initialize(file)
|
3
|
+
@file = file
|
4
|
+
parse
|
5
|
+
end
|
6
|
+
|
7
|
+
def add(task)
|
8
|
+
# Try to fill a hole in the task list, otherwise append to the end.
|
9
|
+
i = @tasks.find_index(nil)
|
10
|
+
i = @tasks.length unless i
|
11
|
+
|
12
|
+
@tasks[i] = task
|
13
|
+
|
14
|
+
# Return the task number
|
15
|
+
i + 1
|
16
|
+
end
|
17
|
+
|
18
|
+
def erase(task_num)
|
19
|
+
raise "No such task ##{task_num}." unless @tasks[task_num - 1]
|
20
|
+
@tasks[task_num - 1] = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def get(task_num)
|
24
|
+
@tasks[task_num - 1]
|
25
|
+
end
|
26
|
+
|
27
|
+
def tasks
|
28
|
+
# Group each task with its number and remove all nils
|
29
|
+
@tasks.map.with_index{|task, i| [i + 1, task] if task }.compact
|
30
|
+
end
|
31
|
+
|
32
|
+
def write!
|
33
|
+
File.open(@file, 'w') do |f|
|
34
|
+
tasks.each{|num, task| f.puts("#{num}. #{task}") }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.edit(file)
|
39
|
+
# TODO: Use task_num to jump to a line
|
40
|
+
system(ENV['EDITOR'], file)
|
41
|
+
end
|
42
|
+
|
43
|
+
class ParseError < StandardError
|
44
|
+
attr_accessor :file
|
45
|
+
def initialize(file, msg)
|
46
|
+
@file = file
|
47
|
+
super(msg)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def parse
|
53
|
+
@tasks = []
|
54
|
+
|
55
|
+
File.read(@file).each_line do |line|
|
56
|
+
line.chomp!
|
57
|
+
if line =~ /^(\d+)\.\s+(.+)$/
|
58
|
+
task_num, task = $1.to_i, $2
|
59
|
+
i = task_num - 1
|
60
|
+
|
61
|
+
if @tasks[i]
|
62
|
+
raise ParseError.new(@file, "Two definitions for task #{task_num}:\n\t" +
|
63
|
+
"#{task_num}. #{@tasks[i]}\n\t#{line}")
|
64
|
+
end
|
65
|
+
|
66
|
+
@tasks[i] = task
|
67
|
+
else
|
68
|
+
raise ParseError.new(@file, "Ill-formed line encountered:\n\t#{line}")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/do_stuff.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'do_stuff/todolist'
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: do_stuff
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Scott Olson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-22 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: A minimalistic command-line todo list
|
15
|
+
email: scott@scott-olson.org
|
16
|
+
executables:
|
17
|
+
- do_stuff
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/do_stuff/todolist.rb
|
22
|
+
- lib/do_stuff.rb
|
23
|
+
- bin/do_stuff
|
24
|
+
homepage: https://github.com/tsion/do_stuff
|
25
|
+
licenses: []
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ! '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubyforge_project:
|
44
|
+
rubygems_version: 1.8.17
|
45
|
+
signing_key:
|
46
|
+
specification_version: 3
|
47
|
+
summary: A minimalistic command-line todo list
|
48
|
+
test_files: []
|