rbcli 0.3.3 → 0.4.1
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/LICENSE.md +9 -0
- data/LICENSE.txt +5 -670
- data/README.md +64 -160
- data/VERSION +1 -0
- data/exe/rbcli +181 -242
- data/lib/rbcli/components/commands/command.rb +120 -0
- data/lib/rbcli/components/commands/command.rb.erb +55 -0
- data/lib/rbcli/components/commands/command_old.rb +105 -0
- data/lib/rbcli/components/commands/script.rb.erb +43 -0
- data/{lib-sh → lib/rbcli/components/commands/scriptwrapper}/lib-rbcli.sh +29 -34
- data/lib/rbcli/components/commands/scriptwrapper/scriptwrapper.rb +64 -0
- data/lib/rbcli/components/config/backend.rb +104 -0
- data/lib/rbcli/components/config/backends/env.rb +63 -0
- data/lib/rbcli/components/config/backends/helpers/deep_assign.rb +47 -0
- data/lib/rbcli/components/config/backends/ini.rb +53 -0
- data/lib/rbcli/components/config/backends/json.rb +31 -0
- data/lib/rbcli/components/config/backends/null.rb +28 -0
- data/lib/rbcli/components/config/backends/toml.rb +37 -0
- data/lib/rbcli/components/config/backends/yaml.rb +31 -0
- data/lib/rbcli/components/config/component.rb +28 -0
- data/lib/rbcli/components/config/config.rb +110 -0
- data/lib/rbcli/components/config/config_of_death.rb +12 -0
- data/lib/rbcli/components/config/template.rb.erb +34 -0
- data/lib/rbcli/components/core/configurate.rb +63 -0
- data/lib/rbcli/components/core/engine.rb +30 -0
- data/lib/rbcli/components/core/warehouse.rb +18 -0
- data/lib/rbcli/components/envvars/component.rb +20 -0
- data/lib/rbcli/components/envvars/template.rb.erb +24 -0
- data/lib/rbcli/components/hooks/component.rb +36 -0
- data/lib/rbcli/components/hooks/template.rb.erb +20 -0
- data/lib/rbcli/components/logger/component.rb +32 -0
- data/lib/rbcli/components/logger/logger.rb +155 -0
- data/lib/rbcli/components/logger/lolcat/lol.rb +71 -0
- data/lib/rbcli/components/logger/template.rb.erb +40 -0
- data/lib/rbcli/components/parser/component.rb +34 -0
- data/lib/rbcli/{util → components/parser/optimist}/optimist.rb +134 -48
- data/lib/rbcli/components/parser/parser.rb +179 -0
- data/lib/rbcli/components/parser/template.rb.erb +36 -0
- data/lib/rbcli/components/updatechecker/common/common.rb +52 -0
- data/lib/rbcli/components/updatechecker/component.rb +42 -0
- data/lib/rbcli/components/updatechecker/gem_checker.rb +40 -0
- data/lib/rbcli/components/updatechecker/github_checker.rb +46 -0
- data/lib/rbcli/components/updatechecker/template.rb.erb +14 -0
- data/lib/rbcli/util/deprecation_warning.rb +41 -55
- data/lib/rbcli/util/errors.rb +12 -0
- data/lib/rbcli/util/exit.rb +12 -0
- data/lib/rbcli/util/hash_deep_symbolize.rb +50 -41
- data/lib/rbcli/util/string_compression.rb +10 -0
- data/lib/rbcli/version.rb +5 -20
- data/lib/rbcli-tool/helpers.rb +58 -0
- data/lib/rbcli-tool/skeletons/gem.rb.erb +17 -0
- data/lib/rbcli-tool/skeletons/portable.rb.erb +48 -0
- data/lib/rbcli.rb +19 -50
- data/sig/rbcli.rbs +9 -0
- metadata +124 -496
- data/.gitignore +0 -60
- data/.rakeTasks +0 -7
- data/.rbenv-gemsets +0 -1
- data/.travis.yml +0 -5
- data/CHANGELOG.md +0 -193
- data/CODE_OF_CONDUCT.md +0 -74
- data/Gemfile +0 -6
- data/Gemfile.lock +0 -92
- data/Rakefile +0 -10
- data/bin/console +0 -33
- data/bin/setup +0 -28
- data/docs/404.html +0 -59
- data/docs/advanced/automatic_updates/index.html +0 -1174
- data/docs/advanced/command_types/index.html +0 -1262
- data/docs/advanced/distributed_state_locking/index.html +0 -1176
- data/docs/advanced/hooks/index.html +0 -1192
- data/docs/advanced/index.html +0 -1140
- data/docs/advanced/index.xml +0 -75
- data/docs/advanced/interactive_commands/index.html +0 -1177
- data/docs/advanced/logging/index.html +0 -1184
- data/docs/advanced/remote_execution/index.html +0 -1190
- data/docs/advanced/state_storage/index.html +0 -1281
- data/docs/advanced/user_config_files/index.html +0 -1209
- data/docs/categories/index.html +0 -1146
- data/docs/categories/index.xml +0 -11
- data/docs/css/atom-one-dark-reasonable.css +0 -77
- data/docs/css/auto-complete.css +0 -47
- data/docs/css/featherlight.min.css +0 -8
- data/docs/css/fontawesome-all.min.css +0 -1
- data/docs/css/hugo-theme.css +0 -254
- data/docs/css/hybrid.css +0 -102
- data/docs/css/nucleus.css +0 -615
- data/docs/css/perfect-scrollbar.min.css +0 -2
- data/docs/css/tags.css +0 -49
- data/docs/css/theme-blue.css +0 -111
- data/docs/css/theme-green.css +0 -111
- data/docs/css/theme-red.css +0 -111
- data/docs/css/theme.css +0 -1136
- data/docs/development/changelog/index.html +0 -1420
- data/docs/development/code_of_conduct/index.html +0 -1222
- data/docs/development/contributing/index.html +0 -1201
- data/docs/development/index.html +0 -1140
- data/docs/development/index.xml +0 -40
- data/docs/development/license/index.html +0 -1165
- data/docs/fonts/Inconsolata.eot +0 -0
- data/docs/fonts/Inconsolata.svg +0 -1
- data/docs/fonts/Inconsolata.ttf +0 -0
- data/docs/fonts/Inconsolata.woff +0 -0
- data/docs/fonts/Novecentosanswide-Normal-webfont.eot +0 -0
- data/docs/fonts/Novecentosanswide-Normal-webfont.svg +0 -1
- data/docs/fonts/Novecentosanswide-Normal-webfont.ttf +0 -0
- data/docs/fonts/Novecentosanswide-Normal-webfont.woff +0 -0
- data/docs/fonts/Novecentosanswide-Normal-webfont.woff2 +0 -0
- data/docs/fonts/Novecentosanswide-UltraLight-webfont.eot +0 -0
- data/docs/fonts/Novecentosanswide-UltraLight-webfont.svg +0 -1
- data/docs/fonts/Novecentosanswide-UltraLight-webfont.ttf +0 -0
- data/docs/fonts/Novecentosanswide-UltraLight-webfont.woff +0 -0
- data/docs/fonts/Novecentosanswide-UltraLight-webfont.woff2 +0 -0
- data/docs/fonts/Work_Sans_200.eot +0 -0
- data/docs/fonts/Work_Sans_200.svg +0 -1
- data/docs/fonts/Work_Sans_200.ttf +0 -0
- data/docs/fonts/Work_Sans_200.woff +0 -0
- data/docs/fonts/Work_Sans_200.woff2 +0 -0
- data/docs/fonts/Work_Sans_300.eot +0 -0
- data/docs/fonts/Work_Sans_300.svg +0 -1
- data/docs/fonts/Work_Sans_300.ttf +0 -0
- data/docs/fonts/Work_Sans_300.woff +0 -0
- data/docs/fonts/Work_Sans_300.woff2 +0 -0
- data/docs/fonts/Work_Sans_500.eot +0 -0
- data/docs/fonts/Work_Sans_500.svg +0 -1
- data/docs/fonts/Work_Sans_500.ttf +0 -0
- data/docs/fonts/Work_Sans_500.woff +0 -0
- data/docs/fonts/Work_Sans_500.woff2 +0 -0
- data/docs/images/clippy.svg +0 -1
- data/docs/images/favicon.png +0 -0
- data/docs/images/gopher-404.jpg +0 -0
- data/docs/imported/changelog/index.html +0 -1449
- data/docs/imported/index.html +0 -1191
- data/docs/imported/index.xml +0 -23
- data/docs/index.html +0 -1138
- data/docs/index.json +0 -183
- data/docs/index.xml +0 -138
- data/docs/js/auto-complete.js +0 -3
- data/docs/js/clipboard.min.js +0 -7
- data/docs/js/featherlight.min.js +0 -9
- data/docs/js/highlight.pack.js +0 -6
- data/docs/js/html5shiv-printshiv.min.js +0 -4
- data/docs/js/hugo-learn.js +0 -94
- data/docs/js/jquery-3.3.1.min.js +0 -2
- data/docs/js/jquery.sticky.js +0 -288
- data/docs/js/learn.js +0 -459
- data/docs/js/lunr.min.js +0 -6
- data/docs/js/modernizr.custom-3.6.0.js +0 -3
- data/docs/js/perfect-scrollbar.jquery.min.js +0 -2
- data/docs/js/perfect-scrollbar.min.js +0 -2
- data/docs/js/search.js +0 -93
- data/docs/mermaid/mermaid.css +0 -277
- data/docs/mermaid/mermaid.dark.css +0 -278
- data/docs/mermaid/mermaid.forest.css +0 -356
- data/docs/mermaid/mermaid.js +0 -8
- data/docs/quick_reference/index.html +0 -1246
- data/docs/quick_reference/index.xml +0 -12
- data/docs/sitemap.xml +0 -81
- data/docs/tags/index.html +0 -1146
- data/docs/tags/index.xml +0 -11
- data/docs/tutorial/10-getting_started/index.html +0 -1174
- data/docs/tutorial/20-project_layout/index.html +0 -1299
- data/docs/tutorial/30-your_first_command/index.html +0 -1263
- data/docs/tutorial/40-options_parameters_and_arguments/index.html +0 -1384
- data/docs/tutorial/50-publishing/index.html +0 -1187
- data/docs/tutorial/index.html +0 -1140
- data/docs/tutorial/index.xml +0 -47
- data/docs/webfonts/fa-brands-400.eot +0 -0
- data/docs/webfonts/fa-brands-400.svg +0 -1
- data/docs/webfonts/fa-brands-400.ttf +0 -0
- data/docs/webfonts/fa-brands-400.woff +0 -0
- data/docs/webfonts/fa-brands-400.woff2 +0 -0
- data/docs/webfonts/fa-regular-400.eot +0 -0
- data/docs/webfonts/fa-regular-400.svg +0 -1
- data/docs/webfonts/fa-regular-400.ttf +0 -0
- data/docs/webfonts/fa-regular-400.woff +0 -0
- data/docs/webfonts/fa-regular-400.woff2 +0 -0
- data/docs/webfonts/fa-solid-900.eot +0 -0
- data/docs/webfonts/fa-solid-900.svg +0 -1
- data/docs/webfonts/fa-solid-900.ttf +0 -0
- data/docs/webfonts/fa-solid-900.woff +0 -0
- data/docs/webfonts/fa-solid-900.woff2 +0 -0
- data/docs/whoami/index.html +0 -1155
- data/docs/whoami/index.xml +0 -12
- data/docs-src/archetypes/default.md +0 -6
- data/docs-src/config.toml +0 -37
- data/docs-src/content/_index.md +0 -40
- data/docs-src/content/advanced/_index.md +0 -11
- data/docs-src/content/advanced/automatic_updates.md +0 -46
- data/docs-src/content/advanced/command_types.md +0 -148
- data/docs-src/content/advanced/distributed_state_locking.md +0 -37
- data/docs-src/content/advanced/hooks.md +0 -69
- data/docs-src/content/advanced/interactive_commands.md +0 -41
- data/docs-src/content/advanced/logging.md +0 -39
- data/docs-src/content/advanced/remote_execution.md +0 -60
- data/docs-src/content/advanced/state_storage.md +0 -120
- data/docs-src/content/advanced/user_config_files.md +0 -51
- data/docs-src/content/development/_index.md +0 -11
- data/docs-src/content/development/changelog.md +0 -199
- data/docs-src/content/development/code_of_conduct.md +0 -81
- data/docs-src/content/development/contributing.md +0 -88
- data/docs-src/content/development/license.md +0 -17
- data/docs-src/content/quick_reference/_index.md +0 -180
- data/docs-src/content/tutorial/10-getting_started.md +0 -47
- data/docs-src/content/tutorial/20-project_layout.md +0 -123
- data/docs-src/content/tutorial/30-your_first_command.md +0 -132
- data/docs-src/content/tutorial/40-options_parameters_and_arguments.md +0 -282
- data/docs-src/content/tutorial/50-publishing.md +0 -53
- data/docs-src/content/tutorial/_index.md +0 -11
- data/docs-src/content/whoami/_index.md +0 -34
- data/docs-src/layouts/partials/logo.html +0 -3
- data/docs-src/makesite.sh +0 -40
- data/docs-src/mkdocs-archived.tar.gz +0 -0
- data/docs-src/runsite.sh +0 -8
- data/docs-src/themes/hugo-theme-learn/.editorconfig +0 -16
- data/docs-src/themes/hugo-theme-learn/.gitignore +0 -3
- data/docs-src/themes/hugo-theme-learn/.grenrc.yml +0 -25
- data/docs-src/themes/hugo-theme-learn/CHANGELOG.md +0 -226
- data/docs-src/themes/hugo-theme-learn/LICENSE.md +0 -22
- data/docs-src/themes/hugo-theme-learn/README.md +0 -97
- data/docs-src/themes/hugo-theme-learn/archetypes/chapter.md +0 -13
- data/docs-src/themes/hugo-theme-learn/archetypes/default.md +0 -7
- data/docs-src/themes/hugo-theme-learn/exampleSite/LICENSE.md +0 -20
- data/docs-src/themes/hugo-theme-learn/exampleSite/config.toml +0 -102
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/_index.en.md +0 -41
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/_index.fr.md +0 -43
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/_index.en.md +0 -12
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/_index.fr.md +0 -12
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/_index.zh.md +0 -12
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/configuration/_index.en.md +0 -60
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/configuration/_index.fr.md +0 -56
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/installation/_index.en.md +0 -102
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/installation/_index.fr.md +0 -100
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/installation/images/chapter.png +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/requirements/_index.en.md +0 -11
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/requirements/_index.fr.md +0 -11
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/requirements/images/magic.gif +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/_index.en.md +0 -194
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/_index.fr.md +0 -194
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/images/blue-variant.png +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/images/green-variant.png +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/images/red-variant.png +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/_index.en.md +0 -12
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/_index.fr.md +0 -12
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/archetypes.en.md +0 -57
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/archetypes.fr.md +0 -57
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/i18n/_index.en.md +0 -78
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/i18n/_index.fr.md +0 -78
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/i18n/images/i18n-menu.gif +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/icons.en.md +0 -41
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/markdown.en.md +0 -692
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/markdown.fr.md +0 -666
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/menushortcuts.en.md +0 -109
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/menushortcuts.fr.md +0 -109
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/_index.en.md +0 -166
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/_index.fr.md +0 -146
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/images/frontmatter-icon.png +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/images/pages-chapter.png +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/images/pages-default.png +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/syntaxhighlight.en.md +0 -89
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/tags.en.md +0 -39
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/tags.fr.md +0 -40
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/credits.en.md +0 -28
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/credits.fr.md +0 -28
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/_index.en.md +0 -16
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/_index.fr.md +0 -16
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/BachGavotteShort.mp3 +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/Carroll_AliceAuPaysDesMerveilles.pdf +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/adivorciarsetoca00cape.pdf +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/hugo.png +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/movieselectricsheep-flock-244-32500-2.mp4 +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.md +0 -85
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/BachGavotteShort.mp3 +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/Carroll_AliceAuPaysDesMerveilles.pdf +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/adivorciarsetoca00cape.pdf +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/hugo.png +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/movieselectricsheep-flock-244-32500-2.mp4 +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.md +0 -85
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/button.en.md +0 -16
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/button.fr.md +0 -16
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/_index.en.md +0 -45
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/_index.fr.md +0 -45
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/_index.en.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/_index.fr.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/_index.en.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/_index.fr.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/_index.en.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/_index.fr.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/children-1-1-1-1/_index.en.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/children-1-1-1-1/_index.fr.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/children-1-1-1-1/children-1-1-1-1-1/_index.en.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/children-1-1-1-1/children-1-1-1-1-1/_index.fr.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-2/_index.en.md +0 -11
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-2/_index.fr.md +0 -11
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-2/test3.en.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-2/test3.fr.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-3/_index.en.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-3/_index.fr.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-4/_index.en.md +0 -7
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-4/_index.fr.md +0 -7
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/test.en.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/test.fr.md +0 -6
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/expand.en.md +0 -45
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/expand.fr.md +0 -45
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/mermaid.en.md +0 -283
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/mermaid.fr.md +0 -283
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/notice.en.md +0 -62
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/notice.fr.md +0 -62
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/siteparam.en.md +0 -23
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/siteparam.fr.md +0 -23
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/showcase.en.md +0 -13
- data/docs-src/themes/hugo-theme-learn/exampleSite/content/showcase.fr.md +0 -14
- data/docs-src/themes/hugo-theme-learn/exampleSite/layouts/partials/custom-footer.html +0 -10
- data/docs-src/themes/hugo-theme-learn/exampleSite/layouts/partials/logo.html +0 -39
- data/docs-src/themes/hugo-theme-learn/exampleSite/layouts/partials/menu-footer.html +0 -14
- data/docs-src/themes/hugo-theme-learn/exampleSite/layouts/shortcodes/ghcontributors.html +0 -31
- data/docs-src/themes/hugo-theme-learn/exampleSite/static/css/theme-mine.css +0 -104
- data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.eot +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.svg +0 -1
- data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.ttf +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.woff +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.woff2 +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/static/images/showcase/inteliver_docs.png +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/static/images/showcase/tat.png +0 -0
- data/docs-src/themes/hugo-theme-learn/exampleSite/static/images/showcase/tshark_dev.png +0 -0
- data/docs-src/themes/hugo-theme-learn/i18n/ar.toml +0 -26
- data/docs-src/themes/hugo-theme-learn/i18n/de.toml +0 -26
- data/docs-src/themes/hugo-theme-learn/i18n/en.toml +0 -26
- data/docs-src/themes/hugo-theme-learn/i18n/es.toml +0 -26
- data/docs-src/themes/hugo-theme-learn/i18n/fr.toml +0 -26
- data/docs-src/themes/hugo-theme-learn/i18n/hi.toml +0 -26
- data/docs-src/themes/hugo-theme-learn/i18n/id.toml +0 -26
- data/docs-src/themes/hugo-theme-learn/i18n/ja.toml +0 -26
- data/docs-src/themes/hugo-theme-learn/i18n/nl.toml +0 -26
- data/docs-src/themes/hugo-theme-learn/i18n/pt.toml +0 -26
- data/docs-src/themes/hugo-theme-learn/i18n/ru.toml +0 -26
- data/docs-src/themes/hugo-theme-learn/i18n/tr.toml +0 -26
- data/docs-src/themes/hugo-theme-learn/i18n/zh-cn.toml +0 -26
- data/docs-src/themes/hugo-theme-learn/images/screenshot.png +0 -0
- data/docs-src/themes/hugo-theme-learn/images/tn.png +0 -0
- data/docs-src/themes/hugo-theme-learn/layouts/404.html +0 -56
- data/docs-src/themes/hugo-theme-learn/layouts/_default/list.html +0 -22
- data/docs-src/themes/hugo-theme-learn/layouts/_default/single.html +0 -12
- data/docs-src/themes/hugo-theme-learn/layouts/index.html +0 -31
- data/docs-src/themes/hugo-theme-learn/layouts/index.json +0 -12
- data/docs-src/themes/hugo-theme-learn/layouts/partials/custom-comments.html +0 -3
- data/docs-src/themes/hugo-theme-learn/layouts/partials/custom-footer.html +0 -5
- data/docs-src/themes/hugo-theme-learn/layouts/partials/custom-header.html +0 -5
- data/docs-src/themes/hugo-theme-learn/layouts/partials/favicon.html +0 -1
- data/docs-src/themes/hugo-theme-learn/layouts/partials/footer.html +0 -77
- data/docs-src/themes/hugo-theme-learn/layouts/partials/header.html +0 -111
- data/docs-src/themes/hugo-theme-learn/layouts/partials/logo.html +0 -19
- data/docs-src/themes/hugo-theme-learn/layouts/partials/menu-footer.html +0 -1
- data/docs-src/themes/hugo-theme-learn/layouts/partials/menu.html +0 -151
- data/docs-src/themes/hugo-theme-learn/layouts/partials/meta.html +0 -2
- data/docs-src/themes/hugo-theme-learn/layouts/partials/search.html +0 -16
- data/docs-src/themes/hugo-theme-learn/layouts/partials/tags.html +0 -7
- data/docs-src/themes/hugo-theme-learn/layouts/partials/toc.html +0 -5
- data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/attachments.html +0 -36
- data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/button.html +0 -14
- data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/children.html +0 -101
- data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/expand.html +0 -17
- data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/mermaid.html +0 -2
- data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/notice.html +0 -2
- data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/ref.html +0 -14
- data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/relref.html +0 -14
- data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/siteparam.html +0 -7
- data/docs-src/themes/hugo-theme-learn/netlify.toml +0 -23
- data/docs-src/themes/hugo-theme-learn/static/css/atom-one-dark-reasonable.css +0 -77
- data/docs-src/themes/hugo-theme-learn/static/css/auto-complete.css +0 -47
- data/docs-src/themes/hugo-theme-learn/static/css/featherlight.min.css +0 -8
- data/docs-src/themes/hugo-theme-learn/static/css/fontawesome-all.min.css +0 -1
- data/docs-src/themes/hugo-theme-learn/static/css/hugo-theme.css +0 -254
- data/docs-src/themes/hugo-theme-learn/static/css/hybrid.css +0 -102
- data/docs-src/themes/hugo-theme-learn/static/css/nucleus.css +0 -615
- data/docs-src/themes/hugo-theme-learn/static/css/perfect-scrollbar.min.css +0 -2
- data/docs-src/themes/hugo-theme-learn/static/css/tags.css +0 -49
- data/docs-src/themes/hugo-theme-learn/static/css/theme-blue.css +0 -111
- data/docs-src/themes/hugo-theme-learn/static/css/theme-green.css +0 -111
- data/docs-src/themes/hugo-theme-learn/static/css/theme-red.css +0 -111
- data/docs-src/themes/hugo-theme-learn/static/css/theme.css +0 -1136
- data/docs-src/themes/hugo-theme-learn/static/fonts/Inconsolata.eot +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Inconsolata.svg +0 -1
- data/docs-src/themes/hugo-theme-learn/static/fonts/Inconsolata.ttf +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Inconsolata.woff +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.eot +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.svg +0 -1
- data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.ttf +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.woff +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.woff2 +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.eot +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.svg +0 -1
- data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.ttf +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.woff +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.woff2 +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.eot +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.svg +0 -1
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.ttf +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.woff +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.woff2 +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.eot +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.svg +0 -1
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.ttf +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.woff +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.woff2 +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.eot +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.svg +0 -1
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.ttf +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.woff +0 -0
- data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.woff2 +0 -0
- data/docs-src/themes/hugo-theme-learn/static/images/clippy.svg +0 -1
- data/docs-src/themes/hugo-theme-learn/static/images/favicon.png +0 -0
- data/docs-src/themes/hugo-theme-learn/static/images/gopher-404.jpg +0 -0
- data/docs-src/themes/hugo-theme-learn/static/js/auto-complete.js +0 -3
- data/docs-src/themes/hugo-theme-learn/static/js/clipboard.min.js +0 -7
- data/docs-src/themes/hugo-theme-learn/static/js/featherlight.min.js +0 -9
- data/docs-src/themes/hugo-theme-learn/static/js/highlight.pack.js +0 -6
- data/docs-src/themes/hugo-theme-learn/static/js/hugo-learn.js +0 -94
- data/docs-src/themes/hugo-theme-learn/static/js/jquery-3.3.1.min.js +0 -2
- data/docs-src/themes/hugo-theme-learn/static/js/jquery.sticky.js +0 -288
- data/docs-src/themes/hugo-theme-learn/static/js/learn.js +0 -459
- data/docs-src/themes/hugo-theme-learn/static/js/lunr.min.js +0 -6
- data/docs-src/themes/hugo-theme-learn/static/js/modernizr.custom-3.6.0.js +0 -3
- data/docs-src/themes/hugo-theme-learn/static/js/perfect-scrollbar.jquery.min.js +0 -2
- data/docs-src/themes/hugo-theme-learn/static/js/perfect-scrollbar.min.js +0 -2
- data/docs-src/themes/hugo-theme-learn/static/js/search.js +0 -93
- data/docs-src/themes/hugo-theme-learn/static/mermaid/mermaid.css +0 -277
- data/docs-src/themes/hugo-theme-learn/static/mermaid/mermaid.dark.css +0 -278
- data/docs-src/themes/hugo-theme-learn/static/mermaid/mermaid.forest.css +0 -356
- data/docs-src/themes/hugo-theme-learn/static/mermaid/mermaid.js +0 -8
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.eot +0 -0
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.svg +0 -1
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.ttf +0 -0
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.woff +0 -0
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.woff2 +0 -0
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.eot +0 -0
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.svg +0 -1
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.ttf +0 -0
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.woff +0 -0
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.woff2 +0 -0
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.eot +0 -0
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.svg +0 -1
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.ttf +0 -0
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.woff +0 -0
- data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.woff2 +0 -0
- data/docs-src/themes/hugo-theme-learn/theme.toml +0 -21
- data/docs-src/themes/hugo-theme-learn/wercker.yml +0 -16
- data/lib/rbcli/configuration/configurate.rb +0 -85
- data/lib/rbcli/configuration/configurate_blocks/hooks.rb +0 -52
- data/lib/rbcli/configuration/configurate_blocks/me.rb +0 -122
- data/lib/rbcli/configuration/configurate_blocks/storage.rb +0 -50
- data/lib/rbcli/engine/command.rb +0 -251
- data/lib/rbcli/engine/load_project.rb +0 -45
- data/lib/rbcli/engine/parser.rb +0 -116
- data/lib/rbcli/features/autoupdate/common/autoupdate.rb +0 -50
- data/lib/rbcli/features/autoupdate/gem_updater.rb +0 -62
- data/lib/rbcli/features/autoupdate/github_updater.rb +0 -76
- data/lib/rbcli/features/logging.rb +0 -98
- data/lib/rbcli/features/remote_exec.rb +0 -187
- data/lib/rbcli/features/scriptwrapper.rb +0 -75
- data/lib/rbcli/features/userconfig.rb +0 -163
- data/lib/rbcli/state_storage/common/state_storage.rb +0 -138
- data/lib/rbcli/state_storage/localstate.rb +0 -77
- data/lib/rbcli/state_storage/placeholders.rb +0 -29
- data/lib/rbcli/state_storage/remote_state_connectors/dynamodb.rb +0 -272
- data/lib/rbcli/state_storage/remotestate_dynamodb.rb +0 -115
- data/lib/rbcli/util/msg.rb +0 -55
- data/lib/rbcli/util/string_colorize.rb +0 -45
- data/lib/rbcli-tool/generators.rb +0 -105
- data/lib/rbcli-tool/mdless_fix.rb +0 -406
- data/lib/rbcli-tool/project.rb +0 -120
- data/lib/rbcli-tool/util.rb +0 -70
- data/lib/rbcli-tool.rb +0 -37
- data/rbcli.gemspec +0 -73
- data/skeletons/micro/executable +0 -132
- data/skeletons/mini/executable +0 -247
- data/skeletons/project/.gitignore +0 -11
- data/skeletons/project/.rakeTasks +0 -7
- data/skeletons/project/.rbcli +0 -0
- data/skeletons/project/.rspec +0 -3
- data/skeletons/project/CODE_OF_CONDUCT.md +0 -74
- data/skeletons/project/Gemfile +0 -6
- data/skeletons/project/README.md +0 -46
- data/skeletons/project/Rakefile +0 -6
- data/skeletons/project/application/commands/command.erb +0 -28
- data/skeletons/project/application/commands/script.erb +0 -30
- data/skeletons/project/application/commands/scripts/script.sh +0 -60
- data/skeletons/project/application/options.rb +0 -34
- data/skeletons/project/config/autoupdate.rb +0 -35
- data/skeletons/project/config/general.rb +0 -17
- data/skeletons/project/config/logging.rb +0 -19
- data/skeletons/project/config/storage.rb +0 -35
- data/skeletons/project/config/userspace.rb +0 -33
- data/skeletons/project/config/version.rb +0 -3
- data/skeletons/project/exe/executable +0 -53
- data/skeletons/project/hooks/default_action.rb +0 -16
- data/skeletons/project/hooks/first_run.rb +0 -16
- data/skeletons/project/hooks/post_execution.rb +0 -14
- data/skeletons/project/hooks/pre_execution.rb +0 -14
- data/skeletons/project/lib/lib.erb +0 -9
- data/skeletons/project/spec/spec_helper.rb +0 -14
- data/skeletons/project/spec/untitled_spec.rb +0 -9
- data/skeletons/project/untitled.gemspec +0 -40
- data/skeletons/project/userconf/user_defaults.yml +0 -6
- /data/{docs-src/.hugo_build.lock → lib/rbcli/plugins/.keep} +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
##################################################################################
|
|
3
|
+
# Rbcli -- A framework for developing command line applications in Ruby #
|
|
4
|
+
# Copyright (C) 2024 Andrew Khoury <akhoury@live.com> #
|
|
5
|
+
##################################################################################
|
|
6
|
+
require 'toml'
|
|
7
|
+
|
|
8
|
+
class Rbcli::UserConf::Toml < Rbcli::UserConf::Backend
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def parse str
|
|
12
|
+
begin
|
|
13
|
+
parsed_str = TOML.load(str).deep_symbolize!
|
|
14
|
+
rescue => e
|
|
15
|
+
Rbcli.log.warn "Error when parsing TOML file", "CONF"
|
|
16
|
+
Rbcli.log.warn e.message, "CONF"
|
|
17
|
+
Hash.new
|
|
18
|
+
else
|
|
19
|
+
@loaded = true
|
|
20
|
+
parsed_str
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def unparse hash
|
|
25
|
+
TOML::Generator.new(hash).body
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def inject_banner text, banner
|
|
29
|
+
banner.lines.map { |line| "# #{line.chomp}" }.join("\n") + "\n" + text
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class Symbol
|
|
34
|
+
def to_toml(path = "")
|
|
35
|
+
'"' + self.to_s.sub(/^:/, '') + '"'
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
##################################################################################
|
|
3
|
+
# Rbcli -- A framework for developing command line applications in Ruby #
|
|
4
|
+
# Copyright (C) 2024 Andrew Khoury <akhoury@live.com> #
|
|
5
|
+
##################################################################################
|
|
6
|
+
require 'yaml'
|
|
7
|
+
|
|
8
|
+
class Rbcli::UserConf::Yaml < Rbcli::UserConf::Backend
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def parse str
|
|
12
|
+
begin
|
|
13
|
+
parsed_str = YAML.safe_load(str, symbolize_names: true, aliases: true, permitted_classes: [Symbol])
|
|
14
|
+
rescue Psych::SyntaxError, Psych::DisallowedClass => e
|
|
15
|
+
Rbcli.log.warn "Invalid #{@type} syntax found at '#{@path}'", "CONF"
|
|
16
|
+
Rbcli.log.warn e.message, "CONF"
|
|
17
|
+
Hash.new
|
|
18
|
+
else
|
|
19
|
+
@loaded = true
|
|
20
|
+
parsed_str
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def unparse hash
|
|
25
|
+
hash.to_yaml
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def inject_banner text, banner
|
|
29
|
+
banner.lines.map { |line| "# #{line.chomp}" }.join("\n") + "\n" + text
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
##################################################################################
|
|
3
|
+
# Rbcli -- A framework for developing command line applications in Ruby #
|
|
4
|
+
# Copyright (C) 2024 Andrew Khoury <akhoury@live.com> #
|
|
5
|
+
##################################################################################
|
|
6
|
+
module Rbcli::Configurate::Config
|
|
7
|
+
include Rbcli::Configurable
|
|
8
|
+
|
|
9
|
+
def self.file location: nil, type: nil, schema_location: nil, save_on_exit: false, create_if_not_exists: false, suppress_errors: false
|
|
10
|
+
raise Rbcli::ConfigurateError.new "Config file location must either be a path or an array of paths" unless location.nil? || location.is_a?(String) || (location.is_a?(Array) && location.all? { |loc| loc.is_a?(String) })
|
|
11
|
+
raise Rbcli::ConfigurateError.new "Config schema file location must be a path" unless schema_location.nil? || schema_location.is_a?(String)
|
|
12
|
+
raise Rbcli::ConfigurateError.new "Config type must be one of the following: #{Rbcli::UserConf::Backend.types.keys.join(', ')}" unless (type.is_a?(String) || type.is_a?(Symbol)) && Rbcli::UserConf::Backend.types.key?(type.downcase.to_sym)
|
|
13
|
+
config = Rbcli::Config.new location: location, type: type, schema_location: schema_location, create_if_not_exists: create_if_not_exists, suppress_errors: suppress_errors
|
|
14
|
+
Rbcli::Warehouse.set(:config, config, :parsedopts)
|
|
15
|
+
Rbcli::Engine.register_operation Proc.new { Rbcli::Warehouse.get(:config, :parsedopts).load!; Rbcli::Warehouse.get(:config, :parsedopts).validate! }, name: :load_config, priority: 40
|
|
16
|
+
Rbcli::Engine.register_operation Proc.new { Rbcli::Warehouse.get(:config, :parsedopts).save! }, name: :save_config, priority: 160 if save_on_exit
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.banner text
|
|
20
|
+
raise Rbcli::ConfigurateError.new "The banner must be set to a string." unless text.is_a?(String)
|
|
21
|
+
Rbcli::Warehouse.get(:config, :parsedopts).set_banner text
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.defaults hash
|
|
25
|
+
raise Rbcli::ConfigurateError.new "The default configuration must be a hash." unless hash.is_a?(Hash)
|
|
26
|
+
Rbcli::Warehouse.get(:config, :parsedopts).defaults = hash
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
##################################################################################
|
|
3
|
+
# Rbcli -- A framework for developing command line applications in Ruby #
|
|
4
|
+
# Copyright (C) 2024 Andrew Khoury <akhoury@live.com> #
|
|
5
|
+
##################################################################################
|
|
6
|
+
require 'deep_merge'
|
|
7
|
+
require 'json-schema'
|
|
8
|
+
require_relative 'backend'
|
|
9
|
+
|
|
10
|
+
class Rbcli::Config < Hash
|
|
11
|
+
def initialize location: nil, type: nil, schema_location: nil, create_if_not_exists: false, suppress_errors: false
|
|
12
|
+
location = [location] unless location.is_a?(Array)
|
|
13
|
+
locations = location.map { |path| [path, Rbcli::UserConf::Backend.create(path, type: type)] }.reject { |path, storage| !(path.nil? || path == :null) && storage.type == 'NULL' }
|
|
14
|
+
existing_location = locations.select { |_path, storage| storage.exist? }.first
|
|
15
|
+
savable_location = locations.select { |_path, storage| storage.savable? }.first
|
|
16
|
+
if !existing_location.nil?
|
|
17
|
+
@location, @storage = existing_location
|
|
18
|
+
Rbcli.log.debug @location.nil? ? "Instantiated null config; data will not be stored" : "Found config of type '#{@storage.type}' at '#{@location}'", "CONF"
|
|
19
|
+
elsif !savable_location.nil? && create_if_not_exists
|
|
20
|
+
@location, @storage = savable_location
|
|
21
|
+
@should_create = true
|
|
22
|
+
Rbcli.log.debug "Ready to create new config of type '#{@storage.type}' at '#{@location}'", "CONF"
|
|
23
|
+
elsif suppress_errors
|
|
24
|
+
@location, @storage = :null, Rbcli::UserConf::Backend.create(:null)
|
|
25
|
+
Rbcli.log.debug "Location(s) could not be found and/or are not writeable. Instantiating null config and failing silently.", "CONF"
|
|
26
|
+
else
|
|
27
|
+
Rbcli.log.fatal "Config file could not be loaded. Please verify that it exists at one of the following locations: #{location.join(", ")}", "CONF"
|
|
28
|
+
Rbcli::exit 2
|
|
29
|
+
end
|
|
30
|
+
@suppress_errors = suppress_errors
|
|
31
|
+
@original_hash = {}
|
|
32
|
+
@defaults = {}
|
|
33
|
+
if schema_location
|
|
34
|
+
@schema = self.class.new(location: schema_location)
|
|
35
|
+
@schema.is_schema = true
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
attr_accessor :is_schema, :defaults
|
|
40
|
+
|
|
41
|
+
def set_banner text
|
|
42
|
+
@banner = text
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def add_default slug, default: nil
|
|
46
|
+
@defaults[slug] = default
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def type
|
|
50
|
+
@storage.type.downcase.to_sym
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def load!
|
|
54
|
+
if @should_create
|
|
55
|
+
Rbcli.log.add (@suppress_errors ? :debug : :info), "Config file #{@location} does not exist. Creating with default values.", "CONF"
|
|
56
|
+
self.deep_merge!(@storage.respond_to?(:parse_defaults) ? @storage.parse_defaults(@defaults) : @defaults)
|
|
57
|
+
self.save!
|
|
58
|
+
else
|
|
59
|
+
Rbcli.log.debug "Loading #{@is_schema ? 'schema' : 'config'} file", "CONF"
|
|
60
|
+
@original_hash = @storage.load(defaults: @defaults)
|
|
61
|
+
if !@storage.loaded?
|
|
62
|
+
Rbcli.log.add (@suppress_errors ? :debug : :warn), "Could not load #{@is_schema ? 'schema' : 'config'} file", "CONF"
|
|
63
|
+
Rbcli.log.add (@suppress_errors ? :debug : :warn), "Using defaults", "CONF" unless @defaults.empty?
|
|
64
|
+
return false
|
|
65
|
+
else
|
|
66
|
+
self.deep_merge!(@storage.respond_to?(:parse_defaults) ? @storage.parse_defaults(@defaults) : @defaults)
|
|
67
|
+
self.deep_merge!(@original_hash.deep_symbolize!) if @original_hash.is_a?(Hash)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def validate!
|
|
73
|
+
return true if @schema.nil?
|
|
74
|
+
Rbcli.log.debug "Validating config against schema", "CONF"
|
|
75
|
+
@schema.load!
|
|
76
|
+
begin
|
|
77
|
+
JSON::Validator.validate!(@schema, self)
|
|
78
|
+
rescue JSON::Schema::ValidationError => e
|
|
79
|
+
Rbcli.log.send (@suppress_errors ? :debug : :error), "There are errors in the config. Please fix these errors and try again."
|
|
80
|
+
Rbcli.log.send (@suppress_errors ? :debug : :error), JSON::Validator.fully_validate(@schema, self).join("\n")
|
|
81
|
+
Rbcli::exit 3 unless @suppress_errors
|
|
82
|
+
return false
|
|
83
|
+
end
|
|
84
|
+
Rbcli.log.debug "Validated config against schema successfully", "CONF"
|
|
85
|
+
true
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def save!
|
|
89
|
+
unless @storage.savable?
|
|
90
|
+
Rbcli.log.add (@suppress_errors ? :debug : :warn), "Config file not savable. Data not stored.", "CONF"
|
|
91
|
+
return false
|
|
92
|
+
end
|
|
93
|
+
hash_to_save = Marshal.load(Marshal.dump(self)).to_h # This removes all custom instance variables and types from the data
|
|
94
|
+
if hash_to_save == @original_hash && !@should_create
|
|
95
|
+
Rbcli.log.debug "No changes detected in the config. Skipping save.", "CONF"
|
|
96
|
+
else
|
|
97
|
+
Rbcli.log.debug "Changes detected in the config. Saving updated config.", "CONF"
|
|
98
|
+
@storage.save(hash_to_save.deep_stringify!)
|
|
99
|
+
@original_hash = hash_to_save.deep_symbolize!
|
|
100
|
+
@should_create = false
|
|
101
|
+
end
|
|
102
|
+
self
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def annotate!
|
|
106
|
+
@storage.annotate! @banner
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
require_relative 'config_of_death'
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
##################################################################################
|
|
3
|
+
# Rbcli -- A framework for developing command line applications in Ruby #
|
|
4
|
+
# Copyright (C) 2024 Andrew Khoury <akhoury@live.com> #
|
|
5
|
+
##################################################################################
|
|
6
|
+
class Rbcli::ConfigOfDeath < Rbcli::Config
|
|
7
|
+
(Rbcli::Config.instance_methods - Class.instance_methods).each do |method|
|
|
8
|
+
self.define_method(method) do |*args|
|
|
9
|
+
raise Rbcli::ConfigurateError.new "Attempted to access config that was not configured."
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Rbcli::Configurate.config do
|
|
2
|
+
<%- if @showdocs -%>
|
|
3
|
+
##### Config (Optional) #####
|
|
4
|
+
# The built-in config will automatically pull in a config file to a hash and vice versa
|
|
5
|
+
# It can either be used immutably (as user-defined configuration) and/or to store application state
|
|
6
|
+
#
|
|
7
|
+
# file location: <string> or <array> (Required) Provide either a specific config file location or a hierarchy to search
|
|
8
|
+
# type: (:yaml|:json|:ini|:toml|:null) (Optional) Select which backend/file format to use. If the file has an associated extension (i.e. '.yaml') then this can be omitted.
|
|
9
|
+
# schema_location: <string> (Optional) The file location of a JSON Schema (https://json-schema.org). If provided, the config will automatically be validated. (default: nil)
|
|
10
|
+
# save_on_exit: (true|false) (Optional) Save changes to the config file on exit (default: false)
|
|
11
|
+
# create_if_not_exists: (true|false) (Optional) Create the file using default values if it is not found on the system (default: false)
|
|
12
|
+
# suppress_errors: (true|false) (Optional) If set to false, the application will halt on any errors in loading the config. If set to true, defaults will be provided (default: true)
|
|
13
|
+
<%- end -%>
|
|
14
|
+
file location: ['./<%= @appname.downcase %>.yaml', '~/.<%= @appname.downcase %>.yaml', '/etc/<%= @appname.downcase %>.yaml'],
|
|
15
|
+
type: :yaml, schema_location: nil, save_on_exit: false,
|
|
16
|
+
create_if_not_exists: false, suppress_errors: true
|
|
17
|
+
<%- if @showdocs -%>
|
|
18
|
+
##### Banner (Optional) #####
|
|
19
|
+
# Define a banner to be placed at the top of the config file.
|
|
20
|
+
# Note that the banner will only be written to backends that support comments (:yaml, :ini, and :toml).
|
|
21
|
+
<%- end -%>
|
|
22
|
+
banner <<~BANNER
|
|
23
|
+
This text appears at the top of the config file when using a backend that supports comments.
|
|
24
|
+
Tell the user a bit about what they're doing here.
|
|
25
|
+
BANNER
|
|
26
|
+
<%- if @showdocs -%>
|
|
27
|
+
##### Defaults (Optional) #####
|
|
28
|
+
# Set defaults for your config values.
|
|
29
|
+
#
|
|
30
|
+
# Defaults set here will be provided to your application if the values are missing in the config.
|
|
31
|
+
# They will also be used to create new config files when the flag `create_if_not_exists` is set to true.
|
|
32
|
+
<%- end -%>
|
|
33
|
+
defaults({ setting_one: true, setting_two: false })
|
|
34
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
##################################################################################
|
|
3
|
+
# Rbcli -- A framework for developing command line applications in Ruby #
|
|
4
|
+
# Copyright (C) 2024 Andrew Khoury <akhoury@live.com> #
|
|
5
|
+
##################################################################################
|
|
6
|
+
module Rbcli::Configurate
|
|
7
|
+
# If a non-existant method is called, we attempt to load the plugin.
|
|
8
|
+
# If the plugin fails to load we display a message to the developer
|
|
9
|
+
def self.method_missing(method, *args, &block)
|
|
10
|
+
filename = File.join(RBCLI_LIBDIR, 'plugins', method.to_s.downcase, 'component.rb')
|
|
11
|
+
if File.exist? filename
|
|
12
|
+
require filename
|
|
13
|
+
self.send method, *args, &block
|
|
14
|
+
else
|
|
15
|
+
raise Rbcli::ConfigurateError.new "Invalid Rbcli Configurate plugin called: `#{method}` in file #{File.expand_path caller[0]}"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
module Rbcli::Configurable
|
|
21
|
+
def self.included klass
|
|
22
|
+
# We dynamically add two methods to the module: one that runs other methods dynamially, and one that
|
|
23
|
+
# displays a reasonable message if a method is missing
|
|
24
|
+
klass.singleton_class.class_eval do
|
|
25
|
+
define_method :rbcli_private_running_method do |&block|
|
|
26
|
+
@self_before_instance_eval = eval 'self', block.binding
|
|
27
|
+
instance_eval &block
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
define_method :method_missing do |method, *args, &block|
|
|
31
|
+
raise Rbcli::ConfigurateError.new "Invalid Configurate.#{self.name.split('::')[-1].downcase} method called: `#{method}` in file #{File.expand_path caller[0]}"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# This will dynamically create the configurate block based on the class name.
|
|
36
|
+
# For example, if the class name is 'Me', then the resulting block is `Configurate.me`
|
|
37
|
+
name = klass.name.split('::')[-1]
|
|
38
|
+
Rbcli::Configurate.singleton_class.class_eval do
|
|
39
|
+
define_method name.downcase.to_sym do |&block|
|
|
40
|
+
mod = self.const_get name
|
|
41
|
+
begin
|
|
42
|
+
mod.rbcli_private_running_method &block
|
|
43
|
+
rescue Rbcli::ConfigurateError => e
|
|
44
|
+
Rbcli.log.fatal 'Rbcli Configuration Error: ' + e.message
|
|
45
|
+
Rbcli::exit 255
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
Dir.glob(File.dirname(__FILE__) + '/../**/component.rb', &method(:require))
|
|
53
|
+
|
|
54
|
+
# module Rbcli
|
|
55
|
+
# def self.configuration mod, key = nil
|
|
56
|
+
# begin
|
|
57
|
+
# d = Rbcli::Configurate.const_get(mod.to_s.capitalize.to_sym).config
|
|
58
|
+
# (key.nil?) ? d : d[key]
|
|
59
|
+
# rescue
|
|
60
|
+
# nil
|
|
61
|
+
# end
|
|
62
|
+
# end
|
|
63
|
+
# end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
##################################################################################
|
|
3
|
+
# Rbcli -- A framework for developing command line applications in Ruby #
|
|
4
|
+
# Copyright (C) 2024 Andrew Khoury <akhoury@live.com> #
|
|
5
|
+
##################################################################################
|
|
6
|
+
module Rbcli::Engine
|
|
7
|
+
@operations = []
|
|
8
|
+
|
|
9
|
+
def self.register_operation operation, name: nil, priority: nil
|
|
10
|
+
if @operations.select { |op| op[:priority] == priority }.count != 0
|
|
11
|
+
raise Rbcli::Error.new "The Rbcli engine can not have two operations defined with the same priority: #{name}, #{@operations.select { |op| op[:priority] == priority }.join(", ")}"
|
|
12
|
+
end
|
|
13
|
+
@operations << { operation: operation, name: name, priority: priority }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.run!
|
|
17
|
+
Rbcli.log.debug "The engine has been started", "ENGN"
|
|
18
|
+
@operations.sort_by { |op| op[:priority] }.each do |op|
|
|
19
|
+
Rbcli.log.debug "Running operation #{op[:priority]} -- #{op[:name]}", "ENGN"
|
|
20
|
+
op[:operation].call
|
|
21
|
+
end
|
|
22
|
+
Rbcli.log.debug "The engine has been stopped", "ENGN"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module Rbcli
|
|
27
|
+
def self.go!
|
|
28
|
+
Rbcli::Engine.run!
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
##################################################################################
|
|
3
|
+
# Rbcli -- A framework for developing command line applications in Ruby #
|
|
4
|
+
# Copyright (C) 2024 Andrew Khoury <akhoury@live.com> #
|
|
5
|
+
##################################################################################
|
|
6
|
+
module Rbcli::Warehouse
|
|
7
|
+
@data = {}
|
|
8
|
+
|
|
9
|
+
def self.set key, value, namespace = :default
|
|
10
|
+
raise Rbcli::Error.new "Namespace must be a symbol" unless namespace.is_a? Symbol
|
|
11
|
+
@data[namespace] ||= {}
|
|
12
|
+
@data[namespace][key] = value
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.get key, namespace = :default
|
|
16
|
+
key.nil? ? @data.dig(namespace) : @data.dig(namespace, key)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
##################################################################################
|
|
3
|
+
# Rbcli -- A framework for developing command line applications in Ruby #
|
|
4
|
+
# Copyright (C) 2024 Andrew Khoury <akhoury@live.com> #
|
|
5
|
+
##################################################################################
|
|
6
|
+
module Rbcli::Configurate::Envvars
|
|
7
|
+
include Rbcli::Configurable
|
|
8
|
+
|
|
9
|
+
def self.prefix envvar_prefix
|
|
10
|
+
raise Rbcli::ConfigurateError.new "Environment variable prefix must be a string" unless envvar_prefix.is_a?(String)
|
|
11
|
+
env = Rbcli::Config.new location: envvar_prefix.sub(/_+$/, ''), type: :env
|
|
12
|
+
Rbcli::Warehouse.set(:env, env, :parsedopts)
|
|
13
|
+
Rbcli::Engine.register_operation Proc.new { Rbcli::Warehouse.get(:env, :parsedopts).load! }, name: :load_envvars, priority: 50
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.envvar envvar, default
|
|
17
|
+
raise Rbcli::ConfigurateError.new "Environment variables must be a string" unless envvar.is_a?(String)
|
|
18
|
+
Rbcli::Warehouse.get(:env, :parsedopts).add_default(envvar, default: default)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Rbcli::Configurate.envvars do
|
|
2
|
+
<%- if @showdocs -%>
|
|
3
|
+
##### Environment Variable Parsing (Optional) #####
|
|
4
|
+
# The envvars module can pull in all environment variables with a given
|
|
5
|
+
# prefix and organize them into a hash structure based on name.
|
|
6
|
+
# It will also parse the string values and convert them to the proper type (Integer, Boolean, etc)
|
|
7
|
+
# Any values set here will be treated as defaults and made available when a variable is missing
|
|
8
|
+
#
|
|
9
|
+
# For example, these two environment variables:
|
|
10
|
+
# <%= @appname.upcase %>_TERM_HEIGHT=40
|
|
11
|
+
# <%= @appname.upcase %>_TERM_WIDTH=120
|
|
12
|
+
# Would be declared here as:
|
|
13
|
+
# prefix '<%= @appname.upcase %>'
|
|
14
|
+
# envvar 'TERM_HEIGHT', 40
|
|
15
|
+
# envvar 'TERM_WIDTH', 120
|
|
16
|
+
# And get loaded into the env hash as:
|
|
17
|
+
# { term: { height: 40, width: 120 } }
|
|
18
|
+
#
|
|
19
|
+
# If the prefix is unset or equal to nil, the environment variables specified here will
|
|
20
|
+
# be loaded without one.
|
|
21
|
+
<%- end -%>
|
|
22
|
+
prefix '<%= @appname.upcase %>'
|
|
23
|
+
envvar 'DEVELOPMENT', false
|
|
24
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
##################################################################################
|
|
3
|
+
# Rbcli -- A framework for developing command line applications in Ruby #
|
|
4
|
+
# Copyright (C) 2024 Andrew Khoury <akhoury@live.com> #
|
|
5
|
+
##################################################################################
|
|
6
|
+
module Rbcli::Configurate::Hooks
|
|
7
|
+
include Rbcli::Configurable
|
|
8
|
+
|
|
9
|
+
def self.pre_execute & block
|
|
10
|
+
Rbcli::Warehouse.set(:pre_execute, block, :hooks)
|
|
11
|
+
Rbcli.log.debug "Registered pre_execute hook", "HOOK"
|
|
12
|
+
Rbcli::Engine.register_operation(Proc.new do
|
|
13
|
+
Rbcli::Warehouse.get(:pre_execute, :hooks).call(
|
|
14
|
+
Rbcli::Warehouse.get(:opts, :parsedopts),
|
|
15
|
+
Rbcli::Warehouse.get(:params, :parsedopts),
|
|
16
|
+
Rbcli::Warehouse.get(:args, :parsedopts),
|
|
17
|
+
Rbcli::Warehouse.get(:config, :parsedopts) || Rbcli::ConfigOfDeath.new,
|
|
18
|
+
Rbcli::Warehouse.get(:env, :parsedopts) || Rbcli::ConfigOfDeath.new
|
|
19
|
+
)
|
|
20
|
+
end, name: :pre_execute_hook, priority: 90)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.post_execute & block
|
|
24
|
+
Rbcli::Warehouse.set(:post_execute, block, :hooks)
|
|
25
|
+
Rbcli.log.debug "Registered post_execute hook", "HOOK"
|
|
26
|
+
Rbcli::Engine.register_operation(Proc.new do
|
|
27
|
+
Rbcli::Warehouse.get(:post_execute, :hooks).call(
|
|
28
|
+
Rbcli::Warehouse.get(:opts, :parsedopts),
|
|
29
|
+
Rbcli::Warehouse.get(:params, :parsedopts),
|
|
30
|
+
Rbcli::Warehouse.get(:args, :parsedopts),
|
|
31
|
+
Rbcli::Warehouse.get(:config, :parsedopts) || Rbcli::ConfigOfDeath.new,
|
|
32
|
+
Rbcli::Warehouse.get(:env, :parsedopts) || Rbcli::ConfigOfDeath.new
|
|
33
|
+
)
|
|
34
|
+
end, name: :post_execute_hook, priority: 110)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Rbcli::Configurate.hooks do
|
|
2
|
+
<%- if @showdocs -%>
|
|
3
|
+
##### Hooks (Optional) #####
|
|
4
|
+
# These hooks are scheduled on the Rbcli execution engine to run
|
|
5
|
+
# Pre- and Post- the command specified. They are executed after
|
|
6
|
+
# everything else has been initialized, so the runtime configuration
|
|
7
|
+
# values are all made available, as they will appear to the command.
|
|
8
|
+
#
|
|
9
|
+
# These are good for parsing and/or doing transformations on the provided
|
|
10
|
+
# configuration before passing them to the command, and for cleaning
|
|
11
|
+
# up your environment afterwards.
|
|
12
|
+
<%- end -%>
|
|
13
|
+
pre_execute do |opts, params, args, config, env|
|
|
14
|
+
Rbcli.log.info "I'm about to run a command..."
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
post_execute do |opts, params, args, config, env|
|
|
18
|
+
Rbcli.log.info "I'm done running the command!"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
##################################################################################
|
|
3
|
+
# Rbcli -- A framework for developing command line applications in Ruby #
|
|
4
|
+
# Copyright (C) 2024 Andrew Khoury <akhoury@live.com> #
|
|
5
|
+
##################################################################################
|
|
6
|
+
module Rbcli::Configurate::Logger
|
|
7
|
+
include Rbcli::Configurable
|
|
8
|
+
|
|
9
|
+
def self.logger target: :stdout, level: :info, format: :display
|
|
10
|
+
unless target.is_a?(IO) ||
|
|
11
|
+
(defined?(StringIO) && target.is_a?(StringIO)) ||
|
|
12
|
+
(target.is_a?(String) && Dir.exist?(File.dirname(File.expand_path(target)))) ||
|
|
13
|
+
(target.is_a?(Symbol) && [:stdout, :stderr].include?(target.to_sym))
|
|
14
|
+
raise Rbcli::ConfigurateError.new "Log Target is invalid. Please use either :stdout, :stderr, or a valid file path where the directory already exists on the system. Target given: #{target}"
|
|
15
|
+
end
|
|
16
|
+
unless level.is_a?(Integer) || %i(debug info warn error fatal unknown).include?(level)
|
|
17
|
+
raise Rbcli::ConfigurateError.new "Log Level must be one of the following: #{%i(debug info warn error fatal unknown)}. Level provided: #{level}"
|
|
18
|
+
end
|
|
19
|
+
unless Rbcli::Logger.formats.include?(format)
|
|
20
|
+
raise Rbcli::ConfigurateError.new "Log format must be one of the following: #{Rbcli::Logger.formats}. Format provided: #{format}"
|
|
21
|
+
end
|
|
22
|
+
Rbcli.start_logger(target: target, level: level, format: format)
|
|
23
|
+
Rbcli.log.debug "Logger initialized with target #{target} at level #{level}", "CORE"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.format slug, prok
|
|
27
|
+
raise Rbcli::ConfigurateError.new "The slug for the custom log format must be a string or a symbol." unless slug.is_a?(String) || slug.is_a?(Symbol)
|
|
28
|
+
raise Rbcli::ConfigurateError.new "A proc must be provided to use a custom log format" unless prok.is_a?(Proc)
|
|
29
|
+
Rbcli.log.add_format slug, prok
|
|
30
|
+
Rbcli.log.format slug
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
##################################################################################
|
|
3
|
+
# Rbcli -- A framework for developing command line applications in Ruby #
|
|
4
|
+
# Copyright (C) 2024 Andrew Khoury <akhoury@live.com> #
|
|
5
|
+
##################################################################################
|
|
6
|
+
%w(logger json colorize).each { |req| require req }
|
|
7
|
+
require_relative 'lolcat/lol'
|
|
8
|
+
|
|
9
|
+
# noinspection RubyClassVariableUsageInspection
|
|
10
|
+
class Rbcli::Logger
|
|
11
|
+
EXECUTABLE ||= File.basename($0).gsub(/\.[^.]+$/, '')
|
|
12
|
+
@max_prog_len = 0
|
|
13
|
+
@original_formatter = Logger::Formatter.new
|
|
14
|
+
@@formatters = {
|
|
15
|
+
display: Proc.new { |severity, _datetime, _progname, msg|
|
|
16
|
+
severity == 'INFO' ? msg : "#{colorlevel(severity)}#{(' ' * (5 - severity.length))} || #{msg}"
|
|
17
|
+
},
|
|
18
|
+
simple: Proc.new { |severity, _datetime, progname, msg|
|
|
19
|
+
@max_prog_len = (@max_prog_len > progname.length) ? @max_prog_len : progname.length unless progname.nil?
|
|
20
|
+
"#{colorlevel(severity)}#{(' ' * (5 - severity.length))} || #{progname || (' ' * @max_prog_len)} || #{msg}"
|
|
21
|
+
},
|
|
22
|
+
full: Proc.new { |severity, datetime, progname, msg|
|
|
23
|
+
@max_prog_len = (@max_prog_len > progname.length) ? @max_prog_len : progname.length unless progname.nil?
|
|
24
|
+
"#{datetime.strftime("%Y-%m-%d %H:%M:%S.%6N")} || #{EXECUTABLE} || #{progname || (' ' * @max_prog_len)} || #{colorlevel(severity)}#{(' ' * (5 - severity.length))} || #{msg}"
|
|
25
|
+
},
|
|
26
|
+
apache: Proc.new { |severity, datetime, progname, msg|
|
|
27
|
+
"[#{datetime.strftime("%a %b %d %H:%M:%S.%6N %Y")}] [#{severity}] [#{EXECUTABLE}] [#{progname}] #{msg.gsub(/\e\[([;\d]+)?m/, '')}"
|
|
28
|
+
},
|
|
29
|
+
json: Proc.new { |severity, datetime, progname, msg|
|
|
30
|
+
{ timestamp: datetime.strftime("%Y-%m-%d %H:%M:%S.%N"), severity: severity, application: EXECUTABLE, module: progname, message: msg.gsub(/\e\[([;\d]+)?m/, '') }.to_json
|
|
31
|
+
},
|
|
32
|
+
ruby: Proc.new { |severity, datetime, progname, msg|
|
|
33
|
+
@original_formatter.call(severity, datetime, progname, msg).chomp
|
|
34
|
+
},
|
|
35
|
+
lolcat: Proc.new { |severity, _datetime, _progname, msg|
|
|
36
|
+
"#{colorlevel(severity)}#{(' ' * (5 - severity.length))} || #{Lol.makestr(msg, { spread: 3, freq: 0.1, slope: 4, invert: false, truecolor: true })}"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
def self.formats
|
|
41
|
+
@@formatters.keys
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def initialize(target: STDOUT, level: :info, format: :display)
|
|
45
|
+
self.target(target)
|
|
46
|
+
self.level(level)
|
|
47
|
+
self.format(format)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def target target
|
|
51
|
+
@logger = Logger.new(target_select(target))
|
|
52
|
+
@logger.formatter = Proc.new { |severity, datetime, progname, msg|
|
|
53
|
+
msg = msg.to_s unless msg.is_a?(String)
|
|
54
|
+
msg.lines.map { |line| @@formatters[@format].call(severity, datetime, progname, line.chomp) }.join("\n") + "\n"
|
|
55
|
+
}
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def level slug = nil
|
|
59
|
+
return @logger.level if slug.nil?
|
|
60
|
+
@logger.level = logger_level(slug)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def format slug = nil
|
|
64
|
+
return @format if slug.nil?
|
|
65
|
+
@format = slug if @@formatters.key?(slug)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def add_format slug, prok
|
|
69
|
+
@@formatters[slug] = prok
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def add level, message, progname = nil, &block
|
|
73
|
+
@logger.add(logger_level(level), message, progname, &block)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def debug message, progname = nil, &block
|
|
77
|
+
self.add(Logger::DEBUG, message, progname, &block)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def info message, progname = nil, &block
|
|
81
|
+
self.add(Logger::INFO, message, progname, &block)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def warn message, progname = nil, &block
|
|
85
|
+
self.add(Logger::WARN, message, progname, &block)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def error message, progname = nil, &block
|
|
89
|
+
self.add(Logger::ERROR, message, progname, &block)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def fatal message, progname = nil, &block
|
|
93
|
+
self.add(Logger::FATAL, message, progname, &block)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def unknown message, progname = nil, &block
|
|
97
|
+
self.add(Logger::UNKNOWN, message, progname, &block)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
%w(debug, info, warn, error, fatal, unknown).each do |l|
|
|
101
|
+
self.define_method(l.to_sym) do |message, progname = nil, &block|
|
|
102
|
+
self.send(:add, l.to_sym, message, progname, &block)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
private
|
|
107
|
+
|
|
108
|
+
def self.colorlevel level
|
|
109
|
+
level.colorize(
|
|
110
|
+
{
|
|
111
|
+
'DEBUG' => :blue,
|
|
112
|
+
'INFO' => :green,
|
|
113
|
+
'WARN' => :yellow,
|
|
114
|
+
'ERROR' => :red,
|
|
115
|
+
'FATAL' => { color: :light_red, mode: :bold },
|
|
116
|
+
'ANY' => :cyan
|
|
117
|
+
}[level.to_s.upcase] || :default)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def target_select slug
|
|
121
|
+
{
|
|
122
|
+
stdout: STDOUT,
|
|
123
|
+
stderr: STDERR
|
|
124
|
+
}[slug] || slug
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def logger_level slug
|
|
128
|
+
if slug.is_a?(String) || slug.is_a?(Symbol)
|
|
129
|
+
{
|
|
130
|
+
debug: Logger::DEBUG,
|
|
131
|
+
info: Logger::INFO,
|
|
132
|
+
warn: Logger::WARN,
|
|
133
|
+
error: Logger::ERROR,
|
|
134
|
+
fatal: Logger::FATAL,
|
|
135
|
+
unknown: Logger::UNKNOWN,
|
|
136
|
+
any: -1
|
|
137
|
+
}[slug.to_s.downcase.to_sym] || Logger::UNKNOWN
|
|
138
|
+
else
|
|
139
|
+
slug
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
module Rbcli
|
|
145
|
+
@logger = nil
|
|
146
|
+
|
|
147
|
+
def self.start_logger target: STDOUT, level: :info, format: :display
|
|
148
|
+
@logger = Rbcli::Logger.new(target: target, level: level, format: format)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def self.log
|
|
152
|
+
self.start_logger if @logger.nil?
|
|
153
|
+
@logger
|
|
154
|
+
end
|
|
155
|
+
end
|