r2do 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/r2do/category.rb +10 -2
- data/lib/r2do/command.rb +9 -23
- data/lib/r2do/commands/category_command.rb +173 -0
- data/lib/r2do/commands/command.rb +64 -0
- data/lib/r2do/commands/display_categories.rb +70 -0
- data/lib/r2do/{handlers/handle_init.rb → commands/help_command.rb} +24 -17
- data/lib/r2do/commands/init_command.rb +67 -0
- data/lib/r2do/commands/now_command.rb +71 -0
- data/lib/r2do/commands/task_command.rb +186 -0
- data/lib/r2do/exceptions.rb +2 -0
- data/lib/r2do/option.rb +51 -0
- data/lib/r2do/state.rb +18 -0
- data/lib/r2do/task.rb +6 -0
- data/lib/r2do/utility.rb +0 -1
- data/lib/r2do/version.rb +1 -1
- data/lib/r2do.rb +23 -19
- data/r2do.gemspec +4 -2
- data/spec/r2do/option_spec.rb +87 -0
- data/spec/r2do/task_spec.rb +14 -0
- metadata +20 -14
- data/lib/r2do/handlers/handle_categories.rb +0 -52
- data/lib/r2do/handlers/handle_category.rb +0 -111
- data/lib/r2do/handlers/handle_task.rb +0 -157
- data/spec/r2do/command_spec.rb +0 -85
data/lib/r2do/category.rb
CHANGED
@@ -34,6 +34,10 @@ module R2do
|
|
34
34
|
@current_task = nil
|
35
35
|
end
|
36
36
|
|
37
|
+
def rename(name)
|
38
|
+
@name = name
|
39
|
+
end
|
40
|
+
|
37
41
|
# Finds a task based on the description.
|
38
42
|
#
|
39
43
|
# @param [String] description the task description.
|
@@ -49,10 +53,14 @@ module R2do
|
|
49
53
|
# @raise [Exceptions::TaskAlreadyExistsError] if task with same description is already present.
|
50
54
|
# @return [void]
|
51
55
|
def add(task)
|
52
|
-
|
56
|
+
if task.nil?
|
57
|
+
raise ArgumentError
|
58
|
+
end
|
53
59
|
|
54
60
|
duplicate = @tasks.find { |t| t.description == task.description }
|
55
|
-
|
61
|
+
if duplicate
|
62
|
+
raise TaskAlreadyExistsError
|
63
|
+
end
|
56
64
|
|
57
65
|
@tasks.push(task)
|
58
66
|
end
|
data/lib/r2do/command.rb
CHANGED
@@ -16,13 +16,8 @@
|
|
16
16
|
|
17
17
|
module R2do
|
18
18
|
|
19
|
-
class Command
|
20
|
-
|
21
|
-
attr_reader :short
|
22
|
-
# @return [String] the name of this command.
|
23
|
-
attr_reader :extended
|
24
|
-
# @return [String] the description for the command.
|
25
|
-
attr_reader :description
|
19
|
+
class Option < Command
|
20
|
+
|
26
21
|
|
27
22
|
# Creates an instance of a Command
|
28
23
|
#
|
@@ -31,15 +26,13 @@ module R2do
|
|
31
26
|
# @param [String] argument the optional argument for commands that have arguments
|
32
27
|
# @param [String] description the command's description
|
33
28
|
# @param [callback] callback the callback method for this command
|
34
|
-
def initialize(short, extended,
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
@extended = extended
|
42
|
-
@description = description
|
29
|
+
def initialize(short, extended, description, callback)
|
30
|
+
super(short, extended, argument, description)
|
31
|
+
|
32
|
+
if callback.nil?
|
33
|
+
raise ArgumentError
|
34
|
+
end
|
35
|
+
|
43
36
|
@callback = callback
|
44
37
|
end
|
45
38
|
|
@@ -51,13 +44,6 @@ module R2do
|
|
51
44
|
@callback.call(args)
|
52
45
|
end
|
53
46
|
|
54
|
-
# Returns a string representation of this Command
|
55
|
-
#
|
56
|
-
# @return [String] the representation of this Command
|
57
|
-
def to_s()
|
58
|
-
return "%2s, %-10s \t# %s" % [@short, @extended, @description]
|
59
|
-
end
|
60
|
-
|
61
47
|
end
|
62
48
|
|
63
49
|
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Christian Giacomi http://www.christiangiacomi.com
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
module R2do
|
18
|
+
module Commands
|
19
|
+
class CategoryCommand < Command
|
20
|
+
|
21
|
+
YES = "Y"
|
22
|
+
|
23
|
+
DISPLAY = "--display"
|
24
|
+
DELETE = "--delete"
|
25
|
+
EDIT = "--edit"
|
26
|
+
|
27
|
+
def initialize(state)
|
28
|
+
super('c', 'category', 'Creates a new category.')
|
29
|
+
|
30
|
+
@state = state
|
31
|
+
end
|
32
|
+
|
33
|
+
# Creates a new category or makes a category current in the state if a category with the
|
34
|
+
# same name already exists
|
35
|
+
#
|
36
|
+
# @param [Array] args the arguments passed to the app by the user
|
37
|
+
# @raise [ArgumentError] if the command does not contain a name for the category
|
38
|
+
# @return [void]
|
39
|
+
def execute(args)
|
40
|
+
if args.length < 2
|
41
|
+
raise ArgumentError, "The 'category' command requires additional arguments."
|
42
|
+
end
|
43
|
+
|
44
|
+
option = args[1]
|
45
|
+
|
46
|
+
if option.eql?(DISPLAY)
|
47
|
+
display_current_category(args)
|
48
|
+
elsif option.eql?(EDIT)
|
49
|
+
require_selected_category()
|
50
|
+
edit_current_category(args)
|
51
|
+
elsif option.eql?(DELETE)
|
52
|
+
require_selected_category()
|
53
|
+
delete_category(args)
|
54
|
+
elsif option.start_with?("--")
|
55
|
+
raise InvalidOptionError
|
56
|
+
else
|
57
|
+
parse_category(args)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Edit the current task.
|
62
|
+
#
|
63
|
+
# @param [Array] args the arguments passed to the app by the user.
|
64
|
+
# @return [void]
|
65
|
+
def edit_current_category(args)
|
66
|
+
UI.status("Are you sure you want to edit the category:")
|
67
|
+
UI.status(" #{@state.current_category.name}")
|
68
|
+
UI.new_line()
|
69
|
+
value = UI.input("Continue? [Yn]")
|
70
|
+
if value == YES
|
71
|
+
cat = @state.current_category
|
72
|
+
|
73
|
+
original_name = cat.name
|
74
|
+
name = UI.input("Enter new name:")
|
75
|
+
|
76
|
+
cat.rename(name)
|
77
|
+
|
78
|
+
@state.refresh(original_name, cat)
|
79
|
+
@state.modified = true
|
80
|
+
|
81
|
+
UI.status("The category as been modified.")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Shows the detailed information for the current category, including the tasks contained
|
86
|
+
#
|
87
|
+
# @param [Array] args the arguments passed to the app by the user
|
88
|
+
# @return [void]
|
89
|
+
def display_current_category(args)
|
90
|
+
#TODO: need to refatctor the code to remove the duplication (NowCommand)
|
91
|
+
if not @state.current_category
|
92
|
+
UI.status("No category is currently selected.")
|
93
|
+
else
|
94
|
+
UI.status(@state.current_category.to_s)
|
95
|
+
UI.new_line()
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Deletes the currently selected category
|
100
|
+
#
|
101
|
+
# @param [Array] args the argumets passed to the app by the user
|
102
|
+
# @return [void]
|
103
|
+
def delete_category(args)
|
104
|
+
UI.status("Are you sure you want to delete the category:")
|
105
|
+
UI.status(" #{@state.current_category.name}")
|
106
|
+
UI.new_line()
|
107
|
+
UI.status("All tasks contained in this category will be lost.")
|
108
|
+
value = UI.input("This action cannot be undone. Continue? [Yn]")
|
109
|
+
if value == YES
|
110
|
+
cat = @state.current_category
|
111
|
+
@state.remove(cat)
|
112
|
+
@state.clear_current_category()
|
113
|
+
@state.modified = true
|
114
|
+
|
115
|
+
UI.status("Category '#{cat.name}' has been deleted.")
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Creates a new Category or selects an already existing one.
|
120
|
+
#
|
121
|
+
# @param [Array] args the argumets passed to the app by the user.
|
122
|
+
# @return [void]
|
123
|
+
def parse_category(args)
|
124
|
+
extra = ''
|
125
|
+
category_name = args[1]
|
126
|
+
if @state.contains?(category_name)
|
127
|
+
cat = @state.get(category_name)
|
128
|
+
else
|
129
|
+
extra = 'new '
|
130
|
+
cat = Category.new(category_name)
|
131
|
+
@state.add(cat)
|
132
|
+
end
|
133
|
+
|
134
|
+
@state.set_current(cat)
|
135
|
+
@state.modified = true
|
136
|
+
|
137
|
+
UI.status("Switched to #{extra}category '#{category_name}'")
|
138
|
+
end
|
139
|
+
|
140
|
+
# Ensures that a category is selected.
|
141
|
+
#
|
142
|
+
# @return [void]
|
143
|
+
def require_selected_category()
|
144
|
+
if @state.current_category.nil?
|
145
|
+
raise CategoryNotSelectedError, "This action requires a selected category."
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def help()
|
150
|
+
help = <<-EOF
|
151
|
+
NAME
|
152
|
+
r2do #{@extended}
|
153
|
+
|
154
|
+
SYNOPSIS
|
155
|
+
'r2do #{@extended}' or 'r2do #{@short}' are equivalent
|
156
|
+
|
157
|
+
DESCRIPTION
|
158
|
+
The #{@extended} lets you interact with a category, create, edit, or delete. Defaults to the active category.
|
159
|
+
|
160
|
+
usage: r2do #{@extended} [NAME] [--edit] [--display] [--delete]
|
161
|
+
|
162
|
+
--edit Edit the currently selected category
|
163
|
+
--display Displays the details for the selected category
|
164
|
+
--delete Delete the selected category
|
165
|
+
|
166
|
+
EOF
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Christian Giacomi http://www.christiangiacomi.com
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
module R2do
|
18
|
+
|
19
|
+
class Command
|
20
|
+
# @return [String] the value for the command switch.
|
21
|
+
attr_reader :short
|
22
|
+
# @return [String] the name of this command.
|
23
|
+
attr_reader :extended
|
24
|
+
# @return [String] the description for the command.
|
25
|
+
attr_reader :description
|
26
|
+
|
27
|
+
# Creates an instance of a Command
|
28
|
+
#
|
29
|
+
# @param [String] short the short option name for this command
|
30
|
+
# @param [String] extended the full option name for this command
|
31
|
+
# @param [String] argument the optional argument for commands that have arguments
|
32
|
+
# @param [String] description the command's description
|
33
|
+
def initialize(short, extended, description)
|
34
|
+
if short.nil? or extended.nil? or description.nil?
|
35
|
+
raise ArgumentError
|
36
|
+
end
|
37
|
+
|
38
|
+
@short = short
|
39
|
+
@extended = extended
|
40
|
+
@description = description
|
41
|
+
end
|
42
|
+
|
43
|
+
# Executes the callback of this command
|
44
|
+
#
|
45
|
+
# @param [Array] args the collection of arguments
|
46
|
+
# @return [void]
|
47
|
+
def execute(args)
|
48
|
+
raise ScriptError, "Cannot call execute on an abstract command"
|
49
|
+
end
|
50
|
+
|
51
|
+
def help()
|
52
|
+
return "No help available for this command."
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns a string representation of this Command
|
56
|
+
#
|
57
|
+
# @return [String] the representation of this Command
|
58
|
+
def to_s()
|
59
|
+
return "%2s, %-10s \t# %s" % [@short, @extended, @description]
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Christian Giacomi http://www.christiangiacomi.com
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
module R2do
|
18
|
+
module Commands
|
19
|
+
class DisplayCategoriesCommand < Command
|
20
|
+
|
21
|
+
def initialize(state)
|
22
|
+
super('l', 'list', 'Displays all the categories.')
|
23
|
+
|
24
|
+
@state = state
|
25
|
+
end
|
26
|
+
|
27
|
+
# Displays all the categories available
|
28
|
+
#
|
29
|
+
# @param [Array] args the arguments passed to the app by the user
|
30
|
+
# @return [void]
|
31
|
+
def execute(args)
|
32
|
+
if @state.categories.empty?
|
33
|
+
UI.status("No categories to display")
|
34
|
+
else
|
35
|
+
@state.categories.each do |key, value|
|
36
|
+
current = (value == @state.current_category && "*") || ' '
|
37
|
+
UI.status("#{current} #{value.name}")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def help()
|
43
|
+
help = <<-EOF
|
44
|
+
NAME
|
45
|
+
r2do #{@extended}
|
46
|
+
|
47
|
+
SYNOPSIS
|
48
|
+
'r2do #{@extended}' or 'r2do #{@short}' are equivalent
|
49
|
+
|
50
|
+
DESCRIPTION
|
51
|
+
The #{@extended} lets you Lists all the available categories in the application.
|
52
|
+
|
53
|
+
The current selected category is marked with and asterisk '*'
|
54
|
+
|
55
|
+
usage: r2do #{@extended}
|
56
|
+
|
57
|
+
e.g.
|
58
|
+
|
59
|
+
Category 1
|
60
|
+
* Category 2
|
61
|
+
Category 3
|
62
|
+
|
63
|
+
EOF
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -15,24 +15,31 @@
|
|
15
15
|
#
|
16
16
|
|
17
17
|
module R2do
|
18
|
-
module
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
18
|
+
module Commands
|
19
|
+
class HelpCommand < Command
|
20
|
+
|
21
|
+
def initialize(cmd_list)
|
22
|
+
super('h', 'help', 'Shows the help for a given command')
|
23
|
+
|
24
|
+
@cmd_list = cmd_list
|
25
|
+
end
|
26
|
+
|
27
|
+
# Initializes the applications and resets the datafile
|
28
|
+
#
|
29
|
+
# @param [Array] args the arguments passed to the app by the user
|
30
|
+
# @return [void]
|
31
|
+
def execute(args)
|
32
|
+
argument = args[1]
|
33
|
+
|
34
|
+
cmd = @cmd_list.find { |c| c.short == argument or c.extended == argument }
|
35
|
+
if cmd.nil?
|
36
|
+
raise InvalidCommandError, "Invalid command. See 'r2do -h'"
|
37
|
+
end
|
38
|
+
|
39
|
+
UI.status(cmd.help())
|
35
40
|
end
|
41
|
+
|
42
|
+
|
36
43
|
end
|
37
44
|
|
38
45
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Christian Giacomi http://www.christiangiacomi.com
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
module R2do
|
18
|
+
module Commands
|
19
|
+
class InitCommand < Command
|
20
|
+
|
21
|
+
YES = "Y"
|
22
|
+
|
23
|
+
def initialize(state)
|
24
|
+
super('i', 'init', 'Initializes a new clean session.')
|
25
|
+
|
26
|
+
@state = state
|
27
|
+
end
|
28
|
+
|
29
|
+
# Initializes the applications and resets the datafile
|
30
|
+
#
|
31
|
+
# @param [Array] args the arguments passed to the app by the user
|
32
|
+
# @return [void]
|
33
|
+
def execute(args)
|
34
|
+
UI.status("Initialize new session?")
|
35
|
+
UI.new_line()
|
36
|
+
value = UI.input("Any previous session will be lost. Continue? [Yn]")
|
37
|
+
if value == YES
|
38
|
+
@state.reset()
|
39
|
+
@state.modified = true
|
40
|
+
UI.status("Initialized a new session of r2do.")
|
41
|
+
else
|
42
|
+
UI.status("Continuing with current session.")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def help()
|
47
|
+
help = <<-EOF
|
48
|
+
NAME
|
49
|
+
r2do #{@extended}
|
50
|
+
|
51
|
+
SYNOPSIS
|
52
|
+
'r2do #{@extended}' or 'r2do #{@short}' are equivalent
|
53
|
+
|
54
|
+
DESCRIPTION
|
55
|
+
|
56
|
+
The #{@extended} command initializes a new session of the application. Any previously saved data is permanently lost.
|
57
|
+
|
58
|
+
usage: r2do #{@extended}
|
59
|
+
|
60
|
+
EOF
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Christian Giacomi http://www.christiangiacomi.com
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
module R2do
|
18
|
+
module Commands
|
19
|
+
class NowCommand < Command
|
20
|
+
|
21
|
+
def initialize(state)
|
22
|
+
super('n', 'now', 'Displays the information for the current category.')
|
23
|
+
|
24
|
+
@state = state
|
25
|
+
end
|
26
|
+
|
27
|
+
# Creates a new category or makes a category current in the state if a category with the
|
28
|
+
# same name already exists
|
29
|
+
#
|
30
|
+
# @param [Array] args the arguments passed to the app by the user
|
31
|
+
# @raise [ArgumentError] if the command does not contain a name for the category
|
32
|
+
# @return [void]
|
33
|
+
def execute(args)
|
34
|
+
display_current_category(args)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Shows the detailed information for the current category, including the tasks contained
|
38
|
+
#
|
39
|
+
# @param [Array] args the arguments passed to the app by the user
|
40
|
+
# @return [void]
|
41
|
+
def display_current_category(args)
|
42
|
+
#TODO: need to refatctor the code to remove the duplication
|
43
|
+
if not @state.current_category
|
44
|
+
UI.status("No category is currently selected.")
|
45
|
+
else
|
46
|
+
UI.status(@state.current_category.to_s)
|
47
|
+
UI.new_line()
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def help()
|
52
|
+
help = <<-EOF
|
53
|
+
NAME
|
54
|
+
r2do #{@extended}
|
55
|
+
|
56
|
+
SYNOPSIS
|
57
|
+
'r2do #{@extended}' or 'r2do #{@short}' are equivalent
|
58
|
+
|
59
|
+
DESCRIPTION
|
60
|
+
The #{@extended} lets view the current category and its tasks
|
61
|
+
|
62
|
+
usage: r2do #{@extended}
|
63
|
+
|
64
|
+
EOF
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|