bblib 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +502 -8
- data/lib/bblib.rb +1 -28
- data/lib/bblib/all.rb +5 -0
- data/lib/{time → bblib/classes}/cron.rb +0 -0
- data/lib/{string → bblib/classes}/fuzzy_matcher.rb +0 -0
- data/lib/bblib/cli.rb +3 -0
- data/lib/bblib/cli/color.rb +51 -0
- data/lib/bblib/cli/exceptions/invalid_argument.rb +5 -0
- data/lib/bblib/cli/exceptions/missing_argument.rb +5 -0
- data/lib/bblib/cli/exceptions/missing_required_argument.rb +5 -0
- data/lib/bblib/cli/exceptions/opts_parser.rb +9 -0
- data/lib/bblib/cli/option.rb +116 -0
- data/lib/bblib/cli/options/basic_option.rb +19 -0
- data/lib/bblib/cli/options/bool.rb +19 -0
- data/lib/bblib/cli/options/command.rb +11 -0
- data/lib/bblib/cli/options/date.rb +14 -0
- data/lib/bblib/cli/options/float.rb +14 -0
- data/lib/bblib/cli/options/integer.rb +14 -0
- data/lib/bblib/cli/options/json.rb +16 -0
- data/lib/bblib/cli/options/regexp.rb +17 -0
- data/lib/bblib/cli/options/string.rb +13 -0
- data/lib/bblib/cli/options/symbol.rb +13 -0
- data/lib/bblib/cli/options/time.rb +14 -0
- data/lib/bblib/cli/options/toggle.rb +27 -0
- data/lib/bblib/cli/options/untoggle.rb +18 -0
- data/lib/bblib/cli/opts_parser.rb +65 -0
- data/lib/bblib/core.rb +37 -0
- data/lib/{hash → bblib/core/classes}/hash_struct.rb +9 -2
- data/lib/bblib/core/classes/splitter.rb +101 -0
- data/lib/{time → bblib/core/classes}/task_timer.rb +0 -0
- data/lib/{hash → bblib/core/classes}/tree_hash.rb +22 -22
- data/lib/bblib/core/exceptions/abstract.rb +3 -0
- data/lib/bblib/core/exceptions/exception.rb +5 -0
- data/lib/{hash_path → bblib/core/hash_path}/hash_path.rb +0 -2
- data/lib/{hash_path → bblib/core/hash_path}/part.rb +0 -0
- data/lib/{mixins → bblib/core/mixins}/attrs.rb +17 -7
- data/lib/{mixins → bblib/core/mixins}/bbmixins.rb +1 -0
- data/lib/{mixins → bblib/core/mixins}/bridge.rb +0 -0
- data/lib/bblib/core/mixins/delegator.rb +90 -0
- data/lib/{class → bblib/core/mixins}/effortless.rb +0 -0
- data/lib/{mixins → bblib/core/mixins}/family_tree.rb +1 -1
- data/lib/{mixins → bblib/core/mixins}/hooks.rb +0 -0
- data/lib/{mixins → bblib/core/mixins}/logger.rb +0 -0
- data/lib/{mixins → bblib/core/mixins}/prototype.rb +0 -0
- data/lib/{mixins → bblib/core/mixins}/serializer.rb +0 -0
- data/lib/{mixins → bblib/core/mixins}/simple_init.rb +41 -3
- data/lib/{mixins → bblib/core/mixins}/type_init.rb +0 -0
- data/lib/{array/bbarray.rb → bblib/core/util/array.rb} +0 -0
- data/lib/{string → bblib/core/util}/cases.rb +0 -0
- data/lib/{file/bbfile.rb → bblib/core/util/file.rb} +31 -7
- data/lib/{hash/bbhash.rb → bblib/core/util/hash.rb} +0 -3
- data/lib/{logging/bblogging.rb → bblib/core/util/logging.rb} +11 -2
- data/lib/{string → bblib/core/util}/matching.rb +0 -0
- data/lib/{number/bbnumber.rb → bblib/core/util/number.rb} +0 -0
- data/lib/{object/bbobject.rb → bblib/core/util/object.rb} +2 -0
- data/lib/{opal/bbopal.rb → bblib/core/util/opal.rb} +0 -0
- data/lib/{os/bbos.rb → bblib/core/util/os.rb} +0 -0
- data/lib/{string → bblib/core/util}/pluralization.rb +0 -0
- data/lib/{string → bblib/core/util}/regexp.rb +0 -0
- data/lib/{string → bblib/core/util}/roman.rb +0 -0
- data/lib/{string/bbstring.rb → bblib/core/util/string.rb} +18 -24
- data/lib/{time/bbtime.rb → bblib/core/util/time.rb} +1 -5
- data/lib/bblib/cron.rb +2 -0
- data/lib/bblib/fuzzy_matcher.rb +2 -0
- data/lib/bblib/html.rb +4 -0
- data/lib/{html → bblib/html}/builder.rb +0 -0
- data/lib/{html → bblib/html}/tag.rb +0 -0
- data/lib/{html → bblib/html}/tag_set.rb +0 -0
- data/lib/bblib/system.rb +3 -0
- data/lib/bblib/system/command.rb +7 -0
- data/lib/bblib/system/system.rb +39 -0
- data/lib/bblib/version.rb +1 -1
- metadata +71 -44
- data/lib/error/abstract.rb +0 -3
- data/lib/hash_path/path_hash.rb +0 -84
- data/lib/hash_path/proc.rb +0 -93
- data/lib/hash_path/processors.rb +0 -239
- data/lib/html/bbhtml.rb +0 -3
- data/lib/system/bbsystem.rb +0 -42
data/lib/bblib.rb
CHANGED
@@ -1,28 +1 @@
|
|
1
|
-
require_relative 'bblib/
|
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'
|
data/lib/bblib/all.rb
ADDED
File without changes
|
File without changes
|
data/lib/bblib/cli.rb
ADDED
@@ -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,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,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,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
|