Pratt 1.6.8-x86-linux

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.
Files changed (72) hide show
  1. data/.exrc +61 -0
  2. data/.gitignore +6 -0
  3. data/History.txt +6 -0
  4. data/Manifest.txt +46 -0
  5. data/Pratt.gemspec +173 -0
  6. data/Pratt.mm +1867 -0
  7. data/README.txt +67 -0
  8. data/Rakefile +96 -0
  9. data/TODO +56 -0
  10. data/VERSION +1 -0
  11. data/bin/pratt +13 -0
  12. data/config.rb +19 -0
  13. data/db/sqlite_databases_go_here +0 -0
  14. data/db/zips.csv.zip +0 -0
  15. data/lib/models.rb +8 -0
  16. data/lib/pratt.rb +308 -0
  17. data/lib/pratt/core_ext.rb +6 -0
  18. data/lib/pratt/core_ext/array.rb +20 -0
  19. data/lib/pratt/core_ext/float.rb +29 -0
  20. data/lib/pratt/core_ext/nil.rb +5 -0
  21. data/lib/pratt/core_ext/numeric.rb +9 -0
  22. data/lib/pratt/core_ext/string.rb +31 -0
  23. data/lib/pratt/core_ext/time.rb +20 -0
  24. data/lib/pratt/dialogs.rb +81 -0
  25. data/lib/pratt/formatting.rb +19 -0
  26. data/lib/pratt/project_actions.rb +25 -0
  27. data/lib/pratt/reports.rb +140 -0
  28. data/models/app.rb +39 -0
  29. data/models/customer.rb +50 -0
  30. data/models/invoice.rb +28 -0
  31. data/models/invoice_whence.rb +18 -0
  32. data/models/payment.rb +22 -0
  33. data/models/pratt.rb +15 -0
  34. data/models/project.rb +89 -0
  35. data/models/whence.rb +77 -0
  36. data/models/zip.rb +27 -0
  37. data/pratt.mm +1875 -0
  38. data/spec/app_spec.rb +48 -0
  39. data/spec/array_spec.rb +24 -0
  40. data/spec/customer_spec.rb +31 -0
  41. data/spec/fixtures/empty_graph.expectation +8 -0
  42. data/spec/fixtures/graph.expectation +13 -0
  43. data/spec/fixtures/proportions.expectation +4 -0
  44. data/spec/float_spec.rb +24 -0
  45. data/spec/formatting_spec.rb +7 -0
  46. data/spec/money_spec.rb +9 -0
  47. data/spec/nil_class_spec.rb +8 -0
  48. data/spec/numeric_spec.rb +30 -0
  49. data/spec/payment_spec.rb +19 -0
  50. data/spec/pratt_spec.rb +106 -0
  51. data/spec/project_spec.rb +182 -0
  52. data/spec/rcov.opts +0 -0
  53. data/spec/report_action_spec.rb +83 -0
  54. data/spec/report_spec.rb +205 -0
  55. data/spec/seed_data.rb +33 -0
  56. data/spec/spec.opts +1 -0
  57. data/spec/spec_helper.rb +24 -0
  58. data/spec/string_ext_spec.rb +33 -0
  59. data/spec/whence_spec.rb +54 -0
  60. data/tasks/pratt.rb +87 -0
  61. data/templates/model.eruby +12 -0
  62. data/templates/spec.eruby +8 -0
  63. data/views/current.eruby +5 -0
  64. data/views/general-invoice.eruby +538 -0
  65. data/views/graph.eruby +16 -0
  66. data/views/invoice.eruby +148 -0
  67. data/views/main.rb +90 -0
  68. data/views/pid.eruby +3 -0
  69. data/views/pop.rb +78 -0
  70. data/views/proportions.eruby +4 -0
  71. data/views/raw.eruby +11 -0
  72. metadata +275 -0
@@ -0,0 +1,67 @@
1
+ = pratt
2
+
3
+ * Pratt (url)
4
+
5
+ == DESCRIPTION:
6
+
7
+ Pratt (Pro/Re)-Active Time Tracker
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ (list of features or problems)
12
+ * Currently you'll need to manually fix the project data since I haven't
13
+ fully integrated the support for Projects to have a Customer.
14
+ * Upgrading versions looses your database. (See TODO)
15
+ * Windows doesn't work (no fork). (See TODO)
16
+
17
+
18
+ == SYNOPSIS:
19
+
20
+ * pratt (code sample of usage)
21
+
22
+ ** PRATT_ENV=production pratt -D # daemonize (or if already daemonized init the
23
+ gui)
24
+ ** pratt -h (as you'd expect lists available commands)
25
+
26
+ == REQUIREMENTS:
27
+
28
+ * pratt
29
+ debian: libtcltk-ruby tk-tile libsqlite3-dev
30
+ gems: activerecord sqlite3-ruby rspec mocha
31
+ tk: http://sourceforge.net/project/showfiles.php?group_id=11464&package_id=107795&release_id=562098
32
+
33
+ == INSTALL:
34
+
35
+ * sudo gem install
36
+
37
+ Credits
38
+
39
+ Michael Goff
40
+ Thanks for helping me with some of the workflow details
41
+ Michael and Kent Krenrich
42
+ Thanks for the UI input, suggestions, and testing.
43
+
44
+ == LICENSE:
45
+
46
+ (The MIT License)
47
+
48
+ Copyright (c) 2009 Frogstarr78 Software
49
+
50
+ Permission is hereby granted, free of charge, to any person obtaining
51
+ a copy of this software and associated documentation files (the
52
+ 'Software'), to deal in the Software without restriction, including
53
+ without limitation the rights to use, copy, modify, merge, publish,
54
+ distribute, sublicense, and/or sell copies of the Software, and to
55
+ permit persons to whom the Software is furnished to do so, subject to
56
+ the following conditions:
57
+
58
+ The above copyright notice and this permission notice shall be
59
+ included in all copies or substantial portions of the Software.
60
+
61
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
62
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
63
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
64
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
65
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
66
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
67
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,96 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'lib/pratt'
6
+ require 'tasks/pratt'
7
+
8
+ task :default => :spec
9
+
10
+ begin
11
+ require 'jeweler'
12
+ Jeweler::Tasks.new do |gem|
13
+ gem.rubyforge_project = Pratt::NAME
14
+ gem.name = Pratt::NAME
15
+ gem.summary = Pratt::SUMMARY
16
+ gem.description = Pratt::DESCRIPTION
17
+ gem.email = "frogstarr78@gmail.com"
18
+ gem.homepage = "http://github.com/frogstarr78/pratt"
19
+ gem.authors = Pratt::AUTHORS
20
+ gem.add_development_dependency 'rspec', '>=1.2.6'
21
+ gem.add_development_dependency 'mocha', '>=0.9.5'
22
+ gem.add_runtime_dependency 'activerecord', '>=2.1.1'
23
+ gem.add_runtime_dependency 'sqlite3-ruby', '=1.2.4'
24
+ gem.add_runtime_dependency 'shifty_week', '>=0.1.0'
25
+ gem.add_runtime_dependency 'erubis', '=2.6.5'
26
+ gem.add_runtime_dependency 'chronic', '=0.2.3'
27
+ gem.add_runtime_dependency 'colored', '=1.2'
28
+ gem.platform = 'current'
29
+ gem.test_files = FileList['spec/**/*.{rb,opts}', 'spec/fixtures/*.expectation']
30
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
31
+ end
32
+ Jeweler::GemcutterTasks.new
33
+ Jeweler::RubyforgeTasks.new do |rubyforge|
34
+ rubyforge.doc_task = "rdoc"
35
+ end
36
+ rescue LoadError
37
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
38
+ end
39
+
40
+ require 'spec/rake/spectask'
41
+ Spec::Rake::SpecTask.new(:spec) do |spec|
42
+ spec.libs << 'lib' << 'spec'
43
+ spec.spec_files = FileList['spec/**/*_spec.rb']
44
+ end
45
+
46
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
47
+ spec.libs << 'lib' << 'spec'
48
+ spec.pattern = 'spec/**/*_spec.rb'
49
+ spec.rcov = true
50
+ spec.rcov_opts = %w(--text-report --exclude=activerecord,ruby-debug,shifty_week,sqlite3-ruby,rspec,mocha,erubis,chronic,colored,columnize,builder,activesupport,i18n,linecache,json_pure,rcov,abstract,spec_helper.rb,config.rb,spec)
51
+ end
52
+
53
+ task :spec => :check_dependencies
54
+
55
+ begin
56
+ require 'reek/adapters/rake_task'
57
+ Reek::RakeTask.new do |t|
58
+ t.fail_on_error = true
59
+ t.verbose = false
60
+ t.source_files = 'lib/**/*.rb'
61
+ end
62
+ rescue LoadError
63
+ task :reek do
64
+ abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
65
+ end
66
+ end
67
+
68
+ begin
69
+ require 'roodi'
70
+ require 'roodi_task'
71
+ RoodiTask.new do |t|
72
+ t.verbose = false
73
+ end
74
+ rescue LoadError
75
+ task :roodi do
76
+ abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi"
77
+ end
78
+ end
79
+
80
+ task :default => :spec
81
+
82
+ require 'rake/rdoctask'
83
+ Rake::RDocTask.new do |rdoc|
84
+ if File.exist?('VERSION')
85
+ version = File.read('VERSION')
86
+ else
87
+ version = ""
88
+ end
89
+
90
+ rdoc.rdoc_dir = 'rdoc'
91
+ rdoc.title = "pratt #{version}"
92
+ rdoc.rdoc_files.include('README*')
93
+ rdoc.rdoc_files.include('lib/**/*.rb')
94
+ end
95
+
96
+ # vim: syntax=ruby
data/TODO ADDED
@@ -0,0 +1,56 @@
1
+ General:
2
+ [ ] Remove environment ability
3
+ [ ] Change to use raw command line arguments / Remove optparse lib
4
+ [ ] Update general package setup (It's messy)
5
+ [?] Add file watching like merb
6
+ [?] Move to Observer Pattern for reporting functionality
7
+
8
+ Invoicing:
9
+ [x] Add shifty week plugin
10
+ [ ] Add support for variable rates.
11
+
12
+ Templating:
13
+ [ ] Invoices
14
+ [x] Move other output to template based
15
+
16
+ Data:
17
+ [?] Change to Use DataMapper
18
+ [?] Put everything in the db? (logs, app locks, etc)
19
+ [ ] Move database location to central location that doesn't dissappear when upgrading the app.
20
+
21
+ GUI:
22
+ [ ] Add TrayIcon.
23
+ [ ] Customer CRUD
24
+ [ ] Payment CRUD
25
+ [ ] Re-design prompts
26
+ [ ] Remove fork in favor of ( eval OR (!?!) GUI classes )
27
+ [ ] Don't assume gui.
28
+
29
+ Test:
30
+ [ ] Add more I'm not testing everything
31
+ [ ] Flog
32
+ [ ] Flay
33
+
34
+
35
+
36
+ Done:
37
+ [x] Whence.last should be last unended.
38
+ [x] Add date range argument to timed report.
39
+ [x] Add validation for start/end at.
40
+ [x] Manual data manipulation date/time.
41
+ [x] Change pop prompt to show helpful time.
42
+ [x] Change Start/Continue interface.
43
+ [x] Add directoryless agnostic runner.
44
+ [x] Log output.
45
+ [x] Add Quiet option??
46
+ [x] Allow only one prompt at a time.
47
+ [x] Handle stop when there isn't a running project w/out errors
48
+ [x] fix gui so if last_unended is detected app knows which gui to display
49
+ [x] Intelligently detect correctly running stored pid.
50
+ [x] Fix pid directory access.
51
+
52
+ [x] Add support for Customer's model
53
+ [x] Add Template command
54
+ [x] Add Invoice command
55
+ [x] Fix colorability
56
+ [x] Add console command
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.6.8
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'fileutils'
4
+ bin_file = __FILE__
5
+ bin_file = File.symlink?(bin_file) ? File.readlink(bin_file) : bin_file
6
+
7
+ bin_path = File.expand_path( '..', bin_file )
8
+ pratt_dir = File.dirname( bin_path )
9
+ FileUtils.chdir pratt_dir
10
+
11
+ require "lib/pratt"
12
+
13
+ Pratt.parse(ARGV)
@@ -0,0 +1,19 @@
1
+ PRATT_ENV = ENV["PRATT_ENV"] || 'development' unless Object.const_defined? :PRATT_ENV
2
+
3
+ class Pratt
4
+ include FileUtils
5
+
6
+ class << self
7
+ def connect! to_env = :development
8
+ connect_to = "db/#{to_env}.sqlite3"
9
+ ActiveRecord::Base.establish_connection( :adapter => 'sqlite3', :database => connect_to )
10
+ unless File.exists? connect_to
11
+ Pratt.migrate
12
+ end
13
+ end
14
+
15
+ def connected?
16
+ ActiveRecord::Base.connected?
17
+ end
18
+ end
19
+ end
File without changes
Binary file
@@ -0,0 +1,8 @@
1
+ require 'models/app'
2
+ require 'models/customer'
3
+ require 'models/whence'
4
+ require 'models/project'
5
+ require 'models/payment'
6
+ require 'models/invoice'
7
+ require 'models/invoice_whence'
8
+ require 'models/zip'
@@ -0,0 +1,308 @@
1
+ # coding: utf-8
2
+ require 'fileutils'
3
+ require 'optparse'
4
+ require 'pathname'
5
+
6
+ require 'rubygems'
7
+ require 'colored'
8
+ require 'chronic'
9
+ require 'active_record'
10
+ require 'erubis'
11
+ require 'config'
12
+ require 'shifty_week'
13
+ require 'shifty_week/time'
14
+ require 'shifty_week/date'
15
+
16
+ require 'lib/pratt/formatting'
17
+ require 'lib/pratt/core_ext'
18
+ require 'lib/pratt/dialogs'
19
+ require 'lib/pratt/project_actions'
20
+ require 'lib/pratt/reports'
21
+ require 'lib/models'
22
+
23
+
24
+ class Pratt
25
+
26
+ NAME = 'Pratt'
27
+ URL = 'http://www.frogstarr78.com/projects/pratt'
28
+ AUTHORS = ['Scott Noel-Hemming']
29
+ SUMMARY = "Pro/Re-Active Time Tracker. Track time based on what you expect to be working on, with frequent prompts to ensure accuracy."
30
+ DESCRIPTION = %q|
31
+ Need a way to keep track of your time, but get caught up in work? Or constant interruptions?
32
+ Yeah you know who I'm talking about. Those people from the [abc] department always "NEEDING xyz FEATURE NOW!!!".
33
+ Seriously though. I'm usually just loose track of time. I wanted an app that I could start with a task I think
34
+ I'll be working on, but that get's in my face constantly to ensure I'm still working on it. And if I'm not any longer,
35
+ provides an easy way of changing to another task, or if I have changed tasks and not already updated the app, would
36
+ provide an easy way of changing the task of the previously recorded interval. That's what this is intended to do.
37
+
38
+ Time Tracking.
39
+ Proactively set what you expect to work on.
40
+ Reactively modify what you are no longer working on.
41
+ |
42
+ DEPENDENCIES = ["activerecord >=2.1.1", "sqlite3-ruby >=1.2.4", "rspec >=1.2.6", "mocha >=0.9.5"]
43
+ VERSION = File.open( File.join(Dir.pwd, 'VERSION') ).read.strip
44
+
45
+ PID_FILE='pratt.pid'
46
+ FMT = "%a %X %b %d %Y"
47
+ INVOICE_FMT = "%x"
48
+
49
+ attr_accessor :when_to, :scale, :color, :show_all, :raw_conditions, :template, :week_day_start
50
+ attr_reader :project, :todo
51
+ def initialize proj = nil
52
+ @when_to = DateTime.now
53
+ @week = false
54
+ @day = false
55
+ @todo = []
56
+ @scale = nil
57
+ @show_all = false
58
+ @template = nil
59
+ @raw_conditions = ''
60
+ self.project = proj unless proj.nil?
61
+ end
62
+
63
+ # Set the project to something (Project/String)
64
+ # Conditionally creating a new project if the project
65
+ # named by the parameter isn't found
66
+ def project= proj
67
+ if proj.is_a?(Project)
68
+ @project = proj
69
+ else
70
+ @project = Project.find_or_create_by_name( { :name => proj } )
71
+ end
72
+ end
73
+
74
+ # We should act like an array
75
+ def << what
76
+ @todo << what
77
+ end
78
+
79
+ # Connect to the database in irb for manual commands/investigation
80
+ def console
81
+ require 'irb'
82
+ require 'irb/completion'
83
+ ARGV.clear
84
+ IRB.start
85
+ end
86
+
87
+ # Stop everything and kill daemonized processes.
88
+ def quit
89
+ project.stop! if project? and project.whences.last_unended
90
+ Whence.last_unended.stop! if Whence.last_unended
91
+ begin
92
+ Process.kill("KILL", app.pid.to_i)
93
+ rescue Errno::ESRCH
94
+ puts "Unable to kill Pratt@pid(#{app.pid})."
95
+ end
96
+ app.pid = ''
97
+ app.gui = ''
98
+ app.save!
99
+ end
100
+
101
+ # Singleton Accessor for @app
102
+ def app
103
+ @app ||= App.last
104
+ @app
105
+ end
106
+
107
+ # "Unlock" the gui.
108
+ def unlock
109
+ self.app.unlock
110
+ end
111
+
112
+ def run
113
+ # ensure we've shifted the when_to value to the
114
+ # current start of week
115
+ self.when_to.week_day_start = self.week_day_start
116
+
117
+ # << order is semi important
118
+ self.end if i_should? :end
119
+ self.begin if i_should? :begin
120
+ self.change if i_should? :change
121
+ self.restart if i_should? :restart
122
+
123
+ self.destroy if i_should? :destroy
124
+ # end order is semi important
125
+
126
+ # << order doesn't matter within this set
127
+ self.pid if i_should? :pid
128
+ self.raw if i_should? :raw
129
+ self.current if i_should? :current
130
+ self.graph if i_should? :graph
131
+ self.proportions if i_should? :proportions
132
+ self.invoice if i_should? :invoice
133
+ self.console if i_should? :console
134
+ self.gui if i_should? :gui
135
+ self.detect if i_should? :detect
136
+ self.unlock if i_should? :unlock
137
+ # end order doesn't matter within this set
138
+
139
+ # << these should happen last
140
+ self.quit if i_should? :quit
141
+ self.daemonize! if i_should? :daemonize and not self.daemonized?
142
+ # end these should happen last
143
+ end
144
+
145
+ private
146
+ def i_should? what
147
+ @todo.include?(what)
148
+ end
149
+
150
+ # Is there a project that can be operated on?
151
+ def project?
152
+ !@project.nil? and @project.name?
153
+ end
154
+
155
+ class << self
156
+
157
+ # Parse cli arguments and init Pratt
158
+ def parse args
159
+ me = Pratt.new
160
+
161
+ # There are aa few things we're parsing here
162
+ # Pratt config arguments (Ideally that should be all we do)
163
+ # Pratt actions. These may require ordering or not. They also may require an argument value.
164
+ #
165
+ # TODO: Redo the cli parsing...
166
+ # In some cases we require arguments to be run in a certain order, but we don't want some to be run concurrently w/ others.
167
+ # Sometimes it may be unexpected but helpful to allow that behavior.
168
+ opt = OptionParser.new do |opt|
169
+ Pratt.connect! ENV['PRATT_ENV'] || 'development' unless Pratt.connected?
170
+
171
+ # Actionable options
172
+ opt.on('-b', "--begin", String, "Begin project tracking.") do
173
+ me << :begin
174
+ end
175
+ opt.on('-r', "--restart", String, "Restart project log (stop last log and start a new one).
176
+ Applies to last un-ended project, unless a specific project is provided.") do
177
+ me << :restart
178
+ end
179
+ opt.on('-e', "--end", String, "Stop tracking interval for last project or supplied project if provided.") do
180
+ me << :end
181
+ end
182
+ opt.on('-c', "--change", String, "Change last time interval to this project.") do
183
+ me << :change
184
+ end
185
+ opt.on('-g', "--graph", String, "Display time spent on supplied project or all projects without argument value.") do
186
+ me << :graph
187
+ end
188
+ opt.on('-I', "--invoice", "Create an invoice.") do
189
+ me << :invoice
190
+ end
191
+ opt.on('-r', '--proportions', "") do
192
+ me << :proportions
193
+ end
194
+ opt.on('-p', '--pid', "Process id display. (Is it still running)") do
195
+ me << :pid
196
+ end
197
+ opt.on('-R', '--raw [CONDITIONS]', "Dump logs (semi-)raw") do |conditions|
198
+ me << :raw
199
+ me.raw_conditions = conditions
200
+ end
201
+ opt.on('-C', "--current", "Show available projects and current project (if there is one)") do
202
+ me << :current
203
+ end
204
+ opt.on("-d", "--daemonize", "Start daemon.") do
205
+ me << :daemonize
206
+ end
207
+ opt.on('-D', '--detect', 'Detect appropriate behavior. (Daemonize or Graphical).') do
208
+ me << :detect
209
+ end
210
+ opt.on('-G', '--gui', 'Show "smart" gui.') do
211
+ me << :gui
212
+ end
213
+ opt.on('-q', "--quit", "Stop daemon.") do
214
+ me << :quit
215
+ end
216
+ opt.on('-U', '--unlock', "Manually unlock a gui that has died but left it's lock around.") do
217
+ me << :unlock
218
+ end
219
+ opt.on '-V', '--version' do
220
+ puts "Pro-Reactive Time Tracker [Pratt] (#{VERSION})"
221
+ end
222
+ opt.on('--destroy', String, "Remove a project.") do
223
+ me << :destroy
224
+ end
225
+
226
+ # Strictly configuration options
227
+ project_names = Project.all.collect(&:name)
228
+ colored_project_names = project_names.collect{|name|
229
+ " #{name.cyan}"}
230
+ opt.on('-P', "--project PROJECT_NAME", project_names, "Set project.
231
+ Available projects are:\n#{colored_project_names*"\n"}") do |proj|
232
+ me.project = proj
233
+ end
234
+
235
+ templates = []
236
+ Pratt.root("views", "*.eruby") {|view| templates << File.basename(view, '.eruby') }
237
+ opt.on('-t', "--template TEMPLATE", templates, "Template to use for displaying work done.
238
+ Available templates are #{templates.to_sentence('or')}.") do |template|
239
+ me.template = template
240
+ end
241
+ opt.on '-w', '--when_to TIME', String, 'When to do something.
242
+ (e.g. log time start|stop, or what time interval to graph)
243
+ If graphing, silently ignored w/out scale argument.' do |when_to|
244
+ me.when_to = Chronic.parse(when_to).to_datetime
245
+ end
246
+ scales = %w(day week month quarter year)
247
+ opt.on('-l', '--scale SCALE', scales, "Granularity of time argument
248
+ Available scales are #{scales.to_sentence('or')}.
249
+ Only applies to graphing.") do |scale|
250
+ me.scale = scale
251
+ end
252
+ opt.on('-L', '--log', "Redirect errors") do
253
+ FileUtils.mkdir 'log' unless File.exists? 'log'
254
+ $stderr.reopen('log/pratt.log', 'a')
255
+ $stderr.sync = true
256
+ end
257
+ opt.on('-N', '--no-color', "Display output without color or special characters.") do
258
+ Pratt.color = false
259
+ end
260
+ opt.on('-A', '--show-all', "Display all project regardless of other options.") do
261
+ me.show_all = true
262
+ end
263
+ opt.on '-s', '--start-day WEEK_DAY_START', String, "" do |wday_start|
264
+ me.week_day_start = wday_start
265
+ end
266
+ opt.on('-i', "--interval INTERVAL", Float, "Set the remind interval/min (Only applies to daemonized process).") do |interval|
267
+ me.app.interval = interval
268
+ me.app.save
269
+ end
270
+
271
+ opt.parse!
272
+ end
273
+
274
+ me << :console if args.include? 'console'
275
+
276
+ me.run
277
+ end
278
+
279
+ # Where is Pratt installed.
280
+ # We've already chdir'd to it's base dir in the bin file
281
+ def root *globs, &block
282
+ root = Dir.pwd
283
+ if globs.empty?
284
+ subdir = root
285
+ else
286
+ subdir = File.join(root, *globs)
287
+ end
288
+
289
+ if block_given?
290
+ Pathname.glob(subdir) {|dir_files| yield dir_files }
291
+ else
292
+ Pathname.glob(subdir)
293
+ end
294
+ end
295
+
296
+ # Migrate schema.
297
+ def migrate
298
+ Pratt.root( 'models', '*.rb' ) do |model_file|
299
+ klass = File.basename( model_file, '.rb' ).classify.constantize
300
+ begin
301
+ ActiveRecord::Base.connection.table_structure(model_file)
302
+ rescue ActiveRecord::StatementInvalid
303
+ klass.migrate :up if klass.superclass == ActiveRecord::Base
304
+ end
305
+ end
306
+ end
307
+ end
308
+ end