Class: Gitomator::GitHub::HostingProvider

Inherits:
BaseProvider show all
Defined in:
lib/gitomator/github/hosting_provider.rb

Constant Summary collapse

SUPPORTED_CREATE_OPTS =

—————————- REPO ———————————–

[:description, :homepage, :private, :has_issues,
:has_wiki, :has_downloads, :auto_init]
SUPPORTED_UPDATE_OPTS =
[:name, :description, :homepage, :private,
:has_issues, :has_wiki, :has_downloads,
:default_branch]

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(github_client, github_organization = nil) ⇒ HostingProvider

Returns a new instance of HostingProvider.

Parameters:

  • github_client (Octokit::Client)
  • github_organization (String) (defaults to: nil)
  • opts (Hash)


31
32
33
34
35
# File 'lib/gitomator/github/hosting_provider.rb', line 31

def initialize(github_client, github_organization=nil)
  super
  # GitHub API doesn't have a straight forward way to get a team by name, so we'll keep an in-memory cache
  @name2team_cache = {}
end

Class Method Details

.from_config(config = {}) ⇒ Gitomator::GitHub::HostingProvider

Returns GitHub hosting provider.

Parameters:

  • config (Hash<String,Object>) (defaults to: {})

Returns:



18
19
20
21
# File 'lib/gitomator/github/hosting_provider.rb', line 18

def self.from_config(config = {})
  org = config['organization'] || config[:organization]
  return new(Gitomator::GitHub::github_client_from_config(config), org)
end

Instance Method Details

#_fetch_teamsObject




50
51
52
53
54
# File 'lib/gitomator/github/hosting_provider.rb', line 50

def _fetch_teams
  with_auto_paginate do
    @name2team_cache = @gh.org_teams(@org).map {|t| [t.name, t]} .to_h
  end
end

#_strinigify_permission(permission) ⇒ Object



220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/gitomator/github/hosting_provider.rb', line 220

def _strinigify_permission(permission)
  if permission.nil?
    return nil
  end

  case permission.to_s
  when 'read' || 'pull'
    return 'pull'
  when 'write' || 'push'
    return 'push'
  else
    raise "Invalid permission '#{permission}'"
  end
end

#close_pull_request(dst_repo, id) ⇒ Object



385
386
387
388
# File 'lib/gitomator/github/hosting_provider.rb', line 385

def close_pull_request(dst_repo, id)
  Gitomator::GitHub::Model::PullRequest.new(
    @gh.close_pull_request(repo_name_full(dst_repo), id), @gh)
end

#create_pull_request(src, dst, opts = {}) ⇒ Object

Parameters:

  • src (String)

    of the following format ‘org/repo:branch’.

  • dst (String)

    of the following format ‘org/repo:branch’.



335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/gitomator/github/hosting_provider.rb', line 335

def create_pull_request(src, dst, opts = {})

  def extract_org_repo_and_branch(src_or_dst)
    match = src_or_dst.match(/(.+)\/(.+):(.+)/i)
    raise "Invalid src/dst, #{src_or_dst} (expected: `org_or_user/repo:branch`)" if match.nil?
    return match.captures
  end

  src_org, src_repo, src_branch = extract_org_repo_and_branch(src)
  dst_org, dst_repo, dst_branch = extract_org_repo_and_branch(dst)

  unless src_repo == dst_repo
    raise "Cannot create pull-request from #{src} to #{dst} (must be the same repo or a fork)."
  end

  Gitomator::GitHub::Model::PullRequest.new(
    @gh.create_pull_request("#{dst_org}/#{dst_repo}", dst_branch,
      (src_org == dst_org ? '' : "#{src_org}:") + src_branch,
      opts[:title] || 'New Pull Request',
      opts[:body] || 'Pull-request created using Gitomator.'
    )
  )
end

#create_repo(name, opts = {}) ⇒ Object

Parameters:

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :description (String)
  • :homepage (String)
  • :private (Boolean)
  • :has_issues (Boolean)
  • :has_wiki (Boolean)
  • :has_downloads (Boolean)
  • :auto_init (Boolean)


70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/gitomator/github/hosting_provider.rb', line 70

def create_repo(name, opts = {})
  opts = opts.select {|k,_| SUPPORTED_CREATE_OPTS.include? k }

  # Decide whether this is an organization-repo or a user-repo ...
  org = @repo_name_resolver.namespace(name)
  unless org.nil? || org == @gh.user.
    opts[:organization] = org
  end

  return Gitomator::GitHub::Model::HostedRepo.new(
    @gh.create_repo(@repo_name_resolver.name_only(name), opts)
  )
end

#create_team(name, opts = {}) ⇒ Object

—————————- TEAMS ———————————-



135
136
137
# File 'lib/gitomator/github/hosting_provider.rb', line 135

def create_team(name, opts = {})
    Gitomator::GitHub::Model::Team.new(@gh.create_team(@org, {name: name}))
end

#create_team_membership(team_name, user_name, role = 'member') ⇒ Object



262
263
264
265
266
267
# File 'lib/gitomator/github/hosting_provider.rb', line 262

def create_team_membership(team_name, user_name, role='member')
  @gh.add_team_membership(team_id(team_name), user_name,
    { :role => gitomator_role_2_github_role(role) }
  )
  return role
end

#delete_repo(name) ⇒ Object



116
117
118
# File 'lib/gitomator/github/hosting_provider.rb', line 116

def delete_repo(name)
  @gh.delete_repo repo_name_full(name)
end

#delete_team(name) ⇒ Object



166
167
168
169
170
171
172
173
174
175
176
# File 'lib/gitomator/github/hosting_provider.rb', line 166

def delete_team(name)
  unless @name2team_cache.has_key? name
    _fetch_teams()
  end
  if @name2team_cache.has_key? name
    @gh.delete_team @name2team_cache[name].id
    @name2team_cache.delete(name)
    return true
  end
  return false
end

#delete_team_membership(team_name, user_name) ⇒ Object



287
288
289
# File 'lib/gitomator/github/hosting_provider.rb', line 287

def delete_team_membership(team_name, user_name)
  @gh.remove_team_membership(team_id(team_name), user_name)
end

#extract_org_repo_and_branch(src_or_dst) ⇒ Object



337
338
339
340
341
# File 'lib/gitomator/github/hosting_provider.rb', line 337

def extract_org_repo_and_branch(src_or_dst)
  match = src_or_dst.match(/(.+)\/(.+):(.+)/i)
  raise "Invalid src/dst, #{src_or_dst} (expected: `org_or_user/repo:branch`)" if match.nil?
  return match.captures
end

#github_role_2_gitomator_role(role) ⇒ Object



249
250
251
# File 'lib/gitomator/github/hosting_provider.rb', line 249

def github_role_2_gitomator_role(role)
  role == 'maintainer' ? 'admin' : role
end

#gitomator_role_2_github_role(role) ⇒ Object

———– Helpers ———



241
242
243
244
245
246
247
# File 'lib/gitomator/github/hosting_provider.rb', line 241

def gitomator_role_2_github_role(role)
  if ['admin', 'maintainer'].include? role.to_s.downcase
    return 'maintainer'
  else
    return 'member'
  end
end

#merge_pull_request(dst_repo, id, message = '') ⇒ Object



380
381
382
383
# File 'lib/gitomator/github/hosting_provider.rb', line 380

def merge_pull_request(dst_repo, id, message='')
  Gitomator::GitHub::Model::PullRequest.new(
    @gh.merge_pull_request(repo_name_full(dst_repo), id, message), @gh)
end

#nameObject



37
38
39
# File 'lib/gitomator/github/hosting_provider.rb', line 37

def name
  :github
end

#open_pull_request(dst_repo, id) ⇒ Object



390
391
392
393
# File 'lib/gitomator/github/hosting_provider.rb', line 390

def open_pull_request(dst_repo, id)
  Gitomator::GitHub::Model::PullRequest.new(
    @gh.update_pull_request(repo_name_full(dst_repo), id, {state: :open}), @gh)
end

#read_pull_request(dst_repo, id) ⇒ Object



360
361
362
363
364
365
366
367
# File 'lib/gitomator/github/hosting_provider.rb', line 360

def read_pull_request(dst_repo, id)
  begin
    return Gitomator::GitHub::Model::PullRequest.new(
                  @gh.pull_request(repo_name_full(dst_repo), id))
  rescue Octokit::NotFound
    return nil
  end
end

#read_pull_requests(dst_repo, opts = {}) ⇒ Object

> @param :state [Symbol] One of :open, :close or :all (default: :open)

Parameters:

  • opts (Hash) (defaults to: {})


374
375
376
377
# File 'lib/gitomator/github/hosting_provider.rb', line 374

def read_pull_requests(dst_repo, opts = {})
  @gh.pulls(repo_name_full(dst_repo), opts)
          .map {|pr| Gitomator::GitHub::Model::PullRequest.new(pr, @gh)}
end

#read_repo(name) ⇒ Object



85
86
87
88
89
90
91
# File 'lib/gitomator/github/hosting_provider.rb', line 85

def read_repo(name)
  begin
    return Gitomator::GitHub::Model::HostedRepo.new(@gh.repo repo_name_full(name))
  rescue Octokit::NotFound
    return nil
  end
end

#read_team(name) ⇒ Object



139
140
141
142
143
144
145
146
147
148
# File 'lib/gitomator/github/hosting_provider.rb', line 139

def read_team(name)
  unless @name2team_cache.has_key? name
    _fetch_teams()
  end
  if @name2team_cache[name]
    Gitomator::GitHub::Model::Team.new(@name2team_cache[name])
  else
    return nil
  end
end

#read_team_membership(team_name, user_name) ⇒ Object



270
271
272
273
274
275
276
277
# File 'lib/gitomator/github/hosting_provider.rb', line 270

def read_team_membership(team_name, user_name)
  begin
    m = @gh.team_membership(team_id(team_name), user_name)
    return m.nil? ? nil : m.role
  rescue Octokit::NotFound
    return nil
  end
end

#repo_name_full(repo_name) ⇒ Object

———— Helper Methods, Dealing With Naming Conventions ——-



44
45
46
# File 'lib/gitomator/github/hosting_provider.rb', line 44

def repo_name_full(repo_name)
  @repo_name_resolver.full_name(repo_name)
end

#search_repos(query, opts = {}) ⇒ Object



123
124
125
126
127
128
129
130
# File 'lib/gitomator/github/hosting_provider.rb', line 123

def search_repos(query, opts = {})
  gh_repos = nil
  with_auto_paginate do
    gh_repos = @gh.search_repos("#{query} user:#{@org}", opts).items
  end

  gh_repos.map {|r| Gitomator::GitHub::Model::HostedRepo.new(r)}
end

#search_teams(query, opts = {}) ⇒ Object



179
180
181
182
183
184
185
186
# File 'lib/gitomator/github/hosting_provider.rb', line 179

def search_teams(query, opts={})
  result = @name2team_cache.select {|k,_| k.downcase.include? query} .values
  if result.empty?
    _fetch_teams()
    result = @name2team_cache.select {|k,_| k.downcase.include? query} .values
  end
  return result.map {|t| Gitomator::GitHub::Model::Team.new(t)}
end

#search_users(query, opts = {}) ⇒ Object



305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/gitomator/github/hosting_provider.rb', line 305

def search_users(query, opts={})

  # If the team's name is specified ...
  gh_users = nil
  if opts[:team_name]
    team = read_team(opts[:team_name])
    gh_users = with_auto_paginate { @gh.team_members(team.id) }
  else
    gh_users = with_auto_paginate { @gh.org_members(@org) }
  end

  result = gh_users.map { |u| Gitomator::GitHub::Model::User.new(u) }

  if query.is_a?(String) && (! query.empty?)
    result = result.select {|u| u.username.include? query }
  elsif query.is_a? Regexp
    result = result.select {|u| query.match(u.username) }
  end

  return result
end

#set_team_permission(team, repo, permission) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/gitomator/github/hosting_provider.rb', line 201

def set_team_permission(team, repo, permission)
  permission = _strinigify_permission(permission)

  t = read_team(team)
  raise "No such team, #{team}" if t.nil?

  if permission.nil?
    @gh.remove_team_repo(t.id, repo_name_full(repo))
  else
    @gh.add_team_repo(t.id, repo_name_full(repo),
      {
        permission: permission,
        accept: 'application/vnd.github.ironman-preview+json'
      }
    )
  end
end

#set_user_permission(user, repo, permission) ⇒ Object




191
192
193
194
195
196
197
198
# File 'lib/gitomator/github/hosting_provider.rb', line 191

def set_user_permission(user, repo, permission)
  permission = _strinigify_permission(permission)
  if permission.nil?
    @gh.remove_collab(repo_name_full(repo), user)
  else
    @gh.add_collab(repo_name_full(repo), user, {permission: permission})
  end
end

#team_id(team_name) ⇒ Object



253
254
255
256
257
# File 'lib/gitomator/github/hosting_provider.rb', line 253

def team_id(team_name)
  team = read_team(team_name)
  raise "No such team, #{team_name}" if team.nil?
  return team.id
end

#update_repo(name, opts = {}) ⇒ Object

Parameters:

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :name (String)

    — Name of the repo

  • :description (String)

    — Description of the repo

  • :homepage (String)

    — Home page of the repo

  • :private (Boolean)

    — true makes the repository private, and false makes it public.

  • :has_issues (Boolean)

    — true enables issues for this repo, false disables issues.

  • :has_wiki (Boolean)

    — true enables wiki for this repo, false disables wiki.

  • :has_downloads (Boolean)

    — true enables downloads for this repo, false disables downloads.

  • :default_branch (String)

    — Update the default branch for this repository.



107
108
109
110
111
112
113
# File 'lib/gitomator/github/hosting_provider.rb', line 107

def update_repo(name, opts = {})
  opts = opts.select {|k,_| SUPPORTED_UPDATE_OPTS.include? k }
  unless opts.empty?
    return Gitomator::GitHub::Model::HostedRepo.new(
          @gh.edit_repository repo_name_full(name), opts)
  end
end

#update_team(name, opts) ⇒ Object

opts:

- :name (String)
- :permission (String, one of 'pull', 'push' or 'admin')


155
156
157
158
159
160
161
162
163
164
# File 'lib/gitomator/github/hosting_provider.rb', line 155

def update_team(name, opts)
  unless @name2team_cache.has_key? name
    _fetch_teams()
  end
  raise "No such team, '#{name}'" unless @name2team_cache.has_key? name

  t = @gh.update_team(@name2team_cache[name].id, opts)
  @name2team_cache[name] = t
  return Gitomator::GitHub::Model::Team.new(t)
end

#update_team_membership(team_name, user_name, role) ⇒ Object



280
281
282
283
284
# File 'lib/gitomator/github/hosting_provider.rb', line 280

def update_team_membership(team_name, user_name, role)
  @gh.add_team_membership(team_id(team_name), user_name,
    { :role => gitomator_role_2_github_role(role) } )
  return role
end

#with_auto_paginateObject




294
295
296
297
298
299
300
301
302
# File 'lib/gitomator/github/hosting_provider.rb', line 294

def with_auto_paginate
  raise "You must supply a block" unless block_given?
  begin
    @gh.auto_paginate = true # We want to get all team members
    yield
  ensure
    @gh.auto_paginate = nil  # We don't want to hit GitHub's API rate-limit
  end
end