gloo 0.3.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 +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +139 -0
- data/LICENSE.txt +21 -0
- data/README.md +43 -0
- data/Rakefile +12 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/gloo +4 -0
- data/exe/o +4 -0
- data/gloo.gemspec +38 -0
- data/lib/gloo.rb +19 -0
- data/lib/gloo/app/args.rb +71 -0
- data/lib/gloo/app/engine.rb +158 -0
- data/lib/gloo/app/help.rb +29 -0
- data/lib/gloo/app/info.rb +21 -0
- data/lib/gloo/app/log.rb +58 -0
- data/lib/gloo/app/mode.rb +25 -0
- data/lib/gloo/app/settings.rb +125 -0
- data/lib/gloo/core/baseo.rb +28 -0
- data/lib/gloo/core/dictionary.rb +101 -0
- data/lib/gloo/core/event_manager.rb +46 -0
- data/lib/gloo/core/factory.rb +67 -0
- data/lib/gloo/core/gloo_system.rb +190 -0
- data/lib/gloo/core/heap.rb +42 -0
- data/lib/gloo/core/it.rb +30 -0
- data/lib/gloo/core/literal.rb +25 -0
- data/lib/gloo/core/obj.rb +222 -0
- data/lib/gloo/core/obj_finder.rb +35 -0
- data/lib/gloo/core/op.rb +33 -0
- data/lib/gloo/core/parser.rb +52 -0
- data/lib/gloo/core/pn.rb +134 -0
- data/lib/gloo/core/script.rb +37 -0
- data/lib/gloo/core/tokens.rb +123 -0
- data/lib/gloo/core/verb.rb +63 -0
- data/lib/gloo/expr/expression.rb +103 -0
- data/lib/gloo/expr/l_boolean.rb +29 -0
- data/lib/gloo/expr/l_integer.rb +29 -0
- data/lib/gloo/expr/l_string.rb +53 -0
- data/lib/gloo/expr/op_div.rb +20 -0
- data/lib/gloo/expr/op_minus.rb +20 -0
- data/lib/gloo/expr/op_mult.rb +20 -0
- data/lib/gloo/expr/op_plus.rb +22 -0
- data/lib/gloo/objs/basic/boolean.rb +113 -0
- data/lib/gloo/objs/basic/container.rb +50 -0
- data/lib/gloo/objs/basic/integer.rb +65 -0
- data/lib/gloo/objs/basic/script.rb +101 -0
- data/lib/gloo/objs/basic/string.rb +65 -0
- data/lib/gloo/objs/basic/text.rb +64 -0
- data/lib/gloo/objs/basic/untyped.rb +42 -0
- data/lib/gloo/objs/cli/colorize.rb +73 -0
- data/lib/gloo/objs/cli/confirm.rb +92 -0
- data/lib/gloo/objs/cli/prompt.rb +92 -0
- data/lib/gloo/objs/ctrl/each.rb +212 -0
- data/lib/gloo/objs/dev/git.rb +112 -0
- data/lib/gloo/objs/ror/erb.rb +109 -0
- data/lib/gloo/objs/ror/eval.rb +92 -0
- data/lib/gloo/objs/system/file_handle.rb +86 -0
- data/lib/gloo/objs/system/system.rb +120 -0
- data/lib/gloo/objs/web/http_get.rb +128 -0
- data/lib/gloo/objs/web/http_post.rb +127 -0
- data/lib/gloo/objs/web/slack.rb +126 -0
- data/lib/gloo/objs/web/teams.rb +117 -0
- data/lib/gloo/persist/file_loader.rb +171 -0
- data/lib/gloo/persist/file_saver.rb +43 -0
- data/lib/gloo/persist/file_storage.rb +43 -0
- data/lib/gloo/persist/persist_man.rb +90 -0
- data/lib/gloo/utils/words.rb +19 -0
- data/lib/gloo/verbs/alert.rb +42 -0
- data/lib/gloo/verbs/context.rb +52 -0
- data/lib/gloo/verbs/create.rb +52 -0
- data/lib/gloo/verbs/help.rb +69 -0
- data/lib/gloo/verbs/if.rb +56 -0
- data/lib/gloo/verbs/list.rb +85 -0
- data/lib/gloo/verbs/load.rb +39 -0
- data/lib/gloo/verbs/put.rb +62 -0
- data/lib/gloo/verbs/quit.rb +40 -0
- data/lib/gloo/verbs/run.rb +46 -0
- data/lib/gloo/verbs/save.rb +37 -0
- data/lib/gloo/verbs/show.rb +55 -0
- data/lib/gloo/verbs/tell.rb +47 -0
- data/lib/gloo/verbs/unless.rb +56 -0
- data/lib/gloo/verbs/version.rb +37 -0
- data/lib/run.rb +13 -0
- metadata +254 -0
@@ -0,0 +1,171 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# Helper class used to load a file and create objects in the heap.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Gloo
|
8
|
+
module Persist
|
9
|
+
class FileLoader
|
10
|
+
|
11
|
+
BEGIN_BLOCK = "BEGIN"
|
12
|
+
END_BLOCK = "END"
|
13
|
+
|
14
|
+
attr_reader :obj
|
15
|
+
|
16
|
+
# Set up a file storage for an object.
|
17
|
+
def initialize pn
|
18
|
+
@pn = pn
|
19
|
+
@tabs = 0
|
20
|
+
@obj = nil
|
21
|
+
@in_multiline = false
|
22
|
+
@exiting_multiline = false
|
23
|
+
@in_block = false
|
24
|
+
@block_value = ""
|
25
|
+
@debug = false
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Load the objects from the file.
|
30
|
+
#
|
31
|
+
def load
|
32
|
+
unless File.exists?( @pn )
|
33
|
+
$log.error "File '#{@pn}' does not exist."
|
34
|
+
return
|
35
|
+
end
|
36
|
+
@tabs = 0
|
37
|
+
@parent_stack = []
|
38
|
+
@parent = $engine.heap.root
|
39
|
+
@parent_stack.push @parent
|
40
|
+
f = File.open( @pn, "r" )
|
41
|
+
f.each_line do |line|
|
42
|
+
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
|
54
|
+
else
|
55
|
+
determine_indent line
|
56
|
+
process_line line
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Is this line a comment or a blank line?
|
62
|
+
# If so we'll skip it.
|
63
|
+
def skip_line? line
|
64
|
+
line = line.strip
|
65
|
+
return true if line.empty?
|
66
|
+
return true if line[0] == "#"
|
67
|
+
return false
|
68
|
+
end
|
69
|
+
|
70
|
+
# Determine the relative indent level for the line.
|
71
|
+
def determine_indent line
|
72
|
+
tabs = tab_count( line )
|
73
|
+
@indent = 0 # same level as prior line
|
74
|
+
if tabs > @tabs # indent
|
75
|
+
# TODO: What if indent is more than one more level?
|
76
|
+
@tabs = tabs
|
77
|
+
@indent = 1
|
78
|
+
elsif tabs < @tabs # outdent
|
79
|
+
while tabs < @tabs
|
80
|
+
@tabs -= 1
|
81
|
+
@indent -= 1
|
82
|
+
end
|
83
|
+
end
|
84
|
+
puts "tabs: #{@tabs}, indent: #{@indent}, line: #{line}" if @debug
|
85
|
+
end
|
86
|
+
|
87
|
+
# Process one line and add objects.
|
88
|
+
def process_line line
|
89
|
+
# reset multiline unless we're actually indented
|
90
|
+
if @in_multiline && @multi_indent > @indent
|
91
|
+
puts "Done multiline mi: #{@multi_indent}, i: #{@indent}" if @debug
|
92
|
+
@in_multiline = false
|
93
|
+
@exiting_multiline = true
|
94
|
+
end
|
95
|
+
|
96
|
+
if @in_multiline
|
97
|
+
@last.add_line line
|
98
|
+
else
|
99
|
+
process_obj_line line
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Process one line and add objects.
|
104
|
+
def process_obj_line line
|
105
|
+
if @exiting_multiline
|
106
|
+
@exiting_multiline = false
|
107
|
+
elsif @indent > 0
|
108
|
+
@parent = @last
|
109
|
+
@parent_stack.push @parent
|
110
|
+
elsif @indent < 0
|
111
|
+
@indent.abs.times do
|
112
|
+
@parent_stack.pop
|
113
|
+
@parent = @parent_stack.last
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
name, type, value = split_line( line )
|
118
|
+
unless @block_value == ""
|
119
|
+
value = @block_value
|
120
|
+
@block_value = ""
|
121
|
+
end
|
122
|
+
@last = $engine.factory.create( name, type, value, @parent )
|
123
|
+
if @last && @last.has_multiline_value?
|
124
|
+
@multi_indent = 0
|
125
|
+
@in_multiline = true
|
126
|
+
puts "*** Start multiline. multi_indent: #{@multi_indent}" if @debug
|
127
|
+
end
|
128
|
+
|
129
|
+
@obj = @last if @obj.nil?
|
130
|
+
end
|
131
|
+
|
132
|
+
# Get the number of leading tabs.
|
133
|
+
def tab_count line
|
134
|
+
i = 0
|
135
|
+
while line[i] == "\t"
|
136
|
+
i += 1
|
137
|
+
end
|
138
|
+
return i
|
139
|
+
end
|
140
|
+
|
141
|
+
# 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
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# Helper class used to save an object to a file..
|
5
|
+
#
|
6
|
+
|
7
|
+
module Gloo
|
8
|
+
module Persist
|
9
|
+
class FileSaver
|
10
|
+
|
11
|
+
# Set up a file storage for an object.
|
12
|
+
def initialize pn, obj
|
13
|
+
@pn = pn
|
14
|
+
@obj = obj
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# Save the object to the file.
|
19
|
+
#
|
20
|
+
def save
|
21
|
+
data = get_obj( @obj )
|
22
|
+
File.write( @pn, data )
|
23
|
+
end
|
24
|
+
|
25
|
+
# Get string of tabs for indentation.
|
26
|
+
def tabs indent=0
|
27
|
+
return "\t" * indent
|
28
|
+
end
|
29
|
+
|
30
|
+
# Convert an object to textual representation.
|
31
|
+
# This is a recursive function.
|
32
|
+
def get_obj o, indent=0
|
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 )
|
37
|
+
end
|
38
|
+
return str
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# Helper class takes an object and writes it to a file.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Gloo
|
8
|
+
module Persist
|
9
|
+
class FileStorage
|
10
|
+
|
11
|
+
attr_reader :obj, :pn
|
12
|
+
|
13
|
+
# Set up a file storage for an object.
|
14
|
+
def initialize pn, obj=nil
|
15
|
+
@obj = obj
|
16
|
+
@pn = pn
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Save the object to the file.
|
21
|
+
#
|
22
|
+
def save
|
23
|
+
fs = FileSaver.new @pn, @obj
|
24
|
+
fs.save
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# Load the object from the file.
|
29
|
+
#
|
30
|
+
def load
|
31
|
+
fl = FileLoader.new @pn
|
32
|
+
fl.load
|
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
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# The persistance manager.
|
5
|
+
# Keeps a collection of object-file mappings, and then
|
6
|
+
# uses mappings to know how/where to save updated objects.
|
7
|
+
#
|
8
|
+
|
9
|
+
module Gloo
|
10
|
+
module Persist
|
11
|
+
class PersistMan
|
12
|
+
|
13
|
+
attr_reader :maps
|
14
|
+
|
15
|
+
# Contructor for the persistence manager.
|
16
|
+
def initialize
|
17
|
+
@maps = []
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Save one object to the file.
|
22
|
+
#
|
23
|
+
def save name=""
|
24
|
+
if name.nil? || name.strip.empty?
|
25
|
+
save_all
|
26
|
+
else
|
27
|
+
save_one name
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Save one object to the file.
|
33
|
+
#
|
34
|
+
def save_all
|
35
|
+
@maps.each do |o|
|
36
|
+
o.save
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Save one object to the file.
|
42
|
+
#
|
43
|
+
def save_one name
|
44
|
+
ref = Gloo::Core::Pn.new name
|
45
|
+
obj = ref.resolve
|
46
|
+
pn = get_full_path_name name
|
47
|
+
fs = Gloo::Persist::FileStorage.new( pn, obj )
|
48
|
+
fs.save
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# 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
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Get the full path and name of the file.
|
67
|
+
#
|
68
|
+
def get_full_path_name name
|
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 )
|
73
|
+
end
|
74
|
+
|
75
|
+
# Get the default file extention.
|
76
|
+
def file_ext
|
77
|
+
return ".gloo"
|
78
|
+
end
|
79
|
+
|
80
|
+
# Print out all object - persistance mappings.
|
81
|
+
# This is a debugging tool.
|
82
|
+
def show_maps
|
83
|
+
@maps.each do |o|
|
84
|
+
puts " \t #{o.pn} \t #{o.obj.name}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# Utilities related to words (strings).
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'active_support/inflector'
|
8
|
+
|
9
|
+
module Gloo
|
10
|
+
module Utils
|
11
|
+
class Words
|
12
|
+
|
13
|
+
def self.pluralize( word )
|
14
|
+
return word.pluralize
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# Show a system notification.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Gloo
|
8
|
+
module Verbs
|
9
|
+
class Alert < Gloo::Core::Verb
|
10
|
+
|
11
|
+
KEYWORD = 'alert'
|
12
|
+
KEYWORD_SHORT = '!'
|
13
|
+
|
14
|
+
#
|
15
|
+
# Run the verb.
|
16
|
+
#
|
17
|
+
def run
|
18
|
+
if @tokens.token_count > 1
|
19
|
+
expr = Gloo::Expr::Expression.new( @tokens.params )
|
20
|
+
result = expr.evaluate
|
21
|
+
$engine.heap.it.set_to result
|
22
|
+
system( '/usr/bin/osascript -e "display notification \"' + result.to_s + '\" with title \"OutlineScript\" "' )
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Get the Verb's keyword.
|
28
|
+
#
|
29
|
+
def self.keyword
|
30
|
+
return KEYWORD
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Get the Verb's keyword shortcut.
|
35
|
+
#
|
36
|
+
def self.keyword_shortcut
|
37
|
+
return KEYWORD_SHORT
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# Set the current context pointer.
|
5
|
+
# Alternatively if no value is provided, just show the context.
|
6
|
+
#
|
7
|
+
|
8
|
+
module Gloo
|
9
|
+
module Verbs
|
10
|
+
class Context < Gloo::Core::Verb
|
11
|
+
|
12
|
+
KEYWORD = 'context'
|
13
|
+
KEYWORD_SHORT = '@'
|
14
|
+
|
15
|
+
#
|
16
|
+
# Run the verb.
|
17
|
+
#
|
18
|
+
def run
|
19
|
+
if @tokens.token_count == 1
|
20
|
+
show_context
|
21
|
+
else
|
22
|
+
path = @tokens.second
|
23
|
+
$engine.heap.context.set_to path
|
24
|
+
$engine.heap.it.set_to path
|
25
|
+
$log.debug "Context set to #{$engine.heap.context}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Show the current context.
|
31
|
+
#
|
32
|
+
def show_context
|
33
|
+
$log.show "Context: #{$engine.heap.context}"
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Get the Verb's keyword.
|
38
|
+
#
|
39
|
+
def self.keyword
|
40
|
+
return KEYWORD
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Get the Verb's keyword shortcut.
|
45
|
+
#
|
46
|
+
def self.keyword_shortcut
|
47
|
+
return KEYWORD_SHORT
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|