watson-ruby 1.0.3 → 1.0.4
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 +4 -4
- data/.travis.yml +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +9 -8
- data/Rakefile +2 -2
- data/lib/watson.rb +49 -49
- data/lib/watson/bitbucket.rb +370 -371
- data/lib/watson/command.rb +468 -468
- data/lib/watson/config.rb +490 -490
- data/lib/watson/fs.rb +59 -59
- data/lib/watson/github.rb +367 -367
- data/lib/watson/parser.rb +417 -418
- data/lib/watson/printer.rb +291 -291
- data/lib/watson/remote.rb +104 -104
- data/lib/watson/version.rb +1 -1
- data/spec/config_spec.rb +111 -111
- data/spec/fs_spec.rb +47 -47
- data/spec/parser_spec.rb +124 -124
- data/watson.gemspec +21 -21
- metadata +2 -1
data/lib/watson/fs.rb
CHANGED
@@ -1,69 +1,69 @@
|
|
1
1
|
module Watson
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
2
|
+
# File system utility function class
|
3
|
+
# Contains all methods for file access in watson
|
4
|
+
class FS
|
5
|
+
|
6
|
+
# Debug printing for this class
|
7
|
+
DEBUG = false
|
8
|
+
|
9
|
+
class << self
|
10
|
+
# [todo] - Not sure whether to make check* methods return FP
|
11
|
+
# Makes it nice to get it returned and use it but
|
12
|
+
# not sure how to deal with closing the FP after
|
13
|
+
# Currently just close inside
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
15
|
+
# Include for debug_print
|
16
|
+
include Watson
|
17
|
+
|
18
|
+
###########################################################
|
19
|
+
# Check if file exists and can be opened
|
20
|
+
def check_file(file)
|
21
|
+
|
22
|
+
# Identify method entry
|
23
|
+
debug_print "#{ self } : #{ __method__ }\n"
|
24
|
+
|
25
|
+
# Error check for input
|
26
|
+
if file.length == 0
|
27
|
+
debug_print "No file specified\n"
|
28
|
+
return false
|
29
|
+
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
31
|
+
# Check if file can be opened
|
32
|
+
if File.readable?(file)
|
33
|
+
debug_print "#{ file } exists and opened successfully\n"
|
34
|
+
return true
|
35
|
+
else
|
36
|
+
debug_print "Could not open #{ file }, skipping\n"
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
end
|
40
40
|
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
42
|
+
###########################################################
|
43
|
+
# Check if directory exists and can be opened
|
44
|
+
def check_dir(dir)
|
45
|
+
|
46
|
+
# Identify method entry
|
47
|
+
debug_print "#{ self } : #{ __method__ }\n"
|
48
|
+
|
49
|
+
# Error check for input
|
50
|
+
if dir.length == 0
|
51
|
+
debug_print "No directory specified\n"
|
52
|
+
return false
|
53
|
+
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
55
|
+
# Check if directory exists
|
56
|
+
if Dir.exists?(dir)
|
57
|
+
debug_print "#{ dir } exists and opened succesfully\n"
|
58
|
+
return true
|
59
|
+
else
|
60
|
+
debug_print "Could not open #{ dir }, skipping\n"
|
61
|
+
return false
|
62
|
+
end
|
63
|
+
end
|
64
64
|
|
65
|
-
|
66
|
-
|
65
|
+
end
|
66
|
+
end
|
67
67
|
end
|
68
68
|
|
69
69
|
|
data/lib/watson/github.rb
CHANGED
@@ -1,369 +1,369 @@
|
|
1
1
|
module Watson
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
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
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
2
|
+
class Remote
|
3
|
+
# GitHub remote access class
|
4
|
+
# Contains all necessary methods to obtain access to, get issue list,
|
5
|
+
# and post issues to GitHub
|
6
|
+
class GitHub
|
7
|
+
|
8
|
+
# Debug printing for this class
|
9
|
+
DEBUG = false
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
# [todo] - Allow closing of issues from watson? Don't like that idea but maybe
|
14
|
+
# [review] - Properly scope Printer class so we dont need the Printer. for
|
15
|
+
# method calls?
|
16
|
+
# [todo] - Keep asking for user data until valid instead of leaving app
|
17
|
+
|
18
|
+
|
19
|
+
# Include for debug_print
|
20
|
+
include Watson
|
21
|
+
|
22
|
+
#############################################################################
|
23
|
+
# Setup remote access to GitHub
|
24
|
+
# Get Username, Repo, and PW and perform necessary HTTP calls to check validity
|
25
|
+
def setup(config)
|
26
|
+
|
27
|
+
# Identify method entry
|
28
|
+
debug_print "#{ self.class } : #{ __method__ }\n"
|
29
|
+
|
30
|
+
Printer.print_status "+", GREEN
|
31
|
+
print BOLD + "Obtaining OAuth Token for GitHub...\n" + RESET
|
32
|
+
|
33
|
+
# Check config to make sure no previous API exists
|
34
|
+
unless config.github_api.empty? && config.github_repo.empty?
|
35
|
+
Printer.print_status "!", RED
|
36
|
+
print BOLD + "Previous GitHub API + Repo is in RC, are you sure you want to overwrite?\n" + RESET
|
37
|
+
print " (Y)es/(N)o: "
|
38
|
+
|
39
|
+
# Get user input
|
40
|
+
_overwrite = $stdin.gets.chomp
|
41
|
+
if ["no", "n"].include?(_overwrite.downcase)
|
42
|
+
print "\n"
|
43
|
+
Printer.print_status "x", RED
|
44
|
+
print BOLD + "Not overwriting current GitHub API + repo info\n" + RESET
|
45
|
+
return false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
Printer.print_status "!", YELLOW
|
51
|
+
print BOLD + "Access to your GitHub account required to make/update issues\n" + RESET
|
52
|
+
print " See help or README for more details on GitHub/Bitbucket access\n\n"
|
53
|
+
|
54
|
+
|
55
|
+
# [todo] - Don't just check for blank password but invalid as well
|
56
|
+
# Poor mans username/password grabbing
|
57
|
+
print BOLD + "Username: " + RESET
|
58
|
+
_username = $stdin.gets.chomp
|
59
|
+
if _username.empty?
|
60
|
+
Printer.print_status "x", RED
|
61
|
+
print BOLD + "Input blank. Please enter your username!\n\n" + RESET
|
62
|
+
return false
|
63
|
+
end
|
64
|
+
|
65
|
+
# [fix] - Crossplatform password block needed, not sure if current method is safe either
|
66
|
+
# Block output to tty to prevent PW showing, Linux/Unix only :(
|
67
|
+
print BOLD + "Password: " + RESET
|
68
|
+
system "stty -echo"
|
69
|
+
_password = $stdin.gets.chomp
|
70
|
+
system "stty echo"
|
71
|
+
print "\n\n"
|
72
|
+
if _password.empty?
|
73
|
+
Printer.print_status "x", RED
|
74
|
+
print BOLD + "Input is blank. Please enter your password!\n\n" + RESET
|
75
|
+
return false
|
76
|
+
end
|
77
|
+
|
78
|
+
# HTTP Request to get OAuth Token
|
79
|
+
# GitHub API v3 - http://developer.github.com/v3/
|
80
|
+
|
81
|
+
# Create options hash to pass to Remote::http_call
|
82
|
+
# Auth URL for GitHub + SSL
|
83
|
+
# Repo scope + notes for watson
|
84
|
+
# Basic auth with user input
|
85
|
+
opts = {:url => "https://api.github.com/authorizations",
|
86
|
+
:ssl => true,
|
87
|
+
:method => "POST",
|
88
|
+
:basic_auth => [_username, _password],
|
89
|
+
:data => {"scopes" => ["repo"],
|
90
|
+
"note" => "watson",
|
91
|
+
"note_url" => "http://watson.goosecode.com/" },
|
92
|
+
:verbose => false
|
93
|
+
}
|
94
|
+
|
95
|
+
_json, _resp = Watson::Remote.http_call(opts)
|
96
|
+
|
97
|
+
# Check response to validate authorization
|
98
|
+
if _resp.code == "201"
|
99
|
+
Printer.print_status "o", GREEN
|
100
|
+
print BOLD + "Obtained OAuth Token\n\n" + RESET
|
101
|
+
else
|
102
|
+
Printer.print_status "x", RED
|
103
|
+
print BOLD + "Unable to obtain OAuth Token\n" + RESET
|
104
|
+
print " Status: #{ _resp.code } - #{ _resp.message }\n\n"
|
105
|
+
return false
|
106
|
+
end
|
107
|
+
|
108
|
+
# Store API key obtained from POST to @config.github_api
|
109
|
+
config.github_api = _json["token"]
|
110
|
+
debug_print "Config GitHub API Key updated to: #{ config.github_api }\n"
|
111
|
+
|
112
|
+
|
113
|
+
# Get repo information, if blank give error
|
114
|
+
Printer.print_status "!", YELLOW
|
115
|
+
print BOLD + "Repo information required\n" + RESET
|
116
|
+
print " Please provide owner that repo is under followed by repo name\n"
|
117
|
+
print " e.g. owner: nhmood, repo: watson (case sensitive)\n"
|
118
|
+
print " See help or README for more details on GitHub access\n\n"
|
119
|
+
|
120
|
+
print BOLD + "Owner: " + RESET
|
121
|
+
_owner = $stdin.gets.chomp
|
122
|
+
if _owner.empty?
|
123
|
+
print "\n"
|
124
|
+
Printer.print_status "x", RED
|
125
|
+
print BOLD + "Input blank. Please enter the owner the repo is under!\n\n" + RESET
|
126
|
+
return false
|
127
|
+
end
|
128
|
+
|
129
|
+
print BOLD + "Repo: " + RESET
|
130
|
+
_repo = $stdin.gets.chomp
|
131
|
+
if _repo.empty?
|
132
|
+
print "\n"
|
133
|
+
Printer.print_status "x", RED
|
134
|
+
print BOLD + "Input blank. Please enter the repo name!\n\n" + RESET
|
135
|
+
return false
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
# Make call to GitHub API to create new label for Issues
|
140
|
+
# If status returns not 404, then we have access to repo (+ it exists)
|
141
|
+
# If 422, then (most likely) the label already exists
|
142
|
+
|
143
|
+
# Create options hash to pass to Remote::http_call
|
144
|
+
# Label URL for GitHub + SSL
|
145
|
+
#
|
146
|
+
# Auth token
|
147
|
+
opts = {:url => "https://api.github.com/repos/#{ _owner }/#{ _repo }/labels",
|
148
|
+
:ssl => true,
|
149
|
+
:method => "POST",
|
150
|
+
:auth => config.github_api,
|
151
|
+
:data => {"name" => "watson",
|
152
|
+
"color" => "00AEEF" },
|
153
|
+
:verbose => false
|
154
|
+
}
|
155
|
+
|
156
|
+
_json, _resp = Watson::Remote.http_call(opts)
|
157
|
+
|
158
|
+
# [review] - This is pretty messy, maybe clean it up later
|
159
|
+
# Check response to validate repo access
|
160
|
+
if _resp.code == "404"
|
161
|
+
print "\n"
|
162
|
+
Printer.print_status "x", RED
|
163
|
+
print BOLD + "Unable to access /#{ _owner }/#{ _repo } with given credentials\n" + RESET
|
164
|
+
print " Check that credentials are correct and repository exists under user\n"
|
165
|
+
print " Status: #{ _resp.code } - #{ _resp.message }\n\n"
|
166
|
+
return false
|
167
|
+
|
168
|
+
else
|
169
|
+
# If it is anything but a 404, I THINK it means we have access...
|
170
|
+
# Will assume that until proven otherwise
|
171
|
+
print "\n"
|
172
|
+
Printer.print_status "o", GREEN
|
173
|
+
print BOLD + "Repo successfully accessed\n\n" + RESET
|
174
|
+
end
|
175
|
+
|
176
|
+
# Store owner/repo obtained from POST to @config.github_repo
|
177
|
+
config.github_repo = "#{ _owner }/#{ _repo }"
|
178
|
+
debug_print "Config GitHub API Key updated to: #{ config.github_repo }\n"
|
179
|
+
|
180
|
+
# Inform user of label creation status (created above)
|
181
|
+
Printer.print_status "+", GREEN
|
182
|
+
print BOLD + "Creating label for watson on GitHub...\n" + RESET
|
183
|
+
if _resp.code == "201"
|
184
|
+
Printer.print_status "+", GREEN
|
185
|
+
print BOLD + "Label successfully created\n" + RESET
|
186
|
+
elsif _resp.code == "422" && _json["code"] == "already_exists"
|
187
|
+
Printer.print_status "!", YELLOW
|
188
|
+
print BOLD + "Label already exists\n" + RESET
|
189
|
+
else
|
190
|
+
Printer.print_status "x", RED
|
191
|
+
print BOLD + "Unable to create label for /#{ _owner }/#{ _repo }\n" + RESET
|
192
|
+
print " Status: #{ _resp.code } - #{ _resp.message }\n"
|
193
|
+
end
|
194
|
+
|
195
|
+
# All setup has been completed, need to update RC
|
196
|
+
# Call config updater/writer from @config to write config
|
197
|
+
debug_print "Updating config with new GitHub info\n"
|
198
|
+
config.update_conf("github_api", "github_repo")
|
199
|
+
|
200
|
+
# Give user some info
|
201
|
+
print "\n"
|
202
|
+
Printer.print_status "o", GREEN
|
203
|
+
print BOLD + "GitHub successfully setup\n" + RESET
|
204
|
+
print " Issues will now automatically be retrieved from GitHub by default\n"
|
205
|
+
print " Use -p, --push to post issues to GitHub\n"
|
206
|
+
print " See help or README for more details on GitHub/Bitbucket access\n\n"
|
207
|
+
|
208
|
+
return true
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
###########################################################
|
214
|
+
# Get all remote GitHub issues and store into Config container class
|
215
|
+
|
216
|
+
def get_issues(config)
|
217
|
+
|
218
|
+
# Identify method entry
|
219
|
+
debug_print "#{ self.class } : #{ __method__ }\n"
|
220
|
+
|
221
|
+
# Only attempt to get issues if API is specified
|
222
|
+
if config.github_api.empty?
|
223
|
+
debug_print "No API found, this shouldn't be called...\n"
|
224
|
+
return false
|
225
|
+
end
|
226
|
+
|
227
|
+
|
228
|
+
# Get all open tickets
|
229
|
+
# Create options hash to pass to Remote::http_call
|
230
|
+
# Issues URL for GitHub + SSL
|
231
|
+
opts = {:url => "https://api.github.com/repos/#{ config.github_repo }/issues?labels=watson&state=open",
|
232
|
+
:ssl => true,
|
233
|
+
:method => "GET",
|
234
|
+
:auth => config.github_api,
|
235
|
+
:verbose => false
|
236
|
+
}
|
237
|
+
|
238
|
+
_json, _resp = Watson::Remote.http_call(opts)
|
239
|
+
|
240
|
+
|
241
|
+
# Check response to validate repo access
|
242
|
+
if _resp.code != "200"
|
243
|
+
Printer.print_status "x", RED
|
244
|
+
print BOLD + "Unable to access remote #{ config.github_repo }, GitHub API may be invalid\n" + RESET
|
245
|
+
print " Consider running --remote (-r) option to regenerate key\n\n"
|
246
|
+
print " Status: #{ _resp.code } - #{ _resp.message }\n"
|
247
|
+
|
248
|
+
debug_print "GitHub invalid, setting config var\n"
|
249
|
+
config.github_valid = false
|
250
|
+
return false
|
251
|
+
end
|
252
|
+
|
253
|
+
config.github_issues[:open] = _json.empty? ? Hash.new : _json
|
254
|
+
config.github_valid = true
|
255
|
+
|
256
|
+
# Get all closed tickets
|
257
|
+
# Create option hash to pass to Remote::http_call
|
258
|
+
# Issues URL for GitHub + SSL
|
259
|
+
opts = {:url => "https://api.github.com/repos/#{ config.github_repo }/issues?labels=watson&state=closed",
|
260
|
+
:ssl => true,
|
261
|
+
:method => "GET",
|
262
|
+
:auth => config.github_api,
|
263
|
+
:verbose => false
|
264
|
+
}
|
265
|
+
|
266
|
+
_json, _resp = Watson::Remote.http_call(opts)
|
267
|
+
|
268
|
+
# Check response to validate repo access
|
269
|
+
# Shouldn't be necessary if we passed the last check but just to be safe
|
270
|
+
if _resp.code != "200"
|
271
|
+
Printer.print_status "x", RED
|
272
|
+
print BOLD + "Unable to get closed issues.\n" + RESET
|
273
|
+
print " Since the open issues were obtained, something is probably wrong and you should file a bug report or something...\n"
|
274
|
+
print " Status: #{ _resp.code } - #{ _resp.message }\n"
|
275
|
+
|
276
|
+
debug_print "GitHub invalid, setting config var\n"
|
277
|
+
config.github_valid = false
|
278
|
+
return false
|
279
|
+
end
|
280
|
+
|
281
|
+
config.github_issues[:closed] = _json.empty? ? Hash.new : _json
|
282
|
+
config.github_valid = true
|
283
|
+
return true
|
284
|
+
end
|
285
|
+
|
286
|
+
|
287
|
+
###########################################################
|
288
|
+
# Post given issue to remote GitHub repo
|
289
|
+
def post_issue(issue, config)
|
290
|
+
# [todo] - Better way to identify/compare remote->local issues than md5
|
291
|
+
# Current md5 based on some things that easily can change, need better ident
|
292
|
+
|
293
|
+
# Identify method entry
|
294
|
+
debug_print "#{ self.class } : #{ __method__ }\n"
|
295
|
+
|
296
|
+
|
297
|
+
# Only attempt to get issues if API is specified
|
298
|
+
if config.github_api.empty?
|
299
|
+
debug_print "No API found, this shouldn't be called...\n"
|
300
|
+
return false
|
301
|
+
end
|
302
|
+
|
303
|
+
# Check that issue hasn't been posted already by comparing md5s
|
304
|
+
# Go through all open issues, if there is a match in md5, return out of method
|
305
|
+
# [todo] - Play with idea of making body of GitHub issue hash format to be exec'd
|
306
|
+
# Store pieces in text as :md5 => "whatever" so when we get issues we can
|
307
|
+
# call exec and turn it into a real hash for parsing in watson
|
308
|
+
# Makes watson code cleaner but not as readable comment on GitHub...?
|
309
|
+
debug_print "Checking open issues to see if already posted\n"
|
310
|
+
config.github_issues[:open].each do | _open |
|
311
|
+
if _open["body"].include?(issue[:md5])
|
312
|
+
debug_print "Found in #{ _open["title"] }, not posting\n"
|
313
|
+
return false
|
314
|
+
end
|
315
|
+
debug_print "Did not find in #{ _open["title"] }\n"
|
316
|
+
end
|
317
|
+
|
318
|
+
|
319
|
+
debug_print "Checking closed issues to see if already posted\n"
|
320
|
+
config.github_issues[:closed].each do | _closed |
|
321
|
+
if _closed["body"].include?(issue[:md5])
|
322
|
+
debug_print "Found in #{ _closed["title"] }, not posting\n"
|
323
|
+
return false
|
324
|
+
end
|
325
|
+
debug_print "Did not find in #{ _closed["title"] }\n"
|
326
|
+
end
|
327
|
+
|
328
|
+
# We didn't find the md5 for this issue in the open or closed issues, so safe to post
|
329
|
+
|
330
|
+
# Create the body text for the issue here, too long to fit nicely into opts hash
|
331
|
+
# [review] - Only give relative path for privacy when posted
|
332
|
+
_body = "__filename__ : #{ issue[:path] }\n" +
|
333
|
+
"__line #__ : #{ issue[:line_number] }\n" +
|
334
|
+
"__tag__ : #{ issue[:tag] }\n" +
|
335
|
+
"__md5__ : #{ issue[:md5] }\n\n" +
|
336
|
+
"#{ issue[:context].join }\n"
|
337
|
+
|
338
|
+
# Create option hash to pass to Remote::http_call
|
339
|
+
# Issues URL for GitHub + SSL
|
340
|
+
opts = {:url => "https://api.github.com/repos/#{ config.github_repo }/issues",
|
341
|
+
:ssl => true,
|
342
|
+
:method => "POST",
|
343
|
+
:auth => config.github_api,
|
344
|
+
:data => { "title" => issue[:title] + " [#{ issue[:path] }]",
|
345
|
+
"labels" => [issue[:tag], "watson"],
|
346
|
+
"body" => _body },
|
347
|
+
:verbose => false
|
348
|
+
}
|
349
|
+
|
350
|
+
_json, _resp = Watson::Remote.http_call(opts)
|
351
|
+
|
352
|
+
|
353
|
+
# Check response to validate repo access
|
354
|
+
# Shouldn't be necessary if we passed the last check but just to be safe
|
355
|
+
if _resp.code != "201"
|
356
|
+
Printer.print_status "x", RED
|
357
|
+
print BOLD + "Post unsuccessful. \n" + RESET
|
358
|
+
print " Since the open issues were obtained earlier, something is probably wrong and you should let someone know...\n"
|
359
|
+
print " Status: #{ _resp.code } - #{ _resp.message }\n"
|
360
|
+
return false
|
361
|
+
end
|
362
|
+
|
363
|
+
return true
|
364
|
+
end
|
365
|
+
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
369
|
end
|