Class: OctocatalogDiff::CatalogDiff::Display::Text

Inherits:
OctocatalogDiff::CatalogDiff::Display show all
Defined in:
lib/octocatalog-diff/catalog-diff/display/text.rb

Overview

Display the output from a diff in text format. Uses the ‘diffy’ gem to provide diffs in blocks of text. Formats results in a logical Puppet output.

Constant Summary collapse

SEPARATOR =
'*******************************************'.freeze

Class Method Summary collapse

Methods inherited from OctocatalogDiff::CatalogDiff::Display

header, output, parse_diff_array_into_categorized_hashes, simple_deep_merge!

Class Method Details

._adjust_for_display_datatype(obj1, obj2, option, logger) ⇒ <String, String> or <?, ?>

Utility Method! Called by adjust_for_display_datatype_changes to compare an old value to a new value and adjust as appropriate.

Parameters:

  • obj1 (?)

    First object

  • obj2 (?)

    Second object

  • option (Boolean)

    Selected behavior; see adjust_for_display_datatype_changes

Returns:

  • (<String, String> or <?, ?>)

    Updated values of objects



510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 510

def self._adjust_for_display_datatype(obj1, obj2, option, logger)
  # If not string-equal, return to leave untouched
  return [obj1, obj2] unless obj1.to_s == obj2.to_s

  # Delete if option to display these is false
  return [nil, nil] unless option

  # Delete if both objects are nil
  return [nil, nil] if obj1.nil? && obj2.nil?

  # If one is nil and the other is the empty string...
  return ['undef', '""'] if obj1.nil?
  return ['""', 'undef'] if obj2.nil?

  # If one is an integer and the other is a string
  return [obj1, "\"#{obj2}\""] if obj1.is_a?(Integer) && obj2.is_a?(String)
  return ["\"#{obj1}\"", obj2] if obj1.is_a?(String) && obj2.is_a?(Integer)

  # True and false
  return [obj1, "\"#{obj2}\""] if obj1.is_a?(TrueClass) && obj2.is_a?(String)
  return [obj1, "\"#{obj2}\""] if obj1.is_a?(FalseClass) && obj2.is_a?(String)
  return ["\"#{obj1}\"", obj2] if obj1.is_a?(String) && obj2.is_a?(TrueClass)
  return ["\"#{obj1}\"", obj2] if obj1.is_a?(String) && obj2.is_a?(FalseClass)

  # Unhandled case - warn about it and then return inputs untouched
  # Note: If you encounter this, please report it so we can add a handler.
  # :nocov:
  msg = "In _adjust_for_display_datatype, objects '#{obj1.inspect}' (#{obj1.class}) and"\
        " '#{obj2.inspect}' (#{obj2.class}) have identical string representations but"\
        ' formatting is not implemented to update display.'
  logger.warn(msg) if logger
  [obj1, obj2]
  # :nocov:
end

.add_source_file_line_info(opts = {}) ⇒ Object

Generate info about the source of the change. Pass in parameters as a hash with indicated names.

Parameters:

  • item (Hash)

    Item that is added/removed/changed

  • result (Array)

    Result array (modified by this method)

  • old_loc (Hash)

    Old location hash { file => …, line => … }

  • new_loc (Hash)

    New location hash { file => …, line => … }

  • options (Hash)

    Options hash

  • logger (Logger)

    Logger object



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 201

def self.add_source_file_line_info(opts = {})
  item = opts.fetch(:item)
  result = opts.fetch(:result)
  old_loc = opts[:old_loc]
  new_loc = opts[:new_loc]
  options = opts.fetch(:options, {})
  logger = opts[:logger]

  # Initialize any currently undefined settings
  empty_hash = { 'file' => nil, 'line' => nil }
  old_loc ||= empty_hash
  new_loc ||= empty_hash
  return if old_loc == empty_hash && new_loc == empty_hash

  # Convert old_loc and new_loc to strings
  old_loc_string = loc_string(old_loc, options[:compilation_from_dir], logger)
  new_loc_string = loc_string(new_loc, options[:compilation_to_dir], logger)

  # Debug log information and build up local_result with printable changes
  local_result = []
  if old_loc == new_loc || new_loc == empty_hash || old_loc_string == new_loc_string
    logger.debug "#{item} @ #{old_loc_string || 'nil'}" if logger
    local_result << "  #{old_loc_string}".cyan unless old_loc_string.nil?
  elsif old_loc == empty_hash
    logger.debug "#{item} @ #{new_loc_string || 'nil'}" if logger
    local_result << "  #{new_loc_string}".cyan unless new_loc_string.nil?
  else
    logger.debug "#{item} -@ #{old_loc_string} +@ #{new_loc_string}" if logger
    local_result << "- #{old_loc_string}".cyan
    local_result << "+ #{new_loc_string}".cyan
  end

  # Only modify result if option to display source file and line is enabled
  result.concat local_result if options[:display_source_file_line]
end

.add_trailing_newlines(string_1, string_2) ⇒ Array<String>

Add “n” to the end of both strings, only if both strings are lacking it. This prevents “\ No newline at end of file” for single string comparison.

Parameters:

  • string_1 (String)

    First string

  • string_2 (String)

    Second string

Returns:

  • (Array<String>)

    Adjusted string_1, string_2



291
292
293
294
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 291

def self.add_trailing_newlines(string_1, string_2)
  return [string_1, string_2] unless string_1 !~ /\n\Z/ && string_2 !~ /\n\Z/
  [string_1 + "\n", string_2 + "\n"]
end

.addition_only_no_truncation(depth, hash) ⇒ Array<String>

Special case: addition only, no truncation

Parameters:

  • depth (Integer)

    Depth, for correct indentation

  • hash (Hash)

    Added object

Returns:

  • (Array<String>)

    Displayable result



365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 365

def self.addition_only_no_truncation(depth, hash)
  result = []

  # Single line strings
  hash.keys.sort.map do |key|
    next if hash[key] =~ /\n/
    result << left_pad(2 * depth + 4, [key.inspect, ': ', hash[key].inspect].join('')).green
  end

  # Multi-line strings
  hash.keys.sort.map do |key|
    next if hash[key] !~ /\n/
    result << left_pad(2 * depth + 4, [key.inspect, ': >>>'].join('')).green
    result.concat hash[key].split(/\n/).map(&:green)
    result << '<<<'.green
  end

  result
end

.adjust_for_display_datatype_changes(diff, option, logger = nil) ⇒ Object

Utility Method! Implement the –display-datatype-changes option by:

  • Removing string-equivalent differences when option == false

  • Updating display of string-equivalent differences when option == true

Parameters:

  • diff (Array<Diff Objects>)

    Difference array

  • option (Boolean)

    Selected behavior; see description

  • logger (Logger) (defaults to: nil)

    Logger object



471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 471

def self.adjust_for_display_datatype_changes(diff, option, logger = nil)
  diff.map! do |diff_obj|
    if diff_obj[0] == '+' || diff_obj[0] == '-'
      diff_obj[2] = 'undef' if diff_obj[2].nil?
      diff_obj
    else
      x2, x3 = _adjust_for_display_datatype(diff_obj[2], diff_obj[3], option, logger)
      if x2.nil? && x3.nil?
        # Delete this! Return nil and compact! will get rid of them.
        msg = "Adjust display for #{diff_obj[1].gsub(/\f/, '::')}: " \
              "#{diff_obj[2].inspect} != #{diff_obj[3].inspect} DELETED"
        logger.debug(msg) if logger
        nil
      elsif x2 == diff_obj[2] && x3 == diff_obj[3]
        # Neither object changed
        diff_obj
      else
        # Adjust the display and return modified object
        msg = "Adjust display for #{diff_obj[1].gsub(/\f/, '::')}: " \
              "old=#{x2.inspect} new=#{x3.inspect} "\
              "(extra debugging: #{diff_obj[2].inspect} -> #{x2}; "\
              "#{diff_obj[3].inspect} -> #{x3})"
        logger.debug(msg) if logger
        diff_obj[2] = x2
        diff_obj[3] = x3
        diff_obj
      end
    end
  end
  diff.compact!
end

.adjust_position_of_plus_minus(string_in) ⇒ String

Adjust the space after of the ‘-` / `+` in the diff for single line diffs. Diffy prints diffs with no space between the `-` / `+` in the text, but for single lines it’s easier to read with that space added.

Parameters:

  • string_in (String)

    Input string, which is a line of a diff from diffy

Returns:

  • (String)

    Modified string



301
302
303
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 301

def self.adjust_position_of_plus_minus(string_in)
  string_in.sub(/\A(\e\[\d+m)?([\-\+])/, '\1\2 ')
end

.class_name_for_diffy(class_name) ⇒ String

Utility Method! Harmonize equivalent class names for comparison purposes.

Parameters:

  • class_name (String)

    Class name as input

Returns:

  • (String)

    Class name as output



446
447
448
449
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 446

def self.class_name_for_diffy(class_name)
  return 'Integer' if class_name == 'Fixnum'
  class_name
end

.diff_at_depth(depth, old_obj, new_obj) ⇒ Object

Get the diff between two arbitrary objects

Parameters:

  • depth (Integer)

    Depth of nesting, used for indentation

  • old_obj (?)

    Old object

  • new_obj (?)

    New object



425
426
427
428
429
430
431
432
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 425

def self.diff_at_depth(depth, old_obj, new_obj)
  old_s = old_obj.to_s
  new_s = new_obj.to_s
  result = []
  result << left_pad(2 * depth + 2, "- #{old_s}").red unless old_s == ''
  result << left_pad(2 * depth + 2, "+ #{new_s}").green unless new_s == ''
  result
end

.diff_two_hashes_with_diffy(opts = {}) ⇒ Array<String>

Get the diff of two hashes. Call the ‘diffy’ gem for this.

Parameters:

  • hash1 (Hash)

    First hash (-)

  • hash1 (Hash)

    Second hash (+)

  • depth (Integer)

    Depth, for correct indentation

  • limit (Integer)

    Maximum string length

  • strip_diff (Boolean)

    Strip leading +/-/“ ”

Returns:

  • (Array<String>)

    Displayable result



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 332

def self.diff_two_hashes_with_diffy(opts = {})
  depth = opts.fetch(:depth, 0)
  hash1 = opts.fetch(:hash1, {})
  hash2 = opts.fetch(:hash2, {})
  limit = opts[:limit]
  strip_diff = opts.fetch(:strip_diff, false)

  # Special case: addition only, no truncation
  return addition_only_no_truncation(depth, hash2) if hash1 == {} && limit.nil?

  json_old = stringify_for_diffy(hash1)
  json_new = stringify_for_diffy(hash2)

  # If stripping the diff, we need to make sure diffy does not colorize the output, so that
  # there are not color codes in the output to deal with.
  diff = if strip_diff
    Diffy::Diff.new(json_old, json_new, context: 0).to_s(:text).split("\n")
  else
    Diffy::Diff.new(json_old, json_new, context: 0).to_s.split("\n")
  end
  raise "Diffy diff empty for string: #{json_old}" if diff.empty?

  # This is the array that is returned
  diff.map do |x|
    x = x[2..-1] if strip_diff # Drop first 2 characters: '+ ', '- ', or '  '
    truncate_string(left_pad(2 * depth + 2, x), limit)
  end
end

.diff_two_strings_with_diffy(string1, string2, depth) ⇒ Object

Get the diff of two long strings. Call the ‘diffy’ gem for this.

Parameters:

  • string1 (String)

    First string (-)

  • string2 (String)

    Second string (+)

  • depth (Integer)

    Depth, for correct indentation



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 261

def self.diff_two_strings_with_diffy(string1, string2, depth)
  # Single line strings?
  if single_lines?(string1, string2)
    string1, string2 = add_trailing_newlines(string1, string2)
    diff = Diffy::Diff.new(string1, string2, context: 2, include_diff_info: false).to_s.split("\n")
    return diff.map { |x| left_pad(2 * depth + 2, make_trailing_whitespace_visible(adjust_position_of_plus_minus(x))) }
  end

  # Multiple line strings
  string1, string2 = add_trailing_newlines(string1, string2)
  diff = Diffy::Diff.new(string1, string2, context: 2, include_diff_info: true).to_s.split("\n")
  diff.shift # Remove first line of diff info (filename that makes no sense)
  diff.shift # Remove second line of diff info (filename that makes no sense)
  diff.map { |x| left_pad(2 * depth + 2, make_trailing_whitespace_visible(x)) }
end

.display_added_item(opts = {}) ⇒ Array

Display an added item

Parameters:

  • item (String)

    Item (type+title) that has changed

  • new_loc (Hash)

    File and line number of location in “to” catalog

  • diff (Hash)

    Difference hash

  • options (Hash)

    Display options

  • logger (Logger)

    Logger object

Returns:

  • (Array)

    Lines of text



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 162

def self.display_added_item(opts = {})
  item = opts.fetch(:item)
  new_loc = opts.fetch(:new_loc)
  diff = opts.fetch(:diff)
  options = opts.fetch(:options)
  logger = opts[:logger]

  result = []
  add_source_file_line_info(item: item, result: result, new_loc: new_loc, options: options, logger: logger)
  if options[:display_detail_add] && diff.key?('parameters')
    limit = options.fetch(:truncate_details, true) ? 80 : nil
    result << "+ #{item} =>".green
    result << '   parameters =>'.green
    result.concat(
      diff_two_hashes_with_diffy(
        depth: 1,
        hash2: Hash[diff['parameters'].sort], # Should work with somewhat older rubies too
        limit: limit,
        strip_diff: true
      ).map(&:green)
    )
  else
    result << "+ #{item}".green
    if diff.key?('parameters') && logger && !options[:display_detail_add_notice_printed]
      logger.info 'Note: you can use --display-detail-add to view details of added resources'
      options[:display_detail_add_notice_printed] = true
    end
  end

  result
end

.display_changed_or_nested_item(opts = {}) ⇒ Array

Display a changed or nested item

Parameters:

  • item (String)

    Item (type+title) that has changed

  • old_loc (Hash)

    File and line number of location in “from” catalog

  • new_loc (Hash)

    File and line number of location in “to” catalog

  • diff (Hash)

    Difference hash

  • options (Hash)

    Display options

  • logger (Logger)

    Logger object

Returns:

  • (Array)

    Lines of text



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 122

def self.display_changed_or_nested_item(opts = {})
  item = opts.fetch(:item)
  old_loc = opts.fetch(:old_loc)
  new_loc = opts.fetch(:new_loc)
  diff = opts.fetch(:diff)
  options = opts.fetch(:options)
  logger = opts[:logger]

  result = []
  info_hash = { item: item, result: result, old_loc: old_loc, new_loc: new_loc, options: options, logger: logger }
  add_source_file_line_info(info_hash)
  result << "  #{item} =>"
  diff.keys.sort.each { |key| result.concat hash_diff(diff[key], 1, key, true) }
  result
end

.display_removed_item(opts = {}) ⇒ Array

Display a removed item

Parameters:

  • item (String)

    Item (type+title) that has changed

  • old_loc (Hash)

    File and line number of location in “from” catalog

  • options (Hash)

    Display options

  • logger (Logger)

    Logger object

Returns:

  • (Array)

    Lines of text



144
145
146
147
148
149
150
151
152
153
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 144

def self.display_removed_item(opts = {})
  item = opts.fetch(:item)
  old_loc = opts.fetch(:old_loc)
  options = opts.fetch(:options)
  logger = opts[:logger]

  result = []
  add_source_file_line_info(item: item, result: result, old_loc: old_loc, options: options, logger: logger)
  result << "- #{item}".red
end

.generate(diff, options_in = {}, logger = nil) ⇒ Array<String>

Generate the text representation of the ‘diff’ suitable for rendering in a console or log.

Parameters:

  • diff (Array<Diff results>)

    The diff which must be in this format

  • options_in (Hash) (defaults to: {})

    Options which are:

    • :color => [Boolean] True or false, whether to use color codes

    • :header => [String] Header to print; no header is printed if not specified

    • :display_source_file_line [Boolean] True or false, print filename and line (if known)

    • :display_detail_add [Boolean] If true, print details of any added resources

  • logger (Logger) (defaults to: nil)

    Logger object

Returns:



27
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 27

def self.generate(diff, options_in = {}, logger = nil)
  # Empty?
  return [] if diff.empty?

  # We may modify this for temporary local use, but don't want to pass these changes
  # back to the rest of the program.
  options = options_in.dup

  # Enable color support if requested...
  String.colors_enabled = options.fetch(:color, true)

  previous_diffy_default_format = Diffy::Diff.default_format
  Diffy::Diff.default_format = options.fetch(:color, true) ? :color : :text

  # Strip out differences or update display where string matches but data type differs.
  # For example, 28 (the integer) and "28" (the string) have identical string
  # representations, but are different data types. Same for nil vs. "".
  adjust_for_display_datatype_changes(diff, options[:display_datatype_changes], logger)

  # Call the utility method to sort changes into their respective types
  only_in_new, only_in_old, changed = parse_diff_array_into_categorized_hashes(diff)
  sorted_list = only_in_old.keys | only_in_new.keys | changed.keys
  sorted_list.sort!
  unless logger.nil?
    logger.debug "Added resources: #{only_in_new.keys.count}"
    logger.debug "Removed resources: #{only_in_old.keys.count}"
    logger.debug "Changed resources: #{changed.keys.count}"
  end

  # Run through the list to build the result
  result = []
  sorted_list.each do |item|
    # Print the header if needed
    unless options[:header].nil?
      result << options[:header] unless options[:header].empty?
      result << SEPARATOR
      options[:header] = nil
    end

    # A removed item appears only in the old hash.
    if only_in_old.key?(item)
      result.concat display_removed_item(
        item: item,
        old_loc: only_in_old[item][:loc],
        options: options,
        logger: logger
      )

    # An added item appears only in the new hash.
    elsif only_in_new.key?(item)
      result.concat display_added_item(
        item: item,
        new_loc: only_in_new[item][:loc],
        diff: only_in_new[item][:diff],
        options: options,
        logger: logger
      )

    # A change can appear either in the change hash, the nested hash, or both.
    # Therefore, changes and nested changes are combined for display.
    elsif changed.key?(item)
      result.concat display_changed_or_nested_item(
        item: item,
        old_loc: changed[item][:old_loc],
        new_loc: changed[item][:new_loc],
        diff: changed[item][:diff],
        options: options,
        logger: logger
      )

    # An unrecognized change throws an error. This indicates a bug.
    else
      # :nocov:
      raise "BUG (please report): Unable to determine diff type of item: #{item.inspect}"
      # :nocov:
    end
    result << SEPARATOR
  end

  # Reset the global color-related flags
  String.colors_enabled = false
  Diffy::Diff.default_format = previous_diffy_default_format

  # The end
  result
end

.hash_diff(obj, depth, key_in, nested = false) ⇒ Object

Get the diff between two hashes. This is recursive-aware.

Parameters:

  • obj (diff object)

    diff object

  • depth (Integer)

    Depth of nesting, used for indentation



398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 398

def self.hash_diff(obj, depth, key_in, nested = false)
  result = []
  result << left_pad(2 * depth, " #{key_in} =>")
  if obj.key?(:old) && obj.key?(:new)
    if nested && obj[:old].is_a?(Hash) && obj[:new].is_a?(Hash)
      # Nested hashes will be stringified and then use 'diffy'
      result.concat diff_two_hashes_with_diffy(depth: depth, hash1: obj[:old], hash2: obj[:new])
    elsif obj[:old].is_a?(String) && obj[:new].is_a?(String)
      # Strings will use 'diffy' to mimic the output seen when using
      # "diff" on the command line.
      result.concat diff_two_strings_with_diffy(obj[:old], obj[:new], depth)
    else
      # Stuff we don't recognize will be converted to a string and printed
      # with '+' and '-' unless the object resolves to an empty string.
      result.concat diff_at_depth(depth, obj[:old], obj[:new])
    end
  else
    obj.keys.sort.each { |key| result.concat hash_diff(obj[key], 1 + depth, key, nested) }
  end
  result
end

.left_pad(spaces, text = '') ⇒ Object

Utility Method! Indent a given text string with a certain number of spaces

Parameters:

  • spaces (Integer)

    Number of spaces

  • text (String) (defaults to: '')

    Text



438
439
440
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 438

def self.left_pad(spaces, text = '')
  [' ' * spaces, text].join('')
end

.loc_string(loc, compilation_dir, logger) ⇒ String

Convert { file => …, line => … } to displayable string

Parameters:

  • loc (Hash)

    file => …, line => … hash

  • compilation_dir (String)

    Compilation directory

  • logger (Logger)

    Logger object

Returns:

  • (String)

    Location string



242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 242

def self.loc_string(loc, compilation_dir, logger)
  return nil if loc.nil? || !loc.is_a?(Hash) || loc['file'].nil? || loc['line'].nil?
  result = "#{loc['file']}:#{loc['line']}"
  if compilation_dir
    rex = Regexp.new('^' + Regexp.escape(compilation_dir + '/'))
    result_new = result.sub(rex, '')
    if result_new != result
      logger.debug "Removed compilation directory in #{result} -> #{result_new}" if logger
      result = result_new
    end
  end
  result
end

.make_trailing_whitespace_visible(string_in) ⇒ String

Convert trailing whitespace to underscore for display purposes. Also convert special whitespace (r, n, t, …) to character representation.

Parameters:

  • string_in (String)

    Input string, which might contain trailing whitespace

Returns:

  • (String)

    Modified string



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 309

def self.make_trailing_whitespace_visible(string_in)
  return string_in unless string_in =~ /\A((?:.|\n){1,1000}?)(\s+)(\e\[0m)?\Z/
  beginning = Regexp.last_match(1)
  trailing_space = Regexp.last_match(2)
  end_escape = Regexp.last_match(3)

  # Trailing space adjustment for line endings
  trailing_space.gsub! "\n", '\n'
  trailing_space.gsub! "\r", '\r'
  trailing_space.gsub! "\t", '\t'
  trailing_space.gsub! "\f", '\f'
  trailing_space.tr! ' ', '_'

  [beginning, trailing_space, end_escape].join('')
end

.single_lines?(string_1, string_2) ⇒ Boolean

Determine if two incoming strings are single lines. Returns true if both incoming strings are single lines, false otherwise.

Parameters:

  • string_1 (String)

    First string

  • string_2 (String)

    Second string

Returns:

  • (Boolean)

    Whether both incoming strings are single lines



282
283
284
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 282

def self.single_lines?(string_1, string_2)
  string_1.strip !~ /\n/ && string_2.strip !~ /\n/
end

.stringify_for_diffy(obj) ⇒ String

Utility Method! Given an arbitrary object, convert it into a string for use by ‘diffy’. This basically exists so we can do something prettier than just calling .inspect or .to_s on object types we anticipate seeing, while not failing entirely on other object types.

Parameters:

  • obj (?)

    Object to be stringified

Returns:

  • (String)

    String representation of object for diffy



457
458
459
460
461
462
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 457

def self.stringify_for_diffy(obj)
  return JSON.pretty_generate(obj) if OctocatalogDiff::Util::Util.object_is_any_of?(obj, [Hash, Array])
  return '""' if obj.is_a?(String) && obj == ''
  return obj if OctocatalogDiff::Util::Util.object_is_any_of?(obj, [String, Integer, Float])
  "#{class_name_for_diffy(obj.class)}: #{obj.inspect}"
end

.truncate_string(str, limit) ⇒ String

Limit length of a string

Parameters:

  • str (String)

    String

  • limit (Integer)

    Limit (0=unlimited)

Returns:

  • (String)

    Truncated string



389
390
391
392
# File 'lib/octocatalog-diff/catalog-diff/display/text.rb', line 389

def self.truncate_string(str, limit)
  return str if limit.nil? || str.length <= limit
  "#{str[0..limit]}..."
end