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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7eebce5b88e954faa6242724ed451878b495285aa11757e40361ad430d45e5d5
4
- data.tar.gz: 683dd70aff93d5a0731bf56472d7ed55c5a62dfb71aba141b6534da100c90c6d
3
+ metadata.gz: c918d6adace19f7c6fcf87f5a52a82c3fd3c60ddfc85e4042299e67dc204a17a
4
+ data.tar.gz: d901d4d78036bb7754f58406f47a9d003690dec8a087cffcaf77bc55e0d4de26
5
5
  SHA512:
6
- metadata.gz: 9fda2165e1a06fe4df84eaa3c7d7396bcdf8f0fa14468bbadf89632c35cce0ba425e9b80fab2844fa07c8a65f18330d29593d142c5b8695e1976bb6b343f3e0f
7
- data.tar.gz: 217d4319ee3dd036000c4b14c9fc9a413e3920391d4b538a786db2239107bf46e56832fe23161416940fe0f98a086676b5cb25d2edb23e4978b9b33b3f8807c9
6
+ metadata.gz: f7400ed28bd389bbe70c51a61abfd63ae3fe3cbc7575273b8383e85aeef6b11137b8f645b57e65fc8f5bd6bb3fe5814387b9c3b2b9e11f755dd1bae933854d2f
7
+ data.tar.gz: a016e500815e38dfbb4308fe07ce599fc46f71eaf96c7fc3af668198f00b3985f09f7d02144faadca83c326cfd8b91ce201aa56b2077bae7545c012000cb7670
data/.version CHANGED
@@ -1 +1 @@
1
- 0.3.8
1
+ 0.3.10
data/lib/github/client.rb CHANGED
@@ -16,7 +16,6 @@ module Worklog
16
16
  EVENT_FILTER = Set.new(%w[
17
17
  PullRequestEvent
18
18
  PullRequestReviewEvent
19
-
20
19
  ]).freeze
21
20
 
22
21
  def initialize(configuration)
@@ -50,7 +50,7 @@ module Worklog
50
50
 
51
51
  # Convert the PullRequestEvent to a LogEntry
52
52
  # @return [LogEntry]
53
- def to_log_entry
53
+ def to_log_entry(*)
54
54
  message = if merged?
55
55
  'Merged PR '
56
56
  elsif closed?
@@ -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} #{creator}: #{title}"
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
@@ -6,7 +6,7 @@ module Worklog
6
6
  module Github
7
7
  # Event representing a push event
8
8
  class PushEvent
9
- def to_log_entry
9
+ def to_log_entry(*)
10
10
  WorkLogger.debug('Converting PushEvent to LogEntry')
11
11
  LogEntry.new(
12
12
  key: 'github-push-event',
@@ -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 = @storage.load_people_hash
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.8
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