bblib 1.0.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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