gloo 6.0 → 6.1.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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +9 -3
  3. data/README.md +38 -7
  4. data/docs/application.md +164 -0
  5. data/docs/getting_started.md +112 -0
  6. data/docs/iterators.md +294 -0
  7. data/docs/language_objects.md +190 -0
  8. data/docs/language_scripting.md +62 -0
  9. data/docs/language_syntax.md +307 -0
  10. data/docs/objects.md +77 -0
  11. data/docs/operators.md +62 -0
  12. data/docs/plugins.md +54 -0
  13. data/docs/verbs.md +64 -0
  14. data/gloo.gemspec +5 -3
  15. data/lib/VERSION +1 -1
  16. data/lib/VERSION_NOTES +14 -0
  17. data/lib/gloo/app/platform.rb +29 -2
  18. data/lib/gloo/app/settings.rb +1 -1
  19. data/lib/gloo/core/gloo_system.rb +52 -1
  20. data/lib/gloo/docs/doc_data.rb +160 -0
  21. data/lib/gloo/docs/help_shell.rb +285 -0
  22. data/lib/gloo/docs/markdown_renderer.rb +39 -0
  23. data/lib/gloo/objs/basic/alias.rb +53 -0
  24. data/lib/gloo/objs/basic/boolean.rb +30 -0
  25. data/lib/gloo/objs/basic/container.rb +38 -0
  26. data/lib/gloo/objs/basic/decimal.rb +30 -0
  27. data/lib/gloo/objs/basic/integer.rb +58 -0
  28. data/lib/gloo/objs/basic/script.rb +31 -0
  29. data/lib/gloo/objs/basic/string.rb +51 -4
  30. data/lib/gloo/objs/basic/string_msgs.rb +20 -0
  31. data/lib/gloo/objs/basic/text.rb +51 -4
  32. data/lib/gloo/objs/basic/untyped.rb +21 -0
  33. data/lib/gloo/objs/ctrl/each.rb +63 -1
  34. data/lib/gloo/objs/ctrl/function.rb +69 -0
  35. data/lib/gloo/objs/ctrl/repeat.rb +41 -0
  36. data/lib/gloo/objs/dt/date.rb +43 -0
  37. data/lib/gloo/objs/dt/datetime.rb +50 -0
  38. data/lib/gloo/objs/dt/time.rb +43 -0
  39. data/lib/gloo/objs/str_utils/cipher.rb +59 -0
  40. data/lib/gloo/objs/str_utils/outline.rb +65 -1
  41. data/lib/gloo/objs/str_utils/password.rb +56 -0
  42. data/lib/gloo/objs/system/erb.rb +39 -0
  43. data/lib/gloo/objs/system/file_handle.rb +56 -0
  44. data/lib/gloo/objs/system/system.rb +29 -0
  45. data/lib/gloo/objs/web/http_get.rb +35 -0
  46. data/lib/gloo/objs/web/http_post.rb +33 -0
  47. data/lib/gloo/objs/web/json.rb +40 -0
  48. data/lib/gloo/objs/web/uri.rb +40 -0
  49. data/lib/gloo/shell/command_node.rb +39 -0
  50. data/lib/gloo/shell/context.rb +93 -0
  51. data/lib/gloo/shell/runner.rb +315 -0
  52. data/lib/gloo/verbs/break.rb +32 -0
  53. data/lib/gloo/verbs/check.rb +49 -0
  54. data/lib/gloo/verbs/cls.rb +18 -0
  55. data/lib/gloo/verbs/context.rb +47 -0
  56. data/lib/gloo/verbs/create.rb +42 -0
  57. data/lib/gloo/verbs/eval.rb +27 -0
  58. data/lib/gloo/verbs/execute.rb +27 -0
  59. data/lib/gloo/verbs/exists.rb +54 -2
  60. data/lib/gloo/verbs/files.rb +22 -0
  61. data/lib/gloo/verbs/help.rb +43 -178
  62. data/lib/gloo/verbs/if.rb +52 -0
  63. data/lib/gloo/verbs/invoke.rb +62 -0
  64. data/lib/gloo/verbs/list.rb +32 -0
  65. data/lib/gloo/verbs/load.rb +55 -2
  66. data/lib/gloo/verbs/log.rb +44 -0
  67. data/lib/gloo/verbs/move.rb +36 -1
  68. data/lib/gloo/verbs/put.rb +35 -0
  69. data/lib/gloo/verbs/quit.rb +19 -0
  70. data/lib/gloo/verbs/redirect.rb +52 -2
  71. data/lib/gloo/verbs/reload.rb +27 -0
  72. data/lib/gloo/verbs/run.rb +39 -0
  73. data/lib/gloo/verbs/save.rb +26 -0
  74. data/lib/gloo/verbs/show.rb +54 -0
  75. data/lib/gloo/verbs/tell.rb +32 -0
  76. data/lib/gloo/verbs/throw.rb +29 -0
  77. data/lib/gloo/verbs/unless.rb +50 -0
  78. data/lib/gloo/verbs/unload.rb +23 -0
  79. data/lib/gloo/verbs/version.rb +37 -3
  80. data/lib/gloo/verbs/wait.rb +26 -0
  81. metadata +28 -20
data/docs/plugins.md ADDED
@@ -0,0 +1,54 @@
1
+ # Plugins
2
+
3
+ **Contents**
4
+
5
+ - Core Libraries
6
+ - User Extensions
7
+
8
+ ## Core Libraries
9
+
10
+ Core Libraries extend gloo functionality, primarily by adding object types and potentially verbs.
11
+
12
+ Be sure to load a core library (or extension) prior to loading a gloo file that includes object types defined in the library.
13
+
14
+ Use the Load Verb to use an extension.
15
+
16
+ ### Available Core Libraries
17
+
18
+ - **CLI** — Use the `gloo-cli` gem when building CLI applications.
19
+ - Library Objects: Prompt, Colorize, Confirm, Select, Menu, Menu Item, Shell, Command
20
+ - **Database** — Use the `gloo-db` gem and one or more of `gloo-sqlite`, `gloo-mysql`, `gloo-pg` connector gems.
21
+ - Library Objects: Query, Table, SQLite, MySQL, Postgres
22
+ - **Email** — Use the `gloo-email` gem to send and receive email.
23
+ - Library Objects: Email, Email SMTP, Email IMAP
24
+ - **Markdown** — Use the `gloo-md` gem to render markdown.
25
+ - Library Objects: Markdown, MD Doc (a markdown file with YAML frontmatter), Markdown Extensions (part of the markdown object)
26
+ - **Test** — Use the `gloo-test` gem to manually include. See Test Runner for notes about the gloo test runner.
27
+ - Library Objects: Test
28
+ - Library Verbs: Assert, Refute
29
+ - See also: Eval, It
30
+ - **Web Server** — Use the `gloo-web` gem when building web applications.
31
+ - Library Objects: Server, Page, Partial, Form, Field, Element
32
+ - **YAML** — Use the `gloo-yaml` gem for YAML file read/write support.
33
+ - Library Objects: YAML
34
+
35
+ ## User Extensions
36
+
37
+ A User Extension is a mechanism that can be used to add verbs and objects that are not built into gloo.
38
+
39
+ Extensions are ruby code that live in the `extensions` folder inside the gloo root folder.
40
+
41
+ An extension is structured thus:
42
+
43
+ ```
44
+ ~/gloo/extensions/
45
+ /ext_name
46
+ /doc/
47
+ /src/
48
+ /test/
49
+ /ext_name.rb
50
+ ```
51
+
52
+ Be sure to load an extension (or core library) prior to loading a gloo file that includes object types defined in the extension.
53
+
54
+ Use the Load Verb to use an extension.
data/docs/verbs.md ADDED
@@ -0,0 +1,64 @@
1
+ # Verbs
2
+
3
+ Verbs are the commands that make up a gloo script — `put`, `show`, `run`, `tell`, and 25 others. Every statement in gloo starts with a verb.
4
+
5
+ Verbs aren't just for scripts, though. They're also the interactive language of the gloo application itself: run `gloo` in CLI mode (see Application, Running Gloo) and you can type these same verbs directly at the prompt, one at a time, in a REPL.
6
+
7
+ **Contents**
8
+
9
+ - Run
10
+ - Tell
11
+ - Put
12
+
13
+ This page walks through three of the most commonly used verbs to get a feel for how they work together. For the complete list of verbs, their full syntax, and every error they can raise, use the in-app help: enter `help` (or `?`), then `verbs` to list them all, or `verb {name}` for detail on one (see Application, Help).
14
+
15
+ ## Run
16
+
17
+ `run` runs a script or other runnable object — the same as sending it a `run` message.
18
+
19
+ ```gloo
20
+ run {path.to.object}
21
+ ```
22
+
23
+ ```gloo
24
+ > run my.script
25
+
26
+ > create s as script : "show 3 + 4"
27
+ > run s
28
+ ```
29
+
30
+ ## Tell
31
+
32
+ `tell` sends a message to an object, asking it to do something. Where `run` executes a runnable object, `tell` is the general-purpose way to invoke any message an object supports (`up`, `count`, `inc`, `randomize` — see Objects).
33
+
34
+ ```gloo
35
+ tell {path.to.object} to {message}
36
+ ```
37
+
38
+ ```gloo
39
+ > tell an.obj to unload
40
+ > tell the.script to run
41
+ > tell my.str to up
42
+ > tell the.container to count
43
+ ```
44
+
45
+ ## Put
46
+
47
+ `put` evaluates an expression and stores the result in an object.
48
+
49
+ ```gloo
50
+ put {expression} into {dst.path}
51
+ ```
52
+
53
+ ```gloo
54
+ > put 'one' into str
55
+ > put 123 into x
56
+ > put 3 + 5 into x
57
+ > put TRUE into flag
58
+ ```
59
+
60
+ `it` also picks up the result of the evaluation, same as with other verbs — see It.
61
+
62
+ ---
63
+
64
+ `run`, `tell`, and `put` cover a lot of ground on their own, but there are 26 more verbs — `show`, `if`, `create`, `each`, `check`, and so on — all documented in-app. Enter `help` (or `?`), then `verbs` to browse them. (This page itself is also viewable in-app: `help> doc verbs`.)
data/gloo.gemspec CHANGED
@@ -11,9 +11,11 @@ Gem::Specification.new do |spec|
11
11
 
12
12
  spec.summary = %q{Gloo scripting language. A scripting language built on ruby.}
13
13
  spec.description = %q{A scripting languge to keep it all together.}
14
- spec.homepage = "http://github.com/ecrane/gloo"
14
+ spec.homepage = "https://github.com/ecrane/gloo"
15
15
  spec.license = 'MIT'
16
16
 
17
+ spec.metadata['documentation_uri'] = 'https://github.com/ecrane/gloo'
18
+
17
19
  # Specify which files should be added to the gem when it is released.
18
20
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
21
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
@@ -33,10 +35,10 @@ Gem::Specification.new do |spec|
33
35
  spec.add_development_dependency 'bundler'
34
36
  spec.add_development_dependency 'minitest', '~> 5.1', '>= 5.14.2'
35
37
  spec.add_development_dependency "rake", '~> 13.0', '>= 13.0.1'
36
- spec.add_development_dependency 'concurrent-ruby', '1.3.4'
38
+ spec.add_development_dependency 'concurrent-ruby', '~> 1.3.7'
37
39
 
38
40
  # Used by many objects
39
- spec.add_dependency "activesupport", '~> 6.1', ">= 6.1.5"
41
+ spec.add_dependency "activesupport", '~> 7.2.3.1'
40
42
 
41
43
  # Used by date and time tools
42
44
  spec.add_dependency 'chronic', '~> 0.10', '>= 0.10.2'
data/lib/VERSION CHANGED
@@ -1 +1 @@
1
- 6.0
1
+ 6.1.0
data/lib/VERSION_NOTES CHANGED
@@ -1,3 +1,17 @@
1
+ 6.1.0 - 2026.08.04
2
+ - Adds narrative documentation: 10 pages in `docs/`, covering getting started, application, language objects/syntax/scripting, operators, iterators, objects, verbs, and plugins
3
+ - Adds an in-app interactive help shell (`help`/`?`) to look up verbs, objects, settings, libraries, extensions, and doc pages, with tab completion
4
+ - Adds `doc_data` to every verb and object type, in the interpreter and its core library gems, rendered by the help shell
5
+ - Fixes gemspecs so docs and READMEs are actually packaged with the gem and its core libraries
6
+ - Adds a table of contents and reading order to the README's documentation list
7
+ - Fixes the rubygems.org "Documentation" link
8
+ - Adds page message to string and text
9
+
10
+
11
+ 6.0.1 - 2026.07.16
12
+ - Update dependencies to newer versions for better security.
13
+
14
+
1
15
  6.0 - 2026.07.12
2
16
  - General code cleanup, additional tests added.
3
17
  - ERB object's template can now be an alias.
@@ -13,6 +13,9 @@ module Gloo
13
13
 
14
14
  DEFAULT_TMP_FILE = 'tmp.txt'.freeze
15
15
  RETURN = "\n".freeze
16
+ DEFAULT_LINES = 24
17
+ DEFAULT_COLS = 80
18
+ PAGER_CMD = 'less -R -F -X'.freeze
16
19
 
17
20
  attr_reader :prompt, :table
18
21
 
@@ -31,6 +34,22 @@ module Gloo
31
34
  puts msg
32
35
  end
33
36
 
37
+ #
38
+ # Show a message in a pager (less), for long content.
39
+ # Falls back to a plain puts when there is no real terminal
40
+ # to page in (piped output, captured test output, etc) or
41
+ # when less isn't available on the system.
42
+ #
43
+ def page( msg )
44
+ return show( msg ) unless $stdout.tty?
45
+
46
+ IO.popen( PAGER_CMD, 'w' ) { |less| less.puts msg }
47
+ rescue Errno::ENOENT
48
+ show( msg )
49
+ rescue Errno::EPIPE
50
+ # The user quit the pager early. Nothing more to do.
51
+ end
52
+
34
53
  #
35
54
  # Clear the screen.
36
55
  #
@@ -64,18 +83,26 @@ module Gloo
64
83
  # ---------------------------------------------------------------------
65
84
  #
66
85
  # Get the number of vertical lines on screen.
86
+ # Falls back to a default when stdout has no real screen behind it
87
+ # (piped/captured output, no controlling TTY, etc).
67
88
  #
68
89
  def lines
69
- rows, columns = $stdout.winsize
90
+ rows, _columns = $stdout.winsize
70
91
  return rows
92
+ rescue StandardError
93
+ return DEFAULT_LINES
71
94
  end
72
95
 
73
96
  #
74
97
  # Get the number of horizontal columns on screen.
98
+ # Falls back to a default when stdout has no real screen behind it
99
+ # (piped/captured output, no controlling TTY, etc).
75
100
  #
76
101
  def cols
77
- rows, columns = $stdout.winsize
102
+ _rows, columns = $stdout.winsize
78
103
  return columns
104
+ rescue StandardError
105
+ return DEFAULT_COLS
79
106
  end
80
107
 
81
108
  # ---------------------------------------------------------------------
@@ -34,7 +34,7 @@ module Gloo
34
34
  #
35
35
  def show
36
36
  puts "\n Application Settings:".blue
37
- puts ' Startup with: '.yellow + @start_with.white
37
+ puts ' Startup with: '.yellow + @start_with.to_s.white
38
38
  puts ' Indent in Listing: '.yellow + @list_indent.to_s.white
39
39
  puts ' List Levels: '.yellow + @list_levels.to_s.white
40
40
  puts ' Debug? '.yellow + @debug.to_s.white
@@ -278,13 +278,64 @@ module Gloo
278
278
  def self.open_for_platform
279
279
  return 'open' if OS.mac?
280
280
  return 'xdg-open' if OS.posix?
281
-
281
+
282
282
  return 'Start-Process' if OS.windows?
283
283
  return 'explorer.exe' if self.wsl?
284
284
 
285
285
  return nil
286
286
  end
287
287
 
288
+ # ---------------------------------------------------------------------
289
+ # Object Documentation
290
+ # ---------------------------------------------------------------------
291
+
292
+ #
293
+ # Get the object's documentation data.
294
+ #
295
+ def self.doc_data
296
+ {
297
+ :name => KEYWORD,
298
+ :shortcut => KEYWORD_SHORT,
299
+ :description => 'The gloo system objects are virtual objects — ' \
300
+ "accessed like other objects (via 'gloo' or the shortcut " \
301
+ '$), but their values are set by the system and cannot be ' \
302
+ 'updated. They also do not show up in the object heap. Some ' \
303
+ 'names include an underscore to separate words; a period ' \
304
+ 'can be used instead, so gloo.working_dir and ' \
305
+ 'gloo.working.dir are identical.',
306
+ :children => [
307
+ 'app — Path of the running app (same as gloo_projects).',
308
+ 'hostname — Get the system hostname.',
309
+ 'user — Get the logged in user.',
310
+ 'line — A carriage return (line feed) character.',
311
+ "user_home — Get the user's home directory.",
312
+ 'working_dir — Get the working directory.',
313
+ 'gloo_home — Get the gloo home directory.',
314
+ 'gloo_config — Get the gloo configuration directory.',
315
+ 'gloo_projects — Get the gloo projects directory.',
316
+ 'gloo_log — Get the gloo logging directory.',
317
+ 'screen_lines — Get the number of lines on screen.',
318
+ 'screen_cols — Get the number of columns on screen.',
319
+ 'platform_cpu — Get the platform CPU.',
320
+ 'platform_os — Get the platform operating system.',
321
+ 'platform_version — Get the platform version.',
322
+ 'platform_windows? — Is the platform Windows?',
323
+ 'platform_unix? — Is the platform Unix?',
324
+ 'platform_linux? — Is the platform Linux?',
325
+ 'platform_mac? — Is the platform Mac?'
326
+ ],
327
+ :examples => <<~EXAMPLES.strip
328
+ > show gloo.user
329
+ > show $.user
330
+
331
+ > show gloo.working_dir
332
+ > show gloo.working.dir
333
+ > show $.working_dir
334
+ > show $.working.dir
335
+ EXAMPLES
336
+ }
337
+ end
338
+
288
339
  end
289
340
  end
290
341
  end
@@ -0,0 +1,160 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2026 Eric Crane. All rights reserved.
3
+ #
4
+ # Documentation data for a primitive: a verb or an object.
5
+ #
6
+ # Renders as plain markdown - no color/ANSI here. Color is applied
7
+ # separately, at display time, by Gloo::Docs::MarkdownRenderer, so
8
+ # this stays reusable wherever the raw markdown is useful (paging,
9
+ # export, tests).
10
+ #
11
+
12
+ module Gloo
13
+ module Docs
14
+ class DocData
15
+
16
+ DESCRIPTION = '## Description'.freeze
17
+ SYNTAX = '## Syntax'.freeze
18
+ PARAMETERS = '## Parameters'.freeze
19
+ CHILDREN = '## Children'.freeze
20
+ MESSAGES = '## Messages'.freeze
21
+ RESULT = '## Result'.freeze
22
+ ERRORS = '## Errors'.freeze
23
+ EXAMPLES = '## Examples'.freeze
24
+ NOTES = '## Notes'.freeze
25
+ FENCE = '```gloo'.freeze
26
+
27
+ attr_accessor :name, :shortcut, :description, :syntax,
28
+ :parameters, :children, :messages, :result, :errors,
29
+ :examples, :notes
30
+
31
+ def initialize( value_hash )
32
+ @name = value_hash[:name]
33
+ @shortcut = value_hash[:shortcut]
34
+ @description = value_hash[:description]
35
+ @syntax = value_hash[:syntax]
36
+ @parameters = value_hash[:parameters]
37
+ @children = value_hash[:children]
38
+ @messages = value_hash[:messages]
39
+ @result = value_hash[:result]
40
+ @errors = value_hash[:errors]
41
+ @examples = value_hash[:examples]
42
+ @notes = value_hash[:notes]
43
+ end
44
+
45
+ #
46
+ # Render the documentation as a markdown string.
47
+ def render
48
+ buf = +''
49
+ add_name buf
50
+ add_description buf
51
+ add_syntax buf
52
+ add_parameters buf
53
+ add_children buf
54
+ add_messages buf
55
+ add_result buf
56
+ add_errors buf
57
+ add_examples buf
58
+ add_notes buf
59
+ buf << "\n"
60
+ return buf
61
+ end
62
+
63
+ #
64
+ # Show the documentation in the terminal.
65
+ def show_in_terminal
66
+ puts render
67
+ end
68
+
69
+ private
70
+
71
+ #
72
+ # Append the name and shortcut, if there is a name.
73
+ def add_name( buf )
74
+ return unless @name
75
+
76
+ buf << "\n# #{@name}\n"
77
+ buf << "#{@shortcut}\n" if @shortcut
78
+ end
79
+
80
+ #
81
+ # Append the description, if there is one.
82
+ def add_description( buf )
83
+ return unless @description
84
+
85
+ buf << "\n#{DESCRIPTION}\n#{@description}\n"
86
+ end
87
+
88
+ #
89
+ # Append the syntax lines, if there are any.
90
+ def add_syntax( buf )
91
+ return unless @syntax
92
+
93
+ buf << "\n#{SYNTAX}\n#{FENCE}\n"
94
+ @syntax.each { |line| buf << "#{line}\n" }
95
+ buf << "```\n"
96
+ end
97
+
98
+ #
99
+ # Append the parameter lines, if there are any.
100
+ def add_parameters( buf )
101
+ return unless @parameters
102
+
103
+ buf << "\n#{PARAMETERS}\n"
104
+ @parameters.each { |line| buf << "- #{line}\n" }
105
+ end
106
+
107
+ #
108
+ # Append the child lines, if there are any.
109
+ def add_children( buf )
110
+ return unless @children
111
+
112
+ buf << "\n#{CHILDREN}\n"
113
+ @children.each { |line| buf << "- #{line}\n" }
114
+ end
115
+
116
+ #
117
+ # Append the message lines, if there are any.
118
+ def add_messages( buf )
119
+ return unless @messages
120
+
121
+ buf << "\n#{MESSAGES}\n"
122
+ @messages.each { |line| buf << "- #{line}\n" }
123
+ end
124
+
125
+ #
126
+ # Append the result, if there is one.
127
+ def add_result( buf )
128
+ return unless @result
129
+
130
+ buf << "\n#{RESULT}\n#{@result}\n"
131
+ end
132
+
133
+ #
134
+ # Append the error lines, if there are any.
135
+ def add_errors( buf )
136
+ return unless @errors
137
+
138
+ buf << "\n#{ERRORS}\n"
139
+ @errors.each { |line| buf << "- #{line}\n" }
140
+ end
141
+
142
+ #
143
+ # Append the example code, if there is any.
144
+ def add_examples( buf )
145
+ return unless @examples
146
+
147
+ buf << "\n#{EXAMPLES}\n#{FENCE}\n#{@examples}\n```\n"
148
+ end
149
+
150
+ #
151
+ # Append the notes, if there are any.
152
+ def add_notes( buf )
153
+ return unless @notes
154
+
155
+ buf << "\n#{NOTES}\n#{@notes}\n"
156
+ end
157
+
158
+ end
159
+ end
160
+ end