Class: Factorix::Changelog

Inherits:
Object
  • Object
show all
Defined in:
lib/factorix/changelog.rb

Overview

Parser and writer for Factorio MOD changelog.txt files

Defined Under Namespace

Classes: Section

Constant Summary collapse

SEPARATOR =
("-" * 99).freeze
UNRELEASED =
"Unreleased"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sections) ⇒ Changelog

Returns a new instance of Changelog.

Parameters:

  • sections (Array<Section>)

    changelog sections



44
45
46
# File 'lib/factorix/changelog.rb', line 44

def initialize(sections)
  @sections = sections
end

Instance Attribute Details

#sectionsArray<Section> (readonly)

Returns:



49
50
51
# File 'lib/factorix/changelog.rb', line 49

def sections
  @sections
end

Class Method Details

.load(path) ⇒ Changelog

Load a changelog from a file

Parameters:

  • path (Pathname)

    path to changelog.txt

Returns:

Raises:



24
25
26
27
28
# File 'lib/factorix/changelog.rb', line 24

def self.load(path)
  return new([]) unless path.exist?

  parse(path.read)
end

.parse(text) ⇒ Changelog

Parse changelog text content

Parameters:

  • text (String)

    changelog content

Returns:

Raises:



35
36
37
38
39
40
41
# File 'lib/factorix/changelog.rb', line 35

def self.parse(text)
  tree = Grammar.new.parse(text)
  sections = Transform.new.apply(tree)
  new(Array(sections))
rescue Parslet::ParseFailed => e
  raise ChangelogParseError, e.message
end

Instance Method Details

#add_entry(version, category, entry) ⇒ void

This method returns an undefined value.

Add an entry to the changelog

Parameters:

  • version (MODVersion, String)

    target version (or Changelog::UNRELEASED)

  • category (String)

    category name

  • entry (String)

    entry text

Raises:



66
67
68
69
70
71
72
73
74
# File 'lib/factorix/changelog.rb', line 66

def add_entry(version, category, entry)
  raise InvalidArgumentError, "entry must not be blank" if entry.match?(/\A[[:space:]]*\z/)

  section = find_or_create_section(version)
  entries = (section.categories[category] ||= [])
  raise InvalidArgumentError, "duplicate entry: #{entry}" if entries.include?(entry)

  entries << entry
end

#find_section(version) ⇒ Section

Find a section by version

Parameters:

  • version (MODVersion, String)

    target version (or Changelog::UNRELEASED)

Returns:

Raises:



100
101
102
# File 'lib/factorix/changelog.rb', line 100

def find_section(version)
  @sections.find {|s| s.version == version } or raise InvalidArgumentError, "version not found: #{version}"
end

#format_section(section) ⇒ String

Format a section as plain text (without separator line)

Parameters:

  • section (Section)

    changelog section

Returns:

  • (String)


108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/factorix/changelog.rb', line 108

def format_section(section)
  lines = []
  lines << "Version: #{section.version}"
  lines << "Date: #{section.date}" if section.date
  section.categories.each do |cat, entries|
    lines << "  #{cat}:"
    entries.each do |entry|
      first, *rest = entry.split("\n")
      lines << "    - #{first}"
      rest.each {|line| lines << "      #{line}" }
    end
  end
  lines.join("\n")
end

#release_section(version, date:) ⇒ void

This method returns an undefined value.

Replace the first section (Unreleased) with a versioned section

Parameters:

  • version (MODVersion)

    target version

  • date (String)

    release date (YYYY-MM-DD)

Raises:



80
81
82
83
84
85
86
# File 'lib/factorix/changelog.rb', line 80

def release_section(version, date:)
  raise InvalidOperationError, "First section is not Unreleased" unless @sections.first&.version == UNRELEASED
  raise InvalidOperationError, "Version #{version} already exists" if @sections.any? {|s| s.version == version }

  unreleased = @sections.first
  @sections[0] = Section[version:, date:, categories: unreleased.categories]
end

#save(path) ⇒ void

This method returns an undefined value.

Save the changelog to a file

Parameters:

  • path (Pathname)

    path to write



55
56
57
# File 'lib/factorix/changelog.rb', line 55

def save(path)
  path.write(to_s)
end

#to_sString

Render the changelog as a string

Returns:

  • (String)


91
92
93
# File 'lib/factorix/changelog.rb', line 91

def to_s
  @sections.map {|section| "#{SEPARATOR}\n#{format_section(section)}" }.join("\n") + "\n"
end