Class: Ace::Git::Models::DiffConfig

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/git/models/diff_config.rb

Overview

Data structure representing diff configuration Migrated from ace-git-diff

Constant Summary collapse

KNOWN_KEYS =

Known configuration keys

%w[
  exclude_patterns exclude_whitespace exclude_renames exclude_moves
  max_lines ranges paths since format timeout grouped_stats
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(exclude_patterns: [], exclude_whitespace: true, exclude_renames: false, exclude_moves: false, max_lines: 10_000, ranges: [], paths: [], since: nil, format: :diff, timeout: Ace::Git.git_timeout, grouped_stats_layers: %w[lib test handbook],, grouped_stats_collapse_above: 5, grouped_stats_show_full_tree: "collapsible", grouped_stats_dotfile_groups: %w[.ace-task .ace]) ⇒ DiffConfig

Returns a new instance of DiffConfig.

Parameters:

  • exclude_patterns (Array<String>) (defaults to: [])

    Glob patterns to exclude

  • exclude_whitespace (Boolean) (defaults to: true)

    Whether to exclude whitespace changes

  • exclude_renames (Boolean) (defaults to: false)

    Whether to exclude renames

  • exclude_moves (Boolean) (defaults to: false)

    Whether to exclude moves

  • max_lines (Integer) (defaults to: 10_000)

    Maximum lines in diff output

  • ranges (Array<String>) (defaults to: [])

    Git ranges to diff (e.g., [“origin/main…HEAD”])

  • paths (Array<String>) (defaults to: [])

    Path patterns to include

  • since (String) (defaults to: nil)

    Date or commit to diff from

  • format (Symbol) (defaults to: :diff)

    Output format (:diff or :summary)

  • timeout (Integer) (defaults to: Ace::Git.git_timeout)

    Command timeout in seconds (default from config)

  • grouped_stats_layers (Array<String>) (defaults to: %w[lib test handbook],)

    Layer order for grouped-stats output

  • grouped_stats_collapse_above (Integer) (defaults to: 5)

    Markdown collapse threshold

  • grouped_stats_show_full_tree (String) (defaults to: "collapsible")

    Tree rendering mode

  • grouped_stats_dotfile_groups (Array<String>) (defaults to: %w[.ace-task .ace])

    Dot directories to prioritize



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/ace/git/models/diff_config.rb', line 28

def initialize(
  exclude_patterns: [],
  exclude_whitespace: true,
  exclude_renames: false,
  exclude_moves: false,
  max_lines: 10_000,
  ranges: [],
  paths: [],
  since: nil,
  format: :diff,
  timeout: Ace::Git.git_timeout,
  grouped_stats_layers: %w[lib test handbook],
  grouped_stats_collapse_above: 5,
  grouped_stats_show_full_tree: "collapsible",
  grouped_stats_dotfile_groups: %w[.ace-task .ace]
)
  @exclude_patterns = Array(exclude_patterns)
  @exclude_whitespace = exclude_whitespace
  @exclude_renames = exclude_renames
  @exclude_moves = exclude_moves
  @max_lines = max_lines
  @ranges = Array(ranges)
  @paths = Array(paths)
  @since = since
  @format = format&.to_sym || :diff
  @timeout = timeout || Ace::Git.git_timeout
  @grouped_stats_layers = Array(grouped_stats_layers).map(&:to_s)
  @grouped_stats_collapse_above = grouped_stats_collapse_above.to_i
  @grouped_stats_show_full_tree = grouped_stats_show_full_tree.to_s
  @grouped_stats_dotfile_groups = Array(grouped_stats_dotfile_groups).map(&:to_s)
end

Instance Attribute Details

#exclude_movesObject (readonly)

Returns the value of attribute exclude_moves.



9
10
11
# File 'lib/ace/git/models/diff_config.rb', line 9

def exclude_moves
  @exclude_moves
end

#exclude_patternsObject (readonly)

Returns the value of attribute exclude_patterns.



9
10
11
# File 'lib/ace/git/models/diff_config.rb', line 9

def exclude_patterns
  @exclude_patterns
end

#exclude_renamesObject (readonly)

Returns the value of attribute exclude_renames.



9
10
11
# File 'lib/ace/git/models/diff_config.rb', line 9

def exclude_renames
  @exclude_renames
end

#exclude_whitespaceObject (readonly)

Returns the value of attribute exclude_whitespace.



9
10
11
# File 'lib/ace/git/models/diff_config.rb', line 9

def exclude_whitespace
  @exclude_whitespace
end

#formatObject (readonly)

Returns the value of attribute format.



9
10
11
# File 'lib/ace/git/models/diff_config.rb', line 9

def format
  @format
end

#grouped_stats_collapse_aboveObject (readonly)

Returns the value of attribute grouped_stats_collapse_above.



9
10
11
# File 'lib/ace/git/models/diff_config.rb', line 9

def grouped_stats_collapse_above
  @grouped_stats_collapse_above
end

#grouped_stats_dotfile_groupsObject (readonly)

Returns the value of attribute grouped_stats_dotfile_groups.



9
10
11
# File 'lib/ace/git/models/diff_config.rb', line 9

def grouped_stats_dotfile_groups
  @grouped_stats_dotfile_groups
end

#grouped_stats_layersObject (readonly)

Returns the value of attribute grouped_stats_layers.



9
10
11
# File 'lib/ace/git/models/diff_config.rb', line 9

def grouped_stats_layers
  @grouped_stats_layers
end

#grouped_stats_show_full_treeObject (readonly)

Returns the value of attribute grouped_stats_show_full_tree.



9
10
11
# File 'lib/ace/git/models/diff_config.rb', line 9

def grouped_stats_show_full_tree
  @grouped_stats_show_full_tree
end

#max_linesObject (readonly)

Returns the value of attribute max_lines.



9
10
11
# File 'lib/ace/git/models/diff_config.rb', line 9

def max_lines
  @max_lines
end

#pathsObject (readonly)

Returns the value of attribute paths.



9
10
11
# File 'lib/ace/git/models/diff_config.rb', line 9

def paths
  @paths
end

#rangesObject (readonly)

Returns the value of attribute ranges.



9
10
11
# File 'lib/ace/git/models/diff_config.rb', line 9

def ranges
  @ranges
end

#sinceObject (readonly)

Returns the value of attribute since.



9
10
11
# File 'lib/ace/git/models/diff_config.rb', line 9

def since
  @since
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



9
10
11
# File 'lib/ace/git/models/diff_config.rb', line 9

def timeout
  @timeout
end

Class Method Details

.from_hash(hash) ⇒ DiffConfig

Create DiffConfig from hash (e.g., from YAML config) Warns on unknown keys to help users catch typos

Parameters:

  • hash (Hash)

    Configuration hash

Returns:



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/ace/git/models/diff_config.rb', line 133

def self.from_hash(hash)
  return new if hash.nil? || hash.empty?

  # Warn about unknown keys to help catch typos
  warn_unknown_keys(hash)

  grouped_stats = hash["grouped_stats"] || hash[:grouped_stats] || {}

  new(
    exclude_patterns: hash["exclude_patterns"] || hash[:exclude_patterns] || [],
    exclude_whitespace: hash.fetch("exclude_whitespace", hash.fetch(:exclude_whitespace, true)),
    exclude_renames: hash.fetch("exclude_renames", hash.fetch(:exclude_renames, false)),
    exclude_moves: hash.fetch("exclude_moves", hash.fetch(:exclude_moves, false)),
    max_lines: hash.fetch("max_lines", hash.fetch(:max_lines, 10_000)),
    ranges: hash["ranges"] || hash[:ranges] || [],
    paths: hash["paths"] || hash[:paths] || [],
    since: hash["since"] || hash[:since],
    format: hash["format"] || hash[:format] || :diff,
    timeout: hash.fetch("timeout", hash.fetch(:timeout, Ace::Git.git_timeout)),
    grouped_stats_layers: grouped_stats["layers"] || grouped_stats[:layers] || %w[lib test handbook],
    grouped_stats_collapse_above: grouped_stats.fetch("collapse_above", grouped_stats.fetch(:collapse_above, 5)),
    grouped_stats_show_full_tree: grouped_stats["show_full_tree"] || grouped_stats[:show_full_tree] || "collapsible",
    grouped_stats_dotfile_groups: grouped_stats["dotfile_groups"] || grouped_stats[:dotfile_groups] || %w[.ace-task .ace]
  )
end

.warn_unknown_keys(hash) ⇒ Object

Warn about unknown configuration keys

Parameters:

  • hash (Hash)

    Configuration hash



161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/ace/git/models/diff_config.rb', line 161

def self.warn_unknown_keys(hash)
  return if hash.nil? || hash.empty?

  hash.each_key do |key|
    key_str = key.to_s
    next if KNOWN_KEYS.include?(key_str)
    # Skip nested sections that may be passed through
    next if %w[diff rebase pr squash default_branch remote verbose].include?(key_str)

    warn "[ace-git] Unknown config key '#{key_str}' in DiffConfig - did you mean one of: #{KNOWN_KEYS.join(", ")}?"
  end
end

Instance Method Details

#exclude_moves?Boolean

Check if diff should exclude moves

Returns:

  • (Boolean)

    True if moves should be excluded



74
75
76
# File 'lib/ace/git/models/diff_config.rb', line 74

def exclude_moves?
  @exclude_moves
end

#exclude_renames?Boolean

Check if diff should exclude renames

Returns:

  • (Boolean)

    True if renames should be excluded



68
69
70
# File 'lib/ace/git/models/diff_config.rb', line 68

def exclude_renames?
  @exclude_renames
end

#exclude_whitespace?Boolean

Check if diff should exclude whitespace changes

Returns:

  • (Boolean)

    True if whitespace should be excluded



62
63
64
# File 'lib/ace/git/models/diff_config.rb', line 62

def exclude_whitespace?
  @exclude_whitespace
end

#git_flagsArray<String>

Get git diff command flags based on configuration

Returns:

  • (Array<String>)

    Command flags



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/ace/git/models/diff_config.rb', line 80

def git_flags
  flags = []
  flags << "-w" if exclude_whitespace?
  # Use --diff-filter to exclude renames (R) and optionally moves
  # This is more explicit and avoids redundant flags
  # ACDMTUXB includes: Added, Copied, Deleted, Modified, Type, Unmerged, Unknown, Broken
  # When excluding moves, we also disable copy detection (C) as moves are detected as copy+delete
  if exclude_renames? && exclude_moves?
    # Exclude both renames (R) and copies (C) which covers moves
    flags << "--diff-filter=ADMTUXB"
    flags << "-M0" # Disable rename detection entirely
  elsif exclude_renames?
    flags << "--diff-filter=ACDMTUXB"
  elsif exclude_moves?
    # Moves appear as rename with 100% similarity, disable high-similarity renames
    flags << "-M0" # Disable rename detection (moves are renames at 100% similarity)
  end
  flags
end

#merge(other) ⇒ DiffConfig

Merge with another config (other takes precedence - complete override)

Parameters:

  • other (DiffConfig, Hash)

    Other config to merge

Returns:



177
178
179
180
181
# File 'lib/ace/git/models/diff_config.rb', line 177

def merge(other)
  other_hash = other.is_a?(DiffConfig) ? other.to_h : other

  self.class.from_hash(to_h.merge(other_hash))
end

#to_hHash

Convert to hash representation

Returns:

  • (Hash)

    Hash representation of the config



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/ace/git/models/diff_config.rb', line 102

def to_h
  {
    exclude_patterns: exclude_patterns,
    exclude_whitespace: exclude_whitespace?,
    exclude_renames: exclude_renames?,
    exclude_moves: exclude_moves?,
    max_lines: max_lines,
    ranges: ranges,
    paths: paths,
    since: since,
    format: format,
    timeout: timeout,
    grouped_stats: {
      layers: grouped_stats_layers,
      collapse_above: grouped_stats_collapse_above,
      show_full_tree: grouped_stats_show_full_tree,
      dotfile_groups: grouped_stats_dotfile_groups
    }
  }
end