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.
data/lib/watson/config.rb CHANGED
@@ -1,493 +1,493 @@
1
1
  module Watson
2
- # Configuration container class
3
- # Contains all configuration options and state variables
4
- # that are accessed throughout watson
5
- class Config
6
-
7
- # Include for debug_print
8
- include Watson
9
-
10
- # Debug printing for this class
11
- DEBUG = false
12
-
13
- # [review] - Combine into single statement (for performance or something?)
14
- # [todo] - Add config options (rc file) for default max depth and context lines
15
-
16
- # List of all files/folders to ignore when parsing
17
- attr_accessor :ignore_list
18
- # List of directories to parse
19
- attr_accessor :dir_list
20
- # List of all files to parse
21
- attr_accessor :file_list
22
- # List of tags to look for when parsing
23
- attr_accessor :tag_list
24
- # Number of directories to parse recursively
25
- attr_accessor :parse_depth
26
- # Number of lines of issue context to grab
27
- attr_accessor :context_depth
28
-
29
- # Flag for command line setting of file/dir to parse
30
- attr_accessor :cl_entry_set
31
- # Flag for command line setting of file/dir to ignore
32
- attr_accessor :cl_ignore_set
33
- # Flag for command line setting of tag to parse for
34
- attr_accessor :cl_tag_set
35
-
36
- # Flag for whether less is avaliable to print results
37
- attr_reader :use_less
38
- # Flag for where the temp file for printing is located
39
- attr_reader :tmp_file
40
-
41
- # Flag for whether remote access is avaliable
42
- attr_accessor :remote_valid
43
-
44
- # Flag for whether GitHub access is avaliable
45
- attr_accessor :github_valid
46
- # GitHub API key generated from Remote::GitHub setup
47
- attr_accessor :github_api
48
- # GitHub repo associated with current directory + watson config
49
- attr_accessor :github_repo
50
- # Hash to hold list of all GitHub issues associated with repo
51
- attr_accessor :github_issues
52
-
53
-
54
- # Flag for whether Bitbucket access is avaliable
55
- attr_accessor :bitbucket_valid
56
- # Bitbucket API key generated from Remote::Bitbucket setup (username for now)
57
- attr_accessor :bitbucket_api
58
- # Bitbucket password for access until OAuth is implemented for Bitbucket
59
- attr_accessor :bitbucket_pw
60
- # Bitbucket repo associated with current directory + watson config
61
- attr_accessor :bitbucket_repo
62
- # Hash to hold list of all Bitbucket issues associated with repo
63
- attr_accessor :bitbucket_issues
64
-
65
-
66
- ###########################################################
67
- # Config initialization method to setup necessary parameters, states, and vars
68
- def initialize
69
-
70
- # [review] - Read and store rc FP inside initialize?
71
- # This way we don't need to keep reopening the FP to use it
72
- # but then we need a way to reliably close the FP when done
73
-
74
- # Identify method entry
75
- debug_print "#{self.class} : #{__method__}\n"
76
-
77
- # Program config
78
- @rc_file = ".watsonrc"
79
- @tmp_file = ".watsonresults"
80
-
81
- @parse_depth = 0
82
- @context_depth = 15
83
-
84
- # State flags
85
- @cl_entry_set = false
86
- @cl_tag_set = false
87
- @cl_ignore_set = false
88
-
89
- # System flags
90
- # [todo] - Add option to save output to file also
91
- @use_less = false
92
-
93
- # Data containers
94
- @ignore_list = Array.new()
95
- @dir_list = Array.new()
96
- @file_list = Array.new()
97
- @tag_list = Array.new()
98
-
99
- # Remote options
100
- @remote_valid = false
101
-
102
- @github_valid = false
103
- @github_api = ""
104
- @github_repo = ""
105
- @github_issues = {:open => Hash.new(),
106
- :closed => Hash.new()
107
- }
108
-
109
- # Keep API param (and put username there) for OAuth update later
110
- @bitbucket_valid = false
111
- @bitbucket_api = ""
112
- @bitbucket_pw = ""
113
- @bitbucket_repo = ""
114
- @bitbucket_issues = {:open => Hash.new(),
115
- :closed => Hash.new()
116
- }
117
- end
118
-
119
-
120
- ###########################################################
121
- # Parse through configuration and obtain remote info if necessary
122
- def run
123
-
124
- # Identify method entry
125
- debug_print "#{ self.class } : #{ __method__ }\n"
126
-
127
- # check_conf should create if no conf found, exit entirely if can't do either
128
- exit if check_conf == false
129
- read_conf
130
-
131
- unless @github_api.empty? && @github_api.empty?
132
- Remote::GitHub.get_issues(self)
133
- end
134
-
135
- unless @bitbucket_api.empty? && @bitbucket_repo.empty?
136
- Remote::Bitbucket.get_issues(self)
137
- end
138
- end
139
-
140
-
141
- ###########################################################
142
- # Check for config file in directory of execution
143
- # Should have individual .rc for each dir that watson is used in
144
- # This allows you to keep different preferences for different projects
145
- # Create conf (with #create_conf) if not found
146
- def check_conf
147
-
148
- # Identify method entry
149
- debug_print "#{ self.class } : #{ __method__ }\n"
150
-
151
- # Check for .rc
152
- # If one doesn't exist, create default one with create_conf method
153
- if !Watson::FS.check_file(@rc_file)
154
- debug_print "#{ @rc_file } not found\n"
155
- debug_print "Creating default #{ @rc_file }\n"
156
-
157
- # Create default .rc and return create_conf (true if created,
158
- # false if not)
159
- return create_conf
160
- else
161
- debug_print "#{ @rc_file } found\n"
162
- return true
163
- end
164
- end
165
-
166
-
167
- ###########################################################
168
- # Watson config creater
169
- # Copies default config from /assets/defaultConf to the current directory
170
- def create_conf
171
- # [review] - Not sure if I should use the open/read/write or Fileutils.cp
172
-
173
- # Identify method entry
174
- debug_print "#{ self.class } : #{ __method__ }\n"
175
-
176
-
177
- # Generate full path since File doesn't care about the LOAD_PATH
178
- # [review] - gsub uses (.?)+ to grab anything after lib (optional), better regex?
179
- _full_path = __dir__.gsub(%r!/lib/watson(.?)+!, '') + "/assets/defaultConf"
180
- debug_print "Full path to defaultConf (in gem): #{ _full_path }\n"
181
-
182
- # Check to make sure we can access the default file
183
- if !Watson::FS.check_file(_full_path)
184
- print "Unable to open #{ _full_path }\n"
185
- print "Cannot create default, exiting...\n"
186
- return false
187
- else
188
- # Open default config file in read mode and read into temp
189
- _input = File.open(_full_path, 'r')
190
- _default = _input.read
191
-
192
- # Open rc file in current directory in write mode and write default
193
- _output = File.open(@rc_file, 'w')
194
- _output.write(_default)
195
-
196
- # Close both default and new rc files
197
- _input.close
198
- _output.close
199
-
200
- debug_print "Successfully wrote defaultConf to current directory\n"
201
- return true
202
- end
203
- end
204
-
205
-
206
- ###########################################################
207
- # Read configuration file and populate Config container class
208
- def read_conf
209
-
210
- # Identify method entry
211
- debug_print "#{ self.class } : #{ __method__ }\n"
212
-
213
-
214
- debug_print "Reading #{ @rc_file }\n"
215
- if !Watson::FS.check_file(@rc_file)
216
- print "Unable to open #{@rc_file}, exiting\n"
217
- return false
218
- else
219
- debug_print "Opened #{ @rc_file } for reading\n"
220
- end
221
-
222
-
223
- # Check if system has less for output
224
- @use_less = check_less
225
-
226
-
227
- # Add all the standard items to ignorelist
228
- # This gets added regardless of ignore list specified
229
- # [review] - Keep *.swp in there?
230
- # [todo] - Add conditional to @rc_file such that if passed by -f we accept it
231
- # [todo] - Add current file (watson) to avoid accidentally printing app tags
232
- @ignore_list.push(".")
233
- @ignore_list.push("..")
234
- @ignore_list.push("*.swp")
235
- @ignore_list.push(@rc_file)
236
- @ignore_list.push(@tmp_file)
237
-
238
- # Open and read rc
239
- # [review] - Not sure if explicit file close is required here
240
- _rc = File.open(@rc_file, 'r').read
241
-
242
- debug_print "\n\n"
243
-
244
- # Create temp section var to keep track of what we are populating in config
245
- _section = ""
246
-
247
- # Keep index to print what line we are on
248
- # Could fool around with Enumerable + each_with_index but oh well
249
- _i = 0;
250
-
251
- # Fix line endings so we can support Windows/Linux edited rc files
252
- _rc.gsub!(/\r\n?/, "\n")
253
- _rc.each_line do | _line |
254
- debug_print "#{ _i }: #{ _line }" if (_line != "\n")
255
- _i = _i + 1
256
-
257
-
258
- # Ignore full line comments or newlines
259
- if _line.match(/(^#)|(^\n)|(^ )/)
260
- debug_print "Full line comment or newline found, skipping\n"
261
- # [review] - More "Ruby" way of going to next line?
262
- next
263
- end
264
-
265
-
266
- # [review] - Use if with match so we can call next on the line reading loop
267
- # Tried using match(){|_mtch|} as well as do |_mtch| but those don't seem to
268
- # register the next call to the outer loop, so this way will do for now
269
-
270
- # Regex on line to find out if we are in a new [section] of
271
- # config parameters. If so, store it into section var and move
272
- # to next line
273
- _mtch = _line.match(/^\[(\w+)\]/)
274
- if _mtch
275
- debug_print "Found section #{ _mtch[1] }\n"
276
- _section = _mtch[1]
277
- next
278
- end
279
-
280
-
281
- case _section
282
- when "context_depth"
283
- # No need for regex on context value, command should read this in only as a #
284
- # Chomp to get rid of any nonsense
285
- @context_depth = _line.chomp!
286
-
287
-
288
- when "parse_depth"
289
- # No need for regex on parse value, command should read this in only as a #
290
- # Chomp to get rid of any nonsense
291
- @parse_depth = _line.chomp!
292
-
293
-
294
- when "dirs"
295
- # If @dir_list or @file_list wasn't populated by CL args
296
- # then populate from rc
297
- # [review] - Populate @dirs/files_list first, then check size instead
298
- if @cl_entry_set
299
- debug_print "Directories or files set from command line ignoring rc [dirs]\n"
300
- next
301
- end
302
-
303
- # Regex to grab directory
304
- # Then substitute trailing / (necessary for later formatting)
305
- # Then push to @dir_list
306
- _mtch = _line.match(/^((\w+)?\.?\/?)+/)[0].gsub(/(\/)+$/, "")
307
- if !_mtch.empty?
308
- @dir_list.push(_mtch)
309
- debug_print "#{ _mtch } added to @dir_list\n"
310
- end
311
- debug_print "@dir_list --> #{ @dir_list }\n"
312
-
313
-
314
- when "tags"
315
- # Same as previous for tags
316
- # [review] - Populate @tag_list, then check size instead
317
- if @cl_tag_set
318
- debug_print "Tags set from command line, ignoring rc [tags]\n"
319
- next
320
- end
321
-
322
- # Same as previous for tags
323
- # [review] - Need to think about what kind of tags this supports
324
- # Check compatibility with GitHub + Bitbucket and what makes sense
325
- # Only supports single word+number tags
326
- _mtch = _line.match(/^(\S+)/)[0]
327
- if !_mtch.empty?
328
- @tag_list.push(_mtch)
329
- debug_print "#{ _mtch } added to @tag_list\n"
330
- end
331
- debug_print "@tag_list --> #{ @tag_list }\n"
332
-
333
-
334
- when "ignore"
335
- # Same as previous for ignores
336
- # [review] - Populate @tag_list, then check size instead
337
-
338
- if @cl_ignore_set
339
- debug_print "Ignores set from command line, ignoring rc [ignores]\n"
340
- next
341
- end
342
-
343
- # Same as previous for ignores (regex same as dirs)
344
- # Don't eliminate trailing / because not sure if dir can have
345
- # same name as file (Linux it can't, but not sure about Win/Mac)
346
- # [review] - Can Win/Mac have dir + file with same name in same dir?
347
- _mtch = _line.match(/^((\w+)?\.?\/?)+/)[0]
348
- if !_mtch.empty?
349
- @ignore_list.push(_mtch)
350
- debug_print "#{ _mtch } added to @ignore_list\n"
351
- end
352
- debug_print "@ignore_list --> #{ @ignore_list }\n"
353
-
354
-
355
- when "github_api"
356
- # No need for regex on API key, GitHub setup should do this properly
357
- # Chomp to get rid of any nonsense
358
- @github_api = _line.chomp!
359
- debug_print "GitHub API: #{ @github_api }\n"
360
-
361
-
362
- when "github_repo"
363
- # Same as above
364
- @github_repo = _line.chomp!
365
- debug_print "GitHub Repo: #{ @github_repo }\n"
366
-
367
-
368
- when "bitbucket_api"
369
- # Same as GitHub parse above
370
- @bitbucket_api = _line.chomp!
371
- debug_print "Bitbucket API: #{ @bitbucket_api }\n"
372
-
373
-
374
- when "bitbucket_repo"
375
- # Same as GitHub repo parse above
376
- @bitbucket_repo = _line.chomp!
377
- debug_print "Bitbucket Repo: #{ @bitbucket_repo }\n"
378
-
379
-
380
- else
381
- debug_print "Unknown tag found #{_section}\n"
382
- end
383
-
384
- end
385
-
386
- return true
387
- end
388
-
389
-
390
- ###########################################################
391
- # Update config file with specified parameters
392
- # Accepts input parameters that should be updated and writes to file
393
- # Selective updating to make bookkeeping easier
394
- def update_conf(*params)
395
-
396
- # Identify method entry
397
- debug_print "#{ self.class } : #{ __method__ }\n"
398
-
399
- # Check if RC exists, if not create one
400
- if !Watson::FS.check_file(@rc_file)
401
- print "Unable to open #{ @rc_file }, exiting\n"
402
- create_conf
403
- else
404
- debug_print "Opened #{ @rc_file } for reading\n"
405
- end
406
-
407
- # Go through all given params and make sure they are actually config vars
408
- params.each_with_index do | _param, _i |
409
- if !self.instance_variable_defined?("@#{ _param }")
410
- debug_print "#{ _param } does not exist in Config\n"
411
- debug_print "Check your input(s) to update_conf\n"
412
- params.slice!(_i)
413
- end
414
- end
415
-
416
-
417
- # Read in currently saved RC and go through it line by line
418
- # Only update params that were passed to update_conf
419
- # This allows us to clean up the config file at the same time
420
-
421
-
422
- # Open and read rc
423
- # [review] - Not sure if explicit file close is required here
424
- _rc = File.open(@rc_file, 'r').read
425
- _update = File.open(@rc_file, 'w')
426
-
427
-
428
- # Keep index to print what line we are on
429
- # Could fool around with Enumerable + each_with_index but oh well
430
- _i = 0;
431
-
432
- # Keep track of newlines for prettying up the conf
433
- _nlc = 0
434
- _section = ""
435
-
436
- # Fix line endings so we can support Windows/Linux edited rc files
437
- _rc.gsub!(/\r\n?/, "\n")
438
- _rc.each_line do | _line |
439
- # Print line for debug purposes
440
- debug_print "#{ _i }: #{ _line }"
441
- _i = _i + 1
442
-
443
-
444
- # Look for sections and set section var
445
- _mtch = _line.match(/^\[(\w+)\]/)
446
- if _mtch
447
- debug_print "Found section #{ _mtch[1] }\n"
448
- _section = _mtch[1]
449
- end
450
-
451
- # Check for newlines
452
- # If we already have 2 newlines before any actual content, skip
453
- # This is just to make the RC file output nicer looking
454
- if _line == "\n"
455
- debug_print "Newline found\n"
456
- _nlc = _nlc + 1
457
- if _nlc < 3
458
- debug_print "Less than 3 newlines so far, let it print\n"
459
- _update.write(_line)
460
- end
461
- # If the section we are in doesn't match the params passed to update_conf
462
- # it is safe to write the line over to the new config
463
- elsif !params.include?(_section)
464
- debug_print "Current section NOT a param to update\n"
465
- debug_print "Writing to new rc\n"
466
- _update.write(_line)
467
-
468
- # Reset newline
469
- _nlc = 0
470
- end
471
-
472
- debug_print "line: #{ _line }\n"
473
- debug_print "nlc: #{ _nlc }\n"
474
- end
475
-
476
- # Make sure there is at least 3 newlines between last section before writing new params
477
- (2 - _nlc).times do
478
- _update.write("\n")
479
- end
480
-
481
- # Now that we have skipped all the things that need to be updated, write them in
482
- params.each do | _param |
483
- _update.write("[#{ _param }]\n")
484
- _update.write("#{ self.instance_variable_get("@#{ _param }") }")
485
- _update.write("\n\n\n")
486
- end
487
-
488
- _update.close
489
- end
490
-
491
- end
2
+ # Configuration container class
3
+ # Contains all configuration options and state variables
4
+ # that are accessed throughout watson
5
+ class Config
6
+
7
+ # Include for debug_print
8
+ include Watson
9
+
10
+ # Debug printing for this class
11
+ DEBUG = false
12
+
13
+ # [review] - Combine into single statement (for performance or something?)
14
+ # [todo] - Add config options (rc file) for default max depth and context lines
15
+
16
+ # List of all files/folders to ignore when parsing
17
+ attr_accessor :ignore_list
18
+ # List of directories to parse
19
+ attr_accessor :dir_list
20
+ # List of all files to parse
21
+ attr_accessor :file_list
22
+ # List of tags to look for when parsing
23
+ attr_accessor :tag_list
24
+ # Number of directories to parse recursively
25
+ attr_accessor :parse_depth
26
+ # Number of lines of issue context to grab
27
+ attr_accessor :context_depth
28
+
29
+ # Flag for command line setting of file/dir to parse
30
+ attr_accessor :cl_entry_set
31
+ # Flag for command line setting of file/dir to ignore
32
+ attr_accessor :cl_ignore_set
33
+ # Flag for command line setting of tag to parse for
34
+ attr_accessor :cl_tag_set
35
+
36
+ # Flag for whether less is avaliable to print results
37
+ attr_reader :use_less
38
+ # Flag for where the temp file for printing is located
39
+ attr_reader :tmp_file
40
+
41
+ # Flag for whether remote access is avaliable
42
+ attr_accessor :remote_valid
43
+
44
+ # Flag for whether GitHub access is avaliable
45
+ attr_accessor :github_valid
46
+ # GitHub API key generated from Remote::GitHub setup
47
+ attr_accessor :github_api
48
+ # GitHub repo associated with current directory + watson config
49
+ attr_accessor :github_repo
50
+ # Hash to hold list of all GitHub issues associated with repo
51
+ attr_accessor :github_issues
52
+
53
+
54
+ # Flag for whether Bitbucket access is avaliable
55
+ attr_accessor :bitbucket_valid
56
+ # Bitbucket API key generated from Remote::Bitbucket setup (username for now)
57
+ attr_accessor :bitbucket_api
58
+ # Bitbucket password for access until OAuth is implemented for Bitbucket
59
+ attr_accessor :bitbucket_pw
60
+ # Bitbucket repo associated with current directory + watson config
61
+ attr_accessor :bitbucket_repo
62
+ # Hash to hold list of all Bitbucket issues associated with repo
63
+ attr_accessor :bitbucket_issues
64
+
65
+
66
+ ###########################################################
67
+ # Config initialization method to setup necessary parameters, states, and vars
68
+ def initialize
69
+
70
+ # [review] - Read and store rc FP inside initialize?
71
+ # This way we don't need to keep reopening the FP to use it
72
+ # but then we need a way to reliably close the FP when done
73
+
74
+ # Identify method entry
75
+ debug_print "#{self.class} : #{__method__}\n"
76
+
77
+ # Program config
78
+ @rc_file = ".watsonrc"
79
+ @tmp_file = ".watsonresults"
80
+
81
+ @parse_depth = 0
82
+ @context_depth = 15
83
+
84
+ # State flags
85
+ @cl_entry_set = false
86
+ @cl_tag_set = false
87
+ @cl_ignore_set = false
88
+
89
+ # System flags
90
+ # [todo] - Add option to save output to file also
91
+ @use_less = false
92
+
93
+ # Data containers
94
+ @ignore_list = Array.new()
95
+ @dir_list = Array.new()
96
+ @file_list = Array.new()
97
+ @tag_list = Array.new()
98
+
99
+ # Remote options
100
+ @remote_valid = false
101
+
102
+ @github_valid = false
103
+ @github_api = ""
104
+ @github_repo = ""
105
+ @github_issues = {:open => Hash.new(),
106
+ :closed => Hash.new()
107
+ }
108
+
109
+ # Keep API param (and put username there) for OAuth update later
110
+ @bitbucket_valid = false
111
+ @bitbucket_api = ""
112
+ @bitbucket_pw = ""
113
+ @bitbucket_repo = ""
114
+ @bitbucket_issues = {:open => Hash.new(),
115
+ :closed => Hash.new()
116
+ }
117
+ end
118
+
119
+
120
+ ###########################################################
121
+ # Parse through configuration and obtain remote info if necessary
122
+ def run
123
+
124
+ # Identify method entry
125
+ debug_print "#{ self.class } : #{ __method__ }\n"
126
+
127
+ # check_conf should create if no conf found, exit entirely if can't do either
128
+ exit if check_conf == false
129
+ read_conf
130
+
131
+ unless @github_api.empty? && @github_api.empty?
132
+ Remote::GitHub.get_issues(self)
133
+ end
134
+
135
+ unless @bitbucket_api.empty? && @bitbucket_repo.empty?
136
+ Remote::Bitbucket.get_issues(self)
137
+ end
138
+ end
139
+
140
+
141
+ ###########################################################
142
+ # Check for config file in directory of execution
143
+ # Should have individual .rc for each dir that watson is used in
144
+ # This allows you to keep different preferences for different projects
145
+ # Create conf (with #create_conf) if not found
146
+ def check_conf
147
+
148
+ # Identify method entry
149
+ debug_print "#{ self.class } : #{ __method__ }\n"
150
+
151
+ # Check for .rc
152
+ # If one doesn't exist, create default one with create_conf method
153
+ if !Watson::FS.check_file(@rc_file)
154
+ debug_print "#{ @rc_file } not found\n"
155
+ debug_print "Creating default #{ @rc_file }\n"
156
+
157
+ # Create default .rc and return create_conf (true if created,
158
+ # false if not)
159
+ return create_conf
160
+ else
161
+ debug_print "#{ @rc_file } found\n"
162
+ return true
163
+ end
164
+ end
165
+
166
+
167
+ ###########################################################
168
+ # Watson config creater
169
+ # Copies default config from /assets/defaultConf to the current directory
170
+ def create_conf
171
+ # [review] - Not sure if I should use the open/read/write or Fileutils.cp
172
+
173
+ # Identify method entry
174
+ debug_print "#{ self.class } : #{ __method__ }\n"
175
+
176
+
177
+ # Generate full path since File doesn't care about the LOAD_PATH
178
+ # [review] - gsub uses (.?)+ to grab anything after lib (optional), better regex?
179
+ _full_path = __dir__.gsub(%r!/lib/watson(.?)+!, '') + "/assets/defaultConf"
180
+ debug_print "Full path to defaultConf (in gem): #{ _full_path }\n"
181
+
182
+ # Check to make sure we can access the default file
183
+ if !Watson::FS.check_file(_full_path)
184
+ print "Unable to open #{ _full_path }\n"
185
+ print "Cannot create default, exiting...\n"
186
+ return false
187
+ else
188
+ # Open default config file in read mode and read into temp
189
+ _input = File.open(_full_path, 'r')
190
+ _default = _input.read
191
+
192
+ # Open rc file in current directory in write mode and write default
193
+ _output = File.open(@rc_file, 'w')
194
+ _output.write(_default)
195
+
196
+ # Close both default and new rc files
197
+ _input.close
198
+ _output.close
199
+
200
+ debug_print "Successfully wrote defaultConf to current directory\n"
201
+ return true
202
+ end
203
+ end
204
+
205
+
206
+ ###########################################################
207
+ # Read configuration file and populate Config container class
208
+ def read_conf
209
+
210
+ # Identify method entry
211
+ debug_print "#{ self.class } : #{ __method__ }\n"
212
+
213
+
214
+ debug_print "Reading #{ @rc_file }\n"
215
+ if !Watson::FS.check_file(@rc_file)
216
+ print "Unable to open #{@rc_file}, exiting\n"
217
+ return false
218
+ else
219
+ debug_print "Opened #{ @rc_file } for reading\n"
220
+ end
221
+
222
+
223
+ # Check if system has less for output
224
+ @use_less = check_less
225
+
226
+
227
+ # Add all the standard items to ignorelist
228
+ # This gets added regardless of ignore list specified
229
+ # [review] - Keep *.swp in there?
230
+ # [todo] - Add conditional to @rc_file such that if passed by -f we accept it
231
+ # [todo] - Add current file (watson) to avoid accidentally printing app tags
232
+ @ignore_list.push(".")
233
+ @ignore_list.push("..")
234
+ @ignore_list.push("*.swp")
235
+ @ignore_list.push(@rc_file)
236
+ @ignore_list.push(@tmp_file)
237
+
238
+ # Open and read rc
239
+ # [review] - Not sure if explicit file close is required here
240
+ _rc = File.open(@rc_file, 'r').read
241
+
242
+ debug_print "\n\n"
243
+
244
+ # Create temp section var to keep track of what we are populating in config
245
+ _section = ""
246
+
247
+ # Keep index to print what line we are on
248
+ # Could fool around with Enumerable + each_with_index but oh well
249
+ _i = 0;
250
+
251
+ # Fix line endings so we can support Windows/Linux edited rc files
252
+ _rc.gsub!(/\r\n?/, "\n")
253
+ _rc.each_line do | _line |
254
+ debug_print "#{ _i }: #{ _line }" if (_line != "\n")
255
+ _i = _i + 1
256
+
257
+
258
+ # Ignore full line comments or newlines
259
+ if _line.match(/(^#)|(^\n)|(^ )/)
260
+ debug_print "Full line comment or newline found, skipping\n"
261
+ # [review] - More "Ruby" way of going to next line?
262
+ next
263
+ end
264
+
265
+
266
+ # [review] - Use if with match so we can call next on the line reading loop
267
+ # Tried using match(){|_mtch|} as well as do |_mtch| but those don't seem to
268
+ # register the next call to the outer loop, so this way will do for now
269
+
270
+ # Regex on line to find out if we are in a new [section] of
271
+ # config parameters. If so, store it into section var and move
272
+ # to next line
273
+ _mtch = _line.match(/^\[(\w+)\]/)
274
+ if _mtch
275
+ debug_print "Found section #{ _mtch[1] }\n"
276
+ _section = _mtch[1]
277
+ next
278
+ end
279
+
280
+
281
+ case _section
282
+ when "context_depth"
283
+ # No need for regex on context value, command should read this in only as a #
284
+ # Chomp to get rid of any nonsense
285
+ @context_depth = _line.chomp!
286
+
287
+
288
+ when "parse_depth"
289
+ # No need for regex on parse value, command should read this in only as a #
290
+ # Chomp to get rid of any nonsense
291
+ @parse_depth = _line.chomp!
292
+
293
+
294
+ when "dirs"
295
+ # If @dir_list or @file_list wasn't populated by CL args
296
+ # then populate from rc
297
+ # [review] - Populate @dirs/files_list first, then check size instead
298
+ if @cl_entry_set
299
+ debug_print "Directories or files set from command line ignoring rc [dirs]\n"
300
+ next
301
+ end
302
+
303
+ # Regex to grab directory
304
+ # Then substitute trailing / (necessary for later formatting)
305
+ # Then push to @dir_list
306
+ _mtch = _line.match(/^((\w+)?\.?\/?)+/)[0].gsub(/(\/)+$/, "")
307
+ if !_mtch.empty?
308
+ @dir_list.push(_mtch)
309
+ debug_print "#{ _mtch } added to @dir_list\n"
310
+ end
311
+ debug_print "@dir_list --> #{ @dir_list }\n"
312
+
313
+
314
+ when "tags"
315
+ # Same as previous for tags
316
+ # [review] - Populate @tag_list, then check size instead
317
+ if @cl_tag_set
318
+ debug_print "Tags set from command line, ignoring rc [tags]\n"
319
+ next
320
+ end
321
+
322
+ # Same as previous for tags
323
+ # [review] - Need to think about what kind of tags this supports
324
+ # Check compatibility with GitHub + Bitbucket and what makes sense
325
+ # Only supports single word+number tags
326
+ _mtch = _line.match(/^(\S+)/)[0]
327
+ if !_mtch.empty?
328
+ @tag_list.push(_mtch)
329
+ debug_print "#{ _mtch } added to @tag_list\n"
330
+ end
331
+ debug_print "@tag_list --> #{ @tag_list }\n"
332
+
333
+
334
+ when "ignore"
335
+ # Same as previous for ignores
336
+ # [review] - Populate @tag_list, then check size instead
337
+
338
+ if @cl_ignore_set
339
+ debug_print "Ignores set from command line, ignoring rc [ignores]\n"
340
+ next
341
+ end
342
+
343
+ # Same as previous for ignores (regex same as dirs)
344
+ # Don't eliminate trailing / because not sure if dir can have
345
+ # same name as file (Linux it can't, but not sure about Win/Mac)
346
+ # [review] - Can Win/Mac have dir + file with same name in same dir?
347
+ _mtch = _line.match(/^((\w+)?\.?\/?)+/)[0]
348
+ if !_mtch.empty?
349
+ @ignore_list.push(_mtch)
350
+ debug_print "#{ _mtch } added to @ignore_list\n"
351
+ end
352
+ debug_print "@ignore_list --> #{ @ignore_list }\n"
353
+
354
+
355
+ when "github_api"
356
+ # No need for regex on API key, GitHub setup should do this properly
357
+ # Chomp to get rid of any nonsense
358
+ @github_api = _line.chomp!
359
+ debug_print "GitHub API: #{ @github_api }\n"
360
+
361
+
362
+ when "github_repo"
363
+ # Same as above
364
+ @github_repo = _line.chomp!
365
+ debug_print "GitHub Repo: #{ @github_repo }\n"
366
+
367
+
368
+ when "bitbucket_api"
369
+ # Same as GitHub parse above
370
+ @bitbucket_api = _line.chomp!
371
+ debug_print "Bitbucket API: #{ @bitbucket_api }\n"
372
+
373
+
374
+ when "bitbucket_repo"
375
+ # Same as GitHub repo parse above
376
+ @bitbucket_repo = _line.chomp!
377
+ debug_print "Bitbucket Repo: #{ @bitbucket_repo }\n"
378
+
379
+
380
+ else
381
+ debug_print "Unknown tag found #{_section}\n"
382
+ end
383
+
384
+ end
385
+
386
+ return true
387
+ end
388
+
389
+
390
+ ###########################################################
391
+ # Update config file with specified parameters
392
+ # Accepts input parameters that should be updated and writes to file
393
+ # Selective updating to make bookkeeping easier
394
+ def update_conf(*params)
395
+
396
+ # Identify method entry
397
+ debug_print "#{ self.class } : #{ __method__ }\n"
398
+
399
+ # Check if RC exists, if not create one
400
+ if !Watson::FS.check_file(@rc_file)
401
+ print "Unable to open #{ @rc_file }, exiting\n"
402
+ create_conf
403
+ else
404
+ debug_print "Opened #{ @rc_file } for reading\n"
405
+ end
406
+
407
+ # Go through all given params and make sure they are actually config vars
408
+ params.each_with_index do | _param, _i |
409
+ if !self.instance_variable_defined?("@#{ _param }")
410
+ debug_print "#{ _param } does not exist in Config\n"
411
+ debug_print "Check your input(s) to update_conf\n"
412
+ params.slice!(_i)
413
+ end
414
+ end
415
+
416
+
417
+ # Read in currently saved RC and go through it line by line
418
+ # Only update params that were passed to update_conf
419
+ # This allows us to clean up the config file at the same time
420
+
421
+
422
+ # Open and read rc
423
+ # [review] - Not sure if explicit file close is required here
424
+ _rc = File.open(@rc_file, 'r').read
425
+ _update = File.open(@rc_file, 'w')
426
+
427
+
428
+ # Keep index to print what line we are on
429
+ # Could fool around with Enumerable + each_with_index but oh well
430
+ _i = 0;
431
+
432
+ # Keep track of newlines for prettying up the conf
433
+ _nlc = 0
434
+ _section = ""
435
+
436
+ # Fix line endings so we can support Windows/Linux edited rc files
437
+ _rc.gsub!(/\r\n?/, "\n")
438
+ _rc.each_line do | _line |
439
+ # Print line for debug purposes
440
+ debug_print "#{ _i }: #{ _line }"
441
+ _i = _i + 1
442
+
443
+
444
+ # Look for sections and set section var
445
+ _mtch = _line.match(/^\[(\w+)\]/)
446
+ if _mtch
447
+ debug_print "Found section #{ _mtch[1] }\n"
448
+ _section = _mtch[1]
449
+ end
450
+
451
+ # Check for newlines
452
+ # If we already have 2 newlines before any actual content, skip
453
+ # This is just to make the RC file output nicer looking
454
+ if _line == "\n"
455
+ debug_print "Newline found\n"
456
+ _nlc = _nlc + 1
457
+ if _nlc < 3
458
+ debug_print "Less than 3 newlines so far, let it print\n"
459
+ _update.write(_line)
460
+ end
461
+ # If the section we are in doesn't match the params passed to update_conf
462
+ # it is safe to write the line over to the new config
463
+ elsif !params.include?(_section)
464
+ debug_print "Current section NOT a param to update\n"
465
+ debug_print "Writing to new rc\n"
466
+ _update.write(_line)
467
+
468
+ # Reset newline
469
+ _nlc = 0
470
+ end
471
+
472
+ debug_print "line: #{ _line }\n"
473
+ debug_print "nlc: #{ _nlc }\n"
474
+ end
475
+
476
+ # Make sure there is at least 3 newlines between last section before writing new params
477
+ (2 - _nlc).times do
478
+ _update.write("\n")
479
+ end
480
+
481
+ # Now that we have skipped all the things that need to be updated, write them in
482
+ params.each do | _param |
483
+ _update.write("[#{ _param }]\n")
484
+ _update.write("#{ self.instance_variable_get("@#{ _param }") }")
485
+ _update.write("\n\n\n")
486
+ end
487
+
488
+ _update.close
489
+ end
490
+
491
+ end
492
492
  end
493
493