From e48e45f1d6fa54d143f78d67d284fb1aebed7fe5 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 9 Mar 2017 07:50:17 -0700 Subject: [PATCH] support label filtering --- README.md | 3 +++ assets/lib/filters/label.rb | 20 +++++++++++++++++ assets/lib/repository.rb | 3 ++- spec/filters/label_spec.rb | 43 +++++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 assets/lib/filters/label.rb create mode 100644 spec/filters/label_spec.rb diff --git a/README.md b/README.md index 11afab5..bdd8189 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,9 @@ resource_types: * `disable_forks`: *Optional.* If set to `true`, it will filter out pull requests that were created via users that forked from your repo. +* `label`: *Optional.* If set to a string it will only return pull requests that have been +marked with that specific label. It is case insensitive. + * `username`: *Optional.* Username for HTTP(S) auth when pulling/pushing. This is needed when only HTTP/HTTPS protocol for git is available (which does not support private key auth) and auth is required. diff --git a/assets/lib/filters/label.rb b/assets/lib/filters/label.rb new file mode 100644 index 0000000..4f2e2db --- /dev/null +++ b/assets/lib/filters/label.rb @@ -0,0 +1,20 @@ +module Filters + class Label + def initialize(pull_requests:, input: Input.instance) + @pull_requests = pull_requests + @input = input + end + + def pull_requests + if @input.source.label + @memoized ||= @pull_requests.select do |pr| + issue = Octokit.issue(@input.source.repo, pr.id) + labels = issue[:labels] || [] + labels.find { |l| l['name'].to_s.casecmp(@input.source.label.to_s.downcase).zero? } + end + else + @pull_requests + end + end + end +end diff --git a/assets/lib/repository.rb b/assets/lib/repository.rb index b9bcd43..a8ad96f 100644 --- a/assets/lib/repository.rb +++ b/assets/lib/repository.rb @@ -1,11 +1,12 @@ require_relative 'filters/all' require_relative 'filters/fork' +require_relative 'filters/label' require_relative 'filters/path' class Repository attr_reader :name - def initialize(name:, input: Input.instance, filters: [Filters::All, Filters::Path, Filters::Fork]) + def initialize(name:, input: Input.instance, filters: [Filters::All, Filters::Path, Filters::Fork, Filters::Label]) @filters = filters @name = name @input = input diff --git a/spec/filters/label_spec.rb b/spec/filters/label_spec.rb new file mode 100644 index 0000000..65dd0aa --- /dev/null +++ b/spec/filters/label_spec.rb @@ -0,0 +1,43 @@ +require_relative '../../assets/lib/filters/label' +require_relative '../../assets/lib/pull_request' +require 'webmock/rspec' + +describe Filters::Label do + let(:ignore_pr) do + PullRequest.new(pr: { 'number' => 1 }) + end + + let(:pr) do + PullRequest.new(pr: { 'number' => 2 }) + end + + let(:pull_requests) { [ignore_pr, pr] } + + def stub_json(uri, body) + stub_request(:get, uri) + .to_return(headers: { 'Content-Type' => 'application/json' }, body: body.to_json) + end + + context 'when no label is specified' do + it 'does not filter' do + payload = { 'source' => { 'repo' => 'user/repo' } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq pull_requests + end + end + + context 'when the label for filtering is provided' do + before do + stub_json(%r{https://api.github.com/repos/user/repo/issues/1}, 'labels' => [{ 'name' => 'feature' }]) + stub_json(%r{https://api.github.com/repos/user/repo/issues/2}, 'labels' => [{ 'name' => 'bug' }]) + end + + it 'only returns PRs with that label' do + payload = { 'source' => { 'repo' => 'user/repo', 'label' => 'bug' } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq [pr] + end + end +end