fewald-worklog 0.3.7 → 0.3.9

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: 403f517a4187813057f08fa0152df86fdbcc29271a6881650c9de260b1026283
4
- data.tar.gz: 8a6fc79840438dc25323ffa4b7a172919be95982783259658dfbdccf90286449
3
+ metadata.gz: a5a920425a1afeebc25dfcc71d12b6df1019cee84acb600121371d42e041004f
4
+ data.tar.gz: 1f2de59cecee3fd2ed0d553488738bb908aefa1f907c2125aa8c28b3c0a4a641
5
5
  SHA512:
6
- metadata.gz: 1a4e9fd85a1b1c80a8432763706a06b5496fc8160dac7a1bd07f487ded8cd250040d0cd8442e72c78de570ec29bfac6fdb7eab6168817e0af3bb9f4c4b682ade
7
- data.tar.gz: 7a36f2c3dbe92fc4543a359d4736a80078b2a5f80a544df354d60df684c14036ed44782d342a7ac25d51ea300688cf0098ca25eef9b8729fb5892081168cb567
6
+ metadata.gz: 1c4d4203b735ebe240623eddfed044793bc6a1a9dc45ade6e28c171f8f9b458a0624228d864b743ffe7396eb1cf432563331027ed68e521e74445ccb27af5107
7
+ data.tar.gz: 648c610f794c778610de43a4698cbb6cbf04cfd8ac3abf09c3d219d3bb9552e0502bf7cb4b823036b1b95c1526114c7ae7b774f6acacd3f208b8683129d214d0
data/.version CHANGED
@@ -1 +1 @@
1
- 0.3.7
1
+ 0.3.9
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)
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require_relative 'worklogger'
5
+ require_relative 'person'
6
+ module Worklog
7
+ # Handles storage of people
8
+ class PeopleStorage
9
+ PEOPLE_FILE = 'people.yaml'
10
+
11
+ # The template for the people YAML file.
12
+ # This template is used to create a new people file if it does not exist.
13
+ PERSON_TEMPLATE = <<~YAML
14
+ ---
15
+ # Each person is defined by the following attributes:
16
+ # - handle: <unique_handle>
17
+ # github_username: <github_username>
18
+ # name: <full_name>
19
+ # team: <team_name>
20
+ # email: <email_address>
21
+ # title: <title_or_role>
22
+ # inactive: <true_or_false>
23
+ # --- Define your people below this line ---
24
+ YAML
25
+
26
+ def initialize(config)
27
+ @config = config
28
+ end
29
+
30
+ # Return the full absolute filepath for the people.yaml file
31
+ # @return [String] The filepath
32
+ def people_filepath
33
+ File.join(@config.storage_path, PEOPLE_FILE)
34
+ end
35
+
36
+ # Load all people from the people file and return them as a hash with handle as key
37
+ # @return [Hash<String, Person>] Hash of people with handle as key
38
+ def load_people_hash
39
+ load_people.to_h { |person| [person.handle, person] }
40
+ end
41
+
42
+ # Load all people from the people YAML file
43
+ # Return empty array if file does not exist
44
+ # @return [Array<Person>] List of all people
45
+ def load_people
46
+ load_people!
47
+ rescue Errno::ENOENT
48
+ # If the file does not exist, create it with the template
49
+ File.write(people_filepath, PERSON_TEMPLATE)
50
+ []
51
+ end
52
+
53
+ # Load all people from the people YAML file
54
+ # @return [Array<Person>] List of all people
55
+ # @raise [Errno::ENOENT] if the people file does not exist
56
+ def load_people!
57
+ # TODO: Remove this migration code in future versions
58
+ # This was introduced in v0.2.26 (Oct 2 2025) to fix deprecated YAML syntax
59
+ yamltext = File.read(people_filepath)
60
+ if yamltext != yamltext.gsub(/^- !.*$/, '-')
61
+ WorkLogger.debug 'The people.yaml file contains deprecated syntax. Migrating now.'
62
+ yamltext.gsub!(/^- !.*$/, '-')
63
+ File.write(people_filepath, yamltext)
64
+ end
65
+ # End TODO
66
+
67
+ data = YAML.load(yamltext, permitted_classes: [])
68
+ return [] unless data.is_a?(Array)
69
+
70
+ data.map { |person_hash| Person.from_hash(person_hash) }
71
+ end
72
+
73
+ # Write people to the people file
74
+ # @param [Array<Person>] people List of people
75
+ def write_people!(people)
76
+ raise ArgumentError, 'people must be an array of Person objects' if people.nil? || !people.is_a?(Array)
77
+
78
+ File.open(people_filepath, 'w') do |f|
79
+ f.puts people.to_yaml
80
+ end
81
+ @people = people
82
+ end
83
+
84
+ # Create the default people file if it does not exist
85
+ # @return [void]
86
+ def create_default_file
87
+ if File.exist?(people_filepath)
88
+ WorkLogger.info 'people.yaml already exists, skipping creation.'
89
+ else
90
+ WorkLogger.info 'Creating default people.yaml file.'
91
+ File.write(people_filepath, PERSON_TEMPLATE)
92
+ end
93
+ end
94
+
95
+ # Find a person by their handle
96
+ # @param [String] handle The handle of the person
97
+ # @return [Person, nil] The person if found, nil otherwise
98
+ def find_by_handle(handle)
99
+ @people ||= load_people
100
+ @people.find { |person| person.handle == handle }
101
+ end
102
+
103
+ # Find a person by their GitHub username
104
+ # @param [String] github_username The GitHub username of the person
105
+ # @return [Person, nil] The person if found, nil otherwise
106
+ def find_by_github_username(github_username)
107
+ @people ||= load_people
108
+ @people.find { |person| person.github_username == github_username }
109
+ end
110
+ end
111
+ 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,18 +161,14 @@ 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.'
164
+ # Write the default config file if it does not exist
165
+ if File.exist?(Configuration.config_file_path)
166
+ WorkLogger.info "Configuration file (#{Configuration.config_file_path}) already exists, skipping creation."
219
167
  else
220
- WorkLogger.info 'Creating default people.yaml file.'
221
- File.write(people_filepath, PERSON_TEMPLATE)
168
+ WorkLogger.info "Creating default configuration file at #{Configuration.config_file_path}."
169
+ File.write(Configuration.config_file_path,
170
+ Configuration::CONFIGURATION_TEMPLATE.result)
222
171
  end
223
-
224
- # Write the default config file if it does not exist
225
- return if File.exist?(Configuration.config_file_path)
226
-
227
- File.write(Configuration.config_file_path,
228
- Configuration::CONFIGURATION_TEMPLATE.result)
229
172
  end
230
173
 
231
174
  # Construct filepath for a given date.
@@ -234,11 +177,5 @@ module Worklog
234
177
  def filepath(date)
235
178
  File.join(@config.storage_path, "#{date}#{FILE_SUFFIX}")
236
179
  end
237
-
238
- # Return the full absolute filepath for the people.yaml file
239
- # @return [String] The filepath
240
- def people_filepath
241
- File.join(@config.storage_path, 'people.yaml')
242
- end
243
180
  end
244
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
@@ -134,6 +136,44 @@ module Worklog
134
136
  WorkLogger.info Rainbow("Updated work log for #{options[:date]}").green
135
137
  end
136
138
 
139
+ # Fetch latest events from GitHub for a specified user and add them to the work log.
140
+ #
141
+ # @param options [Hash] the options hash containing GitHub username and other parameters.
142
+ def github(_options = {})
143
+ github = Github::Client.new(@config)
144
+ github_events = github.fetch_events
145
+
146
+ WorkLogger.info Rainbow("Fetched #{github_events.size} events from GitHub.").green
147
+
148
+ events_by_date = github_events.group_by { |event| event.to_log_entry.time.to_date }
149
+
150
+ events_by_date.each do |date, events|
151
+ WorkLogger.info Rainbow("Found #{events.size} events for #{date}").green
152
+ puts "Processing #{events.size} events for '#{date}'"
153
+ @storage.create_file_skeleton(date)
154
+ daily_log = @storage.load_log!(@storage.filepath(date))
155
+ entries_before = daily_log.entries.size
156
+ events.each do |event|
157
+ log_entry = event.to_log_entry
158
+ WorkLogger.debug('Entry already exists, skipping') if daily_log.key?(log_entry.key)
159
+ daily_log << log_entry unless daily_log.key?(log_entry.key)
160
+ WorkLogger.debug "Added entry: #{log_entry.message_string}"
161
+ end
162
+ entries_after = daily_log.entries.size
163
+ WorkLogger.info Rainbow("Added #{entries_after - entries_before} new entries for #{date}").green
164
+
165
+ # Write log back to storage
166
+ @storage.write_log(@storage.filepath(date), daily_log)
167
+ end
168
+ end
169
+
170
+ # Initialize the work log storage with default files and folders.
171
+ # This method will not overwrite existing files and is thus safe to run multiple times.
172
+ def init(_options = {})
173
+ @storage.create_default_files
174
+ @people_storage.create_default_file
175
+ end
176
+
137
177
  # Show the work log for a specific date range or a single date.
138
178
  #
139
179
  # @param options [Hash] the options hash containing date range or 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.7
4
+ version: 0.3.9
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