gloo 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +73 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +3 -3
- data/Rakefile +6 -6
- data/bin/console +4 -4
- data/gloo.gemspec +19 -18
- data/lib/gloo.rb +6 -6
- data/lib/gloo/app/args.rb +30 -31
- data/lib/gloo/app/engine.rb +33 -28
- data/lib/gloo/app/help.rb +17 -11
- data/lib/gloo/app/info.rb +3 -3
- data/lib/gloo/app/log.rb +17 -17
- data/lib/gloo/app/mode.rb +4 -4
- data/lib/gloo/app/settings.rb +43 -40
- data/lib/gloo/core/baseo.rb +7 -7
- data/lib/gloo/core/dictionary.rb +30 -27
- data/lib/gloo/core/error.rb +50 -0
- data/lib/gloo/core/event_manager.rb +17 -19
- data/lib/gloo/core/factory.rb +92 -39
- data/lib/gloo/core/gloo_system.rb +49 -54
- data/lib/gloo/core/heap.rb +15 -13
- data/lib/gloo/core/it.rb +5 -5
- data/lib/gloo/core/literal.rb +7 -7
- data/lib/gloo/core/obj.rb +89 -79
- data/lib/gloo/core/obj_finder.rb +9 -14
- data/lib/gloo/core/op.rb +8 -8
- data/lib/gloo/core/parser.rb +25 -26
- data/lib/gloo/core/pn.rb +65 -50
- data/lib/gloo/core/runner.rb +26 -0
- data/lib/gloo/core/script.rb +7 -7
- data/lib/gloo/core/tokens.rb +39 -41
- data/lib/gloo/core/verb.rb +30 -19
- data/lib/gloo/expr/expression.rb +35 -43
- data/lib/gloo/expr/l_boolean.rb +7 -6
- data/lib/gloo/expr/l_integer.rb +5 -4
- data/lib/gloo/expr/l_string.rb +13 -15
- data/lib/gloo/expr/op_div.rb +3 -5
- data/lib/gloo/expr/op_minus.rb +3 -5
- data/lib/gloo/expr/op_mult.rb +3 -5
- data/lib/gloo/expr/op_plus.rb +5 -7
- data/lib/gloo/objs/basic/boolean.rb +63 -38
- data/lib/gloo/objs/basic/container.rb +40 -12
- data/lib/gloo/objs/basic/integer.rb +40 -16
- data/lib/gloo/objs/basic/script.rb +62 -38
- data/lib/gloo/objs/basic/string.rb +39 -15
- data/lib/gloo/objs/basic/text.rb +43 -20
- data/lib/gloo/objs/basic/untyped.rb +35 -10
- data/lib/gloo/objs/cli/colorize.rb +53 -23
- data/lib/gloo/objs/cli/confirm.rb +63 -29
- data/lib/gloo/objs/cli/prompt.rb +63 -29
- data/lib/gloo/objs/ctrl/each.rb +98 -60
- data/lib/gloo/objs/dev/git.rb +98 -64
- data/lib/gloo/objs/ror/erb.rb +81 -41
- data/lib/gloo/objs/ror/eval.rb +73 -31
- data/lib/gloo/objs/snd/play.rb +71 -0
- data/lib/gloo/objs/snd/say.rb +120 -0
- data/lib/gloo/objs/system/file_handle.rb +80 -48
- data/lib/gloo/objs/system/system.rb +84 -38
- data/lib/gloo/objs/web/http_get.rb +83 -46
- data/lib/gloo/objs/web/http_post.rb +69 -43
- data/lib/gloo/objs/web/slack.rb +89 -58
- data/lib/gloo/objs/web/teams.rb +88 -53
- data/lib/gloo/persist/file_loader.rb +81 -82
- data/lib/gloo/persist/file_saver.rb +12 -12
- data/lib/gloo/persist/file_storage.rb +15 -15
- data/lib/gloo/persist/line_splitter.rb +74 -0
- data/lib/gloo/persist/persist_man.rb +29 -29
- data/lib/gloo/utils/words.rb +2 -2
- data/lib/gloo/verbs/alert.rb +67 -16
- data/lib/gloo/verbs/beep.rb +70 -0
- data/lib/gloo/verbs/context.rb +61 -21
- data/lib/gloo/verbs/create.rb +52 -21
- data/lib/gloo/verbs/help.rb +177 -27
- data/lib/gloo/verbs/if.rb +54 -21
- data/lib/gloo/verbs/list.rb +55 -24
- data/lib/gloo/verbs/load.rb +46 -12
- data/lib/gloo/verbs/put.rb +90 -34
- data/lib/gloo/verbs/quit.rb +43 -12
- data/lib/gloo/verbs/run.rb +42 -11
- data/lib/gloo/verbs/save.rb +45 -10
- data/lib/gloo/verbs/show.rb +56 -22
- data/lib/gloo/verbs/tell.rb +44 -12
- data/lib/gloo/verbs/unless.rb +55 -21
- data/lib/gloo/verbs/version.rb +42 -12
- data/lib/run.rb +5 -5
- metadata +19 -12
@@ -7,29 +7,29 @@
|
|
7
7
|
module Gloo
|
8
8
|
module Persist
|
9
9
|
class FileLoader
|
10
|
-
|
11
|
-
BEGIN_BLOCK =
|
12
|
-
END_BLOCK =
|
13
|
-
|
10
|
+
|
11
|
+
BEGIN_BLOCK = 'BEGIN'.freeze
|
12
|
+
END_BLOCK = 'END'.freeze
|
13
|
+
|
14
14
|
attr_reader :obj
|
15
|
-
|
15
|
+
|
16
16
|
# Set up a file storage for an object.
|
17
|
-
def initialize pn
|
17
|
+
def initialize( pn )
|
18
18
|
@pn = pn
|
19
19
|
@tabs = 0
|
20
20
|
@obj = nil
|
21
21
|
@in_multiline = false
|
22
22
|
@exiting_multiline = false
|
23
23
|
@in_block = false
|
24
|
-
@block_value =
|
25
|
-
|
24
|
+
@block_value = ''
|
25
|
+
@debug = false
|
26
26
|
end
|
27
|
-
|
28
|
-
#
|
27
|
+
|
28
|
+
#
|
29
29
|
# Load the objects from the file.
|
30
|
-
#
|
30
|
+
#
|
31
31
|
def load
|
32
|
-
unless File.
|
32
|
+
unless File.exist?( @pn )
|
33
33
|
$log.error "File '#{@pn}' does not exist."
|
34
34
|
return
|
35
35
|
end
|
@@ -37,135 +37,134 @@ module Gloo
|
|
37
37
|
@parent_stack = []
|
38
38
|
@parent = $engine.heap.root
|
39
39
|
@parent_stack.push @parent
|
40
|
-
f = File.open( @pn,
|
40
|
+
f = File.open( @pn, 'r' )
|
41
41
|
f.each_line do |line|
|
42
42
|
next if skip_line? line
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
43
|
+
|
44
|
+
handle_one_line line
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# Process one one of the file we're loading.
|
50
|
+
#
|
51
|
+
def handle_one_line( line )
|
52
|
+
if line.strip.end_with? BEGIN_BLOCK
|
53
|
+
@in_block = true
|
54
|
+
@save_line = line
|
55
|
+
elsif @in_block
|
56
|
+
if line.strip == END_BLOCK
|
57
|
+
@in_block = false
|
58
|
+
determine_indent @save_line
|
59
|
+
process_line @save_line
|
54
60
|
else
|
55
|
-
|
56
|
-
process_line line
|
61
|
+
@block_value << line
|
57
62
|
end
|
63
|
+
else
|
64
|
+
determine_indent line
|
65
|
+
process_line line
|
58
66
|
end
|
59
67
|
end
|
60
|
-
|
68
|
+
|
61
69
|
# Is this line a comment or a blank line?
|
62
70
|
# If so we'll skip it.
|
63
|
-
def skip_line? line
|
71
|
+
def skip_line?( line )
|
64
72
|
line = line.strip
|
65
73
|
return true if line.empty?
|
66
|
-
return true if line[0] ==
|
74
|
+
return true if line[ 0 ] == '#'
|
75
|
+
|
67
76
|
return false
|
68
77
|
end
|
69
|
-
|
78
|
+
|
70
79
|
# Determine the relative indent level for the line.
|
71
|
-
def determine_indent line
|
80
|
+
def determine_indent( line )
|
72
81
|
tabs = tab_count( line )
|
73
|
-
@indent = 0
|
74
|
-
if tabs > @tabs
|
82
|
+
@indent = 0 # same level as prior line
|
83
|
+
if tabs > @tabs # indent
|
75
84
|
# TODO: What if indent is more than one more level?
|
76
85
|
@tabs = tabs
|
77
86
|
@indent = 1
|
78
|
-
elsif tabs < @tabs
|
87
|
+
elsif tabs < @tabs # outdent
|
79
88
|
while tabs < @tabs
|
80
89
|
@tabs -= 1
|
81
90
|
@indent -= 1
|
82
91
|
end
|
83
92
|
end
|
84
|
-
|
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
|
-
|
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
|
-
#
|
104
|
-
|
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
|
119
|
+
elsif @indent.positive?
|
108
120
|
@parent = @last
|
109
121
|
@parent_stack.push @parent
|
110
|
-
elsif @indent
|
122
|
+
elsif @indent.negative?
|
111
123
|
@indent.abs.times do
|
112
124
|
@parent_stack.pop
|
113
125
|
@parent = @parent_stack.last
|
114
126
|
end
|
115
127
|
end
|
116
|
-
|
128
|
+
end
|
129
|
+
|
130
|
+
#
|
131
|
+
# Process one line and add objects.
|
132
|
+
#
|
133
|
+
def process_obj_line( line )
|
117
134
|
name, type, value = split_line( line )
|
118
|
-
unless @block_value ==
|
135
|
+
unless @block_value == ''
|
119
136
|
value = @block_value
|
120
|
-
@block_value =
|
137
|
+
@block_value = ''
|
121
138
|
end
|
122
|
-
|
123
|
-
|
139
|
+
params = { name: name, type: type, value: value, parent: @parent }
|
140
|
+
@last = $engine.factory.create( params )
|
141
|
+
|
142
|
+
if @last&.multiline_value?
|
124
143
|
@multi_indent = 0
|
125
144
|
@in_multiline = true
|
126
|
-
|
145
|
+
puts "*** Start multiline. multi_indent: #{@multi_indent}" if @debug
|
127
146
|
end
|
128
|
-
|
147
|
+
|
129
148
|
@obj = @last if @obj.nil?
|
130
149
|
end
|
131
|
-
|
150
|
+
|
151
|
+
#
|
132
152
|
# Get the number of leading tabs.
|
133
|
-
|
153
|
+
#
|
154
|
+
def tab_count( line )
|
134
155
|
i = 0
|
135
|
-
while line[i] == "\t"
|
136
|
-
i += 1
|
137
|
-
end
|
156
|
+
i += 1 while line[ i ] == "\t"
|
138
157
|
return i
|
139
158
|
end
|
140
|
-
|
159
|
+
|
160
|
+
#
|
141
161
|
# Split the line into 3 parts.
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
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
|
162
|
+
#
|
163
|
+
def split_line( line )
|
164
|
+
o = LineSplitter.new( line, @tabs )
|
165
|
+
return o.split
|
167
166
|
end
|
168
|
-
|
167
|
+
|
169
168
|
end
|
170
169
|
end
|
171
170
|
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
|
32
|
+
def get_obj( obj, indent = 0 )
|
33
33
|
t = tabs( indent )
|
34
|
-
str = "#{t}#{
|
35
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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,74 @@
|
|
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[ @tabs..-1 ]
|
39
|
+
@line = @line[ 0..-2 ] if @line[ -1 ] == "\n"
|
40
|
+
@idx = @line.index( ' ' )
|
41
|
+
@name = @line[ 0..@idx - 1 ]
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Detect the object type.
|
46
|
+
#
|
47
|
+
def detect_type
|
48
|
+
@line = @line[ @idx + 1..-1 ]
|
49
|
+
@idx = @line.index( ' ' )
|
50
|
+
@type = @line[ 0..( @idx ? @idx - 1 : -1 ) ]
|
51
|
+
@type = @type[ 1..-1 ] if @type[ 0 ] == '['
|
52
|
+
@type = @type[ 0..-2 ] if @type[ -1 ] == ']'
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Detect the object value.
|
57
|
+
# Use nil if there is no value specified.
|
58
|
+
#
|
59
|
+
def detect_value
|
60
|
+
if @idx
|
61
|
+
@value = @line[ @idx + 1..-1 ]
|
62
|
+
if @value[ 0..1 ] == ': '
|
63
|
+
@value = @value[ 2..-1 ]
|
64
|
+
elsif @value[ 0 ] == ':'
|
65
|
+
@value = @value[ 1..-1 ]
|
66
|
+
end
|
67
|
+
else
|
68
|
+
@value = nil
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -9,74 +9,74 @@
|
|
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
|
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
|
51
|
+
#
|
52
|
+
def load( name )
|
55
53
|
pn = get_full_path_name name
|
56
54
|
return unless pn
|
57
|
-
|
55
|
+
|
56
|
+
$log.debug "Load file at: #{pn}"
|
58
57
|
fs = Gloo::Persist::FileStorage.new( pn )
|
59
58
|
fs.load
|
60
59
|
@maps << fs
|
61
60
|
$engine.event_manager.on_load fs.obj
|
62
61
|
# show_maps
|
63
62
|
end
|
64
|
-
|
65
|
-
#
|
63
|
+
|
64
|
+
#
|
66
65
|
# Get the full path and name of the file.
|
67
|
-
#
|
68
|
-
def get_full_path_name name
|
66
|
+
#
|
67
|
+
def get_full_path_name( name )
|
69
68
|
return nil if name.strip.empty?
|
69
|
+
|
70
70
|
path = $settings.project_path
|
71
71
|
full_name = "#{name}#{file_ext}"
|
72
72
|
return File.join( path, full_name )
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
# Get the default file extention.
|
76
76
|
def file_ext
|
77
|
-
return
|
77
|
+
return '.gloo'
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
# Print out all object - persistance mappings.
|
81
81
|
# This is a debugging tool.
|
82
82
|
def show_maps
|
@@ -84,7 +84,7 @@ module Gloo
|
|
84
84
|
puts " \t #{o.pn} \t #{o.obj.name}"
|
85
85
|
end
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|