bblib 1.0.2 → 2.0.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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +502 -8
  3. data/lib/bblib.rb +1 -28
  4. data/lib/bblib/all.rb +5 -0
  5. data/lib/{time → bblib/classes}/cron.rb +0 -0
  6. data/lib/{string → bblib/classes}/fuzzy_matcher.rb +0 -0
  7. data/lib/bblib/cli.rb +3 -0
  8. data/lib/bblib/cli/color.rb +51 -0
  9. data/lib/bblib/cli/exceptions/invalid_argument.rb +5 -0
  10. data/lib/bblib/cli/exceptions/missing_argument.rb +5 -0
  11. data/lib/bblib/cli/exceptions/missing_required_argument.rb +5 -0
  12. data/lib/bblib/cli/exceptions/opts_parser.rb +9 -0
  13. data/lib/bblib/cli/option.rb +116 -0
  14. data/lib/bblib/cli/options/basic_option.rb +19 -0
  15. data/lib/bblib/cli/options/bool.rb +19 -0
  16. data/lib/bblib/cli/options/command.rb +11 -0
  17. data/lib/bblib/cli/options/date.rb +14 -0
  18. data/lib/bblib/cli/options/float.rb +14 -0
  19. data/lib/bblib/cli/options/integer.rb +14 -0
  20. data/lib/bblib/cli/options/json.rb +16 -0
  21. data/lib/bblib/cli/options/regexp.rb +17 -0
  22. data/lib/bblib/cli/options/string.rb +13 -0
  23. data/lib/bblib/cli/options/symbol.rb +13 -0
  24. data/lib/bblib/cli/options/time.rb +14 -0
  25. data/lib/bblib/cli/options/toggle.rb +27 -0
  26. data/lib/bblib/cli/options/untoggle.rb +18 -0
  27. data/lib/bblib/cli/opts_parser.rb +65 -0
  28. data/lib/bblib/core.rb +37 -0
  29. data/lib/{hash → bblib/core/classes}/hash_struct.rb +9 -2
  30. data/lib/bblib/core/classes/splitter.rb +101 -0
  31. data/lib/{time → bblib/core/classes}/task_timer.rb +0 -0
  32. data/lib/{hash → bblib/core/classes}/tree_hash.rb +22 -22
  33. data/lib/bblib/core/exceptions/abstract.rb +3 -0
  34. data/lib/bblib/core/exceptions/exception.rb +5 -0
  35. data/lib/{hash_path → bblib/core/hash_path}/hash_path.rb +0 -2
  36. data/lib/{hash_path → bblib/core/hash_path}/part.rb +0 -0
  37. data/lib/{mixins → bblib/core/mixins}/attrs.rb +17 -7
  38. data/lib/{mixins → bblib/core/mixins}/bbmixins.rb +1 -0
  39. data/lib/{mixins → bblib/core/mixins}/bridge.rb +0 -0
  40. data/lib/bblib/core/mixins/delegator.rb +90 -0
  41. data/lib/{class → bblib/core/mixins}/effortless.rb +0 -0
  42. data/lib/{mixins → bblib/core/mixins}/family_tree.rb +1 -1
  43. data/lib/{mixins → bblib/core/mixins}/hooks.rb +0 -0
  44. data/lib/{mixins → bblib/core/mixins}/logger.rb +0 -0
  45. data/lib/{mixins → bblib/core/mixins}/prototype.rb +0 -0
  46. data/lib/{mixins → bblib/core/mixins}/serializer.rb +0 -0
  47. data/lib/{mixins → bblib/core/mixins}/simple_init.rb +41 -3
  48. data/lib/{mixins → bblib/core/mixins}/type_init.rb +0 -0
  49. data/lib/{array/bbarray.rb → bblib/core/util/array.rb} +0 -0
  50. data/lib/{string → bblib/core/util}/cases.rb +0 -0
  51. data/lib/{file/bbfile.rb → bblib/core/util/file.rb} +31 -7
  52. data/lib/{hash/bbhash.rb → bblib/core/util/hash.rb} +0 -3
  53. data/lib/{logging/bblogging.rb → bblib/core/util/logging.rb} +11 -2
  54. data/lib/{string → bblib/core/util}/matching.rb +0 -0
  55. data/lib/{number/bbnumber.rb → bblib/core/util/number.rb} +0 -0
  56. data/lib/{object/bbobject.rb → bblib/core/util/object.rb} +2 -0
  57. data/lib/{opal/bbopal.rb → bblib/core/util/opal.rb} +0 -0
  58. data/lib/{os/bbos.rb → bblib/core/util/os.rb} +0 -0
  59. data/lib/{string → bblib/core/util}/pluralization.rb +0 -0
  60. data/lib/{string → bblib/core/util}/regexp.rb +0 -0
  61. data/lib/{string → bblib/core/util}/roman.rb +0 -0
  62. data/lib/{string/bbstring.rb → bblib/core/util/string.rb} +18 -24
  63. data/lib/{time/bbtime.rb → bblib/core/util/time.rb} +1 -5
  64. data/lib/bblib/cron.rb +2 -0
  65. data/lib/bblib/fuzzy_matcher.rb +2 -0
  66. data/lib/bblib/html.rb +4 -0
  67. data/lib/{html → bblib/html}/builder.rb +0 -0
  68. data/lib/{html → bblib/html}/tag.rb +0 -0
  69. data/lib/{html → bblib/html}/tag_set.rb +0 -0
  70. data/lib/bblib/system.rb +3 -0
  71. data/lib/bblib/system/command.rb +7 -0
  72. data/lib/bblib/system/system.rb +39 -0
  73. data/lib/bblib/version.rb +1 -1
  74. metadata +71 -44
  75. data/lib/error/abstract.rb +0 -3
  76. data/lib/hash_path/path_hash.rb +0 -84
  77. data/lib/hash_path/proc.rb +0 -93
  78. data/lib/hash_path/processors.rb +0 -239
  79. data/lib/html/bbhtml.rb +0 -3
  80. data/lib/system/bbsystem.rb +0 -42
@@ -1,28 +1 @@
1
- require_relative 'bblib/version'
2
- require_relative 'opal/bbopal'
3
- require_relative 'object/bbobject'
4
- require_relative 'hash/bbhash'
5
- require_relative 'mixins/bbmixins'
6
- require_relative 'class/effortless'
7
- require_relative 'hash_path/hash_path'
8
- require_relative 'string/bbstring'
9
- require_relative 'file/bbfile'
10
- require_relative 'time/bbtime'
11
- require_relative 'number/bbnumber'
12
- require_relative 'array/bbarray'
13
- require_relative 'system/bbsystem'
14
- require_relative 'logging/bblogging'
15
- require_relative 'error/abstract'
16
- require_relative 'html/bbhtml'
17
-
18
- non_opal = ['os/bbos']
19
-
20
- non_opal.each { |i| require_relative i } unless BBLib.in_opal?
21
-
22
- require 'fileutils'
23
- require 'time'
24
- # require 'logger'
25
-
26
- module BBLib
27
- CONFIGS_PATH = 'config/'.freeze
28
- end
1
+ require_relative 'bblib/core'
@@ -0,0 +1,5 @@
1
+ require_relative 'core'
2
+ require_relative 'cli'
3
+ require_relative 'system'
4
+ require_relative 'html'
5
+ require_relative 'cron'
File without changes
@@ -0,0 +1,3 @@
1
+ require_relative 'core'
2
+ require_relative 'cli/opts_parser'
3
+ require_relative 'cli/color'
@@ -0,0 +1,51 @@
1
+ module BBLib
2
+ module Console
3
+
4
+ COLOR_CODES = {
5
+ black: 30,
6
+ red: 31,
7
+ green: 32,
8
+ orange: 33,
9
+ yellow: 33,
10
+ blue: 34,
11
+ purple: 35,
12
+ cyan: 36,
13
+ gray: 37,
14
+ grey: 37,
15
+ white: 37,
16
+ none: 0,
17
+ default: 39
18
+ }.freeze
19
+
20
+ SEVERITY_COLORS = {
21
+ debug: :light_purple,
22
+ info: :light_blue,
23
+ warn: :yellow,
24
+ error: :light_red,
25
+ fatal: :red,
26
+ success: :green,
27
+ ok: :green,
28
+ fail: :red
29
+ }
30
+
31
+ def self.colorize(text, color = :none, background: false, light: false)
32
+ color = SEVERITY_COLORS[color.to_s.downcase.to_sym] if SEVERITY_COLORS.include?(color.to_s.downcase.to_sym)
33
+ if color.to_s.start_with?('light_')
34
+ color = color.to_s.split('_', 2).last.to_sym
35
+ light = true
36
+ end
37
+ light = true if color == :grey || color == :gray
38
+ color = COLOR_CODES[color] if COLOR_CODES.include?(color)
39
+ color = COLOR_CODES[:default] unless color.is_a?(Integer)
40
+ color += 10 if background
41
+ "\e[#{light ? 1 : 0};#{color}m#{text}\e[0m"
42
+ end
43
+
44
+ end
45
+ end
46
+
47
+ class String
48
+ def to_color(color_code, opts = {})
49
+ BBLib::Console.colorize(self, color_code, **opts)
50
+ end
51
+ end
@@ -0,0 +1,5 @@
1
+ module BBLib
2
+ class InvalidArgumentException < OptsParserException
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module BBLib
2
+ class MissingArgumentException < OptsParserException
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module BBLib
2
+ class MissingRequiredArgumentException < MissingArgumentException
3
+
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ module BBLib
2
+ class OptsParserException < Exception
3
+ # Nothing...
4
+ end
5
+ end
6
+
7
+ require_relative 'invalid_argument'
8
+ require_relative 'missing_argument'
9
+ require_relative 'missing_required_argument'
@@ -0,0 +1,116 @@
1
+ module BBLib
2
+ class OptsParser
3
+ class Option
4
+ include BBLib::Effortless
5
+ include BBLib::TypeInit
6
+
7
+ attr_sym :name, default_proc: :determine_name
8
+ attr_str :description, aliases: :desc
9
+ attr_of Object, :default, allow_nil: true, default: nil
10
+ attr_str :placeholder, default_proc: proc { |x| x.name.upcase }
11
+ attr_ary_of String, :flags, arg_at: 1
12
+ attr_of [String, Regexp], :delimiter, default: nil, allow_nil: true
13
+ attr_str :argument_delimiter, default: ' '
14
+ attr_bool :raise_errors, default: true
15
+ attr_bool :required, default: false
16
+ attr_of Proc, :processor, arg_at: :block, default: nil, allow_nil: true
17
+ attr_ary_of Proc, :validators
18
+ attr_bool :singular, default: true
19
+ attr_of [Integer, Range], :position, default: nil, allow_nil: true
20
+ attr_hash :sub_commands, keys: String, values: OptsParser, aliases: [:sub_cmds, :subcommands], default: nil, allow_nil: true, pre_proc: proc { |hash| hash.is_a?(Hash) ? hash.keys_to_s : hash }
21
+
22
+
23
+ def to_s
24
+ (flags.sort_by(&:size).join(', ') + " #{placeholder}").strip.ljust(40, ' ') + "\t#{description}"
25
+ end
26
+
27
+ def self.types
28
+ descendants.map(&:type)
29
+ end
30
+
31
+ def retrieve(args, parsed)
32
+ result = singular? ? nil : []
33
+ index = 0
34
+ until index >= args.size
35
+ begin
36
+ unless flag_match?(args[index], index)
37
+ index += 1
38
+ next
39
+ end
40
+ values = split(extract(index, args))
41
+ values.each do |value|
42
+ valid!(value)
43
+ if singular?
44
+ result = value
45
+ index = args.size
46
+ else
47
+ result << value
48
+ end
49
+ end
50
+ rescue OptsParserException => e
51
+ raise e if raise_errors?
52
+ end
53
+ end
54
+ raise MissingArgumentException, "A required argument is missing: #{name}" if required? && result.nil?
55
+ result = processor.call(result) if !result.nil? && processor
56
+ process_result(result.nil? ? default : result, args, parsed)
57
+ end
58
+
59
+ def singular?
60
+ singular && !delimiter
61
+ end
62
+
63
+ def flag_match?(str, index = 0)
64
+ text_match = if flags.empty? && position
65
+ true
66
+ elsif argument_delimiter == ' '
67
+ if str =~ /^\-[^\-]/
68
+ flags.any? do |flag|
69
+ flag =~ /^\-[\w\d]/ && str.include?(flag[1])
70
+ end
71
+ else
72
+ flags.include?(str)
73
+ end
74
+ else
75
+ flags.any? do |flag|
76
+ flag.start_with?("#{str}#{argument_delimiter}")
77
+ end
78
+ end
79
+ return text_match unless text_match && position
80
+ position === index
81
+ end
82
+
83
+ def valid?(value)
84
+ return true if validators.empty?
85
+ validators.all? do |validator|
86
+ validator.call(value)
87
+ end
88
+ end
89
+
90
+ def valid!(value)
91
+ raise InvalidArgumentException, "Invalid argument for #{name}" unless valid?(value)
92
+ end
93
+
94
+ def split(value)
95
+ return [value] unless delimiter
96
+ value.msplit(delimiter)
97
+ end
98
+
99
+ protected
100
+
101
+ def determine_name
102
+ flag = flags.find { |f| f.start_with?('--') }
103
+ flag = flags.first unless flag
104
+ flag.to_s.sub(/^-{1,2}/, '').snake_case
105
+ end
106
+
107
+ def process_result(result, args, parsed)
108
+ parsed.deep_merge!(name => result)
109
+ if sub_commands && sub_commands[result]
110
+ parsed.deep_merge!(sub_commands[result].parse!(args))
111
+ end
112
+ end
113
+
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,19 @@
1
+ module BBLib
2
+ class OptsParser
3
+ class BasicOption < Option
4
+
5
+ def extract(index, args)
6
+ args.delete_at(index)
7
+ raise MissingArgumentException, "No argument was provided for #{name}" if args[index].nil?
8
+ format_value(args.delete_at(index))
9
+ end
10
+
11
+ protected
12
+
13
+ def format_value(value)
14
+ raise AbstractError
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module BBLib
2
+ class OptsParser
3
+ class Bool < BasicOption
4
+
5
+ TRUE_STATEMENTS = %w{true yes y t 1}
6
+ FALSE_STATEMENTS = %w{false no n f 0}
7
+
8
+ protected
9
+
10
+ def format_value(value)
11
+ tru = TRUE_STATEMENTS.any? { |ts| ts == value.downcase }
12
+ fal = FALSE_STATEMENTS.any? { |fs| fs == value.downcase }
13
+ raise InvalidArgumentException, "#{name} is a boolean argument but got a non-boolean value" unless tru || fal
14
+ tru && !fal
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ module BBLib
2
+ class OptsParser
3
+ class Command < Option
4
+
5
+ def extract(index, args)
6
+ args.delete_at(index)
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ module BBLib
2
+ class OptsParser
3
+ class Date < BasicOption
4
+
5
+ protected
6
+
7
+ # TODO Support custom formats
8
+ def format_value(value)
9
+ ::Date.parse(value)
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module BBLib
2
+ class OptsParser
3
+ class Float < BasicOption
4
+
5
+ protected
6
+
7
+ def format_value(value)
8
+ raise InvalidArgumentException, "Argument provided for #{name} should be an float but was '#{args[index]}'" unless value =~ /^\d+(\.\d+)?$/
9
+ value.to_f
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module BBLib
2
+ class OptsParser
3
+ class Integer < BasicOption
4
+
5
+ protected
6
+
7
+ def format_value(value)
8
+ raise InvalidArgumentException, "Argument provided for #{name} should be an integer but was '#{args[index]}'" unless value =~ /^\d+$/
9
+ value.to_i
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ module BBLib
2
+ class OptsParser
3
+ class JSON < BasicOption
4
+
5
+ protected
6
+
7
+ def format_value(value)
8
+ require 'json' unless defined?(::JSON)
9
+ ::JSON.parse(value)
10
+ rescue ::JSON::ParserError => e
11
+ raise InvalidArgumentException, "Invalid JSON. #{e.to_s}"
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module BBLib
2
+ class OptsParser
3
+ class Regexp < BasicOption
4
+
5
+ protected
6
+
7
+ def format_value(value)
8
+ if value =~ /^\/.*\/\w*$/
9
+ value.to_regex
10
+ else
11
+ /#{value}/
12
+ end
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ module BBLib
2
+ class OptsParser
3
+ class String < BasicOption
4
+
5
+ protected
6
+
7
+ def format_value(value)
8
+ value.to_s
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module BBLib
2
+ class OptsParser
3
+ class Symbol < BasicOption
4
+
5
+ protected
6
+
7
+ def format_value(value)
8
+ value.to_sym
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module BBLib
2
+ class OptsParser
3
+ class Time < BasicOption
4
+
5
+ protected
6
+
7
+ # TODO Support custom formats
8
+ def format_value(value)
9
+ ::Time.parse(value)
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,27 @@
1
+ module BBLib
2
+ class OptsParser
3
+ class Toggle < Option
4
+
5
+ def extract(index, args)
6
+ value = args[index]
7
+ if value =~ /^\-[\w\d]$/ || flags.include?(value)
8
+ args.delete_at(index)
9
+ else
10
+ flag = flags.find do |flag|
11
+ next unless flag =~ /^\-[\w\d]$/
12
+ value.include?(flag[1])
13
+ end
14
+ value.sub!(flag[1], '')
15
+ end
16
+ true
17
+ end
18
+
19
+ protected
20
+
21
+ def simple_setup
22
+ self.default = false
23
+ end
24
+
25
+ end
26
+ end
27
+ end