tt 0.0.1

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 (6) hide show
  1. data/README +21 -0
  2. data/Rakefile +390 -0
  3. data/bin/tt +226 -0
  4. data/lib/tt.rb +158 -0
  5. data/tt.gemspec +34 -0
  6. metadata +83 -0
data/README ADDED
@@ -0,0 +1,21 @@
1
+ Treetop Parsing Expression Grammar (PEG) Comand Line Compiler
2
+ Usage: tt [options] grammar_file[.treetop|.tt] ...
3
+
4
+ Examples:
5
+ tt foo.tt # 1 grammar -> 1 parser source
6
+ tt foo bar.treetop # 2 grammars -> 2 separate parsers
7
+ tt -o alt_name.rb foo # alternately named output file
8
+
9
+
10
+ NOTE: while treetop grammar files *must* have one of the following
11
+ filename extensions, the extension name is not required when calling
12
+ the compiler with grammar file names.
13
+
14
+ Valid extensions: .treetop, .tt
15
+
16
+
17
+ Options:
18
+ -o, --output FILENAME Write parser source to FILENAME
19
+ -f, --force Overwrite existing output file(s)
20
+ -v, --version Show Treetop version
21
+ -h, --help Show this help message
@@ -0,0 +1,390 @@
1
+ This.rubyforge_project = 'codeforpeople'
2
+ This.author = "Ara T. Howard"
3
+ This.email = "ara.t.howard@gmail.com"
4
+ This.homepage = "https://github.com/ahoward/#{ This.lib }"
5
+
6
+
7
+ task :default do
8
+ puts((Rake::Task.tasks.map{|task| task.name.gsub(/::/,':')} - ['default']).sort)
9
+ end
10
+
11
+ task :test do
12
+ run_tests!
13
+ end
14
+
15
+ namespace :test do
16
+ task(:unit){ run_tests!(:unit) }
17
+ task(:functional){ run_tests!(:functional) }
18
+ task(:integration){ run_tests!(:integration) }
19
+ end
20
+
21
+ def run_tests!(which = nil)
22
+ which ||= '**'
23
+ test_dir = File.join(This.dir, "test")
24
+ test_glob ||= File.join(test_dir, "#{ which }/**_test.rb")
25
+ test_rbs = Dir.glob(test_glob).sort
26
+
27
+ div = ('=' * 119)
28
+ line = ('-' * 119)
29
+
30
+ test_rbs.each_with_index do |test_rb, index|
31
+ testno = index + 1
32
+ command = "#{ File.basename(This.ruby) } -I ./lib -I ./test/lib #{ test_rb }"
33
+
34
+ puts
35
+ say(div, :color => :cyan, :bold => true)
36
+ say("@#{ testno } => ", :bold => true, :method => :print)
37
+ say(command, :color => :cyan, :bold => true)
38
+ say(line, :color => :cyan, :bold => true)
39
+
40
+ system(command)
41
+
42
+ say(line, :color => :cyan, :bold => true)
43
+
44
+ status = $?.exitstatus
45
+
46
+ if status.zero?
47
+ say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
48
+ say("SUCCESS", :color => :green, :bold => true)
49
+ else
50
+ say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
51
+ say("FAILURE", :color => :red, :bold => true)
52
+ end
53
+ say(line, :color => :cyan, :bold => true)
54
+
55
+ exit(status) unless status.zero?
56
+ end
57
+ end
58
+
59
+
60
+ task :gemspec do
61
+ ignore_extensions = ['git', 'svn', 'tmp', /sw./, 'bak', 'gem']
62
+ ignore_directories = ['pkg']
63
+ ignore_files = ['test/log', 'a.rb'] + Dir['db/*'] + %w'db'
64
+
65
+ shiteless =
66
+ lambda do |list|
67
+ list.delete_if do |entry|
68
+ next unless test(?e, entry)
69
+ extension = File.basename(entry).split(%r/[.]/).last
70
+ ignore_extensions.any?{|ext| ext === extension}
71
+ end
72
+ list.delete_if do |entry|
73
+ next unless test(?d, entry)
74
+ dirname = File.expand_path(entry)
75
+ ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
76
+ end
77
+ list.delete_if do |entry|
78
+ next unless test(?f, entry)
79
+ filename = File.expand_path(entry)
80
+ ignore_files.any?{|file| File.expand_path(file) == filename}
81
+ end
82
+ end
83
+
84
+ lib = This.lib
85
+ object = This.object
86
+ version = This.version
87
+ files = shiteless[Dir::glob("**/**")]
88
+ executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
89
+ #has_rdoc = true #File.exist?('doc')
90
+ test_files = test(?e, "test/#{ lib }.rb") ? "test/#{ lib }.rb" : nil
91
+ summary = object.respond_to?(:summary) ? object.summary : "summary: #{ lib } kicks the ass"
92
+ description = object.respond_to?(:description) ? object.description : "description: #{ lib } kicks the ass"
93
+
94
+ if This.extensions.nil?
95
+ This.extensions = []
96
+ extensions = This.extensions
97
+ %w( Makefile configure extconf.rb ).each do |ext|
98
+ extensions << ext if File.exists?(ext)
99
+ end
100
+ end
101
+ extensions = [extensions].flatten.compact
102
+
103
+ # TODO
104
+ if This.dependencies.nil?
105
+ dependencies = []
106
+ else
107
+ case This.dependencies
108
+ when Hash
109
+ dependencies = This.dependencies.values
110
+ when Array
111
+ dependencies = This.dependencies
112
+ end
113
+ end
114
+
115
+ template =
116
+ if test(?e, 'gemspec.erb')
117
+ Template{ IO.read('gemspec.erb') }
118
+ else
119
+ Template {
120
+ <<-__
121
+ ## <%= lib %>.gemspec
122
+ #
123
+
124
+ Gem::Specification::new do |spec|
125
+ spec.name = <%= lib.inspect %>
126
+ spec.version = <%= version.inspect %>
127
+ spec.platform = Gem::Platform::RUBY
128
+ spec.summary = <%= lib.inspect %>
129
+ spec.description = <%= description.inspect %>
130
+
131
+ spec.files =\n<%= files.sort.pretty_inspect %>
132
+ spec.executables = <%= executables.inspect %>
133
+
134
+ spec.require_path = "lib"
135
+
136
+ spec.test_files = <%= test_files.inspect %>
137
+
138
+ <% dependencies.each do |lib_version| %>
139
+ spec.add_dependency(*<%= Array(lib_version).flatten.inspect %>)
140
+ <% end %>
141
+
142
+ spec.extensions.push(*<%= extensions.inspect %>)
143
+
144
+ spec.rubyforge_project = <%= This.rubyforge_project.inspect %>
145
+ spec.author = <%= This.author.inspect %>
146
+ spec.email = <%= This.email.inspect %>
147
+ spec.homepage = <%= This.homepage.inspect %>
148
+ end
149
+ __
150
+ }
151
+ end
152
+
153
+ Fu.mkdir_p(This.pkgdir)
154
+ gemspec = "#{ lib }.gemspec"
155
+ open(gemspec, "w"){|fd| fd.puts(template)}
156
+ This.gemspec = gemspec
157
+ end
158
+
159
+ task :gem => [:clean, :gemspec] do
160
+ Fu.mkdir_p(This.pkgdir)
161
+ before = Dir['*.gem']
162
+ cmd = "gem build #{ This.gemspec }"
163
+ `#{ cmd }`
164
+ after = Dir['*.gem']
165
+ gem = ((after - before).first || after.first) or abort('no gem!')
166
+ Fu.mv(gem, This.pkgdir)
167
+ This.gem = File.join(This.pkgdir, File.basename(gem))
168
+ end
169
+
170
+ task :readme do
171
+ samples = ''
172
+ prompt = '~ > '
173
+ lib = This.lib
174
+ version = This.version
175
+
176
+ Dir['sample*/*'].sort.each do |sample|
177
+ samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
178
+
179
+ cmd = "cat #{ sample }"
180
+ samples << Util.indent(prompt + cmd, 2) << "\n\n"
181
+ samples << Util.indent(`#{ cmd }`, 4) << "\n"
182
+
183
+ cmd = "ruby #{ sample }"
184
+ samples << Util.indent(prompt + cmd, 2) << "\n\n"
185
+
186
+ cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -I ./lib #{ sample })'"
187
+ samples << Util.indent(`#{ cmd } 2>&1`, 4) << "\n"
188
+ end
189
+
190
+ template =
191
+ if test(?e, 'readme.erb')
192
+ Template{ IO.read('readme.erb') }
193
+ else
194
+ Template {
195
+ <<-__
196
+ NAME
197
+ #{ lib }
198
+
199
+ DESCRIPTION
200
+
201
+ INSTALL
202
+ gem install #{ lib }
203
+
204
+ SAMPLES
205
+ #{ samples }
206
+ __
207
+ }
208
+ end
209
+
210
+ open("README", "w"){|fd| fd.puts template}
211
+ end
212
+
213
+
214
+ task :clean do
215
+ Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)}
216
+ end
217
+
218
+
219
+ task :release => [:clean, :gemspec, :gem] do
220
+ gems = Dir[File.join(This.pkgdir, '*.gem')].flatten
221
+ raise "which one? : #{ gems.inspect }" if gems.size > 1
222
+ raise "no gems?" if gems.size < 1
223
+
224
+ cmd = "gem push #{ This.gem }"
225
+ puts cmd
226
+ puts
227
+ system(cmd)
228
+ abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
229
+
230
+ cmd = "rubyforge login && rubyforge add_release #{ This.rubyforge_project } #{ This.lib } #{ This.version } #{ This.gem }"
231
+ puts cmd
232
+ puts
233
+ system(cmd)
234
+ abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
235
+ end
236
+
237
+
238
+
239
+
240
+
241
+ BEGIN {
242
+ # support for this rakefile
243
+ #
244
+ $VERBOSE = nil
245
+
246
+ require 'ostruct'
247
+ require 'erb'
248
+ require 'fileutils'
249
+ require 'rbconfig'
250
+ require 'pp'
251
+
252
+ # fu shortcut
253
+ #
254
+ Fu = FileUtils
255
+
256
+ # cache a bunch of stuff about this rakefile/environment
257
+ #
258
+ This = OpenStruct.new
259
+
260
+ This.file = File.expand_path(__FILE__)
261
+ This.dir = File.dirname(This.file)
262
+ This.pkgdir = File.join(This.dir, 'pkg')
263
+
264
+ # grok lib
265
+ #
266
+ lib = ENV['LIB']
267
+ unless lib
268
+ lib = File.basename(Dir.pwd).sub(/[-].*$/, '')
269
+ end
270
+ This.lib = lib
271
+
272
+ # grok version
273
+ #
274
+ version = ENV['VERSION']
275
+ unless version
276
+ require "./lib/#{ This.lib }"
277
+ This.name = lib.capitalize
278
+ This.object = eval(This.name)
279
+ version = This.object.send(:version)
280
+ end
281
+ This.version = version
282
+
283
+ # see if dependencies are export by the module
284
+ #
285
+ if This.object.respond_to?(:dependencies)
286
+ This.dependencies = This.object.dependencies
287
+ end
288
+
289
+ # we need to know the name of the lib an it's version
290
+ #
291
+ abort('no lib') unless This.lib
292
+ abort('no version') unless This.version
293
+
294
+ # discover full path to this ruby executable
295
+ #
296
+ c = RbConfig::CONFIG
297
+ bindir = c["bindir"] || c['BINDIR']
298
+ ruby_install_name = c['ruby_install_name'] || c['RUBY_INSTALL_NAME'] || 'ruby'
299
+ ruby_ext = c['EXEEXT'] || ''
300
+ ruby = File.join(bindir, (ruby_install_name + ruby_ext))
301
+ This.ruby = ruby
302
+
303
+ # some utils
304
+ #
305
+ module Util
306
+ def indent(s, n = 2)
307
+ s = unindent(s)
308
+ ws = ' ' * n
309
+ s.gsub(%r/^/, ws)
310
+ end
311
+
312
+ def unindent(s)
313
+ indent = nil
314
+ s.each_line do |line|
315
+ next if line =~ %r/^\s*$/
316
+ indent = line[%r/^\s*/] and break
317
+ end
318
+ indent ? s.gsub(%r/^#{ indent }/, "") : s
319
+ end
320
+ extend self
321
+ end
322
+
323
+ # template support
324
+ #
325
+ class Template
326
+ def initialize(&block)
327
+ @block = block
328
+ @template = block.call.to_s
329
+ end
330
+ def expand(b=nil)
331
+ ERB.new(Util.unindent(@template)).result((b||@block).binding)
332
+ end
333
+ alias_method 'to_s', 'expand'
334
+ end
335
+ def Template(*args, &block) Template.new(*args, &block) end
336
+
337
+ # colored console output support
338
+ #
339
+ This.ansi = {
340
+ :clear => "\e[0m",
341
+ :reset => "\e[0m",
342
+ :erase_line => "\e[K",
343
+ :erase_char => "\e[P",
344
+ :bold => "\e[1m",
345
+ :dark => "\e[2m",
346
+ :underline => "\e[4m",
347
+ :underscore => "\e[4m",
348
+ :blink => "\e[5m",
349
+ :reverse => "\e[7m",
350
+ :concealed => "\e[8m",
351
+ :black => "\e[30m",
352
+ :red => "\e[31m",
353
+ :green => "\e[32m",
354
+ :yellow => "\e[33m",
355
+ :blue => "\e[34m",
356
+ :magenta => "\e[35m",
357
+ :cyan => "\e[36m",
358
+ :white => "\e[37m",
359
+ :on_black => "\e[40m",
360
+ :on_red => "\e[41m",
361
+ :on_green => "\e[42m",
362
+ :on_yellow => "\e[43m",
363
+ :on_blue => "\e[44m",
364
+ :on_magenta => "\e[45m",
365
+ :on_cyan => "\e[46m",
366
+ :on_white => "\e[47m"
367
+ }
368
+ def say(phrase, *args)
369
+ options = args.last.is_a?(Hash) ? args.pop : {}
370
+ options[:color] = args.shift.to_s.to_sym unless args.empty?
371
+ keys = options.keys
372
+ keys.each{|key| options[key.to_s.to_sym] = options.delete(key)}
373
+
374
+ color = options[:color]
375
+ bold = options.has_key?(:bold)
376
+
377
+ parts = [phrase]
378
+ parts.unshift(This.ansi[color]) if color
379
+ parts.unshift(This.ansi[:bold]) if bold
380
+ parts.push(This.ansi[:clear]) if parts.size > 1
381
+
382
+ method = options[:method] || :puts
383
+
384
+ Kernel.send(method, parts.join)
385
+ end
386
+
387
+ # always run out of the project dir
388
+ #
389
+ Dir.chdir(This.dir)
390
+ }
data/bin/tt ADDED
@@ -0,0 +1,226 @@
1
+ #! /usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+
5
+ Main {
6
+ name <<-__
7
+
8
+ tt
9
+
10
+ __
11
+
12
+ synopsis <<-__
13
+
14
+ tt 2.5 @dojo4 doing something important
15
+
16
+ __
17
+
18
+ description <<-__
19
+
20
+ tt is a svelt time tracker for ruby
21
+
22
+ __
23
+
24
+ examples <<-__
25
+
26
+ . tt 4.5 dojo4 doing something important
27
+
28
+ . tt list project -a 2008-05-01 -b 2008-05-07
29
+
30
+ . tt total project -a 2008-05-01 -b 2008-05-07
31
+
32
+ . tt 4.2 project -- adding --dash feature to project
33
+
34
+ __
35
+
36
+ option('when', 'w'){
37
+ argument :required
38
+ desc 'iso8601 date work was performed'
39
+ cast{|value| Date.from(value)}
40
+ default Date.today
41
+ }
42
+
43
+ option('after', 'a'){
44
+ argument :required
45
+ desc 'limit data shown to entries *after* this iso8601 date'
46
+ default Time::Beginning.to_date
47
+ cast{|value| Date.from(value)}
48
+ }
49
+
50
+ option('before', 'b'){
51
+ argument :required
52
+ desc 'limit data shown to entries *before* this iso8601 date'
53
+ default Time::End.to_date
54
+ cast{|value| Date.from(value)}
55
+ }
56
+
57
+ option('noop', 'n'){
58
+ desc 'perform all operations on a tmp database'
59
+ cast{|value| $noop = value}
60
+ }
61
+
62
+ def run
63
+ mode = argv.shift if argv.first and respond_to?(argv.first)
64
+ if mode.nil?
65
+ if argv.empty?
66
+ mode = :list
67
+ else
68
+ mode = :hours
69
+ end
70
+ end
71
+ send(mode)
72
+ end
73
+
74
+ def hours options = {}
75
+ hours = argv.shift or abort("no hours")
76
+ project = argv.shift or abort("no project")
77
+ message = argv.join(' ')
78
+
79
+ hours = Float hours
80
+ project = String project
81
+ message = message.empty? ? edit_message! : message
82
+
83
+ abort('no message!') if message.empty?
84
+
85
+ record = new_record({
86
+ :when => params['when'].value,
87
+ :what => message,
88
+ :time => hours
89
+ })
90
+
91
+ db.transaction do
92
+ db[project] ||= []
93
+ db[project] << record
94
+ end
95
+
96
+ result = { project => record }
97
+
98
+ y result unless options[:display]==false
99
+ result
100
+ end
101
+
102
+ def edit_message!
103
+ require 'tmpdir'
104
+ require 'fileutils'
105
+ tmp = File.join(Dir.tmpdir, "tt-#{ Process.ppid }-#{ Process.pid }.#{ rand }.txt")
106
+ at_exit{ FileUtils.rm_f(tmp) }
107
+ editor = ENV['EDITOR'] || 'vim'
108
+ system("touch #{ tmp.inspect } && #{ editor.inspect } #{ tmp.inspect }")
109
+ msg = IO.read(tmp).strip
110
+ abort('no msg!') if msg.empty?
111
+ msg
112
+ end
113
+
114
+ def list options = {}
115
+ project = argv.shift
116
+ total = 0 if options['total'] || options[:total]
117
+ after = param['after'].value
118
+ before = param['before'].value
119
+
120
+ result = Hash.new
121
+
122
+ db.transaction do
123
+ projects = project ? [project] : db.roots
124
+ projects.each do |project|
125
+ list = db[project]
126
+ next unless list
127
+ result[project] = []
128
+ list.each do |element|
129
+ record = new_record element
130
+ if record['when'] >= after and record['when'] < before
131
+ result[project] << record
132
+ total += Float(record['time']) if total
133
+ end
134
+ end
135
+ end
136
+ result['total'] = total if total
137
+ end
138
+
139
+ y result unless options[:display]==false
140
+ result
141
+ end
142
+
143
+ def total
144
+ list :total => true
145
+ end
146
+
147
+ def status
148
+ if params[:when].given? and !params[:after].given? and !params[:before].given?
149
+ params[:after].values.replace([params[:when].value - 1])
150
+ params[:before].values.replace([params[:when].value + 1])
151
+ elsif !params[:after].given?
152
+ params[:after].values.replace(Array(Date.from('last sunday')))
153
+ end
154
+
155
+ result = list(:display => false)
156
+
157
+ dates = Hash.new
158
+
159
+ result.each do |project, entries|
160
+ entries.each do |entry|
161
+ synopsis = <<-__
162
+ @#{ project } #{ entry['time'] }
163
+ #{ entry['what'] }
164
+ __
165
+ synopsis.gsub!(/^[\s]{10}/, '')
166
+ synopsis.gsub!(/[\s]$/, '')
167
+ dates[entry['when']] ||= []
168
+ dates[entry['when']].push(synopsis)
169
+ end
170
+ end
171
+
172
+ dates.each do |date, list|
173
+ puts date
174
+ list.each do |synopsis|
175
+ puts(synopsis)
176
+ puts
177
+ end
178
+ end
179
+ end
180
+
181
+ def db
182
+ @db ||= (
183
+ if $noop
184
+ require 'fileutils'
185
+ require 'tempfile'
186
+ tmp = Tempfile.new Process.pid.to_s
187
+ File.open(File.join(TT.home, '.tt.yml')){|fd| tmp.write fd.read}
188
+ tmp.close
189
+ @db = YAML::Store.new(tmp.path)
190
+ else
191
+ @db = YAML::Store.new(File.join(TT.home, '.tt.yml'))
192
+ end
193
+ )
194
+ end
195
+
196
+ def new_record *args
197
+ pairs = []
198
+ args.map do |arg|
199
+ case arg
200
+ when Hash, Array
201
+ arg.to_a
202
+ else
203
+ arg
204
+ end
205
+ end.flatten.each_slice(2) do |first, last|
206
+ pairs << first.to_s << last
207
+ end
208
+ Hash[ *pairs ]
209
+ end
210
+ }
211
+
212
+
213
+ BEGIN {
214
+ require 'pathname'
215
+ this = Pathname.new(__FILE__).realpath.to_s
216
+ bindir = File.dirname(this)
217
+ rootdir = File.dirname(bindir)
218
+ libdir = File.join(rootdir, 'lib')
219
+ tt = File.join(libdir, 'tt.rb')
220
+
221
+ require(tt)
222
+
223
+ STDOUT.sync = true
224
+ STDERR.sync = true
225
+ STDIN.sync = true
226
+ }
@@ -0,0 +1,158 @@
1
+ require 'yaml'
2
+ require 'yaml/store'
3
+ require 'time'
4
+ require 'date'
5
+ require 'pathname'
6
+ require 'tempfile'
7
+ require 'fileutils'
8
+ require 'enumerator'
9
+
10
+ module TT
11
+ Version = '0.0.1' unless defined?(Version)
12
+
13
+ def version
14
+ TT::Version
15
+ end
16
+
17
+ def dependencies
18
+ {
19
+ 'main' => [ 'main' , ' >= 4.8.1' ] ,
20
+ 'map' => [ 'map' , ' >= 5.1.0' ] ,
21
+ 'chronic' => [ 'chronic' , ' >= 0.6.6' ]
22
+ }
23
+ end
24
+
25
+ def libdir(*args, &block)
26
+ @libdir ||= File.expand_path(__FILE__).sub(/\.rb$/,'')
27
+ args.empty? ? @libdir : File.join(@libdir, *args)
28
+ ensure
29
+ if block
30
+ begin
31
+ $LOAD_PATH.unshift(@libdir)
32
+ block.call()
33
+ ensure
34
+ $LOAD_PATH.shift()
35
+ end
36
+ end
37
+ end
38
+
39
+ def load(*libs)
40
+ libs = libs.join(' ').scan(/[^\s+]+/)
41
+ TT.libdir{ libs.each{|lib| Kernel.load(lib) } }
42
+ end
43
+
44
+ extend(TT)
45
+ end
46
+
47
+ # gems
48
+ #
49
+ begin
50
+ require 'rubygems'
51
+ rescue LoadError
52
+ nil
53
+ end
54
+
55
+ if defined?(gem)
56
+ TT.dependencies.each do |lib, dependency|
57
+ gem(*dependency)
58
+ require(lib)
59
+ end
60
+ end
61
+
62
+ def TT.home
63
+ home =
64
+ catch :home do
65
+ ["HOME", "USERPROFILE"].each do |key|
66
+ throw(:home, ENV[key]) if ENV[key]
67
+ end
68
+ if ENV["HOMEDRIVE"] and ENV["HOMEPATH"]
69
+ throw(:home, "#{ ENV['HOMEDRIVE'] }:#{ ENV['HOMEPATH'] }")
70
+ end
71
+ File.expand_path("~") rescue(File::ALT_SEPARATOR ? "C:/" : "/")
72
+ end
73
+ File.expand_path(home)
74
+ end
75
+
76
+ class Date
77
+ def self.from value
78
+ ( Time.parse(value.to_s) || Date.parse(value.to_s) ).to_date
79
+ end
80
+
81
+ def to_date
82
+ self
83
+ end
84
+ end
85
+
86
+
87
+ class Time
88
+ Beginning = Time.at(0)
89
+
90
+ End = Time.at((2**31)-1)
91
+
92
+ Now = Time.now
93
+
94
+ Null = Time.at(0).instance_eval do
95
+ def to_s() "" end
96
+ def inspect() "" end
97
+ self
98
+ end
99
+
100
+ def to_s(n=0) iso8601(n) end
101
+ alias_method 'inspect', 'to_s'
102
+
103
+ ### hack to fix Time.parse bug
104
+ Parse = Time.method 'parse'
105
+ def self.parse string
106
+ if string =~ %r'^\d\d\d\d-\d\d-\d\dT\d\d:?$'
107
+ string = string.sub(%r/:$/,'') + ':00'
108
+ end
109
+ if string =~ %r/\ban\b/
110
+ string = string.sub(%r/\ban\b/, '1')
111
+ end
112
+ if string =~ %r'^\d\d\d\d-\d\d-\d\d'
113
+ Parse.call string
114
+ else
115
+ Chronic.parse string, :context => :past
116
+ end
117
+ end
118
+
119
+ def to_date
120
+ Date.new year, month, day
121
+ end
122
+
123
+ def to_yaml( opts = {} )
124
+ YAML::quick_emit( object_id, opts ) do |out|
125
+ tz = "Z"
126
+ # from the tidy Tobias Peters <t-peters@gmx.de> Thanks!
127
+ unless self.utc?
128
+ utc_same_instant = self.dup.utc
129
+ utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec)
130
+ difference_to_utc = utc_same_writing - utc_same_instant
131
+ if (difference_to_utc < 0)
132
+ difference_sign = '-'
133
+ absolute_difference = -difference_to_utc
134
+ else
135
+ difference_sign = '+'
136
+ absolute_difference = difference_to_utc
137
+ end
138
+ difference_minutes = (absolute_difference/60).round
139
+ tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60]
140
+ end
141
+ standard = self.strftime( "%Y-%m-%dT%H:%M:%S" )
142
+ standard += ".%02d" % [usec] #if usec.nonzero?
143
+ standard += "%s" % [tz]
144
+ if to_yaml_properties.empty?
145
+ out.scalar( taguri, standard, :plain )
146
+ else
147
+ out.map( taguri, to_yaml_style ) do |map|
148
+ map.add( 'at', standard )
149
+ to_yaml_properties.each do |m|
150
+ map.add( m, instance_variable_get( m ) )
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+
158
+ Tt=TT
@@ -0,0 +1,34 @@
1
+ ## tt.gemspec
2
+ #
3
+
4
+ Gem::Specification::new do |spec|
5
+ spec.name = "tt"
6
+ spec.version = "0.0.1"
7
+ spec.platform = Gem::Platform::RUBY
8
+ spec.summary = "tt"
9
+ spec.description = "description: tt kicks the ass"
10
+
11
+ spec.files =
12
+ ["README", "Rakefile", "bin", "bin/tt", "lib", "lib/tt.rb", "tt.gemspec"]
13
+
14
+ spec.executables = ["tt"]
15
+
16
+ spec.require_path = "lib"
17
+
18
+ spec.test_files = nil
19
+
20
+
21
+ spec.add_dependency(*["main", " >= 4.8.1"])
22
+
23
+ spec.add_dependency(*["map", " >= 5.1.0"])
24
+
25
+ spec.add_dependency(*["chronic", " >= 0.6.6"])
26
+
27
+
28
+ spec.extensions.push(*[])
29
+
30
+ spec.rubyforge_project = "codeforpeople"
31
+ spec.author = "Ara T. Howard"
32
+ spec.email = "ara.t.howard@gmail.com"
33
+ spec.homepage = "https://github.com/ahoward/tt"
34
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ara T. Howard
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-31 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: main
16
+ requirement: &70240801841660 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 4.8.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70240801841660
25
+ - !ruby/object:Gem::Dependency
26
+ name: map
27
+ requirement: &70240801840820 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 5.1.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70240801840820
36
+ - !ruby/object:Gem::Dependency
37
+ name: chronic
38
+ requirement: &70240801839940 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 0.6.6
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70240801839940
47
+ description: ! 'description: tt kicks the ass'
48
+ email: ara.t.howard@gmail.com
49
+ executables:
50
+ - tt
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - README
55
+ - Rakefile
56
+ - bin/tt
57
+ - lib/tt.rb
58
+ - tt.gemspec
59
+ homepage: https://github.com/ahoward/tt
60
+ licenses: []
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project: codeforpeople
79
+ rubygems_version: 1.8.11
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: tt
83
+ test_files: []