rubyment 0.7.25752540 → 0.7.25761093

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 (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rubyment.rb +637 -24
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d6fbbb8b232ca1a58d1440b3310dc2a87a5c6f30
4
- data.tar.gz: 459ab366a552afb2fe23f31ecb2e8030842d0002
3
+ metadata.gz: 84fd074da46f8f1ef6ed16cac3d8585c66167edf
4
+ data.tar.gz: 631c77f863b75a6243f83ca966fa192d03577878
5
5
  SHA512:
6
- metadata.gz: f8f6bb176e2bed86d86faa13f7c66755fef1adc4c7b64fc95a854d80b93a2697678289b9126f15b76fab6d762225cb7546b8fd3da1a55d7b57b97eba4ec7f93d
7
- data.tar.gz: 8d2795d66b35b4c1f6670d1aedb69dda3ae65757c39f029f03bb7f372d0b72568a03e4040ca8ddda68eed11f55d545bd9a4edefe85383b72038c1807c8f6efda
6
+ metadata.gz: 4310b2d48cca557ead98af608cddcfa1d180b871040855fc19629752e2934d5fc00c4b75044dfff261447b02b24e4fb75e00bd71cb4011e009373324af68a608
7
+ data.tar.gz: beca4169679bf3924ed30f874519ea6d7b40f8546c627ccfbcbd7d0ff16a1f51e049f3a4a2351b0f3fa424c56a5a58f74a340f63a20ff5c58dee1a80944863d1
@@ -92,7 +92,49 @@ class Object
92
92
  end
93
93
 
94
94
 
95
- end
95
+ =begin
96
+ Turns any Ruby object into a composite.
97
+
98
+ Examples:
99
+
100
+ 1.as_container(:components_only).entries
101
+ # => []
102
+
103
+ 1.as_container.entries
104
+ # => [1]
105
+
106
+ "hello".as_container.entries
107
+ # => ["hello"]
108
+
109
+ [1, 2, 3].as_container().entries
110
+ # => [1, 2, 3]
111
+
112
+ [1, 2, 3].as_container(:components_only).entries
113
+ # => [1, 2, 3]
114
+
115
+ # Take the first element of the operation on the object a:
116
+ # a.as_container.entries - a.as_container(:only_components).entries
117
+ # to find what's the non composite component of a:
118
+
119
+ a = [ 1, 2, 3 ] ; a.as_container.entries - a.as_container(:only_components).entries
120
+ # => []
121
+
122
+ a = "str" ; a.as_container.entries - a.as_container(:only_components).entries
123
+ # => ["str"]
124
+
125
+ =end
126
+ def as_container components_only=nil, method_name=:map
127
+ self.respond_to?(method_name) && (
128
+ self.send method_name
129
+ ) || (!components_only) && (
130
+ [self].send method_name
131
+ ) || (
132
+ [].send method_name
133
+ )
134
+ end
135
+
136
+
137
+ end # of class Object
96
138
 
97
139
 
98
140
  =begin
@@ -903,9 +945,10 @@ module RubymentInternalModule
903
945
  However, it's not sequencial, and therefore not
904
946
  used for versioning.
905
947
  =end
906
- def rubyment_file_sha256
948
+ def rubyment_file_sha256 file=nil
907
949
  require 'openssl'
908
- (Digest::SHA256.hexdigest File.read __FILE__)
950
+ file = containerize(file).first.nne __FILE__
951
+ (Digest::SHA256.hexdigest File.read file)
909
952
  end
910
953
 
911
954
 
@@ -948,6 +991,89 @@ module RubymentInternalModule
948
991
  end # of RubymentInternalModule
949
992
 
950
993
 
994
+ =begin
995
+ # begin_documentation
996
+
997
+ This module offers generic functions to help
998
+ achieving certain programming patterns.
999
+
1000
+ # end_documentation
1001
+ =end
1002
+ module RubymentPatternsModule
1003
+
1004
+
1005
+ =begin
1006
+ Turns any_object into a composite, and
1007
+ returns it in an array with its two parts:
1008
+ the leaf, and its children (another
1009
+ container)
1010
+
1011
+ Note that if an object can be decomposed
1012
+ by duck_type_method (:map) by default,
1013
+ it stays in the leaf, otherwise it is
1014
+ components are returned in the children.
1015
+ So expect always a nil for the leaf or
1016
+ [] for children components.
1017
+
1018
+ Decompose an object is useful, for example,
1019
+ to write a recursive function in functional
1020
+ style. Normally a recursive function will
1021
+ require a test to check if it is the base
1022
+ (leaf) case, otherwise will iterate through
1023
+ children and call recursively the function.
1024
+ With this, no test is needed. Since the "map"
1025
+ call is not defined for every object, it won't
1026
+ go infinite. Also, it won't throw an exception,
1027
+ because the children is a container (empty,
1028
+ when the leaf is defined):
1029
+
1030
+ def rec leaf_or_children
1031
+ l, c = object__decompose leaf_or_children
1032
+ c.map { |children| rec leaf_or_children }
1033
+ do_something_with_leaf l # must be already in
1034
+ # a functional/fault
1035
+ # tolerant style
1036
+ end
1037
+
1038
+ Examples:
1039
+
1040
+ l, c = object__decompose [ "a", "b", "c"]
1041
+ # => [nil, ["a", "b", "c"]]
1042
+
1043
+ l, c = object__decompose "string"
1044
+ # => ["string", []]
1045
+
1046
+ l, c = object__decompose ["a", "b", "c"], :bytes
1047
+ # => [["a", "b", "c"], []]
1048
+
1049
+ l, c = object__decompose "string", :bytes
1050
+ # => [nil, [115, 116, 114, 105, 110, 103]]
1051
+
1052
+
1053
+ =end
1054
+ def object__decompose any_object, duck_type_method=:map
1055
+
1056
+ children = bled {
1057
+ any_object.as_container(:only_components, duck_type_method).entries
1058
+ }.first.call.first || []
1059
+
1060
+ leaf = bled([any_object]) {
1061
+ (
1062
+ any_object.as_container(nil, duck_type_method).entries -
1063
+ children
1064
+ ).first
1065
+ }.first.call.first
1066
+
1067
+ [
1068
+ leaf,
1069
+ children,
1070
+ ]
1071
+ end
1072
+
1073
+
1074
+ end # of RubymentPatternsModule
1075
+
1076
+
951
1077
  =begin
952
1078
  # begin_documentation
953
1079
 
@@ -1070,9 +1196,271 @@ module RubymentInvocationModule
1070
1196
  end
1071
1197
 
1072
1198
 
1199
+ =begin
1200
+ Just a convenience for typing less. Calls
1201
+ the block inside a bled, which is a function
1202
+ which captures and returns exceptions and
1203
+ runtime errors in a functional way, instead
1204
+ of Ruby's way.
1205
+
1206
+ Examples:
1207
+
1208
+ bled_call {:return_value }
1209
+ # => [:return_value, nil, nil]
1210
+
1211
+ bled_call { UndefinedStuff }
1212
+ # => [nil,
1213
+ # ...
1214
+ # nil],
1215
+ # NameError],
1216
+ # #<NameError: uninitialized constant #<Class:#<Rubyment:0x000000035adcc0>>::UndefinedStuff>]
1217
+
1218
+
1219
+ bled_call [:return_value_on_error] { UndefinedStuff }
1220
+ # => [:return_value_on_error,
1221
+ # [nil,
1222
+ # "message{\nuninitialized constant #<Class:#<Rubyment:0x0000000308e078>>::UndefinedStuff\
1223
+
1224
+ =end
1225
+ def bled_call *args, &block
1226
+ b = bled *args, &block
1227
+ b.first.call
1228
+ end
1229
+
1230
+
1231
+ =begin
1232
+ Generates a string that can be given to system (or any other
1233
+ command line executor) to execute a binary in memory (Ie,
1234
+ a file is generated having as contents a given string).
1235
+ If not file path is given a default one in /tmp will be
1236
+ generated (using the digest sha256 of the file (truncated
1237
+ at 96 chars, by now).
1238
+ Arguments can be given in an array (they will be escaped
1239
+ with Shellwords.join) or String (no escape apply)
1240
+
1241
+ Examples:
1242
+
1243
+ # write the contents of /bin/ls to a temporary file and offers
1244
+ # a command to execute it:
1245
+ system_command__exec_via_file [ [nil, File.read("/bin/ls") ] , ["-l", "-h"] ]
1246
+ # => "/tmp/rubyment.file.a90ba058c747458330ba26b5e2a744f4fc57f92f9d0c9112b1cb2f76c66c4ba0 -l -h"
1247
+
1248
+ system_command__exec_via_file [ ["/tmp/my_ls", File.read("/bin/ls") ] , ["-l", "-h"] ]
1249
+ # => "/tmp/my_ls -l -h"
1250
+
1251
+ system_command__exec_via_file [ ["/tmp/my_ls", File.read("/bin/ls") ] , "-l -h" ]
1252
+ # => "/tmp/my_ls -l -h"
1253
+
1254
+
1255
+ =end
1256
+ def system_command__exec_via_file exec_via_file
1257
+ args = exec_via_file
1258
+
1259
+ binary_or_script_blob,
1260
+ args_to_binary_or_blob,
1261
+ reserved = containerize(args)
1262
+
1263
+ file_path_src,
1264
+ string_src,
1265
+ reserved = containerize(binary_or_script_blob)
1266
+
1267
+ require 'openssl'
1268
+ string_src_sha256 = string_truncate [
1269
+ Digest::SHA256.hexdigest(string_src.to_s),
1270
+ 96,
1271
+ ]
1272
+ default_path_for_string_src = "/tmp/rubyment.file.#{string_src_sha256}"
1273
+
1274
+ actual_file_path,
1275
+ old_contents,
1276
+ reserved = file_string__experimental [
1277
+ file_path_src.nne(default_path_for_string_src),
1278
+ string_src,
1279
+ ]
1280
+
1281
+ bled_call {
1282
+ require 'fileutils'
1283
+ FileUtils.chmod "+x", actual_file_path
1284
+ }
1285
+ require "shellwords"
1286
+ escaped_args_as_str = (
1287
+ bled_call [ args_to_binary_or_blob ] {
1288
+ Shellwords.join args_to_binary_or_blob
1289
+ }
1290
+ ).first.to_s
1291
+ string__recursive_join [
1292
+ " ",
1293
+ actual_file_path,
1294
+ escaped_args_as_str,
1295
+ ]
1296
+ end # of system_command__exec_via_file
1297
+
1298
+
1299
+ =begin
1300
+ "Rubyfy" a system's executable binary string/blob/memory chunk.
1301
+ Ruby gems won't distribute binaries other than Ruby executables
1302
+ (no whims, it is just their mechanisms of handling binaries with
1303
+ multiple versions in the system, they solved only for Ruby case).
1304
+
1305
+ With this function, a binary string can be given (in a file_string
1306
+ definition/structure; ie as second element), and a ruby code
1307
+ (which normally relies on Rubyment) will be generated to wrap
1308
+ that binary in a ruby code. A temporary file (not for the ruby
1309
+ code, but for storing the binary memory chunk/string is by
1310
+ default generated at /tmp/ dir; however it can set if given
1311
+ as the first element of that file_string.
1312
+
1313
+ Examples:
1314
+
1315
+ ruby_code__from_binary [nil, File.read("/bin/ls") ] # long output
1316
+ # => "#!/usr/bin/env ruby\n# Autogenerated on 2018.12.21_16:45:11\nrequire 'base64'\nblob_base64 = \"f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAoElAAAAAAABAAAAAAAAAADjnAQAA\\nAAAAAAAAAEAAOAAJAEAAHQAcAAYAAAA
1317
+
1318
+ # this version is good for self development: include this current .rb file, which contains function not yet in the gem package:
1319
+ ruby_code__from_binary [nil, File.read("/bin/ls") ], [ nil, :include_this_file ] # long output
1320
+ # => "#!/usr/bin/env ruby\n# Autogenerated on 2018.12.21_16:45:11\nrequire 'base64'\nblob_base64 = \"f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAoElAAAAAAABAAAAAAAAAADjnAQAA\\nAAAAAAAAAEAAOAAJAEAAHQAcAAYAAAA
1321
+
1322
+ ruby_code__from_binary ["/tmp/temporary_ls", File.read("/bin/ls") ] # long output
1323
+ # => "#!/usr/bin/env ruby\n# Autogenerated on 2018.12.21_16:50:37\nrequire \"rubyment\"\nrequire 'base64'\nblob_base64 =
1324
+
1325
+ system_command__exec_via_file [ [ nil, (ruby_code__from_binary [nil, File.read("/bin/ls") ]) ] ]
1326
+ # => "/tmp/rubyment.file.1e7f29e90deb6ba33b3e2e21540c77c56fca5995bb88141b572481f322290cad"
1327
+
1328
+ # this version is good for self development: include this current .rb file, which contains function not yet in the gem package:
1329
+ system_command__exec_via_file [ [ nil, (ruby_code__from_binary [nil, File.read("/bin/ls") ], [ nil, :include_this_file ]) ] ]
1330
+
1331
+ # or even:
1332
+ # this version is good for self development: include this current .rb file
1333
+ system_command__exec_via_file [ [ nil, (ruby_code__from_binary [nil, File.read("/bin/ls") ], [ nil, :include_this_file ]) ] , "-l" ]
1334
+
1335
+
1336
+ =end
1337
+ def ruby_code__from_binary binary_or_script_blob, requirements=nil
1338
+ require 'base64'
1339
+ temporary_file_path,
1340
+ blob_string = containerize(binary_or_script_blob)
1341
+ blob_base64 = Base64.encode64 blob_string
1342
+
1343
+ required_gems,
1344
+ load_current,
1345
+ object_creator,
1346
+ memory_exec_function,
1347
+ reserved = containerize(requirements)
1348
+
1349
+ memory_exec_function = memory_exec_function.nne(
1350
+ "system_command__exec_via_file"
1351
+ )
1352
+
1353
+ object_creator = object_creator.nne(
1354
+ "#{self.class}.new"
1355
+ )
1356
+
1357
+ memory_exec_function_call = string__recursive_join [
1358
+ ".",
1359
+ object_creator,
1360
+ memory_exec_function,
1361
+ ]
1362
+
1363
+
1364
+ required_gem,
1365
+ *only_one_currently_supported,
1366
+ reserved = containerize(required_gem)
1367
+
1368
+ required_gem = required_gem.nne "rubyment"
1369
+ load_current &&= "load #{__FILE__.inspect}"
1370
+
1371
+ code =<<-ENDHEREDOC
1372
+ #!/usr/bin/env ruby
1373
+ # Autogenerated on #{time__now_strftime_default}
1374
+ require #{required_gem.inspect}
1375
+ #{load_current}
1376
+ require 'base64'
1377
+ blob_base64 = #{blob_base64.inspect}
1378
+ system #{memory_exec_function_call} [
1379
+ [
1380
+ #{temporary_file_path.inspect},
1381
+ Base64.decode64(blob_base64),
1382
+ ],
1383
+ ARGV,
1384
+ ]
1385
+ ENDHEREDOC
1386
+ end # of ruby_code__from_binary
1387
+
1388
+
1073
1389
  end # of RubymentInvocationModule
1074
1390
 
1075
1391
 
1392
+ =begin
1393
+ # begin_documentation
1394
+
1395
+ This module offers functions to generate or
1396
+ deploy gem packages.
1397
+
1398
+ As of now, there are many similar functions
1399
+ directly coded in RubymentModule; they will
1400
+ be moved here upon proper maintenance/cleanup
1401
+
1402
+ # end_documentation
1403
+ =end
1404
+ module RubymentGemGenerationModule
1405
+
1406
+
1407
+ =begin
1408
+ Gem files by default can distribute only Ruby files.
1409
+ This function implements the work needed to convert
1410
+ and automatize the generation of ruby executables out
1411
+ of non ruby binaries
1412
+ =end
1413
+ def gem_deploy__non_ruby_binaries args
1414
+ gem_name,
1415
+ gem_non_ruby_executables,
1416
+ gem_executables, # same as gem_bin_executables
1417
+ reserved = args
1418
+
1419
+ new_executables = gem_non_ruby_executables.map { |gem_non_ruby_executable|
1420
+
1421
+ new_gem_executable = string__recursive_join [
1422
+ "/",
1423
+ "bin",
1424
+ File.basename(gem_non_ruby_executable),
1425
+ ]
1426
+
1427
+ new_gem_executable_contents = ruby_code__from_binary(
1428
+ [
1429
+ nil,
1430
+ File.read(gem_non_ruby_executable),
1431
+ ],
1432
+ [
1433
+ gem_name,
1434
+ ],
1435
+ )
1436
+
1437
+ # write file
1438
+ file_string__experimental [
1439
+ new_gem_executable,
1440
+ new_gem_executable_contents,
1441
+ ]
1442
+
1443
+ bled_call {
1444
+ require 'fileutils'
1445
+ FileUtils.chmod "+x", new_gem_executable
1446
+ }
1447
+
1448
+ File.basename(new_gem_executable)
1449
+
1450
+ } # of gem_non_ruby_executables.map
1451
+
1452
+ gem_executables = gem_executables.nne([]).concat new_executables
1453
+
1454
+ [
1455
+ gem_executables,
1456
+ ]
1457
+
1458
+ end # of gem_deploy_non_ruby_binaries
1459
+
1460
+
1461
+ end # of RubymentGemGenerationModule
1462
+
1463
+
1076
1464
  =begin
1077
1465
  # begin_documentation
1078
1466
  This module receives functions that are being worked on.
@@ -2915,6 +3303,166 @@ trying to get the interface compatible with
2915
3303
  end
2916
3304
 
2917
3305
 
3306
+ =begin
3307
+ Takes a file_string definition as input and output
3308
+ a new one.
3309
+
3310
+ A file_string definition is an image of a file on
3311
+ a string. Each time this function is called, the
3312
+ image is written to the disk (if set), and the previous
3313
+ file_contents is loaded into the string.
3314
+
3315
+ The first element of file_string is a file_path, existing
3316
+ or not.
3317
+
3318
+ the returned file_string has the same first element, and
3319
+ the second is either:
3320
+ . unexisting file_path
3321
+ . a string having the file path contents, in the case it is a file_path
3322
+ . a list of file_strings, one per each file inside a directory, in
3323
+ the case file_path is a directory.
3324
+
3325
+ This function, after generating the file_string to be returned,
3326
+ will write file_path accordingly to the second parameter. If :
3327
+ . a string: will write the string to the file_path (if file_path
3328
+ is not a directory, otherwise does nothing).
3329
+ . a list of file_strings / nil: will call recursively this function
3330
+ for each of the file_string inside, and will create file_path as
3331
+ directory (if still does not exist).
3332
+
3333
+ There is yet a third element in a file_string, mode (as in "rw+",
3334
+ and not as in permissions), used as parameter for file write.
3335
+ Check https://ruby-doc.org/core-2.3.1/IO.html#method-c-new
3336
+
3337
+
3338
+ This function does not have semantics to be called from
3339
+ the command line in its full interface, because
3340
+ it differentiates nil from ""
3341
+
3342
+ Planned improvements: permissions, shallow cat of a dir.
3343
+
3344
+ Examples:
3345
+
3346
+ # -- case: touch (non existing path and empty string)
3347
+ file_string__experimental ["non_existing_path", ""]
3348
+
3349
+ # -- case: echo > (existing or not path (can't be a dir) and non empty string)
3350
+ file_string__experimental ["existing_or_not_path__file", "contents of file"]
3351
+
3352
+ # -- case: echo >> (existing path (no dir) and non empty string, "a" mode)
3353
+ file_string__experimental ["existing_or_not_path__file", "contents of file", "a"]
3354
+
3355
+ # -- case: cat (path exists, (dir or file) otherwise becomes mkdir, nil string -- it is a recursive cat in the case of directories )
3356
+ file_string__experimental ["existing_path"]
3357
+
3358
+ # --- case: mkdir (or mkdir -p with only one argument): (non existing filepath, no string)
3359
+ file_string__experimental ["non_existing_path"]
3360
+
3361
+ # -- case: mkdir -p (non existing filepath, no string)
3362
+ file_string__experimental ["a/b/c/d"]
3363
+
3364
+
3365
+ =end
3366
+ def file_string__experimental file_string
3367
+ args = file_string
3368
+
3369
+ file_path,
3370
+ string_or_file_strings,
3371
+ mode,
3372
+ reserved = containerize(args)
3373
+
3374
+
3375
+ # if file_path is a directory, calls recursively this
3376
+ # function, retrieving the file_string representation
3377
+ # for each entry in a subdirectory:
3378
+ file_strings_entries = File.directory?(file_path) && (
3379
+ Dir.new(file_path).entries
3380
+ ).nne([]).map { |file_path_entry|
3381
+ next_file_path = [file_path, file_path_entry].join("/")
3382
+ # To avoid infinite recursion, we need to check if
3383
+ # the next file path is not something like the
3384
+ # parent with "/./" at the end.
3385
+ # It is not simple to normalize file paths:
3386
+ # https://stackoverflow.com/a/53884097/533510
3387
+ # It makes more difficult the fact that the next
3388
+ # may not yet exist (although the parent must exist).
3389
+ # But the parent has to exist. And, if the next
3390
+ # and the parent are the same, then both exist. In
3391
+ # that case, we case compare if both have the
3392
+ # same inode.
3393
+
3394
+ inodes = [
3395
+ [
3396
+ File.stat(file_path).ino,
3397
+ File.stat(File.dirname file_path).ino,
3398
+ ],
3399
+ :index,
3400
+ (
3401
+ bled_call { File.stat(next_file_path).ino }
3402
+ ).first,
3403
+ ]
3404
+
3405
+ skip = invoke__basic_sender_array(inodes)
3406
+ skip.negate_me &&
3407
+ # recursive call
3408
+ send(__method__, [next_file_path]) ||
3409
+ nil
3410
+ }.compact
3411
+
3412
+ # what is considered to be a file_path's contents?
3413
+ # this value will be the string_or_file_strings of
3414
+ # the returned value
3415
+ file_contents =
3416
+ # first case: it's a directory, thus its contents.
3417
+ file_strings_entries || (
3418
+ # second case: plain file, thus its contents as string
3419
+ bled_call {
3420
+ File.read(file_path)
3421
+ }
3422
+ # third case: non existing file (nil returned)
3423
+ ).first
3424
+
3425
+ string,
3426
+ file_strings = object__decompose string_or_file_strings
3427
+
3428
+ # let's just write file_path accordingly
3429
+ # to string_or_file_strings, regardless of file_contents
3430
+
3431
+ require 'fileutils'
3432
+ bled_call {
3433
+ string && (
3434
+ # for write matters:
3435
+ # if string, then file_path is a file...
3436
+ FileUtils.mkdir_p File.dirname file_path
3437
+ File.write file_path, string, mode: mode
3438
+ ) || (
3439
+ # otherwise file_path is a directory...
3440
+ FileUtils.mkdir_p file_path
3441
+ )
3442
+ }
3443
+
3444
+
3445
+ # if string_or_file_strings is a a list of file_strings
3446
+ # so file_path is interpreted to be written as a
3447
+ # directory
3448
+ file_strings = file_strings.map { |next_file_string|
3449
+ next_file_string = next_file_string.as_container
3450
+ # prepend file_path:
3451
+ next_file_string[0] = [
3452
+ file_path,
3453
+ next_file_string[0].to_s,
3454
+ ].join("/")
3455
+
3456
+ send __method__, next_file_string # recursive call
3457
+ }
3458
+
3459
+ [
3460
+ file_path,
3461
+ file_contents,
3462
+ ]
3463
+ end # of file_string__experimental
3464
+
3465
+
2918
3466
  end # of RubymentExperimentModule
2919
3467
 
2920
3468
 
@@ -3179,6 +3727,33 @@ module RubymentMaintainedModule
3179
3727
  =begin
3180
3728
  # documentation_begin
3181
3729
  # short_desc = "generates a block which may return exceptions instead of raising them."
3730
+ examples = [
3731
+ "
3732
+ (bled [] { :bled_returns }).first.call
3733
+ # => [:bled_returns, nil, nil]
3734
+ ",
3735
+ "
3736
+ (bled { :bled_returns }).first.call
3737
+ # => [:bled_returns, nil, nil]
3738
+ ",
3739
+ '
3740
+ (bled { X }).first.call
3741
+ => [nil,
3742
+ [nil,
3743
+ # ...
3744
+ # ["uninitialized constant #<Class:#<Rubyment:0x000000035adcc0>>::X", nil],
3745
+ # NameError],
3746
+ # #<NameError: uninitialized constant #<Class:#<Rubyment:0x000000035adcc0>>::X>]
3747
+ ',
3748
+ '
3749
+ (bled ["X is not undefined" ] { X }).first.call
3750
+ # => ["X is not undefined",
3751
+ # [nil,
3752
+ # "message{\
3753
+ ',
3754
+
3755
+ ]
3756
+
3182
3757
  @memory[:documentation].push = {
3183
3758
  :function => :bled,
3184
3759
  :short_desc => short_desc,
@@ -4066,6 +4641,17 @@ end
4066
4641
  this module from a file without stopping the process (#autoreload).
4067
4642
  - some function to redesign part of Ruby API arguably misdesigned,
4068
4643
  like #arrays__zip
4644
+ - functional exception handling (#bled_call and #bled)
4645
+ - certain programming patterns, like turning any ruby object in
4646
+ an effective composite pattern (#as_container, #object__decompose)
4647
+ - ... or a imaging of two system resources, like a file and a
4648
+ memory chunk (string), in a simplified interface that can
4649
+ abstract away many functions (file_string__experimental).
4650
+ - some functions to run a binary directly from a binary blob/memory
4651
+ chunk, or to convert that memory chunk in to an executable ruby
4652
+ script (#system_command__exec_via_file, #ruby_code__from_binary), so
4653
+ it can be deployed as a binary in a gem package
4654
+ (#gem_deploy__non_ruby_binaries).
4069
4655
 
4070
4656
 
4071
4657
  Rubyment functions must respect the open/closed principle
@@ -4104,7 +4690,9 @@ module RubymentModule
4104
4690
  include RubymentStringsModule
4105
4691
  include RubymentArraysModule
4106
4692
  include RubymentInternalModule
4693
+ include RubymentPatternsModule
4107
4694
  include RubymentInvocationModule
4695
+ include RubymentGemGenerationModule
4108
4696
  include RubymentExperimentModule
4109
4697
  include RubymentMaintainedModule
4110
4698
  include RubymentDeprecatedModule
@@ -5816,6 +6404,7 @@ module RubymentModule
5816
6404
  gem_bin_contents,
5817
6405
  gem_bin_executables,
5818
6406
  gem_dependencies,
6407
+ gem_non_ruby_executables,
5819
6408
  reserved = args
5820
6409
 
5821
6410
  debug = @memory[:debug]
@@ -5833,6 +6422,14 @@ module RubymentModule
5833
6422
  debug && (stderr.puts "gem_dependencies=#{gem_dependencies}")
5834
6423
  debug && (stderr.puts "gem_dependencies_str=#{gem_dependencies_str.inspect}")
5835
6424
 
6425
+ gem_bin_executables,
6426
+ reserved = gem_deploy__non_ruby_binaries [
6427
+ gem_name,
6428
+ gem_non_ruby_executables,
6429
+ gem_bin_executables,
6430
+ ]
6431
+ #
6432
+
5836
6433
  contents =<<-ENDHEREDOC
5837
6434
  Gem::Specification.new do |s|
5838
6435
  s.name = '#{gem_name}'
@@ -5893,22 +6490,28 @@ end
5893
6490
  major_version = memory[:major_version]
5894
6491
 
5895
6492
  gem_name,
5896
- gem_version,
5897
- gem_dir,
5898
- gem_ext,
5899
- gem_hifen,
5900
- gem_date,
5901
- gem_summary,
5902
- gem_description,
5903
- gem_authors,
5904
- gem_email,
5905
- gem_files,
5906
- gem_homepage,
5907
- gem_license,
5908
- gem_validate_class,
5909
- gem_validate_class_args,
5910
- gem_validate_class_method,
5911
- gem_is_current_file = args
6493
+ gem_version,
6494
+ gem_dir,
6495
+ gem_ext,
6496
+ gem_hifen,
6497
+ gem_date,
6498
+ gem_summary,
6499
+ gem_description,
6500
+ gem_authors,
6501
+ gem_email,
6502
+ gem_files,
6503
+ gem_homepage,
6504
+ gem_license,
6505
+ gem_validate_class,
6506
+ gem_validate_class_args,
6507
+ gem_validate_class_method,
6508
+ gem_is_current_file,
6509
+ gem_bin_generate,
6510
+ gem_bin_contents,
6511
+ gem_executables,
6512
+ gem_dependencies,
6513
+ gem_non_ruby_executables,
6514
+ reserved = args
5912
6515
 
5913
6516
  gem_name ||= "rubyment"
5914
6517
  gem_version ||= (version [])
@@ -5928,20 +6531,28 @@ end
5928
6531
  gem_validate_class ||= self.class.to_s
5929
6532
  gem_validate_class_args ||= {:invoke => ["p", "installed and validated"] }
5930
6533
  gem_validate_class_method ||= "new"
5931
- gem_is_current_file = __FILE__ # this enables the possibility of building
6534
+ gem_is_current_file ||= __FILE__ # this enables the possibility of building
5932
6535
  # a gem for the calling file itself, but be aware that lib/gem_file.rb
5933
6536
  # is supposed to be overriden later.
5934
- gem_bin_generate = "bin/#{gem_name}" # generate a bin file
5935
- gem_bin_contents =<<-ENDHEREDOC
6537
+ gem_bin_generate ||= "bin/#{gem_name}" # generate a bin file
6538
+ gem_bin_contents ||=<<-ENDHEREDOC
5936
6539
  #!/usr/bin/env ruby
5937
6540
  require '#{gem_name}'
5938
6541
  #{gem_validate_class}.new({:invoke => ARGV})
5939
6542
  ENDHEREDOC
5940
- gem_executables = [ gem_bin_generate && "#{gem_name}" ]
5941
- gem_dependencies = [
6543
+ gem_executables ||= [ gem_bin_generate && "#{gem_name}" ]
6544
+ gem_dependencies ||= [
5942
6545
  # use the format, for gems with semantic versioning
5943
6546
  # ["gems", "~> 0"],
5944
6547
  ]
6548
+ gem_non_ruby_executables ||= [
6549
+ # gem normally can only deploy non_ruby execs.
6550
+ # each file in this array will be escapsulated
6551
+ # as a ruby script that calls that file instead.
6552
+ # that ruby script will be placed in the
6553
+ # bin/ dir, and added to gem_executables
6554
+
6555
+ ]
5945
6556
 
5946
6557
  [
5947
6558
  gem_name,
@@ -5965,6 +6576,7 @@ require '#{gem_name}'
5965
6576
  gem_bin_contents,
5966
6577
  gem_executables,
5967
6578
  gem_dependencies,
6579
+ gem_non_ruby_executables,
5968
6580
  ]
5969
6581
  end
5970
6582
 
@@ -6531,6 +7143,7 @@ require '#{gem_name}'
6531
7143
 
6532
7144
  # test file_backup (just like a copy)
6533
7145
  def test__file_backup args=ARGV
7146
+ require 'fileutils'
6534
7147
  dest_dir, filename, append, prepend, file_contents, user, pw, keep_new = args
6535
7148
  filename ||= "testing-" + Time.now.hash.abs.to_s + ""
6536
7149
  dest_dir ||= "/tmp/"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyment
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.25752540
4
+ version: 0.7.25761093
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribamar Santarosa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-18 00:00:00.000000000 Z
11
+ date: 2018-12-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: a gem for keeping Rubyment, a set of ruby helpers
14
14
  email: ribamar@gmail.com