fewald-worklog 0.3.8 → 0.3.10
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/.version +1 -1
- data/lib/github/client.rb +0 -1
- data/lib/github/pull_request_event.rb +1 -1
- data/lib/github/pull_request_review_event.rb +18 -2
- data/lib/github/push_event.rb +1 -1
- data/lib/people_storage.rb +118 -0
- data/lib/storage.rb +0 -66
- data/lib/worklog.rb +5 -2
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c918d6adace19f7c6fcf87f5a52a82c3fd3c60ddfc85e4042299e67dc204a17a
|
|
4
|
+
data.tar.gz: d901d4d78036bb7754f58406f47a9d003690dec8a087cffcaf77bc55e0d4de26
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f7400ed28bd389bbe70c51a61abfd63ae3fe3cbc7575273b8383e85aeef6b11137b8f645b57e65fc8f5bd6bb3fe5814387b9c3b2b9e11f755dd1bae933854d2f
|
|
7
|
+
data.tar.gz: a016e500815e38dfbb4308fe07ce599fc46f71eaf96c7fc3af668198f00b3985f09f7d02144faadca83c326cfd8b91ce201aa56b2077bae7545c012000cb7670
|
data/.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.3.
|
|
1
|
+
0.3.10
|
data/lib/github/client.rb
CHANGED
|
@@ -40,10 +40,12 @@ module Worklog
|
|
|
40
40
|
|
|
41
41
|
# Convert the PullRequestReviewEvent to a LogEntry
|
|
42
42
|
# @return [LogEntry]
|
|
43
|
-
def to_log_entry
|
|
43
|
+
def to_log_entry(people_storage = nil)
|
|
44
|
+
handle = resolve_username(people_storage) || creator
|
|
45
|
+
|
|
44
46
|
message = String.new 'Reviewed '
|
|
45
47
|
message << 'and approved ' if approved?
|
|
46
|
-
message << "PR ##{number} #{
|
|
48
|
+
message << "PR ##{number} #{handle}: #{title}"
|
|
47
49
|
LogEntry.new(
|
|
48
50
|
key: Hasher.sha256("#{repository}-#{number}-#{state}"),
|
|
49
51
|
source: 'github',
|
|
@@ -58,6 +60,20 @@ module Worklog
|
|
|
58
60
|
def to_s
|
|
59
61
|
"#<PullRequestReviewEvent repository=#{repository} number=#{number} state=#{state} creator=#{creator} created_at=#{created_at}>" # rubocop:disable Layout/LineLength
|
|
60
62
|
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
# Resolve the GitHub username to a person handle using the provided PeopleStorage
|
|
67
|
+
# @param [PeopleStorage, nil] people_storage The PeopleStorage instance to use for resolution
|
|
68
|
+
# @return [String, nil] The person handle if found, otherwise nil
|
|
69
|
+
# @example
|
|
70
|
+
# resolve_username(people_storage) #=> "~johndoe"
|
|
71
|
+
def resolve_username(people_storage)
|
|
72
|
+
return if people_storage.nil?
|
|
73
|
+
|
|
74
|
+
person = people_storage.find_by_github_username(creator)
|
|
75
|
+
person ? "~#{person.handle}" : nil
|
|
76
|
+
end
|
|
61
77
|
end
|
|
62
78
|
end
|
|
63
79
|
end
|
data/lib/github/push_event.rb
CHANGED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'person'
|
|
4
|
+
require 'worklogger'
|
|
5
|
+
require 'yaml'
|
|
6
|
+
|
|
7
|
+
module Worklog
|
|
8
|
+
# Finding, reading, and writing of people
|
|
9
|
+
# @see Person
|
|
10
|
+
# @see Storage
|
|
11
|
+
class PeopleStorage
|
|
12
|
+
PEOPLE_FILE = 'people.yaml'
|
|
13
|
+
|
|
14
|
+
# The template for the people YAML file.
|
|
15
|
+
# This template is used to create a new people file if it does not exist.
|
|
16
|
+
PERSON_TEMPLATE = <<~YAML
|
|
17
|
+
---
|
|
18
|
+
# Each person is defined by the following attributes:
|
|
19
|
+
# - handle: <unique_handle>
|
|
20
|
+
# Unique handle used to reference this person (e.g., ~jdoe)
|
|
21
|
+
# github_username: <github_username>
|
|
22
|
+
# GitHub username of the person, used to link GitHub events to this person.
|
|
23
|
+
# This can be omitted if the person does not have a GitHub account and can
|
|
24
|
+
# be different from the handle.
|
|
25
|
+
# name: <full_name>
|
|
26
|
+
# team: <team_name>
|
|
27
|
+
# email: <email_address>
|
|
28
|
+
# title: <title_or_role>
|
|
29
|
+
# inactive: <true_or_false>
|
|
30
|
+
# --- Define your people below this line ---
|
|
31
|
+
YAML
|
|
32
|
+
|
|
33
|
+
def initialize(config)
|
|
34
|
+
@config = config
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Return the full absolute filepath for the people.yaml file
|
|
38
|
+
# @return [String] The filepath
|
|
39
|
+
def people_filepath
|
|
40
|
+
File.join(@config.storage_path, PEOPLE_FILE)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Load all people from the people file and return them as a hash with handle as key
|
|
44
|
+
# @return [Hash<String, Person>] Hash of people with handle as key
|
|
45
|
+
def load_people_hash
|
|
46
|
+
load_people.to_h { |person| [person.handle, person] }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Load all people from the people YAML file
|
|
50
|
+
# Return empty array if file does not exist
|
|
51
|
+
# @return [Array<Person>] List of all people
|
|
52
|
+
def load_people
|
|
53
|
+
load_people!
|
|
54
|
+
rescue Errno::ENOENT
|
|
55
|
+
# If the file does not exist, create it with the template
|
|
56
|
+
File.write(people_filepath, PERSON_TEMPLATE)
|
|
57
|
+
[]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Load all people from the people YAML file
|
|
61
|
+
# @return [Array<Person>] List of all people
|
|
62
|
+
# @raise [Errno::ENOENT] if the people file does not exist
|
|
63
|
+
def load_people!
|
|
64
|
+
# TODO: Remove this migration code in future versions
|
|
65
|
+
# This was introduced in v0.2.26 (Oct 2 2025) to fix deprecated YAML syntax
|
|
66
|
+
yamltext = File.read(people_filepath)
|
|
67
|
+
if yamltext != yamltext.gsub(/^- !.*$/, '-')
|
|
68
|
+
WorkLogger.debug 'The people.yaml file contains deprecated syntax. Migrating now.'
|
|
69
|
+
yamltext.gsub!(/^- !.*$/, '-')
|
|
70
|
+
File.write(people_filepath, yamltext)
|
|
71
|
+
end
|
|
72
|
+
# End TODO
|
|
73
|
+
|
|
74
|
+
data = YAML.load(yamltext, permitted_classes: [])
|
|
75
|
+
return [] unless data.is_a?(Array)
|
|
76
|
+
|
|
77
|
+
data.map { |person_hash| Person.from_hash(person_hash) }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Write people to the people file
|
|
81
|
+
# @param [Array<Person>] people List of people
|
|
82
|
+
def write_people!(people)
|
|
83
|
+
raise ArgumentError, 'people must be an array of Person objects' if people.nil? || !people.is_a?(Array)
|
|
84
|
+
|
|
85
|
+
File.open(people_filepath, 'w') do |f|
|
|
86
|
+
f.puts people.to_yaml
|
|
87
|
+
end
|
|
88
|
+
@people = people
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Create the default people file if it does not exist
|
|
92
|
+
# @return [void]
|
|
93
|
+
def create_default_file
|
|
94
|
+
if File.exist?(people_filepath)
|
|
95
|
+
WorkLogger.info 'people.yaml already exists, skipping creation.'
|
|
96
|
+
else
|
|
97
|
+
WorkLogger.info 'Creating default people.yaml file.'
|
|
98
|
+
File.write(people_filepath, PERSON_TEMPLATE)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Find a person by their handle
|
|
103
|
+
# @param [String] handle The handle of the person
|
|
104
|
+
# @return [Person, nil] The person if found, nil otherwise
|
|
105
|
+
def find_by_handle(handle)
|
|
106
|
+
@people ||= load_people
|
|
107
|
+
@people.find { |person| person.handle == handle }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Find a person by their GitHub username
|
|
111
|
+
# @param [String] github_username The GitHub username of the person
|
|
112
|
+
# @return [Person, nil] The person if found, nil otherwise
|
|
113
|
+
def find_by_github_username(github_username)
|
|
114
|
+
@people ||= load_people
|
|
115
|
+
@people.find { |person| person.github_username == github_username }
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
data/lib/storage.rb
CHANGED
|
@@ -17,21 +17,6 @@ module Worklog
|
|
|
17
17
|
# Regular expression to match daily log file names
|
|
18
18
|
LOG_PATTERN = /\d{4}-\d{2}-\d{2}#{FILE_SUFFIX}\z/
|
|
19
19
|
|
|
20
|
-
# The template for the people YAML file.
|
|
21
|
-
# This template is used to create a new people file if it does not exist.
|
|
22
|
-
PERSON_TEMPLATE = <<~YAML
|
|
23
|
-
---
|
|
24
|
-
# Each person is defined by the following attributes:
|
|
25
|
-
# - handle: <unique_handle>
|
|
26
|
-
# github_username: <github_username>
|
|
27
|
-
# name: <full_name>
|
|
28
|
-
# team: <team_name>
|
|
29
|
-
# email: <email_address>
|
|
30
|
-
# role: <role_in_team>
|
|
31
|
-
# inactive: <true_or_false>
|
|
32
|
-
# --- Define your people below this line ---
|
|
33
|
-
YAML
|
|
34
|
-
|
|
35
20
|
def initialize(config)
|
|
36
21
|
@config = config
|
|
37
22
|
end
|
|
@@ -153,44 +138,6 @@ module Worklog
|
|
|
153
138
|
daily_log.entries
|
|
154
139
|
end
|
|
155
140
|
|
|
156
|
-
# Load all people from the people file, or return an empty array if the file does not exist
|
|
157
|
-
#
|
|
158
|
-
# @return [Array<Person>] List of people
|
|
159
|
-
def load_people
|
|
160
|
-
load_people!
|
|
161
|
-
rescue Errno::ENOENT
|
|
162
|
-
WorkLogger.info 'Unable to load people.'
|
|
163
|
-
[]
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
# Load all people from the people file and return them as a hash with handle as key
|
|
167
|
-
# @return [Hash<String, Person>] Hash of people with handle as key
|
|
168
|
-
def load_people_hash
|
|
169
|
-
load_people.to_h { |person| [person.handle, person] }
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
# Load all people from the people file
|
|
173
|
-
# @return [Array<Person>] List of people
|
|
174
|
-
def load_people!
|
|
175
|
-
return [] unless File.exist?(people_filepath)
|
|
176
|
-
|
|
177
|
-
yamltext = File.read(people_filepath)
|
|
178
|
-
if yamltext != yamltext.gsub(/^- !.*$/, '-')
|
|
179
|
-
WorkLogger.debug 'The people.yaml file contains deprecated syntax. Migrating now.'
|
|
180
|
-
yamltext.gsub!(/^- !.*$/, '-')
|
|
181
|
-
File.write(people_filepath, yamltext)
|
|
182
|
-
end
|
|
183
|
-
YAML.load(yamltext, permitted_classes: []).map { |person_hash| Person.from_hash(person_hash) }
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
# Write people to the people file
|
|
187
|
-
# @param [Array<Person>] people List of people
|
|
188
|
-
def write_people!(people)
|
|
189
|
-
File.open(people_filepath, 'w') do |f|
|
|
190
|
-
f.puts people.to_yaml
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
|
|
194
141
|
# Create folder if not exists already.
|
|
195
142
|
# @return [void]
|
|
196
143
|
def create_default_folder
|
|
@@ -214,13 +161,6 @@ module Worklog
|
|
|
214
161
|
# File.write(projects_file, [].to_yaml)
|
|
215
162
|
# end
|
|
216
163
|
|
|
217
|
-
if File.exist?(people_filepath)
|
|
218
|
-
WorkLogger.info 'people.yaml already exists, skipping creation.'
|
|
219
|
-
else
|
|
220
|
-
WorkLogger.info 'Creating default people.yaml file.'
|
|
221
|
-
File.write(people_filepath, PERSON_TEMPLATE)
|
|
222
|
-
end
|
|
223
|
-
|
|
224
164
|
# Write the default config file if it does not exist
|
|
225
165
|
if File.exist?(Configuration.config_file_path)
|
|
226
166
|
WorkLogger.info "Configuration file (#{Configuration.config_file_path}) already exists, skipping creation."
|
|
@@ -237,11 +177,5 @@ module Worklog
|
|
|
237
177
|
def filepath(date)
|
|
238
178
|
File.join(@config.storage_path, "#{date}#{FILE_SUFFIX}")
|
|
239
179
|
end
|
|
240
|
-
|
|
241
|
-
# Return the full absolute filepath for the people.yaml file
|
|
242
|
-
# @return [String] The filepath
|
|
243
|
-
def people_filepath
|
|
244
|
-
File.join(@config.storage_path, 'people.yaml')
|
|
245
|
-
end
|
|
246
180
|
end
|
|
247
181
|
end
|
data/lib/worklog.rb
CHANGED
|
@@ -14,6 +14,7 @@ require 'hasher'
|
|
|
14
14
|
require 'log_entry'
|
|
15
15
|
require 'worklogger'
|
|
16
16
|
require 'string_helper'
|
|
17
|
+
require 'people_storage'
|
|
17
18
|
require 'printer'
|
|
18
19
|
require 'project_storage'
|
|
19
20
|
require 'statistics'
|
|
@@ -57,6 +58,7 @@ module Worklog
|
|
|
57
58
|
|
|
58
59
|
# Initialize (project) storage
|
|
59
60
|
@storage = Storage.new(@config)
|
|
61
|
+
@people_storage = PeopleStorage.new(@config)
|
|
60
62
|
@project_storage = ProjectStorage.new(@config)
|
|
61
63
|
|
|
62
64
|
bootstrap
|
|
@@ -67,7 +69,7 @@ module Worklog
|
|
|
67
69
|
@storage.create_default_folder
|
|
68
70
|
|
|
69
71
|
# Load all people as they're used in multiple/most of the methods.
|
|
70
|
-
@people = @
|
|
72
|
+
@people = @people_storage.load_people_hash
|
|
71
73
|
|
|
72
74
|
# Load all projects from disk
|
|
73
75
|
@projects = @project_storage.load_projects
|
|
@@ -152,7 +154,7 @@ module Worklog
|
|
|
152
154
|
daily_log = @storage.load_log!(@storage.filepath(date))
|
|
153
155
|
entries_before = daily_log.entries.size
|
|
154
156
|
events.each do |event|
|
|
155
|
-
log_entry = event.to_log_entry
|
|
157
|
+
log_entry = event.to_log_entry(@people_storage)
|
|
156
158
|
WorkLogger.debug('Entry already exists, skipping') if daily_log.key?(log_entry.key)
|
|
157
159
|
daily_log << log_entry unless daily_log.key?(log_entry.key)
|
|
158
160
|
WorkLogger.debug "Added entry: #{log_entry.message_string}"
|
|
@@ -169,6 +171,7 @@ module Worklog
|
|
|
169
171
|
# This method will not overwrite existing files and is thus safe to run multiple times.
|
|
170
172
|
def init(_options = {})
|
|
171
173
|
@storage.create_default_files
|
|
174
|
+
@people_storage.create_default_file
|
|
172
175
|
end
|
|
173
176
|
|
|
174
177
|
# Show the work log for a specific date range or a single date.
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fewald-worklog
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Friedrich Ewald
|
|
@@ -149,6 +149,7 @@ files:
|
|
|
149
149
|
- lib/hash.rb
|
|
150
150
|
- lib/hasher.rb
|
|
151
151
|
- lib/log_entry.rb
|
|
152
|
+
- lib/people_storage.rb
|
|
152
153
|
- lib/person.rb
|
|
153
154
|
- lib/printer.rb
|
|
154
155
|
- lib/project.rb
|