class Doing::Change

A single version’s entries

Attributes

change_date[RW]
content[R]
entries[RW]
prefix[W]
version[R]

Public Class Methods

new(version, content, prefix: false, only: %i[changed new improved fixed]) click to toggle source
# File lib/doing/changelog/change.rb, line 12
def initialize(version, content, prefix: false, only: %i[changed new improved fixed])
  @version = Version.new(version)
  @content = content
  @prefix = prefix
  @only = only
  parse_entries
end

Public Instance Methods

changes_only() click to toggle source
# File lib/doing/changelog/change.rb, line 94
def changes_only
  out = []

  split_items.each do |type, members|
    next unless @only.include?(type)

    out << members.map(&:to_s).join("\n")
  end

  out.join("\n")
end
parse_entries() click to toggle source
# File lib/doing/changelog/change.rb, line 20
def parse_entries
  date = @content.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/)
  @change_date = Time.parse(date[0]) if date

  @entries = []
  types = @content.scan(/(?<=\n|\A)#### (CHANGED|NEW|IMPROVED|FIXED)(.*?)(?=\n####|\Z)/m)
  types.each do |type|
    type[1].scan(/\s*- +(.*?)$/).each do |entry|
      @entries << Entry.new(entry[0].strip, type[0], prefix: @prefix)
    end
  end
end
search_entries(search_string) click to toggle source
# File lib/doing/changelog/change.rb, line 33
def search_entries(search_string)
  case_type = :ignore

  matches = []

  if search_string.rx?
    matches = @entries.select { |e| e.string =~ search_string.to_rx(distance: 2, case_type: case_type) }
  else
    query = search_string.gsub(/(-)?--/, '\1]]').to_phrase_query

    if query[:must].nil? && query[:must_not].nil?
      query[:must] = query[:should]
      query[:should] = []
    end

    @entries.each do |entry|
      m = no_searches?(entry.string, query[:must_not])
      m &&= all_searches?(entry.string, query[:must])
      m &&= any_searches?(entry.string, query[:should])
      matches << entry if m
    end
  end

  @entries = matches.count.positive? ? matches : nil
end
split_items() click to toggle source
# File lib/doing/changelog/change.rb, line 63
def split_items
  items = { changed: [], new: [], improved: [], fixed: [], other: [] }

  @entries.each do |e|
    type = e.type.downcase.to_sym
    if items.key?(type)
      items[type] << e
    else
      items[:other] << e
    end
  end

  items
end
to_h() click to toggle source
# File lib/doing/changelog/change.rb, line 59
def to_h
  { version: @version, content: @content }
end
to_s() click to toggle source
# File lib/doing/changelog/change.rb, line 78
def to_s
  date = @change_date.nil? ? '' : " _(#{@change_date.strftime('%F')})_"
  out = ["### __#{@version}__#{date}"]

  split_items.each do |type, members|
    next unless @only.include?(type)

    if members.count.positive?
      out << "#### #{type.to_s.capitalize}"
      out << members.map(&:to_s).join("\n")
    end
  end

  out.join("\n\n")
end

Private Instance Methods

all_searches?(text, searches) click to toggle source
# File lib/doing/changelog/change.rb, line 108
def all_searches?(text, searches)
  return true if searches.nil? || searches.empty?

  searches.each do |s|
    rx = Regexp.new(s.wildcard_to_rx, true)
    return false unless text =~ rx
  end
  true
end
any_searches?(text, searches) click to toggle source
# File lib/doing/changelog/change.rb, line 128
def any_searches?(text, searches)
  return true if searches.nil? || searches.empty?

  searches.each do |s|
    rx = Regexp.new(s.wildcard_to_rx, true)
    return true if text =~ rx
  end
  false
end
no_searches?(text, searches) click to toggle source
# File lib/doing/changelog/change.rb, line 118
def no_searches?(text, searches)
  return true if searches.nil? || searches.empty?

  searches.each do |s|
    rx = Regexp.new(s.wildcard_to_rx, true)
    return false if text =~ rx
  end
  true
end