gloo 0.3.0 → 0.5.3

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 (112) hide show
  1. checksums.yaml +4 -4
  2. data/.DS_Store +0 -0
  3. data/.rubocop.yml +73 -0
  4. data/Gemfile +2 -2
  5. data/Gemfile.lock +86 -83
  6. data/Rakefile +7 -6
  7. data/bin/console +4 -4
  8. data/gloo.gemspec +22 -18
  9. data/lib/gloo.rb +6 -6
  10. data/lib/gloo/app/args.rb +30 -31
  11. data/lib/gloo/app/engine.rb +80 -30
  12. data/lib/gloo/app/help.rb +17 -11
  13. data/lib/gloo/app/info.rb +3 -3
  14. data/lib/gloo/app/log.rb +17 -17
  15. data/lib/gloo/app/mode.rb +4 -4
  16. data/lib/gloo/app/settings.rb +51 -41
  17. data/lib/gloo/convert/string_to_datetime.rb +21 -0
  18. data/lib/gloo/convert/string_to_decimal.rb +20 -0
  19. data/lib/gloo/convert/string_to_integer.rb +20 -0
  20. data/lib/gloo/core/baseo.rb +7 -7
  21. data/lib/gloo/core/dictionary.rb +30 -27
  22. data/lib/gloo/core/error.rb +50 -0
  23. data/lib/gloo/core/event_manager.rb +17 -23
  24. data/lib/gloo/core/factory.rb +149 -39
  25. data/lib/gloo/core/gloo_system.rb +121 -54
  26. data/lib/gloo/core/heap.rb +15 -13
  27. data/lib/gloo/core/it.rb +5 -5
  28. data/lib/gloo/core/literal.rb +7 -7
  29. data/lib/gloo/core/obj.rb +138 -79
  30. data/lib/gloo/core/obj_finder.rb +9 -14
  31. data/lib/gloo/core/op.rb +8 -8
  32. data/lib/gloo/core/parser.rb +27 -26
  33. data/lib/gloo/core/pn.rb +68 -52
  34. data/lib/gloo/core/script.rb +7 -7
  35. data/lib/gloo/core/tokens.rb +39 -41
  36. data/lib/gloo/core/verb.rb +30 -19
  37. data/lib/gloo/exec/dispatch.rb +30 -0
  38. data/lib/gloo/exec/runner.rb +43 -0
  39. data/lib/gloo/expr/expression.rb +36 -43
  40. data/lib/gloo/expr/l_boolean.rb +7 -6
  41. data/lib/gloo/expr/l_decimal.rb +34 -0
  42. data/lib/gloo/expr/l_integer.rb +5 -4
  43. data/lib/gloo/expr/l_string.rb +13 -15
  44. data/lib/gloo/expr/op_div.rb +5 -5
  45. data/lib/gloo/expr/op_minus.rb +5 -5
  46. data/lib/gloo/expr/op_mult.rb +5 -5
  47. data/lib/gloo/expr/op_plus.rb +7 -7
  48. data/lib/gloo/objs/basic/alias.rb +111 -0
  49. data/lib/gloo/objs/basic/boolean.rb +63 -38
  50. data/lib/gloo/objs/basic/container.rb +71 -12
  51. data/lib/gloo/objs/basic/decimal.rb +96 -0
  52. data/lib/gloo/objs/basic/integer.rb +45 -16
  53. data/lib/gloo/objs/basic/script.rb +62 -38
  54. data/lib/gloo/objs/basic/string.rb +47 -15
  55. data/lib/gloo/objs/basic/text.rb +69 -21
  56. data/lib/gloo/objs/basic/untyped.rb +35 -10
  57. data/lib/gloo/objs/cli/banner.rb +137 -0
  58. data/lib/gloo/objs/cli/bar.rb +141 -0
  59. data/lib/gloo/objs/cli/colorize.rb +54 -24
  60. data/lib/gloo/objs/cli/confirm.rb +63 -29
  61. data/lib/gloo/objs/cli/menu.rb +236 -0
  62. data/lib/gloo/objs/cli/menu_item.rb +128 -0
  63. data/lib/gloo/objs/cli/pastel.rb +120 -0
  64. data/lib/gloo/objs/cli/prompt.rb +73 -31
  65. data/lib/gloo/objs/cli/select.rb +153 -0
  66. data/lib/gloo/objs/ctrl/each.rb +128 -61
  67. data/lib/gloo/objs/ctrl/repeat.rb +129 -0
  68. data/lib/gloo/objs/data/markdown.rb +109 -0
  69. data/lib/gloo/objs/data/table.rb +168 -0
  70. data/lib/gloo/objs/dev/git.rb +98 -64
  71. data/lib/gloo/objs/dt/date.rb +72 -0
  72. data/lib/gloo/objs/dt/datetime.rb +84 -0
  73. data/lib/gloo/objs/dt/time.rb +72 -0
  74. data/lib/gloo/objs/ror/erb.rb +82 -41
  75. data/lib/gloo/objs/ror/eval.rb +73 -31
  76. data/lib/gloo/objs/snd/play.rb +71 -0
  77. data/lib/gloo/objs/snd/say.rb +120 -0
  78. data/lib/gloo/objs/system/file_handle.rb +129 -48
  79. data/lib/gloo/objs/system/system.rb +84 -38
  80. data/lib/gloo/objs/web/http_get.rb +103 -46
  81. data/lib/gloo/objs/web/http_post.rb +70 -44
  82. data/lib/gloo/objs/web/json.rb +155 -0
  83. data/lib/gloo/objs/web/slack.rb +89 -58
  84. data/lib/gloo/objs/web/teams.rb +88 -53
  85. data/lib/gloo/objs/web/uri.rb +160 -0
  86. data/lib/gloo/persist/file_loader.rb +95 -85
  87. data/lib/gloo/persist/file_saver.rb +12 -12
  88. data/lib/gloo/persist/file_storage.rb +15 -15
  89. data/lib/gloo/persist/line_splitter.rb +79 -0
  90. data/lib/gloo/persist/persist_man.rb +63 -39
  91. data/lib/gloo/utils/words.rb +2 -2
  92. data/lib/gloo/verbs/alert.rb +67 -16
  93. data/lib/gloo/verbs/beep.rb +70 -0
  94. data/lib/gloo/verbs/cls.rb +67 -0
  95. data/lib/gloo/verbs/context.rb +61 -21
  96. data/lib/gloo/verbs/create.rb +52 -21
  97. data/lib/gloo/verbs/help.rb +186 -27
  98. data/lib/gloo/verbs/if.rb +55 -21
  99. data/lib/gloo/verbs/list.rb +55 -24
  100. data/lib/gloo/verbs/load.rb +47 -12
  101. data/lib/gloo/verbs/move.rb +128 -0
  102. data/lib/gloo/verbs/put.rb +90 -34
  103. data/lib/gloo/verbs/quit.rb +43 -12
  104. data/lib/gloo/verbs/run.rb +63 -18
  105. data/lib/gloo/verbs/save.rb +45 -10
  106. data/lib/gloo/verbs/show.rb +56 -22
  107. data/lib/gloo/verbs/tell.rb +45 -13
  108. data/lib/gloo/verbs/unless.rb +56 -21
  109. data/lib/gloo/verbs/version.rb +42 -12
  110. data/lib/gloo/verbs/wait.rb +73 -0
  111. data/lib/run.rb +5 -5
  112. metadata +90 -12
@@ -7,29 +7,30 @@
7
7
  module Gloo
8
8
  module Persist
9
9
  class FileLoader
10
-
11
- BEGIN_BLOCK = "BEGIN"
12
- END_BLOCK = "END"
13
-
10
+
11
+ BEGIN_BLOCK = 'BEGIN'.freeze
12
+ END_BLOCK = 'END'.freeze
13
+ SPACE_CNT = 2
14
+
14
15
  attr_reader :obj
15
-
16
+
16
17
  # Set up a file storage for an object.
17
- def initialize pn
18
+ def initialize( pn )
18
19
  @pn = pn
19
20
  @tabs = 0
20
21
  @obj = nil
21
22
  @in_multiline = false
22
23
  @exiting_multiline = false
23
24
  @in_block = false
24
- @block_value = ""
25
- @debug = false
25
+ @block_value = ''
26
+ @debug = false
26
27
  end
27
-
28
- #
28
+
29
+ #
29
30
  # Load the objects from the file.
30
- #
31
+ #
31
32
  def load
32
- unless File.exists?( @pn )
33
+ unless File.exist?( @pn )
33
34
  $log.error "File '#{@pn}' does not exist."
34
35
  return
35
36
  end
@@ -37,135 +38,144 @@ module Gloo
37
38
  @parent_stack = []
38
39
  @parent = $engine.heap.root
39
40
  @parent_stack.push @parent
40
- f = File.open( @pn, "r" )
41
+ f = File.open( @pn, 'r' )
41
42
  f.each_line do |line|
42
43
  next if skip_line? line
43
- if line.strip.end_with? BEGIN_BLOCK
44
- @in_block = true
45
- @save_line = line
46
- elsif @in_block
47
- if line.strip == END_BLOCK
48
- @in_block = false
49
- determine_indent @save_line
50
- process_line @save_line
51
- else
52
- @block_value << line
53
- end
44
+
45
+ handle_one_line line
46
+ end
47
+ end
48
+
49
+ #
50
+ # Process one one of the file we're loading.
51
+ #
52
+ def handle_one_line( line )
53
+ if line.strip.end_with? BEGIN_BLOCK
54
+ @in_block = true
55
+ @save_line = line
56
+ elsif @in_block
57
+ if line.strip == END_BLOCK
58
+ @in_block = false
59
+ determine_indent @save_line
60
+ process_line @save_line
54
61
  else
55
- determine_indent line
56
- process_line line
62
+ @block_value << line
57
63
  end
64
+ else
65
+ determine_indent line
66
+ process_line line
58
67
  end
59
68
  end
60
-
69
+
61
70
  # Is this line a comment or a blank line?
62
71
  # If so we'll skip it.
63
- def skip_line? line
72
+ def skip_line?( line )
64
73
  line = line.strip
65
74
  return true if line.empty?
66
- return true if line[0] == "#"
75
+ return true if line[ 0 ] == '#'
76
+
67
77
  return false
68
78
  end
69
-
79
+
70
80
  # Determine the relative indent level for the line.
71
- def determine_indent line
81
+ def determine_indent( line )
72
82
  tabs = tab_count( line )
73
- @indent = 0 # same level as prior line
74
- if tabs > @tabs # indent
83
+ @indent = 0 # same level as prior line
84
+ if tabs > @tabs # indent
75
85
  # TODO: What if indent is more than one more level?
76
86
  @tabs = tabs
77
87
  @indent = 1
78
- elsif tabs < @tabs # outdent
79
- while tabs < @tabs
80
- @tabs -= 1
81
- @indent -= 1
82
- end
88
+ elsif tabs < @tabs # outdent
89
+ diff = @tabs - tabs
90
+ @tabs -= diff
91
+ @indent -= diff
83
92
  end
84
- puts "tabs: #{@tabs}, indent: #{@indent}, line: #{line}" if @debug
93
+ puts "tabs: #{@tabs}, indent: #{@indent}, line: #{line}" if @debug
85
94
  end
86
95
 
87
96
  # Process one line and add objects.
88
- def process_line line
97
+ def process_line( line )
89
98
  # reset multiline unless we're actually indented
90
99
  if @in_multiline && @multi_indent > @indent
91
- puts "Done multiline mi: #{@multi_indent}, i: #{@indent}" if @debug
100
+ puts "Done multiline mi: #{@multi_indent}, i: #{@indent}" if @debug
92
101
  @in_multiline = false
93
102
  @exiting_multiline = true
94
103
  end
95
-
104
+
96
105
  if @in_multiline
97
106
  @last.add_line line
98
107
  else
108
+ setup_process_obj_line
99
109
  process_obj_line line
100
110
  end
101
111
  end
102
-
103
- # Process one line and add objects.
104
- def process_obj_line line
112
+
113
+ #
114
+ # Setup and get ready to process an object line.
115
+ #
116
+ def setup_process_obj_line
105
117
  if @exiting_multiline
106
118
  @exiting_multiline = false
107
- elsif @indent > 0
119
+ @indent += 1
120
+ end
121
+
122
+ if @indent.positive?
108
123
  @parent = @last
109
124
  @parent_stack.push @parent
110
- elsif @indent < 0
125
+ elsif @indent.negative?
111
126
  @indent.abs.times do
112
127
  @parent_stack.pop
113
128
  @parent = @parent_stack.last
114
129
  end
115
130
  end
116
-
131
+ end
132
+
133
+ #
134
+ # Process one line and add objects.
135
+ #
136
+ def process_obj_line( line )
117
137
  name, type, value = split_line( line )
118
- unless @block_value == ""
138
+ unless @block_value == ''
119
139
  value = @block_value
120
- @block_value = ""
140
+ @block_value = ''
121
141
  end
122
- @last = $engine.factory.create( name, type, value, @parent )
123
- if @last && @last.has_multiline_value?
142
+ params = { name: name, type: type, value: value, parent: @parent }
143
+ @last = $engine.factory.create( params )
144
+
145
+ if value.empty? && @last&.multiline_value?
124
146
  @multi_indent = 0
125
147
  @in_multiline = true
126
- puts "*** Start multiline. multi_indent: #{@multi_indent}" if @debug
148
+ puts "*** Start multiline. multi_indent: #{@multi_indent}" if @debug
127
149
  end
128
-
150
+
129
151
  @obj = @last if @obj.nil?
130
152
  end
131
-
153
+
154
+ #
132
155
  # Get the number of leading tabs.
133
- def tab_count line
156
+ #
157
+ def tab_count( line )
134
158
  i = 0
135
- while line[i] == "\t"
136
- i += 1
159
+
160
+ if line[ i ] == ' '
161
+ i += 1 while line[ i ] == ' '
162
+ tab_equiv = ( i / SPACE_CNT ).to_i
163
+ puts "Found #{i} spaces => #{tab_equiv}" if @debug
164
+ return tab_equiv
137
165
  end
166
+
167
+ i += 1 while line[ i ] == "\t"
138
168
  return i
139
169
  end
140
-
170
+
171
+ #
141
172
  # Split the line into 3 parts.
142
- def split_line line
143
- puts "splitting line: #{line}" if @debug
144
- line = line[ @tabs..-1]
145
- line = line[0..-2] if line[-1] == "\n"
146
- i = line.index( ' ' )
147
- name = line[0..i-1]
148
-
149
- line = line[i+1..-1]
150
- i = line.index( ' ' )
151
- type = line[0..(i ? i-1 : -1)]
152
- type = type[1..-1] if type[0] == '['
153
- type = type[0..-2] if type[-1] == ']'
154
-
155
- if i
156
- value = line[i+1..-1]
157
- if value[0..1] == ': '
158
- value = value[2..-1]
159
- elsif value[0] == ':'
160
- value = value[1..-1]
161
- end
162
- else
163
- value = nil
164
- end
165
- # puts "'#{value}'".yellow
166
- return name, type, value
173
+ #
174
+ def split_line( line )
175
+ o = LineSplitter.new( line, @tabs )
176
+ return o.split
167
177
  end
168
-
178
+
169
179
  end
170
180
  end
171
181
  end
@@ -7,33 +7,33 @@
7
7
  module Gloo
8
8
  module Persist
9
9
  class FileSaver
10
-
10
+
11
11
  # Set up a file storage for an object.
12
- def initialize pn, obj
12
+ def initialize( pn, obj )
13
13
  @pn = pn
14
14
  @obj = obj
15
15
  end
16
-
17
- #
16
+
17
+ #
18
18
  # Save the object to the file.
19
- #
19
+ #
20
20
  def save
21
21
  data = get_obj( @obj )
22
22
  File.write( @pn, data )
23
23
  end
24
-
24
+
25
25
  # Get string of tabs for indentation.
26
- def tabs indent=0
26
+ def tabs( indent = 0 )
27
27
  return "\t" * indent
28
28
  end
29
-
29
+
30
30
  # Convert an object to textual representation.
31
31
  # This is a recursive function.
32
- def get_obj o, indent=0
32
+ def get_obj( obj, indent = 0 )
33
33
  t = tabs( indent )
34
- str = "#{t}#{o.name} [#{o.type_display}] : #{o.value_display}\n"
35
- o.children.each do |child|
36
- str << get_obj( child, indent+1 )
34
+ str = "#{t}#{obj.name} [#{obj.type_display}] : #{obj.value_display}\n"
35
+ obj.children.each do |child|
36
+ str << get_obj( child, indent + 1 )
37
37
  end
38
38
  return str
39
39
  end
@@ -7,37 +7,37 @@
7
7
  module Gloo
8
8
  module Persist
9
9
  class FileStorage
10
-
10
+
11
11
  attr_reader :obj, :pn
12
-
12
+
13
13
  # Set up a file storage for an object.
14
- def initialize pn, obj=nil
14
+ def initialize( pn, obj = nil )
15
15
  @obj = obj
16
16
  @pn = pn
17
17
  end
18
-
19
- #
18
+
19
+ #
20
20
  # Save the object to the file.
21
- #
21
+ #
22
22
  def save
23
23
  fs = FileSaver.new @pn, @obj
24
24
  fs.save
25
25
  end
26
-
27
- #
26
+
27
+ #
28
28
  # Load the object from the file.
29
- #
29
+ #
30
30
  def load
31
31
  fl = FileLoader.new @pn
32
32
  fl.load
33
33
  @obj = fl.obj
34
- if @obj
35
- $log.debug "Loaded object: #{@obj.name}"
36
- else
37
- $log.error "Error loading file at #{@pn}"
38
- end
34
+ if @obj
35
+ $log.debug "Loaded object: #{@obj.name}"
36
+ else
37
+ $log.error "Error loading file at #{@pn}"
38
+ end
39
39
  end
40
-
40
+
41
41
  end
42
42
  end
43
43
  end
@@ -0,0 +1,79 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2020 Eric Crane. All rights reserved.
3
+ #
4
+ # Helper class used as part of file loading.
5
+ # It is responsible for splitting a line into components.
6
+ #
7
+
8
+ module Gloo
9
+ module Persist
10
+ class LineSplitter
11
+
12
+ BEGIN_BLOCK = 'BEGIN'.freeze
13
+ END_BLOCK = 'END'.freeze
14
+
15
+ attr_reader :obj
16
+
17
+ # Set up a line splitter
18
+ def initialize( line, tabs )
19
+ @line = line
20
+ @tabs = tabs
21
+ end
22
+
23
+ #
24
+ # Split the line into 3 parts.
25
+ #
26
+ def split
27
+ detect_name
28
+ detect_type
29
+ detect_value
30
+
31
+ return @name, @type, @value
32
+ end
33
+
34
+ #
35
+ # Detect the object name.
36
+ #
37
+ def detect_name
38
+ @line = @line.strip
39
+ @idx = @line.index( ' ' )
40
+ @name = @line[ 0..@idx - 1 ]
41
+ end
42
+
43
+ #
44
+ # Detect the object type.
45
+ #
46
+ def detect_type
47
+ @line = @line[ @idx + 1..-1 ]
48
+ @idx = @line.index( ' ' )
49
+
50
+ if @line[ 0 ] == ':'
51
+ @type = 'untyped'
52
+ return
53
+ end
54
+
55
+ @type = @line[ 0..( @idx ? @idx - 1 : -1 ) ]
56
+ @type = @type[ 1..-1 ] if @type[ 0 ] == '['
57
+ @type = @type[ 0..-2 ] if @type[ -1 ] == ']'
58
+ end
59
+
60
+ #
61
+ # Detect the object value.
62
+ # Use nil if there is no value specified.
63
+ #
64
+ def detect_value
65
+ if @idx
66
+ @value = @line[ @idx + 1..-1 ]
67
+ if @value[ 0..1 ] == ': '
68
+ @value = @value[ 2..-1 ]
69
+ elsif @value[ 0 ] == ':'
70
+ @value = @value[ 1..-1 ]
71
+ end
72
+ else
73
+ @value = nil
74
+ end
75
+ end
76
+
77
+ end
78
+ end
79
+ end
@@ -9,74 +9,98 @@
9
9
  module Gloo
10
10
  module Persist
11
11
  class PersistMan
12
-
12
+
13
13
  attr_reader :maps
14
-
14
+
15
15
  # Contructor for the persistence manager.
16
16
  def initialize
17
17
  @maps = []
18
18
  end
19
-
20
- #
19
+
20
+ #
21
21
  # Save one object to the file.
22
- #
23
- def save name=""
22
+ #
23
+ def save( name = '' )
24
24
  if name.nil? || name.strip.empty?
25
25
  save_all
26
26
  else
27
27
  save_one name
28
28
  end
29
29
  end
30
-
31
- #
30
+
31
+ #
32
32
  # Save one object to the file.
33
- #
33
+ #
34
34
  def save_all
35
- @maps.each do |o|
36
- o.save
37
- end
35
+ @maps.each( &:save )
38
36
  end
39
-
40
- #
37
+
38
+ #
41
39
  # Save one object to the file.
42
- #
43
- def save_one name
40
+ #
41
+ def save_one( name )
44
42
  ref = Gloo::Core::Pn.new name
45
43
  obj = ref.resolve
46
44
  pn = get_full_path_name name
47
45
  fs = Gloo::Persist::FileStorage.new( pn, obj )
48
46
  fs.save
49
47
  end
50
-
51
- #
48
+
49
+ #
52
50
  # Load the object from the file.
53
- #
54
- def load name
55
- pn = get_full_path_name name
56
- return unless pn
57
- $log.debug "Load file at: #{pn}"
58
- fs = Gloo::Persist::FileStorage.new( pn )
59
- fs.load
60
- @maps << fs
61
- $engine.event_manager.on_load fs.obj
62
- # show_maps
51
+ #
52
+ def load( name )
53
+ pns = get_full_path_names name
54
+ return unless pns
55
+
56
+ pns.each do |pn|
57
+ $log.debug "Load file(s) at: #{pn}"
58
+ fs = Gloo::Persist::FileStorage.new( pn )
59
+ fs.load
60
+ @maps << fs
61
+ $engine.event_manager.on_load fs.obj
62
+ end
63
63
  end
64
-
65
- #
64
+
65
+ #
66
66
  # Get the full path and name of the file.
67
- #
68
- def get_full_path_name name
67
+ #
68
+ def get_full_path_names( name )
69
69
  return nil if name.strip.empty?
70
- path = $settings.project_path
71
- full_name = "#{name}#{file_ext}"
72
- return File.join( path, full_name )
70
+
71
+ if name.strip[ -1 ] == '*'
72
+ pns = []
73
+ dir = File.join( $settings.project_path, name[ 0..-2 ] )
74
+ Dir.glob( "#{dir}*.gloo" ).each do |f|
75
+ pns << f
76
+ end
77
+ return pns
78
+ else
79
+ ext_path = File.expand_path( name )
80
+ return [ ext_path ] if self.gloo_file?( ext_path )
81
+
82
+ full_name = "#{name}#{file_ext}"
83
+ return [ File.join( $settings.project_path, full_name ) ]
84
+ end
73
85
  end
74
-
86
+
87
+ #
88
+ # Check to see if a given path name refers to a gloo object file.
89
+ #
90
+ def gloo_file?( name )
91
+ return false unless name
92
+ return false unless File.exist?( name )
93
+ return false unless File.file?( name )
94
+ return false unless name.end_with?( self.file_ext )
95
+
96
+ return true
97
+ end
98
+
75
99
  # Get the default file extention.
76
100
  def file_ext
77
- return ".gloo"
101
+ return '.gloo'
78
102
  end
79
-
103
+
80
104
  # Print out all object - persistance mappings.
81
105
  # This is a debugging tool.
82
106
  def show_maps
@@ -84,7 +108,7 @@ module Gloo
84
108
  puts " \t #{o.pn} \t #{o.obj.name}"
85
109
  end
86
110
  end
87
-
111
+
88
112
  end
89
113
  end
90
114
  end