timetrack 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 64c133eec77f7c3e384c12cc90080d5e243ac594
4
- data.tar.gz: 63777024840ac286d9d950ea07ea0b32cba5fa6e
3
+ metadata.gz: 686619e77bc75eb5e02f6ffcd1658e1b998f69b4
4
+ data.tar.gz: 6ba068152488dbfdd4e6d4730f099486cb459817
5
5
  SHA512:
6
- metadata.gz: a8645748bc558b0797f44f5cd605b0e14995cea6472f7d9b0d2740615e163e3c25c130ab15105f3a28436b1492ca78c1fb52a56da0af626153d026fe7ae5e8f9
7
- data.tar.gz: 90e7108e71bc82b678f6ca2db4741e38318a398cf9f086fb1db80539ccee13ad6944080d5400df9934260bad745f3766daf2f5677833c7470615c53877436798
6
+ metadata.gz: 6468aaec89019f984564e41eaf989aea69173dd8995fad85f9374096a80bf9795fdb798ef827482bfaee71fd68e5e013f7ab35c89ab759b3414a5b3143ca7f51
7
+ data.tar.gz: afef472a142141568ec7d2a20c2ea5a1a08e66f4535b534cce1b67f7907ddc4e5d82288bee6ae2dd74076ed809dd22c80f460b0bf4fdfa5e6aa84a7886b22482
data/.rspec CHANGED
@@ -1,2 +1,6 @@
1
- --format documentation
2
1
  --color
2
+ --format progress
3
+ --profile
4
+ --warnings
5
+ --order random
6
+ --require spec_helper
data/Gemfile CHANGED
@@ -3,3 +3,5 @@ source 'https://rubygems.org'
3
3
 
4
4
  # Specify your gem's dependencies in timetrack.gemspec
5
5
  gemspec
6
+
7
+ gem 'parslet', git: 'https://github.com/jreut/parslet', branch: 'master'
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Timetrack
2
2
 
3
+ [![CircleCI](https://circleci.com/gh/jreut/timetrack/tree/master.svg?style=svg)](https://circleci.com/gh/jreut/timetrack/tree/master)
4
+
3
5
  Track time spent on tasks in a [ledger][ledger]-like format.
4
6
 
5
7
  ## Installation
@@ -0,0 +1,7 @@
1
+ ---
2
+ machine:
3
+ ruby:
4
+ version: '2.3.3'
5
+ test:
6
+ override:
7
+ - bundle exec rake ci
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 8
3
- total_score: 44
3
+ total_score: 97
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 19.2
2
+ threshold: 18.0
@@ -1,4 +1,6 @@
1
1
  ---
2
+ require: rubocop-rspec
3
+
2
4
  Metrics/BlockLength:
3
5
  Exclude:
4
6
  # Ignore RSpec DSL
@@ -2,3 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'timetrack'
5
+
6
+ Timetrack::CLI.start ARGV
@@ -1,7 +1,20 @@
1
1
  # frozen_string_literal: true
2
- require 'timetrack/version'
2
+ require 'anima'
3
+ require 'parslet'
4
+ require 'thor'
5
+
6
+ require 'timetrack/cli'
7
+ require 'timetrack/day'
8
+ require 'timetrack/event'
9
+ require 'timetrack/time_formatter'
3
10
  require 'timetrack/parser'
11
+ require 'timetrack/reader'
12
+ require 'timetrack/transform'
13
+ require 'timetrack/version'
14
+ require 'timetrack/writer'
4
15
 
5
- # Entrypoint for gem
16
+ # :nodoc:
17
+ #
18
+ # @api private
6
19
  module Timetrack
7
20
  end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ module Timetrack
3
+ # Command-line interface to this gem
4
+ class CLI < Thor
5
+ end
6
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ module Timetrack
3
+ # Collection of events for a single day
4
+ class Day
5
+ include Anima.new :date, :events
6
+
7
+ def to_s
8
+ "#{date_string}\n#{events.join("\n")}"
9
+ end
10
+
11
+ private
12
+
13
+ def date_string
14
+ format '%04d/%02d/%02d', date.year, date.month, date.day
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ module Timetrack
3
+ # Value object for an event that has its date information
4
+ class Event
5
+ include Anima.new :submitted, :task, :begin, :end, :comment
6
+
7
+ def to_s
8
+ " #{submitted_block}#{task} #{TimeFormatter.format self.begin}" \
9
+ " #{TimeFormatter.format self.end}#{comment_block}"
10
+ end
11
+
12
+ private
13
+
14
+ def submitted_block
15
+ '* ' if submitted
16
+ end
17
+
18
+ def comment_block
19
+ " ; #{comment}" unless comment.to_s.empty?
20
+ end
21
+ end
22
+ end
@@ -1,6 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'parslet'
3
-
4
2
  module Timetrack
5
3
  # Read an IO and parse it into an AST
6
4
  class Parser < Parslet::Parser
@@ -16,7 +14,7 @@ module Timetrack
16
14
  rule(:date) { year >> str('/') >> month >> str('/') >> day }
17
15
  rule(:hour) { match['\d'].repeat 2 }
18
16
  rule(:minute) { match['\d'].repeat 2 }
19
- rule(:time) { hour >> str(':') >> minute }
17
+ rule(:time) { (hour >> str(':') >> minute).as(:time) }
20
18
  rule(:begin_time) { (gutter >> time.as(:begin)) }
21
19
  rule(:end_time) { (gutter >> time.as(:end)).maybe }
22
20
  rule(:times) { begin_time >> end_time }
@@ -29,9 +27,9 @@ module Timetrack
29
27
  gutter >> submission_block >> task >> times >> comment_block >> to_eol
30
28
  end
31
29
  rule(:events) { (event.as(:event) >> newline).repeat }
32
- rule(:event_day) { date >> newline >> events }
30
+ rule(:event_day) { date.as(:date) >> newline >> events.as(:events) }
33
31
  rule(:days) do
34
- (event_day.as(:day) >> newline.repeat).repeat
32
+ (event_day >> newline.repeat).repeat
35
33
  end
36
34
  rule(:document) { days >> newline.repeat >> eof }
37
35
  root :document
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ module Timetrack
3
+ # Assemble a parser, a transform, and an IO-like object together to turn them
4
+ # into an AST.
5
+ class Reader
6
+ include Anima.new :input, :parser, :transform
7
+
8
+ def load
9
+ transform.apply parser.parse input.read
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+ module Timetrack
3
+ # Format a Time as HH:MM
4
+ class TimeFormatter
5
+ def self.format(time)
6
+ Kernel.format '%02d:%02d', time.hour, time.min
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+ module Timetrack
3
+ # Transform a deeply-nested hash into a rich object graph
4
+ class Transform < Parslet::Transform
5
+ def self.parse_time(string)
6
+ hour, minute = string.split(':').map(&:to_i)
7
+ UnassociatedTime.new hour: hour, minute: minute
8
+ end
9
+
10
+ rule(time: simple(:time)) { |bind| parse_time bind[:time] }
11
+ rule(event: subtree(:event)) do
12
+ UnassociatedEvent.new(event).with submitted: !event[:submitted].empty?
13
+ end
14
+ rule(date: simple(:date)) { Date.parse date }
15
+ rule(date: simple(:date), events: sequence(:events)) do
16
+ events.map do |unassociated_event|
17
+ unassociated_event.to_event date
18
+ end
19
+ end
20
+
21
+ # Intermediate event representation before it's been associated with a date
22
+ class UnassociatedEvent
23
+ include Anima.new :submitted, :task, :begin, :end, :comment
24
+
25
+ def to_event(date)
26
+ Event.new(
27
+ with(
28
+ begin: self.begin.to_time(date),
29
+ end: self.end.to_time(date)
30
+ ).to_h
31
+ )
32
+ end
33
+ end
34
+
35
+ # Intermediate time representation before it's been associated with a date
36
+ class UnassociatedTime
37
+ include Anima.new :hour, :minute
38
+
39
+ # This method smells of :reek:FeatureEnvy
40
+ def to_time(date)
41
+ Time.new date.year, date.month, date.day, hour, minute
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Timetrack
3
- VERSION = '0.1.0'
3
+ VERSION = '0.2.0'
4
4
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+ module Timetrack
3
+ # Stringify Events in a format suitable for writing to a file
4
+ class Writer
5
+ attr_reader :events
6
+
7
+ def initialize(events:)
8
+ @events = events
9
+ end
10
+
11
+ def dump
12
+ days.join("\n\n")
13
+ end
14
+
15
+ private
16
+
17
+ def days
18
+ events
19
+ .group_by { |event| event.begin.to_date }
20
+ .map { |date, events| Day.new date: date, events: events }
21
+ end
22
+ end
23
+ end
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  # 'allowed_push_host' to allow pushing to a single host or delete this
19
19
  # section to allow pushing to any host.
20
20
  if spec.respond_to?(:metadata)
21
- spec.metadata['allowed_push_host'] = "https://rubygems.org"
21
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
22
22
  else
23
23
  raise 'RubyGems 2.0 or newer is required to protect against ' \
24
24
  'public gem pushes.'
@@ -31,12 +31,15 @@ Gem::Specification.new do |spec|
31
31
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
32
  spec.require_paths = ['lib']
33
33
 
34
+ spec.add_dependency 'anima', '~> 0.3.0'
34
35
  spec.add_dependency 'parslet', '~> 1.7.1'
36
+ spec.add_dependency 'thor', '~> 0.19.4'
35
37
 
36
38
  spec.add_development_dependency 'bundler', '~> 1.13'
39
+ spec.add_development_dependency 'devtools', '~> 0.1.16'
40
+ spec.add_development_dependency 'pry'
37
41
  spec.add_development_dependency 'rake', '~> 11.0'
38
42
  spec.add_development_dependency 'rspec', '~> 3.0'
39
43
  spec.add_development_dependency 'rspec-snapshot', '~> 0.1.1'
40
- spec.add_development_dependency 'devtools', '~> 0.1.16'
41
- spec.add_development_dependency 'pry'
44
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.10.0'
42
45
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timetrack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Ryan Reuter
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-21 00:00:00.000000000 Z
11
+ date: 2017-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: anima
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: parslet
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -24,6 +38,20 @@ dependencies:
24
38
  - - "~>"
25
39
  - !ruby/object:Gem::Version
26
40
  version: 1.7.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.19.4
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.19.4
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: bundler
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -39,75 +67,89 @@ dependencies:
39
67
  - !ruby/object:Gem::Version
40
68
  version: '1.13'
41
69
  - !ruby/object:Gem::Dependency
42
- name: rake
70
+ name: devtools
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
73
  - - "~>"
46
74
  - !ruby/object:Gem::Version
47
- version: '11.0'
75
+ version: 0.1.16
48
76
  type: :development
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
80
  - - "~>"
53
81
  - !ruby/object:Gem::Version
54
- version: '11.0'
82
+ version: 0.1.16
55
83
  - !ruby/object:Gem::Dependency
56
- name: rspec
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
57
99
  requirement: !ruby/object:Gem::Requirement
58
100
  requirements:
59
101
  - - "~>"
60
102
  - !ruby/object:Gem::Version
61
- version: '3.0'
103
+ version: '11.0'
62
104
  type: :development
63
105
  prerelease: false
64
106
  version_requirements: !ruby/object:Gem::Requirement
65
107
  requirements:
66
108
  - - "~>"
67
109
  - !ruby/object:Gem::Version
68
- version: '3.0'
110
+ version: '11.0'
69
111
  - !ruby/object:Gem::Dependency
70
- name: rspec-snapshot
112
+ name: rspec
71
113
  requirement: !ruby/object:Gem::Requirement
72
114
  requirements:
73
115
  - - "~>"
74
116
  - !ruby/object:Gem::Version
75
- version: 0.1.1
117
+ version: '3.0'
76
118
  type: :development
77
119
  prerelease: false
78
120
  version_requirements: !ruby/object:Gem::Requirement
79
121
  requirements:
80
122
  - - "~>"
81
123
  - !ruby/object:Gem::Version
82
- version: 0.1.1
124
+ version: '3.0'
83
125
  - !ruby/object:Gem::Dependency
84
- name: devtools
126
+ name: rspec-snapshot
85
127
  requirement: !ruby/object:Gem::Requirement
86
128
  requirements:
87
129
  - - "~>"
88
130
  - !ruby/object:Gem::Version
89
- version: 0.1.16
131
+ version: 0.1.1
90
132
  type: :development
91
133
  prerelease: false
92
134
  version_requirements: !ruby/object:Gem::Requirement
93
135
  requirements:
94
136
  - - "~>"
95
137
  - !ruby/object:Gem::Version
96
- version: 0.1.16
138
+ version: 0.1.1
97
139
  - !ruby/object:Gem::Dependency
98
- name: pry
140
+ name: rubocop-rspec
99
141
  requirement: !ruby/object:Gem::Requirement
100
142
  requirements:
101
- - - ">="
143
+ - - "~>"
102
144
  - !ruby/object:Gem::Version
103
- version: '0'
145
+ version: 1.10.0
104
146
  type: :development
105
147
  prerelease: false
106
148
  version_requirements: !ruby/object:Gem::Requirement
107
149
  requirements:
108
- - - ">="
150
+ - - "~>"
109
151
  - !ruby/object:Gem::Version
110
- version: '0'
152
+ version: 1.10.0
111
153
  description:
112
154
  email:
113
155
  - me+timetrack@jreut.com
@@ -120,7 +162,6 @@ files:
120
162
  - ".rspec"
121
163
  - ".rubocop.yml"
122
164
  - ".ruby-version"
123
- - ".travis.yml"
124
165
  - CODE_OF_CONDUCT.md
125
166
  - Gemfile
126
167
  - LICENSE.txt
@@ -128,6 +169,7 @@ files:
128
169
  - Rakefile
129
170
  - bin/console
130
171
  - bin/setup
172
+ - circle.yml
131
173
  - config/flay.yml
132
174
  - config/flog.yml
133
175
  - config/mutant.yml
@@ -136,8 +178,15 @@ files:
136
178
  - config/yardstick.yml
137
179
  - exe/timetrack
138
180
  - lib/timetrack.rb
181
+ - lib/timetrack/cli.rb
182
+ - lib/timetrack/day.rb
183
+ - lib/timetrack/event.rb
139
184
  - lib/timetrack/parser.rb
185
+ - lib/timetrack/reader.rb
186
+ - lib/timetrack/time_formatter.rb
187
+ - lib/timetrack/transform.rb
140
188
  - lib/timetrack/version.rb
189
+ - lib/timetrack/writer.rb
141
190
  - timetrack.gemspec
142
191
  homepage: https://www.github.com/jreut/timetrack
143
192
  licenses:
@@ -1,5 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.3.3
5
- before_install: gem install bundler -v 1.13.7