slimtimercli 0.1.2 → 0.1.3

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/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