Skip to content

Commit

Permalink
Improve maintainability of labeler class using polymorphism
Browse files Browse the repository at this point in the history
  • Loading branch information
codisart committed Mar 23, 2021
1 parent 47351a1 commit 5295b53
Show file tree
Hide file tree
Showing 11 changed files with 339 additions and 197 deletions.
3 changes: 2 additions & 1 deletion common/lib/dependabot/pull_request_creator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class PullRequestCreator
require "dependabot/pull_request_creator/message_builder"
require "dependabot/pull_request_creator/branch_namer"
require "dependabot/pull_request_creator/labeler"
require "dependabot/pull_request_creator/labelers/factory"

class RepoNotFound < StandardError; end

Expand Down Expand Up @@ -225,7 +226,7 @@ def branch_namer

def labeler
@labeler ||=
Labeler.new(
Dependabot::PullRequestCreator::Labelers::Factory.for_source(
source: source,
custom_labels: custom_labels,
credentials: credentials,
Expand Down
198 changes: 18 additions & 180 deletions common/lib/dependabot/pull_request_creator/labeler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require "octokit"
require "dependabot/pull_request_creator"

module Dependabot
class PullRequestCreator
class Labeler
Expand All @@ -26,12 +27,11 @@ def register_label_details(package_manager, label_details)
end
end

def initialize(source:, custom_labels:, credentials:, dependencies:,
def initialize(source:, custom_labels:, dependencies:,
includes_security_fixes:, label_language:,
automerge_candidate:)
@source = source
@custom_labels = custom_labels
@credentials = credentials
@dependencies = dependencies
@includes_security_fixes = includes_security_fixes
@label_language = label_language
Expand All @@ -53,29 +53,13 @@ def labels_for_pr
].compact.uniq
end

def label_pull_request(pull_request_number)
create_default_labels_if_required

return if labels_for_pr.none?
raise "Only GitHub!" unless source.provider == "github"

github_client_for_source.add_labels_to_an_issue(
source.repo,
pull_request_number,
labels_for_pr
)
rescue Octokit::UnprocessableEntity, Octokit::NotFound
retry_count ||= 0
retry_count += 1
raise if retry_count > 10

sleep(rand(1..1.99))
retry
def label_pull_request(_pull_request_number)
raise "Only GitHub!"
end

private

attr_reader :source, :custom_labels, :credentials, :dependencies
attr_reader :source, :custom_labels, :dependencies

def label_language?
@label_language
Expand Down Expand Up @@ -226,183 +210,37 @@ def language_label_exists?
end

def language_label
label_name =
self.class.label_details_for_package_manager(package_manager).
fetch(:name)
labels.find { |l| l.casecmp(label_name).zero? }
labels.find { |l| l.casecmp(language_name).zero? }
end

def labels
@labels ||=
case source.provider
when "github" then fetch_github_labels
when "gitlab" then fetch_gitlab_labels
when "azure" then fetch_azure_labels
else raise "Unsupported provider #{source.provider}"
end
end

def fetch_github_labels
client = github_client_for_source

labels =
client.
labels(source.repo, per_page: 100).
map(&:name)

next_link = client.last_response.rels[:next]

while next_link
next_page = next_link.get
labels += next_page.data.map(&:name)
next_link = next_page.rels[:next]
end

labels
end

def fetch_gitlab_labels
gitlab_client_for_source.
labels(source.repo, per_page: 100).
auto_paginate.
map(&:name)
end

def fetch_azure_labels
langauge_name =
self.class.label_details_for_package_manager(package_manager).
fetch(:name)

@labels = [
*@labels,
DEFAULT_DEPENDENCIES_LABEL,
DEFAULT_SECURITY_LABEL,
langauge_name
].uniq
raise "Unsupported provider #{source.provider}"
end

def create_dependencies_label
case source.provider
when "github" then create_github_dependencies_label
when "gitlab" then create_gitlab_dependencies_label
when "azure" then @labels # Azure does not have centralised labels
else raise "Unsupported provider #{source.provider}"
end
raise "Unsupported provider #{source.provider}"
end

def create_security_label
case source.provider
when "github" then create_github_security_label
when "gitlab" then create_gitlab_security_label
when "azure" then @labels # Azure does not have centralised labels
else raise "Unsupported provider #{source.provider}"
end
raise "Unsupported provider #{source.provider}"
end

def create_language_label
case source.provider
when "github" then create_github_language_label
when "gitlab" then create_gitlab_language_label
when "azure" then @labels # Azure does not have centralised labels
else raise "Unsupported provider #{source.provider}"
end
end

def create_github_dependencies_label
github_client_for_source.add_label(
source.repo, DEFAULT_DEPENDENCIES_LABEL, "0366d6",
description: "Pull requests that update a dependency file",
accept: "application/vnd.github.symmetra-preview+json"
)
@labels = [*@labels, DEFAULT_DEPENDENCIES_LABEL].uniq
rescue Octokit::UnprocessableEntity => e
raise unless e.errors.first.fetch(:code) == "already_exists"

@labels = [*@labels, DEFAULT_DEPENDENCIES_LABEL].uniq
end

def create_gitlab_dependencies_label
gitlab_client_for_source.create_label(
source.repo, DEFAULT_DEPENDENCIES_LABEL, "#0366d6",
description: "Pull requests that update a dependency file"
)
@labels = [*@labels, DEFAULT_DEPENDENCIES_LABEL].uniq
end

def create_github_security_label
github_client_for_source.add_label(
source.repo, DEFAULT_SECURITY_LABEL, "ee0701",
description: "Pull requests that address a security vulnerability",
accept: "application/vnd.github.symmetra-preview+json"
)
@labels = [*@labels, DEFAULT_SECURITY_LABEL].uniq
rescue Octokit::UnprocessableEntity => e
raise unless e.errors.first.fetch(:code) == "already_exists"

@labels = [*@labels, DEFAULT_SECURITY_LABEL].uniq
end

def create_gitlab_security_label
gitlab_client_for_source.create_label(
source.repo, DEFAULT_SECURITY_LABEL, "#ee0701",
description: "Pull requests that address a security vulnerability"
)
@labels = [*@labels, DEFAULT_SECURITY_LABEL].uniq
end

def create_github_language_label
langauge_name =
self.class.label_details_for_package_manager(package_manager).
fetch(:name)
github_client_for_source.add_label(
source.repo,
langauge_name,
self.class.label_details_for_package_manager(package_manager).
fetch(:colour),
description: "Pull requests that update #{langauge_name.capitalize} "\
"code",
accept: "application/vnd.github.symmetra-preview+json"
)
@labels = [*@labels, langauge_name].uniq
rescue Octokit::UnprocessableEntity => e
raise unless e.errors.first.fetch(:code) == "already_exists"

@labels = [*@labels, langauge_name].uniq
end

def create_gitlab_language_label
langauge_name =
self.class.label_details_for_package_manager(package_manager).
fetch(:name)
gitlab_client_for_source.create_label(
source.repo,
langauge_name,
"#" + self.class.label_details_for_package_manager(package_manager).
fetch(:colour)
)
@labels = [*@labels, langauge_name].uniq
end

def github_client_for_source
@github_client_for_source ||=
Dependabot::Clients::GithubWithRetries.for_source(
source: source,
credentials: credentials
)
end

def gitlab_client_for_source
@gitlab_client_for_source ||=
Dependabot::Clients::GitlabWithRetries.for_source(
source: source,
credentials: credentials
)
raise "Unsupported provider #{source.provider}"
end

def package_manager
@package_manager ||= dependencies.first.package_manager
end

def language_name
@language_name ||= self.class.label_details_for_package_manager(package_manager).fetch(:name)
end

def colour
@colour ||= self.class.label_details_for_package_manager(package_manager).fetch(:colour)
end

def version_class
Utils.version_class_for_package_manager(package_manager)
end
Expand Down
34 changes: 34 additions & 0 deletions common/lib/dependabot/pull_request_creator/labelers/azure.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

require "dependabot/pull_request_creator/labeler"

module Dependabot
class PullRequestCreator
module Labelers
class Azure < Labeler
@package_manager_labels = {}

# Azure does not have centralised labels
def labels
@labels ||= [
DEFAULT_DEPENDENCIES_LABEL,
DEFAULT_SECURITY_LABEL,
language_name
]
end

def create_dependencies_label
labels
end

def create_security_label
labels
end

def create_language_label
labels
end
end
end
end
end
77 changes: 77 additions & 0 deletions common/lib/dependabot/pull_request_creator/labelers/factory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# frozen_string_literal: true

module Dependabot
class PullRequestCreator
module Labelers
class Factory
class << self
def for_source(source:, custom_labels:, credentials:, includes_security_fixes:, dependencies:,
label_language:, automerge_candidate:)
labeler_params = {
custom_labels: custom_labels,
includes_security_fixes: includes_security_fixes,
dependencies: dependencies,
label_language: label_language,
automerge_candidate: automerge_candidate
}

case source.provider
when "github" then github_labeler(source, credentials, labeler_params)
when "gitlab" then gitlab_labeler(source, credentials, labeler_params)
when "azure" then azure_labeler(source, labeler_params)
when "bitbucket" then base_labeler(source, labeler_params)
when "codecommit" then base_labeler(source, labeler_params)
else raise "Unsupported provider '#{source.provider}'."
end
end

private

def github_labeler(source, credentials, labeler_params)
require "dependabot/pull_request_creator/labelers/github"
require "dependabot/clients/github_with_retries"
client = Dependabot::Clients::GithubWithRetries.for_source(
source: source,
credentials: credentials
)
Dependabot::PullRequestCreator::Labelers::Github.new(
source: source,
client: client,
**labeler_params
)
end

def gitlab_labeler(source, credentials, labeler_params)
require "dependabot/pull_request_creator/labelers/gitlab"
require "dependabot/clients/gitlab_with_retries"
client = Dependabot::Clients::GitlabWithRetries.for_source(
source: source,
credentials: credentials
)
Dependabot::PullRequestCreator::Labelers::Gitlab.new(
source: source,
client: client,
**labeler_params
)
end

def azure_labeler(source, labeler_params)
require "dependabot/pull_request_creator/labelers/azure"
Dependabot::PullRequestCreator::Labelers::Azure.new(
source: source,
**labeler_params
)
end

def base_labeler(source, labeler_params)
require "dependabot/pull_request_creator/labeler"
Dependabot::PullRequestCreator.Labeler.new(
source: source,
**labeler_params
)
end
end
end
end
end
end
Loading

0 comments on commit 5295b53

Please sign in to comment.