gitomator 0.1.2.2 → 0.1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 84f57a80b2ebad2a34c34af1ee482573a6adf9bd
4
- data.tar.gz: 3a344435d2a2a8133f2fbef8917c06de9a0feb3c
3
+ metadata.gz: 72d552670e91c7db9a0850b797cf463ef819bb39
4
+ data.tar.gz: 51af6b8d334e37b8b05820dc0026731c23330ac4
5
5
  SHA512:
6
- metadata.gz: 100cbab10b50137f49689199c34c813b4db8c7904e3e2249b5c0b7f6d4635bc3cfccbd0304467107978969f4b3c806958e1adb3146df57a14fc1a5105af89aec
7
- data.tar.gz: e4a3c7b9118329f977c0d3a680cea7f2df7ab3db6e890ca8cb341256a955851c18add373a5e0ed91f5269457d0befb06674e9af70e07a22e887ec9f524802bf3
6
+ metadata.gz: db58cf86b79ecbb02bc5d248816c08b83b4a6ebd71200803678391243a0fd8856db6773f83e2a1b1e79f9389b4b4261ed20d4f7e0e1ae5b7edc8ef558a47bb37
7
+ data.tar.gz: 862bb2ff0cf25dd6fe6d6599c7ae012feb87300b572988ebe47057e54d951b4b35bc2be4035ed4ef27710b71d8edeaaf579703410f8fc057ffd10f5e50c60647
data/Gemfile CHANGED
@@ -2,12 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in gitomator.gemspec
4
4
  gemspec
5
-
6
- #
7
- # FIXME: The whole point is to be able to plug-in different providers (where the
8
- # core project is light, and doesn't know/care/depends on any specific provider).
9
- # I still don't know of a clean way to do that in Ruby, so for now let's add
10
- # gitomator-github and gitomator-travis as dependencies...
11
- #
12
- gem 'gitomator-github', :git => 'git@github.com:Gitomator/gitomator-github.git'
13
- gem 'gitomator-travis', :git => 'git@github.com:Gitomator/gitomator-travis.git'
data/gitomator.gemspec CHANGED
@@ -24,5 +24,7 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_runtime_dependency 'trollop', '~> 2.1', '>= 2.1.2'
26
26
  spec.add_runtime_dependency 'logger', '~> 1.2', '>= 1.2.8'
27
+ spec.add_runtime_dependency 'travis', '~> 1.8', '>= 1.8.2'
28
+ spec.add_runtime_dependency 'octokit', '~> 4.2'
27
29
 
28
30
  end
@@ -0,0 +1,28 @@
1
+ require 'gitomator/github'
2
+ require 'gitomator/util/repo/name_resolver'
3
+
4
+
5
+ module Gitomator
6
+ module GitHub
7
+ class BaseProvider
8
+
9
+
10
+ #
11
+ # @param github_client [Octokit::Client]
12
+ # @param github_organization [String]
13
+ #
14
+ def initialize(github_client, github_organization=nil)
15
+ @gh = github_client
16
+ @org = github_organization
17
+ @repo_name_resolver = Gitomator::Util::Repo::NameResolver.new(@org)
18
+ end
19
+
20
+
21
+ def name
22
+ :github
23
+ end
24
+
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,402 @@
1
+ require 'gitomator/github'
2
+ require 'gitomator/github/base_provider'
3
+ require 'gitomator/github/model/hosted_repo'
4
+ require 'gitomator/github/model/pull_request'
5
+ require 'gitomator/github/model/team'
6
+ require 'gitomator/github/model/user'
7
+ require 'gitomator/util/repo/name_resolver'
8
+
9
+
10
+ module Gitomator
11
+ module GitHub
12
+ class HostingProvider < Gitomator::GitHub::BaseProvider
13
+
14
+ #
15
+ # @param config [Hash<String,Object>]
16
+ # @return [Gitomator::GitHub::HostingProvider] GitHub hosting provider.
17
+ #
18
+ def self.from_config(config = {})
19
+ org = config['organization'] || config[:organization]
20
+ return new(Gitomator::GitHub::github_client_from_config(config), org)
21
+ end
22
+
23
+
24
+ #=========================================================================
25
+
26
+ #
27
+ # @param github_client [Octokit::Client]
28
+ # @param github_organization [String]
29
+ # @param opts [Hash]
30
+ #
31
+ def initialize(github_client, github_organization=nil)
32
+ super
33
+ # GitHub API doesn't have a straight forward way to get a team by name, so we'll keep an in-memory cache
34
+ @name2team_cache = {}
35
+ end
36
+
37
+ def name
38
+ :github
39
+ end
40
+
41
+
42
+ # ------------ Helper Methods, Dealing With Naming Conventions -------
43
+
44
+ def repo_name_full(repo_name)
45
+ @repo_name_resolver.full_name(repo_name)
46
+ end
47
+
48
+ #---------------------------------------------------------------------
49
+
50
+ def _fetch_teams
51
+ with_auto_paginate do
52
+ @name2team_cache = @gh.org_teams(@org).map {|t| [t.name, t]} .to_h
53
+ end
54
+ end
55
+
56
+
57
+ #---------------------------- REPO -----------------------------------
58
+
59
+ SUPPORTED_CREATE_OPTS = [:description, :homepage, :private, :has_issues,
60
+ :has_wiki, :has_downloads, :auto_init]
61
+ #
62
+ # @option opts [String] :description
63
+ # @option opts [String] :homepage
64
+ # @option opts [Boolean] :private
65
+ # @option opts [Boolean] :has_issues
66
+ # @option opts [Boolean] :has_wiki
67
+ # @option opts [Boolean] :has_downloads
68
+ # @option opts [Boolean] :auto_init
69
+ #
70
+ def create_repo(name, opts = {})
71
+ opts = opts.select {|k,_| SUPPORTED_CREATE_OPTS.include? k }
72
+
73
+ # Decide whether this is an organization-repo or a user-repo ...
74
+ org = @repo_name_resolver.namespace(name)
75
+ unless org.nil? || org == @gh.user.login
76
+ opts[:organization] = org
77
+ end
78
+
79
+ return Gitomator::GitHub::Model::HostedRepo.new(
80
+ @gh.create_repo(@repo_name_resolver.name_only(name), opts)
81
+ )
82
+ end
83
+
84
+
85
+ def read_repo(name)
86
+ begin
87
+ return Gitomator::GitHub::Model::HostedRepo.new(@gh.repo repo_name_full(name))
88
+ rescue Octokit::NotFound
89
+ return nil
90
+ end
91
+ end
92
+
93
+
94
+ SUPPORTED_UPDATE_OPTS = [:name, :description, :homepage, :private,
95
+ :has_issues, :has_wiki, :has_downloads,
96
+ :default_branch]
97
+ #
98
+ # @option opts [String] :name — Name of the repo
99
+ # @option opts [String] :description — Description of the repo
100
+ # @option opts [String] :homepage — Home page of the repo
101
+ # @option opts [Boolean] :private — true makes the repository private, and false makes it public.
102
+ # @option opts [Boolean] :has_issues — true enables issues for this repo, false disables issues.
103
+ # @option opts [Boolean] :has_wiki — true enables wiki for this repo, false disables wiki.
104
+ # @option opts [Boolean] :has_downloads — true enables downloads for this repo, false disables downloads.
105
+ # @option opts [String] :default_branch — Update the default branch for this repository.
106
+ #
107
+ def update_repo(name, opts = {})
108
+ opts = opts.select {|k,_| SUPPORTED_UPDATE_OPTS.include? k }
109
+ unless opts.empty?
110
+ return Gitomator::GitHub::Model::HostedRepo.new(
111
+ @gh.edit_repository repo_name_full(name), opts)
112
+ end
113
+ end
114
+
115
+
116
+ def delete_repo(name)
117
+ @gh.delete_repo repo_name_full(name)
118
+ end
119
+
120
+ #
121
+ # For opts see http://www.rubydoc.info/gems/octokit/Octokit%2FClient%2FSearch%3Asearch_issues
122
+ #
123
+ def search_repos(query, opts = {})
124
+ gh_repos = nil
125
+ with_auto_paginate do
126
+ gh_repos = @gh.search_repos("#{query} user:#{@org}", opts).items
127
+ end
128
+
129
+ gh_repos.map {|r| Gitomator::GitHub::Model::HostedRepo.new(r)}
130
+ end
131
+
132
+
133
+ #---------------------------- TEAMS ----------------------------------
134
+
135
+ def create_team(name, opts = {})
136
+ Gitomator::GitHub::Model::Team.new(@gh.create_team(@org, {name: name}))
137
+ end
138
+
139
+ def read_team(name)
140
+ unless @name2team_cache.has_key? name
141
+ _fetch_teams()
142
+ end
143
+ if @name2team_cache[name]
144
+ Gitomator::GitHub::Model::Team.new(@name2team_cache[name])
145
+ else
146
+ return nil
147
+ end
148
+ end
149
+
150
+ #
151
+ # opts:
152
+ # - :name (String)
153
+ # - :permission (String, one of 'pull', 'push' or 'admin')
154
+ #
155
+ def update_team(name, opts)
156
+ unless @name2team_cache.has_key? name
157
+ _fetch_teams()
158
+ end
159
+ raise "No such team, '#{name}'" unless @name2team_cache.has_key? name
160
+
161
+ t = @gh.update_team(@name2team_cache[name].id, opts)
162
+ @name2team_cache[name] = t
163
+ return Gitomator::GitHub::Model::Team.new(t)
164
+ end
165
+
166
+ def delete_team(name)
167
+ unless @name2team_cache.has_key? name
168
+ _fetch_teams()
169
+ end
170
+ if @name2team_cache.has_key? name
171
+ @gh.delete_team @name2team_cache[name].id
172
+ @name2team_cache.delete(name)
173
+ return true
174
+ end
175
+ return false
176
+ end
177
+
178
+
179
+ def search_teams(query, opts={})
180
+ result = @name2team_cache.select {|k,_| k.downcase.include? query} .values
181
+ if result.empty?
182
+ _fetch_teams()
183
+ result = @name2team_cache.select {|k,_| k.downcase.include? query} .values
184
+ end
185
+ return result.map {|t| Gitomator::GitHub::Model::Team.new(t)}
186
+ end
187
+
188
+
189
+ #---------------------------------------------------------------------
190
+
191
+ def set_user_permission(user, repo, permission)
192
+ permission = _strinigify_permission(permission)
193
+ if permission.nil?
194
+ @gh.remove_collab(repo_name_full(repo), user)
195
+ else
196
+ @gh.add_collab(repo_name_full(repo), user, {permission: permission})
197
+ end
198
+ end
199
+
200
+
201
+ def set_team_permission(team, repo, permission)
202
+ permission = _strinigify_permission(permission)
203
+
204
+ t = read_team(team)
205
+ raise "No such team, #{team}" if t.nil?
206
+
207
+ if permission.nil?
208
+ @gh.remove_team_repo(t.id, repo_name_full(repo))
209
+ else
210
+ @gh.add_team_repo(t.id, repo_name_full(repo),
211
+ {
212
+ permission: permission,
213
+ accept: 'application/vnd.github.ironman-preview+json'
214
+ }
215
+ )
216
+ end
217
+ end
218
+
219
+
220
+ def _strinigify_permission(permission)
221
+ if permission.nil?
222
+ return nil
223
+ end
224
+
225
+ case permission.to_s
226
+ when 'read' || 'pull'
227
+ return 'pull'
228
+ when 'write' || 'push'
229
+ return 'push'
230
+ else
231
+ raise "Invalid permission '#{permission}'"
232
+ end
233
+ end
234
+
235
+
236
+
237
+ #--------------------------- Team Membership -------------------------
238
+
239
+ #----------- Helpers ---------
240
+
241
+ def gitomator_role_2_github_role(role)
242
+ if ['admin', 'maintainer'].include? role.to_s.downcase
243
+ return 'maintainer'
244
+ else
245
+ return 'member'
246
+ end
247
+ end
248
+
249
+ def github_role_2_gitomator_role(role)
250
+ role == 'maintainer' ? 'admin' : role
251
+ end
252
+
253
+ def team_id(team_name)
254
+ team = read_team(team_name)
255
+ raise "No such team, #{team_name}" if team.nil?
256
+ return team.id
257
+ end
258
+
259
+ #-----------------------------
260
+
261
+
262
+ def create_team_membership(team_name, user_name, role='member')
263
+ @gh.add_team_membership(team_id(team_name), user_name,
264
+ { :role => gitomator_role_2_github_role(role) }
265
+ )
266
+ return role
267
+ end
268
+
269
+
270
+ def read_team_membership(team_name, user_name)
271
+ begin
272
+ m = @gh.team_membership(team_id(team_name), user_name)
273
+ return m.nil? ? nil : m.role
274
+ rescue Octokit::NotFound
275
+ return nil
276
+ end
277
+ end
278
+
279
+
280
+ def update_team_membership(team_name, user_name, role)
281
+ @gh.add_team_membership(team_id(team_name), user_name,
282
+ { :role => gitomator_role_2_github_role(role) } )
283
+ return role
284
+ end
285
+
286
+
287
+ def delete_team_membership(team_name, user_name)
288
+ @gh.remove_team_membership(team_id(team_name), user_name)
289
+ end
290
+
291
+
292
+ #---------------------------------------------------------------------
293
+
294
+ def with_auto_paginate
295
+ raise "You must supply a block" unless block_given?
296
+ begin
297
+ @gh.auto_paginate = true # We want to get all team members
298
+ yield
299
+ ensure
300
+ @gh.auto_paginate = nil # We don't want to hit GitHub's API rate-limit
301
+ end
302
+ end
303
+
304
+
305
+ def search_users(query, opts={})
306
+
307
+ # If the team's name is specified ...
308
+ gh_users = nil
309
+ if opts[:team_name]
310
+ team = read_team(opts[:team_name])
311
+ gh_users = with_auto_paginate { @gh.team_members(team.id) }
312
+ else
313
+ gh_users = with_auto_paginate { @gh.org_members(@org) }
314
+ end
315
+
316
+ result = gh_users.map { |u| Gitomator::GitHub::Model::User.new(u) }
317
+
318
+ if query.is_a?(String) && (! query.empty?)
319
+ result = result.select {|u| u.username.include? query }
320
+ elsif query.is_a? Regexp
321
+ result = result.select {|u| query.match(u.username) }
322
+ end
323
+
324
+ return result
325
+ end
326
+
327
+
328
+ #---------------------------------------------------------------------
329
+
330
+
331
+ #
332
+ # @param src (String) of the following format 'org/repo:branch'.
333
+ # @param dst (String) of the following format 'org/repo:branch'.
334
+ #
335
+ def create_pull_request(src, dst, opts = {})
336
+
337
+ def extract_org_repo_and_branch(src_or_dst)
338
+ match = src_or_dst.match(/(.+)\/(.+):(.+)/i)
339
+ raise "Invalid src/dst, #{src_or_dst} (expected: `org_or_user/repo:branch`)" if match.nil?
340
+ return match.captures
341
+ end
342
+
343
+ src_org, src_repo, src_branch = extract_org_repo_and_branch(src)
344
+ dst_org, dst_repo, dst_branch = extract_org_repo_and_branch(dst)
345
+
346
+ unless src_repo == dst_repo
347
+ raise "Cannot create pull-request from #{src} to #{dst} (must be the same repo or a fork)."
348
+ end
349
+
350
+ Gitomator::GitHub::Model::PullRequest.new(
351
+ @gh.create_pull_request("#{dst_org}/#{dst_repo}", dst_branch,
352
+ (src_org == dst_org ? '' : "#{src_org}:") + src_branch,
353
+ opts[:title] || 'New Pull Request',
354
+ opts[:body] || 'Pull-request created using Gitomator.'
355
+ )
356
+ )
357
+ end
358
+
359
+
360
+ def read_pull_request(dst_repo, id)
361
+ begin
362
+ return Gitomator::GitHub::Model::PullRequest.new(
363
+ @gh.pull_request(repo_name_full(dst_repo), id))
364
+ rescue Octokit::NotFound
365
+ return nil
366
+ end
367
+ end
368
+
369
+
370
+ #
371
+ # @param opts [Hash]
372
+ # => @param :state [Symbol] One of :open, :close or :all (default: :open)
373
+ #
374
+ def read_pull_requests(dst_repo, opts = {})
375
+ @gh.pulls(repo_name_full(dst_repo), opts)
376
+ .map {|pr| Gitomator::GitHub::Model::PullRequest.new(pr, @gh)}
377
+ end
378
+
379
+
380
+ def merge_pull_request(dst_repo, id, message='')
381
+ Gitomator::GitHub::Model::PullRequest.new(
382
+ @gh.merge_pull_request(repo_name_full(dst_repo), id, message), @gh)
383
+ end
384
+
385
+ def close_pull_request(dst_repo, id)
386
+ Gitomator::GitHub::Model::PullRequest.new(
387
+ @gh.close_pull_request(repo_name_full(dst_repo), id), @gh)
388
+ end
389
+
390
+ def open_pull_request(dst_repo, id)
391
+ Gitomator::GitHub::Model::PullRequest.new(
392
+ @gh.update_pull_request(repo_name_full(dst_repo), id, {state: :open}), @gh)
393
+ end
394
+
395
+
396
+ #---------------------------------------------------------------------
397
+
398
+
399
+
400
+ end
401
+ end
402
+ end
@@ -0,0 +1,43 @@
1
+ module Gitomator
2
+ module GitHub
3
+ module Model
4
+ class HostedRepo
5
+
6
+
7
+ #
8
+ # @param gh_repo [Sawyer::Resource]
9
+ #
10
+ def initialize(gh_repo)
11
+ @r = gh_repo
12
+ end
13
+
14
+
15
+ def name
16
+ @r.name
17
+ end
18
+
19
+ def full_name
20
+ @r.full_name
21
+ end
22
+
23
+ def url
24
+ @r.clone_url
25
+ end
26
+
27
+ def properties
28
+ return {
29
+ :description => @r.description,
30
+ :homepage => @r.homepage,
31
+ :private => @r.private?,
32
+ :has_issues => @r.has_issues?,
33
+ :has_wiki => @r.has_wiki?,
34
+ :has_downloads => @r.has_downloads?,
35
+ :default_branch => @r.default_branch
36
+ }
37
+ end
38
+
39
+
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,81 @@
1
+ require 'gitomator/github/model/hosted_repo'
2
+
3
+ module Gitomator
4
+ module GitHub
5
+ module Model
6
+ class PullRequest
7
+
8
+
9
+ #
10
+ # @param gh_pull_request [Sawyer::Resource]
11
+ # @param octokit [Octokit::Client]
12
+ #
13
+ def initialize(gh_pull_request, octokit)
14
+ @r = gh_pull_request
15
+ @octokit = octokit
16
+ end
17
+
18
+
19
+ def id
20
+ @r.number
21
+ end
22
+
23
+ def title
24
+ @r.title
25
+ end
26
+
27
+ def created_by
28
+ @r.user.login
29
+ end
30
+
31
+ def created_at
32
+ @r.created_at
33
+ end
34
+
35
+ # @return [String] One of 'open', 'close'
36
+ #
37
+ def state
38
+ @r.state
39
+ end
40
+
41
+ #
42
+ # @return true/false/nil
43
+ #
44
+ def mergeable?
45
+ # In Octokit, the two methods `pull_request` and `pull_requests` return
46
+ # different type of objects (the one returned by `pull_requests` is missing
47
+ # the mergeable? method)
48
+ if (not @r.respond_to? :mergeable?)
49
+ @r = @octokit.pull_request(@r.base.repo.full_name, @r.number)
50
+ end
51
+
52
+ if @r.mergeable_state == 'clean'
53
+ return @r.mergeable?
54
+ else
55
+ return nil
56
+ end
57
+ end
58
+
59
+ # The "source repo"
60
+ def head_repo
61
+ Gitomator::GitHub::Model::HostedRepo.new(@r.head.repo)
62
+ end
63
+
64
+ def head_branch
65
+ @r.head.label.split(':').last
66
+ end
67
+
68
+ # The "destination repo"
69
+ def base_repo
70
+ Gitomator::GitHub::Model::HostedRepo.new(@r.base.repo)
71
+ end
72
+
73
+ def base_branch
74
+ @r.base.label.split(':').last
75
+ end
76
+
77
+
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,26 @@
1
+ module Gitomator
2
+ module GitHub
3
+ module Model
4
+ class Team
5
+
6
+
7
+ #
8
+ # @param gh_team [Sawyer::Resource]
9
+ #
10
+ def initialize(gh_team)
11
+ @r = gh_team
12
+ end
13
+
14
+ def id
15
+ @r.id
16
+ end
17
+
18
+ def name
19
+ @r.name
20
+ end
21
+
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,21 @@
1
+ module Gitomator
2
+ module GitHub
3
+ module Model
4
+ class User
5
+
6
+
7
+ #
8
+ # @param gh_user [Sawyer::Resource]
9
+ #
10
+ def initialize(gh_user)
11
+ @r = gh_user
12
+ end
13
+
14
+ def username
15
+ @r.login
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,95 @@
1
+ require 'gitomator/github'
2
+ require 'gitomator/github/base_provider'
3
+
4
+
5
+ module Gitomator
6
+ module GitHub
7
+ class TaggingProvider < Gitomator::GitHub::BaseProvider
8
+
9
+
10
+ # ---------------------- Static Factory Methods --------------------------
11
+
12
+ #
13
+ # @param config [Hash<String,Object>]
14
+ # @return [Gitomator::GitHub::HostingProvider] GitHub hosting provider.
15
+ #
16
+ def self.from_config(config = {})
17
+ return new(Gitomator::GitHub::github_client_from_config(config),
18
+ config['organization'])
19
+ end
20
+
21
+ #-------------------------------------------------------------------------
22
+
23
+
24
+ def add_tags(repo, issue_or_pr_id, *tags)
25
+ @gh.add_labels_to_an_issue(@repo_name_resolver.full_name(repo),
26
+ issue_or_pr_id, tags
27
+ ).map { |r| r.to_h }
28
+ end
29
+
30
+ def remove_tag(repo, id_or_name, tag)
31
+ @gh.remove_label(@repo_name_resolver.full_name(repo), id_or_name, tag)
32
+ .map { |r| r.to_h } # Make the result a regular Ruby Hash
33
+ end
34
+
35
+
36
+ def tags(repo, id_or_name)
37
+ repo = @repo_name_resolver.full_name(repo)
38
+ @gh.labels_for_issue(repo, id_or_name).map {|r| r.name }
39
+ end
40
+
41
+
42
+ #
43
+ # @return Enumerable of object identifiers.
44
+ #
45
+ def search(repo, label)
46
+ if label.is_a? String
47
+ q = "repo:#{@repo_name_resolver.full_name(repo)} type:issue|pr label:\"#{label}\""
48
+ @gh.search_issues(q)
49
+ .items.map {|item| item.number} # Make the result an array of issue/or id's
50
+ else
51
+ raise "Unimplemented! Search only supports a single tag at the moment."
52
+ end
53
+
54
+ end
55
+
56
+
57
+ def metadata(repo, tag=nil)
58
+ repo = @repo_name_resolver.full_name(repo)
59
+
60
+ if tag
61
+ begin
62
+ @gh.label(repo, tag).to_h # Return metadata (Hash<Symbol,String>)
63
+ rescue Octokit::NotFound
64
+ return nil
65
+ end
66
+ else
67
+ @gh.labels(repo).map {|r| [r.name, r.to_h]}.to_h # Return Hash<String,Hash<Symbol,String>>, mapping tags to their metadata
68
+ end
69
+ end
70
+
71
+
72
+
73
+ def set_metadata(repo, tag, metadata)
74
+ repo = @repo_name_resolver.full_name(repo)
75
+ color = metadata[:color] || metadata['color']
76
+ raise "The only supported metadata property is 'color'" if color.nil?
77
+ # TODO: Validate the color string (6-char-long Hex string. Any other formats supproted by GitHub?)
78
+
79
+ if metadata(repo, tag).nil?
80
+ @gh.add_label(repo, tag, color).to_h
81
+ else
82
+ @gh.update_label(repo, tag, {:color => color}).to_h
83
+ end
84
+
85
+ end
86
+
87
+
88
+ def delete_metadata(repo, tag)
89
+ @gh.delete_label!(@repo_name_resolver.full_name(repo), tag)
90
+ end
91
+
92
+
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,5 @@
1
+ module Gitomator
2
+ module Github
3
+ VERSION = "0.1.1"
4
+ end
5
+ end
@@ -0,0 +1,31 @@
1
+ require "gitomator/github/version"
2
+
3
+ module Gitomator
4
+ module GitHub
5
+
6
+
7
+ def self.github_client_from_config(config = {})
8
+ # Convert keys yo strings (to handle keys whose type is Symbol)
9
+ config = config.map {|k,v| [k.to_s, v]} .to_h
10
+
11
+ opts = {}
12
+
13
+ if config['access_token']
14
+ opts[:access_token] = config['access_token']
15
+ elsif config['username'] && config['password']
16
+ opts[:login] = config['username']
17
+ opts[:password] = config['password']
18
+ elsif config['client_id'] && config['client_secret']
19
+ opts[:client_id] = config['client_id']
20
+ opts[:client_secret] = config['client_secret']
21
+ else
22
+ raise "Invalid GitHub hosting configuration - #{config}"
23
+ end
24
+
25
+ require 'octokit'
26
+ return Octokit::Client.new(opts)
27
+ end
28
+
29
+
30
+ end
31
+ end
@@ -0,0 +1,109 @@
1
+ require 'gitomator/util/repo/name_resolver'
2
+ require 'travis'
3
+
4
+ module Gitomator
5
+ module Travis
6
+ class CIProvider
7
+
8
+
9
+ # ---------------------- Static Factory Methods --------------------------
10
+
11
+ class << self
12
+ private :new
13
+ end
14
+
15
+ #
16
+ # @param config [Hash<String,Object>]
17
+ # @return [Gitomator::GitHub::HostingProvider] GitHub hosting provider.
18
+ #
19
+ def self.from_config(config = {})
20
+ config = config.map {|k,v| [k.to_s, v] } .to_h
21
+
22
+ if config['provider'] == 'travis'
23
+ uri = ::Travis::Client::ORG_URI
24
+ elsif config['provider'] == 'travis_pro'
25
+ uri = ::Travis::Client::PRO_URI
26
+ else
27
+ raise "Invalid Travis CI provider name, #{config['provider']}."
28
+ end
29
+
30
+ if config['access_token']
31
+ access_token = config['access_token']
32
+ elsif config['github_access_token']
33
+ access_token = ::Travis.github_auth(config['github_access_token'])
34
+ else
35
+ raise "Invalid Travis CI provider config - #{config}"
36
+ end
37
+
38
+ travis_client = ::Travis::Client.new({:uri => uri, :access_token => access_token })
39
+ return new(travis_client, config['github_organization'])
40
+ end
41
+
42
+
43
+ # ------------------------------------------------------------------------
44
+
45
+
46
+ #
47
+ # @param travis_client [Travis::Client::Session]
48
+ # @param github_organization [String] - Default GitHub organization
49
+ #
50
+ def initialize(travis_client, github_organization, opts={})
51
+ raise "Travis client is nil" if travis_client.nil?
52
+ @travis = travis_client
53
+ @org = github_organization
54
+ @repo_name_resolver = Gitomator::Util::Repo::NameResolver.new(@org)
55
+ end
56
+
57
+ def name
58
+ :travis
59
+ end
60
+
61
+
62
+ def _find_repo_and_execute_block(repo)
63
+ begin
64
+ yield @travis.repo(@repo_name_resolver.full_name(repo))
65
+ rescue ::Travis::Client::NotFound
66
+ return nil
67
+ end
68
+ end
69
+
70
+
71
+ def enable_ci(repo, opts={})
72
+ _find_repo_and_execute_block(repo) {|r| r.enable}
73
+ end
74
+
75
+ def disable_ci(repo, opts={})
76
+ _find_repo_and_execute_block(repo) {|r| r.disable}
77
+ end
78
+
79
+ def ci_enabled?(repo)
80
+ _find_repo_and_execute_block(repo) {|r| r.reload.active? }
81
+ end
82
+
83
+
84
+
85
+ #
86
+ # @param blocking [Boolean]
87
+ #
88
+ def sync(blocking=false, opts={})
89
+ @travis.user.sync()
90
+ while blocking && syncing?
91
+ sleep(1)
92
+ end
93
+ end
94
+
95
+
96
+ #
97
+ # @return Boolean - Indicates whether a sync' is currently in progress.
98
+ #
99
+ def syncing?(opts={})
100
+ @travis.user.reload.syncing?
101
+ end
102
+
103
+
104
+
105
+
106
+
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,5 @@
1
+ module Gitomator
2
+ module Travis
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ require "gitomator/travis/version"
2
+
3
+ module Gitomator
4
+ module Travis
5
+ # Your code goes here...
6
+ end
7
+ end
@@ -1,3 +1,3 @@
1
1
  module Gitomator
2
- VERSION = "0.1.2.2"
2
+ VERSION = "0.1.2.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitomator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2.2
4
+ version: 0.1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joey Freund
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-27 00:00:00.000000000 Z
11
+ date: 2017-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -92,6 +92,40 @@ dependencies:
92
92
  - - ">="
93
93
  - !ruby/object:Gem::Version
94
94
  version: 1.2.8
95
+ - !ruby/object:Gem::Dependency
96
+ name: travis
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '1.8'
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: 1.8.2
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '1.8'
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: 1.8.2
115
+ - !ruby/object:Gem::Dependency
116
+ name: octokit
117
+ requirement: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - "~>"
120
+ - !ruby/object:Gem::Version
121
+ version: '4.2'
122
+ type: :runtime
123
+ prerelease: false
124
+ version_requirements: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - "~>"
127
+ - !ruby/object:Gem::Version
128
+ version: '4.2'
95
129
  description:
96
130
  email:
97
131
  - joeyfreund@gmail.com
@@ -127,6 +161,15 @@ files:
127
161
  - lib/gitomator/console.rb
128
162
  - lib/gitomator/context.rb
129
163
  - lib/gitomator/exceptions.rb
164
+ - lib/gitomator/github.rb
165
+ - lib/gitomator/github/base_provider.rb
166
+ - lib/gitomator/github/hosting_provider.rb
167
+ - lib/gitomator/github/model/hosted_repo.rb
168
+ - lib/gitomator/github/model/pull_request.rb
169
+ - lib/gitomator/github/model/team.rb
170
+ - lib/gitomator/github/model/user.rb
171
+ - lib/gitomator/github/tagging_provider.rb
172
+ - lib/gitomator/github/version.rb
130
173
  - lib/gitomator/service.rb
131
174
  - lib/gitomator/service/ci.rb
132
175
  - lib/gitomator/service/git.rb
@@ -143,6 +186,9 @@ files:
143
186
  - lib/gitomator/task/make_repos.rb
144
187
  - lib/gitomator/task/setup_team.rb
145
188
  - lib/gitomator/task/update_repo_access_permissions.rb
189
+ - lib/gitomator/travis.rb
190
+ - lib/gitomator/travis/ci_provider.rb
191
+ - lib/gitomator/travis/version.rb
146
192
  - lib/gitomator/util/repo/name_resolver.rb
147
193
  - lib/gitomator/util/script_util.rb
148
194
  - lib/gitomator/version.rb