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 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: []