eco-helpers 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.rspec +3 -0
  4. data/README.md +20 -0
  5. data/eco-helpers.gemspec +34 -0
  6. data/lib/eco-helpers.rb +15 -0
  7. data/lib/eco/api.rb +13 -0
  8. data/lib/eco/api/common.rb +10 -0
  9. data/lib/eco/api/common/people.rb +17 -0
  10. data/lib/eco/api/common/people/base_parser.rb +16 -0
  11. data/lib/eco/api/common/people/default_parsers.rb +40 -0
  12. data/lib/eco/api/common/people/default_parsers/boolean_parser.rb +28 -0
  13. data/lib/eco/api/common/people/default_parsers/date_parser.rb +33 -0
  14. data/lib/eco/api/common/people/default_parsers/multi_parser.rb +33 -0
  15. data/lib/eco/api/common/people/default_parsers/numeric_parser.rb +23 -0
  16. data/lib/eco/api/common/people/default_parsers/select_parser.rb +29 -0
  17. data/lib/eco/api/common/people/entries.rb +120 -0
  18. data/lib/eco/api/common/people/person_entry.rb +380 -0
  19. data/lib/eco/api/common/people/person_factory.rb +114 -0
  20. data/lib/eco/api/common/people/person_modifier.rb +62 -0
  21. data/lib/eco/api/common/people/person_parser.rb +140 -0
  22. data/lib/eco/api/common/people/types.rb +47 -0
  23. data/lib/eco/api/common/session.rb +15 -0
  24. data/lib/eco/api/common/session/base_session.rb +46 -0
  25. data/lib/eco/api/common/session/environment.rb +47 -0
  26. data/lib/eco/api/common/session/file_manager.rb +90 -0
  27. data/lib/eco/api/common/session/logger.rb +105 -0
  28. data/lib/eco/api/common/session/mailer.rb +92 -0
  29. data/lib/eco/api/common/session/s3_uploader.rb +110 -0
  30. data/lib/eco/api/common/version_patches.rb +11 -0
  31. data/lib/eco/api/common/version_patches/external_person.rb +11 -0
  32. data/lib/eco/api/eco_faker.rb +59 -0
  33. data/lib/eco/api/organization.rb +13 -0
  34. data/lib/eco/api/organization/account.rb +23 -0
  35. data/lib/eco/api/organization/people.rb +118 -0
  36. data/lib/eco/api/organization/policy_groups.rb +51 -0
  37. data/lib/eco/api/organization/preferences.rb +28 -0
  38. data/lib/eco/api/organization/preferences_reference.json +23 -0
  39. data/lib/eco/api/organization/presets.rb +138 -0
  40. data/lib/eco/api/organization/presets_backup.rb +220 -0
  41. data/lib/eco/api/organization/presets_values.json +10 -0
  42. data/lib/eco/api/organization/tag_tree.rb +134 -0
  43. data/lib/eco/api/organization_old.rb +73 -0
  44. data/lib/eco/api/session.rb +180 -0
  45. data/lib/eco/api/session/batch.rb +132 -0
  46. data/lib/eco/api/session/batch_job.rb +152 -0
  47. data/lib/eco/api/session/batch_jobs.rb +131 -0
  48. data/lib/eco/api/session/batch_status.rb +138 -0
  49. data/lib/eco/api/session/task.rb +92 -0
  50. data/lib/eco/api/session_config.rb +179 -0
  51. data/lib/eco/api/session_config/api.rb +47 -0
  52. data/lib/eco/api/session_config/apis.rb +78 -0
  53. data/lib/eco/api/session_config/files.rb +30 -0
  54. data/lib/eco/api/session_config/logger.rb +54 -0
  55. data/lib/eco/api/session_config/mailer.rb +65 -0
  56. data/lib/eco/api/session_config/people.rb +89 -0
  57. data/lib/eco/api/session_config/s3_bucket.rb +62 -0
  58. data/lib/eco/api/session_config/use_cases.rb +30 -0
  59. data/lib/eco/api/usecases.rb +12 -0
  60. data/lib/eco/api/usecases/base_case.rb +14 -0
  61. data/lib/eco/api/usecases/case_data.rb +13 -0
  62. data/lib/eco/api/usecases/default_cases.rb +53 -0
  63. data/lib/eco/api/usecases/default_cases/change_email_case.rb +47 -0
  64. data/lib/eco/api/usecases/default_cases/create_details_case.rb +29 -0
  65. data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +49 -0
  66. data/lib/eco/api/usecases/default_cases/delete_case.rb +20 -0
  67. data/lib/eco/api/usecases/default_cases/email_as_id_case.rb +24 -0
  68. data/lib/eco/api/usecases/default_cases/hris_case.rb +67 -0
  69. data/lib/eco/api/usecases/default_cases/new_email_case.rb +26 -0
  70. data/lib/eco/api/usecases/default_cases/new_id_case.rb +26 -0
  71. data/lib/eco/api/usecases/default_cases/refresh_presets.rb +25 -0
  72. data/lib/eco/api/usecases/default_cases/reinvite_case.rb +22 -0
  73. data/lib/eco/api/usecases/default_cases/remove_account_case.rb +36 -0
  74. data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +24 -0
  75. data/lib/eco/api/usecases/default_cases/set_default_tag_case.rb +44 -0
  76. data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +39 -0
  77. data/lib/eco/api/usecases/default_cases/to_csv_case.rb +36 -0
  78. data/lib/eco/api/usecases/default_cases/update_details_case.rb +30 -0
  79. data/lib/eco/api/usecases/default_cases/upsert_account_case.rb +35 -0
  80. data/lib/eco/api/usecases/use_case.rb +177 -0
  81. data/lib/eco/api/usecases/use_group.rb +104 -0
  82. data/lib/eco/cli.rb +9 -0
  83. data/lib/eco/cli/input.rb +109 -0
  84. data/lib/eco/cli/input_multi.rb +137 -0
  85. data/lib/eco/cli/root.rb +8 -0
  86. data/lib/eco/cli/session.rb +9 -0
  87. data/lib/eco/cli/session/batch.rb +9 -0
  88. data/lib/eco/common.rb +7 -0
  89. data/lib/eco/common/base_cli.rb +116 -0
  90. data/lib/eco/common/language.rb +9 -0
  91. data/lib/eco/data.rb +9 -0
  92. data/lib/eco/data/crypto.rb +7 -0
  93. data/lib/eco/data/crypto/encryption.rb +318 -0
  94. data/lib/eco/data/files.rb +10 -0
  95. data/lib/eco/data/files/directory.rb +93 -0
  96. data/lib/eco/data/files/file_pattern.rb +32 -0
  97. data/lib/eco/data/files/helpers.rb +90 -0
  98. data/lib/eco/data/mapper.rb +54 -0
  99. data/lib/eco/data/random.rb +10 -0
  100. data/lib/eco/data/random/distribution.rb +133 -0
  101. data/lib/eco/data/random/fake.rb +320 -0
  102. data/lib/eco/data/random/values.rb +80 -0
  103. data/lib/eco/language.rb +12 -0
  104. data/lib/eco/language/curry.rb +28 -0
  105. data/lib/eco/language/hash_transform.rb +68 -0
  106. data/lib/eco/language/hash_transform_modifier.rb +114 -0
  107. data/lib/eco/language/match.rb +30 -0
  108. data/lib/eco/language/match_modifier.rb +190 -0
  109. data/lib/eco/language/models.rb +11 -0
  110. data/lib/eco/language/models/attribute_parser.rb +38 -0
  111. data/lib/eco/language/models/collection.rb +181 -0
  112. data/lib/eco/language/models/modifier.rb +68 -0
  113. data/lib/eco/language/models/wrap.rb +114 -0
  114. data/lib/eco/language/values_at.rb +159 -0
  115. data/lib/eco/lexic/dictionary.rb +33 -0
  116. data/lib/eco/lexic/dictionary/dictionary.txt +355484 -0
  117. data/lib/eco/lexic/dictionary/tags.json +38 -0
  118. data/lib/eco/scripting.rb +30 -0
  119. data/lib/eco/scripting/README.md +11 -0
  120. data/lib/eco/scripting/arguments.rb +40 -0
  121. data/lib/eco/tester.rb +97 -0
  122. data/lib/eco/version.rb +3 -0
  123. metadata +325 -0
@@ -0,0 +1,9 @@
1
+ module Eco
2
+ module Common
3
+ class Language
4
+ include Eco::Language
5
+ end
6
+ end
7
+ end
8
+
9
+ Handy = Eco::Common::Language.new
data/lib/eco/data.rb ADDED
@@ -0,0 +1,9 @@
1
+ module Eco
2
+ module Data
3
+ end
4
+ end
5
+
6
+ require_relative 'data/crypto'
7
+ require_relative 'data/files'
8
+ require_relative 'data/random'
9
+ require_relative 'data/mapper'
@@ -0,0 +1,7 @@
1
+ module Eco
2
+ module Data
3
+ module Crypto
4
+ end
5
+ end
6
+ end
7
+ require_relative 'crypto/encryption'
@@ -0,0 +1,318 @@
1
+ require 'openssl'
2
+ require 'json'
3
+ require 'base64'
4
+ require 'pp'
5
+
6
+ require_relative '../../scripting'
7
+
8
+ # see some ramblings here: http://distributed-frostbite.blogspot.com/2010/06/file-encryption-in-ruby-with-openssl.html
9
+
10
+ def run! # this will run only if called from command line (not when require'd nor load'd)
11
+ include Eco::Scripting
12
+ include Eco::Data::Crypto
13
+ # script arguments
14
+ keygen = get_arg("-keygen")
15
+ filename = get_arg("-keygen", with_param: true)
16
+ ssh = get_arg("-ssh")
17
+ length = get_arg("-length", with_param: true)
18
+ check_rsa_pairs = get_arg("-keypairs")
19
+ key_filename = get_arg("-keypairs", with_param: true)
20
+
21
+ # methods
22
+ case true
23
+ when keygen
24
+ puts "++ keygen RSA ++"
25
+ #pp ::OpenSSL.constants.sort
26
+ cr = Eco::Data::Crypto::OpenSSL.new
27
+ case true
28
+ when ssh
29
+ puts "think about installing this library: https://rubygems.org/gems/sshkey"
30
+ puts "GitHub: https://github.com/bensie/sshkey"
31
+ puts "or add this Ruby solution to convert to ssh-rsa: https://stackoverflow.com/a/3162593/4352306"
32
+ exit(1)
33
+ cr.rsa_keygen_ssh(filename: filename)
34
+ else
35
+ cr.rsa_keygen(filename: filename)
36
+ end
37
+ when check_rsa_pairs
38
+ puts "++ checking file pairs ++"
39
+ begin
40
+ key_filename = "rsa" if !key_filename
41
+ priv = File.read(key_filename + '.pem')
42
+ pub = File.read(key_filename + '.pub')
43
+ rescue
44
+ puts "could not find files with basename: #{key_filename}"
45
+ exit(1)
46
+ end
47
+ cr = Eco::Data::Crypto::OpenSSL.new
48
+ equals = cr.rsa_keypairs?(priv, pub)
49
+ if equals
50
+ puts "the pair #{key_filename} seem to be for one to another!"
51
+ else
52
+ puts "those files with base name #{key_filename} are not a rsa pair"
53
+ end
54
+ end
55
+ end
56
+
57
+
58
+ module Eco
59
+ module Data
60
+ #TODO study how to encrypt uniquely the api key in the configuration file
61
+ #TODO study how RSA could boost team-shared Drive folder (updates, and people files should be encrypted via public key)
62
+ module Crypto
63
+ # file conf definitions
64
+ THIS_FILENAME = __FILE__
65
+ MY_NAME = File.basename(THIS_FILENAME, File.extname(THIS_FILENAME)) # ".rb"
66
+ PATH = File.dirname(THIS_FILENAME)
67
+ WORKING_DIR = PATH + "/" + MY_NAME
68
+ PARSER_FILE = WORKING_DIR + "/json_parser.json" # .dll
69
+
70
+ class OpenSSL
71
+ DEFAULT_KEY_LENGTH = 256
72
+ DEFAULT_RSA_LENGTH = 2048
73
+ SALT_LENGTH = 128
74
+ SALT_SEED = "$%!@_halt9000"
75
+ BLOCK_OCTETS = 512
76
+ attr_accessor :salt_seed
77
+ attr_reader :digest, :pkcs5, :kdf, :cipher, :rsa
78
+ attr_reader :salt
79
+ def initialize(init = {})
80
+ @digest = ::OpenSSL::Digest
81
+ @pkcs5 = ::OpenSSL::PKCS5
82
+ #@kdf = ::OpenSSL::KDF
83
+ @cipher = ::OpenSSL::Cipher
84
+ self.salt_seed = SALT_SEED
85
+ @rsa = ::OpenSSL::PKey::RSA
86
+ end
87
+ def salt_seed=(value)
88
+ @salt_seed = value
89
+ @salt = self.pbkdf2(@salt_seed, salt: @salt_seed, length: SALT_LENGTH)
90
+ end
91
+ def sha256 (str = nil)
92
+ sha = @digest.SHA256.new
93
+ digest = sha.digest(str) unless !str
94
+ sha.reset
95
+ digest
96
+ end
97
+ def sha512 (str = nil)
98
+ sha = @digest.SHA512.new
99
+ digest = sha.digest(str) unless !str
100
+ sha.reset
101
+ digest
102
+ end
103
+ # default hmac hash to "sha256" -> https://github.com/hueniverse/iron/issues/55
104
+ def pbkdf2 (pass, salt: @salt || "salt", iterations: 1000, length: DEFAULT_KEY_LENGTH, hash: "sha256")
105
+ octets = length.div(8)
106
+ #puts "this has been called"
107
+ #puts "pass: #{pass}"
108
+ #puts "salt: #{salt}"
109
+ #puts "iterations: #{iterations}"
110
+ #puts "length: #{length}"
111
+ #puts "hash: #{hash}"
112
+ @pkcs5.pbkdf2_hmac(pass, salt, iterations, octets, hash)
113
+ end
114
+ def pbkdf2_sha1 (pass, salt: @salt, iterations: 1000, length: DEFAULT_KEY_LENGTH)
115
+ #self.pbkdf2(pass, salt: salt, iterations: iternations, length: length, hash: "sha1")
116
+ @pkcs5.pbkdf2_hmac(pass, salt, iterations, octets, "sha1")
117
+ end
118
+ =begin
119
+ def scrypt (pass, salt: @salt, cost: 14, length: DEFAULT_KEY_LENGTH)
120
+ block_size = 8
121
+ parallelization = 1
122
+ octets = length.div(8)
123
+ @kdf.scrypt(pass, salt: salt, N: 2**cost, r: block_size, p: parallelization, length: octets)
124
+ end
125
+ =end
126
+ def aes256_pass(pass)
127
+ self.pbkdf2(pass, length: 256)
128
+ end
129
+ def aes256_encrypt(data, key: nil, iv: nil, block_octets: BLOCK_OCTETS)
130
+ block_bits = block_bits * 8
131
+ cipher = @cipher.new('aes-256-cbc')
132
+ cipher.encrypt
133
+
134
+ if key ; cipher.key = key
135
+ else ; key = cipher.random_key
136
+ end
137
+ if iv ; cipher.iv = iv
138
+ else ; iv = cipher.random_iv
139
+ end
140
+
141
+ str_c = ""
142
+ while str.length > 0
143
+ str_c += cipher.update(str.slice!(0, block_bits))
144
+ end
145
+ str_c += cipher.final
146
+ return str_c
147
+ #EncryptedData.new({content: str_c, key: key, iv: iv})
148
+ end
149
+ def aes256_decrypt(data, key: , iv: , block_octets: BLOCK_OCTETS)
150
+ block_bits = block_bits * 8
151
+ #validation = encrypted_data && encrypted_data.key && encrypted_data.iv
152
+ # return nil unless validation
153
+ cipher = @cipher.new('aes-256-cbc')
154
+ cipher.decrypt
155
+ cipher.key = key
156
+ cipher.iv = iv
157
+ #cipher.key = encrypted_data.key
158
+ #cipher.iv = encrypted_data.iv
159
+ #str_c = encrypted_data.content
160
+ str_c = data
161
+ str = ""
162
+ while str_c.length > 0
163
+ str += cipher.update(str_c.slice!(0, block_bits))
164
+ #puts str[-50..-1] || str
165
+ end
166
+ str += cipher.final
167
+ return str
168
+ end
169
+ def rsa_keygen(length = DEFAULT_RSA_LENGTH, filename: "rsa")
170
+ filename = "rsa" if !filename
171
+ key = @rsa.new(length)
172
+ File.open('./' + filename + '.pem',"w") {|fd| fd << key.to_pem }
173
+ File.open('./' + filename + '.pub',"w") {|fd| fd << key.public_key.to_pem }
174
+ end
175
+ def rsa_keygen_ssh(length = DEFAULT_RSA_LENGTH, filename: "rsa")
176
+ # to do conersion pem to ssh-rsa: https://stackoverflow.com/a/3162593/4352306
177
+ # conversion explained here: http://blog.oddbit.com/2011/05/08/converting-openssh-public-keys/
178
+ # much simpler developed in php here: https://stackoverflow.com/a/5524323/4352306
179
+ filename = "rsa" if !filename
180
+ key = @rsa.new(length)
181
+ File.open('./' + filename + '.der',"w") {|fd| fd << key.ssh_type }
182
+ File.open('./' + filename + '.pub',"w") {|fd| fd << key.public_key.ssh_type }
183
+ end
184
+ def rsa_keypairs?(private_key, public_key)
185
+ str_original = "See, my mule don’t like people laughing"
186
+
187
+ pub_key = @rsa.new(public_key)
188
+ str_original.force_encoding(Encoding::UTF_8)
189
+ encrypted_data = Base64.encode64(pub_key.public_encrypt(str_original))
190
+
191
+ priv_key = @rsa.new(private_key)
192
+ begin # see here: https://stackoverflow.com/a/13251160/4352306 (padding error when false pub key)
193
+ decrypted_data = priv_key.private_decrypt(Base64.decode64(encrypted_data))
194
+ # OpenSSL core Ruby library is written in C which uses different encoding (ASCII-8BIT)
195
+ # that's why we force UTF-8 encoding (before and after encryption)
196
+ # see this answer: https://stackoverflow.com/a/27326915/4352306
197
+ decrypted_data.force_encoding(Encoding::UTF_8)
198
+ rescue
199
+ return false
200
+ end
201
+
202
+ puts "encrypted string: #{str_original}"
203
+ puts "decrypted string: #{decrypted_data}"
204
+ return (decrypted_data == str_original)
205
+ end
206
+ end
207
+
208
+
209
+ class EncryptedData
210
+ attr_reader :key, :iv, :content
211
+ def initialize(init = {})
212
+ @key = init[:key]
213
+ @iv = init[:iv]
214
+ @content = init[:content]
215
+ @sha = sha256(@content)
216
+ load() if !@key || !@iv
217
+ end
218
+ def load (file = nil)
219
+ parser = get_parser(file)
220
+ sha64 = Base64.encode64(@sha) if @sha
221
+ if parser.key?(sha64)
222
+ #puts "found key!"
223
+ meta = parser[sha64]
224
+ key64, iv64 = meta.values_at("key", "iv")
225
+ @key = Base64.decode64(key64) if key64
226
+ @iv = Base64.decode64(iv64) if iv64
227
+ else
228
+ #puts "key not found! #{sha64}"
229
+ end
230
+ end
231
+ def save (file = nil)
232
+ parser = get_parser(file)
233
+ sha64 = Base64.encode64(@sha) if @sha
234
+ #puts "save key: #{sha64}"
235
+ if parser.key?(sha64)
236
+ meta = parser[sha64]
237
+ else
238
+ meta = {key: nil, iv: nil}
239
+ parser[sha64] = meta
240
+ end
241
+ meta[:key] = Base64.encode64(@key) if @key
242
+ meta[:iv] = Base64.encode64(@iv) if @iv
243
+ set_parser(file, parser)
244
+ end
245
+
246
+ private
247
+ def get_parser (file = nil)
248
+ file = PARSER_FILE if !file
249
+ # create the directory unless it exists
250
+ Dir.mkdir(WORKING_DIR) unless Dir.exist?(WORKING_DIR)
251
+ parser = {}
252
+ if File.file?(file)
253
+ fd = File.open(file,"r")
254
+ parser = JSON.load(fd)
255
+ fd.close
256
+ end
257
+ return parser
258
+ end
259
+ def set_parser (file = nil, parser = {})
260
+ file = PARSER_FILE if !file
261
+ # create the directory unless it exists
262
+ Dir.mkdir(WORKING_DIR) unless Dir.exist?(WORKING_DIR)
263
+ fd = File.open(file,"w")
264
+ fd << parser.to_json
265
+ fd.close
266
+ end
267
+ def sha256 (str = nil)
268
+ sha = OpenSSL::Digest::SHA256.new
269
+ digest = sha.digest(str) unless !str
270
+ sha.reset
271
+ digest
272
+ end
273
+ end
274
+
275
+ def self.encrypt (str)
276
+ cipher = OpenSSL::Cipher.new('aes-256-cbc')
277
+ cipher.encrypt
278
+ key = cipher.random_key
279
+ iv = cipher.random_iv
280
+
281
+ str_c = ""
282
+ while str.length > 0
283
+ str_c += cipher.update(str.slice!(0, 4096))
284
+ end
285
+ str_c += cipher.final
286
+ EncryptedData.new({content: str_c, key: key, iv: iv})
287
+ end
288
+
289
+ def self.decrypt (encrypted_data)
290
+ unless encrypted_data && encrypted_data.key && encrypted_data.iv
291
+ return nil
292
+ end
293
+ cipher = OpenSSL::Cipher.new('aes-256-cbc')
294
+ cipher.decrypt
295
+ cipher.key = encrypted_data.key
296
+ cipher.iv = encrypted_data.iv
297
+ str_c = encrypted_data.content
298
+ str = ""
299
+ while str_c.length > 0
300
+ str += cipher.update(str_c.slice!(0, 4096))
301
+ #puts str[-50..-1] || str
302
+ end
303
+ str += cipher.final
304
+ return str
305
+ end
306
+
307
+ end
308
+ =begin
309
+ class Includer
310
+ include Crypto
311
+ end
312
+ CRYPTO = Includer.new
313
+ =end
314
+ end
315
+ end
316
+
317
+
318
+ run! if __FILE__==$0
@@ -0,0 +1,10 @@
1
+ module Eco
2
+ module Data
3
+ module Files
4
+ end
5
+ end
6
+ end
7
+
8
+ require_relative 'files/helpers'
9
+ require_relative 'files/file_pattern'
10
+ require_relative 'files/directory'
@@ -0,0 +1,93 @@
1
+ #require 'fileutils'
2
+
3
+ module Eco
4
+ module Data
5
+ module Files
6
+ class Directory
7
+
8
+ attr_reader :dir_path
9
+
10
+ def initialize(dir_path = Dir.pwd)
11
+ dir_path = script_subfolder if dir_path == :script
12
+ raise "Cannot initialize with directory: '#{dir_path.to_s}'" if !dir_path || dir_path.is_a?(Symbol)
13
+ @dir_path = dir_path
14
+ end
15
+
16
+ def exists?
17
+ Files.dir_exists(@dir_path)
18
+ end
19
+
20
+ def create
21
+ succeed = Directory.create(File.expand_path(@dir_path)) unless self.exists?
22
+ self.full_path if succeed
23
+ end
24
+
25
+ def full_path
26
+ File.expand_path(@dir_path)
27
+ end
28
+
29
+ def dir_files(file: nil, file_pattern: dir_pattern)
30
+ find = !!file ? file_pattern(file) : dir_pattern
31
+ Dir.glob(find)
32
+ end
33
+
34
+ def newest_file(files_list = nil, file: nil)
35
+ files_list = files_list || dir_files(file: file)
36
+ return nil unless files_list && files_list.is_a?(Array) && (files_list.length > 0) # files available?
37
+ files_list.max_by {|f| File.mtime(f) }
38
+ end
39
+
40
+ def file(filename, should_exist: false)
41
+ return nil if !filename
42
+ if File.expand_path(filename) == filename
43
+ return filename if !should_exist || Files.file_exists?(filename)
44
+ end
45
+
46
+ file = FilePattern.new(filename).resolve(dir: @dir_path)
47
+ return file if !should_exist || Files.file_exists?(file)
48
+
49
+ file = File.expand_path(filename)
50
+ return file if !should_exist || Files.file_exists?(file)
51
+
52
+ nil
53
+ end
54
+
55
+ def join(*args)
56
+ args.unshift(@dir_path)
57
+ File.join(*args)
58
+ end
59
+
60
+ def self.create(path, includes_file: false)
61
+ return true if Files.file_exists?(path)
62
+ parts = Files.split(File.expand_path(path))
63
+ filename = parts.pop if includes_file
64
+ return true if Files.dir_exists?(File.join(*parts))
65
+ subpath = nil
66
+ begin
67
+ parts.each do |curr|
68
+ subpath = subpath ? File.join(subpath, curr) : curr
69
+ Dir.mkdir(subpath) unless Files.dir_exists?(subpath)
70
+ end
71
+ rescue Exception => e
72
+ pp e
73
+ end
74
+ false
75
+ end
76
+
77
+ private
78
+
79
+ def file_pattern(filename)
80
+ Files::FilePattern.new(filename).pattern(@dir_path)
81
+ end
82
+
83
+ def dir_pattern
84
+ Files::FilePattern.new.pattern(@dir_path)
85
+ end
86
+
87
+ def script_subfolder
88
+ Files.script_subfolder
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end