watson-ruby 1.2.0 → 1.3.0

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: 6526764e5a9d056f1e208763be9871e9097c7848
4
- data.tar.gz: 13b5605c8e07c6e05ce2b035180c5327a115cbb6
3
+ metadata.gz: ca27dbddaa8f1c118cb988a0798bcac865a47c38
4
+ data.tar.gz: 1c474e7962dff2e93839f30bc3513cd27dd63153
5
5
  SHA512:
6
- metadata.gz: 385b0d1fc3a4398fa63671ef1e96ac497c2e81924e2d6b8877b1df36bbea08b6e8bfca3edd2c3860a894d970deddd9cf18d51bfa2faf3b237ff569e192c2e70b
7
- data.tar.gz: ba4a0830d8b1600da0b0506da9cedef1effb4c0cde820cc67d9b3e2261dc42a30c557201aed2a6b0df1e934c321c727da7d23f4c8d86de49661eee40f4870ddf
6
+ metadata.gz: 28d381b26c4216d36e987f5dd619ea78b0acd998e24b86df36376f68ab5283a3f53acac6141a2f913812064a1e5eb9721c618cc73673f70809f2f39f2d943efa
7
+ data.tar.gz: 60bb4d26b816e0f2276624984d01e60cd139a36feb94c8800e89948e4a2d7dab019a61a797cb22524c3591d569c5440853b1781b630ea6e7a0dfa46bd4a7259f
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- watson-ruby (1.2.0)
4
+ watson-ruby (1.3.0)
5
5
  json
6
6
 
7
7
  GEM
@@ -3,6 +3,7 @@ require_relative 'watson/config'
3
3
  require_relative 'watson/fs'
4
4
  require_relative 'watson/parser'
5
5
  require_relative 'watson/printer'
6
+ require_relative 'watson/formatters'
6
7
  require_relative 'watson/remote'
7
8
  require_relative 'watson/github'
8
9
  require_relative 'watson/bitbucket'
@@ -24,12 +24,13 @@ module Watson
24
24
  # Identify method entry
25
25
  debug_print "#{ self.class } : #{ __method__ }\n"
26
26
 
27
- Printer.print_status "+", GREEN
27
+ formatter = Printer.new(config).build_formatter
28
+ formatter.print_status "+", GREEN
28
29
  print BOLD + "Attempting to access Bitbucket...\n" + RESET
29
30
 
30
31
  # Check config to make sure no previous repo info exists
31
32
  unless config.bitbucket_api.empty? && config.bitbucket_repo.empty?
32
- Printer.print_status "!", RED
33
+ formatter.print_status "!", RED
33
34
  print BOLD + "Previous Bitbucket API + Repo is in RC, are you sure you want to overwrite?\n" + RESET
34
35
  print " (Y)es/(N)o: "
35
36
 
@@ -37,14 +38,14 @@ module Watson
37
38
  _overwrite = $stdin.gets.chomp
38
39
  if ["no", "n"].include?(_overwrite.downcase)
39
40
  print "\n"
40
- Printer.print_status "x", RED
41
+ formatter.print_status "x", RED
41
42
  print BOLD + "Not overwriting current Bitbucket API + repo info\n" + RESET
42
43
  return false
43
44
  end
44
45
  end
45
46
 
46
47
 
47
- Printer.print_status "!", YELLOW
48
+ formatter.print_status "!", YELLOW
48
49
  print BOLD + "Access to your Bitbucket account required to make/update issues\n" + RESET
49
50
  print " See help or README for more details on GitHub/Bitbucket access\n\n"
50
51
 
@@ -52,7 +53,7 @@ module Watson
52
53
  # [todo] - Bitbucket OAuth not implemented yet so warn user about HTTP Auth
53
54
  # Bitbucket doesn't have nonOAuth flow that GitHub does :(
54
55
  # Even if I use OAuth lib, still need to validate from webview which is lame
55
- Printer.print_status "!", RED
56
+ formatter.print_status "!", RED
56
57
  print BOLD + "Bitbucket OAuth not implemented yet.\n" + RESET;
57
58
  print " Basic HTTP Auth in use, will request PW entry every time.\n\n"
58
59
 
@@ -62,7 +63,7 @@ module Watson
62
63
  print BOLD + "Username: " + RESET
63
64
  _username = $stdin.gets.chomp
64
65
  if _username.empty?
65
- Printer.print_status "x", RED
66
+ formatter.print_status "x", RED
66
67
  print BOLD + "Input blank. Please enter your username!\n\n" + RESET
67
68
  return false
68
69
  end
@@ -70,7 +71,7 @@ module Watson
70
71
  print "\n"
71
72
 
72
73
  # Get repo information, if blank give error
73
- Printer.print_status "!", YELLOW
74
+ formatter.print_status "!", YELLOW
74
75
  print BOLD + "Repo information required\n" + RESET
75
76
  print " Please provide owner that repo is under followed by repo name\n"
76
77
  print " e.g. owner: nhmood, repo: watson (case sensitive)\n"
@@ -80,7 +81,7 @@ module Watson
80
81
  _owner = $stdin.gets.chomp
81
82
  if _owner.empty?
82
83
  print "\n"
83
- Printer.print_status "x", RED
84
+ formatter.print_status "x", RED
84
85
  print BOLD + "Input blank. Please enter the owner the repo is under!\n\n" + RESET
85
86
  return false
86
87
  end
@@ -89,7 +90,7 @@ module Watson
89
90
  _repo = $stdin.gets.chomp
90
91
  if _repo.empty?
91
92
  print "\n"
92
- Printer.print_status "x", RED
93
+ formatter.print_status "x", RED
93
94
  print BOLD + "Input blank. Please enter the repo name!\n\n" + RESET
94
95
  return false
95
96
  end
@@ -104,7 +105,7 @@ module Watson
104
105
  system "stty echo"
105
106
  print "\n"
106
107
  if _password.empty?
107
- Printer.print_status "x", RED
108
+ formatter.print_status "x", RED
108
109
  print BOLD + "Input is blank. Please enter your password!\n\n" + RESET
109
110
  return false
110
111
  end
@@ -127,11 +128,11 @@ module Watson
127
128
  # Check response to validate authorization
128
129
  if _resp.code == "200"
129
130
  print "\n"
130
- Printer.print_status "o", GREEN
131
+ formatter.print_status "o", GREEN
131
132
  print BOLD + "Successfully accessed remote repo with given credentials\n" + RESET
132
133
  else
133
134
  print "\n"
134
- Printer.print_status "x", RED
135
+ formatter.print_status "x", RED
135
136
  print BOLD + "Unable to access /#{ _owner }/#{ _repo } with given credentials\n" + RESET
136
137
  print " Check that credentials are correct and repository exists under user\n"
137
138
  print " Status: #{ _resp.code } - #{ _resp.message }\n\n"
@@ -152,10 +153,10 @@ module Watson
152
153
  config.update_conf("bitbucket_api", "bitbucket_repo")
153
154
 
154
155
  print "\n"
155
- Printer.print_status "o", GREEN
156
+ formatter.print_status "o", GREEN
156
157
  print BOLD + "Bitbucket successfully setup\n" + RESET
157
158
  print " Issues will now automatically be retrieved from Bitbucket by default\n"
158
- print " Use -p, --push to post issues to GitHub\n"
159
+ print " Use -u, --update to post issues to GitHub\n"
159
160
  print " See help or README for more details on GitHub/Bitbucket access\n\n"
160
161
 
161
162
  return true
@@ -170,6 +171,12 @@ module Watson
170
171
  # Identify method entry
171
172
  debug_print "#{ self.class } : #{ __method__ }\n"
172
173
 
174
+
175
+ # Set up formatter for printing errors
176
+ # config.output_format should be set based on less status by now
177
+ formatter = Printer.new(config).build_formatter
178
+
179
+
173
180
  # Only attempt to get issues if API is specified
174
181
  if config.bitbucket_api.empty?
175
182
  debug_print "No API found, this shouldn't be called...\n"
@@ -179,7 +186,7 @@ module Watson
179
186
  # If we haven't obtained the pw from user yet, do it
180
187
  if config.bitbucket_pw.empty?
181
188
  # No OAuth for Bitbucket yet, gotta get user password in order to make calls :(
182
- Printer.print_status "!", YELLOW
189
+ formatter.print_status "!", YELLOW
183
190
  print BOLD + "Bitbucket password required for remote checking/posting.\n" + RESET
184
191
  print " Password: "
185
192
 
@@ -213,7 +220,7 @@ module Watson
213
220
 
214
221
  # Check response to validate repo access
215
222
  if _resp.code != "200"
216
- Printer.print_status "x", RED
223
+ formatter.print_status "x", RED
217
224
  print BOLD + "Unable to access remote #{ config.bitbucket_repo }, Bitbucket API may be invalid\n" + RESET
218
225
  print " Make sure you have created an issue tracker for your repository on the Bitbucket website\n"
219
226
  print " Consider running --remote (-r) option to regenerate/validate settings\n"
@@ -244,7 +251,7 @@ module Watson
244
251
  # Check response to validate repo access
245
252
  # Shouldn't be necessary if we passed the last check but just to be safe
246
253
  if _resp.code != "200"
247
- Printer.print_status "x", RED
254
+ formatter.print_status "x", RED
248
255
  print BOLD + "Unable to get closed issues.\n" + RESET
249
256
  print " Since the open issues were obtained, something is probably wrong and you should file a bug report or something...\n"
250
257
  print " Status: #{ _resp.code } - #{ _resp.message }\n"
@@ -270,6 +277,11 @@ module Watson
270
277
  debug_print "#{self.class} : #{__method__}\n"
271
278
 
272
279
 
280
+ # Set up formatter for printing errors
281
+ # config.output_format should be set based on less status by now
282
+ formatter = Printer.new(config).build_formatter
283
+
284
+
273
285
  # Only attempt to get issues if API is specified
274
286
  if config.bitbucket_api.empty?
275
287
  debug_print "No API found, this shouldn't be called...\n"
@@ -304,7 +316,7 @@ module Watson
304
316
  # If we haven't obtained the pw from user yet, do it
305
317
  if config.bitbucket_pw.empty?
306
318
  # No OAuth for Bitbucket yet, gotta get user password in order to make calls :(
307
- Printer.print_status "!", YELLOW
319
+ formatter.print_status "!", YELLOW
308
320
  print BOLD + "Bitbucket password required for remote checking/posting.\n" + RESET
309
321
  print " Password: "
310
322
 
@@ -354,7 +366,7 @@ module Watson
354
366
  # Check response to validate repo access
355
367
  # Shouldn't be necessary if we passed the last check but just to be safe
356
368
  if _resp.code != "200"
357
- Printer.print_status "x", RED
369
+ formatter.print_status "x", RED
358
370
  print BOLD + "Post unsuccessful. \n" + RESET
359
371
  print " Since the open issues were obtained earlier, something is probably wrong and you should let someone know...\n"
360
372
  print " Status: #{ _resp.code } - #{ _resp.message }\n"
@@ -23,18 +23,20 @@ module Watson
23
23
  debug_print "#{ self } : #{ __method__ }\n"
24
24
 
25
25
  # List of possible flags, used later in parsing and for user reference
26
- _flag_list = ["-c", "--context-depth",
27
- "-d", "--dirs",
28
- "-f", "--files",
29
- "-h", "--help",
30
- "-i", "--ignore",
31
- "-p", "--parse-depth",
32
- "-r", "--remote",
33
- "-s", "--show",
34
- "-t", "--tags",
35
- "-u", "--update",
36
- "-v", "--version"
37
- ]
26
+ _flag_list = %w[
27
+ -c --context-depth
28
+ -d --dirs
29
+ -f --files
30
+ -h --help
31
+ -i --ignore
32
+ -p --parse-depth
33
+ -r --remote
34
+ -s --show
35
+ -t --tags
36
+ --format
37
+ -u --update
38
+ -v --version
39
+ ]
38
40
 
39
41
 
40
42
  # If we get the version or help flag, ignore all other flags
@@ -118,6 +120,10 @@ module Watson
118
120
  debug_print "Found -i/--ignore argument\n"
119
121
  set_ignores(_flag_args)
120
122
 
123
+ when '--format'
124
+ debug_print "Found --format argument\n"
125
+ set_output_format(_flag_args)
126
+
121
127
  when "-p", "--parse-depth"
122
128
  debug_print "Found -r/--parse-depth argument\n"
123
129
  set_parse_depth(_flag_args)
@@ -423,14 +429,15 @@ module Watson
423
429
  # Identify method entry
424
430
  debug_print "#{ self } : #{ __method__ }\n"
425
431
 
426
- Printer.print_header
432
+ formatter = Printer.new(@config).build_formatter
433
+ formatter.print_header
427
434
 
428
435
  print BOLD + "Existing Remotes:\n" + RESET
429
436
 
430
437
  # Check the config for any remote entries (GitHub or Bitbucket) and print
431
438
  # We *should* always have a repo + API together, but API should be enough
432
439
  if @config.github_api.empty? && @config.bitbucket_api.empty?
433
- Printer.print_status "!", YELLOW
440
+ formatter.print_status "!", YELLOW
434
441
  print BOLD + "No remotes currently exist\n\n" + RESET
435
442
  end
436
443
 
@@ -458,7 +465,7 @@ module Watson
458
465
  Watson::Remote::Bitbucket.setup(@config)
459
466
  end
460
467
  elsif args.length > 1
461
- Printer.print_status "x", RED
468
+ formatter.print_status "x", RED
462
469
  puts <<-SUMMERY.gsub(/^ {,8}/, '')
463
470
  #{BOLD}Incorrect arguments passed#{RESET}
464
471
  Please specify either Github or Bitbucket to setup remote
@@ -470,6 +477,30 @@ module Watson
470
477
  end
471
478
  end
472
479
 
480
+ ###########################################################
481
+ # set_output_format
482
+ # Set format watson should output in
483
+ def set_output_format(args)
484
+ # Identify method entry
485
+ debug_print "#{ self } : #{ __method__ }\n"
486
+
487
+ # Need at least one file in args
488
+ unless args.length == 1
489
+ debug_print "Invalid argument passed\n"
490
+ return false
491
+ end
492
+
493
+ @config.output_format = case args.pop.to_s
494
+ when 'j', 'json'
495
+ Watson::Formatters::JsonFormatter
496
+ when 'unite'
497
+ Watson::Formatters::UniteFormatter
498
+ else
499
+ Watson::Formatters::DefaultFormatter
500
+ end
501
+
502
+ debug_print "Updated output_format to: #{@config.output_format}\n"
503
+ end
473
504
 
474
505
  ###########################################################
475
506
  # set_show
@@ -35,7 +35,7 @@ module Watson
35
35
 
36
36
  # Entries that watson should show
37
37
  attr_accessor :show_type
38
-
38
+
39
39
  # Flag for whether less is avaliable to print results
40
40
  attr_reader :use_less
41
41
  # Flag for where the temp file for printing is located
@@ -66,7 +66,8 @@ module Watson
66
66
  attr_accessor :bitbucket_repo
67
67
  # Hash to hold list of all Bitbucket issues associated with repo
68
68
  attr_accessor :bitbucket_issues
69
-
69
+ # Formatter
70
+ attr_accessor :output_format
70
71
 
71
72
  ###########################################################
72
73
  # Config initialization method to setup necessary parameters, states, and vars
@@ -119,9 +120,10 @@ module Watson
119
120
  @bitbucket_api = ""
120
121
  @bitbucket_pw = ""
121
122
  @bitbucket_repo = ""
122
- @bitbucket_issues = {:open => Hash.new(),
123
- :closed => Hash.new()
124
- }
123
+ @bitbucket_issues = {:open => Hash.new(),
124
+ :closed => Hash.new()
125
+ }
126
+ @output_format = Watson::Formatters::DefaultFormatter
125
127
  end
126
128
 
127
129
 
@@ -0,0 +1,6 @@
1
+ module Watson::Formatters
2
+ autoload :BaseFormatter, 'watson/formatters/base_formatter'
3
+ autoload :DefaultFormatter, 'watson/formatters/default_formatter'
4
+ autoload :JsonFormatter, 'watson/formatters/json_formatter'
5
+ autoload :UniteFormatter, 'watson/formatters/unite_formatter'
6
+ end
@@ -0,0 +1,10 @@
1
+ module Watson::Formatters
2
+ class BaseFormatter
3
+ include Watson
4
+ DEBUG = false
5
+
6
+ def initialize(config)
7
+ @config = config
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,196 @@
1
+ module Watson::Formatters
2
+ class DefaultFormatter < BaseFormatter
3
+ def initialize(config)
4
+ super
5
+
6
+ @output = STDOUT
7
+ end
8
+
9
+ def run(structure)
10
+ debug_print "#{self} : #{__method__}\n"
11
+
12
+ output_result do
13
+ # Check Config to see if we have access to less for printing
14
+ # If so, open our temp file as the output to write to
15
+ # Else, just print out to STDOUT
16
+ # Print header for output
17
+ debug_print "Printing Header\n"
18
+
19
+ print_header
20
+
21
+ # Print out structure that was passed to this Printer
22
+ debug_print "Starting structure printing\n"
23
+ print_structure(structure)
24
+ end
25
+ end
26
+
27
+ ###########################################################
28
+ # Standard header print for class call (uses member cprint)
29
+ def print_header
30
+ # Identify method entry
31
+ debug_print "#{ self } : #{ __method__ }\n"
32
+
33
+ # Header
34
+ cprint <<-MESSAGE.gsub(/^ {6}/, '')
35
+ #{BOLD}------------------------------#{RESET}
36
+ #{BOLD}watson#{RESET} - #{RESET}#{BOLD}#{YELLOW}inline issue manager#{RESET}
37
+
38
+ Run in: #{Dir.pwd}
39
+ Run @ #{Time.now.asctime}
40
+ #{BOLD}------------------------------\n#{RESET}
41
+ MESSAGE
42
+ end
43
+
44
+ ###########################################################
45
+ # Status printer for member call (uses member cprint)
46
+ # Print status block in standard format
47
+ def print_status(msg, color)
48
+ cprint "#{RESET}#{BOLD}#{WHITE}[ "
49
+ cprint "#{msg} ", color
50
+ cprint "#{WHITE}] #{RESET}"
51
+ end
52
+
53
+ private
54
+
55
+ def output_result(&block)
56
+ debug_print "#{self} : #{__method__}\n"
57
+ @output = if @config.use_less
58
+ debug_print "Unix less avaliable, setting output to #{@config.tmp_file}\n"
59
+ File.open(@config.tmp_file, 'w')
60
+ else
61
+ debug_print "Unix less is unavaliable, setting output to STDOUT\n"
62
+ STDOUT
63
+ end
64
+
65
+ yield
66
+
67
+ # If we are using less, close the output file, display with less, then delete
68
+ if @config.use_less
69
+ @output.close
70
+ # [review] - Way of calling a native Ruby less?
71
+ system("less -R #{@config.tmp_file}")
72
+ debug_print "File displayed with less, now deleting...\n"
73
+ File.delete(@config.tmp_file)
74
+ end
75
+ end
76
+
77
+ ###########################################################
78
+ # Go through all files and directories and call necessary printing methods
79
+ # Print all individual entries, call print_structure on each subdir
80
+ def print_structure(structure)
81
+ # Identify method entry
82
+ debug_print "#{self} : #{__method__}\n"
83
+
84
+ # First go through all the files in the current structure
85
+ # The current "structure" should reflect a dir/subdir
86
+ structure[:files].each do |file|
87
+ debug_print "Printing info for #{file}\n"
88
+ print_entry(file)
89
+ end
90
+
91
+ # Next go through all the subdirs and pass them to print_structure
92
+ structure[:subdirs].each do |subdir|
93
+ debug_print "Entering #{subdir} to print further\n"
94
+ print_structure(subdir)
95
+ end
96
+ end
97
+
98
+ ###########################################################
99
+ # Individual entry printer
100
+ # Uses issue hash to format printed output
101
+ def print_entry(entry)
102
+ # Identify method entry
103
+ debug_print "#{self} : #{__method__}\n"
104
+
105
+ # If no issues for this file, print that and break
106
+ # The filename print is repetative, but reduces another check later
107
+ if entry[:has_issues]
108
+ return true if @config.show_type == 'clean'
109
+
110
+ debug_print "Issues found for #{entry}\n"
111
+ cprint "\n"
112
+ print_status 'x', RED
113
+ cprint " #{BOLD}#{UNDERLINE}#{RED}#{entry[:relative_path]}#{RESET}\n"
114
+ else
115
+ unless @config.show_type == 'dirty'
116
+ debug_print "No issues for #{entry}\n"
117
+ print_status 'o', GREEN
118
+ cprint " #{BOLD}#{UNDERLINE}#{GREEN}#{entry[:relative_path]}#{RESET}\n"
119
+ return true
120
+ end
121
+ end
122
+
123
+ # [review] - Should the tag structure be self contained in the hash
124
+ # Or is it ok to reference @config to figure out the tags
125
+ @config.tag_list.each do | tag |
126
+ debug_print "Checking for #{ tag }\n"
127
+ print_tag(tag, entry)
128
+ end
129
+ end
130
+
131
+ def print_tag(tag, entry)
132
+ # [review] - Better way to ignore tags through structure (hash) data
133
+ # Maybe have individual has_issues for each one?
134
+ if entry[tag].size.zero?
135
+ debug_print "#{ tag } has no issues, skipping\n"
136
+ return
137
+ end
138
+
139
+ debug_print "#{tag} has issues in it, print!\n"
140
+ print_status "#{tag}", BLUE
141
+ cprint "\n"
142
+
143
+ # Go through each issue in tag
144
+ entry[tag].each do |issue|
145
+ cprint "#{WHITE} line #{issue[:line_number]} - #{RESET}#{BOLD}#{issue[:title]}#{RESET}"
146
+
147
+ # Check to see if it has been resolved on GitHub/Bitbucket
148
+ debug_print "Checking if issue has been resolved\n"
149
+ @config.github_issues[:closed].each do | _closed |
150
+ if _closed["body"].include?(issue[:md5])
151
+ debug_print "Found in #{ _closed[:comment] }, not posting\n"
152
+ cprint <<-MESSAGE.gsub(/^(\s+)/, '')
153
+ #{BOLD} [#{RESET}#{GREEN}#{BOLD}Resolved on GitHub#{RESET}#{BOLD}]#{RESET}
154
+ MESSAGE
155
+ end
156
+ debug_print "Did not find in #{ _closed[:comment] }\n"
157
+ end
158
+
159
+ debug_print "Checking if issue has been resolved\n"
160
+ @config.bitbucket_issues[:closed].each do |closed|
161
+ if closed['content'].include?(issue[:md5])
162
+ debug_print "Found in #{ closed["content"] }, not posting\n"
163
+ cprint <<-MESSAGE.gsub(/^(\s+)/, '')
164
+ #{BOLD} [#{RESET}#{GREEN}#{BOLD}Resolved on Bitbucket#{RESET}#{BOLD}]#{RESET}
165
+ MESSAGE
166
+ end
167
+ debug_print "Did not find in #{ closed["title"] }\n"
168
+ end
169
+
170
+ cprint "\n"
171
+ end
172
+
173
+ cprint "\n"
174
+ end
175
+
176
+ ###########################################################
177
+ # Custom color print for member call
178
+ # Allows not only for custom color printing but writing to file vs STDOUT
179
+ def cprint(msg = '', color = '')
180
+ # Identify method entry
181
+ debug_print "#{self} : #{__method__}\n"
182
+
183
+ # This little check will allow us to take a Constant defined color
184
+ # As well as a [0-256] value if specified
185
+ if color.is_a?(String)
186
+ debug_print "Custom color specified for cprint\n"
187
+ @output.write(color)
188
+ elsif color.between?(0, 256)
189
+ debug_print "No or Default color specified for cprint\n"
190
+ @output.write("\e[38;5;#{color}m")
191
+ end
192
+
193
+ @output.write(msg)
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,13 @@
1
+ require 'json'
2
+
3
+ module Watson::Formatters
4
+ class JsonFormatter < BaseFormatter
5
+ def run(structure)
6
+ debug_print "#{self} : #{__method__}\n"
7
+
8
+ File.open(@config.tmp_file, 'w') do |f|
9
+ f.write(structure.to_json)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,60 @@
1
+ require 'json'
2
+
3
+ module Watson::Formatters
4
+ class UniteFormatter < BaseFormatter
5
+ def run(structure)
6
+ debug_print "#{self} : #{__method__}\n"
7
+
8
+ candidates = generate_candidates(structure)
9
+
10
+ File.open(@config.tmp_file, 'w') do |f|
11
+ f.write(candidates.to_json)
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def generate_candidates(structure)
18
+ candidates = []
19
+
20
+ structure[:files].each do |file|
21
+ original_candidate = {
22
+ action__path: file[:absolute_path],
23
+ action__absolute_path: file[:absolute_path],
24
+ action__relative_path: file[:relative_path],
25
+ is_multiline: 1,
26
+ action__has_issue: file[:has_issues] ? 1 : 0,
27
+ action__tags: @config.tag_list,
28
+ }
29
+
30
+ if file[:has_issues]
31
+ @config.tag_list.each do |tag|
32
+ file[tag].each do |info|
33
+ candidates << original_candidate.dup.merge(create_candidate(file, info))
34
+ end
35
+ end
36
+ else
37
+ original_candidate[:word] = "[o] #{file[:relative_path]}"
38
+ candidates << original_candidate
39
+ end
40
+ end
41
+
42
+ structure[:subdirs].each do |dir|
43
+ candidates += generate_candidates(dir)
44
+ end
45
+
46
+ candidates
47
+ end
48
+
49
+ def create_candidate(file, info)
50
+ {
51
+ word: "[x] #{file[:relative_path]}:#{info[:line_number]}\n #{info[:tag]} - #{info[:title]}",
52
+ action__line: info[:line_number],
53
+ action__tag: info[:tag],
54
+ action__md5: info[:md5],
55
+ action__title: info[:title],
56
+ action__context: info[:context],
57
+ }
58
+ end
59
+ end
60
+ end
@@ -11,7 +11,7 @@ module Watson
11
11
  class << self
12
12
 
13
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
14
+ # [review] - Properly scope formatter class so we dont need the formatter. for
15
15
  # method calls?
16
16
  # [todo] - Keep asking for user data until valid instead of leaving app
17
17
 
@@ -27,12 +27,13 @@ module Watson
27
27
  # Identify method entry
28
28
  debug_print "#{ self.class } : #{ __method__ }\n"
29
29
 
30
- Printer.print_status "+", GREEN
30
+ formatter = Printer.new(config).build_formatter
31
+ formatter.print_status "+", GREEN
31
32
  print BOLD + "Obtaining OAuth Token for GitHub...\n" + RESET
32
33
 
33
34
  # Check config to make sure no previous API exists
34
35
  unless config.github_api.empty? && config.github_repo.empty? && config.github_endpoint.empty?
35
- Printer.print_status "!", RED
36
+ formatter.print_status "!", RED
36
37
  print BOLD + "Previous GitHub API + Repo is in RC, are you sure you want to overwrite?\n" + RESET
37
38
  print " (Y)es/(N)o: "
38
39
 
@@ -40,19 +41,18 @@ module Watson
40
41
  _overwrite = $stdin.gets.chomp
41
42
  if ["no", "n"].include?(_overwrite.downcase)
42
43
  print "\n\n"
43
- Printer.print_status "x", RED
44
+ formatter.print_status "x", RED
44
45
  print BOLD + "Not overwriting current GitHub API + repo info\n" + RESET
45
46
  return false
46
47
  end
47
48
  end
48
49
 
49
- print "\n\n"
50
50
 
51
- Printer.print_status "!", YELLOW
51
+ formatter.print_status "!", YELLOW
52
52
  print BOLD + "Access to your GitHub account required to make/update issues\n" + RESET
53
53
  print " See help or README for more details on GitHub/Bitbucket access\n\n"
54
54
 
55
- Printer.print_status "!", GREEN
55
+ formatter.print_status "!", GREEN
56
56
  print BOLD + "Is this a GitHub Enterprise account?\n" + RESET
57
57
  print " (Y)es/(N)o: "
58
58
 
@@ -63,7 +63,7 @@ module Watson
63
63
  print BOLD + "GitHub API Endpoint: " + RESET
64
64
  _endpoint = $stdin.gets.chomp.chomp('/')
65
65
  if _endpoint.empty?
66
- Printer.print_status "x", RED
66
+ formatter.print_status "x", RED
67
67
  print BOLD + "Input blank. Please enter your API endpoint!\n\n" + RESET
68
68
  return false
69
69
  end
@@ -78,7 +78,7 @@ module Watson
78
78
  print BOLD + "Username: " + RESET
79
79
  _username = $stdin.gets.chomp
80
80
  if _username.empty?
81
- Printer.print_status "x", RED
81
+ formatter.print_status "x", RED
82
82
  print BOLD + "Input blank. Please enter your username!\n\n" + RESET
83
83
  return false
84
84
  end
@@ -91,7 +91,7 @@ module Watson
91
91
  system "stty echo"
92
92
  print "\n\n"
93
93
  if _password.empty?
94
- Printer.print_status "x", RED
94
+ formatter.print_status "x", RED
95
95
  print BOLD + "Input is blank. Please enter your password!\n\n" + RESET
96
96
  return false
97
97
  end
@@ -119,10 +119,10 @@ module Watson
119
119
 
120
120
  # Check response to validate authorization
121
121
  if _resp.code == "201"
122
- Printer.print_status "o", GREEN
122
+ formatter.print_status "o", GREEN
123
123
  print BOLD + "Obtained OAuth Token\n\n" + RESET
124
124
  else
125
- Printer.print_status "x", RED
125
+ formatter.print_status "x", RED
126
126
  print BOLD + "Unable to obtain OAuth Token\n" + RESET
127
127
  print " Status: #{ _resp.code } - #{ _resp.message }\n\n"
128
128
  return false
@@ -136,7 +136,7 @@ module Watson
136
136
 
137
137
 
138
138
  # Get repo information, if blank give error
139
- Printer.print_status "!", YELLOW
139
+ formatter.print_status "!", YELLOW
140
140
  print BOLD + "Repo information required\n" + RESET
141
141
  print " Please provide owner that repo is under followed by repo name\n"
142
142
  print " e.g. owner: nhmood, repo: watson (case sensitive)\n"
@@ -146,7 +146,7 @@ module Watson
146
146
  _owner = $stdin.gets.chomp
147
147
  if _owner.empty?
148
148
  print "\n"
149
- Printer.print_status "x", RED
149
+ formatter.print_status "x", RED
150
150
  print BOLD + "Input blank. Please enter the owner the repo is under!\n\n" + RESET
151
151
  return false
152
152
  end
@@ -155,7 +155,7 @@ module Watson
155
155
  _repo = $stdin.gets.chomp
156
156
  if _repo.empty?
157
157
  print "\n"
158
- Printer.print_status "x", RED
158
+ formatter.print_status "x", RED
159
159
  print BOLD + "Input blank. Please enter the repo name!\n\n" + RESET
160
160
  return false
161
161
  end
@@ -184,7 +184,7 @@ module Watson
184
184
  # Check response to validate repo access
185
185
  if _resp.code == "404"
186
186
  print "\n"
187
- Printer.print_status "x", RED
187
+ formatter.print_status "x", RED
188
188
  print BOLD + "Unable to access /#{ _owner }/#{ _repo } with given credentials\n" + RESET
189
189
  print " Check that credentials are correct and repository exists under user\n"
190
190
  print " Status: #{ _resp.code } - #{ _resp.message }\n\n"
@@ -194,7 +194,7 @@ module Watson
194
194
  # If it is anything but a 404, I THINK it means we have access...
195
195
  # Will assume that until proven otherwise
196
196
  print "\n"
197
- Printer.print_status "o", GREEN
197
+ formatter.print_status "o", GREEN
198
198
  print BOLD + "Repo successfully accessed\n\n" + RESET
199
199
  end
200
200
 
@@ -203,16 +203,16 @@ module Watson
203
203
  debug_print "Config GitHub API Key updated to: #{ config.github_repo }\n"
204
204
 
205
205
  # Inform user of label creation status (created above)
206
- Printer.print_status "+", GREEN
206
+ formatter.print_status "+", GREEN
207
207
  print BOLD + "Creating label for watson on GitHub...\n" + RESET
208
208
  if _resp.code == "201"
209
- Printer.print_status "+", GREEN
209
+ formatter.print_status "+", GREEN
210
210
  print BOLD + "Label successfully created\n" + RESET
211
211
  elsif _resp.code == "422" && _json["code"] == "already_exists"
212
- Printer.print_status "!", YELLOW
212
+ formatter.print_status "!", YELLOW
213
213
  print BOLD + "Label already exists\n" + RESET
214
214
  else
215
- Printer.print_status "x", RED
215
+ formatter.print_status "x", RED
216
216
  print BOLD + "Unable to create label for /#{ _owner }/#{ _repo }\n" + RESET
217
217
  print " Status: #{ _resp.code } - #{ _resp.message }\n"
218
218
  end
@@ -224,7 +224,7 @@ module Watson
224
224
 
225
225
  # Give user some info
226
226
  print "\n"
227
- Printer.print_status "o", GREEN
227
+ formatter.print_status "o", GREEN
228
228
  print BOLD + "GitHub successfully setup\n" + RESET
229
229
  print " Issues will now automatically be retrieved from GitHub by default\n"
230
230
  print " Use -u, --update to post issues to GitHub\n"
@@ -243,6 +243,10 @@ module Watson
243
243
  # Identify method entry
244
244
  debug_print "#{ self.class } : #{ __method__ }\n"
245
245
 
246
+ # Set up formatter for printing errors
247
+ # config.output_format should be set based on less status by now
248
+ formatter = Printer.new(config).build_formatter
249
+
246
250
  # Only attempt to get issues if API is specified
247
251
  if config.github_api.empty?
248
252
  debug_print "No API found, this shouldn't be called...\n"
@@ -265,7 +269,7 @@ module Watson
265
269
 
266
270
  # Check response to validate repo access
267
271
  if _resp.code != "200"
268
- Printer.print_status "x", RED
272
+ formatter.print_status "x", RED
269
273
  print BOLD + "Unable to access remote #{ config.github_repo }, GitHub API may be invalid\n" + RESET
270
274
  print " Consider running --remote (-r) option to regenerate key\n\n"
271
275
  print " Status: #{ _resp.code } - #{ _resp.message }\n"
@@ -293,7 +297,7 @@ module Watson
293
297
  # Check response to validate repo access
294
298
  # Shouldn't be necessary if we passed the last check but just to be safe
295
299
  if _resp.code != "200"
296
- Printer.print_status "x", RED
300
+ formatter.print_status "x", RED
297
301
  print BOLD + "Unable to get closed issues.\n" + RESET
298
302
  print " Since the open issues were obtained, something is probably wrong and you should file a bug report or something...\n"
299
303
  print " Status: #{ _resp.code } - #{ _resp.message }\n"
@@ -319,6 +323,11 @@ module Watson
319
323
  debug_print "#{ self.class } : #{ __method__ }\n"
320
324
 
321
325
 
326
+ # Set up formatter for printing errors
327
+ # config.output_format should be set based on less status by now
328
+ formatter = Printer.new(config).build_formatter
329
+
330
+
322
331
  # Only attempt to get issues if API is specified
323
332
  if config.github_api.empty?
324
333
  debug_print "No API found, this shouldn't be called...\n"
@@ -378,7 +387,7 @@ module Watson
378
387
  # Check response to validate repo access
379
388
  # Shouldn't be necessary if we passed the last check but just to be safe
380
389
  if _resp.code != "201"
381
- Printer.print_status "x", RED
390
+ formatter.print_status "x", RED
382
391
  print BOLD + "Post unsuccessful. \n" + RESET
383
392
  print " Since the open issues were obtained earlier, something is probably wrong and you should let someone know...\n"
384
393
  print " Status: #{ _resp.code } - #{ _resp.message }\n"
@@ -397,6 +397,10 @@ module Watson
397
397
  '.go' => ['//', '/*'], # Go(lang)
398
398
  '.scala' => ['//', '/*'], # Scala
399
399
  '.erl' => ['%%', '%'], # Erlang
400
+ '.f' => ['!'], # Fortran
401
+ '.f90' => ['!'], # Fortran
402
+ '.F' => ['!'], # Fortran
403
+ '.F90' => ['!'], # Fortran
400
404
  '.hs' => ['--'], # Haskell
401
405
  '.sh' => ['#'], # Bash
402
406
  '.rb' => ['#'], # Ruby
@@ -406,7 +410,8 @@ module Watson
406
410
  '.py' => ['#'], # Python
407
411
  '.coffee' => ['#'], # CoffeeScript
408
412
  '.zsh' => ['#'], # Zsh
409
- '.clj' => [';;'] # Clojure
413
+ '.clj' => [';;'], # Clojure
414
+ '.sql' => ['---', '//', '#' ] # SQL and PL types
410
415
  }
411
416
 
412
417
  loop do
@@ -1,22 +1,19 @@
1
1
  module Watson
2
-
3
- # Color definitions for pretty printing
4
- # Defined here because we need Global scope but makes sense to have them
5
- # in the printer.rb file at least
6
-
7
- BOLD = "\e[01m"
8
- UNDERLINE = "\e[4m"
9
- RESET = "\e[00m"
10
-
11
- GRAY = "\e[38;5;0m"
12
- RED = "\e[38;5;1m"
13
- GREEN = "\e[38;5;2m"
14
- YELLOW = "\e[38;5;3m"
15
- BLUE = "\e[38;5;4m"
16
- MAGENTA = "\e[38;5;5m"
17
- CYAN = "\e[38;5;6m"
18
- WHITE = "\e[38;5;7m"
19
-
2
+ # Color definitions for pretty printing
3
+ # Defined here because we need Global scope but makes sense to have them
4
+ # in the printer.rb file at least
5
+ BOLD = "\e[01m"
6
+ UNDERLINE = "\e[4m"
7
+ RESET = "\e[00m"
8
+
9
+ GRAY = "\e[38;5;0m"
10
+ RED = "\e[38;5;1m"
11
+ GREEN = "\e[38;5;2m"
12
+ YELLOW = "\e[38;5;3m"
13
+ BLUE = "\e[38;5;4m"
14
+ MAGENTA = "\e[38;5;5m"
15
+ CYAN = "\e[38;5;6m"
16
+ WHITE = "\e[38;5;7m"
20
17
 
21
18
  # Printer class that handles all formatting and printing of parsed dir/file structure
22
19
  class Printer
@@ -31,268 +28,25 @@ module Watson
31
28
  # Debug printing for this class
32
29
  DEBUG = false
33
30
 
34
- class << self
35
-
36
- # Include for debug_print (for static methods)
37
- include Watson
38
-
39
- ###########################################################
40
- # Custom color print for static call (only writes to STDOUT)
41
- def cprint (msg = "", color = "")
42
-
43
- # Identify method entry
44
- debug_print "#{ self } : #{ __method__ }\n"
45
-
46
- # This little check will allow us to take a Constant defined color
47
- # As well as a [0-256] value if specified
48
- if (color.is_a?(String))
49
- debug_print "Custom color specified for cprint\n"
50
- STDOUT.write(color)
51
- elsif (color.between?(0, 256))
52
- debug_print "No or Default color specified for cprint\n"
53
- STDOUT.write("\e[38;5;#{ color }m")
54
- end
55
-
56
- STDOUT.write(msg)
57
- end
58
-
59
-
60
- ###########################################################
61
- # Standard header print for static call (uses static cprint)
62
- def print_header
63
-
64
- # Identify method entry
65
- debug_print "#{ self } : #{ __method__ }\n"
66
-
67
- # Header
68
- cprint BOLD + "------------------------------\n" + RESET
69
- cprint BOLD + "watson" + RESET
70
- cprint " - " + RESET
71
- cprint BOLD + YELLOW + "inline issue manager\n" + RESET
72
- cprint BOLD + "------------------------------\n\n" + RESET
73
-
74
- return true
75
- end
76
-
77
-
78
- ###########################################################
79
- # Status printer for static call (uses static cprint)
80
- # Print status block in standard format
81
- def print_status(msg, color)
82
- cprint RESET + BOLD
83
- cprint WHITE + "[ "
84
- cprint "#{ msg } ", color
85
- cprint WHITE + "] " + RESET
86
- end
87
-
88
- end
89
-
90
31
  ###########################################################
91
32
  # Printer initialization method to setup necessary parameters, states, and vars
92
33
  def initialize(config)
93
-
94
34
  # Identify method entry
95
- debug_print "#{ self } : #{ __method__ }\n"
96
-
35
+ debug_print "#{self} : #{__method__}\n"
97
36
  @config = config
98
- return true
99
37
  end
100
38
 
101
-
102
39
  ###########################################################
103
40
  # Take parsed structure and print out in specified formatting
104
41
  def run(structure)
105
-
106
42
  # Identify method entry
107
- debug_print "#{ self } : #{ __method__ }\n"
108
-
109
- # Check Config to see if we have access to less for printing
110
- # If so, open our temp file as the output to write to
111
- # Else, just print out to STDOUT
112
- if @config.use_less
113
- debug_print "Unix less avaliable, setting output to #{ @config.tmp_file }\n"
114
- @output = File.open(@config.tmp_file, 'w')
115
- else
116
- debug_print "Unix less is unavaliable, setting output to STDOUT\n"
117
- @output = STDOUT
118
- end
119
-
120
- # Print header for output
121
- debug_print "Printing Header\n"
122
- print_header
123
-
124
- # Print out structure that was passed to this Printer
125
- debug_print "Starting structure printing\n"
126
- print_structure(structure)
43
+ debug_print "#{self} : #{__method__}\n"
127
44
 
128
- # If we are using less, close the output file, display with less, then delete
129
- if @config.use_less
130
- @output.close
131
- # [review] - Way of calling a native Ruby less?
132
- system("less -R #{ @config.tmp_file }")
133
- debug_print "File displayed with less, now deleting...\n"
134
- File.delete(@config.tmp_file)
135
- end
136
-
137
- return true
45
+ build_formatter.run(structure)
138
46
  end
139
47
 
140
-
141
- ###########################################################
142
- # Custom color print for member call
143
- # Allows not only for custom color printing but writing to file vs STDOUT
144
- def cprint (msg = "", color = "")
145
-
146
- # Identify method entry
147
- debug_print "#{ self } : #{ __method__ }\n"
148
-
149
- # This little check will allow us to take a Constant defined color
150
- # As well as a [0-256] value if specified
151
- if (color.is_a?(String))
152
- debug_print "Custom color specified for cprint\n"
153
- @output.write(color)
154
- elsif (color.between?(0, 256))
155
- debug_print "No or Default color specified for cprint\n"
156
- @output.write("\e[38;5;#{ color }m")
157
- end
158
-
159
- @output.write(msg)
160
- end
161
-
162
-
163
- ###########################################################
164
- # Standard header print for class call (uses member cprint)
165
- def print_header
166
- # Identify method entry
167
-
168
- debug_print "#{ self } : #{ __method__ }\n"
169
-
170
- # Header
171
- cprint BOLD + "------------------------------\n" + RESET
172
- cprint BOLD + "watson" + RESET
173
- cprint " - " + RESET
174
- cprint BOLD + YELLOW + "inline issue manager\n\n" + RESET
175
- cprint "Run in: #{ Dir.pwd }\n"
176
- cprint "Run @ #{ Time.now.asctime }\n"
177
- cprint BOLD + "------------------------------\n\n" + RESET
178
-
179
- return true
48
+ def build_formatter
49
+ @formatter ||= @config.output_format.new(@config)
180
50
  end
181
-
182
-
183
- ###########################################################
184
- # Status printer for member call (uses member cprint)
185
- # Print status block in standard format
186
- def print_status(msg, color)
187
- cprint RESET + BOLD
188
- cprint WHITE + "[ "
189
- cprint "#{ msg } ", color
190
- cprint WHITE + "] " + RESET
191
- end
192
-
193
-
194
- ###########################################################
195
- # Go through all files and directories and call necessary printing methods
196
- # Print all individual entries, call print_structure on each subdir
197
- def print_structure(structure)
198
-
199
- # Identify method entry
200
- debug_print "#{ self } : #{ __method__ }\n"
201
-
202
- # First go through all the files in the current structure
203
- # The current "structure" should reflect a dir/subdir
204
- structure[:files].each do | _file |
205
- debug_print "Printing info for #{ _file }\n"
206
- print_entry(_file)
207
- end
208
-
209
- # Next go through all the subdirs and pass them to print_structure
210
- structure[:subdirs].each do | _subdir |
211
- debug_print "Entering #{ _subdir } to print further\n"
212
- print_structure(_subdir)
213
- end
214
- end
215
-
216
-
217
- ###########################################################
218
- # Individual entry printer
219
- # Uses issue hash to format printed output
220
- def print_entry(entry)
221
-
222
- # Identify method entry
223
- debug_print "#{ self } : #{ __method__ }\n"
224
-
225
- # If no issues for this file, print that and break
226
- # The filename print is repetative, but reduces another check later
227
- if !entry[:has_issues]
228
- if @config.show_type != 'dirty'
229
- debug_print "No issues for #{ entry }\n"
230
- print_status "o", GREEN
231
- cprint BOLD + UNDERLINE + GREEN + "#{ entry[:relative_path] }" + RESET + "\n"
232
- return true
233
- end
234
- else
235
- if @config.show_type != 'clean'
236
- debug_print "Issues found for #{ entry }\n"
237
- cprint "\n"
238
- print_status "x", RED
239
- cprint BOLD + UNDERLINE + RED + "#{entry[:relative_path]}" + RESET + "\n"
240
- else
241
- return true
242
- end
243
- end
244
-
245
-
246
- # [review] - Should the tag structure be self contained in the hash
247
- # Or is it ok to reference @config to figure out the tags
248
- @config.tag_list.each do | _tag |
249
- debug_print "Checking for #{ _tag }\n"
250
-
251
- # [review] - Better way to ignore tags through structure (hash) data
252
- # Maybe have individual has_issues for each one?
253
- if entry[_tag].size.zero?
254
- debug_print "#{ _tag } has no issues, skipping\n"
255
- next
256
- end
257
-
258
- debug_print "#{ _tag } has issues in it, print!\n"
259
- print_status "#{ _tag }", BLUE
260
- cprint "\n"
261
-
262
- # Go through each issue in tag
263
- entry[_tag].each do | _issue |
264
- cprint WHITE + " line #{ _issue[:line_number] } - " + RESET
265
- cprint BOLD + "#{ _issue[:title] }" + RESET
266
-
267
-
268
- # Check to see if it has been resolved on GitHub/Bitbucket
269
- debug_print "Checking if issue has been resolved\n"
270
- @config.github_issues[:closed].each do | _closed |
271
- if _closed["body"].include?(_issue[:md5])
272
- debug_print "Found in #{ _closed[:comment] }, not posting\n"
273
- cprint BOLD + " [" + RESET
274
- cprint GREEN + BOLD + "Resolved on GitHub" + RESET
275
- cprint BOLD + "]" + RESET
276
- end
277
- debug_print "Did not find in #{ _closed[:comment] }\n"
278
- end
279
-
280
- debug_print "Checking if issue has been resolved\n"
281
- @config.bitbucket_issues[:closed].each do | _closed |
282
- if _closed["content"].include?(_issue[:md5])
283
- debug_print "Found in #{ _closed["content"] }, not posting\n"
284
- cprint BOLD + " [" + RESET
285
- cprint GREEN + BOLD + "Resolved on Bitbucket" + RESET
286
- cprint BOLD + "]\n" + RESET
287
- end
288
- debug_print "Did not find in #{ _closed["title"] }\n"
289
- end
290
- cprint "\n"
291
-
292
- end
293
- cprint "\n"
294
- end
295
- end
296
-
297
51
  end
298
52
  end
@@ -1,3 +1,3 @@
1
1
  module Watson
2
- VERSION = "1.2.0"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
26
26
  s.required_ruby_version = '>= 2.0.0'
27
27
 
28
28
  # Runtime Dependencies
29
- s.add_runtime_dependency 'json'
29
+ s.add_runtime_dependency (RUBY_PLATFORM == 'java' ? 'json_pure' : 'json')
30
30
 
31
31
  # Development Dependencies
32
32
  s.add_development_dependency 'rake'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: watson-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - nhmood
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-28 00:00:00.000000000 Z
11
+ date: 2013-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -73,6 +73,11 @@ files:
73
73
  - lib/watson/bitbucket.rb
74
74
  - lib/watson/command.rb
75
75
  - lib/watson/config.rb
76
+ - lib/watson/formatters.rb
77
+ - lib/watson/formatters/base_formatter.rb
78
+ - lib/watson/formatters/default_formatter.rb
79
+ - lib/watson/formatters/json_formatter.rb
80
+ - lib/watson/formatters/unite_formatter.rb
76
81
  - lib/watson/fs.rb
77
82
  - lib/watson/github.rb
78
83
  - lib/watson/parser.rb