slimtimercli 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ == 0.1.3 2008-04-07
2
+ * fixed bug that allows starting a nonexisting task
3
+ * refactored options to start slimtimer
4
+
1
5
  == 0.1.2 2008-04-06
2
6
  * time recording can only be stopped if a task was started
3
7
  * time recording can only be started if no other task was started
data/bin/slimtimer CHANGED
@@ -4,9 +4,7 @@ require 'rubygems'
4
4
  gem 'slimtimercli'
5
5
  require 'slimtimercli'
6
6
 
7
- # Run
8
- if ARGV.size == 0
9
- Slimtimercli.__send__(:help)
10
- else
11
- Slimtimercli.__send__(ARGV[0].to_sym)
12
- end
7
+ include Slimtimercli
8
+
9
+ c = CommandLine.new(ARGV)
10
+ c.run
data/lib/slimtimercli.rb CHANGED
@@ -6,7 +6,9 @@ require 'net/http'
6
6
  require 'rubygems'
7
7
  require 'active_record'
8
8
  require 'active_support'
9
- require 'yaml'
9
+ require 'yaml'
10
+ require 'optparse'
11
+ require 'ostruct'
10
12
 
11
13
  require "slimtimercli/entities"
12
14
  require "slimtimercli/slim_timer"
@@ -14,7 +16,7 @@ require "slimtimercli/version"
14
16
 
15
17
  module Slimtimercli
16
18
  module Helper
17
- def self.login
19
+ def login
18
20
  config = Helper::load_config
19
21
  st = SlimTimer.new(config["email"], config["password"],
20
22
  config["api_key"])
@@ -23,23 +25,23 @@ module Slimtimercli
23
25
  st
24
26
  end
25
27
 
26
- def self.root
28
+ def root
27
29
  File.join(ENV["HOME"], ".slimtimer")
28
30
  end
29
31
 
30
- def self.config_file
32
+ def config_file
31
33
  File.join(root, "config.yml")
32
34
  end
33
35
 
34
- def self.tasks_file
36
+ def tasks_file
35
37
  File.join(root, "tasks.yml")
36
38
  end
37
39
 
38
- def self.current_file
40
+ def current_file
39
41
  File.join(root, "current.yml")
40
42
  end
41
43
 
42
- def self.check_and_create_dir
44
+ def check_and_create_dir
43
45
  raise "Home DIR not set!" unless ENV["HOME"]
44
46
 
45
47
  unless File.directory?(root)
@@ -47,7 +49,7 @@ module Slimtimercli
47
49
  end
48
50
  end
49
51
 
50
- def self.load_config
52
+ def load_config
51
53
  check_and_create_dir
52
54
 
53
55
  unless File.exists?(File.join(root, "config.yml"))
@@ -58,89 +60,76 @@ module Slimtimercli
58
60
  load_file("config.yml")
59
61
  end
60
62
 
61
- def self.save_config(config)
63
+ def save_config(config)
62
64
  dump_to_file(config, "config.yml")
63
65
  end
64
66
 
65
- def self.load_file(file)
67
+ def load_file(file)
66
68
  File.open( File.join(root, file) ) { |yf| YAML::load( yf ) }
67
69
  end
68
70
 
69
- def self.dump_to_file(object, file)
71
+ def dump_to_file(object, file)
70
72
  check_and_create_dir
71
73
  File.open( File.join(root, file), 'w' ) do |out|
72
74
  YAML.dump(object, out )
73
75
  end
74
76
  end
75
- end
76
-
77
- def self.create_task
78
- name = ARGV[1]
79
-
80
- st = Helper::login
81
- if st.create_task(name)
82
- Helper::dump_to_file(st.tasks, "tasks.yml")
83
- puts "Task #{name} successfully created."
84
- end
85
- end
86
-
87
- def self.tasks(show= true)
88
- config = Helper::load_config
89
- st = SlimTimer.new(config["email"], config["password"],
90
- config["api_key"])
91
-
92
- if !File.exists?(Helper::tasks_file) ||
93
- File.mtime(Helper::tasks_file) < (Time.now - 60 * 60 *24)
94
-
95
- st.login
96
- Helper::dump_to_file(st.tasks, "tasks.yml")
97
- end
98
77
 
99
- tasks = Helper::load_file("tasks.yml")
100
-
101
- return tasks unless show
102
-
103
- tasks.each do |t|
104
- puts t.name
105
- end
106
- end
107
-
108
- def self.force_reload
109
- config = Helper::load_config
110
- st = SlimTimer.new(config["email"], config["password"],
111
- config["api_key"])
112
-
113
- st.login
114
- Helper::dump_to_file(st.tasks, "tasks.yml")
115
- tasks = Helper::load_file("tasks.yml")
116
-
117
- tasks.each do |t|
118
- puts t.name
78
+ def rm_current
79
+ FileUtils.rm(current_file) if
80
+ File.exists?(current_file)
119
81
  end
120
- end
121
82
 
122
- # This method stores the credentials in the necessary directoyr
123
- def self.setup
124
- config = Helper::load_config
125
-
126
- puts "Slimtimer Login Credentials\n"
127
- print "E-Mail: "
128
- config["email"] = STDIN.gets.gsub("\n", "")
129
-
130
- print "Password: "
131
- config["password"] = STDIN.gets.gsub("\n", "")
132
-
133
- print "API Key: "
134
- config["api_key"] = STDIN.gets.gsub("\n", "")
135
-
136
- Helper::save_config(config)
137
-
138
- # clear the screen
139
- system("clear")
140
- end
141
-
142
- def self.help
143
- puts <<-HELP
83
+ def parse(args)
84
+
85
+ if !args || args.empty?
86
+ raise "Need to specify arguments, run slimtimer -h for help"
87
+
88
+ end
89
+
90
+ options = OpenStruct.new
91
+ options.force = false
92
+
93
+ opts = OptionParser.new do |opts|
94
+
95
+ opts.banner = "Usage: slimtimer [options]"
96
+
97
+ opts.on("-s TASK", "--start TASK",
98
+ "Start a TASK given by the task name") do |t|
99
+
100
+ options.run = "start"
101
+ options.task_name = t
102
+ end
103
+
104
+ opts.on("-c TASK", "--create TASK",
105
+ "Create a ne task by the given name") do |t|
106
+ options.run = "create"
107
+ options.task_name = t
108
+ end
109
+
110
+ opts.on("-e", "--end" ,"Stops time recording for the given task") do
111
+ options.run = "stop"
112
+ end
113
+
114
+ opts.on("-t", "--tasks", "Prints all available tasks") do
115
+ options.run = "tasks"
116
+ end
117
+
118
+ opts.on("-f", "--force", "Force deletion of tasks") do
119
+ options.force = true
120
+ end
121
+
122
+ opts.on("--setup", "Setup your account") do
123
+ options.run = "setup"
124
+ end
125
+
126
+ opts.on_tail("-h", "Shows this note") do
127
+ puts opts
128
+ exit
129
+ end
130
+
131
+ opts.on("--help", "Show verbose help") do
132
+ @out.puts <<-HELP
144
133
  SlimTimer is a tool to record your time spend on a
145
134
  task. SlimTimer CLI allows you to controll your
146
135
  SlimTimer directly from where you spend most of your
@@ -174,53 +163,166 @@ Finally you can run
174
163
 
175
164
  To show all your tasks available.
176
165
  HELP
166
+ exit
167
+ end
168
+ end
169
+
170
+ begin
171
+ opts.parse!(args)
172
+ rescue
173
+ puts $!.message
174
+ exit
175
+ end
176
+ options
177
+ end
177
178
  end
178
179
 
179
- def self.start
180
- if ARGV.empty?
181
- puts "Need to specify a task as argument"
182
- return false
180
+ class CommandLine
181
+
182
+ # Include Helper module
183
+ include Helper
184
+
185
+ def initialize(args, output = $stdout)
186
+ @args = args
187
+ @out = output
188
+
189
+ deprecated_calls
190
+
191
+ @options = parse(args)
183
192
  end
184
-
185
- if File.exists?(Helper::current_file)
186
- puts "Need to stop the other task first"
187
- return false
193
+
194
+ def create
195
+ st = login
196
+ if st.create_task(@options.task_name)
197
+ dump_to_file(st.tasks, "tasks.yml")
198
+ @out.puts "Task #{name} successfully created."
199
+ end
188
200
  end
189
201
 
190
- info = {"task" => ARGV[1],
191
- "start_time" => Time.now}
192
-
193
- # dum curent task to file
194
- Helper::dump_to_file(info, "current.yml")
195
- return true
196
- end
202
+ def tasks(show = true)
203
+ tasks = load_tasks
204
+ return tasks unless show
197
205
 
198
- def self.end
199
- begin
200
- info = Helper::load_file("current.yml")
201
- rescue
202
- puts "You must start a task before you finish it"
203
- return false
206
+ tasks.each do |t|
207
+ @out.puts t.name
208
+ end
204
209
  end
210
+
211
+ def setup
212
+ config = load_config
213
+
214
+ @out.puts "Slimtimer Login Credentials\n"
215
+ @out.print "E-Mail: "
216
+ config["email"] = STDIN.gets.gsub("\n", "")
217
+
218
+ @out.print "Password: "
219
+ config["password"] = STDIN.gets.gsub("\n", "")
205
220
 
221
+ @out.print "API Key: "
222
+ config["api_key"] = STDIN.gets.gsub("\n", "")
206
223
 
207
- #Find task in tasks yml
208
- t = tasks(false).find {|t| t.name == info["task"]}
224
+ save_config(config)
209
225
 
210
- raise "Task not found in list. Reload List?" unless t
226
+ # clear the screen
227
+ system("clear")
228
+ end
229
+
230
+ def start
231
+ if File.exists?(current_file)
232
+ @out.puts "Need to stop the other task first"
233
+ return false
234
+ end
235
+
236
+ info = {"task" => @options.task_name,
237
+ "start_time" => Time.now}
238
+
239
+ #Find task in tasks yml
240
+ t = load_tasks.find {|t| t.name == info["task"]}
241
+ unless t
242
+ @out.puts "Task not found in list. Reload List?"
243
+ return false
244
+ end
211
245
 
212
- st = Helper::login
213
- result = st.create_time_entry(t, info["start_time"],
214
- (Time.now - info["start_time"]).to_i)
246
+ dump_to_file(info, "current.yml")
247
+ return true
248
+ end
249
+
250
+ def stop
215
251
 
216
- # Delete yml file
217
- if result
218
- FileUtils.rm(Helper::current_file)
219
- end
252
+ if @options.force
253
+ rm_current
254
+ @out.puts "Forced ending of task, no entry to slimtimer.com written"
255
+ return true
256
+ end
257
+
258
+
259
+ begin
260
+ info = load_file("current.yml")
261
+ rescue
262
+ puts "You must start a task before you finish it"
263
+ return false
264
+ end
220
265
 
221
- # Output
222
- puts "Wrote new Entry for #{t.name}, duration #{result["duration_in_seconds"] / 60}m"
223
- return true
266
+ #Find task in tasks yml
267
+ t = load_tasks.find {|t| t.name == info["task"]}
268
+ unless t
269
+ @out.puts "Task not found in list. Reload List?"
270
+ return false
271
+ end
272
+ raise unless t
273
+
274
+ st = login
275
+ result = st.create_time_entry(t, info["start_time"],
276
+ (Time.now - info["start_time"]).to_i)
277
+
278
+ # Delete yml file
279
+ if result
280
+ rm_current
281
+
282
+ # Output
283
+ @out.puts "Wrote new Entry for #{t.name}, duration #{result["duration_in_seconds"] / 60}m"
284
+ return true
285
+ else
286
+ @out.puts "Coult not write new entry, please try again"
287
+ return false
288
+ end
289
+ end
290
+
291
+ def run
292
+ send(@options.run.to_sym)
293
+ end
294
+
295
+ alias_method :end, :stop
296
+
297
+ private
298
+
299
+ # This method checks if the first parameter in args needs to
300
+ # be transformed to the new one
301
+ def deprecated_calls
302
+ case @args[0]
303
+ when "start": @args[0] = "-s"
304
+ when "end": @args[0] = "-e"
305
+ when "create_task": @args[0] = "-c"
306
+ when "tasks": @args[0] = "-t"
307
+ when "setup": @args[0] = "--setup"
308
+ end
309
+ end
310
+
311
+ def load_tasks(force = false)
312
+ config = load_config
313
+ st = SlimTimer.new(config["email"], config["password"],
314
+ config["api_key"])
315
+
316
+ tasks = []
317
+ if !File.exists?(tasks_file) ||
318
+ File.mtime(tasks_file) < (Time.now - 60 * 60 *24) || force
319
+ st.login
320
+ tasks = st.tasks
321
+ dump_to_file(tasks, "tasks.yml")
322
+ else
323
+ tasks = load_file("tasks.yml")
324
+ end
325
+ tasks
326
+ end
224
327
  end
225
-
226
328
  end
@@ -2,7 +2,7 @@ module Slimtimercli #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- TINY = 2
5
+ TINY = 3
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -1,5 +1,6 @@
1
- require File.dirname(__FILE__) + '/spec_helper.rb'
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
2
 
3
+ include Slimtimercli::Helper
3
4
  # Time to add your specs!
4
5
  # http://rspec.rubyforge.org/
5
6
  describe "SlimTimer" do
@@ -7,8 +8,11 @@ describe "SlimTimer" do
7
8
  describe "Helper" do
8
9
 
9
10
  it "should return the path to the config files" do
10
- Slimtimercli::Helper::config_file.should =~ /.slimtimer\/config.yml/
11
- Slimtimercli::Helper::tasks_file.should =~ /.slimtimer\/tasks.yml/
11
+
12
+ st = Slimtimercli::CommandLine.new(["-e"])
13
+
14
+ st.config_file.should =~ /.slimtimer\/config.yml/
15
+ st.tasks_file.should =~ /.slimtimer\/tasks.yml/
12
16
  end
13
17
 
14
18
  end
@@ -49,44 +53,92 @@ describe "SlimTimer" do
49
53
  describe "command line interface" do
50
54
 
51
55
  before do
52
- Slimtimercli::Helper.stub!(:root).and_return(File.dirname(__FILE__))
56
+ Slimtimercli::CommandLine.
57
+ any_instance.stubs(:root).returns(File.dirname(__FILE__))
53
58
 
54
59
  @c = File.join(File.dirname(__FILE__), "current.yml")
55
60
  FileUtils.rm(@c) if File.exists?(@c)
56
61
 
57
62
  @d = File.join(File.dirname(__FILE__), "config.yml")
58
63
  FileUtils.rm(@d) if File.exists?(@d)
64
+
59
65
  end
60
66
 
61
67
  it "should start a task" do
62
-
63
- # Manipulate ARGV
64
- Slimtimercli.start
68
+ # Manipulate ARGV
69
+
70
+ lambda { Slimtimercli::CommandLine.new([]) }.should
71
+ raise_error(RuntimeError)
65
72
  File.exists?(@c).should be_false
66
-
73
+
74
+ Slimtimercli::CommandLine.
75
+ any_instance.stubs(:load_tasks).
76
+ returns(stub("task", :find => stub("task", :name => "test")))
77
+
67
78
  # Set a task
68
79
  ARGV[1] = "test"
69
- Slimtimercli.start
80
+
81
+ st = Slimtimercli::CommandLine.new(ARGV)
82
+ st.start
70
83
  File.exists?(@c).should be_true
71
84
 
72
85
  # no double start
73
- Slimtimercli.start.should be_false
74
-
75
-
86
+ st.start.should be_false
76
87
  end
77
88
 
78
89
  it "should stop a task" do
79
- Slimtimercli.stub!(:tasks).and_return(stub("task", :find => stub("task", :name => "test")))
80
- Slimtimercli::Helper.stub!(:login).
81
- and_return(stub("slimtimer", :create_time_entry => {"duration_in_seconds" => 10}))
90
+ Slimtimercli::CommandLine.
91
+ any_instance.stubs(:load_tasks).
92
+ returns(stub("task", :find => stub("task", :name => "test")))
93
+
94
+ Slimtimercli::CommandLine.any_instance.stubs(:login).
95
+ returns(stub("slimtimer",
96
+ :create_time_entry => {"duration_in_seconds" => 10}))
82
97
 
83
- ARGV[1] = "test"
84
- Slimtimercli.start.should be_true
85
- Slimtimercli.end.should be_true
98
+ ARGV[1] = "test"
99
+ st = Slimtimercli::CommandLine.new(ARGV)
100
+ st.start.should be_true
101
+ st.end.should be_true
102
+
103
+ File.exists?(@c).should be_false
86
104
  end
87
105
 
88
106
  it "should not stop a task if none is running" do
89
- Slimtimercli.end.should be_false
107
+ st = Slimtimercli::CommandLine.new(["-e"])
108
+ st.end.should be_false
109
+ end
110
+
111
+ it "should not start a task that does not exist" do
112
+ Slimtimercli::CommandLine.any_instance.
113
+ stubs(:load_tasks).returns(stub("task", :find => nil))
114
+
115
+ ARGV[1] = "not exisiting task"
116
+ st = Slimtimercli::CommandLine.new(ARGV)
117
+ st.start.should be_false
118
+
119
+ end
120
+
121
+ it "should allow to force the deletion of the current task" do
122
+ st = Slimtimercli::CommandLine.new(["-e"])
123
+ st.end.should be_false
124
+ ARGV[0] = "-e"
125
+ ARGV[1] = "--force" || "-f"
126
+ st = Slimtimercli::CommandLine.new(ARGV)
127
+ st.end.should be_true
128
+ end
129
+
130
+ end
131
+
132
+ describe "option parser" do
133
+
134
+ it "should parse the start part correctly" do
135
+
136
+ args = ["--start", "my_task"]
137
+ options = parse(args)
138
+
139
+ options.run.should == "start"
140
+ options.task_name.should == "my_task"
141
+
90
142
  end
91
143
 
92
144
  end
data/spec/spec_helper.rb CHANGED
@@ -1,10 +1,20 @@
1
1
  begin
2
+
2
3
  require 'spec'
4
+ require 'mocha'
5
+
3
6
  rescue LoadError
4
7
  require 'rubygems'
5
8
  gem 'rspec'
6
- require 'spec'
9
+ require 'spec'
10
+
11
+ gem 'mocha'
12
+ require 'mocha'
7
13
  end
8
-
14
+
9
15
  $:.unshift(File.dirname(__FILE__) + '/../lib')
10
- require 'slimtimercli'
16
+ require 'slimtimercli'
17
+
18
+ Spec::Runner.configure do |config|
19
+ config.mock_with :mocha
20
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slimtimercli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Grund
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-04-06 00:00:00 +02:00
12
+ date: 2008-04-07 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies: []
15
15