opensecret 0.0.2 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/README.md +2 -2
- data/bin/opensecret +3 -6
- data/lib/opensecret-domain.ini +23 -0
- data/lib/opensecret.rb +30 -2
- data/lib/opensecret/additions/array.rb +117 -0
- data/lib/opensecret/additions/dir.rb +35 -0
- data/lib/opensecret/additions/string.rb +312 -0
- data/lib/opensecret/commons/eco.cmdline.rb +446 -0
- data/lib/opensecret/commons/eco.faculty.rb +364 -0
- data/lib/opensecret/commons/eco.system.rb +437 -0
- data/lib/opensecret/commons/eco.systems.rb +98 -0
- data/lib/opensecret/{safe.rb → delegate.rb} +4 -2
- data/lib/opensecret/eco.do.rb +46 -0
- data/lib/opensecret/executors/crypt.keys/crypt.keys.ini +79 -0
- data/lib/opensecret/executors/crypt.keys/crypt.keys.rb +68 -0
- data/lib/opensecret/executors/decrypt/decrypt.ini +64 -0
- data/lib/opensecret/executors/decrypt/decrypt.rb +49 -0
- data/lib/opensecret/executors/encrypt/encrypt.ini +55 -0
- data/lib/opensecret/executors/encrypt/encrypt.rb +82 -0
- data/lib/opensecret/factbase/hub-runtime.ini +123 -0
- data/lib/opensecret/factbase/known-hosts.ini +75 -0
- data/lib/opensecret/factbase/published.facts/blobbolicious-facts.ini +553 -0
- data/lib/opensecret/factbase/published.facts/credential-facts.ini +40 -0
- data/lib/opensecret/factbase/published.facts/infrastructure-facts.ini +63 -0
- data/lib/opensecret/factbase/readme.md +24 -0
- data/lib/opensecret/factbase/retired.facts/maven.database.ide.facts.ini +127 -0
- data/lib/opensecret/factbase/retired.facts/s3-upload-block-facts.ini +17 -0
- data/lib/opensecret/plugins.io/cipher/crypto.rb +174 -0
- data/lib/opensecret/plugins.io/error/eco.exceptions.rb +24 -0
- data/lib/opensecret/plugins.io/facts/fact.chars.rb +66 -0
- data/lib/opensecret/plugins.io/facts/fact.factor.rb +156 -0
- data/lib/opensecret/plugins.io/facts/fact.locator.rb +105 -0
- data/lib/opensecret/plugins.io/facts/fact.reader.rb +137 -0
- data/lib/opensecret/plugins.io/facts/fact.tree.rb +661 -0
- data/lib/opensecret/plugins.io/file/file.rb +483 -0
- data/lib/opensecret/plugins.io/git/git.flow.rb +388 -0
- data/lib/opensecret/plugins.io/logs/log.object.rb +89 -0
- data/lib/opensecret/plugins.io/logs/logging.rb +203 -0
- data/lib/opensecret/plugins.io/time/time.stamp.rb +425 -0
- data/lib/opensecret/version.rb +2 -2
- data/opensecret.gemspec +8 -13
- metadata +68 -18
@@ -0,0 +1,483 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# -- --------------------------------------------------------------- -- #
|
4
|
+
# -- File facts are placeholders (keys in effect) just begging to be -- #
|
5
|
+
# -- replaced by values sourced from some sort of map. This software -- #
|
6
|
+
# -- centres around the DevOps fact replacement placeholder pattern. -- #
|
7
|
+
# -- --------------------------------------------------------------- -- #
|
8
|
+
class Files
|
9
|
+
#### ==> ===================================================================================
|
10
|
+
#### ==> ===================================================================================
|
11
|
+
#### ==> Name this class FindReplace or simply just Replace => Replace.contains? Replace.do
|
12
|
+
#### ==> Name this class FindReplace or simply just Replace => Replace.contains? Replace.do
|
13
|
+
#### ==> Name this class FindReplace or simply just Replace => Replace.contains? Replace.do
|
14
|
+
#### ==> Name this class FindReplace or simply just Replace => Replace.contains? Replace.do
|
15
|
+
#### ==> Name this class FindReplace or simply just Replace => Replace.contains? Replace.do
|
16
|
+
#### ==> Name this class FindReplace or simply just Replace => Replace.contains? Replace.do
|
17
|
+
#### ==> Name this class FindReplace or simply just Replace => Replace.contains? Replace.do
|
18
|
+
#### ==> ===================================================================================
|
19
|
+
#### ==> ===================================================================================
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
## --- ---------------------------------------------------------------------- --- #
|
24
|
+
## --- How to Use File to extract different parts of an [absolute] file path. --- #
|
25
|
+
## --- ---------------------------------------------------------------------- --- #
|
26
|
+
### File Names ====] file = "/path/to/xyz.mp4"
|
27
|
+
### File Names ====] comp = File.basename file # => "xyz.mp4"
|
28
|
+
### File Names ====] extn = File.extname file # => ".mp4"
|
29
|
+
### File Names ====] name = File.basename file, extn # => "xyz"
|
30
|
+
### File Names ====] path = File.dirname file # => "/path/to"
|
31
|
+
## --- ---------------------------------------------------------------------- --- #
|
32
|
+
|
33
|
+
|
34
|
+
# --
|
35
|
+
# -- Scan every file in directory for placeholder keys within the
|
36
|
+
# -- parameter map and replace them with the corresponding value.
|
37
|
+
# -- Not Recursive => the scan does [not] recurse into folders
|
38
|
+
# --
|
39
|
+
# -- ----------------------------------
|
40
|
+
# -- Replacing Betty (Nested Replace)
|
41
|
+
# -- ----------------------------------
|
42
|
+
# --
|
43
|
+
# -- "GoBBetBettytyettyne" => "Gone"
|
44
|
+
# --
|
45
|
+
# -- A nested replace is done up to approximately 5 levels deep.
|
46
|
+
# -- So replacing "Betty" from the above string does [NOT] produce
|
47
|
+
# -- "GoBBettyettyne". The string becomes "Gone".
|
48
|
+
# --
|
49
|
+
# -- -----------
|
50
|
+
# -- Parameters
|
51
|
+
# -- -----------
|
52
|
+
# -- fact_map : driving [placeholder] => [value] map
|
53
|
+
# -- replace_dir : dir subject of the scan and replace
|
54
|
+
# --
|
55
|
+
def self.find_replace fact_map, replace_folder
|
56
|
+
|
57
|
+
log.info(ere){ "#-- --------------------------------------------------------- #" }
|
58
|
+
log.info(ere){ "#-- File changing in #{File.basename replace_folder}" }
|
59
|
+
log.info(ere){ "#-- #{replace_folder}" }
|
60
|
+
log.info(ere){ "#-- --------------------------------------------------------- #" }
|
61
|
+
|
62
|
+
# -- ------------------------------------------------------------------------------ -- #
|
63
|
+
# -- Iterate to substitute matched strings in file with their corresponding values. -- #
|
64
|
+
# -- ------------------------------------------------------------------------------ -- #
|
65
|
+
Dir.foreach( replace_folder ) do | file_name |
|
66
|
+
|
67
|
+
file_path = File.join replace_folder, file_name
|
68
|
+
next if File.directory? file_path
|
69
|
+
next if File.extname(file_path).eql? ".log"
|
70
|
+
|
71
|
+
nested_key_replace fact_map, file_path
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
log.info(ere){ "#-- --------------------------------------------------------- #" }
|
76
|
+
log.info(ere){ "#-- Done changing files in #{File.basename replace_folder}" }
|
77
|
+
log.info(ere){ "#-- --------------------------------------------------------- #" }
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
#--
|
82
|
+
#-- Using the parameter [file] [replace] any occurence
|
83
|
+
#-- of any [key] found in the parameter [map] with the
|
84
|
+
#-- corresponding mapped key [value].
|
85
|
+
#--
|
86
|
+
#-- -----------------------------------
|
87
|
+
#-- [Nested Replace]
|
88
|
+
# -- Replacing Betty (Nested Replace)
|
89
|
+
# -- ----------------------------------
|
90
|
+
# --
|
91
|
+
# -- "GoBBetBettytyettyne" => "Gone"
|
92
|
+
# --
|
93
|
+
# -- A nested replace is done up to approximately 5 levels deep.
|
94
|
+
# -- So replacing "Betty" from the above string does [NOT] produce
|
95
|
+
# -- "GoBBettyettyne". The string becomes "Gone".
|
96
|
+
# --
|
97
|
+
def self.nested_key_replace source_map, filepath
|
98
|
+
|
99
|
+
for i in 1..5
|
100
|
+
file_changed = key_replace source_map, filepath
|
101
|
+
return unless file_changed
|
102
|
+
log.info(ere){ "#-- --------------------------------------------------------- #" }
|
103
|
+
log.info(ere){ "#-- File #{File.basename filepath} has been changed" }
|
104
|
+
log.info(ere){ "#-- --------------------------------------------------------- #" }
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
#--
|
110
|
+
#-- Using the parameter [file] [replace] any occurence
|
111
|
+
#-- of any [key] found in the parameter [map] with the
|
112
|
+
#-- corresponding mapped key [value].
|
113
|
+
#--
|
114
|
+
#-- Side Effect => If at least one replacement occured this
|
115
|
+
#-- method returns true, else false.
|
116
|
+
#--
|
117
|
+
def self.key_replace source_map, filepath
|
118
|
+
|
119
|
+
replace_happened = false
|
120
|
+
|
121
|
+
source_map.each do |theKey, theValue|
|
122
|
+
|
123
|
+
next unless has_string? filepath, theKey
|
124
|
+
factorize theKey, theValue, filepath
|
125
|
+
replace_happened = true
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
return replace_happened
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
#--
|
136
|
+
#-- Produce a map of every "recursive" file sitting under
|
137
|
+
#-- any and all of the parameter directories array.
|
138
|
+
#--
|
139
|
+
#-- Harboured folders are traversed but folder names are
|
140
|
+
#-- excluded from the resulting map.
|
141
|
+
#--
|
142
|
+
#-- The key/value structure of the map is
|
143
|
+
#--
|
144
|
+
#-- key => simple filename
|
145
|
+
#-- value => (abs) folder path
|
146
|
+
#--
|
147
|
+
#-- --------------------------------
|
148
|
+
#-- Filename NOT UNIQUE Exception
|
149
|
+
#-- --------------------------------
|
150
|
+
#--
|
151
|
+
#-- Simple filename UNIQUENESS must prevail.
|
152
|
+
#--
|
153
|
+
#-- If the same base filename is found in any part or level
|
154
|
+
#-- of the directory trees under the every parameter parent
|
155
|
+
#-- folder - an exception will be thrown.
|
156
|
+
#--
|
157
|
+
def self.in_folders parent_folders
|
158
|
+
|
159
|
+
files_map = {}
|
160
|
+
|
161
|
+
parent_folders.each do |parent_folder|
|
162
|
+
|
163
|
+
log.info(ere) { "Create map of files under #{nickname parent_folder}" }
|
164
|
+
Throw.if_not_exists parent_folder
|
165
|
+
|
166
|
+
Dir["#{parent_folder}/**/*"].each do |child_file|
|
167
|
+
|
168
|
+
next if File.directory? child_file
|
169
|
+
filename = File.basename child_file
|
170
|
+
foldername = File.dirname child_file
|
171
|
+
log.info(ere) { " #{filename} => #{nickname foldername}" }
|
172
|
+
error_str = "Name NOT UNIQUE Error => [#{filename}].\n\n#{files_map.inspect}"
|
173
|
+
raise RuntimeError.new error_str if files_map.has_key? filename
|
174
|
+
files_map.store filename, foldername
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
return files_map
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
#--
|
186
|
+
#-- Find files of a given type (extension) that exist
|
187
|
+
#-- recursively under a folder.
|
188
|
+
#--
|
189
|
+
#-- --------------------------------
|
190
|
+
#-- Filename NOT UNIQUE Exception
|
191
|
+
#-- --------------------------------
|
192
|
+
#--
|
193
|
+
#-- Simple filename UNIQUENESS must prevail.
|
194
|
+
#--
|
195
|
+
#-- If the same base filename is found in any part or level
|
196
|
+
#-- of the directory trees under the every parameter parent
|
197
|
+
#-- folder - an exception will be thrown.
|
198
|
+
#--
|
199
|
+
#-- ------------
|
200
|
+
#-- Parameters
|
201
|
+
#-- ------------
|
202
|
+
#--
|
203
|
+
#-- base_folder => the top-level folder to search
|
204
|
+
#-- dir at (abs) path must exist
|
205
|
+
#--
|
206
|
+
#-- file_extn => extension of interesting files
|
207
|
+
#-- including the leading [period].
|
208
|
+
#-- (send ".exe" for exe files)
|
209
|
+
#-- (send ".md" for markdown files)
|
210
|
+
#--
|
211
|
+
#-- ------------
|
212
|
+
#-- Map Returned
|
213
|
+
#-- ------------
|
214
|
+
#--
|
215
|
+
#-- Returns a { filename => rel_path } map of the matching
|
216
|
+
#-- files in the folder. The map
|
217
|
+
#--
|
218
|
+
#-- keys => simple filename without extension
|
219
|
+
#-- values => relative path from the base folder
|
220
|
+
#--
|
221
|
+
def self.to_name_path_map base_folder, file_extn
|
222
|
+
|
223
|
+
files_map = {}
|
224
|
+
|
225
|
+
Dir["#{base_folder}/**/*#{file_extn}"].each do |filepath|
|
226
|
+
|
227
|
+
next if File.directory? filepath
|
228
|
+
ext_error = "File extension not [#{file_extn}] in => #{nickname filepath}"
|
229
|
+
raise RuntimeError.new(ext_error) unless File.extname(filepath).eql? "#{file_extn}"
|
230
|
+
|
231
|
+
filename = File.basename filepath
|
232
|
+
|
233
|
+
error_str = "Name NOT UNIQUE Error => [#{filename}].\n\n#{files_map.inspect}"
|
234
|
+
raise RuntimeError.new error_str if files_map.has_key? filename
|
235
|
+
files_map.store filename, filepath
|
236
|
+
|
237
|
+
end
|
238
|
+
|
239
|
+
return files_map
|
240
|
+
|
241
|
+
end
|
242
|
+
|
243
|
+
|
244
|
+
#--
|
245
|
+
#-- Return a new map with the values folder path
|
246
|
+
#-- forwarded by one level
|
247
|
+
#--
|
248
|
+
#-- If the map contains the below
|
249
|
+
#--
|
250
|
+
#-- {
|
251
|
+
#-- file1 => user/docs/pdfs,
|
252
|
+
#-- file2 => user/docs/pdfs/good,
|
253
|
+
#-- file3 => user/docs/pdfs/bad
|
254
|
+
#-- }
|
255
|
+
#--
|
256
|
+
#-- This method will return a map like this
|
257
|
+
#--
|
258
|
+
#-- {
|
259
|
+
#-- file1 => docs/pdfs,
|
260
|
+
#-- file2 => docs/pdfs/good,
|
261
|
+
#-- file3 => docs/pdfs/bad
|
262
|
+
#-- }
|
263
|
+
#--
|
264
|
+
#-- The values part has been forwarded by one level.
|
265
|
+
#--
|
266
|
+
def self.forwarded_path files_map
|
267
|
+
|
268
|
+
changed_map = {}
|
269
|
+
|
270
|
+
files_map.each do |the_name, the_old_path|
|
271
|
+
the_new_path = the_old_path.split("/")[1..-1].join("/")
|
272
|
+
changed_map.store the_name, the_new_path
|
273
|
+
log.info(ere){ "Forwarded from #{the_old_path} to #{the_new_path}" }
|
274
|
+
end
|
275
|
+
|
276
|
+
return changed_map
|
277
|
+
|
278
|
+
end
|
279
|
+
|
280
|
+
|
281
|
+
#--
|
282
|
+
#-- Path stripper expects the path in the first parameter
|
283
|
+
#-- to start with the path in the second parameter.
|
284
|
+
#--
|
285
|
+
#-- It then returns the first parameter path with the
|
286
|
+
#-- leading path stripped out.
|
287
|
+
#--
|
288
|
+
#-- ---------------------------
|
289
|
+
#-- Strip Leading Path Example
|
290
|
+
#-- ---------------------------
|
291
|
+
#--
|
292
|
+
#-- 1st param path = /home/joe/docs/pdfs/websites
|
293
|
+
#-- 2nd param path = /home/joe/docs
|
294
|
+
#-- Returned Path = pdfs/websites
|
295
|
+
#--
|
296
|
+
#-- ---------------------------------
|
297
|
+
#-- The Middle Separator is Stripped
|
298
|
+
#-- ---------------------------------
|
299
|
+
#--
|
300
|
+
#-- Note above that the middle separator is stripped
|
301
|
+
#-- so the returned string has no leading separator.
|
302
|
+
#--
|
303
|
+
def self.lead_path_chopped long_path, lead_path
|
304
|
+
|
305
|
+
return long_path.gsub(lead_path, "")[1..-1]
|
306
|
+
|
307
|
+
end
|
308
|
+
|
309
|
+
|
310
|
+
# -- ------------------------------------------------------------------- -- #
|
311
|
+
# -- Returns true when the parameter file contains the parameter string. -- #
|
312
|
+
# -- As a side effect the lines with at least 1 string match are logged. -- #
|
313
|
+
# -- ------------------------------------------------------------------- -- #
|
314
|
+
def self.has_string? the_file, theString
|
315
|
+
|
316
|
+
containsMatch = false;
|
317
|
+
line_index = 0;
|
318
|
+
|
319
|
+
File.open( the_file, "r") do | file_obj |
|
320
|
+
|
321
|
+
name_abbrv = File.basename the_file
|
322
|
+
file_obj.each_line do | file_line |
|
323
|
+
|
324
|
+
line_index = line_index + 1
|
325
|
+
lineCount = sprintf '%03d', line_index
|
326
|
+
if file_line.include? theString then
|
327
|
+
|
328
|
+
squeezed_line = file_line.chomp.strip.squeeze(" ")
|
329
|
+
log.info(ere) { "== string [#{theString}] occurs @line #{lineCount} in #{name_abbrv}" }
|
330
|
+
log.info(ere) { "== |---> #{squeezed_line}" }
|
331
|
+
containsMatch = true
|
332
|
+
|
333
|
+
end
|
334
|
+
|
335
|
+
end
|
336
|
+
|
337
|
+
end
|
338
|
+
|
339
|
+
return containsMatch;
|
340
|
+
|
341
|
+
end
|
342
|
+
|
343
|
+
|
344
|
+
# --
|
345
|
+
# -- [FIND] lines that include a set of configured strings and
|
346
|
+
# -- [REPLACE] then with the configured alternative.
|
347
|
+
# --
|
348
|
+
# -- -----------
|
349
|
+
# -- Parameters
|
350
|
+
# -- -----------
|
351
|
+
# --
|
352
|
+
# -- filepath : path to existing "to be changed" file
|
353
|
+
# -- includes : include string array for line matching
|
354
|
+
# -- new_line : replace the matched line with this str
|
355
|
+
# --
|
356
|
+
# -- --------------------------------
|
357
|
+
# -- Dependencies and Assumptions
|
358
|
+
# -- --------------------------------
|
359
|
+
# --
|
360
|
+
# -- file exists at filepath
|
361
|
+
# --
|
362
|
+
def self.find_replace_lines filepath, includes, new_line
|
363
|
+
|
364
|
+
Throw.if_not_exists filepath
|
365
|
+
Throw.if_nil includes
|
366
|
+
Throw.if_nil new_line
|
367
|
+
|
368
|
+
line_matches_count = 0;
|
369
|
+
new_file_lines_set = ""
|
370
|
+
|
371
|
+
File.open( filepath, "r") do | file_obj |
|
372
|
+
|
373
|
+
file_obj.each_line do | file_line |
|
374
|
+
|
375
|
+
unless (String.includes_all?( file_line, includes ) ) then
|
376
|
+
new_file_lines_set += file_line
|
377
|
+
next
|
378
|
+
end
|
379
|
+
|
380
|
+
++line_matches_count
|
381
|
+
new_file_lines_set += new_line
|
382
|
+
|
383
|
+
log.info(ere) { "[replace] - ------------------------------------------------------- ##" }
|
384
|
+
log.info(ere) { "[replace] - file name => #{File.basename filepath}" }
|
385
|
+
log.info(ere) { "[replace] - has words => #{pp includes}" }
|
386
|
+
log.info(ere) { "[replace] - orig line => #{file_line}" }
|
387
|
+
log.info(ere) { "[replace] - ------- --------- ------- ---------- ------ ##" }
|
388
|
+
log.info(ere) { "[replace] - outgoing line => #{file_line}" }
|
389
|
+
log.info(ere) { "[replace] - incoming line => #{new_line}" }
|
390
|
+
log.info(ere) { "[replace] - ------- --------- ------- ---------- ------ ##" }
|
391
|
+
|
392
|
+
end
|
393
|
+
|
394
|
+
end
|
395
|
+
|
396
|
+
# -- ---------------------------------------------------------- -- #
|
397
|
+
# -- [(over)write] new set of file lines to the parameter file. -- #
|
398
|
+
# -- ---------------------------------------------------------- -- #
|
399
|
+
File.write filepath, new_file_lines_set
|
400
|
+
LogObject.file filepath, "replace"
|
401
|
+
|
402
|
+
end
|
403
|
+
|
404
|
+
|
405
|
+
# --
|
406
|
+
# -- Write the 1D key/value map into a properties
|
407
|
+
# -- file at the parameter folder.
|
408
|
+
# --
|
409
|
+
# -- Parameters
|
410
|
+
# -- properties_map : the key/value map to serialize
|
411
|
+
# -- props_dir_path : folder holding new properties file
|
412
|
+
# -- props_filename : name of the new properties file
|
413
|
+
# --
|
414
|
+
# -- Dependencies and Assumptions
|
415
|
+
# -- the directory will be created if it does not exist
|
416
|
+
# -- we assume the properties file DOES NOT EXIST
|
417
|
+
# -- the map is 1D and is not nil (can be empty)
|
418
|
+
# -- the directory is writeable by the user
|
419
|
+
# --
|
420
|
+
def self.write_properties properties_map, props_dir_path, props_filename
|
421
|
+
|
422
|
+
Dir.mkdir props_dir_path unless File.exists? props_dir_path
|
423
|
+
prop_filepath = File.join props_dir_path, props_filename
|
424
|
+
File.write prop_filepath, to_properties_text(properties_map)
|
425
|
+
|
426
|
+
LogObject.file prop_filepath, "write properties"
|
427
|
+
|
428
|
+
end
|
429
|
+
|
430
|
+
|
431
|
+
# --
|
432
|
+
# -- Create txt file in the properties format containing
|
433
|
+
# -- a dictionary of name/value pairs separated by an
|
434
|
+
# -- equals sign.
|
435
|
+
# --
|
436
|
+
# -- Parameters
|
437
|
+
# -- properties_map : the key/value map to serialize
|
438
|
+
# --
|
439
|
+
# -- Dependencies and Assumptions
|
440
|
+
# -- the map is 1D and is not nil (can be empty)
|
441
|
+
# -- map keys are SYMBOLS so underscores are made dots
|
442
|
+
# --
|
443
|
+
def self.to_properties_text properties_map
|
444
|
+
|
445
|
+
hdr_1 = "## Properties file with [#{properties_map.length}] key/value pairs.\n"
|
446
|
+
hdr_u = "## @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ##\n"
|
447
|
+
|
448
|
+
property_text = hdr_u + hdr_1 + hdr_u + "\n"
|
449
|
+
properties_map.each do |key_symbol,value|
|
450
|
+
key_string = key_symbol.to_s.gsub("_", ".")
|
451
|
+
property_text += "#{key_string}=#{value}\n"
|
452
|
+
end
|
453
|
+
|
454
|
+
property_text += "\n" + hdr_u
|
455
|
+
return property_text
|
456
|
+
|
457
|
+
end
|
458
|
+
|
459
|
+
|
460
|
+
# -- ---------------------------------------------------------- -- #
|
461
|
+
# -- When the [file fact] replace [behaviour] is called against -- #
|
462
|
+
# -- a "file" it [replaces all occurrences] (as best it can) of -- #
|
463
|
+
# -- the given string within the file. Call replace occurrences -- #
|
464
|
+
# -- against a folder and it replaces in all constituent files. -- #
|
465
|
+
# -- ---------------------------------------------------------- -- #
|
466
|
+
# -- Be careful = this implementation is not that clever. So if -- #
|
467
|
+
# -- we try to replace all "Betty" occurrences - lines that may -- #
|
468
|
+
# -- contain ["BetBettyty"] will likely end up with a ["Betty"] -- #
|
469
|
+
# -- ---------------------------------------------------------- -- #
|
470
|
+
def self.factorize from_string, to_string, in_file
|
471
|
+
|
472
|
+
the_filename = File.basename in_file
|
473
|
+
|
474
|
+
log.info(ere) { "From String => #{from_string}" }
|
475
|
+
log.info(ere) { "[To] String => #{to_string}" }
|
476
|
+
log.info(ere) { "File [Name] => #{the_filename}" }
|
477
|
+
|
478
|
+
File.write( in_file, File.open( in_file, &:read ).gsub( from_string, to_string ) );
|
479
|
+
|
480
|
+
end
|
481
|
+
|
482
|
+
|
483
|
+
end
|