fewald-worklog 0 → 0.1.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.
- checksums.yaml +4 -4
- data/bin/wl +2 -4
- data/worklog/cli.rb +267 -0
- data/{lib → worklog}/daily_log.rb +1 -2
- data/{lib → worklog}/log_entry.rb +6 -22
- data/{lib → worklog}/person.rb +1 -8
- data/{lib → worklog}/printer.rb +8 -15
- data/{lib → worklog}/statistics.rb +4 -10
- data/worklog/storage.rb +119 -0
- data/{lib → worklog}/string_helper.rb +1 -8
- data/{lib → worklog}/summary.rb +4 -10
- data/{lib → worklog}/templates/index.html.erb +8 -6
- data/worklog/version.rb +11 -0
- data/{lib → worklog}/webserver.rb +7 -20
- data/worklog/worklog.rb +14 -0
- metadata +22 -122
- data/.version +0 -1
- data/lib/cli.rb +0 -149
- data/lib/configuration.rb +0 -33
- data/lib/storage.rb +0 -172
- data/lib/version.rb +0 -31
- data/lib/worklog.rb +0 -216
- /data/{lib → worklog}/date_parser.rb +0 -0
- /data/{lib → worklog}/editor.rb +0 -0
- /data/{lib → worklog}/hash.rb +0 -0
- /data/{lib/worklogger.rb → worklog/logger.rb} +0 -0
- /data/{lib → worklog}/templates/favicon.svg.erb +0 -0
data/worklog/version.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
# Returns the current version of the gem from `.version`.
|
6
|
+
# Versioning follows SemVer.
|
7
|
+
# @return [String] The current version of the gem.
|
8
|
+
def current_version
|
9
|
+
version_file_path = File.join(Pathname.new(__dir__).parent, '.version')
|
10
|
+
File.read(version_file_path).strip
|
11
|
+
end
|
@@ -6,8 +6,8 @@ require 'rack'
|
|
6
6
|
require 'rack/constants'
|
7
7
|
require 'rackup'
|
8
8
|
require 'uri'
|
9
|
-
|
10
|
-
|
9
|
+
require_relative 'storage'
|
10
|
+
require_relative 'worklog'
|
11
11
|
|
12
12
|
class DefaultHeaderMiddleware
|
13
13
|
# Rack middleware to add default headers to the response.
|
@@ -24,12 +24,8 @@ class DefaultHeaderMiddleware
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
# Class to render the main page of the WorkLog web application.
|
28
27
|
class WorkLogResponse
|
29
|
-
|
30
|
-
@storage = storage
|
31
|
-
@tags = tags
|
32
|
-
end
|
28
|
+
# Class to render the main page of the WorkLog web application.
|
33
29
|
|
34
30
|
def response(request)
|
35
31
|
template = ERB.new(File.read(File.join(File.dirname(__FILE__), 'templates', 'index.html.erb')), trim_mode: '-')
|
@@ -38,7 +34,7 @@ class WorkLogResponse
|
|
38
34
|
tags = @params['tags'].nil? ? nil : @params['tags'].split(',')
|
39
35
|
epics_only = @params['epics_only'] == 'true'
|
40
36
|
presentation = @params['presentation'] == 'true'
|
41
|
-
logs =
|
37
|
+
logs = Storage.days_between(Date.today - days, Date.today, epics_only, tags).reverse
|
42
38
|
total_entries = logs.sum { |entry| entry.entries.length }
|
43
39
|
_ = total_entries
|
44
40
|
_ = presentation
|
@@ -66,14 +62,9 @@ class WorkLogResponse
|
|
66
62
|
end
|
67
63
|
|
68
64
|
class WorkLogApp
|
69
|
-
def
|
70
|
-
@storage = storage
|
71
|
-
@tags = @storage.tags
|
72
|
-
end
|
73
|
-
|
74
|
-
def call(env)
|
65
|
+
def self.call(env)
|
75
66
|
req = Rack::Request.new(env)
|
76
|
-
WorkLogResponse.new
|
67
|
+
WorkLogResponse.new.response(req)
|
77
68
|
end
|
78
69
|
end
|
79
70
|
|
@@ -88,12 +79,8 @@ end
|
|
88
79
|
|
89
80
|
class WorkLogServer
|
90
81
|
# Main Rack server containing all endpoints.
|
91
|
-
def initialize(worklog_app)
|
92
|
-
@worklog_app = worklog_app
|
93
|
-
end
|
94
82
|
|
95
83
|
def start
|
96
|
-
worklog_app = @worklog_app
|
97
84
|
app = Rack::Builder.new do
|
98
85
|
use Rack::Deflater
|
99
86
|
use Rack::CommonLogger
|
@@ -102,7 +89,7 @@ class WorkLogServer
|
|
102
89
|
use DefaultHeaderMiddleware
|
103
90
|
|
104
91
|
map '/' do
|
105
|
-
run
|
92
|
+
run WorkLogApp
|
106
93
|
end
|
107
94
|
# TODO: Future development
|
108
95
|
# map '/favicon.svg' do
|
data/worklog/worklog.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative 'hash'
|
5
|
+
require_relative 'daily_log'
|
6
|
+
require_relative 'log_entry'
|
7
|
+
require_relative 'storage'
|
8
|
+
|
9
|
+
require 'optparse'
|
10
|
+
require 'rainbow'
|
11
|
+
require 'yaml'
|
12
|
+
|
13
|
+
module Worklog
|
14
|
+
end
|
metadata
CHANGED
@@ -1,112 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fewald-worklog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Friedrich Ewald
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
11
|
-
dependencies:
|
12
|
-
- !ruby/object:Gem::Dependency
|
13
|
-
name: httparty
|
14
|
-
requirement: !ruby/object:Gem::Requirement
|
15
|
-
requirements:
|
16
|
-
- - "~>"
|
17
|
-
- !ruby/object:Gem::Version
|
18
|
-
version: 0.22.0
|
19
|
-
type: :runtime
|
20
|
-
prerelease: false
|
21
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
-
requirements:
|
23
|
-
- - "~>"
|
24
|
-
- !ruby/object:Gem::Version
|
25
|
-
version: 0.22.0
|
26
|
-
- !ruby/object:Gem::Dependency
|
27
|
-
name: logger
|
28
|
-
requirement: !ruby/object:Gem::Requirement
|
29
|
-
requirements:
|
30
|
-
- - "~>"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '1.6'
|
33
|
-
type: :runtime
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
36
|
-
requirements:
|
37
|
-
- - "~>"
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version: '1.6'
|
40
|
-
- !ruby/object:Gem::Dependency
|
41
|
-
name: puma
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
43
|
-
requirements:
|
44
|
-
- - "~>"
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: '6.6'
|
47
|
-
type: :runtime
|
48
|
-
prerelease: false
|
49
|
-
version_requirements: !ruby/object:Gem::Requirement
|
50
|
-
requirements:
|
51
|
-
- - "~>"
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '6.6'
|
54
|
-
- !ruby/object:Gem::Dependency
|
55
|
-
name: rack
|
56
|
-
requirement: !ruby/object:Gem::Requirement
|
57
|
-
requirements:
|
58
|
-
- - "~>"
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: '3.1'
|
61
|
-
type: :runtime
|
62
|
-
prerelease: false
|
63
|
-
version_requirements: !ruby/object:Gem::Requirement
|
64
|
-
requirements:
|
65
|
-
- - "~>"
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version: '3.1'
|
68
|
-
- !ruby/object:Gem::Dependency
|
69
|
-
name: rackup
|
70
|
-
requirement: !ruby/object:Gem::Requirement
|
71
|
-
requirements:
|
72
|
-
- - "~>"
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '2.2'
|
75
|
-
type: :runtime
|
76
|
-
prerelease: false
|
77
|
-
version_requirements: !ruby/object:Gem::Requirement
|
78
|
-
requirements:
|
79
|
-
- - "~>"
|
80
|
-
- !ruby/object:Gem::Version
|
81
|
-
version: '2.2'
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
|
-
name: rainbow
|
84
|
-
requirement: !ruby/object:Gem::Requirement
|
85
|
-
requirements:
|
86
|
-
- - "~>"
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
version: '3.1'
|
89
|
-
type: :runtime
|
90
|
-
prerelease: false
|
91
|
-
version_requirements: !ruby/object:Gem::Requirement
|
92
|
-
requirements:
|
93
|
-
- - "~>"
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version: '3.1'
|
96
|
-
- !ruby/object:Gem::Dependency
|
97
|
-
name: thor
|
98
|
-
requirement: !ruby/object:Gem::Requirement
|
99
|
-
requirements:
|
100
|
-
- - "~>"
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: '1.3'
|
103
|
-
type: :runtime
|
104
|
-
prerelease: false
|
105
|
-
version_requirements: !ruby/object:Gem::Requirement
|
106
|
-
requirements:
|
107
|
-
- - "~>"
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
version: '1.3'
|
10
|
+
date: 2025-03-12 00:00:00.000000000 Z
|
11
|
+
dependencies: []
|
110
12
|
description: |
|
111
13
|
Command line tool for tracking achievments, tasks and interactions.
|
112
14
|
|
@@ -120,27 +22,25 @@ executables:
|
|
120
22
|
extensions: []
|
121
23
|
extra_rdoc_files: []
|
122
24
|
files:
|
123
|
-
- ".version"
|
124
25
|
- bin/wl
|
125
|
-
-
|
126
|
-
-
|
127
|
-
-
|
128
|
-
-
|
129
|
-
-
|
130
|
-
-
|
131
|
-
-
|
132
|
-
-
|
133
|
-
-
|
134
|
-
-
|
135
|
-
-
|
136
|
-
-
|
137
|
-
-
|
138
|
-
-
|
139
|
-
-
|
140
|
-
-
|
141
|
-
-
|
142
|
-
-
|
143
|
-
- lib/worklogger.rb
|
26
|
+
- worklog/cli.rb
|
27
|
+
- worklog/daily_log.rb
|
28
|
+
- worklog/date_parser.rb
|
29
|
+
- worklog/editor.rb
|
30
|
+
- worklog/hash.rb
|
31
|
+
- worklog/log_entry.rb
|
32
|
+
- worklog/logger.rb
|
33
|
+
- worklog/person.rb
|
34
|
+
- worklog/printer.rb
|
35
|
+
- worklog/statistics.rb
|
36
|
+
- worklog/storage.rb
|
37
|
+
- worklog/string_helper.rb
|
38
|
+
- worklog/summary.rb
|
39
|
+
- worklog/templates/favicon.svg.erb
|
40
|
+
- worklog/templates/index.html.erb
|
41
|
+
- worklog/version.rb
|
42
|
+
- worklog/webserver.rb
|
43
|
+
- worklog/worklog.rb
|
144
44
|
homepage: https://github.com/f-ewald/worklog
|
145
45
|
licenses:
|
146
46
|
- MIT
|
@@ -165,7 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
65
|
- !ruby/object:Gem::Version
|
166
66
|
version: '0'
|
167
67
|
requirements: []
|
168
|
-
rubygems_version: 3.6.
|
68
|
+
rubygems_version: 3.6.2
|
169
69
|
specification_version: 4
|
170
70
|
summary: Command line tool for tracking achievments, tasks and interactions.
|
171
71
|
test_files: []
|
data/.version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
|
data/lib/cli.rb
DELETED
@@ -1,149 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Add the current directory to the load path
|
4
|
-
# curr_dir = File.expand_path(__dir__)
|
5
|
-
# $LOAD_PATH << curr_dir unless $LOAD_PATH.include?(curr_dir)
|
6
|
-
|
7
|
-
require 'thor'
|
8
|
-
require 'date'
|
9
|
-
require 'worklogger'
|
10
|
-
|
11
|
-
require 'worklog'
|
12
|
-
require 'date_parser'
|
13
|
-
require 'configuration'
|
14
|
-
require 'editor'
|
15
|
-
require 'printer'
|
16
|
-
require 'statistics'
|
17
|
-
require 'storage'
|
18
|
-
require 'string_helper'
|
19
|
-
require 'summary'
|
20
|
-
require 'version'
|
21
|
-
require 'webserver'
|
22
|
-
|
23
|
-
# CLI for the work log application
|
24
|
-
class WorklogCLI < Thor
|
25
|
-
attr_accessor :config, :storage
|
26
|
-
|
27
|
-
include StringHelper
|
28
|
-
class_option :verbose, type: :boolean, aliases: '-v', desc: 'Enable verbose output'
|
29
|
-
|
30
|
-
package_name 'Worklog'
|
31
|
-
|
32
|
-
# Initialize the CLI with the given arguments, options, and configuration
|
33
|
-
def initialize(args = [], options = {}, config = {})
|
34
|
-
@config = load_configuration
|
35
|
-
@storage = Storage.new(@config)
|
36
|
-
super
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.exit_on_failure?
|
40
|
-
true
|
41
|
-
end
|
42
|
-
|
43
|
-
desc 'add MESSAGE', 'Add a new entry to the work log, defaults to the current date.'
|
44
|
-
long_desc <<~LONGDESC
|
45
|
-
Add a new entry with the current date and time to the work log.
|
46
|
-
The message is required and must be enclosed in quotes if it contains more than one word.
|
47
|
-
|
48
|
-
People can be referenced either by using the tilde "~" or the at symbol "@", followed by
|
49
|
-
an alphanumeric string.
|
50
|
-
LONGDESC
|
51
|
-
option :date, type: :string, default: DateTime.now.strftime('%Y-%m-%d'), desc: 'Set the date of the entry'
|
52
|
-
option :time, type: :string, default: DateTime.now.strftime('%H:%M:%S'), desc: 'Set the time of the entry'
|
53
|
-
option :tags, type: :array, default: [], desc: 'Add tags to the entry'
|
54
|
-
option :ticket, type: :string, desc: 'Ticket number associated with the entry. Can be any alphanumeric string.'
|
55
|
-
option :url, type: :string, desc: 'URL to associate with the entry'
|
56
|
-
option :epic, type: :boolean, default: false, desc: 'Mark the entry as an epic'
|
57
|
-
def add(message)
|
58
|
-
worklog = Worklog.new
|
59
|
-
worklog.add(message, options)
|
60
|
-
end
|
61
|
-
|
62
|
-
desc 'edit', 'Edit a day in the work log. By default, the current date is used.'
|
63
|
-
option :date, type: :string, default: DateTime.now.strftime('%Y-%m-%d')
|
64
|
-
def edit
|
65
|
-
worklog = Worklog.new
|
66
|
-
worklog.edit(options)
|
67
|
-
end
|
68
|
-
|
69
|
-
desc 'remove', 'Remove last entry from the log'
|
70
|
-
option :date, type: :string, default: DateTime.now.strftime('%Y-%m-%d')
|
71
|
-
def remove
|
72
|
-
worklog = Worklog.new
|
73
|
-
worklog.remove(options)
|
74
|
-
end
|
75
|
-
|
76
|
-
desc 'show', 'Show the work log for a specific date or a range of dates. Defaults to todays date.'
|
77
|
-
long_desc <<~LONGDESC
|
78
|
-
Show the work log for a specific date or a range of dates. As a default, all items from the current day will be shown.
|
79
|
-
LONGDESC
|
80
|
-
option :date, type: :string, default: DateTime.now.strftime('%Y-%m-%d'),
|
81
|
-
desc: <<~DESC
|
82
|
-
Show the work log for a specific date. If this option is provided, --from and --to and --days should not be used.
|
83
|
-
DESC
|
84
|
-
option :from, type: :string, desc: <<~EOF
|
85
|
-
Inclusive start date of the range. Takes precedence over --date, if defined.
|
86
|
-
EOF
|
87
|
-
option :to, type: :string, desc: <<~EOF
|
88
|
-
Inclusive end date of the range. Takes precedence over --date, if defined.
|
89
|
-
EOF
|
90
|
-
option :days, type: :numeric, desc: <<~EOF
|
91
|
-
Number of days to show starting from --date. Takes precedence over --from and --to if defined.
|
92
|
-
EOF
|
93
|
-
option :epics_only, type: :boolean, default: false, desc: 'Show only entries that are marked as epic'
|
94
|
-
option :tags, type: :array, default: [], desc: 'Filter entries by tags. Tags are treated as an OR condition.'
|
95
|
-
def show
|
96
|
-
worklog = Worklog.new
|
97
|
-
worklog.show(options)
|
98
|
-
end
|
99
|
-
|
100
|
-
desc 'people', 'Show all people mentioned in the work log'
|
101
|
-
def people(person = nil)
|
102
|
-
worklog = Worklog.new
|
103
|
-
worklog.people(person, options)
|
104
|
-
end
|
105
|
-
|
106
|
-
desc 'tags', 'Show all tags used in the work log'
|
107
|
-
def tags
|
108
|
-
worklog = Worklog.new
|
109
|
-
worklog.tags(options)
|
110
|
-
end
|
111
|
-
|
112
|
-
desc 'server', 'Start the work log server'
|
113
|
-
def server
|
114
|
-
app = WorkLogApp.new(@storage)
|
115
|
-
WorkLogServer.new(app).start
|
116
|
-
end
|
117
|
-
|
118
|
-
desc 'stats', 'Show statistics for the work log'
|
119
|
-
def stats
|
120
|
-
worklog = Worklog.new
|
121
|
-
worklog.stats(options)
|
122
|
-
end
|
123
|
-
|
124
|
-
desc 'summary', 'Generate a summary of the work log entries'
|
125
|
-
option :date, type: :string, default: DateTime.now.strftime('%Y-%m-%d')
|
126
|
-
option :from, type: :string, desc: <<-EOF
|
127
|
-
'Inclusive start date of the range. Takes precedence over --date if defined.'
|
128
|
-
EOF
|
129
|
-
option :to, type: :string, desc: <<-EOF
|
130
|
-
'Inclusive end date of the range. Takes precedence over --date if defined.'
|
131
|
-
EOF
|
132
|
-
option :days, type: :numeric, desc: <<-EOF
|
133
|
-
'Number of days to show starting from --date. Takes precedence over --from and --to if defined.'
|
134
|
-
EOF
|
135
|
-
def summary
|
136
|
-
worklog = Worklog.new
|
137
|
-
worklog.summary(options)
|
138
|
-
end
|
139
|
-
|
140
|
-
desc 'version', 'Show the version of the Worklog'
|
141
|
-
def version
|
142
|
-
puts "Worklog #{current_version} running on Ruby #{RUBY_VERSION}"
|
143
|
-
end
|
144
|
-
|
145
|
-
# Define shortcuts and aliases
|
146
|
-
map 'a' => :add
|
147
|
-
map 'statistics' => :stats
|
148
|
-
map 'serve' => :server
|
149
|
-
end
|
data/lib/configuration.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'yaml'
|
4
|
-
|
5
|
-
# Configuration class for the application.
|
6
|
-
class Configuration
|
7
|
-
attr_accessor :storage_path, :log_level, :webserver_port
|
8
|
-
|
9
|
-
def initialize(&block)
|
10
|
-
block.call(self) if block_given?
|
11
|
-
|
12
|
-
# Set default values if not set
|
13
|
-
@storage_path ||= File.join(Dir.home, '.worklog')
|
14
|
-
@log_level ||= :info
|
15
|
-
@webserver_port ||= 3000
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# Load configuration from a YAML file.
|
20
|
-
# The file should be located at ~/.worklog.yaml.
|
21
|
-
def load_configuration
|
22
|
-
file_path = File.join(Dir.home, '.worklog.yaml')
|
23
|
-
if File.exist?(file_path)
|
24
|
-
file_cfg = YAML.load_file(file_path)
|
25
|
-
Configuration.new do |cfg|
|
26
|
-
cfg.storage_path = file_cfg['storage_path'] if file_cfg['storage_path']
|
27
|
-
cfg.log_level = file_cfg['log_level'].to_sym if file_cfg['log_level']
|
28
|
-
cfg.webserver_port = file_cfg['webserver_port'] if file_cfg['webserver_port']
|
29
|
-
end
|
30
|
-
else
|
31
|
-
puts "Configuration file does not exist in #{file_path}"
|
32
|
-
end
|
33
|
-
end
|
data/lib/storage.rb
DELETED
@@ -1,172 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rainbow'
|
4
|
-
require 'daily_log'
|
5
|
-
require 'log_entry'
|
6
|
-
require 'worklogger'
|
7
|
-
require 'person'
|
8
|
-
|
9
|
-
# Handles storage of daily logs and people
|
10
|
-
class Storage
|
11
|
-
# LogNotFoundError is raised when a log file is not found
|
12
|
-
class LogNotFoundError < StandardError; end
|
13
|
-
|
14
|
-
FILE_SUFFIX = '.yaml'
|
15
|
-
|
16
|
-
def initialize(config)
|
17
|
-
@config = config
|
18
|
-
end
|
19
|
-
|
20
|
-
def folder_exists?
|
21
|
-
Dir.exist?(@config.storage_path)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Return all logs for all available days
|
25
|
-
# @return [Array<DailyLog>] List of all logs
|
26
|
-
def all_days
|
27
|
-
return [] unless folder_exists?
|
28
|
-
|
29
|
-
logs = []
|
30
|
-
Dir.glob(File.join(@config.storage_path, "*#{FILE_SUFFIX}")).map do |file|
|
31
|
-
next if file.end_with?('people.yaml')
|
32
|
-
|
33
|
-
logs << load_log(file)
|
34
|
-
end
|
35
|
-
|
36
|
-
logs
|
37
|
-
end
|
38
|
-
|
39
|
-
# Return all tags as a set
|
40
|
-
# @return [Set<String>] Set of all tags
|
41
|
-
def tags
|
42
|
-
logs = all_days
|
43
|
-
tags = Set[]
|
44
|
-
logs.each do |log|
|
45
|
-
log.entries.each do |entry|
|
46
|
-
next unless entry.tags
|
47
|
-
|
48
|
-
entry.tags.each do |tag|
|
49
|
-
tags << tag
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
tags
|
54
|
-
end
|
55
|
-
|
56
|
-
# Return days between start_date and end_date
|
57
|
-
# If end_date is nil, return logs from start_date to today
|
58
|
-
#
|
59
|
-
# @param [Date] start_date The start date, inclusive
|
60
|
-
# @param [Date] end_date The end date, inclusive
|
61
|
-
# @param [Boolean] epics_only If true, only return logs with epic entries
|
62
|
-
# @param [Array<String>] tags_filter If provided, only return logs with entries that have at least one of the tags
|
63
|
-
# @return [Array<DailyLog>] List of logs
|
64
|
-
def days_between(start_date, end_date = nil, epics_only = nil, tags_filter = nil)
|
65
|
-
return [] unless folder_exists?
|
66
|
-
|
67
|
-
logs = []
|
68
|
-
end_date = Date.today if end_date.nil?
|
69
|
-
|
70
|
-
return [] if start_date > end_date
|
71
|
-
|
72
|
-
while start_date <= end_date
|
73
|
-
if File.exist?(filepath(start_date))
|
74
|
-
tmp_logs = load_log!(filepath(start_date))
|
75
|
-
tmp_logs.entries.keep_if { |entry| entry.epic? } if epics_only
|
76
|
-
|
77
|
-
if tags_filter
|
78
|
-
# Safeguard against entries without any tags, not just empty array
|
79
|
-
tmp_logs.entries.keep_if { |entry| entry.tags && (entry.tags & tags_filter).size > 0 }
|
80
|
-
end
|
81
|
-
|
82
|
-
logs << tmp_logs if tmp_logs.entries.length > 0
|
83
|
-
end
|
84
|
-
|
85
|
-
start_date += 1
|
86
|
-
end
|
87
|
-
logs
|
88
|
-
end
|
89
|
-
|
90
|
-
# Create file for a new day if it does not exist
|
91
|
-
# @param [Date] date The date, used as the file name.
|
92
|
-
def create_file_skeleton(date)
|
93
|
-
create_folder
|
94
|
-
|
95
|
-
File.write(filepath(date), YAML.dump(DailyLog.new(date:, entries: []))) unless File.exist?(filepath(date))
|
96
|
-
end
|
97
|
-
|
98
|
-
def load_log(file)
|
99
|
-
load_log!(file)
|
100
|
-
rescue LogNotFoundError
|
101
|
-
WorkLogger.error "No work log found for #{file}. Aborting."
|
102
|
-
nil
|
103
|
-
end
|
104
|
-
|
105
|
-
def load_log!(file)
|
106
|
-
WorkLogger.debug "Loading file #{file}"
|
107
|
-
begin
|
108
|
-
log = YAML.load_file(file, permitted_classes: [Date, Time, DailyLog, LogEntry])
|
109
|
-
log.entries.each do |entry|
|
110
|
-
entry.time = Time.parse(entry.time) unless entry.time.respond_to?(:strftime)
|
111
|
-
end
|
112
|
-
log
|
113
|
-
rescue Errno::ENOENT
|
114
|
-
raise LogNotFoundError
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
def write_log(file, daily_log)
|
119
|
-
create_folder
|
120
|
-
|
121
|
-
WorkLogger.debug "Writing to file #{file}"
|
122
|
-
|
123
|
-
File.open(file, 'w') do |f|
|
124
|
-
f.puts daily_log.to_yaml
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def load_single_log_file(file, headline = true)
|
129
|
-
daily_log = load_log!(file)
|
130
|
-
puts "Work log for #{Rainbow(daily_log.date).gold}:" if headline
|
131
|
-
daily_log.entries
|
132
|
-
end
|
133
|
-
|
134
|
-
def load_people
|
135
|
-
load_people!
|
136
|
-
rescue Errno::ENOENT
|
137
|
-
WorkLogger.info 'Unable to load people.'
|
138
|
-
[]
|
139
|
-
end
|
140
|
-
|
141
|
-
# Load all people from the people file
|
142
|
-
# @return [Array<Person>] List of people
|
143
|
-
def load_people!
|
144
|
-
people_file = File.join(@config.storage_path, 'people.yaml')
|
145
|
-
return [] unless File.exist?(people_file)
|
146
|
-
|
147
|
-
YAML.load_file(people_file, permitted_classes: [Person])
|
148
|
-
end
|
149
|
-
|
150
|
-
# Write people to the people file
|
151
|
-
# @param [Array<Person>] people List of people
|
152
|
-
def write_people!(people)
|
153
|
-
create_folder
|
154
|
-
|
155
|
-
people_file = File.join(@config.storage_path, 'people.yaml')
|
156
|
-
File.open(people_file, 'w') do |f|
|
157
|
-
f.puts people.to_yaml
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
# Create folder if not exists already.
|
162
|
-
def create_folder
|
163
|
-
Dir.mkdir(@config.storage_path) unless Dir.exist?(@config.storage_path)
|
164
|
-
end
|
165
|
-
|
166
|
-
# Construct filepath for a given date.
|
167
|
-
# @param [Date] date The date
|
168
|
-
# @return [String] The filepath
|
169
|
-
def filepath(date)
|
170
|
-
File.join(@config.storage_path, "#{date}#{FILE_SUFFIX}")
|
171
|
-
end
|
172
|
-
end
|
data/lib/version.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'pathname'
|
4
|
-
|
5
|
-
# Returns the current version of the gem from `.version`.
|
6
|
-
# Versioning follows SemVer.
|
7
|
-
# @return [String] The current version of the gem.
|
8
|
-
def current_version
|
9
|
-
version_file_path = File.join(Pathname.new(__dir__).parent, '.version')
|
10
|
-
File.read(version_file_path).strip
|
11
|
-
end
|
12
|
-
|
13
|
-
# Increment version number according to SemVer.
|
14
|
-
# @param version [String] The current version.
|
15
|
-
# @param part [String] The part of the version to increment.
|
16
|
-
# @return [String] The incremented version.
|
17
|
-
def increment_version(version, part = 'patch')
|
18
|
-
major, minor, patch = version.split('.').map(&:to_i)
|
19
|
-
case part
|
20
|
-
when 'major'
|
21
|
-
major += 1
|
22
|
-
minor = 0
|
23
|
-
patch = 0
|
24
|
-
when 'minor'
|
25
|
-
minor += 1
|
26
|
-
patch = 0
|
27
|
-
when 'patch'
|
28
|
-
patch += 1
|
29
|
-
end
|
30
|
-
[major, minor, patch].join('.')
|
31
|
-
end
|