pretty-git 0.1.4 → 0.1.6

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.
@@ -1,37 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'csv'
4
+ require_relative 'report_schema'
4
5
 
5
6
  module PrettyGit
6
7
  module Render
7
8
  # Renders CSV according to docs/output_formats.md and DR-001
8
9
  class CsvRenderer
9
- HEADERS = {
10
- 'activity' => %w[bucket timestamp commits additions deletions],
11
- 'authors' => %w[author author_email commits additions deletions avg_commit_size],
12
- 'files' => %w[path commits additions deletions changes],
13
- 'heatmap' => %w[dow hour commits],
14
- 'hotspots' => %w[path score commits additions deletions changes],
15
- 'churn' => %w[path churn commits additions deletions],
16
- 'ownership' => %w[path owner owner_share authors]
17
- }.freeze
18
10
  def initialize(io: $stdout)
19
11
  @io = io
20
12
  end
21
13
 
22
14
  def call(report, result, _filters)
23
- headers = headers_for(report, result)
15
+ headers = ReportSchema.headers_for(report, result)
24
16
  write_csv(headers, result[:items])
25
17
  end
26
18
 
27
19
  private
28
20
 
29
21
  def headers_for(report, result)
30
- return ['language', (result[:metric] || 'bytes').to_s, 'percent', 'color'] if report == 'languages'
31
-
32
- HEADERS.fetch(report) do
33
- raise ArgumentError, "CSV output for report '#{report}' is not supported yet"
34
- end
22
+ # Deprecated: use ReportSchema.headers_for instead
23
+ ReportSchema.headers_for(report, result)
35
24
  end
36
25
 
37
26
  def write_csv(headers, rows)
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'report_schema'
4
+
3
5
  module PrettyGit
4
6
  module Render
5
7
  # Renders Markdown tables and sections per docs/output_formats.md
6
- # rubocop:disable Metrics/ClassLength
7
8
  class MarkdownRenderer
8
9
  TITLES = {
9
10
  'activity' => 'Activity',
@@ -16,15 +17,6 @@ module PrettyGit
16
17
  'ownership' => 'Ownership'
17
18
  }.freeze
18
19
 
19
- HEADERS = {
20
- 'activity' => %w[bucket timestamp commits additions deletions],
21
- 'authors' => %w[author author_email commits additions deletions avg_commit_size],
22
- 'files' => %w[path commits additions deletions changes],
23
- 'heatmap' => %w[dow hour commits],
24
- 'hotspots' => %w[path score commits additions deletions changes],
25
- 'churn' => %w[path churn commits additions deletions],
26
- 'ownership' => %w[path owner owner_share authors]
27
- }.freeze
28
20
  def initialize(io: $stdout)
29
21
  @io = io
30
22
  end
@@ -32,7 +24,7 @@ module PrettyGit
32
24
  def call(report, result, _filters)
33
25
  return render_summary(result) if report == 'summary'
34
26
 
35
- headers = headers_for(report, result)
27
+ headers = ReportSchema.headers_for(report, result)
36
28
  title = title_for(report)
37
29
  rows = sort_rows(report, result[:items], result)
38
30
  render_table(title, headers, rows)
@@ -41,9 +33,8 @@ module PrettyGit
41
33
  private
42
34
 
43
35
  def headers_for(report, result)
44
- return ['language', (result[:metric] || 'bytes').to_s, 'percent', 'color'] if report == 'languages'
45
-
46
- HEADERS.fetch(report, [])
36
+ # Deprecated: use ReportSchema.headers_for instead
37
+ ReportSchema.headers_for(report, result)
47
38
  end
48
39
 
49
40
  def title_for(report)
@@ -131,6 +122,5 @@ module PrettyGit
131
122
  (val || '').to_s
132
123
  end
133
124
  end
134
- # rubocop:enable Metrics/ClassLength
135
125
  end
136
126
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrettyGit
4
+ module Render
5
+ # Centralized schema definitions for report headers and structure.
6
+ # Used by all renderers (CSV, Markdown, etc.) to ensure consistency.
7
+ module ReportSchema
8
+ # Standard headers for each report type
9
+ HEADERS = {
10
+ 'activity' => %w[bucket timestamp commits additions deletions],
11
+ 'authors' => %w[author author_email commits additions deletions avg_commit_size],
12
+ 'files' => %w[path commits additions deletions changes],
13
+ 'heatmap' => %w[dow hour commits],
14
+ 'hotspots' => %w[path score commits additions deletions changes],
15
+ 'churn' => %w[path churn commits additions deletions],
16
+ 'ownership' => %w[path owner owner_share authors],
17
+ 'summary' => %w[metric value] # not typically tabular but defined for completeness
18
+ }.freeze
19
+
20
+ module_function
21
+
22
+ # Returns headers for the given report type
23
+ # @param report [String] Report name
24
+ # @param result [Hash] Result hash (used for languages metric detection)
25
+ # @return [Array<String>] Array of header names
26
+ def headers_for(report, result = nil)
27
+ return languages_headers(result) if report == 'languages'
28
+
29
+ HEADERS[report] || raise(ArgumentError, "Unknown report type: #{report}")
30
+ end
31
+
32
+ # Languages report has dynamic headers based on metric
33
+ def languages_headers(result)
34
+ metric = result&.dig(:metric) || 'bytes'
35
+ ['language', metric.to_s, 'percent', 'color']
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrettyGit
4
+ module Utils
5
+ # Utilities for path/glob normalization and handling cross-platform quirks.
6
+ module PathUtils
7
+ module_function
8
+
9
+ # Normalize a string path or glob to Unicode NFC form.
10
+ # Returns nil if input is nil.
11
+ def normalize_nfc(str)
12
+ return nil if str.nil?
13
+
14
+ s = str.to_s
15
+ # Only normalize if supported in this Ruby build; otherwise return as-is
16
+ if s.respond_to?(:unicode_normalize)
17
+ s.unicode_normalize(:nfc)
18
+ else
19
+ s
20
+ end
21
+ end
22
+
23
+ # Normalize each entry in an Array-like collection to NFC and compact
24
+ # nils. Returns an Array.
25
+ def normalize_globs(collection)
26
+ Array(collection).compact.map { |p| normalize_nfc(p) }
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+
5
+ module PrettyGit
6
+ module Utils
7
+ # Utilities for time parsing and ISO8601 normalization used by filters.
8
+ module TimeUtils
9
+ module_function
10
+
11
+ # Converts various time inputs to ISO8601 in UTC.
12
+ # Accepts Time, String(ISO8601), or String(YYYY-MM-DD) treated as UTC midnight.
13
+ # Returns nil for nil/blank input. Raises ArgumentError for invalid values.
14
+ def to_utc_iso8601(val)
15
+ return nil if val.nil? || val.to_s.strip.empty?
16
+
17
+ parse_to_time(val).utc.iso8601
18
+ rescue ArgumentError
19
+ raise ArgumentError, "Invalid datetime: #{val} (expected ISO8601 or YYYY-MM-DD)"
20
+ end
21
+
22
+ def parse_to_time(val)
23
+ return val if val.is_a?(Time)
24
+ return parse_date_only(val) if val.is_a?(String) && date_only?(val)
25
+
26
+ Time.parse(val.to_s)
27
+ end
28
+
29
+ def parse_date_only(str)
30
+ y, m, d = str.split('-').map(&:to_i)
31
+ Time.new(y, m, d, 0, 0, 0, '+00:00')
32
+ end
33
+
34
+ def date_only?(str)
35
+ !!(str =~ /^\d{4}-\d{2}-\d{2}$/)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PrettyGit
4
- VERSION = '0.1.4'
4
+ VERSION = '0.1.6'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pretty-git
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pretty Git Authors
@@ -74,17 +74,22 @@ files:
74
74
  - lib/pretty_git/app.rb
75
75
  - lib/pretty_git/cli.rb
76
76
  - lib/pretty_git/cli_helpers.rb
77
+ - lib/pretty_git/constants.rb
77
78
  - lib/pretty_git/filters.rb
78
79
  - lib/pretty_git/git/provider.rb
80
+ - lib/pretty_git/logger.rb
79
81
  - lib/pretty_git/render/console_renderer.rb
80
82
  - lib/pretty_git/render/csv_renderer.rb
81
83
  - lib/pretty_git/render/json_renderer.rb
82
84
  - lib/pretty_git/render/languages_section.rb
83
85
  - lib/pretty_git/render/markdown_renderer.rb
86
+ - lib/pretty_git/render/report_schema.rb
84
87
  - lib/pretty_git/render/terminal_width.rb
85
88
  - lib/pretty_git/render/xml_renderer.rb
86
89
  - lib/pretty_git/render/yaml_renderer.rb
87
90
  - lib/pretty_git/types.rb
91
+ - lib/pretty_git/utils/path_utils.rb
92
+ - lib/pretty_git/utils/time_utils.rb
88
93
  - lib/pretty_git/version.rb
89
94
  homepage: https://github.com/MikoMikocchi/pretty-git
90
95
  licenses: