timetrack 0.1.0 → 0.2.0

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