do_stuff 0.0.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/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: []
|