r2do 0.0.7 → 0.0.8

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.
@@ -0,0 +1,186 @@
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 TaskCommand < Command
20
+
21
+ YES = "Y"
22
+
23
+ #options
24
+ COMPLETED = "--done"
25
+ DISPLAY = "--display"
26
+ DELETE = "--delete"
27
+ EDIT = "--edit"
28
+
29
+ def initialize(state)
30
+ super('t', 'task', 'Adds a new task to the current category.')
31
+
32
+ @state = state
33
+ end
34
+
35
+ # Creates a new task or makes a task current in the current category if a task with the
36
+ # same name already exists
37
+ #
38
+ # @param [Array] args the arguments passed to the app by the user
39
+ # @raise [ArgumentError] if the command does not contain a name for the task
40
+ # @return [void]
41
+ def execute(args)
42
+ if args.length < 2
43
+ raise ArgumentError, "The 'task' command requires additional arguments."
44
+ end
45
+
46
+ if @state.current_category.nil?
47
+ raise CategoryNotSelectedError, "You need to select a category to create a new task."
48
+ end
49
+
50
+ option = args[1]
51
+
52
+ if option.eql?(DISPLAY)
53
+ require_selected_task()
54
+ show_current_task(args)
55
+ elsif option.eql?(EDIT)
56
+ require_selected_task()
57
+ edit_current_task(args)
58
+ elsif option.eql?(COMPLETED)
59
+ require_selected_task()
60
+ mark_as_complete(args)
61
+ elsif option.eql?(DELETE)
62
+ require_selected_task()
63
+ delete_task(args)
64
+ elsif option.start_with?("--")
65
+ raise InvalidOptionError, "Invalid argument for the command. See 'r2do -h'."
66
+ else
67
+ parse_task(args)
68
+ end
69
+ end
70
+
71
+ # Edit the current task.
72
+ #
73
+ # @param [Array] args the arguments passed to the app by the user.
74
+ # @return [void]
75
+ def edit_current_task(args)
76
+ UI.status("Are you sure you want to edit the task:")
77
+ UI.status(" #{@state.current_category.current_task.description}")
78
+ UI.new_line()
79
+ value = UI.input("Continue? [Yn]")
80
+ if value == YES
81
+ desc = UI.input("Enter new description:")
82
+ task = @state.current_category.current_task
83
+ task.rename(desc)
84
+ @state.modified = true
85
+
86
+ UI.status("The task as been modified.")
87
+ end
88
+ end
89
+
90
+ # Delete the currently selected task.
91
+ #
92
+ # @param [Array] args the arguments passed to the app by the user.
93
+ # @return [void]
94
+ def delete_task(args)
95
+ UI.status("Are you sure you want to delete the task:")
96
+ UI.status(" #{@state.current_category.current_task.description}")
97
+ UI.new_line()
98
+ value = UI.input("This action cannot be undone. Continue? [Yn]")
99
+ if value == YES
100
+ task = @state.current_category.current_task
101
+ @state.current_category.remove(task)
102
+ @state.current_category.clear_current_task()
103
+ @state.modified = true
104
+
105
+ UI.status("Task '#{task.description}' has been deleted.")
106
+ end
107
+ end
108
+
109
+ # Displays the information of the currently selected task.
110
+ #
111
+ # @param [Array] args the arguments passed to the app by the user.
112
+ # @return [void]
113
+ def show_current_task(args)
114
+ task = @state.current_category.current_task
115
+ UI.status(task.display())
116
+ end
117
+
118
+ # Marks a task as completed.
119
+ #
120
+ # @param [Array] args the arguments passed to the app by the user.
121
+ # @return [void]
122
+ def mark_as_complete(args)
123
+ task = @state.current_category.current_task
124
+ task.completed()
125
+ @state.modified = true
126
+
127
+ UI.status("Task '%s' has been marked as completed." % task.description)
128
+ end
129
+
130
+ # Creates a new task or select an already existing one.
131
+ #
132
+ # @param [Array] args the arguments passed to the app by the user.
133
+ # @return [void]
134
+ def parse_task(args)
135
+ extra = ''
136
+ task_description = args[1]
137
+ task = @state.current_category.find_by_description(task_description)
138
+ if task.nil?
139
+ task = Task.new(task_description)
140
+ @state.current_category.add(task)
141
+
142
+ UI.status("Created new task.")
143
+ UI.new_line()
144
+ end
145
+
146
+ @state.current_category.set_current(task)
147
+ @state.modified = true
148
+
149
+ UI.status("Selected task '#{task_description}'")
150
+ end
151
+
152
+ # Checks that a task is currently selected.
153
+ #
154
+ # @return [void]
155
+ def require_selected_task()
156
+ if @state.current_category.current_task.nil?
157
+ raise TaskNotSelectedError, "This action requires a selected task."
158
+ end
159
+ end
160
+
161
+
162
+ def help()
163
+ help = <<-EOF
164
+ NAME
165
+ r2do #{@extended}
166
+
167
+ SYNOPSIS
168
+ 'r2do #{@extended}' or 'r2do #{@short}' are equivalent
169
+
170
+ DESCRIPTION
171
+ The #{@extended} lets you interact with a task, create, edit, or delete. Defaults to the active task.
172
+
173
+ usage: r2do #{@extended} [NAME] [--edit] [--display] [--delete]
174
+
175
+ --edit Edit the currently selected task
176
+ --display Displays the details for the selected task
177
+ --delete Delete the selected task
178
+
179
+ EOF
180
+ end
181
+
182
+ end
183
+
184
+ end
185
+
186
+ end
@@ -24,4 +24,6 @@ module R2do
24
24
  class CategoryNotFoundError < Exception; end;
25
25
  class CategoryAlreadyExistsError < Exception; end;
26
26
  class CategoryNotSelectedError < Exception; end;
27
+
28
+ class InvalidCommandError < Exception; end;
27
29
  end
@@ -0,0 +1,51 @@
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
+
20
+ class Option < Command
21
+
22
+ # Creates an instance of a Command
23
+ #
24
+ # @param [String] short the short option name for this command
25
+ # @param [String] extended the full option name for this command
26
+ # @param [String] argument the optional argument for commands that have arguments
27
+ # @param [String] description the command's description
28
+ # @param [callback] callback the callback method for this command
29
+ def initialize(short, extended, description, callback)
30
+ super(short, extended, description)
31
+
32
+ if callback.nil?
33
+ raise ArgumentError
34
+ end
35
+
36
+ @callback = callback
37
+ end
38
+
39
+ # Executes the callback of this command
40
+ #
41
+ # @param [Array] args the collection of arguments
42
+ # @return [void]
43
+ def execute(args)
44
+ @callback.call(args)
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+
51
+ end
data/lib/r2do/state.rb CHANGED
@@ -21,12 +21,24 @@ module R2do
21
21
  attr_accessor :categories
22
22
  # @return [Category] the current category the user is working on.
23
23
  attr_accessor :current_category
24
+ # @return [bool] true if the state has been modified
25
+ attr_accessor :modified
24
26
 
25
27
  # Creates a new instance of the State
26
28
  #
27
29
  def initialize()
30
+ init()
31
+ end
32
+
33
+ def init()
28
34
  @categories = Hash.new
29
35
  @current_category = nil
36
+ @modified = false
37
+ end
38
+
39
+ def reset()
40
+ init()
41
+ @modified = true
30
42
  end
31
43
 
32
44
  # Sets a Category as the current one.
@@ -68,6 +80,12 @@ module R2do
68
80
  @categories[category.name] = category
69
81
  end
70
82
 
83
+
84
+ def refresh(original_name, category)
85
+ @categories.delete(original_name) { raise CategoryNotFoundError.new() }
86
+ @categories[category.name] = category
87
+ end
88
+
71
89
  # Removes the category from the state.
72
90
  #
73
91
  # @param [Category] category the category to remove.
data/lib/r2do/task.rb CHANGED
@@ -24,10 +24,16 @@ module R2do
24
24
  # @return [DateTime] the date and time of creation
25
25
  attr_accessor :date_created
26
26
 
27
+ MAX_LENGTH = 30
28
+
27
29
  # Creates a new instance of a Task
28
30
  #
29
31
  # @param [String] desctiption the description for this task
30
32
  def initialize(description)
33
+ if description.length > MAX_LENGTH
34
+ raise ArgumentError, "A task description has to be less than 30 characters."
35
+ end
36
+
31
37
  @description = description
32
38
  @done = false
33
39
  @date_created = DateTime.now
data/lib/r2do/utility.rb CHANGED
@@ -15,7 +15,6 @@
15
15
  #
16
16
 
17
17
  module R2do
18
-
19
18
  module Utility
20
19
  module_function
21
20
 
data/lib/r2do/version.rb CHANGED
@@ -15,5 +15,5 @@
15
15
  #
16
16
 
17
17
  module R2do
18
- VERSION = '0.0.7'
18
+ VERSION = '0.0.8'
19
19
  end
data/lib/r2do.rb CHANGED
@@ -16,17 +16,20 @@
16
16
 
17
17
  require 'yaml'
18
18
 
19
+ require 'r2do/commands/command'
19
20
  require 'r2do/ui'
20
21
  require 'r2do/category'
21
22
  require 'r2do/task'
22
23
  require 'r2do/exceptions'
23
- require 'r2do/command'
24
+ require 'r2do/option'
24
25
  require 'r2do/state'
25
26
  require 'r2do/version'
26
- require 'r2do/handlers/handle_category'
27
- require 'r2do/handlers/handle_task'
28
- require 'r2do/handlers/handle_init'
29
- require 'r2do/handlers/handle_categories'
27
+ require 'r2do/commands/now_command'
28
+ require 'r2do/commands/category_command'
29
+ require 'r2do/commands/task_command'
30
+ require 'r2do/commands/init_command'
31
+ require 'r2do/commands/display_categories'
32
+ require 'r2do/commands/help_command'
30
33
  require 'r2do/utility'
31
34
 
32
35
 
@@ -34,18 +37,18 @@ module R2do
34
37
  class App
35
38
  include R2do
36
39
  include Utility
37
- include Handlers
40
+ include Commands
38
41
 
39
42
  # Creates an instance of the application.
40
43
  #
41
44
  # @param [Array] args the command line args.
42
45
  def initialize(args)
43
46
  @args = args
44
- @commands = create_commands()
45
- @modified = false
46
- @file_name = ".r2do.yml"
47
47
 
48
+ @file_name = ".r2do.yml"
48
49
  @state = load_state(@file_name)
50
+
51
+ @commands = create_commands()
49
52
  end
50
53
 
51
54
  # Evaluates the command passed by the user and calls the corresponding application command.
@@ -74,7 +77,7 @@ module R2do
74
77
  #
75
78
  # @return [void]
76
79
  def save()
77
- if @modified
80
+ if @state.modified
78
81
  save_state(@file_name, @state)
79
82
  end
80
83
  end
@@ -86,15 +89,16 @@ module R2do
86
89
  # @return [Array] the collection of commands.
87
90
  def create_commands()
88
91
  cmd_list = Array.new
89
- cmd_list << Command.new('i', 'initialize', nil, 'Initializes a new clean session.', method(:handle_init))
90
- cmd_list << Command.new('c', 'category', 'NAME', 'Creates a new category', method(:handle_category))
91
- cmd_list << Command.new('t', 'task', 'NAME', 'Adds a new task to the current category.', method(:handle_task))
92
- cmd_list << Command.new('d', 'display', nil, 'Displays all the categories', method(:handle_categories))
93
- cmd_list << Command.new('n', 'now', nil, 'Displays the information for the current category', method(:display_current_category))
94
- cmd_list << Command.new('h', 'help', nil, 'Displays the help for a command', method(:handle_help))
95
-
96
- cmd_list << Command.new('-v', '--version', nil, 'Prints the application version.', method(:show_version))
97
- cmd_list << Command.new('-h', '--help', nil, 'You are looking at it.', method(:show_help))
92
+ cmd_list << InitCommand.new(@state)
93
+ cmd_list << CategoryCommand.new(@state)
94
+ cmd_list << TaskCommand.new(@state)
95
+ cmd_list << DisplayCategoriesCommand.new(@state)
96
+ cmd_list << NowCommand.new(@state)
97
+
98
+ cmd_list << HelpCommand.new(Array.new(cmd_list))
99
+
100
+ cmd_list << Option.new('-v', '--version', 'Prints the application version.', method(:show_version))
101
+ cmd_list << Option.new('-h', '--help', 'You are looking at it.', method(:show_help))
98
102
 
99
103
  cmd_list
100
104
  end
data/r2do.gemspec CHANGED
@@ -4,8 +4,8 @@ require File.expand_path('../lib/r2do/version', __FILE__)
4
4
  Gem::Specification.new do |gem|
5
5
  gem.authors = ["cgiacomi"]
6
6
  gem.email = ["christiangiacomi@gmail.com"]
7
- gem.description = %q{A simple todo gem}
8
- gem.summary = %q{A simple todo gem}
7
+ gem.summary = %q{r2do is a simple todo gem for the CLI}
8
+ gem.description = %q{r2do is a simple todo gem which allows you to create Tasks and group them by Category. r2do is meant for the CLI. }
9
9
  gem.homepage = "https://github.com/cgiacomi/r2do"
10
10
 
11
11
  gem.add_development_dependency "rspec"
@@ -20,4 +20,6 @@ Gem::Specification.new do |gem|
20
20
  gem.name = "r2do"
21
21
  gem.require_paths = ["lib"]
22
22
  gem.version = R2do::VERSION
23
+ gem.license = "Apache v2"
24
+ gem.post_install_message = "Thanks for installing r2do."
23
25
  end
@@ -0,0 +1,87 @@
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
+ require 'spec_helper'
18
+
19
+ module R2do
20
+ module Commands
21
+
22
+ describe Option do
23
+ before(:each) do
24
+ @callback_invoked = false
25
+ end
26
+
27
+ def callback(args)
28
+ @callback_invoked = true
29
+ end
30
+
31
+ describe "#new" do
32
+ context "valid arguments" do
33
+ it "returns an instance of Option" do
34
+ command = Option.new('c', 'category', 'description for this command', method(:callback))
35
+ command.should be_an_instance_of Option
36
+ end
37
+ end
38
+
39
+ context "null args" do
40
+ it "raises an error if the swtich is null" do
41
+ expect{ Option.new(nil, 'category', 'description for this command', method(:callback)) }.to raise_error(ArgumentError)
42
+ end
43
+
44
+ it "raises an error if the name is null" do
45
+ expect{ Option.new('c', nil, 'description for this command', method(:callback)) }.to raise_error(ArgumentError)
46
+ end
47
+
48
+ it "raises an error if the description is null" do
49
+ expect{ Option.new('c', 'category', nil, method(:callback)) }.to raise_error(ArgumentError)
50
+ end
51
+
52
+ it "raises an error if the callback is null" do
53
+ expect{ Option.new('c', 'category', 'desctiption', nil) }.to raise_error(ArgumentError)
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "#to_s" do
59
+ it "returns the correct representation" do
60
+ short = 'c'
61
+ extended = 'category'
62
+ description = 'description for this command'
63
+
64
+ result = "%2s, %-10s \t# %s" % [short, extended, description]
65
+ command = Option.new(short, extended, description, method(:callback))
66
+ command.to_s.should eql result
67
+ end
68
+ end
69
+
70
+ describe "#execute" do
71
+ it "exectutes the callback" do
72
+ @callback_invoked.should eql false
73
+
74
+ short = 'c'
75
+ extended = 'category'
76
+ description = 'description for this command'
77
+ args = Array.new
78
+ command = Option.new(short, extended, description, method(:callback))
79
+ command.execute(args)
80
+
81
+ @callback_invoked.should eql true
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ end
@@ -36,6 +36,20 @@ module R2do
36
36
  expect { Task.new }.to raise_error(ArgumentError)
37
37
  end
38
38
  end
39
+
40
+ context "with a length of more than 30 characters" do
41
+ it "raises and exception" do
42
+ name = "a"*31
43
+ expect { Task.new(name) }.to raise_error(ArgumentError)
44
+ end
45
+ end
46
+
47
+ context "with a length of 30 chars" do
48
+ it "returns a valid instance" do
49
+ name = "a"*30
50
+ Task.new(name)
51
+ end
52
+ end
39
53
  end
40
54
 
41
55
  describe "#description" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: r2do
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-22 00:00:00.000000000 Z
12
+ date: 2012-07-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -91,7 +91,8 @@ dependencies:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
- description: A simple todo gem
94
+ description: ! 'r2do is a simple todo gem which allows you to create Tasks and group
95
+ them by Category. r2do is meant for the CLI. '
95
96
  email:
96
97
  - christiangiacomi@gmail.com
97
98
  executables:
@@ -109,11 +110,15 @@ files:
109
110
  - lib/r2do.rb
110
111
  - lib/r2do/category.rb
111
112
  - lib/r2do/command.rb
113
+ - lib/r2do/commands/category_command.rb
114
+ - lib/r2do/commands/command.rb
115
+ - lib/r2do/commands/display_categories.rb
116
+ - lib/r2do/commands/help_command.rb
117
+ - lib/r2do/commands/init_command.rb
118
+ - lib/r2do/commands/now_command.rb
119
+ - lib/r2do/commands/task_command.rb
112
120
  - lib/r2do/exceptions.rb
113
- - lib/r2do/handlers/handle_categories.rb
114
- - lib/r2do/handlers/handle_category.rb
115
- - lib/r2do/handlers/handle_init.rb
116
- - lib/r2do/handlers/handle_task.rb
121
+ - lib/r2do/option.rb
117
122
  - lib/r2do/state.rb
118
123
  - lib/r2do/task.rb
119
124
  - lib/r2do/ui.rb
@@ -121,14 +126,15 @@ files:
121
126
  - lib/r2do/version.rb
122
127
  - r2do.gemspec
123
128
  - spec/r2do/category_spec.rb
124
- - spec/r2do/command_spec.rb
125
129
  - spec/r2do/controller_spec.rb
130
+ - spec/r2do/option_spec.rb
126
131
  - spec/r2do/r2do_spec.rb
127
132
  - spec/r2do/task_spec.rb
128
133
  - spec/spec_helper.rb
129
134
  homepage: https://github.com/cgiacomi/r2do
130
- licenses: []
131
- post_install_message:
135
+ licenses:
136
+ - Apache v2
137
+ post_install_message: Thanks for installing r2do.
132
138
  rdoc_options: []
133
139
  require_paths:
134
140
  - lib
@@ -140,7 +146,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
140
146
  version: '0'
141
147
  segments:
142
148
  - 0
143
- hash: -972365083019823289
149
+ hash: 755238635905797132
144
150
  required_rubygems_version: !ruby/object:Gem::Requirement
145
151
  none: false
146
152
  requirements:
@@ -149,17 +155,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
155
  version: '0'
150
156
  segments:
151
157
  - 0
152
- hash: -972365083019823289
158
+ hash: 755238635905797132
153
159
  requirements: []
154
160
  rubyforge_project:
155
161
  rubygems_version: 1.8.24
156
162
  signing_key:
157
163
  specification_version: 3
158
- summary: A simple todo gem
164
+ summary: r2do is a simple todo gem for the CLI
159
165
  test_files:
160
166
  - spec/r2do/category_spec.rb
161
- - spec/r2do/command_spec.rb
162
167
  - spec/r2do/controller_spec.rb
168
+ - spec/r2do/option_spec.rb
163
169
  - spec/r2do/r2do_spec.rb
164
170
  - spec/r2do/task_spec.rb
165
171
  - spec/spec_helper.rb
@@ -1,52 +0,0 @@
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 Handlers
19
- module_function
20
-
21
- # Displays all the categories available
22
- #
23
- # @param [Array] args the arguments passed to the app by the user
24
- # @return [void]
25
- def handle_categories(args)
26
- if @state.categories.empty?
27
- UI.status("No categories to display")
28
- else
29
- @state.categories.each do |key, value|
30
- current = (value == @state.current_category && "*") || ' '
31
- UI.status("#{current} #{value.name}")
32
- end
33
- end
34
- end
35
-
36
- # Displays the help for a command
37
- #
38
- # @param [Array] args the arguments passed to the app by the user
39
- # @return [void]
40
- def handle_help(args)
41
- if args.length < 2
42
- show_help(args)
43
- return
44
- end
45
-
46
- command = args[1]
47
- UI.status("TODO: show the help for command '%s'" % command)
48
- end
49
-
50
- end
51
-
52
- end