watson-ruby 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
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