Skip to content

Commit

Permalink
Merge pull request #11 from samvera-labs/allow-filtering-repositories…
Browse files Browse the repository at this point in the history
…-by-topic

Allow filtering repositories by one or more topics
  • Loading branch information
jeremyf authored May 14, 2020
2 parents 926d4b6 + bd2714e commit e1971bf
Showing 1 changed file with 64 additions and 14 deletions.
78 changes: 64 additions & 14 deletions lib/huborg.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Client
# @since v0.1.0
#
# @param logger [Logger] used in logging output of processes
# @param github_access_token [String] used to connect to the Oktokit::Client.
# @param github_access_token [String] used to connect to the Octokit::Client.
# The given token will need to have permission to interact with
# repositories. Defaults to ENV["GITHUB_ACCESS_TOKEN"]
# @param org_names [Array<String>, String] used as the default list of Github organizations
Expand All @@ -50,16 +50,25 @@ class Client
#
# @see https://github.com/octokit/octokit.rb#oauth-access-tokens Octokit's documentation for OAuth Tokens
# @see https://developer.github.com/v3/repos/#list-organization-repositories Github's documentation for repository data structures
def initialize(logger: default_logger, github_access_token: default_access_token, org_names:, repository_pattern: DEFAULT_REPOSITORY_PATTERN)
def initialize(logger: default_logger,
github_access_token: default_access_token,
org_names:,
repository_pattern: DEFAULT_REPOSITORY_PATTERN,
repository_topics: default_repository_topics)
@logger = logger
@client = Octokit::Client.new(access_token: github_access_token)
@org_names = Array(org_names)
@repository_pattern = repository_pattern
@repository_topics = repository_topics
end

private

attr_reader :client, :logger, :org_names, :repository_pattern
attr_reader :client, :logger, :org_names, :repository_pattern, :repository_topics

def default_repository_topics
[]
end

def default_logger
require 'logger'
Expand Down Expand Up @@ -265,8 +274,8 @@ def clone_and_rebase!(directory:, skip_forked: false, skip_archived: false, skip
# @param skip_archived [Boolean] skip any archived projects
# @param query [Hash] the query params to use when selecting pull requests
#
# @yieldparam [Oktokit::PullRequest] responds to #created_at, #title, #html_url, etc
# @yieldparam [Oktokit::Repository] responds to #full_name
# @yieldparam [Octokit::PullRequest] responds to #created_at, #title, #html_url, etc
# @yieldparam [Octokit::Repository] responds to #full_name
#
# @example
# require 'huborg'
Expand All @@ -289,13 +298,50 @@ def each_pull_request_with_repo(skip_archived: true, query: { state: :open})
true
end

# @api public
# @since v0.4.0
#
# List every repository that will be acted upon. This is primarily to
# provide extra assurance to the user.
#
# @yieldparam [Octokit::Repository] responds to #full_name
#
# @example
# require 'huborg'
# client = Huborg::Client.new(org_names: ["samvera", "samvera-labs"], repository_topics: ['hyrax'])
# client.list_repositories do |repo|
# puts repo.full_name
# end
#
# @see https://developer.github.com/v3/repos/#list-organization-repositories
# for the response document
#
# @return [True]
def list_repositories
each_github_repository do |repo|
yield repo
end

true
end

private

# Fetch all topics for a repository
#
# @see https://developer.github.com/v3/repos/#list-organization-repositories
# for the response document
#
# @return [Array<String>] the repository's topics or an empty array
def topics_for(repo)
client.topics(repo.full_name, accept: Octokit::Preview::PREVIEW_TYPES[:topics])[:names]
end

# Fetch all of the repositories for the initialized :org_names that
# match the initialized :repository_pattern
#
# @yield [Oktokit::Repository] each repository will be yielded
# @yieldparam [Oktokit::Repository]
# @yield [Octokit::Repository] each repository will be yielded
# @yieldparam [Octokit::Repository]
# @see https://developer.github.com/v3/repos/#list-organization-repositories
# for the response document
# @return [True]
Expand All @@ -308,9 +354,13 @@ def each_github_repository(&block)
end

repos.each do |repo|
block.call(repo) if repository_pattern.match?(repo.full_name)
next unless repository_pattern.match?(repo.full_name) &&
repository_topics.all? { |specified_topic| topics_for(repo).include?(specified_topic) }

block.call(repo)
end
return true

true
end

# @note Due to an implementation detail in octokit.rb, refs sometimes
Expand Down Expand Up @@ -340,7 +390,7 @@ def push_template_to!(repo:, template:, filename:, overwrite: false)
rescue Octokit::NotFound
nil
end
commit_message = "Adding #{filename}\n\nThis was uploaded via automation."
commit_message = "Adding/updating #{filename}\n\nThis was uploaded via automation."
logger.info("Creating pull request for #{filename} on #{repo.full_name}")
target_branch_name = "refs/heads/autoupdate-#{Time.now.utc.to_s.gsub(/\D+/,'')}"
if copy_on_master
Expand Down Expand Up @@ -410,15 +460,15 @@ def clone_and_rebase_one!(repo:, directory:, skip_dirty: true, force: false, sha
# @param rel [Symbol] The name of the related object(s) for the
# given org
# @param from [Object] The receiver of the rels method call. This could be
# but is not limited to an Oktokit::Organization or
# Oktokit::Repository.
# but is not limited to an Octokit::Organization or
# Octokit::Repository.
#
# @return [Array<Object>]
def fetch_rel_for(rel:, from:, query: {})
# Build a list of repositories, note per Github's API, these are
# paginated.
from_to_s = from.respond_to?(:name) ? from.name : from.to_s
logger.info "Fetching rels[#{rel.inspect}] for '#{from_to_s}' with pattern #{repository_pattern.inspect} and query #{query.inspect}"
logger.info "Fetching rels[#{rel.inspect}] for '#{from_to_s}' with pattern #{repository_pattern.inspect}, topics #{repository_topics}, and query #{query.inspect}"
source = from.rels[rel].get(query)
rels = []
while source
Expand All @@ -429,7 +479,7 @@ def fetch_rel_for(rel:, from:, query: {})
source = nil
end
end
logger.info "Finished fetching rels[#{rel.inspect}] for '#{from_to_s}' with pattern #{repository_pattern.inspect} and query #{query.inspect}"
logger.info "Finished fetching rels[#{rel.inspect}] for '#{from_to_s}' with pattern #{repository_pattern.inspect}, topics #{repository_topics}, and query #{query.inspect}"
if block_given?
rels
else
Expand Down

0 comments on commit e1971bf

Please sign in to comment.