Class: GitHubLabeler
- Inherits:
-
Object
- Object
- GitHubLabeler
- Defined in:
- lib/github_labeler.rb
Instance Attribute Summary collapse
-
#client ⇒ Object
Octokit client for acesing the API.
-
#logger ⇒ Object
Octokit client for acesing the API.
-
#repo_labels ⇒ Object
Octokit client for acesing the API.
Instance Method Summary collapse
-
#add_label_to_repo(repo, label, options = {}) ⇒ Object
Create a single change for adding a label to a repo.
-
#add_labels_to_repos(repos, labels, options = {}) ⇒ Object
Create changes for adding a list of labels to a list of repos.
-
#change_string(change, options = {}) ⇒ Object
Get a human readable string representation of a change.
-
#delete_label_from_repo(repo, label, options = {}) ⇒ Object
Create a single change for deleting a label from a repo.
-
#delete_labels_from_repos(repos, labels, options = {}) ⇒ Object
Create changes for deleting a list of labels from a list of repos.
-
#duplicate_labels_from_repo(repo_source, repos_end, options = {}) ⇒ Object
Creates changes for duplicating labels from one repo to other repos.
-
#execute_changes(changes, options = {}) ⇒ Object
Executes a list of label changes.
-
#export_labels_from_repo(repo, options = {}) ⇒ Object
Fetches a list of labels for a repository.
-
#initialize(token, verbose = false, labels = nil) ⇒ GitHubLabeler
constructor
A new instance of GitHubLabeler.
-
#is_remaining_rate_limit_sufficient?(expected_number_of_calls) ⇒ Boolean
Checks if the remaining rate limit allows us to make the specified number of changes.
-
#process_labels_for_repos(repos, labels, change_creator, options = {}) ⇒ Object
Generic creation of changes for list of labels and list of repos.
-
#recolor_label_in_repo(repo, label, options = {}) ⇒ Object
Create a single change for recoloring a label in a repo.
-
#recolor_labels_in_repos(repos, labels, options = {}) ⇒ Object
Create changes for recoloring a list of labels in a list of repos.
-
#refresh_repo_labels(repo, options = {}) ⇒ Object
Fetches the list of labels in a repository and stores them in the labels cache.
-
#rename_label_in_repo(repo, label, options = {}) ⇒ Object
Create a single change for renaming a label in a repo.
-
#rename_labels_in_repos(repos, labels, options = {}) ⇒ Object
Create changes for renaming a list of labels in a list of repos.
-
#update_repos_labels_cache(repo, label) ⇒ Object
Updates repo labels cache for a specific label.
-
#validate_changes(changes, options = {}) ⇒ Object
Validates changes by merging multiple updates into one, removing duplicates, detecting conflicts, etc.
Constructor Details
#initialize(token, verbose = false, labels = nil) ⇒ GitHubLabeler
Returns a new instance of GitHubLabeler.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/github_labeler.rb', line 12 def initialize(token, verbose=false, labels=nil) @logger = Logger.new(STDERR) @logger.sev_threshold = verbose ? Logger::DEBUG : Logger::WARN @logger.debug "Creating new GitHubLabeler instance." @logger.debug "Creating a new Octokit client with token #{token[0..5]}" begin @client = Octokit::Client.new(:access_token => token) @client.rate_limit rescue Octokit:: => exception @logger.error "Token #{token[0..5]} is not valid" raise ArgumentError.new("Token #{token[0..5]} is not valid") end @logger.debug "Token #{token[0..5]} is valid" @repo_labels = !labels.nil? ? labels : {} end |
Instance Attribute Details
#client ⇒ Object
Octokit client for acesing the API
8 9 10 |
# File 'lib/github_labeler.rb', line 8 def client @client end |
#logger ⇒ Object
Octokit client for acesing the API
8 9 10 |
# File 'lib/github_labeler.rb', line 8 def logger @logger end |
#repo_labels ⇒ Object
Octokit client for acesing the API
8 9 10 |
# File 'lib/github_labeler.rb', line 8 def repo_labels @repo_labels end |
Instance Method Details
#add_label_to_repo(repo, label, options = {}) ⇒ Object
Create a single change for adding a label to a repo
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/github_labeler.rb', line 203 def add_label_to_repo(repo, label, = {}) existing_label = @repo_labels[repo][label[:name].downcase] if existing_label if existing_label[:color] != label[:color] or existing_label[:name] != label[:name] @logger.warn "Label #{label[:name]} already exist, creating an update" return { :type => "update", :repo => repo, :label => label } end else return { :type => "add", :repo => repo, :label => label } end @logger.warn "Label #{label[:name]} already exist and is the same. No change created" return nil end |
#add_labels_to_repos(repos, labels, options = {}) ⇒ Object
Create changes for adding a list of labels to a list of repos
129 130 131 132 |
# File 'lib/github_labeler.rb', line 129 def add_labels_to_repos(repos, labels, = {}) @logger.debug "Adding labels to repositories" return process_labels_for_repos(repos, labels, method(:add_label_to_repo), ) end |
#change_string(change, options = {}) ⇒ Object
Get a human readable string representation of a change
295 296 297 |
# File 'lib/github_labeler.rb', line 295 def change_string(change, = {}) return "#{change[:repo]} - #{change[:type]} - #{change[:label][:name]} - color: #{change[:label][:color]} - new_name: #{change[:label][:new_name]}" end |
#delete_label_from_repo(repo, label, options = {}) ⇒ Object
Create a single change for deleting a label from a repo
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/github_labeler.rb', line 222 def delete_label_from_repo(repo, label, = {}) existing_label = @repo_labels[repo][label[:name].downcase] if existing_label return { :type => "delete", :repo => repo, :label => label } end @logger.warn "Label #{label[:name]} doesn't exist. No change created" return nil end |
#delete_labels_from_repos(repos, labels, options = {}) ⇒ Object
Create changes for deleting a list of labels from a list of repos
137 138 139 140 |
# File 'lib/github_labeler.rb', line 137 def delete_labels_from_repos(repos, labels, = {}) @logger.debug "Deleting labels from repositories" return process_labels_for_repos(repos, labels, method(:delete_label_from_repo), ) end |
#duplicate_labels_from_repo(repo_source, repos_end, options = {}) ⇒ Object
Creates changes for duplicating labels from one repo to other repos
275 276 277 278 279 |
# File 'lib/github_labeler.rb', line 275 def duplicate_labels_from_repo(repo_source, repos_end, = {}) @logger.debug "Duplicating labels from repo #{repo_source}" source_repo_labels = export_labels_from_repo(repo_source, ) return add_labels_to_repos(repos_end, source_repo_labels, ) end |
#execute_changes(changes, options = {}) ⇒ Object
Executes a list of label changes. Each change has the following format:
:type => "update/create/delete",
:repo => "testrename/testing",
:label => {:color => "fc2929", :name => "design", :new_name => "ui"
}
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/github_labeler.rb', line 54 def execute_changes(changes, = {}) @logger.debug "Executing changes" if !is_remaining_rate_limit_sufficient?(changes.size) @logger.error "Remaining rate limit is not enough to make all changes. Wait for the limit to refresh and try again." return [] end changes = validate_changes(changes, ) changes.each do |change| @logger.debug "Executing change: #{change_string(change)}" if change[:type] == "add" success = @client.add_label(change[:repo], change[:label][:name], change[:label][:color]) if !@repo_labels[change[:repo]].nil? @repo_labels[change[:repo]][success[:name].downcase] = {:name => success[:name], :color => success[:color]} end @logger.debug "Change succeded" next end if change[:type] == "update" new_label = {:name => change[:label][:new_name] || change[:label][:name]} if !change[:label][:color].nil? new_label[:color] = change[:label][:color] end success = @client.update_label(change[:repo], change[:label][:name], new_label) if !@repo_labels[change[:repo]].nil? @repo_labels[change[:repo]][success[:name].downcase] = {:name => success[:name], :color => success[:color]} end @logger.debug "Change succeded" next end if change[:type] == "delete" success = @client.delete_label!(change[:repo], change[:label][:name]) if !@repo_labels[change[:repo]].nil? @repo_labels[change[:repo]][change[:label][:name].downcase] = nil end @logger.debug "Change succeded" next end end @logger.debug "Done executing changes" return changes end |
#export_labels_from_repo(repo, options = {}) ⇒ Object
Fetches a list of labels for a repository
284 285 286 287 288 289 290 |
# File 'lib/github_labeler.rb', line 284 def export_labels_from_repo(repo, = {}) @logger.debug "Exporting labels from repo #{repo}" @client.labels(repo).map do |label| { :name => label[:name], :color => label[:color] } end end |
#is_remaining_rate_limit_sufficient?(expected_number_of_calls) ⇒ Boolean
Checks if the remaining rate limit allows us to make the specified number of changes
37 38 39 40 41 42 43 |
# File 'lib/github_labeler.rb', line 37 def is_remaining_rate_limit_sufficient?(expected_number_of_calls) remaining_limit = @client.rate_limit.remaining @logger.debug "There are #{expected_number_of_calls} API calls to be made, and the remaining API rate limit quota is #{remaining_limit}." return expected_number_of_calls <= @client.rate_limit.remaining end |
#process_labels_for_repos(repos, labels, change_creator, options = {}) ⇒ Object
Generic creation of changes for list of labels and list of repos
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/github_labeler.rb', line 161 def process_labels_for_repos(repos, labels, change_creator, = {}) if !is_remaining_rate_limit_sufficient?(repos.size) @logger.error "Rate limit is not enough to process all labels in repositories" return nil end changes = [] for repo in repos repo_name = repo if repo.instance_of?(String) repo_name = repo[:full_name] if repo.instance_of?(Hash) @logger.debug "Processing labels for repository #{repo_name}" refresh_repo_labels(repo_name, ) for label in labels @logger.debug "Processing label #{label[:name]}" change = change_creator.call(repo_name, label, ) changes << change if !change.nil? end end return changes end |
#recolor_label_in_repo(repo, label, options = {}) ⇒ Object
Create a single change for recoloring a label in a repo
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/github_labeler.rb', line 256 def recolor_label_in_repo(repo, label, = {}) existing_label = @repo_labels[repo][label[:name].downcase] if existing_label if existing_label[:color] != label[:color] return { :type => "update", :repo => repo, :label => label } end else @logger.warn "Label #{label[:name]} doesn't exist. Creating a create change" return { :type => "add", :repo => repo, :label => label } end @logger.warn "Label #{label[:name]} exist and is the same. No change created" return nil end |
#recolor_labels_in_repos(repos, labels, options = {}) ⇒ Object
Create changes for recoloring a list of labels in a list of repos
153 154 155 156 |
# File 'lib/github_labeler.rb', line 153 def recolor_labels_in_repos(repos, labels, = {}) @logger.debug "Recoloring labels in repositories" return process_labels_for_repos(repos, labels, method(:recolor_label_in_repo), ) end |
#refresh_repo_labels(repo, options = {}) ⇒ Object
Fetches the list of labels in a repository and stores them in the labels cache
191 192 193 194 195 196 197 198 |
# File 'lib/github_labeler.rb', line 191 def refresh_repo_labels(repo, = {}) @logger.debug "Fetching label information for #{repo}" @repo_labels[repo] = {} @client.labels(repo).each do |label| @repo_labels[repo][label[:name].downcase] = label end end |
#rename_label_in_repo(repo, label, options = {}) ⇒ Object
Create a single change for renaming a label in a repo
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/github_labeler.rb', line 236 def rename_label_in_repo(repo, label, = {}) existing_label = @repo_labels[repo][label[:name].downcase] if existing_label if label[:new_name] and label[:new_name] != label[:name] return { :type => "update", :repo => repo, :label => label } end else @logger.warn "Label #{label[:name]} doesn't exist. Creating a create change" newLabel = {:name => label[:new_name], :color => label[:color]} return { :type => "add", :repo => repo, :label => newLabel } end @logger.warn "Label #{label[:name]} exist and is the same. No change created" return nil end |
#rename_labels_in_repos(repos, labels, options = {}) ⇒ Object
Create changes for renaming a list of labels in a list of repos
145 146 147 148 |
# File 'lib/github_labeler.rb', line 145 def rename_labels_in_repos(repos, labels, = {}) @logger.debug "Renaming labels in repositories" return process_labels_for_repos(repos, labels, method(:rename_label_in_repo), ) end |
#update_repos_labels_cache(repo, label) ⇒ Object
Updates repo labels cache for a specific label
114 115 116 |
# File 'lib/github_labeler.rb', line 114 def update_repos_labels_cache(repo, label) @repo_labels[change[:repo]][change[:label][:name].downcase] = success end |
#validate_changes(changes, options = {}) ⇒ Object
Validates changes by merging multiple updates into one, removing duplicates, detecting conflicts, etc.
122 123 124 |
# File 'lib/github_labeler.rb', line 122 def validate_changes(changes, = {}) return changes.sort_by { |hsh| [hsh["repo"], hsh["type"]] } end |