diff --git a/lib/github_changelog_generator/parser_file.rb b/lib/github_changelog_generator/parser_file.rb
index 40c2498..d08ddfe 100644
--- a/lib/github_changelog_generator/parser_file.rb
+++ b/lib/github_changelog_generator/parser_file.rb
@@ -3,29 +3,48 @@ require "pathname"
module GitHubChangelogGenerator
ParserError = Class.new(StandardError)
+ # ParserFile is a configuration file reader which sets options in the
+ # given Hash.
+ #
+ # In your project's root, you can put a file named
+ # .github_changelog_generator to override defaults:
+ #
+ # Example:
+ # header_label=# My Super Changelog
+ # future-release=5.0.0
+ # since-tag=1.0.0
+ #
+ # The configuration format is some-key=value or some_key=value.
+ #
class ParserFile
- FILENAME = ".github_changelog_generator"
-
- def initialize(options)
+ # @param options [Hash] options to be configured from file contents
+ # @param file [nil,IO] configuration file handle, defaults to opening `.github_changelog_generator`
+ def initialize(options, file = open_settings_file)
@options = options
+ @file = file
end
- # Destructively change @options using data in configured options file.
+ # Sets options using configuration file content
def parse!
- file.each_line { |line| parse_line!(line) } if file.exist?
+ return unless @file
+ @file.each_with_index { |line, i| parse_line!(line, i + 1) }
+ @file.close
end
private
- def file
- @file ||= Pathname(File.expand_path(@options[:params_file] || FILENAME))
+ FILENAME = ".github_changelog_generator"
+
+ def open_settings_file
+ path = Pathname(File.expand_path(FILENAME))
+ File.open(path) if path.exist?
end
- def parse_line!(line)
+ def parse_line!(line, line_number)
option_name, value = extract_pair(line)
@options[option_key_for(option_name)] = convert_value(value, option_name)
rescue
- raise ParserError, "Config file #{file} is incorrect in line \"#{line.gsub(/[\n\r]+/, '')}\""
+ raise ParserError, "Failed on line ##{line_number}: \"#{line.gsub(/[\n\r]+/, '')}\""
end
# Returns a the option name as a symbol and its string value sans newlines.
diff --git a/spec/files/github_changelog_params_327 b/spec/files/github_changelog_params_327
deleted file mode 100644
index 2506a61..0000000
--- a/spec/files/github_changelog_params_327
+++ /dev/null
@@ -1,2 +0,0 @@
-exclude-labels=73a91042-da6f-11e5-9335-1040f38d7f90,7adf83b4-da6f-11e5-ae18-1040f38d7f90
-header_label=# My changelog
diff --git a/spec/files/github_changelog_params_empty b/spec/files/github_changelog_params_empty
deleted file mode 100644
index e69de29..0000000
diff --git a/spec/files/github_changelog_params_incorrect b/spec/files/github_changelog_params_incorrect
deleted file mode 100644
index 35fa3d8..0000000
--- a/spec/files/github_changelog_params_incorrect
+++ /dev/null
@@ -1,2 +0,0 @@
-unreleased_label: staging
-unreleased: false
diff --git a/spec/files/github_changelog_params_override b/spec/files/github_changelog_params_override
deleted file mode 100644
index c31e411..0000000
--- a/spec/files/github_changelog_params_override
+++ /dev/null
@@ -1,3 +0,0 @@
-unreleased_label=staging
-unreleased=false
-header==== Changelog ===
diff --git a/spec/unit/parse_file_spec.rb b/spec/unit/parse_file_spec.rb
index 2e4f1a6..735f32e 100644
--- a/spec/unit/parse_file_spec.rb
+++ b/spec/unit/parse_file_spec.rb
@@ -2,35 +2,39 @@ describe GitHubChangelogGenerator::ParserFile do
describe ".github_changelog_generator" do
context "when no has file" do
let(:options) { {} }
- let(:parse) { GitHubChangelogGenerator::ParserFile.new(options) }
- subject { parse.parse! }
+ let(:parser) { GitHubChangelogGenerator::ParserFile.new(options) }
+ subject { parser.parse! }
it { is_expected.to be_nil }
end
context "when file is empty" do
- let(:options) { { params_file: "spec/files/github_changelog_params_empty" } }
- let(:parse) { GitHubChangelogGenerator::ParserFile.new(options) }
+ let(:options) { {} }
+ let(:parser) { GitHubChangelogGenerator::ParserFile.new(options, StringIO.new("")) }
it "does not change the options" do
- expect { parse.parse! }.to_not change { options }
+ expect { parser.parse! }.to_not change { options }
end
end
context "when file is incorrect" do
- let(:options) { { params_file: "spec/files/github_changelog_params_incorrect" } }
+ let(:options) { {} }
let(:options_before_change) { options.dup }
- let(:parse) { GitHubChangelogGenerator::ParserFile.new(options) }
- it { expect { parse.parse! }.to raise_error(GitHubChangelogGenerator::ParserError) }
+ let(:file) { StringIO.new("unreleased_label=staging\nunreleased: false") }
+ let(:parser) do
+ GitHubChangelogGenerator::ParserFile.new(options, file)
+ end
+ it { expect { parser.parse! }.to raise_error(/line #2/) }
end
context "when override default values" do
let(:default_options) { GitHubChangelogGenerator::Parser.default_options }
- let(:options) { { params_file: "spec/files/github_changelog_params_override" }.merge(default_options) }
+ let(:options) { {}.merge(default_options) }
let(:options_before_change) { options.dup }
- let(:parse) { GitHubChangelogGenerator::ParserFile.new(options) }
+ let(:file) { StringIO.new("unreleased_label=staging\nunreleased=false\nheader==== Changelog ===") }
+ let(:parser) { GitHubChangelogGenerator::ParserFile.new(options, file) }
it "changes the options" do
- expect { parse.parse! }.to change { options }
+ expect { parser.parse! }.to change { options }
.from(options_before_change)
.to(options_before_change.merge(unreleased_label: "staging",
unreleased: false,
@@ -38,21 +42,22 @@ describe GitHubChangelogGenerator::ParserFile do
end
context "turns exclude-labels into an Array", bug: '#327' do
- let(:options) do
- {
- params_file: "spec/files/github_changelog_params_327"
- }
+ let(:file) do
+ StringIO.new(<