fewald-worklog 0.2.19 → 0.2.20

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: e2bd1127e65b1c43b9ae95773b29d5648818940b44cfa82be0e69741148f3b16
4
- data.tar.gz: e30b8828d79177651e0179a2a7ec915fd03075de857e47280eaaec8bf682b8b4
3
+ metadata.gz: 7fab9613b51251c6cc9e6cd0f43dd1bd663db717c4783f2a1863b1441c7d8314
4
+ data.tar.gz: a73221bf9dec2a5ada555243d7258fe4b68ba1427e6deaf8c303afd71dabdf41
5
5
  SHA512:
6
- metadata.gz: 05f0bc3f9acd0ebe71b8fd78608c4227c0a54c6b54c711fb657eaa6d1ce24e952bf8e37785327745cfb100a8574705d1441b12110fed80b6103f24b2532761aa
7
- data.tar.gz: 31130d1928c6420c7c681d796189ccfc696875e92befb981463034d3d12c299f6aaab0ef3634c87fa787311e0042e3ff2cb8232be0db6a759505753446a998aa
6
+ metadata.gz: 94922720491591e24299a6da3abdd92e716a6cd61c1e91ea1cb05f880c4b11b0a4de36e04051d548b372653575753a633f279268d7e21b68c5cb895de17e7eaf
7
+ data.tar.gz: 604b44430a2c1b85856cf461e4d79aa7425acc95694eca1fa557909cb80fbc6b80879b2dec0f61ae5bdf8093dc6483a779e96600716f4606d3f35f237feea219
data/.version CHANGED
@@ -1 +1 @@
1
- 0.2.19
1
+ 0.2.20
data/lib/log_entry.rb CHANGED
@@ -5,13 +5,27 @@ require 'rainbow'
5
5
  require 'daily_log'
6
6
  require 'hash'
7
7
 
8
- # A single log entry.
8
+ # A single log entry in a DailyLog.
9
+ # @see DailyLog
10
+ # @!attribute [rw] time
11
+ # @return [DateTime] the date and time of the log entry.
12
+ # @!attribute [rw] tags
13
+ # @return [Array<String>] the tags associated with the log entry.
14
+ # @!attribute [rw] ticket
15
+ # @return [String] the ticket associated with the log entry.
16
+ # @!attribute [rw] url
17
+ # @return [String] the URL associated with the log entry.
18
+ # @!attribute [rw] epic
19
+ # @return [Boolean] whether the log entry is an epic.
20
+ # @!attribute [rw] message
21
+ # @return [String] the message of the log entry.
22
+ # @!attribute [rw] project
23
+ # @return [String] the project associated with the log entry.
9
24
  class LogEntry
10
25
  PERSON_REGEX = /(?:\s|^)[~@](\w+)/
11
26
 
12
27
  include Hashify
13
28
 
14
- # Represents a single entry in the work log.
15
29
  attr_accessor :time, :tags, :ticket, :url, :epic, :message, :project
16
30
 
17
31
  attr_reader :day
@@ -32,6 +46,7 @@ class LogEntry
32
46
  end
33
47
 
34
48
  # Returns true if the entry is an epic, false otherwise.
49
+ # @return [Boolean]
35
50
  def epic?
36
51
  @epic == true
37
52
  end
@@ -81,17 +96,22 @@ class LogEntry
81
96
  @message.scan(PERSON_REGEX).flatten.uniq.sort.to_set
82
97
  end
83
98
 
99
+ # Return true if there are people in the entry.
100
+ #
101
+ # @return [Boolean]
84
102
  def people?
85
- # Return true if there are people in the entry.
86
- #
87
- # @return [Boolean]
88
103
  people.size.positive?
89
104
  end
90
105
 
106
+ # Convert the log entry to YAML format.
91
107
  def to_yaml
92
108
  to_hash.to_yaml
93
109
  end
94
110
 
111
+ # Compare two log entries for equality.
112
+ #
113
+ # @param other [LogEntry] The other log entry to compare against.
114
+ # @return [Boolean] True if the log entries are equal, false otherwise.
95
115
  def ==(other)
96
116
  time == other.time && tags == other.tags && ticket == other.ticket && url == other.url &&
97
117
  epic == other.epic && message == other.message
data/lib/printer.rb CHANGED
@@ -9,7 +9,7 @@ class Printer
9
9
  # Initializes the printer with a list of people.
10
10
  # @param people [Array<Person>] An array of Person objects.
11
11
  def initialize(people = nil)
12
- @people = (people || []).to_h { |person| [person.handle, person] }
12
+ @people = people || {}
13
13
  end
14
14
 
15
15
  # Prints a whole day of work log entries.
data/lib/project.rb CHANGED
@@ -17,10 +17,18 @@ module Worklog
17
17
  # @return [String, nil] The status of the project, can be nil
18
18
  # Possible values: 'active', 'completed', 'archived', etc.
19
19
  # Indicates the current state of the project.
20
+ # @!attribute [rw] entries
21
+ # These entries are related to the work done on this project.
22
+ # Entries are populated dynamically when processing daily logs.
23
+ # They are not stored in the project itself.
24
+ # @return [Array<LogEntry>] An array of log entries associated with the project.
20
25
  # @!attribute [rw] last_activity
21
- # @return [Date, nil] The last activity date or nil if not set.
26
+ # The last activity is not stored in the project itself.
27
+ # Instead, it is updated dynamically when processing daily logs.
28
+ # It represents the most recent log entry time for this project.
29
+ # @return [Date, nil] The last activity date or nil if not set.
22
30
  class Project
23
- attr_accessor :key, :name, :description, :start_date, :end_date, :status, :last_activity
31
+ attr_accessor :key, :name, :description, :start_date, :end_date, :status, :entries, :last_activity
24
32
 
25
33
  # Creates a new Project instance from a hash of attributes.
26
34
  # @param hash [Hash] A hash containing project attributes
data/lib/storage.rb CHANGED
@@ -124,6 +124,7 @@ class Storage
124
124
  end
125
125
  end
126
126
 
127
+ # Load a single log file and return its entries
127
128
  def load_single_log_file(file, headline = true)
128
129
  daily_log = load_log!(file)
129
130
  puts "Work log for #{Rainbow(daily_log.date).gold}:" if headline
data/lib/worklog.rb CHANGED
@@ -54,6 +54,9 @@ module Worklog
54
54
  # Bootstrap the worklog application.
55
55
  def bootstrap
56
56
  @storage.create_default_folder
57
+
58
+ # Load all people as they're used in multiple/most of the methods.
59
+ @people = @storage.load_people_hash
57
60
  end
58
61
 
59
62
  # Add new entry to the work log.
@@ -89,8 +92,7 @@ module Worklog
89
92
 
90
93
  @storage.write_log(@storage.filepath(options[:date]), daily_log)
91
94
 
92
- people_hash = @storage.load_people_hash
93
- (new_entry.people - people_hash.keys).each do |handle|
95
+ (new_entry.people - @people.keys).each do |handle|
94
96
  WorkLogger.warn "Person with handle #{handle} not found. Consider adding them to people.yaml"
95
97
  end
96
98
 
@@ -130,8 +132,7 @@ module Worklog
130
132
  # worklog.show(from: '2023-10-01', to: '2023-10-31')
131
133
  # worklog.show(date: '2023-10-01')
132
134
  def show(options = {})
133
- people = @storage.load_people!
134
- printer = Printer.new(people)
135
+ printer = Printer.new(@people)
135
136
 
136
137
  start_date, end_date = start_end_date(options)
137
138
 
@@ -145,17 +146,16 @@ module Worklog
145
146
  end
146
147
  end
147
148
 
149
+ # Show all known people and details about a specific person.
148
150
  def people(person = nil, _options = {})
149
- all_people = @storage.load_people!
150
- people_map = all_people.to_h { |p| [p.handle, p] }
151
151
  all_logs = @storage.all_days
152
152
 
153
153
  if person
154
- unless people_map.key?(person)
154
+ unless @people.key?(person)
155
155
  WorkLogger.error Rainbow("No person found with handle #{person}.").red
156
156
  return
157
157
  end
158
- person_detail(all_logs, all_people, people_map[person.strip])
158
+ person_detail(all_logs, @people, @people[person.strip])
159
159
  else
160
160
  puts 'People mentioned in the work log:'
161
161
 
@@ -169,8 +169,8 @@ module Worklog
169
169
  mentions = mentions.to_a.sort_by { |handle, _| handle }
170
170
 
171
171
  mentions.each do |handle, v|
172
- if people_map.key?(handle)
173
- person = people_map[handle]
172
+ if @people.key?(handle)
173
+ person = @people[handle]
174
174
  print "#{Rainbow(person.name).gold} (#{handle})"
175
175
  print " (#{person.team})" if person.team
176
176
  else
@@ -203,13 +203,43 @@ module Worklog
203
203
  def projects(_options = {})
204
204
  project_storage = ProjectStorage.new(@config)
205
205
  projects = project_storage.load_projects
206
- puts Rainbow('Projects:').gold
206
+
207
+ # Load all entries to find latest activity for each project
208
+ @storage.all_days.each do |daily_log|
209
+ daily_log.entries.each do |entry|
210
+ if projects.key?(entry.project)
211
+ project = projects[entry.project]
212
+ project.entries ||= []
213
+ project.entries << entry
214
+ # Update last activity date if entry time is more recent
215
+ project.last_activity = entry.time if project.last_activity.nil? || entry.time > project.last_activity
216
+ else
217
+ WorkLogger.debug "Project with key '#{entry.project}' not found in projects. Skipping."
218
+ end
219
+ end
220
+ end
221
+ print_projects(projects)
222
+ end
223
+
224
+ def print_projects(projects)
225
+ puts Rainbow('Active Projects:').gold
207
226
  projects.each_value do |project|
227
+ # Sort entries by descending time
228
+ project.entries.sort_by!(&:time).reverse!
229
+
208
230
  puts "#{Rainbow(project.name).gold} (#{project.key})"
209
231
  puts " Description: #{project.description}" if project.description
210
232
  puts " Start date: #{project.start_date.strftime('%b %d, %Y')}" if project.start_date
211
233
  puts " End date: #{project.end_date.strftime('%b %d, %Y')}" if project.end_date
212
234
  puts " Status: #{project.status}" if project.status
235
+ puts " Last activity: #{project.last_activity.strftime('%b %d, %Y')}" if project.last_activity
236
+
237
+ next unless project.entries && !project.entries.empty?
238
+
239
+ puts " Last #{[project.entries&.size, 3].min} entries:"
240
+ puts " #{project.entries.last(3).map do |e|
241
+ "#{e.time.strftime('%b %d, %Y')} #{e.message_string(@people)}"
242
+ end.join("\n ")}"
213
243
  end
214
244
  puts 'No projects found.' if projects.empty?
215
245
  end
@@ -254,7 +284,7 @@ module Worklog
254
284
  # @example
255
285
  # worklog.tag_detail('example_tag', from: '2023-10-01', to: '2023-10-31')
256
286
  def tag_detail(tag, options)
257
- printer = Printer.new(@storage.load_people!)
287
+ printer = Printer.new(@people)
258
288
  start_date, end_date = start_end_date(options)
259
289
 
260
290
  @storage.days_between(start_date, end_date).each do |daily_log|
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.2.19
4
+ version: 0.2.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Friedrich Ewald