opensecret 0.0.913 → 0.0.941

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +3 -0
  3. data/README.md +129 -19
  4. data/Rakefile +0 -9
  5. data/bin/opensecret +1 -1
  6. data/lib/{opensecret/plugins.io/cipher/crypto.rb → crypto/amalgam.rb} +6 -8
  7. data/lib/crypto/collect.rb +139 -0
  8. data/lib/crypto/engineer.rb +201 -0
  9. data/lib/crypto/verify.rb +33 -0
  10. data/lib/extension/array.rb +133 -0
  11. data/lib/{opensecret/additions → extension}/dir.rb +0 -0
  12. data/lib/extension/file.rb +56 -0
  13. data/lib/extension/hash.rb +33 -0
  14. data/lib/extension/string.rb +349 -0
  15. data/lib/factbase/facts.opensecret.io.ini +28 -0
  16. data/lib/logging/gem.logging.rb +133 -0
  17. data/lib/opensecret.rb +102 -45
  18. data/lib/opensecret/executors/crypt.keys/crypt.keys.ini +0 -53
  19. data/lib/session/{session.rb → attributes.rb} +60 -5
  20. data/lib/session/exceptions.rb +53 -0
  21. data/lib/session/fact.finder.rb +684 -0
  22. data/lib/session/user.home.rb +49 -0
  23. data/lib/usecase/usecase.rb +245 -0
  24. data/lib/usecase/usecases/init.rb +190 -0
  25. data/lib/usecase/usecases/on.rb +33 -0
  26. data/lib/usecase/usecases/safe.rb +95 -0
  27. data/lib/version.rb +1 -1
  28. metadata +22 -17
  29. data/lib/opensecret/additions/array.rb +0 -117
  30. data/lib/opensecret/additions/string.rb +0 -312
  31. data/lib/opensecret/commons/eco.cmdline.rb +0 -446
  32. data/lib/opensecret/eco.do.rb +0 -46
  33. data/lib/opensecret/plugins.io/error/eco.exceptions.rb +0 -24
  34. data/lib/opensecret/plugins.io/facts/fact.chars.rb +0 -66
  35. data/lib/opensecret/plugins.io/facts/fact.factor.rb +0 -156
  36. data/lib/opensecret/plugins.io/facts/fact.locator.rb +0 -105
  37. data/lib/opensecret/plugins.io/facts/fact.reader.rb +0 -137
  38. data/lib/opensecret/plugins.io/facts/fact.tree.rb +0 -661
  39. data/lib/opensecret/plugins.io/logs/log.object.rb +0 -89
  40. data/lib/opensecret/plugins.io/logs/logging.rb +0 -203
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSession
4
+
5
+ # This class is the parent to all opensession errors
6
+ # that originate from the command line.
7
+ #
8
+ # All opensession cli originating errors are about
9
+ #
10
+ # - a problem with the input or
11
+ # - a problem with the current state or
12
+ # - a predictable future problem
13
+ class OpenSessionError < StandardError
14
+
15
+
16
+ # Initialize the error and provide a culprit
17
+ # object which will be to-stringed and given
18
+ # out as evidence (look at this)!
19
+ #
20
+ # This method will take care of loggin the error.
21
+ #
22
+ # @param message [String] human readable error message
23
+ # @param culprit [Object] object that is either pertinent, a culprit or culpable
24
+ def initialize message, culprit
25
+
26
+ super(message)
27
+
28
+ @the_culprit = culprit
29
+
30
+ log.info(x) { "An [Error] Occured => #{message}" }
31
+ log.info(x) { "Object of Interest => #{culprit.to_s}" } unless culprit.nil?
32
+ log.info(x) { "Class Name Culprit => #{culprit.class.name}" }
33
+ log.info(x) { "Error Message From => #{self.class.name}" }
34
+ e.backtrace.to_s.log_lines
35
+
36
+ end
37
+
38
+
39
+ # This method gives interested parties the object that
40
+ # is at the centre of the exception. This object is either
41
+ # very pertinent, culpable or at the very least, interesting.
42
+ #
43
+ # @return [String] string representation of culpable object
44
+ def culprit
45
+ return "No culprit identified." if @the_culprit.nil?
46
+ return @the_culprit.to_s
47
+ end
48
+
49
+
50
+ end
51
+
52
+
53
+ end
@@ -0,0 +1,684 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSession
4
+
5
+ require "pp"
6
+
7
+ # --
8
+ # -- -----------------
9
+ # -- Fact Production
10
+ # -- -----------------
11
+ # --
12
+ # -- The fact tree is tasked with fact production
13
+ # -- (population). Fact production is done by [consuming]
14
+ # --
15
+ # -- [1] - simple string, number of boolean facts
16
+ # -- [2] - facts already produced
17
+ # -- [3] - identity facts from command line and environment
18
+ # -- [4] - software (behaviour) that derives facts
19
+ # -- [5] - inherited (extended) facts from (OO) parents
20
+ # --
21
+ # --
22
+ # --
23
+ # -- -----------------------------------------
24
+ # -- The 4 Universal (DevOps) Creation Facts
25
+ # -- -----------------------------------------
26
+ # --
27
+ # -- No matter the (DevOps) eco-system being fabricated, these four
28
+ # -- facts prevail and stand out.
29
+ # --
30
+ # -- Every time a DevOps [eco-system] is created, cloned, or recovered,
31
+ # -- a small cluster of core facts endure to define the instance and act
32
+ # -- as the identification basis of all new eco-system resources.
33
+ # --
34
+ # -- The 4 facts underpinning eco-system creation are
35
+ # --
36
+ # -- [1] - [what] is being built
37
+ # -- [2] - [when] did the building begin
38
+ # -- [3] - [who] instigated it (and from)
39
+ # -- [4] - [which] workstation.
40
+ # --
41
+ # -- ---------------------------------------
42
+ # -- DevOps 4 Creational [Instance] Facts
43
+ # -- ---------------------------------------
44
+ # --
45
+ # -- The core instance identities used and reused time and again relate to
46
+ # --
47
+ # -- [1] - plugin (eg) wordpress.hub or jenkins.hub
48
+ # -- [2] - time (eg) 18036.0952.065
49
+ # -- [3] - user (eg) peterpan
50
+ # -- [4] - workstation (eg) laptop_susie or hp_desktop
51
+ # --
52
+ # --
53
+ class FactFind
54
+ include Singleton
55
+
56
+ @@eval_prefix = "rb>>"
57
+ attr_reader :i, :f
58
+
59
+ # --
60
+ # -- Initialize the internal fact database
61
+ # -- which is exposed for fact consumption
62
+ # -- via
63
+ # --
64
+ # -- @i => [identity] facts (1D)
65
+ # -- @n => (reserved perhaps 4 nested facts)
66
+ # -- @f => [file facts] database (2D)
67
+ # -- @a => (reserved)
68
+ # -- @c => coded consumtion (in software)
69
+ # -- @t => template placeholders (2D)
70
+ # -- @s => sibling (same category) facts (1D)
71
+ # --
72
+ def instantiate plugin_id
73
+
74
+ @i = { :plugin => plugin_id,
75
+ :time => Stamp.yyjjj_hhmm_sst,
76
+ :user => Home.usr,
77
+ :station => nil
78
+ }
79
+
80
+ @f = {}
81
+
82
+ @s = {}
83
+
84
+ @f.store symbol(plugin_id), {}
85
+ @p = @f[symbol(plugin_id)]
86
+
87
+
88
+ end
89
+
90
+
91
+
92
+ #--
93
+ #-- Set the main directory path.
94
+ #-- This method adds the parameter path to
95
+ #-- the identity map. After this method
96
+ #-- executes you will be able to access the
97
+ #-- directory with @i[:dir]
98
+ #--
99
+ def add_dir_to_identity key_directory
100
+ @i[:dir] = key_directory
101
+ end
102
+
103
+
104
+
105
+ # --
106
+ # --
107
+ # --
108
+ def assimilate_plugin_facts
109
+
110
+ plugin_fact_filepath = File.join @i[:src_dir], "#{@i[:plugin]}.ini"
111
+ log.info(x) { "Plugin Factfile => #{plugin_fact_filepath}" }
112
+ assimilate_ini_file plugin_fact_filepath
113
+
114
+ end
115
+
116
+
117
+ # --
118
+ # --
119
+ # --
120
+ def assimilate_general_facts
121
+
122
+ facts_folder = fact_path("published.facts")
123
+
124
+ factfiles_map = Files.in_folders( Array.new.push(facts_folder) )
125
+ factfiles_map.each do |file_name, folder_name|
126
+
127
+ log.info(x) {"Assimilating facts from => [#{file_name}]"}
128
+ factfile_path = File.join factfiles_map[file_name], file_name
129
+ log.info(x) {"Factfile location => [#{nickname factfile_path}]"}
130
+ assimilate_ini_file factfile_path
131
+
132
+ end
133
+
134
+ end
135
+
136
+
137
+ # Assimilate the gem's main factbase fact file into
138
+ # the structure that is exposed to outside classes
139
+ # as the instance variable @f (a 2D array type).
140
+ #
141
+ # The factfile to assimilate is always expected to
142
+ # exist in folder [ ../factbase ]
143
+ #
144
+ # The factfile name within the above folder is expected
145
+ # to be presented in the parameter.
146
+ #
147
+ # @param factfile_name [String] name of factfile to assimilate
148
+ def assimilate factfile_name
149
+
150
+ factfile_dir = File.join(File.dirname(File.expand_path(__FILE__)), "../factbase")
151
+ factfile_path = File.join factfile_dir, factfile_name
152
+
153
+ log.info(x) { "Assimilating factfile in folder => #{factfile_dir}" }
154
+ log.info(x) { "Assimilating factfile with name => #{factfile_name}" }
155
+
156
+ assimilate_ini_file factfile_path
157
+
158
+ end
159
+
160
+
161
+ # --
162
+ # -- Assimilate [[ hub-runtime.ini ]]
163
+ # -- This factfile builds upon the (fundamental) handful of
164
+ # -- identity facts. It derives the facts for
165
+ # --
166
+ # -- - the plugin instance folder
167
+ # -- - the instance stamp id keys
168
+ # --
169
+ # -- The instance fact file is not allowed to harbour any
170
+ # -- external dependencies.
171
+ # --
172
+ def assimilate_instance_facts
173
+
174
+ instance_facts_file = fact_path("hub-runtime.ini")
175
+ log.info(x) { "Path to instance facts file => #{instance_facts_file}" }
176
+ assimilate_ini_file instance_facts_file
177
+
178
+ end
179
+
180
+
181
+ # --
182
+ # -- -----------------------------------
183
+ # -- Finding the Workstation (Category)
184
+ # -- -----------------------------------
185
+ # --
186
+ # -- The known hosts facts file is parsed with each
187
+ # -- section [examined] by asking two (2) questions.
188
+ # --
189
+ # -- [1] - is [username] this workstation's username?
190
+ # -- [2] - does [hostnames] include this hostname?
191
+ # --
192
+ # -- The 1st section to answer [YES] to both questions
193
+ # -- is deemed as our workstation. Its symbol header is
194
+ # -- then used for assimilation - how?
195
+ # --
196
+ # -- ----------------------------------------
197
+ # -- Assimilating Workstation Specific Facts
198
+ # -- ----------------------------------------
199
+ # --
200
+ # -- We do NOT assimilate the whole file.
201
+ # -- We simply assimilate the [SECTION] of the file
202
+ # -- that is deemed to be OUR (this) workstation.
203
+ # --
204
+ # -- -------------------------------------------
205
+ # -- Dependency Constraints | Workstation Facts
206
+ # -- -------------------------------------------
207
+ # --
208
+ # -- (work)station facts can [only] depend on facts that
209
+ # -- have been declared in [[ hub-runtime.ini ]]. No
210
+ # -- other external fact dependencies are permitted.
211
+ # --
212
+ def identify_my_workstation
213
+
214
+ workstation_factfile_name = "known-hosts.ini"
215
+ log_begin_workstation_identification workstation_factfile_name
216
+ stations_factfile = fact_path workstation_factfile_name
217
+ log.info(x) { "Workstations Facts File (Path) => #{nickname stations_factfile}" }
218
+
219
+ our_user = Home.usr
220
+ our_host = NetDns.instance.host_name
221
+ log.info(x){ "Station Search For => #{our_user}@#{our_host}" }
222
+
223
+ workstations = IniFile.load stations_factfile
224
+ workstations.each_section do |station|
225
+
226
+ no_user = "Workstation [#{station}] has no [username] fact."
227
+ raise RuntimeError.new no_user unless workstations[station].has_key? "username"
228
+
229
+ has_hostnames = workstations[station].has_key? "hostnames"
230
+ no_hostnames = "[#{station}] not a workstation as no [hostnames] fact - Skip!"
231
+ log.warn(x) { no_hostnames } unless has_hostnames
232
+ next unless has_hostnames
233
+
234
+ this_user = evaluate(workstations[station]["username"])
235
+ these_hosts = evaluate(workstations[station]["hostnames"])
236
+ match = this_user.eql?(our_user) && these_hosts.include?(our_host)
237
+
238
+ log.info(x){ "[#{station}] with #{this_user}@#{these_hosts} - No!" } unless match
239
+ next unless match
240
+
241
+ log.info(x){ "[#{station}] with #{this_user}@#{these_hosts} - Matched!" }
242
+ dup_msg = "Duplicate or repeat match disallowed! #{@i[:station]} and #{station}"
243
+ raise RuntimeError.new dup_msg unless @i[:station].nil?
244
+
245
+ @i[:station] = station
246
+ @i[:workstation] = station.gsub(".", "_").to_sym
247
+
248
+ end
249
+
250
+ no_match_msg = "No workstation match made for [#{our_user}@#{our_host}]."
251
+ raise RuntimeError.new no_match_msg if @i[:station].nil?
252
+ log_end_workstation_identification workstation_factfile_name
253
+ LogObject.map @i
254
+
255
+ end
256
+
257
+
258
+ #--
259
+ #-- Knowing and setting @i[:workstation] to our workstation is key.
260
+ #-- This means that the other workstations can reference files in
261
+ #-- each others drives without knowing which workstation is being
262
+ #-- used (see ssh.keyfile for a ghost reference example).
263
+ #--
264
+ #-- Now we can proceed to assimilate the entire station facts file.
265
+ #--
266
+ def assimilate_station_facts
267
+
268
+ stations_factfile = fact_path "known-hosts.ini"
269
+ assimilate_ini_file stations_factfile
270
+
271
+ end
272
+
273
+
274
+ # --
275
+ # -- Get the path to a fact file or folder within the
276
+ # -- reusable facts source tree.
277
+ # --
278
+ # -- The base directory is acquired by dropping down
279
+ # -- three (3) directory levels from where this module
280
+ # -- is and then going into reusable.facts and finally
281
+ # -- appending the parameter path (file or folder).
282
+ # --
283
+ def fact_path fact_filename
284
+ fact_basedir = File.dirname( File.dirname( File.dirname( __FILE__ ) ) )
285
+ return File.join( File.join(fact_basedir,"reusable.facts"), fact_filename )
286
+ end
287
+
288
+
289
+ # --
290
+ # -- Call instantiate() before calling populate().
291
+ # --
292
+ # -- This method assimilates any and all fact files
293
+ # -- (recursively) found in two subdirectories
294
+ # --
295
+ # -- [1] - "reusable facts" and
296
+ # -- [2] - the [plugin] folder
297
+ # --
298
+ def self.populate
299
+
300
+ end
301
+
302
+
303
+ # -- -------------------------------------------------------------- -- #
304
+ # -- Eval and return result of parameter string if it is ruby code. -- #
305
+ # -- -------------------------------------------------------------- -- #
306
+ def evaluate string
307
+
308
+ # -----> @todo raise a FactError here
309
+
310
+ raise RuntimeError.new "Fact to Evaluate is Nil." if string.nil?
311
+ return string unless string.start_with? @@eval_prefix
312
+ return eval( string.gsub @@eval_prefix, "" )
313
+
314
+ end
315
+
316
+
317
+ # ----> -------------------------------------------------->
318
+ # ----> How to Write a Custom Error
319
+ # ----> -------------------------------------------------->
320
+ # ----> Add a custom data attributes to your exception
321
+ # ----> You can add custom data to your exception just like you'd do it in any other class. Let's add an attribute reader to our class and update the constructor.
322
+ # ----> class MyError < StandardError
323
+ # ----> attr_reader :thing
324
+ # ----> def initialize(msg="My default message", thing="apple")
325
+ # ----> @thing = thing
326
+ # ----> super(msg)
327
+ # ----> end
328
+ # ----> end
329
+ # ----> -------------------------------------------------->
330
+ # ----> Using the Custom Error Class
331
+ # ----> -------------------------------------------------->
332
+ # ----> begin
333
+ # ----> raise MyError.new("my message", "my thing")
334
+ # ----> rescue => e
335
+ # ----> puts e.thing # "my thing"
336
+ # ----> end
337
+ # ----> -------------------------------------------------->
338
+
339
+
340
+ # -- ---------------------------------------- -- #
341
+ # -- Add a fact to the main 2D fact database. -- #
342
+ # -- ---------------------------------------- -- #
343
+ def add_fact group_symbol, key_symbol, key_value
344
+
345
+ nil_error_text = "Neither fact coordinates nor value can be nil. [group]=> #{group_symbol} [key]=> #{key_symbol} [value]=> #{key_value}"
346
+ raise ArgumentError.new nil_error_text if group_symbol.nil? || key_symbol.nil? || key_value.nil?
347
+
348
+ if @f.has_key? group_symbol then
349
+
350
+ # --
351
+ # -- This isn't the first fact within this group
352
+ # -- so store the new fact key/value pair within
353
+ # -- the group's namespace.
354
+ # --
355
+ @f[group_symbol][key_symbol] = key_value
356
+
357
+ else
358
+
359
+ # --
360
+ # -- Create a new umbrella grouping against which
361
+ # -- the new key-value pairing will be inserted.
362
+ # --
363
+ @f.store group_symbol, { key_symbol => key_value }
364
+
365
+ end
366
+
367
+ # --
368
+ # -- The @s sibling hash is updated to reflect the
369
+ # -- key-value pairs within the current group. This
370
+ # -- allows @s to be used as shorthand within INI
371
+ # -- file fact definition statements.
372
+ # --
373
+ @s = @f[group_symbol]
374
+
375
+ end
376
+
377
+
378
+ # -- ------------------------------------------- -- #
379
+ # -- -- #
380
+ # -- Template -- #
381
+ # -- -- #
382
+ # -- The longest river in africa is without -- #
383
+ # -- doubt the @[africa|longest.river]. Now -- #
384
+ # -- @[south.america|most.spoken] is the -- #
385
+ # -- most common language in south america. -- #
386
+ # -- -- #
387
+ # -- The population of the americas -- #
388
+ # -- is @[americas|population] according to
389
+ # -- the Harvard 2015 census.
390
+ # -- -- #
391
+ # -- ------------------------------------------- -- #
392
+ # -- -- #
393
+ # -- Ruby Code -- #
394
+ # -- -- #
395
+ # -- double_north_america_pop = @f[:north_america][:population] * 2
396
+ # -- -- #
397
+ # -- ------------------------------------------- -- #
398
+ # -- Parameters -- #
399
+ # -- factory_facts : instantiated 2D hash -- #
400
+ # -- ini_filepath : path to factfile to read -- #
401
+ # -- -- #
402
+ # -- Dependencies and Assumptions -- #
403
+ # -- the [inifile] gem is installed -- #
404
+ # -- file exists at the ini_filepath -- #
405
+ # -- factory_facts are instantiated -- #
406
+ # -- identity facts like @i[:plugin] exist -- #
407
+ # -- ------------------------------------------- -- #
408
+ def assimilate_ini_file ini_filepath
409
+
410
+ fact_filename = File.basename ini_filepath
411
+ log_begin fact_filename
412
+
413
+ no_file = "No (ini) factfile found here => #{ini_filepath}"
414
+ raise ArgumentError.new no_file unless File.exists? ini_filepath
415
+
416
+ # --
417
+ # -- Use the inifile gem to parse and read the fact
418
+ # -- file contents into Ruby's map structures.
419
+ # --
420
+ begin
421
+
422
+ map_facts = IniFile.load ini_filepath
423
+ map_facts.each do | group_str, key_str, input_value |
424
+ assimilate_fact group_str, key_str, input_value
425
+ end
426
+
427
+ rescue Exception => e
428
+
429
+ log.fatal(x) { "## ############################ #################################" }
430
+ log.fatal(x) { "## Fact File Assimilation Error ---------------------------------" }
431
+ log.fatal(x) { "## ############################ #################################" }
432
+ log.fatal(x) { "## File => #{ini_filepath}" }
433
+ log.fatal(x) { "## Error => #{e.message}" }
434
+ log.fatal(x) { "## ############################ #################################" }
435
+ e.backtrace.log_lines
436
+ log.fatal(x) { "## ############################ #################################" }
437
+
438
+ raise e
439
+
440
+ end
441
+
442
+ log_end fact_filename
443
+
444
+ end
445
+
446
+
447
+
448
+ def assimilate_fact group_str, key_str, input_value
449
+
450
+ grp_symbol = group_str.gsub(".", "_").to_sym
451
+ key_symbol = key_str.gsub(".", "_").to_sym
452
+
453
+ raise ArgumentError, "Assimilating Fact [ #{group_str} ][ #{key_str} ] => Value is NIL" if input_value.nil?
454
+
455
+ fact_val = input_value.strip
456
+
457
+ begin
458
+
459
+ unless discard_fact?( group_str, key_str, fact_val )
460
+ eval_value = evaluate(get_fact_value(fact_val))
461
+ add_fact grp_symbol, get_key_symbol(key_str), eval_value
462
+ end
463
+
464
+ rescue Exception => e
465
+
466
+ log.fatal(x) { "## ##################### #################################" }
467
+ log.fatal(x) { "## Fact Evaluation Error ---------------------------------" }
468
+ log.fatal(x) { "## ##################### #################################" }
469
+ log.fatal(x) { "## Fact Family => #{group_str}" }
470
+ log.fatal(x) { "## Fact Key => #{key_str}" }
471
+ log.fatal(x) { "## Fact Stmt => #{fact_val}" }
472
+ log.fatal(x) { "## Fact Error => #{e.message}" }
473
+ log.fatal(x) { "## ##################### #################################" }
474
+ e.backtrace.log_lines
475
+
476
+ raise e
477
+
478
+ end
479
+
480
+ unless @f.has_key? grp_symbol then
481
+
482
+ log.debug(x){ "# -- ---------------------------------------------------------- #" }
483
+ log.debug(x){ "# -- the [#{group_str}] silo facts." }
484
+ log.debug(x){ "# -- ---------------------------------------------------------- #" }
485
+
486
+ end
487
+
488
+ id_keystring = "#{grp_symbol}#{key_symbol}".downcase
489
+ sensitive = id_keystring.includes_any? [ "secret", "password", "credential", "creds" ]
490
+ print_value = "****************"
491
+ print_value = eval_value unless sensitive
492
+
493
+ # -- -------------------------------------------------------- -- #
494
+ # -- Log the human readable (fixed-width) key and value pair. -- #
495
+ # -- -------------------------------------------------------- -- #
496
+ fw_key = sprintf '%-33s', "@f[:#{grp_symbol}][:#{key_symbol}]"
497
+ log.debug(x){ "#{fw_key} => #{print_value}" }
498
+
499
+ end
500
+
501
+
502
+ def discard_fact? group_str, key_str, input_value
503
+
504
+ is_if = key_str.strip.end_with? "(if)"
505
+ is_unless = key_str.strip.end_with?("(un)") || key_str.strip.end_with?("(unless)")
506
+ return false unless is_if || is_unless
507
+
508
+ two_parts = input_value.split( @@eval_prefix )
509
+ no_prefix = "Conditional must be followed by eval prefix => #{two_parts}"
510
+ raise RuntimeError.new no_pefix unless two_parts.length == 2
511
+
512
+ conditional_part = two_parts.first.strip
513
+ no_curlies_msg = "Wrap conditional in curly braces => #{conditional_part}"
514
+ is_wrapped = conditional_part.start_with?("{") && conditional_part.end_with?("}")
515
+ raise RuntimeError.new no_curlies_msg unless is_wrapped
516
+
517
+ conditional_stmt = conditional_part[1..-2].strip
518
+ log.info(x){ "Conditional Stmt => #{conditional_stmt}" }
519
+ conditional_val = evaluate( @@eval_prefix + conditional_stmt )
520
+ is_boolean = [true, false].include? conditional_val
521
+
522
+ boolean_msg = "=> #{conditional_stmt} <= evaluated to [#{conditional_val}] not boolean."
523
+ raise RuntimeError.new boolean_msg unless is_boolean
524
+
525
+ return false if is_if && conditional_val
526
+ return true if is_if && !conditional_val
527
+
528
+ return true if is_unless && conditional_val
529
+ return false if is_unless && !conditional_val
530
+
531
+ raise RuntimeError.new "Unreachable if[#{is_if}] unless[#{is_unless}] => #{conditional_val}"
532
+
533
+ end
534
+
535
+
536
+ #--
537
+ #-- Return the symbolic representation of the
538
+ #-- parameter key. Periods are replaced with
539
+ #-- underscores (as per the fact convention)
540
+ #-- before conversion to a symbol.
541
+ #--
542
+ #-- Nil is not handled.
543
+ #-- String is stripped beforehand just in case.
544
+ #--
545
+ def symbol from_string
546
+
547
+ return from_string.strip.gsub(".", "_").to_sym
548
+
549
+ end
550
+
551
+
552
+ #--
553
+ #-- Return the (key access) symbol that represents the
554
+ #-- plugin id plus a string given in the parameter.
555
+ #--
556
+ #-- ---------
557
+ #-- Example
558
+ #-- ---------
559
+ #--
560
+ #-- Plugin Id => ide.hub
561
+ #-- Append Str => host
562
+ #--
563
+ #-- equals
564
+ #--
565
+ #-- Key String => ide.hub.host
566
+ #-- Key Symbol => ide_hub_host
567
+ #--
568
+ #--
569
+ #-- So the symbol :ide_hub_host is returned.
570
+ #--
571
+ def plugin_symbol append_string
572
+
573
+ key_string = @i[:plugin] + "." + append_string.strip
574
+ return key_string.gsub(".", "_").to_sym
575
+
576
+ end
577
+
578
+
579
+ def get_key_symbol dirty_key_string
580
+
581
+ key_string = dirty_key_string.strip
582
+ split_string = "(unless)"
583
+ split_string = "(if)" if key_string.end_with? "(if)"
584
+ split_string = "(un)" if key_string.end_with? "(un)"
585
+
586
+ return key_string.split(split_string).first.gsub(".", "_").to_sym
587
+
588
+ end
589
+
590
+
591
+ def get_fact_value fact_value_string
592
+
593
+ is_conditional = fact_value_string.start_with?("{") && fact_value_string.include?( @@eval_prefix )
594
+ return fact_value_string unless is_conditional
595
+
596
+ return fact_value_string.rpartition( @@eval_prefix )[1..-1].join
597
+
598
+ end
599
+
600
+
601
+ def exists? fact_reference
602
+
603
+ log.info(x) { "Does Fact Exist? => #{fact_reference}" }
604
+ return false if fact_reference.nil?
605
+ return false if fact_reference.strip.length == 0
606
+ return true if fact_reference.strip.length > 0
607
+
608
+ end
609
+
610
+
611
+ # --
612
+ # -- dot => period (full stop)
613
+ # -- Deliver a "." period character
614
+ # --
615
+ def dot
616
+ return "."
617
+ end
618
+
619
+
620
+ # --
621
+ # -- colon => full colon character
622
+ # -- Delivers a ":" colon character
623
+ # --
624
+ def colon
625
+ return ":"
626
+ end
627
+
628
+
629
+ def log_begin_workstation_identification the_filename
630
+
631
+ log.info(x) { "- -" }
632
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
633
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
634
+ log.info(x) { "# -- [= BEGIN WORKSTATION IDENTIFICATION =] #{the_filename}" }
635
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
636
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
637
+
638
+ end
639
+
640
+
641
+ def log_end_workstation_identification the_filename
642
+
643
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
644
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
645
+ log.info(x) { "# -- [= END WORKSTATION IDENTIFICATION =] #{the_filename}" }
646
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
647
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
648
+ log.info(x) { "- -" }
649
+ log.info(x) { "- -" }
650
+ log.info(x) { "- -" }
651
+
652
+ end
653
+
654
+
655
+ def log_begin the_filename
656
+
657
+ log.info(x) { "- -" }
658
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
659
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
660
+ log.info(x) { "# -- [= BEGIN THE ASSIMILATION =] #{the_filename}" }
661
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
662
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
663
+
664
+ end
665
+
666
+
667
+ def log_end the_filename
668
+
669
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
670
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
671
+ log.info(x) { "# -- [= END ASSIMILATION =] #{the_filename}" }
672
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
673
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
674
+ log.info(x) { "- -" }
675
+ log.info(x) { "- -" }
676
+ log.info(x) { "- -" }
677
+
678
+ end
679
+
680
+
681
+ end
682
+
683
+
684
+ end