From ee5a507f76c9be093471310997a78a9beb67a61d Mon Sep 17 00:00:00 2001 From: Tom Duffield Date: Sat, 19 Nov 2016 19:33:38 -0600 Subject: [PATCH] Filter excluded tags within the section map builder Because we need might need excluded tags to build compare links, the section map generator needs to have access to those tags. But, we don't want excluded tags to have section headers. So instead, we'll create another copy of the list that doesn't have tags excluded. Signed-off-by: Tom Duffield --- .../generator/generator_tags.rb | 34 ++++++++----- spec/unit/generator/generator_tags_spec.rb | 48 +++++++++++++++++-- 2 files changed, 66 insertions(+), 16 deletions(-) diff --git a/lib/github_changelog_generator/generator/generator_tags.rb b/lib/github_changelog_generator/generator/generator_tags.rb index 51d0c2b..9c8fd9d 100644 --- a/lib/github_changelog_generator/generator/generator_tags.rb +++ b/lib/github_changelog_generator/generator/generator_tags.rb @@ -7,35 +7,43 @@ module GitHubChangelogGenerator detect_since_tag detect_due_tag - all_tags = @fetcher.get_all_tags - included_tags = filter_excluded_tags(all_tags) - + all_tags = @fetcher.get_all_tags fetch_tags_dates(all_tags) # Creates a Hash @tag_times_hash - @sorted_tags = sort_tags_by_date(included_tags) - @filtered_tags = get_filtered_tags(included_tags) + all_sorted_tags = sort_tags_by_date(all_tags) - @tag_section_mapping = build_tag_section_mapping(@filtered_tags, sorted_tags) + @sorted_tags = filter_excluded_tags(all_sorted_tags) + @filtered_tags = get_filtered_tags(@sorted_tags) + + # Because we need to properly create compare links, we need a sorted list + # of all filtered tags (including the excluded ones). We'll exclude those + # tags from section headers inside the mapping function. + section_tags = get_filtered_tags(all_sorted_tags) + + @tag_section_mapping = build_tag_section_mapping(section_tags, @filtered_tags) @filtered_tags end - # @param [Array] filtered_tags are the tags that need a subsection output - # @param [Array] all_tags is the list of all tags ordered from newest -> oldest + # @param [Array] section_tags are the tags that need a subsection output + # @param [Array] filtered_tags is the list of filtered tags ordered from newest -> oldest # @return [Hash] key is the tag to output, value is an array of [Left Tag, Right Tag] # PRs to include in this section will be >= [Left Tag Date] and <= [Right Tag Date] # rubocop:disable Style/For - for allows us to be more concise - def build_tag_section_mapping(filtered_tags, _all_tags) + def build_tag_section_mapping(section_tags, filtered_tags) tag_mapping = {} - for i in 0..(filtered_tags.length - 1) - tag = filtered_tags[i] + for i in 0..(section_tags.length - 1) + tag = section_tags[i] # Don't create section header for the "since" tag next if @since_tag && tag["name"] == @since_tag # Don't create a section header for the first tag in between_tags - next if options[:between_tags] && tag == filtered_tags.last + next if options[:between_tags] && tag == section_tags.last - older_tag = filtered_tags[i + 1] + # Don't create a section header for excluded tags + next unless filtered_tags.include?(tag) + + older_tag = section_tags[i + 1] tag_mapping[tag] = [older_tag, tag] end tag_mapping diff --git a/spec/unit/generator/generator_tags_spec.rb b/spec/unit/generator/generator_tags_spec.rb index 8791a05..70d0d80 100644 --- a/spec/unit/generator/generator_tags_spec.rb +++ b/spec/unit/generator/generator_tags_spec.rb @@ -14,13 +14,21 @@ describe GitHubChangelogGenerator::Generator do end describe "#build_tag_section_mapping" do - let(:sorted_tags) { tags_from_strings(%w(8 7 6 5 4 3 2 1)) } - let(:filtered_tags) { generator.get_filtered_tags(sorted_tags) } + let(:all_tags) { tags_from_strings(%w(8 7 6 5 4 3 2 1)) } + let(:sorted_tags) { all_tags } + let(:options) { {} } let(:generator) { GitHubChangelogGenerator::Generator.new(options) } + before do + allow_any_instance_of(GitHubChangelogGenerator::OctoFetcher).to receive(:get_all_tags).and_return(all_tags) + allow(generator).to receive(:fetch_tags_dates).with(all_tags) + allow(generator).to receive(:sort_tags_by_date).with(all_tags).and_return(sorted_tags) + generator.fetch_and_filter_tags + end + subject do - generator.build_tag_section_mapping(filtered_tags, sorted_tags) + generator.tag_section_mapping end shared_examples_for "a section mapping" do @@ -45,6 +53,20 @@ describe GitHubChangelogGenerator::Generator do it_behaves_like "a section mapping" end + shared_examples_for "a changelog with some exclusions" do + let(:expected_mapping) do + { + tag_with_name("8") => [tag_with_name("7"), tag_with_name("8")], + tag_with_name("6") => [tag_with_name("5"), tag_with_name("6")], + tag_with_name("4") => [tag_with_name("3"), tag_with_name("4")], + tag_with_name("3") => [tag_with_name("2"), tag_with_name("3")], + tag_with_name("1") => [nil, tag_with_name("1")] + } + end + + it_behaves_like "a section mapping" + end + context "with no constraints" do it_behaves_like "a full changelog" end @@ -120,6 +142,26 @@ describe GitHubChangelogGenerator::Generator do it_behaves_like "a section mapping" end + + context "with excluded tags" do + context "as a list of strings" do + let(:options) { { exclude_tags: %w(2 5 7) } } + + it_behaves_like "a changelog with some exclusions" + end + + context "as a regex" do + let(:options) { { exclude_tags: /[257]/ } } + + it_behaves_like "a changelog with some exclusions" + end + + context "as a regex string" do + let(:options) { { exclude_tags_regex: "[257]" } } + + it_behaves_like "a changelog with some exclusions" + end + end end describe "#filter_between_tags" do