codepulse 0.1.1 → 0.1.3

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: 9864f8d6e808c28ec1f97134ddca4ddb8648f3e1b290381d78e9644527a7e011
4
- data.tar.gz: d646eb794866fa95d92ea0eeaf81b84bd752212cb8378fe0e39300f4a401ca64
3
+ metadata.gz: dfc914ce32e60fc464e2563c3da95b72889ac156e927f70ff7c0082254e5aaf2
4
+ data.tar.gz: c872a7873251365f85bce4713134c60b514d1854ebe56ea888cab1031bd923b8
5
5
  SHA512:
6
- metadata.gz: 5f6f05cfb98debbd9940f9fed36534a4ce12745fd22945e5bc2b14037c98b267e46b70a1ecb1e9577d7ac9251f795822e82cfa888165e214db9fbf17cab5fd37
7
- data.tar.gz: de6c71e276b2f0022e61c466b822c4f85ea246146e69217f45583042f6dc1095562a4f064b8cd4d836d7820a800fa1cfa94e3b39b55e184d87c57d1913867358
6
+ metadata.gz: 531c38b79a0b09e73f427cf3d860ca16822df1b7797435375618d19feea280a8318791b3cf943dd3342b0675e5cf67cbc7c847bb35beddafb0e8faedfd9509df
7
+ data.tar.gz: 0be7777e2c2640f7a2ed9f3b5939cad157af98de7f825bc64e39cf27ffde1aa0324cd1e6cc8b7b1a7234eb0dadbfeb6330037f4df4b03db978a941f9662bb6bd
data/README.md CHANGED
@@ -23,8 +23,8 @@ gem install codepulse
23
23
  ```sh
24
24
  git clone https://github.com/WorkBright/codepulse.git
25
25
  cd codepulse
26
- gem build codepulse.gemspec
27
- gem install codepulse-0.1.0.gem
26
+ bundle install
27
+ rake install
28
28
  ```
29
29
 
30
30
  ## Usage
@@ -67,7 +67,7 @@ codepulse rails/rails --business-days 30 --limit 50
67
67
 
68
68
  ```
69
69
  ======================================================================================
70
- PR PICKUP TIME REPORT | Last 7 business days (Dec 16 - Dec 24)
70
+ Codepulse PR Metrics Report | Last 7 business days (Dec 16 - Dec 24)
71
71
  rails/rails
72
72
  ======================================================================================
73
73
 
@@ -108,12 +108,14 @@ codepulse rails/rails --business-days 30 --limit 50
108
108
  # Run tests
109
109
  rake test
110
110
 
111
- # Lint (requires: gem install rubocop)
112
- rubocop
111
+ # Lint
112
+ bundle exec rubocop
113
113
 
114
114
  # Build and install locally
115
- gem build codepulse.gemspec
116
- gem install codepulse-0.1.0.gem
115
+ rake install
116
+
117
+ # Release new version (bumps tag, pushes to git and RubyGems)
118
+ rake release
117
119
  ```
118
120
 
119
121
  ## License
@@ -93,7 +93,7 @@ module Codepulse
93
93
  def print_report_header(repo, business_days)
94
94
  time_period = build_time_period(business_days)
95
95
  puts "=" * REPORT_WIDTH
96
- puts " PR PICKUP TIME REPORT | #{time_period}"
96
+ puts " Codepulse PR Metrics Report | #{time_period}"
97
97
  puts " #{repo}"
98
98
  puts "=" * REPORT_WIDTH
99
99
  end
@@ -206,11 +206,11 @@ module Codepulse
206
206
  sorted = values.sort
207
207
  average_seconds = (values.sum / values.length.to_f).round
208
208
 
209
- puts " Average #{label.downcase}: #{format_duration_compact(average_seconds)}"
210
- puts " Median #{label.downcase}: #{format_duration_compact(percentile_value(sorted, 50))}"
211
- puts " p95 #{label.downcase}: #{format_duration_compact(percentile_value(sorted, 95))}" if values.length >= MIN_FOR_P95
212
- puts " Fastest #{label.downcase}: #{format_duration_compact(sorted.first)}"
213
- puts " Slowest #{label.downcase}: #{format_duration_compact(sorted.last)}"
209
+ print_stat_line("Average", label, format_duration_compact(average_seconds))
210
+ print_stat_line("Median", label, format_duration_compact(median_value(sorted)))
211
+ print_stat_line("p95", label, format_duration_compact(percentile_value(sorted, 95))) if values.length >= MIN_FOR_P95
212
+ print_stat_line("Fastest", label, format_duration_compact(sorted.first))
213
+ print_stat_line("Slowest", label, format_duration_compact(sorted.last))
214
214
  end
215
215
 
216
216
  def print_number_stats(label, values)
@@ -219,11 +219,16 @@ module Codepulse
219
219
  sorted = values.sort
220
220
  average_value = (values.sum / values.length.to_f).round(1)
221
221
 
222
- puts " Average #{label.downcase}: #{format_number_compact(average_value)}"
223
- puts " Median #{label.downcase}: #{format_number_compact(percentile_value(sorted, 50))}"
224
- puts " p95 #{label.downcase}: #{format_number_compact(percentile_value(sorted, 95))}" if values.length >= MIN_FOR_P95
225
- puts " Min #{label.downcase}: #{format_number_compact(sorted.first)}"
226
- puts " Max #{label.downcase}: #{format_number_compact(sorted.last)}"
222
+ print_stat_line("Average", label, format_number_compact(average_value))
223
+ print_stat_line("Median", label, format_number_compact(median_value(sorted)))
224
+ print_stat_line("p95", label, format_number_compact(percentile_value(sorted, 95))) if values.length >= MIN_FOR_P95
225
+ print_stat_line("Min", label, format_number_compact(sorted.first))
226
+ print_stat_line("Max", label, format_number_compact(sorted.last))
227
+ end
228
+
229
+ def print_stat_line(prefix, label, value)
230
+ stat_label = "#{prefix} #{label.downcase}:"
231
+ puts " #{stat_label.ljust(28)} #{value}"
227
232
  end
228
233
 
229
234
  def truncate(value, length)
@@ -274,7 +279,7 @@ module Codepulse
274
279
  end
275
280
 
276
281
  # Returns the value at the given percentile from a sorted array.
277
- # Uses nearest-rank method: p50 = median, p95 = 95th percentile.
282
+ # Uses nearest-rank method for percentiles like p95.
278
283
  def percentile_value(sorted_values, percentile)
279
284
  count = sorted_values.length
280
285
  rank = (percentile / 100.0 * count).ceil
@@ -282,6 +287,21 @@ module Codepulse
282
287
  sorted_values[index]
283
288
  end
284
289
 
290
+ # Returns the median of a sorted array.
291
+ # For odd counts, returns the middle value.
292
+ # For even counts, returns the average of the two middle values.
293
+ def median_value(sorted_values)
294
+ count = sorted_values.length
295
+ return nil if count.zero?
296
+
297
+ if count.odd?
298
+ sorted_values[count / 2]
299
+ else
300
+ mid = count / 2
301
+ (sorted_values[mid - 1] + sorted_values[mid]) / 2.0
302
+ end
303
+ end
304
+
285
305
  def format_number_compact(value)
286
306
  return "0" if value.nil?
287
307
 
data/lib/codepulse.rb CHANGED
@@ -9,5 +9,5 @@ require_relative "codepulse/formatter"
9
9
  require_relative "codepulse/cli"
10
10
 
11
11
  module Codepulse
12
- VERSION = "0.1.1"
12
+ VERSION = "0.1.3"
13
13
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codepulse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick Navarro
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-12-26 00:00:00.000000000 Z
10
+ date: 2025-12-27 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: Terminal tool to analyze GitHub pull request pickup times, merge times,
13
13
  and sizes using the gh CLI.
@@ -52,5 +52,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
52
  requirements: []
53
53
  rubygems_version: 3.6.2
54
54
  specification_version: 4
55
- summary: GitHub PR metrics TUI app
55
+ summary: GitHub PR metrics CLI tool
56
56
  test_files: []