rbcli 0.1.10 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/CODE_OF_CONDUCT.md +1 -1
  4. data/Gemfile.lock +12 -12
  5. data/LICENSE.txt +674 -21
  6. data/README.md +80 -443
  7. data/bin/console +19 -0
  8. data/bin/setup +20 -0
  9. data/docs/404.html +639 -0
  10. data/docs/advanced/automatic_updates/index.html +791 -0
  11. data/docs/advanced/command_types/index.html +946 -0
  12. data/docs/advanced/distributed_state_locking/index.html +777 -0
  13. data/docs/advanced/hooks/index.html +836 -0
  14. data/docs/advanced/state_storage/index.html +957 -0
  15. data/docs/advanced/user_config_files/index.html +818 -0
  16. data/docs/assets/fonts/font-awesome.css +4 -0
  17. data/docs/assets/fonts/material-icons.css +13 -0
  18. data/docs/assets/fonts/specimen/FontAwesome.ttf +0 -0
  19. data/docs/assets/fonts/specimen/FontAwesome.woff +0 -0
  20. data/docs/assets/fonts/specimen/FontAwesome.woff2 +0 -0
  21. data/docs/assets/fonts/specimen/MaterialIcons-Regular.ttf +0 -0
  22. data/docs/assets/fonts/specimen/MaterialIcons-Regular.woff +0 -0
  23. data/docs/assets/fonts/specimen/MaterialIcons-Regular.woff2 +0 -0
  24. data/docs/assets/images/favicon.png +0 -0
  25. data/docs/assets/images/icons/bitbucket.1b09e088.svg +20 -0
  26. data/docs/assets/images/icons/github.f0b8504a.svg +18 -0
  27. data/docs/assets/images/icons/gitlab.6dd19c00.svg +38 -0
  28. data/docs/assets/javascripts/application.a59e2a89.js +1 -0
  29. data/docs/assets/javascripts/lunr/lunr.da.js +1 -0
  30. data/docs/assets/javascripts/lunr/lunr.de.js +1 -0
  31. data/docs/assets/javascripts/lunr/lunr.du.js +1 -0
  32. data/docs/assets/javascripts/lunr/lunr.es.js +1 -0
  33. data/docs/assets/javascripts/lunr/lunr.fi.js +1 -0
  34. data/docs/assets/javascripts/lunr/lunr.fr.js +1 -0
  35. data/docs/assets/javascripts/lunr/lunr.hu.js +1 -0
  36. data/docs/assets/javascripts/lunr/lunr.it.js +1 -0
  37. data/docs/assets/javascripts/lunr/lunr.jp.js +1 -0
  38. data/docs/assets/javascripts/lunr/lunr.multi.js +1 -0
  39. data/docs/assets/javascripts/lunr/lunr.no.js +1 -0
  40. data/docs/assets/javascripts/lunr/lunr.pt.js +1 -0
  41. data/docs/assets/javascripts/lunr/lunr.ro.js +1 -0
  42. data/docs/assets/javascripts/lunr/lunr.ru.js +1 -0
  43. data/docs/assets/javascripts/lunr/lunr.stemmer.support.js +1 -0
  44. data/docs/assets/javascripts/lunr/lunr.sv.js +1 -0
  45. data/docs/assets/javascripts/lunr/lunr.tr.js +1 -0
  46. data/docs/assets/javascripts/lunr/tinyseg.js +1 -0
  47. data/docs/assets/javascripts/modernizr.1aa3b519.js +1 -0
  48. data/docs/assets/stylesheets/application-palette.6079476c.css +2 -0
  49. data/docs/assets/stylesheets/application.ba0fd1a6.css +2 -0
  50. data/docs/development/code_of_conduct/index.html +883 -0
  51. data/docs/development/contributing/index.html +744 -0
  52. data/docs/development/license/index.html +715 -0
  53. data/docs/imported/changelog/index.html +853 -0
  54. data/docs/imported/quick_reference/index.html +1057 -0
  55. data/docs/index.html +732 -0
  56. data/docs/search/search_index.json +569 -0
  57. data/docs/sitemap.xml +93 -0
  58. data/docs/tutorial/10-getting_started/index.html +806 -0
  59. data/docs/tutorial/20-project_layout/index.html +972 -0
  60. data/docs/tutorial/30-your_first_command/index.html +906 -0
  61. data/docs/tutorial/40-options_parameters_and_arguments/index.html +1049 -0
  62. data/docs/tutorial/50-publishing/index.html +838 -0
  63. data/docs/whoami/index.html +709 -0
  64. data/docs-src/docs/advanced/automatic_updates.md +42 -0
  65. data/docs-src/docs/advanced/command_types.md +144 -0
  66. data/docs-src/docs/advanced/distributed_state_locking.md +33 -0
  67. data/docs-src/docs/advanced/hooks.md +65 -0
  68. data/docs-src/docs/advanced/logging.md +35 -0
  69. data/docs-src/docs/advanced/state_storage.md +117 -0
  70. data/docs-src/docs/advanced/user_config_files.md +47 -0
  71. data/docs-src/docs/development/code_of_conduct.md +74 -0
  72. data/docs-src/docs/development/contributing.md +49 -0
  73. data/docs-src/docs/development/license.md +10 -0
  74. data/docs-src/docs/imported/changelog.md +31 -0
  75. data/docs-src/docs/imported/quick_reference.md +150 -0
  76. data/docs-src/docs/index.md +38 -0
  77. data/docs-src/docs/tutorial/10-getting_started.md +41 -0
  78. data/docs-src/docs/tutorial/20-project_layout.md +115 -0
  79. data/docs-src/docs/tutorial/30-your_first_command.md +126 -0
  80. data/docs-src/docs/tutorial/40-options_parameters_and_arguments.md +251 -0
  81. data/docs-src/docs/tutorial/50-publishing.md +47 -0
  82. data/docs-src/docs/whoami.md +28 -0
  83. data/docs-src/makesite.sh +14 -0
  84. data/docs-src/mkdocs.yml +76 -0
  85. data/docs-src/runsite.sh +3 -0
  86. data/exe/rbcli +76 -5
  87. data/lib/rbcli/autoupdate/autoupdate.rb +24 -4
  88. data/lib/rbcli/autoupdate/gem_updater.rb +23 -2
  89. data/lib/rbcli/autoupdate/github_updater.rb +22 -1
  90. data/lib/rbcli/configuration/config.rb +22 -1
  91. data/lib/rbcli/configuration/configurate.rb +24 -2
  92. data/lib/rbcli/engine/command.rb +26 -6
  93. data/lib/rbcli/engine/load_project.rb +29 -3
  94. data/lib/rbcli/engine/parser.rb +25 -4
  95. data/lib/rbcli/logging/logging.rb +21 -0
  96. data/lib/rbcli/scriptwrapping/scriptwrapper.rb +30 -11
  97. data/lib/rbcli/stateful_systems/configuratestorage.rb +20 -0
  98. data/lib/rbcli/stateful_systems/state_storage.rb +20 -0
  99. data/lib/rbcli/stateful_systems/storagetypes/localstate.rb +20 -0
  100. data/lib/rbcli/stateful_systems/storagetypes/remote_state_connectors/dynamodb.rb +20 -0
  101. data/lib/rbcli/stateful_systems/storagetypes/remotestate_dynamodb.rb +20 -0
  102. data/lib/rbcli/util/hash_deep_symbolize.rb +43 -22
  103. data/lib/rbcli/util/string_colorize.rb +20 -0
  104. data/lib/rbcli/version.rb +21 -1
  105. data/lib/rbcli-tool/generators.rb +20 -0
  106. data/lib/rbcli-tool/mdless_fix.rb +20 -0
  107. data/lib/rbcli-tool/project.rb +27 -2
  108. data/lib/rbcli-tool/util.rb +20 -0
  109. data/lib/rbcli-tool.rb +20 -0
  110. data/lib/rbcli.rb +20 -0
  111. data/lib-sh/lib-rbcli.sh +19 -0
  112. data/rbcli.gemspec +22 -3
  113. data/skeletons/project/CODE_OF_CONDUCT.md +1 -1
  114. data/skeletons/project/README.md +17 -2
  115. data/skeletons/project/application/commands/command.erb +10 -8
  116. data/skeletons/project/application/commands/script.erb +3 -1
  117. data/skeletons/project/application/commands/scripts/script.sh +2 -2
  118. data/skeletons/project/application/options.rb +12 -3
  119. data/skeletons/project/config/autoupdate.rb +5 -2
  120. data/skeletons/project/config/storage.rb +7 -6
  121. data/skeletons/project/config/userspace.rb +6 -1
  122. data/skeletons/project/exe/executable +1 -1
  123. data/skeletons/project/lib/.keep +0 -0
  124. data/skeletons/project/untitled.gemspec +4 -4
  125. data/skeletons/project/{default_user_configs → userconf}/user_defaults.yml +0 -0
  126. metadata +85 -9
  127. data/examples/defaults.yml +0 -4
  128. data/examples/myscript.sh +0 -23
  129. data/examples/mytool +0 -95
@@ -0,0 +1,569 @@
1
+ {
2
+ "docs": [
3
+ {
4
+ "location": "/",
5
+ "text": "This is RBCli\n\n\nAs technologists today, we work with the command line a lot. We script a lot. We write tools to share with each other to make our lives easier. We even write applications to make up for missing features in the 3rd party software that we buy. Unfortunately, when writing CLI tools, this process has typically been very painful. We've been working with low-level frameworks for decades; frameworks like \ngetopt\n (1980) and \ncurses\n (1977). They fit their purpose well; they were both computationally lightweight for the computers of the day, and they gave engineers full control and flexibility when it came to how things were built. Over the years, we've used them to settle on several design patterns that we know work well. Patterns as to what a CLI command looks like, what a config file looks like, what remote execution looks like, and even how to use locks (mutexes, semaphores, etc) to control application flow and data atomicity. Yet we're stuck writing the same low-level code anytime we want to write our tooling. Not anymore.\n\n\nEnter RBCli. RBCli is a framework to quickly develop advanced command-line tools in Ruby. It has been written from the ground up with the needs of the modern technologist in mind, designed to make advanced CLI tool development as painless as possible. In RBCli, low-level code has been wrapped and/or replaced with higher-level methods. Much of the functionality has even been reduced to single methods: for example, it takes just one declaration to define, load, and generate a user's config file at the appropriate times. Many other features are automated and require no work by the engineer. These make RBCli a fundamental re-thining of how we develop CLI tools, enabling the rapid development of applications for everyone from hobbyists to enterprises.\n\n\nSome of its key features include:\n\n\n\n\n\n\nSimple DSL Interface\n: To cut down on the amount of code that needs to be written, RBCli has a DSL that is designed to cut to the chase. This makes the work a lot less tedious.\n\n\n\n\n\n\nMultiple Levels of Parameters and Arguments\n: Forget about writing parsers for command-line options, or about having to differentiate between parameters and arguments. All of that work is taken care of.\n\n\n\n\n\n\nConfig File Generation\n: Easily piece together a default configuration even with declarations in different parts of the code. Then the user can generate their own configuration, and it gets stored in whatever location you'd like.\n\n\n\n\n\n\nMultiple Hooks and Entry Points\n: Define commands, pre-execution hooks, post-execution hooks, and first_run hooks to quickly and easily customize the flow of your application code.\n\n\n\n\n\n\nLogging\n: Keep track of all instances of your tool through logging. Logs can go to STDOUT, STDERR, or a given file, making them compatible with log aggregators such as Splunk, Logstash, and many others.\n\n\n\n\n\n\nLocal State Storage\n: Easily manage a set of data that persists between runs. You get access to a hash that is automatically kept in-sync with a file on disk.\n\n\n\n\n\n\nRemote State\n: It works just like Local State Storage, but store the data on a remote server! It can be used in tandem with Local State Storage or on its own. Currently supports AWS DyanmoDB. \n\n\n\n\n\n\nState Locking and Sharing\n: Share remote state safely between users with built-in locking! When enabled, it makes sure that only one user is accessing the data at any given time.\n\n\n\n\n\n\nAutomatic Update Notifications\n: Just provide the gem name or git repo, and RBCli will take care of notifying users!\n\n\n\n\n\n\nExternal Script Wrapping\n: High-level wrapping for Bash scripts, or any other applcication you'd like to wrap into a command.\n\n\n\n\n\n\nProject Structure and Generators\n: Create a well-defined project directory structure which organizes your code and allows you to package and distribute your application as a Gem. Generators can also help speed up the process of creating new commands, scripts, and hooks!\n\n\n\n\n\n\nIf you're just getting started with RBCli, take a look at the \nTutorial\n. Or take a look at the \nAdvanced\n menu above to look through RBCli's additional featureset.",
6
+ "title": "Home"
7
+ },
8
+ {
9
+ "location": "/#this-is-rbcli",
10
+ "text": "As technologists today, we work with the command line a lot. We script a lot. We write tools to share with each other to make our lives easier. We even write applications to make up for missing features in the 3rd party software that we buy. Unfortunately, when writing CLI tools, this process has typically been very painful. We've been working with low-level frameworks for decades; frameworks like getopt (1980) and curses (1977). They fit their purpose well; they were both computationally lightweight for the computers of the day, and they gave engineers full control and flexibility when it came to how things were built. Over the years, we've used them to settle on several design patterns that we know work well. Patterns as to what a CLI command looks like, what a config file looks like, what remote execution looks like, and even how to use locks (mutexes, semaphores, etc) to control application flow and data atomicity. Yet we're stuck writing the same low-level code anytime we want to write our tooling. Not anymore. Enter RBCli. RBCli is a framework to quickly develop advanced command-line tools in Ruby. It has been written from the ground up with the needs of the modern technologist in mind, designed to make advanced CLI tool development as painless as possible. In RBCli, low-level code has been wrapped and/or replaced with higher-level methods. Much of the functionality has even been reduced to single methods: for example, it takes just one declaration to define, load, and generate a user's config file at the appropriate times. Many other features are automated and require no work by the engineer. These make RBCli a fundamental re-thining of how we develop CLI tools, enabling the rapid development of applications for everyone from hobbyists to enterprises. Some of its key features include: Simple DSL Interface : To cut down on the amount of code that needs to be written, RBCli has a DSL that is designed to cut to the chase. This makes the work a lot less tedious. Multiple Levels of Parameters and Arguments : Forget about writing parsers for command-line options, or about having to differentiate between parameters and arguments. All of that work is taken care of. Config File Generation : Easily piece together a default configuration even with declarations in different parts of the code. Then the user can generate their own configuration, and it gets stored in whatever location you'd like. Multiple Hooks and Entry Points : Define commands, pre-execution hooks, post-execution hooks, and first_run hooks to quickly and easily customize the flow of your application code. Logging : Keep track of all instances of your tool through logging. Logs can go to STDOUT, STDERR, or a given file, making them compatible with log aggregators such as Splunk, Logstash, and many others. Local State Storage : Easily manage a set of data that persists between runs. You get access to a hash that is automatically kept in-sync with a file on disk. Remote State : It works just like Local State Storage, but store the data on a remote server! It can be used in tandem with Local State Storage or on its own. Currently supports AWS DyanmoDB. State Locking and Sharing : Share remote state safely between users with built-in locking! When enabled, it makes sure that only one user is accessing the data at any given time. Automatic Update Notifications : Just provide the gem name or git repo, and RBCli will take care of notifying users! External Script Wrapping : High-level wrapping for Bash scripts, or any other applcication you'd like to wrap into a command. Project Structure and Generators : Create a well-defined project directory structure which organizes your code and allows you to package and distribute your application as a Gem. Generators can also help speed up the process of creating new commands, scripts, and hooks! If you're just getting started with RBCli, take a look at the Tutorial . Or take a look at the Advanced menu above to look through RBCli's additional featureset.",
11
+ "title": "This is RBCli"
12
+ },
13
+ {
14
+ "location": "/imported/quick_reference/",
15
+ "text": "Quick Reference\n\n\nInstallation\n\n\nRBCli is available on rubygems.org. You can add it to your application's \nGemfile\n or \ngemspec\n, or install it manually by running:\n\n\ngem install rbcli\n\n\n\n\nThen, \ncd\n to the folder you'd like to create your project under and run:\n\n\nrbcli init -n mytool -d \nA simple CLI tool\n\n\n\n\n\nOr, for a single-file tool without any folder/gem tructure, run \nrbcli init -t mini -n \nprojectname\n or \nrbcli init -t micro -n \nprojectname\n.\n\n\nCreating a command\n\n\nThere are three types of commands: standard, scripted, and external.\n\n\n\n\nStandard\n commands let you code the command directly in Ruby\n\n\nScripted\n commands provide you with a bash script, where all of the parsed information (params, options, args, and config) is shared\n\n\nExternal\n commands let you wrap 3rd party applications directly\n\n\n\n\nStandard Commands\n\n\nTo create a new command called \nfoo\n, run:\n\n\nrbcli command -n foo\n\n\n\n\nYou will now find the command code in \napplication/commands/list.rb\n. Edit the \naction\n block to write your coode.\n\n\nScripted Commands\n\n\nTo create a new scripted command called \nbar\n, run:\n\n\nrbcli script -n bar\n\n\n\n\nYou will then find two new files:\n\n\n\n\nThe command declaration under \napplication/commands/bar.rb\n\n\nThe script code under \napplication/commands/scripts/bar.sh\n\n\n\n\nEdit the script to write your code.\n\n\nExternal Commands\n\n\nTo create a new external command called \nbaz\n, run:\n\n\nrbcli extern -n baz\n\n\n\n\nYou will then find the command code in \napplication/commands/baz.rb\n.\n\n\nUse one of the two provided modes -- direct path mode or variable path mode -- to provide the path to the external program.\n\n\nHooks\n\n\nRBCli has several hooks that run at different points in the exectution chain. They can be created via the \nrbcli\n command line tool:\n\n\nrbcli hook --default # Runs when no command is provided\nrbcli hook --pre # Runs before any command\nrbcli hook --post # Runs after any command\nrbcli hook --firstrun # Runs the first time a user runs your application. Requires userspace config.\nrbcli hook -dpof # Create all hooks at once\n\n\n\n\nStorage\n\n\nRBCli supports both local and remote state storage. This is done by synchronizing a Hash with either the local disk or a remote database.\n\n\nLocal State\n\n\nRBCli can provide you with a unique hash that can be persisted to disk on any change to a top-level value.\n\n\nEnable local state in \nconfig/storage.rb\n.\n\n\nThen access it in your Standard Commands with \nRbcli.local_state[:yourkeyhere]\n.\n\n\nRemote State\n\n\nSimilar to the Local State above, RBCli can provide you with a unique hash that can be persisted to a remote storage location.\n\n\nCurrently only AWS DynamoDB is supported, and credentials will be required for each user.\n\n\nEnable remote state in \nconfig/storage.rb\n.\n\n\nThen access it in your Standard Commands with \nRbcli.remote_state[:yourkeyhere]\n.\n\n\nUserspace Configuration Files\n\n\nRBCli provides an easy mechanism to generate and read configuration files from your users. You set the default values and help text with the \ndefaults chain\n, and leverage the \nuser chain\n to read them.\n\n\nYou can set defaults either by placing a YAML file in the \nuserconf/\n folder or by specifying individual options in \napplication/options.rb\n (global) or \napplication/command/*.rb\n (command-specific).\n\n\nUsers can generate a config file, complete with help text, by running your tool with the \n--generate-config\n option.\n\n\nLogging\n\n\nRBCli's logger is configured in \nconfig/logging.rb\n.\n\n\nlog_level :info\nlog_target 'stderr'\n\n\n\n\nThen it can be accessed when writing your commands via:\n\n\nRbcli::log.info { 'These logs can go to STDERR, STDOUT, or a file' }\n\n\n\n\nThe user will also be able to change the log level and target via their config file, if it is enabled.\n\n\nAutomatic Update Check\n\n\nRBCli can automatically notify users when an update is available. Two sources are currently supported: Github (including Enterprise) and RubyGems.\n\n\nYou can configure automatic updates in \nconfig/autoupdate.rb\n in your project.\n\n\nDevelopment and Contributing\n\n\nFor more information about development and contributing, please see the \nOfficial Development Documentation\n\n\nLicense\n\n\nThe gem is available as open source under the terms of the \nGPLv3\n.\n\n\nFull Documentation\n\n\nYou can find the Official Documentation for RBCli Here.",
16
+ "title": "Quick Reference"
17
+ },
18
+ {
19
+ "location": "/imported/quick_reference/#quick-reference",
20
+ "text": "",
21
+ "title": "Quick Reference"
22
+ },
23
+ {
24
+ "location": "/imported/quick_reference/#installation",
25
+ "text": "RBCli is available on rubygems.org. You can add it to your application's Gemfile or gemspec , or install it manually by running: gem install rbcli Then, cd to the folder you'd like to create your project under and run: rbcli init -n mytool -d A simple CLI tool Or, for a single-file tool without any folder/gem tructure, run rbcli init -t mini -n projectname or rbcli init -t micro -n projectname .",
26
+ "title": "Installation"
27
+ },
28
+ {
29
+ "location": "/imported/quick_reference/#creating-a-command",
30
+ "text": "There are three types of commands: standard, scripted, and external. Standard commands let you code the command directly in Ruby Scripted commands provide you with a bash script, where all of the parsed information (params, options, args, and config) is shared External commands let you wrap 3rd party applications directly",
31
+ "title": "Creating a command"
32
+ },
33
+ {
34
+ "location": "/imported/quick_reference/#standard-commands",
35
+ "text": "To create a new command called foo , run: rbcli command -n foo You will now find the command code in application/commands/list.rb . Edit the action block to write your coode.",
36
+ "title": "Standard Commands"
37
+ },
38
+ {
39
+ "location": "/imported/quick_reference/#scripted-commands",
40
+ "text": "To create a new scripted command called bar , run: rbcli script -n bar You will then find two new files: The command declaration under application/commands/bar.rb The script code under application/commands/scripts/bar.sh Edit the script to write your code.",
41
+ "title": "Scripted Commands"
42
+ },
43
+ {
44
+ "location": "/imported/quick_reference/#external-commands",
45
+ "text": "To create a new external command called baz , run: rbcli extern -n baz You will then find the command code in application/commands/baz.rb . Use one of the two provided modes -- direct path mode or variable path mode -- to provide the path to the external program.",
46
+ "title": "External Commands"
47
+ },
48
+ {
49
+ "location": "/imported/quick_reference/#hooks",
50
+ "text": "RBCli has several hooks that run at different points in the exectution chain. They can be created via the rbcli command line tool: rbcli hook --default # Runs when no command is provided\nrbcli hook --pre # Runs before any command\nrbcli hook --post # Runs after any command\nrbcli hook --firstrun # Runs the first time a user runs your application. Requires userspace config.\nrbcli hook -dpof # Create all hooks at once",
51
+ "title": "Hooks"
52
+ },
53
+ {
54
+ "location": "/imported/quick_reference/#storage",
55
+ "text": "RBCli supports both local and remote state storage. This is done by synchronizing a Hash with either the local disk or a remote database.",
56
+ "title": "Storage"
57
+ },
58
+ {
59
+ "location": "/imported/quick_reference/#local-state",
60
+ "text": "RBCli can provide you with a unique hash that can be persisted to disk on any change to a top-level value. Enable local state in config/storage.rb . Then access it in your Standard Commands with Rbcli.local_state[:yourkeyhere] .",
61
+ "title": "Local State"
62
+ },
63
+ {
64
+ "location": "/imported/quick_reference/#remote-state",
65
+ "text": "Similar to the Local State above, RBCli can provide you with a unique hash that can be persisted to a remote storage location. Currently only AWS DynamoDB is supported, and credentials will be required for each user. Enable remote state in config/storage.rb . Then access it in your Standard Commands with Rbcli.remote_state[:yourkeyhere] .",
66
+ "title": "Remote State"
67
+ },
68
+ {
69
+ "location": "/imported/quick_reference/#userspace-configuration-files",
70
+ "text": "RBCli provides an easy mechanism to generate and read configuration files from your users. You set the default values and help text with the defaults chain , and leverage the user chain to read them. You can set defaults either by placing a YAML file in the userconf/ folder or by specifying individual options in application/options.rb (global) or application/command/*.rb (command-specific). Users can generate a config file, complete with help text, by running your tool with the --generate-config option.",
71
+ "title": "Userspace Configuration Files"
72
+ },
73
+ {
74
+ "location": "/imported/quick_reference/#logging",
75
+ "text": "RBCli's logger is configured in config/logging.rb . log_level :info\nlog_target 'stderr' Then it can be accessed when writing your commands via: Rbcli::log.info { 'These logs can go to STDERR, STDOUT, or a file' } The user will also be able to change the log level and target via their config file, if it is enabled.",
76
+ "title": "Logging"
77
+ },
78
+ {
79
+ "location": "/imported/quick_reference/#automatic-update-check",
80
+ "text": "RBCli can automatically notify users when an update is available. Two sources are currently supported: Github (including Enterprise) and RubyGems. You can configure automatic updates in config/autoupdate.rb in your project.",
81
+ "title": "Automatic Update Check"
82
+ },
83
+ {
84
+ "location": "/imported/quick_reference/#development-and-contributing",
85
+ "text": "For more information about development and contributing, please see the Official Development Documentation",
86
+ "title": "Development and Contributing"
87
+ },
88
+ {
89
+ "location": "/imported/quick_reference/#license",
90
+ "text": "The gem is available as open source under the terms of the GPLv3 .",
91
+ "title": "License"
92
+ },
93
+ {
94
+ "location": "/imported/quick_reference/#full-documentation",
95
+ "text": "You can find the Official Documentation for RBCli Here.",
96
+ "title": "Full Documentation"
97
+ },
98
+ {
99
+ "location": "/tutorial/10-getting_started/",
100
+ "text": "Getting Started\n\n\nWelcome to the RBCli getting started tutorial! In this tutorial we're going to cover the basics of RBCli and get a simple application up and running. It should take you between 30-60 minutes to complete, depending on your skill level with Ruby.\n\n\nAs you go throught the tutorial, you can either use the \nNext\n and \nBack\n buttons on the page to navigate, or use the menu directly.\n\n\nSupported Ruby Versions\n\n\nYou'll need Ruby installed before you can use RBCli. If you don't know how to install it, we recommend using either \nrbenv\n (our favorite) or \nrvm\n.\n\n\nRBCli officially supports Ruby versions 2.5.0 and above. It may work on earlier releases even though we haven't tested them. If you do try it find any bugs that break compatibility, feel free to submit a github issue or pull request.\n\n\nInstallation\n\n\nRBCli is available on rubygems.org. You can add it to your application's \nGemfile\n or \ngemspec\n, or install it manually by running:\n\n\ngem install rbcli\n\n\n\n\nThen, \ncd\n to the folder you'd like to create your project under and run:\n\n\nrbcli init -n mytool -d \nA simple CLI tool\n\n\n\n\n\nwhere \nmytool\n can be replaced with any other command name you'd like. You should then see some output about generating a bunch of files. Once it finishes, run:\n\n\ncd mytool\nls -ahl\n\n\n\n\nCongratulations! This is the beginning of your first project.\n\n\nNext Steps\n\n\nNext, you will learn about the layout of an RBCli project and how to code with it.",
101
+ "title": "Getting Started"
102
+ },
103
+ {
104
+ "location": "/tutorial/10-getting_started/#getting-started",
105
+ "text": "Welcome to the RBCli getting started tutorial! In this tutorial we're going to cover the basics of RBCli and get a simple application up and running. It should take you between 30-60 minutes to complete, depending on your skill level with Ruby. As you go throught the tutorial, you can either use the Next and Back buttons on the page to navigate, or use the menu directly.",
106
+ "title": "Getting Started"
107
+ },
108
+ {
109
+ "location": "/tutorial/10-getting_started/#supported-ruby-versions",
110
+ "text": "You'll need Ruby installed before you can use RBCli. If you don't know how to install it, we recommend using either rbenv (our favorite) or rvm . RBCli officially supports Ruby versions 2.5.0 and above. It may work on earlier releases even though we haven't tested them. If you do try it find any bugs that break compatibility, feel free to submit a github issue or pull request.",
111
+ "title": "Supported Ruby Versions"
112
+ },
113
+ {
114
+ "location": "/tutorial/10-getting_started/#installation",
115
+ "text": "RBCli is available on rubygems.org. You can add it to your application's Gemfile or gemspec , or install it manually by running: gem install rbcli Then, cd to the folder you'd like to create your project under and run: rbcli init -n mytool -d A simple CLI tool where mytool can be replaced with any other command name you'd like. You should then see some output about generating a bunch of files. Once it finishes, run: cd mytool\nls -ahl Congratulations! This is the beginning of your first project.",
116
+ "title": "Installation"
117
+ },
118
+ {
119
+ "location": "/tutorial/10-getting_started/#next-steps",
120
+ "text": "Next, you will learn about the layout of an RBCli project and how to code with it.",
121
+ "title": "Next Steps"
122
+ },
123
+ {
124
+ "location": "/tutorial/20-project_layout/",
125
+ "text": "The Project Layout\n\n\nNow we will learn about what an RBCli project looks like and how to start using it.\n\n\nProject Initialization Types\n\n\nRBCli can initialize a tool in three different modes:\n\n\n\n\nProject Mode (default)\n\n\nMini Mode\n\n\nMicro Mode\n\n\n\n\nProject Mode\n\n\nIf you've been following along with the tutorial, you've already seen Project Mode. An RBCli Project consists of several folders, each of which has a specific function. The RBCli framework handles loading and parsing the code automatically. To generate a standard, full-featured RBCli project, run:\n\n\nrbcli init -n mytool\n\n\n\n\nwhere \nmytool\n can be replaced with any other command name you'd like. (We will continue using \nmytool\n in this tutorial though!)\n\n\nInside the newly created \nmytool\n folder you will see a bunch of files and folders related to your project. We will go over the structure later.\n\n\nMini \n Micro Modes\n\n\nIf you need to write a CLI tool but project mode feels a bit overkill for you -- if you think a single-file script is all that is needed -- that's where the Mini and Micro modes come in. Instead of generating a full directory tree, you get only a single file that contains most of the functionality of RBCli. To use it, run:\n\n\nrbcli init -n mytool -t mini\n# or\nrbcli init -n mytool -t micro\n\n\n\n\nThe only difference between the two is that \nmini\n will show you all available options and some documentation to help you, while \nmicro\n is for advanced users who just want the samllest file possible.\n\n\nAs far as documentation goes, every piece of code present in those files is identical to Project mode so it should be pretty easy to navigate.\n\n\nProject Mode Structure\n\n\nAn RBCli project has the following structure:\n\n\nname\n/\n|--- application/\n| |--- commands/\n| | |--- scripts/\n| |--- options.rb\n|--- config/\n|--- exe/\n| |--- \nname\n\n|--- hooks/\n|--- lib/\n|--- spec/\n|--- userconf/\n|--- .gitignore\n|--- .rbcli\n|--- .rspec\n|--- CODE_OF_CONDUCT.md\n|--- Gemfile\n|--- README.md\n|--- Rakefile\n|--- \nname\n.gemspec\n\n\n\n\nGit, RubyGems, and rspec\n\n\nA few files aren't part of RBCli itself, but are provided for your convenience. If you're experienced in Ruby and Git you can skip over this.\n\n\n\n\n.gitignore\n\n\nSpecifies which files to ignore in git. If you don't use git you can delete this file\n\n\n\n\n\n\n.rspec\n\n\nConfigures Rspec for testing your code\n\n\n\n\n\n\nGemfile\n\n\nAllows declaring dependencies for when your users install your application\n\n\n\n\n\n\nGemspec\n\n\nSame as above, but also lets you fill in more information so that you can publish your application as a gem\n\n\n\n\n\n\nREADME.md\n\n\nA skeleton README file that will appear as a front page documentation to your code in most source control systems (i.e. Github, Bitbucket)\n\n\n\n\n\n\nCODE_OF_CONDUCT.md\n\n\nTaken directly from the \ncontributor covenant\n for your convenience\n\n\n\n\n\n\nRakefile\n\n\nSo you can run rspec tests as a rake task\n\n\n\n\n\n\n\n\nThere is a lot of controvesy online regarding using the \ngemfile\n vs the \ngemspec\n. If you are new to Ruby in general then I suggest declaring your dependencies in the gemspec and leaving the \ngemfile\n as-is. This keeps things simple and allows publishing and distributing your tool as a gem.\n\n\nAdditionally, note that a git repo is not created automatically. Using git is out of scope of this tutorial, but you can find tutorials \nhere\n.\n\n\nRBCli Folders\n\n\n\n\napplication/\n\n\nThis is where the core of your application will live. You will define CLI options, commands, scripts, and hooks within this folder.\n\n\n\n\n\n\nconfig/\n\n\nThis folder contains the configuration for RBCli's features; such as storage, logging, and automatic updates.\n\n\n\n\n\n\nexe/\n\n\nThis folder contains the executable for your tool. You should not edit it; doing so may lead to unexpected behavior.\n\n\n\n\n\n\nhooks/\n\n\nRBCli has several hooks that can be used to run code at different times, such as the 'default' code that is run when no command is selected. This is where they are placed.\n\n\n\n\n\n\nlib/\n\n\nThis folder is for you to write any additional code as you see fit, for importing into your commands, scripts, and hooks. It is automatically added to the $LOAD_PATH for you, so you can just use require statements like \nrequire 'abc.rb'\n without worrying about where they are located on the filesystem.\n\n\n\n\n\n\nuserconf/\n\n\nThis folder is for you to place the layout and defaults of any userspace config file. Acceptable formats are yaml and json, though we recommend YAML since it is by far easier to read and supports comments.\n\n\n\n\n\n\nspec/\n\n\nThis folder is for your rspec tests.\n\n\n\n\n\n\n.rbcli\n\n\nThis file is for internal use by RBCli. It should not be modified or deleted.\n\n\n\n\n\n\n\n\nNext Steps\n\n\nFor the purposes of getting started right now, you don't actually need to edit any of the defaults already present.\n\n\nWe just finished going through what an RBCli project looks like. Now let's create our first application with it!",
126
+ "title": "The Project Layout"
127
+ },
128
+ {
129
+ "location": "/tutorial/20-project_layout/#the-project-layout",
130
+ "text": "Now we will learn about what an RBCli project looks like and how to start using it.",
131
+ "title": "The Project Layout"
132
+ },
133
+ {
134
+ "location": "/tutorial/20-project_layout/#project-initialization-types",
135
+ "text": "RBCli can initialize a tool in three different modes: Project Mode (default) Mini Mode Micro Mode",
136
+ "title": "Project Initialization Types"
137
+ },
138
+ {
139
+ "location": "/tutorial/20-project_layout/#project-mode",
140
+ "text": "If you've been following along with the tutorial, you've already seen Project Mode. An RBCli Project consists of several folders, each of which has a specific function. The RBCli framework handles loading and parsing the code automatically. To generate a standard, full-featured RBCli project, run: rbcli init -n mytool where mytool can be replaced with any other command name you'd like. (We will continue using mytool in this tutorial though!) Inside the newly created mytool folder you will see a bunch of files and folders related to your project. We will go over the structure later.",
141
+ "title": "Project Mode"
142
+ },
143
+ {
144
+ "location": "/tutorial/20-project_layout/#mini-micro-modes",
145
+ "text": "If you need to write a CLI tool but project mode feels a bit overkill for you -- if you think a single-file script is all that is needed -- that's where the Mini and Micro modes come in. Instead of generating a full directory tree, you get only a single file that contains most of the functionality of RBCli. To use it, run: rbcli init -n mytool -t mini\n# or\nrbcli init -n mytool -t micro The only difference between the two is that mini will show you all available options and some documentation to help you, while micro is for advanced users who just want the samllest file possible. As far as documentation goes, every piece of code present in those files is identical to Project mode so it should be pretty easy to navigate.",
146
+ "title": "Mini & Micro Modes"
147
+ },
148
+ {
149
+ "location": "/tutorial/20-project_layout/#project-mode-structure",
150
+ "text": "An RBCli project has the following structure: name /\n|--- application/\n| |--- commands/\n| | |--- scripts/\n| |--- options.rb\n|--- config/\n|--- exe/\n| |--- name \n|--- hooks/\n|--- lib/\n|--- spec/\n|--- userconf/\n|--- .gitignore\n|--- .rbcli\n|--- .rspec\n|--- CODE_OF_CONDUCT.md\n|--- Gemfile\n|--- README.md\n|--- Rakefile\n|--- name .gemspec",
151
+ "title": "Project Mode Structure"
152
+ },
153
+ {
154
+ "location": "/tutorial/20-project_layout/#git-rubygems-and-rspec",
155
+ "text": "A few files aren't part of RBCli itself, but are provided for your convenience. If you're experienced in Ruby and Git you can skip over this. .gitignore Specifies which files to ignore in git. If you don't use git you can delete this file .rspec Configures Rspec for testing your code Gemfile Allows declaring dependencies for when your users install your application Gemspec Same as above, but also lets you fill in more information so that you can publish your application as a gem README.md A skeleton README file that will appear as a front page documentation to your code in most source control systems (i.e. Github, Bitbucket) CODE_OF_CONDUCT.md Taken directly from the contributor covenant for your convenience Rakefile So you can run rspec tests as a rake task There is a lot of controvesy online regarding using the gemfile vs the gemspec . If you are new to Ruby in general then I suggest declaring your dependencies in the gemspec and leaving the gemfile as-is. This keeps things simple and allows publishing and distributing your tool as a gem. Additionally, note that a git repo is not created automatically. Using git is out of scope of this tutorial, but you can find tutorials here .",
156
+ "title": "Git, RubyGems, and rspec"
157
+ },
158
+ {
159
+ "location": "/tutorial/20-project_layout/#rbcli-folders",
160
+ "text": "application/ This is where the core of your application will live. You will define CLI options, commands, scripts, and hooks within this folder. config/ This folder contains the configuration for RBCli's features; such as storage, logging, and automatic updates. exe/ This folder contains the executable for your tool. You should not edit it; doing so may lead to unexpected behavior. hooks/ RBCli has several hooks that can be used to run code at different times, such as the 'default' code that is run when no command is selected. This is where they are placed. lib/ This folder is for you to write any additional code as you see fit, for importing into your commands, scripts, and hooks. It is automatically added to the $LOAD_PATH for you, so you can just use require statements like require 'abc.rb' without worrying about where they are located on the filesystem. userconf/ This folder is for you to place the layout and defaults of any userspace config file. Acceptable formats are yaml and json, though we recommend YAML since it is by far easier to read and supports comments. spec/ This folder is for your rspec tests. .rbcli This file is for internal use by RBCli. It should not be modified or deleted.",
161
+ "title": "RBCli Folders"
162
+ },
163
+ {
164
+ "location": "/tutorial/20-project_layout/#next-steps",
165
+ "text": "For the purposes of getting started right now, you don't actually need to edit any of the defaults already present. We just finished going through what an RBCli project looks like. Now let's create our first application with it!",
166
+ "title": "Next Steps"
167
+ },
168
+ {
169
+ "location": "/tutorial/30-your_first_command/",
170
+ "text": "Your First Command\n\n\nCreating the Command\n\n\nCreating the command is straightforward:\n\n\nrbcli command --name=list\n#or\nrbcli command -n list\n\n\n\n\nAnd there you have it! Now you can try out your command by typing:\n\n\n./exe/mytool list\n\n\n\n\nCongrats! You should now see a generic output listing the values of several variables. We'll get into what they mean in a bit, but first, let's make the tool's execution a bit easier.\n\n\nNow that you know your way around a project, its time to create your first command! But before we do, let's make development just a little bit easier. Go to the base directory of the folder and type:\n\n\nalias mytool=\n$(pwd)/exe/mytool\n\n\n\n\n\nAnd now you'll be able to execute your application as if it was already installed as a gem, without worrying about the working path. You can see this in action by running your application again, but without the path:\n\n\nmytool list\n\n\n\n\nSo, now let's take a more in-dpeth look at what the command code looks like.\n\n\nThe Command Declaration\n\n\nAs mentioned in the previous section, you can find your commands listed under the \napplication/commands/\n directory. Each command will appear as its own unique file with some base code to work from. Let's take a look at that code a little more in-depth:\n\n\nclass List \n Rbcli::Command # Declare a new command by subclassing Rbcli::Command\n description 'TODO: Description goes here' # (Required) Short description for the global help\n usage \n-EOF\nTODO: Usage text goes here\nEOF # (Required) Long description for the command-specific help\n parameter :force, 'Force testing', type: :boolean, default: false, required: false # (Optional, Multiple) Add a command-specific CLI parameter. Can be called multiple times\n\n config_default :myopt2, description: 'My Option #2', default: 'Default Value Here' # (Optional, Multiple) Specify an individual configuration parameter and set a default value. These will also be included in generated user config.\n # Alternatively, you can simply create a yaml file in the `default_user_configs` directory in your project that specifies the default values of all options\n\n action do |params, args, global_opts, config| # (Required) Block to execute if the command is called.\n Rbcli::log.info { 'These logs can go to STDERR, STDOUT, or a file' } # Example log. Interface is identical to Ruby's logger\n puts \n\\nArgs:\\n#{args}\n # Arguments that came after the command on the CLI (i.e.: `mytool test bar baz` will yield args=['bar', 'baz'])\n puts \nParams:\\n#{params}\n # Parameters, as described through the option statements above\n puts \nGlobal opts:\\n#{global_opts}\n # Global Parameters, as descirbed in the Configurate section\n puts \nConfig:\\n#{config}\n # Config file values\n puts \nLocalState:\\n#{Rbcli.local_state}\n # Local persistent state storage (when available) -- if unsure use Rbcli.local_state.nil?\n puts \nRemoteState:\\n#{Rbcli.remote_state}\n # Remote persistent state storage (when available) -- if unsure use Rbcli.remote_state.nil?\n puts \n\\nDone!!!\n\n end\nend\n\n\n\n\nCommands are declared to RBCli simply by subclassing them from \nRbcli::Command\n as shown above. Then, you have a list of declarations that tell RBCli information about it. They are:\n\n\n\n\ndescription\n\n\nA short description of the command, which will appear in the top-level help (when the user runs \nmytool -h\n).\n\n\n\n\n\n\nusage\n\n\nA description of how the command is meant to be used. This description can be as long as you want, and can be as in-depth as you'd like. It will show up as a long, multi-line description when the user runs the command-sepcific help (\nmytool list -h\n).\n\n\n\n\n\n\nparameter\n\n\nCommand-line tags that the user can enter that are specific to only this command. We will get into these in the next section on \nOptions, Parameters, and Arguments\n\n\n\n\n\n\nconfig_default\n\n\nThis sets a single item in the config file that will be made available to the user. More information can be found in the documentation on \nUser Config Files\n\n\n\n\n\n\naction\n\n\nThis loads the block of code that will run when the command is called. It brings in all of the CLI and user config data as variables. We will also get into these in the next section \nOptions, Parameters, and Arguments\n\n\n\n\n\n\n\n\nThere is an additional declaration not shown here, \nextern\n. You can find more information on it in the section on \nAdvanced Command Types\n\n\nCreating the \"list\" Command\n\n\nNow we're going to modify this command to list the contents of the current directory to the terminal. So let's change the code in that file to:\n\n\nclass List \n Rbcli::Command\n description %q{List files in current directory}\n usage \n-EOF\nEver wanted to see your files?\nNow you can!\nEOF\n\n action do |params, args, global_opts, config|\n filelist = []\n\n # We store a list of the files in an array, including dotfiles if specified\n Dir.glob \n./*\n do |filename|\n outname = filename.split('/')[1]\n outname += '/' if File.directory? filename\n filelist.append outname\n end\n\n # Apply color\n filelist.map! do |filename|\n if File.directory? filename\n filename.light_blue\n elsif File.executable? filename\n filename.light_green\n else\n filename\n end\n end if global_opts[:color]\n\n puts filelist\n end\nend\n\n\n\n\nGo ahead and test it out! The output doesn't show much obviously, just a list of names and nothing else. Don't worry though, we'll fix that in the next secion.\n\n\nNext Steps\n\n\nNext we're going to take a look at options, parameters, and arguments, and we'll clean up our list command by using them. If you'd like to learn more about the additional command types in RBCli before continuing, see the \nAdvanced Command Types\n documentation.",
171
+ "title": "Your First Command"
172
+ },
173
+ {
174
+ "location": "/tutorial/30-your_first_command/#your-first-command",
175
+ "text": "",
176
+ "title": "Your First Command"
177
+ },
178
+ {
179
+ "location": "/tutorial/30-your_first_command/#creating-the-command",
180
+ "text": "Creating the command is straightforward: rbcli command --name=list\n#or\nrbcli command -n list And there you have it! Now you can try out your command by typing: ./exe/mytool list Congrats! You should now see a generic output listing the values of several variables. We'll get into what they mean in a bit, but first, let's make the tool's execution a bit easier. Now that you know your way around a project, its time to create your first command! But before we do, let's make development just a little bit easier. Go to the base directory of the folder and type: alias mytool= $(pwd)/exe/mytool And now you'll be able to execute your application as if it was already installed as a gem, without worrying about the working path. You can see this in action by running your application again, but without the path: mytool list So, now let's take a more in-dpeth look at what the command code looks like.",
181
+ "title": "Creating the Command"
182
+ },
183
+ {
184
+ "location": "/tutorial/30-your_first_command/#the-command-declaration",
185
+ "text": "As mentioned in the previous section, you can find your commands listed under the application/commands/ directory. Each command will appear as its own unique file with some base code to work from. Let's take a look at that code a little more in-depth: class List Rbcli::Command # Declare a new command by subclassing Rbcli::Command\n description 'TODO: Description goes here' # (Required) Short description for the global help\n usage -EOF\nTODO: Usage text goes here\nEOF # (Required) Long description for the command-specific help\n parameter :force, 'Force testing', type: :boolean, default: false, required: false # (Optional, Multiple) Add a command-specific CLI parameter. Can be called multiple times\n\n config_default :myopt2, description: 'My Option #2', default: 'Default Value Here' # (Optional, Multiple) Specify an individual configuration parameter and set a default value. These will also be included in generated user config.\n # Alternatively, you can simply create a yaml file in the `default_user_configs` directory in your project that specifies the default values of all options\n\n action do |params, args, global_opts, config| # (Required) Block to execute if the command is called.\n Rbcli::log.info { 'These logs can go to STDERR, STDOUT, or a file' } # Example log. Interface is identical to Ruby's logger\n puts \\nArgs:\\n#{args} # Arguments that came after the command on the CLI (i.e.: `mytool test bar baz` will yield args=['bar', 'baz'])\n puts Params:\\n#{params} # Parameters, as described through the option statements above\n puts Global opts:\\n#{global_opts} # Global Parameters, as descirbed in the Configurate section\n puts Config:\\n#{config} # Config file values\n puts LocalState:\\n#{Rbcli.local_state} # Local persistent state storage (when available) -- if unsure use Rbcli.local_state.nil?\n puts RemoteState:\\n#{Rbcli.remote_state} # Remote persistent state storage (when available) -- if unsure use Rbcli.remote_state.nil?\n puts \\nDone!!! \n end\nend Commands are declared to RBCli simply by subclassing them from Rbcli::Command as shown above. Then, you have a list of declarations that tell RBCli information about it. They are: description A short description of the command, which will appear in the top-level help (when the user runs mytool -h ). usage A description of how the command is meant to be used. This description can be as long as you want, and can be as in-depth as you'd like. It will show up as a long, multi-line description when the user runs the command-sepcific help ( mytool list -h ). parameter Command-line tags that the user can enter that are specific to only this command. We will get into these in the next section on Options, Parameters, and Arguments config_default This sets a single item in the config file that will be made available to the user. More information can be found in the documentation on User Config Files action This loads the block of code that will run when the command is called. It brings in all of the CLI and user config data as variables. We will also get into these in the next section Options, Parameters, and Arguments There is an additional declaration not shown here, extern . You can find more information on it in the section on Advanced Command Types",
186
+ "title": "The Command Declaration"
187
+ },
188
+ {
189
+ "location": "/tutorial/30-your_first_command/#creating-the-list-command",
190
+ "text": "Now we're going to modify this command to list the contents of the current directory to the terminal. So let's change the code in that file to: class List Rbcli::Command\n description %q{List files in current directory}\n usage -EOF\nEver wanted to see your files?\nNow you can!\nEOF\n\n action do |params, args, global_opts, config|\n filelist = []\n\n # We store a list of the files in an array, including dotfiles if specified\n Dir.glob ./* do |filename|\n outname = filename.split('/')[1]\n outname += '/' if File.directory? filename\n filelist.append outname\n end\n\n # Apply color\n filelist.map! do |filename|\n if File.directory? filename\n filename.light_blue\n elsif File.executable? filename\n filename.light_green\n else\n filename\n end\n end if global_opts[:color]\n\n puts filelist\n end\nend Go ahead and test it out! The output doesn't show much obviously, just a list of names and nothing else. Don't worry though, we'll fix that in the next secion.",
191
+ "title": "Creating the \"list\" Command"
192
+ },
193
+ {
194
+ "location": "/tutorial/30-your_first_command/#next-steps",
195
+ "text": "Next we're going to take a look at options, parameters, and arguments, and we'll clean up our list command by using them. If you'd like to learn more about the additional command types in RBCli before continuing, see the Advanced Command Types documentation.",
196
+ "title": "Next Steps"
197
+ },
198
+ {
199
+ "location": "/tutorial/40-options_parameters_and_arguments/",
200
+ "text": "Options, Paramters, and Arguments\n\n\nIf you're already an experienced coder, you can jump to the last section of this document, the \nSimplified Reference (TLDR)\n\n\nCommand Line Structure\n\n\nIn the previous section, you saw two parts of the RBCli command line structure - the executable followed by the command. However, RBCli is capable of more complex interaction. The structure is as follows:\n\n\ntoolname [options] command [parameters] argument1 argument2...\n\n\n\n\n\n\nOptions\n are command line parameters such as \n-f\n, or \n--force\n. These are available globally to every command. You can create your own, though several are already built-in and reserved for RBCli:\n\n\n--config-file=\nfilename\n allows specifying a config file location manually.\n\n\n--generate-config\n generates a config file for the user by writing out the defaults to a YAML file. This option will only appear if a config file has been set. The location is configurable, with more on that in the documentation on \nUser Config Files\n).\n\n\n-v / --version\n shows the version.\n\n\n-h / --help\n shows the help.\n\n\n\n\n\n\nCommand\n represents the subcommands that you will create, such as \nlist\n, \ntest\n, or \napply\n.\n\n\nParameters\n are the same as options, but only apply to the specific subcommand being executed. In this case only the \n-h / --help\n parameter is provided automatically.\n\n\nArguments\n are strings that don't begin with a '-', and are passed to the command's code as an array. These can be used as subcommands or additional parameters for your command. \n\n\n\n\nSo a valid command could look something like these:\n\n\nmytool -n load --filename=foo.txt\nmytool parse foo.txt\nmytool show -l\n\n\n\n\nNote that all options and parameters will have both a short and long version of the parameter available for use.\n\n\nSo let's take a look at how we define them.\n\n\nOptions\n\n\nYou can find the options declarations under \napplication/options.rb\n. You'll see the example in the code:\n\n\noption :name, 'Give me your name', short: 'n', type: :string, default: 'Jack', required: false, permitted: ['Jack', 'Jill']\n\n\n\n\nThis won't do for our tool, so let's change it. Remember that these options will be applicable to all of our commands, so lets make it something appropriate:\n\n\noption :color, 'Enable color output', short: 'c', type: :boolean, default: false\n\n\n\n\nSo now, let's take advantage of this flag in our \nlist\n command. Let's change our block to:\n\n\n action do |params, args, global_opts, config|\n Dir.glob \n./*\n do |filename|\n outname = filename.split('/')[1]\n outname += '/' if File.directory? filename\n\n # We change the color based on the kind of file shown\n if global_opts[:color]\n if File.directory? filename\n outname = outname.light_blue\n elsif File.executable? filename\n outname = outname.light_green\n end\n end\n\n puts outname\n end\n end\n\n\n\n\nNotice how we referenced the value by using \nglobal_opts[:color]\n. It's that simple. To see it in action, run:\n\n\nmytool -c list\n\n\n\n\nParameters\n\n\nParameters work the same way as options, but they are localized to only the selected command. They are declared - as you probably guessed by now - in the command's class. So let's add the following lines to our list command within the class declaration:\n\n\nparameter :sort, 'Sort output alphabetically', type: :boolean, default: false\nparameter :all, 'Show hidden files', type: :boolean, default: false\nparameter :directoriesfirst, 'Show directories on top', type: :boolean, default: false\n\n\n\n\nAnd let's modify our action block to utilize them:\n\n\n action do |params, args, global_opts, config|\n filelist = []\n\n # We include dotfiles if specified\n include_dotfiles = (params[:all]) ? File::FNM_DOTMATCH : 0\n\n # We store a list of the files in an array, including dotfiles if specified\n Dir.glob \n./*\n, include_dotfiles do |filename|\n outname = filename.split('/')[1]\n outname += '/' if File.directory? filename\n filelist.append outname\n end\n\n # Sort alphabetically if specified\n filelist.sort! if params[:sort]\n\n # Put directories first if specified\n if params[:directoriesfirst]\n files = []; dirs = []\n filelist.each do |filename|\n if File.directory? filename\n dirs.append(filename)\n else\n files.append(filename)\n end\n end\n filelist = dirs + files\n end\n\n # Apply color. We do this at the end now because color codes can alter the sorting.\n filelist.map! do |filename|\n if File.directory? filename\n filename.light_blue\n elsif File.executable? filename\n filename.light_green\n else\n filename\n end\n end if global_opts[:color]\n\n puts filelist\n end\n\n\n\n\nYou should be able to run it now:\n\n\nmytool -c list -asd\n\n\n\n\nNote how the parameters come after the \nlist\n command in the syntax above. As you create more commands, each will have its own unique set of parameters, while the options remain \nbefore\n the command and are available to all of them.\n\n\nArguments\n\n\nLastly on the command line, there are arguments. Arguments are simply strings without the \n-\n character in front, and automatically get passed into an array in your applicaiton. Let's take a look at how we can use them.\n\n\nUnlike options and parameters, arguments require no setup. So let's assume that we want any arguments passed to the \nlist\n command to be filenames that you want to display, and that you can pass multiple ones. Since arguments aren't listed automatically by the help function, this is a good example of what to put in your usage text. Let's take a look at what our class looks like now:\n\n\nclass List \n Rbcli::Command\n description %q{List files in current directory}\n usage \n-EOF\nTo list only specific files, you can enter filenames as arguments\n\n mytool list filename1 filename2...\nEOF\n parameter :sort, 'Sort output alphabetically', type: :boolean, default: false\n parameter :all, 'Show hidden files', type: :boolean, default: false\n parameter :directoriesfirst, 'Show directories on top', type: :boolean, default: false\n\n action do |params, args, global_opts, config|\n filelist = []\n\n # We include dotfiles if specified\n include_dotfiles = (params[:all]) ? File::FNM_DOTMATCH : 0\n\n # We store a list of the files in an array, including dotfiles if specified\n Dir.glob \n./*\n, include_dotfiles do |filename|\n outname = filename.split('/')[1]\n next unless args.include? outname if args.length \n 0\n outname += '/' if File.directory? filename\n filelist.append outname\n end\n\n # Sort alphabetically if specified\n filelist.sort! if params[:sort]\n\n # Put directories first if specified\n if params[:directoriesfirst]\n files = []; dirs = []\n filelist.each do |filename|\n if File.directory? filename\n dirs.append(filename)\n else\n files.append(filename)\n end\n end\n filelist = dirs + files\n end\n\n # Apply color. We do this at the end because color codes can alter the sorting\n filelist.map! do |filename|\n if File.directory? filename\n filename.light_blue\n elsif File.executable? filename\n filename.light_green\n else\n filename\n end\n end if global_opts[:color]\n\n puts filelist\n end\nend\n\n\n\n\nSimplified Reference (TLDR)\n\n\nRBCli enforces a CLI structure of:\n\n\ntoolname [options] command [parameters] argument1 argument2...\n\n\n\n\nOptions\n are declared in \napplication/options.rb\n file.\n\n\nParameters\n are declared in the respective command's class declaration.\n\n\nArguments\n don't need to be declared, and are passed in as an array to your commands. It is helpful to describe the argument purpose in the \nusage\n text declaration so that the user can see what to do in the help.\n\n\nOptions\n and \nparameters\n both use the same format:\n\n\noption :\nname\n, \ndescription_string\n, short: '\ncharacter\n', type: \nvariable_type\n, default: \ndefault_value\n, permitted: [\narray_of_permitted_values]\n\nparameter :\nname\n, \ndescription_string\n, short: '\ncharacter\n', type: \nvariable_type\n, default: \ndefault_value\n, permitted: [\narray_of_permitted_values]\n\n\n\n\n\n\nname\n\n\n(Required) The long name of the option, as a symbol. This will be represented as \n--name\n on the command line\n\n\n\n\n\n\ndescription_string\n\n\n(Required) A short description of the command that will appear in the help text for the user\n\n\n\n\n\n\ntype\n\n\n(Required) The following types are supported: \n:string\n, \n:boolean\n or \n:flag\n, \n:integer\n, and \n:float\n\n\n\n\n\n\ndefault\n\n\n(Optional) A default value for the option if one isn't entered (default: nil)\n\n\n\n\n\n\nshort\n\n\n(Optional) A letter that acts as a shortcut for the option. This will allow users to apply the command as \n-n\n\n\nTo not have a short value, set this to :none (default: the first letter of the long name)\n\n\n\n\n\n\nrequired\n\n\n(Optional) Specify whether the option is required from the user (default: false)\n\n\n\n\n\n\npermitted\n\n\n(Optional) An array of whitelisted values for the option (default: nil)\n\n\n\n\n\n\n\n\nNext Steps\n\n\nNext, we're going to take a quick look at how to publish and distribute your application, both publicly and within your organization.",
201
+ "title": "Options, Parameters, and Arguments"
202
+ },
203
+ {
204
+ "location": "/tutorial/40-options_parameters_and_arguments/#options-paramters-and-arguments",
205
+ "text": "If you're already an experienced coder, you can jump to the last section of this document, the Simplified Reference (TLDR)",
206
+ "title": "Options, Paramters, and Arguments"
207
+ },
208
+ {
209
+ "location": "/tutorial/40-options_parameters_and_arguments/#command-line-structure",
210
+ "text": "In the previous section, you saw two parts of the RBCli command line structure - the executable followed by the command. However, RBCli is capable of more complex interaction. The structure is as follows: toolname [options] command [parameters] argument1 argument2... Options are command line parameters such as -f , or --force . These are available globally to every command. You can create your own, though several are already built-in and reserved for RBCli: --config-file= filename allows specifying a config file location manually. --generate-config generates a config file for the user by writing out the defaults to a YAML file. This option will only appear if a config file has been set. The location is configurable, with more on that in the documentation on User Config Files ). -v / --version shows the version. -h / --help shows the help. Command represents the subcommands that you will create, such as list , test , or apply . Parameters are the same as options, but only apply to the specific subcommand being executed. In this case only the -h / --help parameter is provided automatically. Arguments are strings that don't begin with a '-', and are passed to the command's code as an array. These can be used as subcommands or additional parameters for your command. So a valid command could look something like these: mytool -n load --filename=foo.txt\nmytool parse foo.txt\nmytool show -l Note that all options and parameters will have both a short and long version of the parameter available for use. So let's take a look at how we define them.",
211
+ "title": "Command Line Structure"
212
+ },
213
+ {
214
+ "location": "/tutorial/40-options_parameters_and_arguments/#options",
215
+ "text": "You can find the options declarations under application/options.rb . You'll see the example in the code: option :name, 'Give me your name', short: 'n', type: :string, default: 'Jack', required: false, permitted: ['Jack', 'Jill'] This won't do for our tool, so let's change it. Remember that these options will be applicable to all of our commands, so lets make it something appropriate: option :color, 'Enable color output', short: 'c', type: :boolean, default: false So now, let's take advantage of this flag in our list command. Let's change our block to: action do |params, args, global_opts, config|\n Dir.glob ./* do |filename|\n outname = filename.split('/')[1]\n outname += '/' if File.directory? filename\n\n # We change the color based on the kind of file shown\n if global_opts[:color]\n if File.directory? filename\n outname = outname.light_blue\n elsif File.executable? filename\n outname = outname.light_green\n end\n end\n\n puts outname\n end\n end Notice how we referenced the value by using global_opts[:color] . It's that simple. To see it in action, run: mytool -c list",
216
+ "title": "Options"
217
+ },
218
+ {
219
+ "location": "/tutorial/40-options_parameters_and_arguments/#parameters",
220
+ "text": "Parameters work the same way as options, but they are localized to only the selected command. They are declared - as you probably guessed by now - in the command's class. So let's add the following lines to our list command within the class declaration: parameter :sort, 'Sort output alphabetically', type: :boolean, default: false\nparameter :all, 'Show hidden files', type: :boolean, default: false\nparameter :directoriesfirst, 'Show directories on top', type: :boolean, default: false And let's modify our action block to utilize them: action do |params, args, global_opts, config|\n filelist = []\n\n # We include dotfiles if specified\n include_dotfiles = (params[:all]) ? File::FNM_DOTMATCH : 0\n\n # We store a list of the files in an array, including dotfiles if specified\n Dir.glob ./* , include_dotfiles do |filename|\n outname = filename.split('/')[1]\n outname += '/' if File.directory? filename\n filelist.append outname\n end\n\n # Sort alphabetically if specified\n filelist.sort! if params[:sort]\n\n # Put directories first if specified\n if params[:directoriesfirst]\n files = []; dirs = []\n filelist.each do |filename|\n if File.directory? filename\n dirs.append(filename)\n else\n files.append(filename)\n end\n end\n filelist = dirs + files\n end\n\n # Apply color. We do this at the end now because color codes can alter the sorting.\n filelist.map! do |filename|\n if File.directory? filename\n filename.light_blue\n elsif File.executable? filename\n filename.light_green\n else\n filename\n end\n end if global_opts[:color]\n\n puts filelist\n end You should be able to run it now: mytool -c list -asd Note how the parameters come after the list command in the syntax above. As you create more commands, each will have its own unique set of parameters, while the options remain before the command and are available to all of them.",
221
+ "title": "Parameters"
222
+ },
223
+ {
224
+ "location": "/tutorial/40-options_parameters_and_arguments/#arguments",
225
+ "text": "Lastly on the command line, there are arguments. Arguments are simply strings without the - character in front, and automatically get passed into an array in your applicaiton. Let's take a look at how we can use them. Unlike options and parameters, arguments require no setup. So let's assume that we want any arguments passed to the list command to be filenames that you want to display, and that you can pass multiple ones. Since arguments aren't listed automatically by the help function, this is a good example of what to put in your usage text. Let's take a look at what our class looks like now: class List Rbcli::Command\n description %q{List files in current directory}\n usage -EOF\nTo list only specific files, you can enter filenames as arguments\n\n mytool list filename1 filename2...\nEOF\n parameter :sort, 'Sort output alphabetically', type: :boolean, default: false\n parameter :all, 'Show hidden files', type: :boolean, default: false\n parameter :directoriesfirst, 'Show directories on top', type: :boolean, default: false\n\n action do |params, args, global_opts, config|\n filelist = []\n\n # We include dotfiles if specified\n include_dotfiles = (params[:all]) ? File::FNM_DOTMATCH : 0\n\n # We store a list of the files in an array, including dotfiles if specified\n Dir.glob ./* , include_dotfiles do |filename|\n outname = filename.split('/')[1]\n next unless args.include? outname if args.length 0\n outname += '/' if File.directory? filename\n filelist.append outname\n end\n\n # Sort alphabetically if specified\n filelist.sort! if params[:sort]\n\n # Put directories first if specified\n if params[:directoriesfirst]\n files = []; dirs = []\n filelist.each do |filename|\n if File.directory? filename\n dirs.append(filename)\n else\n files.append(filename)\n end\n end\n filelist = dirs + files\n end\n\n # Apply color. We do this at the end because color codes can alter the sorting\n filelist.map! do |filename|\n if File.directory? filename\n filename.light_blue\n elsif File.executable? filename\n filename.light_green\n else\n filename\n end\n end if global_opts[:color]\n\n puts filelist\n end\nend",
226
+ "title": "Arguments"
227
+ },
228
+ {
229
+ "location": "/tutorial/40-options_parameters_and_arguments/#simplified-reference-tldr",
230
+ "text": "RBCli enforces a CLI structure of: toolname [options] command [parameters] argument1 argument2... Options are declared in application/options.rb file. Parameters are declared in the respective command's class declaration. Arguments don't need to be declared, and are passed in as an array to your commands. It is helpful to describe the argument purpose in the usage text declaration so that the user can see what to do in the help. Options and parameters both use the same format: option : name , description_string , short: ' character ', type: variable_type , default: default_value , permitted: [ array_of_permitted_values]\n\nparameter : name , description_string , short: ' character ', type: variable_type , default: default_value , permitted: [ array_of_permitted_values] name (Required) The long name of the option, as a symbol. This will be represented as --name on the command line description_string (Required) A short description of the command that will appear in the help text for the user type (Required) The following types are supported: :string , :boolean or :flag , :integer , and :float default (Optional) A default value for the option if one isn't entered (default: nil) short (Optional) A letter that acts as a shortcut for the option. This will allow users to apply the command as -n To not have a short value, set this to :none (default: the first letter of the long name) required (Optional) Specify whether the option is required from the user (default: false) permitted (Optional) An array of whitelisted values for the option (default: nil)",
231
+ "title": "Simplified Reference (TLDR)"
232
+ },
233
+ {
234
+ "location": "/tutorial/40-options_parameters_and_arguments/#next-steps",
235
+ "text": "Next, we're going to take a quick look at how to publish and distribute your application, both publicly and within your organization.",
236
+ "title": "Next Steps"
237
+ },
238
+ {
239
+ "location": "/tutorial/50-publishing/",
240
+ "text": "Publishing Your Application\n\n\nRBCli creates projects designed to be easily distributed via either source control or as a gem. We'll go over both methods.\n\n\nCommon Tasks\n\n\nRegardless of where you are publishing, certain tasks need to be accomplished. Namely, preparing the gemspec and the README.\n\n\nIn both files the items that need changing are pretty obvious -- you'll need to fill out your name, email, etc, and replace the placeholder text in the README with something useful to your users.\n\n\nThen, for every release, you'll need to update the version number in \nconfig/version.rb\n. This number is automatically used by the \ngemspec\n when versioning the gem in the system, and by RBCli when displaying help to the user and checking for automatic updates if you enable that feature (see \nAutomatic Updates\n for more information).\n\n\nSource Control Distribution\n\n\nWith Source Control distribution your users will be cloning the source code directly from your repository, and building and installing the gem locally. Thankfully, the process is pretty simple:\n\n\ngit clone \nyour_repo_here\n\ngem build mytool.gemspec\ngem install mytool-*.gem\n\n\n\n\nNote that he README's placeholder text has these commands already listed for your users, which you can leave as instructions.\n\n\nWhen using this method, we highly recommend using a git flow where you only merge to master when you are ready to release, this way your users don't inadvertently download a buggy commit.\n\n\nRubygems.org Distribution\n\n\nIf you're distributing as a gem via Rubygems.org, you'll need to follow a specific release process.\n\n\n\n\nUpdate the version number in \nconfig/version.rb\n\n\nCommit the change locally\n\n\nRun \nbundle exec rake release\n\n\n\n\nThis will create a git tag for the version, push git commits and tags, and push the \n.gem\n file to \nrubygems.org\n.\n\n\nRecommended Platforms\n\n\nAs far as RBCli is concerned, all Git hosts and gem platforms work equally well, and as long as the code reaches your users in one piece it's all the same. That said, if you'd like to take advantage of automatic update notifications for your users, please see the documentation for \nAutomatic Updates\n for a list of supported platforms for that feature. \n\n\nNext Steps\n\n\nCongratulations! You've completed the tutorial on RBCli and should be able to make all sorts of CLI applications and tools with what you learned. That said, there are still many features in RBCli that we didn't explore, which you can find in the \nAdvanced\n section of this site. If you aren't sure where to start, we recommend looking at \nUser Config Files\n and going from there.",
241
+ "title": "Publishing and Distribution"
242
+ },
243
+ {
244
+ "location": "/tutorial/50-publishing/#publishing-your-application",
245
+ "text": "RBCli creates projects designed to be easily distributed via either source control or as a gem. We'll go over both methods.",
246
+ "title": "Publishing Your Application"
247
+ },
248
+ {
249
+ "location": "/tutorial/50-publishing/#common-tasks",
250
+ "text": "Regardless of where you are publishing, certain tasks need to be accomplished. Namely, preparing the gemspec and the README. In both files the items that need changing are pretty obvious -- you'll need to fill out your name, email, etc, and replace the placeholder text in the README with something useful to your users. Then, for every release, you'll need to update the version number in config/version.rb . This number is automatically used by the gemspec when versioning the gem in the system, and by RBCli when displaying help to the user and checking for automatic updates if you enable that feature (see Automatic Updates for more information).",
251
+ "title": "Common Tasks"
252
+ },
253
+ {
254
+ "location": "/tutorial/50-publishing/#source-control-distribution",
255
+ "text": "With Source Control distribution your users will be cloning the source code directly from your repository, and building and installing the gem locally. Thankfully, the process is pretty simple: git clone your_repo_here \ngem build mytool.gemspec\ngem install mytool-*.gem Note that he README's placeholder text has these commands already listed for your users, which you can leave as instructions. When using this method, we highly recommend using a git flow where you only merge to master when you are ready to release, this way your users don't inadvertently download a buggy commit.",
256
+ "title": "Source Control Distribution"
257
+ },
258
+ {
259
+ "location": "/tutorial/50-publishing/#rubygemsorg-distribution",
260
+ "text": "If you're distributing as a gem via Rubygems.org, you'll need to follow a specific release process. Update the version number in config/version.rb Commit the change locally Run bundle exec rake release This will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org .",
261
+ "title": "Rubygems.org Distribution"
262
+ },
263
+ {
264
+ "location": "/tutorial/50-publishing/#recommended-platforms",
265
+ "text": "As far as RBCli is concerned, all Git hosts and gem platforms work equally well, and as long as the code reaches your users in one piece it's all the same. That said, if you'd like to take advantage of automatic update notifications for your users, please see the documentation for Automatic Updates for a list of supported platforms for that feature.",
266
+ "title": "Recommended Platforms"
267
+ },
268
+ {
269
+ "location": "/tutorial/50-publishing/#next-steps",
270
+ "text": "Congratulations! You've completed the tutorial on RBCli and should be able to make all sorts of CLI applications and tools with what you learned. That said, there are still many features in RBCli that we didn't explore, which you can find in the Advanced section of this site. If you aren't sure where to start, we recommend looking at User Config Files and going from there.",
271
+ "title": "Next Steps"
272
+ },
273
+ {
274
+ "location": "/advanced/command_types/",
275
+ "text": "Advanced Command Types\n\n\nRBCli has three different command types:\n\n\n\n\nStandard Commands\n (Ruby-based)\n\n\nScripted Commands\n (Ruby+Bash based)\n\n\nExternal Commands\n (Wrapping a 3rd party application)\n\n\n\n\nThis document is provided to be a reference. If you would like an in-depth tutorial, please see \nYour First Command\n.\n\n\nGeneral Command Structure\n\n\nCommands in RBCli are created by subclassing \nRbcli::Command\n. All commands share a certain common structure:\n\n\nclass List \n Rbcli::Command # Declare a new command by subclassing Rbcli::Command\n description 'TODO: Description goes here' # (Required) Short description for the global help\n usage \n-EOF\nTODO: Usage text goes here\nEOF # (Required) Long description for the command-specific help\n parameter :force, 'Force testing', type: :boolean, default: false, required: false # (Optional, Multiple) Add a command-specific CLI parameter. Can be called multiple times\n\n config_default :myopt2, description: 'My Option #2', default: 'Default Value Here' # (Optional, Multiple) Specify an individual configuration parameter and set a default value. These will also be included in generated user config.\n # Alternatively, you can simply create a yaml file in the `default_user_configs` directory in your project that specifies the default values of all options\nend\n\n\n\n\n\n\ndescription\n\n\nA short description of the command, which will appear in the top-level help (when the user runs \nmytool -h\n).\n\n\n\n\n\n\nusage\n\n\nA description of how the command is meant to be used. This description can be as long as you want, and can be as in-depth as you'd like. It will show up as a long, multi-line description when the user runs the command-sepcific help (\nmytool list -h\n).\n\n\n\n\n\n\nparameter\n\n\nCommand-line tags that the user can enter that are specific to only this command. We will get into these in the next section on \nOptions, Parameters, and Arguments\n\n\n\n\n\n\nconfig_default\n\n\nThis sets a single item in the config file that will be made available to the user. More information can be found in the documentation on \nUser Config Files\n\n\n\n\n\n\n\n\nStandard Commands\n\n\nStandard commands are written as ruby code. To create a standard command called \nlist\n, run:\n\n\nrbcli command --name=list\n#or\nrbcli command -n list\n\n\n\n\nA standard command can be identified by the presence of an \naction\n block in the definition:\n\n\nclass List \n Rbcli::Command\n action do |params, args, global_opts, config|\n # Code goes here\n end\nend\n\n\n\n\nYour application's \nparameters\n, \narguments\n, \noptions\n, and \nconfig\n are available in the variables passed into the block. For more information on these, see \nOptions, Parameters, and Arguments\n.\n\n\nScripted Commands\n\n\nScripted commands are part Ruby, part Bash scripting. They are a good choice to use if you feel something might be easier or more performant to script with Bash, or if you already have a Bash script you'd like to use in your project. You can create one with:\n\n\nrbcli script -n list\n\n\n\n\nThis will create two files in your RBCli project: a Ruby file with the common command declaration (see \nGeneral Command Structure\n), and a bash script in the folder \napplication/commands/scripts/\n.\n\n\nYou can tell a command is a script by the line:\n\n\nclass List \n Rbcli::Command\n extern path: :default # (Required): Do not edit this line. Do delete it if you wish to manually specify a script path and set environment variables.\nend\n\n\n\n\nRBCli will pass along your applications config and CLI parameters through JSON environment variables. To make things easy, a Bash library is provided that makes retrieving and parsing these variables easy. It is already imported when you generate the command, with the line:\n\n\nsource $(echo $(cd \n$(dirname $(gem which rbcli))/../lib-sh\n \n pwd)/lib-rbcli.sh)\n\n\n\n\nThis will find the library which is stored on the system as part of the RBCli gem.\n\n\nYou can then retrieve the values present in your variables like such:\n\n\nrbcli params\nrbcli args\nrbcli global_opts\nrbcli config\nrbcli myvars\n\necho \nUsage Examples:\n\necho \nLog Level: $(rbcli config .logger.log_level)\n\necho \nLog Target: $(rbcli config .logger.log_target)\n\necho \nFirst Argument (if passed): $(rbcli args .[0])\n\n\n\n\n\nFor your convenience, the script will have all the instructions needed there. For more instructions on how to use JQ syntax to parse values, see the \nJQ documentation\n.\n\n\nExternal Commands\n\n\nExternal Commands are used to wrap 3rd party applications. RBCli accomplishes this by allowing you to set environment variables and command line parameters based on your input variables.\n\n\nRBCli provides this feature through the \nextern\n keyword. It provides two modes -- \ndirect path\n and \nvariable path\n -- which work similarly.\n\n\nDirect Path Mode\n\n\nDirect path mode is the simpler mode of the two External Command modes. It allows you to provide a specific command with environment variables set, though it does not allow using RBCli parameters, arguments, options, and config.\n\n\nruby\nclass List \n Rbcli::Command\n extern path: 'path/to/application', envvars: {MYVAR: 'some_value'} # (Required) Runs a given application, with optional environment variables, when the user runs the command.\nend\n\n\nHere, we supply a string to run the command. We can optioanlly provide environment variables which will be set for the external application.\n\n\nVariable Path Mode\n\n\nVariable Path mode works the same as Direct Path Mode, only instead of providing a string we provide a block that returns a string (which will be the command executed). This allows us to generate different commands based on the CLI parameters that the user passed, or pass configuration as CLI parameters to the external application:\n\n\nclass Test \n Rbcli::Command\n extern envvars: {MY_OTHER_VAR: 'another_value'} do |params, args, global_opts, config| # Alternate usage. Supplying a block instead of a path allows us to modify the command based on the arguments and configuration supplied by the user. This allows passing config settings as command line arguments to external applications. The block must return a string, which is the command to be executed.\n cmd = '/path/to/application'\n cmd += ' --test-script foo --ignore-errors' if params[:force]\n cmd\n end\nend\n\n\n\n\nNOTE\n: Passing user-supplied data as part of the command string may be a security risk (example: \n/path/to/application --name #{params[:name]}\n). It is highly recommended to provide the fixed strings yourself, and only select which strings are used based on the variables provided. This is demonstrated in the example above.",
276
+ "title": "Command Types"
277
+ },
278
+ {
279
+ "location": "/advanced/command_types/#advanced-command-types",
280
+ "text": "RBCli has three different command types: Standard Commands (Ruby-based) Scripted Commands (Ruby+Bash based) External Commands (Wrapping a 3rd party application) This document is provided to be a reference. If you would like an in-depth tutorial, please see Your First Command .",
281
+ "title": "Advanced Command Types"
282
+ },
283
+ {
284
+ "location": "/advanced/command_types/#general-command-structure",
285
+ "text": "Commands in RBCli are created by subclassing Rbcli::Command . All commands share a certain common structure: class List Rbcli::Command # Declare a new command by subclassing Rbcli::Command\n description 'TODO: Description goes here' # (Required) Short description for the global help\n usage -EOF\nTODO: Usage text goes here\nEOF # (Required) Long description for the command-specific help\n parameter :force, 'Force testing', type: :boolean, default: false, required: false # (Optional, Multiple) Add a command-specific CLI parameter. Can be called multiple times\n\n config_default :myopt2, description: 'My Option #2', default: 'Default Value Here' # (Optional, Multiple) Specify an individual configuration parameter and set a default value. These will also be included in generated user config.\n # Alternatively, you can simply create a yaml file in the `default_user_configs` directory in your project that specifies the default values of all options\nend description A short description of the command, which will appear in the top-level help (when the user runs mytool -h ). usage A description of how the command is meant to be used. This description can be as long as you want, and can be as in-depth as you'd like. It will show up as a long, multi-line description when the user runs the command-sepcific help ( mytool list -h ). parameter Command-line tags that the user can enter that are specific to only this command. We will get into these in the next section on Options, Parameters, and Arguments config_default This sets a single item in the config file that will be made available to the user. More information can be found in the documentation on User Config Files",
286
+ "title": "General Command Structure"
287
+ },
288
+ {
289
+ "location": "/advanced/command_types/#standard-commands",
290
+ "text": "Standard commands are written as ruby code. To create a standard command called list , run: rbcli command --name=list\n#or\nrbcli command -n list A standard command can be identified by the presence of an action block in the definition: class List Rbcli::Command\n action do |params, args, global_opts, config|\n # Code goes here\n end\nend Your application's parameters , arguments , options , and config are available in the variables passed into the block. For more information on these, see Options, Parameters, and Arguments .",
291
+ "title": "Standard Commands"
292
+ },
293
+ {
294
+ "location": "/advanced/command_types/#scripted-commands",
295
+ "text": "Scripted commands are part Ruby, part Bash scripting. They are a good choice to use if you feel something might be easier or more performant to script with Bash, or if you already have a Bash script you'd like to use in your project. You can create one with: rbcli script -n list This will create two files in your RBCli project: a Ruby file with the common command declaration (see General Command Structure ), and a bash script in the folder application/commands/scripts/ . You can tell a command is a script by the line: class List Rbcli::Command\n extern path: :default # (Required): Do not edit this line. Do delete it if you wish to manually specify a script path and set environment variables.\nend RBCli will pass along your applications config and CLI parameters through JSON environment variables. To make things easy, a Bash library is provided that makes retrieving and parsing these variables easy. It is already imported when you generate the command, with the line: source $(echo $(cd $(dirname $(gem which rbcli))/../lib-sh pwd)/lib-rbcli.sh) This will find the library which is stored on the system as part of the RBCli gem. You can then retrieve the values present in your variables like such: rbcli params\nrbcli args\nrbcli global_opts\nrbcli config\nrbcli myvars\n\necho Usage Examples: \necho Log Level: $(rbcli config .logger.log_level) \necho Log Target: $(rbcli config .logger.log_target) \necho First Argument (if passed): $(rbcli args .[0]) For your convenience, the script will have all the instructions needed there. For more instructions on how to use JQ syntax to parse values, see the JQ documentation .",
296
+ "title": "Scripted Commands"
297
+ },
298
+ {
299
+ "location": "/advanced/command_types/#external-commands",
300
+ "text": "External Commands are used to wrap 3rd party applications. RBCli accomplishes this by allowing you to set environment variables and command line parameters based on your input variables. RBCli provides this feature through the extern keyword. It provides two modes -- direct path and variable path -- which work similarly.",
301
+ "title": "External Commands"
302
+ },
303
+ {
304
+ "location": "/advanced/command_types/#direct-path-mode",
305
+ "text": "Direct path mode is the simpler mode of the two External Command modes. It allows you to provide a specific command with environment variables set, though it does not allow using RBCli parameters, arguments, options, and config. ruby\nclass List Rbcli::Command\n extern path: 'path/to/application', envvars: {MYVAR: 'some_value'} # (Required) Runs a given application, with optional environment variables, when the user runs the command.\nend Here, we supply a string to run the command. We can optioanlly provide environment variables which will be set for the external application.",
306
+ "title": "Direct Path Mode"
307
+ },
308
+ {
309
+ "location": "/advanced/command_types/#variable-path-mode",
310
+ "text": "Variable Path mode works the same as Direct Path Mode, only instead of providing a string we provide a block that returns a string (which will be the command executed). This allows us to generate different commands based on the CLI parameters that the user passed, or pass configuration as CLI parameters to the external application: class Test Rbcli::Command\n extern envvars: {MY_OTHER_VAR: 'another_value'} do |params, args, global_opts, config| # Alternate usage. Supplying a block instead of a path allows us to modify the command based on the arguments and configuration supplied by the user. This allows passing config settings as command line arguments to external applications. The block must return a string, which is the command to be executed.\n cmd = '/path/to/application'\n cmd += ' --test-script foo --ignore-errors' if params[:force]\n cmd\n end\nend NOTE : Passing user-supplied data as part of the command string may be a security risk (example: /path/to/application --name #{params[:name]} ). It is highly recommended to provide the fixed strings yourself, and only select which strings are used based on the variables provided. This is demonstrated in the example above.",
311
+ "title": "Variable Path Mode"
312
+ },
313
+ {
314
+ "location": "/advanced/user_config_files/",
315
+ "text": "Configuration Files\n\n\nRBCli provides built-in support for creating and managing userspace configuration files. It does this through two chains: the \ndefaults chain\n and the \nuser chain\n.\n\n\nDefaults chain\n\n\nThe defaults chain allows you to specify sane defaults for your CLI tool throughout your code. This gives you the ability to declare configuration alongside the code, and allows RBCli to generate a user config automatically given your defaults. There are two ways to set them:\n\n\n\n\nYAML Files\n\n\nYou can store your defaults in one or more YAML files and RBCli will import and combine them. Note that when generating the user config, RBCli will use the YAML text as-is, so comments are transferred as well. This allows you to write descriptions for the options directly in the file that the user can see.\n\n\nThis is good for tools with large or complex configuration that needs user documentation written inline\n\n\nThese YAML files should be placed in the \nuserconf/\n directory in your project and they will automatically be loaded\n\n\n\n\n\n\nDSL Statements\n\n\nIn the DSL, you can specify options individually by providing a name, description, and default value\n\n\nThis is good for simpler configuration, as the descriptions provided are written out as comments in the generated user config\n\n\nYou can put global configuration options in \nconfig/userspace.rb\n\n\nCommand-specific confiugration can be placed in the command declarations in \napplication/commands/*.rb\n\n\n\n\n\n\n\n\nDSL statements appear in both of the above locations as the following:\n\n\nconfig_default :name, description: '\ndescription_help_text\n', default: '\ndefault_value\n'\n\n\n\n\nUser chain\n\n\nThe user chain has two functions: generating and loading configuration from a YAML file on the end user's machine.\n\n\nRbcli will determine the correct location to locate the user configuration based on two factors:\n\n\n\n\nThe default location set in \nconfig/userspace.rb\n\n\nThe location specified on the command line using the \n--config-file=\nfilename\n option (overrides #1)\n\n\n\n\nTo configure the default location, edit \nconfig/userspace.rb\n:\n\n\nconfig_userfile '~/.mytool', merge_defaults: true, required: false\n\n\n\n\n\n\npath/to/config/file\n\n\nSelf explanatory. Recommended locations are a dotfile in the user's home directory, or a file under \n/etc\n such as \n/etc/mytool/userconf.yaml\n\n\n\n\n\n\nmerge_defaults\n\n\nIf set to \ntrue\n, user settings override default settings. If set to \nfalse\n, default settings are not loaded at all and the user is required to have all values specified in their config.\n\n\n\n\n\n\nrequired\n\n\nIf set to \ntrue\n the application will not run if the file does not exist. A message will be displayed to the user to run your application with the \n--generate-config\n option to generate the file given your specified defaults.\n\n\n\n\n\n\n\n\nUsers can generate configs by running \nyourclitool --generate-config\n. This will generate a config file at the tool's default location specified in the DSL. This location can be overridden via the \n--config-file=\nfilename\n option.",
316
+ "title": "User Config Files"
317
+ },
318
+ {
319
+ "location": "/advanced/user_config_files/#configuration-files",
320
+ "text": "RBCli provides built-in support for creating and managing userspace configuration files. It does this through two chains: the defaults chain and the user chain .",
321
+ "title": "Configuration Files"
322
+ },
323
+ {
324
+ "location": "/advanced/user_config_files/#defaults-chain",
325
+ "text": "The defaults chain allows you to specify sane defaults for your CLI tool throughout your code. This gives you the ability to declare configuration alongside the code, and allows RBCli to generate a user config automatically given your defaults. There are two ways to set them: YAML Files You can store your defaults in one or more YAML files and RBCli will import and combine them. Note that when generating the user config, RBCli will use the YAML text as-is, so comments are transferred as well. This allows you to write descriptions for the options directly in the file that the user can see. This is good for tools with large or complex configuration that needs user documentation written inline These YAML files should be placed in the userconf/ directory in your project and they will automatically be loaded DSL Statements In the DSL, you can specify options individually by providing a name, description, and default value This is good for simpler configuration, as the descriptions provided are written out as comments in the generated user config You can put global configuration options in config/userspace.rb Command-specific confiugration can be placed in the command declarations in application/commands/*.rb DSL statements appear in both of the above locations as the following: config_default :name, description: ' description_help_text ', default: ' default_value '",
326
+ "title": "Defaults chain"
327
+ },
328
+ {
329
+ "location": "/advanced/user_config_files/#user-chain",
330
+ "text": "The user chain has two functions: generating and loading configuration from a YAML file on the end user's machine. Rbcli will determine the correct location to locate the user configuration based on two factors: The default location set in config/userspace.rb The location specified on the command line using the --config-file= filename option (overrides #1) To configure the default location, edit config/userspace.rb : config_userfile '~/.mytool', merge_defaults: true, required: false path/to/config/file Self explanatory. Recommended locations are a dotfile in the user's home directory, or a file under /etc such as /etc/mytool/userconf.yaml merge_defaults If set to true , user settings override default settings. If set to false , default settings are not loaded at all and the user is required to have all values specified in their config. required If set to true the application will not run if the file does not exist. A message will be displayed to the user to run your application with the --generate-config option to generate the file given your specified defaults. Users can generate configs by running yourclitool --generate-config . This will generate a config file at the tool's default location specified in the DSL. This location can be overridden via the --config-file= filename option.",
331
+ "title": "User chain"
332
+ },
333
+ {
334
+ "location": "/advanced/hooks/",
335
+ "text": "Execution Hooks\n\n\nRBCli provides you with hooks that can be used to have code execute at certain places in the execution chain. These hooks are optional, and do not have to be defined for your application to run.\n\n\nAll hooks will be created in the \nhooks/\n folder in your project.\n\n\nThe Defailt Action Hook\n\n\nThe Default hook is called when a user calls your application without providing a command. If the hook is not provided, the application will automatically display the help text (the same as running it with \n-h\n).\n\n\nTo create it in your project, run:\n\n\nrbcli hook --default\n# or\nrbcli hook -d\n\n\n\n\nYou will then find the hook under \nhooks/default_action.rb\n.\n\n\nThe Pre-Execution Hook\n\n\nThe Pre-Execution hook is called after the global command line options are parsed and before a command is executed.\n\n\nTo create it in your project, run:\n\n\nrbcli hook --pre\n# or\nrbcli hook -p\n\n\n\n\nYou will then find the hook under \nhooks/pre_execution.rb\n.\n\n\nThe Post-Execution Hook\n\n\nThe Pre-Execution hook is called after a command is executed.\n\n\nTo create it in your project, run:\n\n\nrbcli hook --post\n# or\nrbcli hook -o\n\n\n\n\nYou will then find the hook under \nhooks/post_execution.rb\n.\n\n\nThe First-Run Hook\n\n\nThe First-Run hook is called the first time a user executes your application. Using the first-run hook requires enabling \nLocal State Storage\n for persistence.\n\n\nTo create it in your project, run:\n\n\nrbcli hook --firstrun\n# or\nrbcli hook -f\n\n\n\n\nYou will then find the hook under \nhooks/first_run.rb\n.",
336
+ "title": "Hooks"
337
+ },
338
+ {
339
+ "location": "/advanced/hooks/#execution-hooks",
340
+ "text": "RBCli provides you with hooks that can be used to have code execute at certain places in the execution chain. These hooks are optional, and do not have to be defined for your application to run. All hooks will be created in the hooks/ folder in your project.",
341
+ "title": "Execution Hooks"
342
+ },
343
+ {
344
+ "location": "/advanced/hooks/#the-defailt-action-hook",
345
+ "text": "The Default hook is called when a user calls your application without providing a command. If the hook is not provided, the application will automatically display the help text (the same as running it with -h ). To create it in your project, run: rbcli hook --default\n# or\nrbcli hook -d You will then find the hook under hooks/default_action.rb .",
346
+ "title": "The Defailt Action Hook"
347
+ },
348
+ {
349
+ "location": "/advanced/hooks/#the-pre-execution-hook",
350
+ "text": "The Pre-Execution hook is called after the global command line options are parsed and before a command is executed. To create it in your project, run: rbcli hook --pre\n# or\nrbcli hook -p You will then find the hook under hooks/pre_execution.rb .",
351
+ "title": "The Pre-Execution Hook"
352
+ },
353
+ {
354
+ "location": "/advanced/hooks/#the-post-execution-hook",
355
+ "text": "The Pre-Execution hook is called after a command is executed. To create it in your project, run: rbcli hook --post\n# or\nrbcli hook -o You will then find the hook under hooks/post_execution.rb .",
356
+ "title": "The Post-Execution Hook"
357
+ },
358
+ {
359
+ "location": "/advanced/hooks/#the-first-run-hook",
360
+ "text": "The First-Run hook is called the first time a user executes your application. Using the first-run hook requires enabling Local State Storage for persistence. To create it in your project, run: rbcli hook --firstrun\n# or\nrbcli hook -f You will then find the hook under hooks/first_run.rb .",
361
+ "title": "The First-Run Hook"
362
+ },
363
+ {
364
+ "location": "/advanced/automatic_updates/",
365
+ "text": "Automatic Updates\n\n\nRBCli can automatically notify users when an update is available. If \nforce_update\n is set (see below), RBCli can halt execution until the user updates their application.\n\n\nTwo sources are currently supported: \nGithub\n (including Enterprise) and \nRubyGems\n.\n\n\nGitHub Update Check\n\n\nThe GitHub update check works best when paired with GitHub's best practices on releases, where new releases are tagged on master with the format \nvX.X.X\n. See \nGithub's release documentation\n to learn more.\n\n\nRBCli will check your github repo's tags and compare that version number with one specified in your application at \nconfig/version.rb\n.\n\n\nautoupdate github_repo: '\nyour_user\n/\nyour_repo\n', access_token: nil, enterprise_hostname: nil, force_update: false, message: nil\n\n\n\n\nThe \ngithub_repo\n should point to the repo using the \nuser/repo\n syntax. \n\n\nThe \naccess_token\n can be overridden by the user via their config file, so it can be left as \nnil\n if you enable \nUserspace Configuration\n. The token is not needed at all if using a public repo. For instructions on generating a new access token, see \nhere\n. \n\n\nThe \nenterprise_hostname\n setting allows you to point RBCli at a local GitHub Enterprise server.\n\n\nSetting \nforce_update: true\n will halt execution if an update is available, forcing the user to update.\n\n\nThe \nmessage\n parameter allows setting a custom message that will be displayed when an update is available. Leaving it as \nnil\n will use the default message provided by RBCli.\n\n\nRubygems.org Update Check\n\n\nThe Rubygems update check will check if there is a new published version of the gem on Rubygems.org. The latest published version is compared to the version number you configured RBCli with.\n\n\nautoupdate gem: '\nyour_gem\n', force_update: false, message: nil\n\n\n\n\nThe \ngem\n parameter should simply state the name of the gem.\n\n\nSetting \nforce_update: true\n will halt execution if an update is available, forcing the user to update.\n\n\nThe \nmessage\n parameter allows setting a custom message that will be displayed when an update is available. Leaving it as \nnil\n will use the default message provided by RBCli.",
366
+ "title": "Automatic Updates"
367
+ },
368
+ {
369
+ "location": "/advanced/automatic_updates/#automatic-updates",
370
+ "text": "RBCli can automatically notify users when an update is available. If force_update is set (see below), RBCli can halt execution until the user updates their application. Two sources are currently supported: Github (including Enterprise) and RubyGems .",
371
+ "title": "Automatic Updates"
372
+ },
373
+ {
374
+ "location": "/advanced/automatic_updates/#github-update-check",
375
+ "text": "The GitHub update check works best when paired with GitHub's best practices on releases, where new releases are tagged on master with the format vX.X.X . See Github's release documentation to learn more. RBCli will check your github repo's tags and compare that version number with one specified in your application at config/version.rb . autoupdate github_repo: ' your_user / your_repo ', access_token: nil, enterprise_hostname: nil, force_update: false, message: nil The github_repo should point to the repo using the user/repo syntax. The access_token can be overridden by the user via their config file, so it can be left as nil if you enable Userspace Configuration . The token is not needed at all if using a public repo. For instructions on generating a new access token, see here . The enterprise_hostname setting allows you to point RBCli at a local GitHub Enterprise server. Setting force_update: true will halt execution if an update is available, forcing the user to update. The message parameter allows setting a custom message that will be displayed when an update is available. Leaving it as nil will use the default message provided by RBCli.",
376
+ "title": "GitHub Update Check"
377
+ },
378
+ {
379
+ "location": "/advanced/automatic_updates/#rubygemsorg-update-check",
380
+ "text": "The Rubygems update check will check if there is a new published version of the gem on Rubygems.org. The latest published version is compared to the version number you configured RBCli with. autoupdate gem: ' your_gem ', force_update: false, message: nil The gem parameter should simply state the name of the gem. Setting force_update: true will halt execution if an update is available, forcing the user to update. The message parameter allows setting a custom message that will be displayed when an update is available. Leaving it as nil will use the default message provided by RBCli.",
381
+ "title": "Rubygems.org Update Check"
382
+ },
383
+ {
384
+ "location": "/advanced/state_storage/",
385
+ "text": "State Storage\n\n\nRBCli supports both local and remote state storage. This is done by synchronizing a Hash with either the local disk or a remote database.\n\n\nLocal State\n\n\nRBCli's local state storage gives you access to a hash that is automatically persisted to disk when changes are made.\n\n\nConfiguration\n\n\nYou can configure it in \nconfig/storage.rb\n.\n\n\nlocal_state '/var/mytool/localstate', force_creation: true, halt_on_error: true\n\n\n\n\nThere are three parameters to configure it with:\n\n\n\n\nThe \npath\n as a string (self-explanatory)\n\n\nforce_creation\n\n\nThis will attempt to create the path and file if it does not exist (equivalent to an \nmkdir -p\n and \ntouch\n in linux)\n\n\n\n\n\n\nhalt_on_error\n\n\nRBCli's default behavior is to raise an exception if the file can not be created, read, or updated at any point in time\n\n\nIf this is set to \nfalse\n, RBCli will silence any errors pertaining to file access and will fall back to whatever data is available. Note that if this is enabled, changes made to the state may not be persisted to disk.\n\n\nIf creation fails and file does not exist, you start with an empty hash\n\n\nIf file exists but can't be read, you will have an empty hash\n\n\nIf file can be read but not written, the hash will be populated with the data. Writes will be stored in memory while the application is running, but will not be persisted to disk.\n\n\n\n\n\n\n\n\n\n\n\n\nAccess and Usage\n\n\nOnce configured you can access it with a standard hash syntax in your Standard Commands:\n\n\nRbcli.local_state[:yourkeyhere]\n\n\n\n\nThe methods available for use at the top level are as follows:\n\n\nHash native methods:\n\n\n\n\n[]\n (Regular hash syntax. Keys are accessed via either symbols or strings indifferently.)\n\n\n[]=\n (Assignment operator)\n\n\ndelete\n\n\neach\n\n\nkey?\n\n\n\n\nAdditional methods:\n\n\n\n\ncommit\n\n\nEvery assignment to the top level of the hash will result in a write to disk (for example: \nRbcli.local_state[:yourkey] = 'foo'\n). However, if you are manipulating nested hashes, these saves will not be triggered. You can trigger them manually by calling \ncommit\n.\n\n\n\n\n\n\nclear\n\n\nResets the data back to an empty hash.\n\n\n\n\n\n\nrefresh\n\n\nLoads the most current version of the data from the disk\n\n\n\n\n\n\ndisconnect\n\n\nRemoves the data from memory and sets \nRbcli.local_state = nil\n. Data will be read from disk again on next access.\n\n\n\n\n\n\n\n\nEvery assignment will result in a write to disk, so if an operation will require a large number of assignments/writes it should be performed to a different hash before beign assigned to this one.\n\n\nRemote State\n\n\nRBCli's remote state storage gives you access to a hash that is automatically persisted to a remote storage location when changes are made. It has optional locking built-in, meaning that multiple users may share remote state without any data consistency issues.\n\n\nCurrently, this feature requires AWS DynamoDB, though other backend systems will be added in the future.\n\n\nConfiguration\n\n\nBefore DynamoDB can be used, AWS API credentials have to be created and made available. RBCli will attempt to find credentials from the following locations in order:\n\n\n\n\nUser's config file\n\n\nEnvironment variables \nAWS_ACCESS_KEY_ID\n and \nAWS_SECRET_ACCESS_KEY\n\n\nUser's AWSCLI configuration at \n~/.aws/credentials\n\n\n\n\nFor more information about generating and storing AWS credentials, see \nConfiguring the AWS SDK for Ruby\n. Please make sure that your users are aware that they will need to provide their own credentials to use this feature.\n\n\nYou can configure it in \nconfig/storage.rb\n.\n\n\nremote_state_dynamodb table_name: 'mytable', region: 'us-east-1', force_creation: true, halt_on_error: true, locking: false\n\n\n\n\nThese are the parameters:\n\n\n\n\ntable_name\n\n\nThe name of the DynamoDB table to use.\n\n\n\n\n\n\nregion\n\n\nThe AWS region that the database is located\n\n\n\n\n\n\nforce_creation\n\n\nCreates the DynamoDB table if it does not already exist\n\n\n\n\n\n\nhalt_on_error\n\n\nSimilar to the way \nLocal State\n works, setting this to \nfalse\n will silence any errors in connecting to the DynamoDB table. Instead, your application will simply have access to an empty hash that does not get persisted anywhere.\n\n\nThis is good for use cases that involve using this storage as a cache, where a connection error might mean the feature doesn't work but its not important enough to interrupt the user.\n\n\n\n\n\n\nlocking\n\n\nSetting this to \ntrue\n enables locking, meaning only one instance of your application can access the shared data at any given time. For more information see \nDistributed State Locking\n.\n\n\n\n\n\n\n\n\nAccess and Usage\n\n\nOnce configured you can access it with a standard hash syntax:\n\n\nRbcli.remote_state[:yourkeyhere]\n\n\n\n\nThis works the same way that \nLocal State\n does, with the same performance caveats (try not to write too frequently).\n\n\nNote that all state in Rbcli is \nlazy-loaded\n, so no connections will be made until your code attempts to access the data even if the feature is enabled.\n\n\nFor more information on the available commands, see the documentation on \nLocal State",
386
+ "title": "State Storage"
387
+ },
388
+ {
389
+ "location": "/advanced/state_storage/#state-storage",
390
+ "text": "RBCli supports both local and remote state storage. This is done by synchronizing a Hash with either the local disk or a remote database.",
391
+ "title": "State Storage"
392
+ },
393
+ {
394
+ "location": "/advanced/state_storage/#local-state",
395
+ "text": "RBCli's local state storage gives you access to a hash that is automatically persisted to disk when changes are made.",
396
+ "title": "Local State"
397
+ },
398
+ {
399
+ "location": "/advanced/state_storage/#configuration",
400
+ "text": "You can configure it in config/storage.rb . local_state '/var/mytool/localstate', force_creation: true, halt_on_error: true There are three parameters to configure it with: The path as a string (self-explanatory) force_creation This will attempt to create the path and file if it does not exist (equivalent to an mkdir -p and touch in linux) halt_on_error RBCli's default behavior is to raise an exception if the file can not be created, read, or updated at any point in time If this is set to false , RBCli will silence any errors pertaining to file access and will fall back to whatever data is available. Note that if this is enabled, changes made to the state may not be persisted to disk. If creation fails and file does not exist, you start with an empty hash If file exists but can't be read, you will have an empty hash If file can be read but not written, the hash will be populated with the data. Writes will be stored in memory while the application is running, but will not be persisted to disk.",
401
+ "title": "Configuration"
402
+ },
403
+ {
404
+ "location": "/advanced/state_storage/#access-and-usage",
405
+ "text": "Once configured you can access it with a standard hash syntax in your Standard Commands: Rbcli.local_state[:yourkeyhere] The methods available for use at the top level are as follows: Hash native methods: [] (Regular hash syntax. Keys are accessed via either symbols or strings indifferently.) []= (Assignment operator) delete each key? Additional methods: commit Every assignment to the top level of the hash will result in a write to disk (for example: Rbcli.local_state[:yourkey] = 'foo' ). However, if you are manipulating nested hashes, these saves will not be triggered. You can trigger them manually by calling commit . clear Resets the data back to an empty hash. refresh Loads the most current version of the data from the disk disconnect Removes the data from memory and sets Rbcli.local_state = nil . Data will be read from disk again on next access. Every assignment will result in a write to disk, so if an operation will require a large number of assignments/writes it should be performed to a different hash before beign assigned to this one.",
406
+ "title": "Access and Usage"
407
+ },
408
+ {
409
+ "location": "/advanced/state_storage/#remote-state",
410
+ "text": "RBCli's remote state storage gives you access to a hash that is automatically persisted to a remote storage location when changes are made. It has optional locking built-in, meaning that multiple users may share remote state without any data consistency issues. Currently, this feature requires AWS DynamoDB, though other backend systems will be added in the future.",
411
+ "title": "Remote State"
412
+ },
413
+ {
414
+ "location": "/advanced/state_storage/#configuration_1",
415
+ "text": "Before DynamoDB can be used, AWS API credentials have to be created and made available. RBCli will attempt to find credentials from the following locations in order: User's config file Environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY User's AWSCLI configuration at ~/.aws/credentials For more information about generating and storing AWS credentials, see Configuring the AWS SDK for Ruby . Please make sure that your users are aware that they will need to provide their own credentials to use this feature. You can configure it in config/storage.rb . remote_state_dynamodb table_name: 'mytable', region: 'us-east-1', force_creation: true, halt_on_error: true, locking: false These are the parameters: table_name The name of the DynamoDB table to use. region The AWS region that the database is located force_creation Creates the DynamoDB table if it does not already exist halt_on_error Similar to the way Local State works, setting this to false will silence any errors in connecting to the DynamoDB table. Instead, your application will simply have access to an empty hash that does not get persisted anywhere. This is good for use cases that involve using this storage as a cache, where a connection error might mean the feature doesn't work but its not important enough to interrupt the user. locking Setting this to true enables locking, meaning only one instance of your application can access the shared data at any given time. For more information see Distributed State Locking .",
416
+ "title": "Configuration"
417
+ },
418
+ {
419
+ "location": "/advanced/state_storage/#access-and-usage_1",
420
+ "text": "Once configured you can access it with a standard hash syntax: Rbcli.remote_state[:yourkeyhere] This works the same way that Local State does, with the same performance caveats (try not to write too frequently). Note that all state in Rbcli is lazy-loaded , so no connections will be made until your code attempts to access the data even if the feature is enabled. For more information on the available commands, see the documentation on Local State",
421
+ "title": "Access and Usage"
422
+ },
423
+ {
424
+ "location": "/advanced/distributed_state_locking/",
425
+ "text": "Distributed Locking and State Sharing\n\n\nDistributed Locking allows a \nRemote State\n to be shared among multiple users of the application to make writes appear atomic between sessions. To use it, simply set the \nlocking:\n parameter to \ntrue\n when enabling remote state.\n\n\nThis is how locking works:\n\n\n\n\nThe application attempts to acquire a lock on the remote state when you first access it\n\n\nIf the backend is locked by a different application, wait and try again\n\n\nIf it succeeds, the lock is held and refreshed periodically\n\n\nWhen the application exits, the lock is released\n\n\nIf the application does not refresh its lock, or fails to release it when it exits, the lock will automatically expire within 60 seconds\n\n\nIf another application steals the lock (unlikely but possible), and the application tries to save data, a \nStandardError\n will be thrown\n\n\nYou can manually attempt to lock/unlock by calling \nRbcli.remote_state.lock\n or \nRbcli.remote_state.unlock\n, respectively. \n\n\n\n\nManual Locking\n\n\nRemember: all state in Rbcli is lazy-loaded. Therefore, RBCli wll only attempt to lock the data when you first try to access it. If you need to make sure that the data is locked before executing a block of code, use:\n\n\nRbcli.remote_state.refresh\n\n\n\n\nto force the lock and retrieve the latest data. You can force an unlock by calling:\n\n\nRbcli.remote_state.disconnect\n\n\n\n\nEven if you do not want to store any data, you can leverage manual locking to control access to a different shared resource, such as a stateful API. For example, if you write a cloud deployment toolkit, you can ensure that only one user is attempting to modify a deployment at any given time.",
426
+ "title": "Distributed State Locking"
427
+ },
428
+ {
429
+ "location": "/advanced/distributed_state_locking/#distributed-locking-and-state-sharing",
430
+ "text": "Distributed Locking allows a Remote State to be shared among multiple users of the application to make writes appear atomic between sessions. To use it, simply set the locking: parameter to true when enabling remote state. This is how locking works: The application attempts to acquire a lock on the remote state when you first access it If the backend is locked by a different application, wait and try again If it succeeds, the lock is held and refreshed periodically When the application exits, the lock is released If the application does not refresh its lock, or fails to release it when it exits, the lock will automatically expire within 60 seconds If another application steals the lock (unlikely but possible), and the application tries to save data, a StandardError will be thrown You can manually attempt to lock/unlock by calling Rbcli.remote_state.lock or Rbcli.remote_state.unlock , respectively.",
431
+ "title": "Distributed Locking and State Sharing"
432
+ },
433
+ {
434
+ "location": "/advanced/distributed_state_locking/#manual-locking",
435
+ "text": "Remember: all state in Rbcli is lazy-loaded. Therefore, RBCli wll only attempt to lock the data when you first try to access it. If you need to make sure that the data is locked before executing a block of code, use: Rbcli.remote_state.refresh to force the lock and retrieve the latest data. You can force an unlock by calling: Rbcli.remote_state.disconnect Even if you do not want to store any data, you can leverage manual locking to control access to a different shared resource, such as a stateful API. For example, if you write a cloud deployment toolkit, you can ensure that only one user is attempting to modify a deployment at any given time.",
436
+ "title": "Manual Locking"
437
+ },
438
+ {
439
+ "location": "/development/contributing/",
440
+ "text": "Contribution Guide\n\n\nContributing to RBCli is the same as most open source projects:\n\n\n\n\nFork the repository\n\n\nCreate your own branch\n\n\nSubmit a pull request when ready\n\n\n\n\nThat's all there is to it! We've also kept our acceptance criteria pretty simple, as you'll see below. Feel free to submit a pull request even if you don't meet it if you would like your code or feature to be reviewed first; we do want to be mindful of your time and will review submissions before they are polished.\n\n\nCode Acceptance Criteria\n\n\nTabs, Not Spaces\n\n\nPlease, and thanks. We all like to use different indentation levels and styles, and this will keep us consistent between editors.\n\n\nFor filetypes where tabs are not supported (such as YAML), please stick to using two (2) spaces.\n\n\nDocumentation for User Features\n\n\nFor any modification that alters the way RBCli is used -- we're talking additional features, options, keyword changes, major behavioral changes, and the like -- the documentation will need to be updated as well. You'll be happy to know we designed it to make the process relatively painless.\n\n\nRBCli's documentation is essentially a collection of markdown files that have been compiled into a static site using \nMkDocs\n. If you already have python and pip on your system, you can install it by running:\n\n\npip install mkdocs mkdocs-material\n\n\n\n\nYou can find the source markdown files in the \ndocs-src/docs\n folder, and the menu organization in \ndocs-src/mkdocs.yml\n. To preview your changes on a live site, run:\n\n\nmkdocs serve\n\n\n\n\nAlso, don't forget to update the \nQuick Reference Guide\n in the \nREADME.md\n file (the main project one) with information about your changes.\n\n\nOnce you've completed your edits, run the \nmakesite.sh\n command to build the actual HTML pages automatically in the \ndocs\n folder, from where they will be served when live.\n\n\nMaintainer's Notes\n\n\nTo install this gem onto your local machine from source, run \nbundle exec rake install\n.\n\n\nTo release a new version, follow theese steps:\n\n\n\n\nUpdate the version number in \nversion.rb\n\n\nRun \nbundle exec rake install\n, which will update \ngemfile.lock\n with the correct version and all dependency changes\n\n\nRun \ndocs-src/makesite.sh\n, which re-compiles the documentation and pulls in the changelog and quick reference automatically\n\n\nCommit the above changes to master, but do not push\n\n\nRun \nbundle exec rake release\n, which will create a git tag for the version, push git commits and tags, and push the \n.gem\n file to \nrubygems.org\n.",
441
+ "title": "Contribution Guide"
442
+ },
443
+ {
444
+ "location": "/development/contributing/#contribution-guide",
445
+ "text": "Contributing to RBCli is the same as most open source projects: Fork the repository Create your own branch Submit a pull request when ready That's all there is to it! We've also kept our acceptance criteria pretty simple, as you'll see below. Feel free to submit a pull request even if you don't meet it if you would like your code or feature to be reviewed first; we do want to be mindful of your time and will review submissions before they are polished.",
446
+ "title": "Contribution Guide"
447
+ },
448
+ {
449
+ "location": "/development/contributing/#code-acceptance-criteria",
450
+ "text": "",
451
+ "title": "Code Acceptance Criteria"
452
+ },
453
+ {
454
+ "location": "/development/contributing/#tabs-not-spaces",
455
+ "text": "Please, and thanks. We all like to use different indentation levels and styles, and this will keep us consistent between editors. For filetypes where tabs are not supported (such as YAML), please stick to using two (2) spaces.",
456
+ "title": "Tabs, Not Spaces"
457
+ },
458
+ {
459
+ "location": "/development/contributing/#documentation-for-user-features",
460
+ "text": "For any modification that alters the way RBCli is used -- we're talking additional features, options, keyword changes, major behavioral changes, and the like -- the documentation will need to be updated as well. You'll be happy to know we designed it to make the process relatively painless. RBCli's documentation is essentially a collection of markdown files that have been compiled into a static site using MkDocs . If you already have python and pip on your system, you can install it by running: pip install mkdocs mkdocs-material You can find the source markdown files in the docs-src/docs folder, and the menu organization in docs-src/mkdocs.yml . To preview your changes on a live site, run: mkdocs serve Also, don't forget to update the Quick Reference Guide in the README.md file (the main project one) with information about your changes. Once you've completed your edits, run the makesite.sh command to build the actual HTML pages automatically in the docs folder, from where they will be served when live.",
461
+ "title": "Documentation for User Features"
462
+ },
463
+ {
464
+ "location": "/development/contributing/#maintainers-notes",
465
+ "text": "To install this gem onto your local machine from source, run bundle exec rake install . To release a new version, follow theese steps: Update the version number in version.rb Run bundle exec rake install , which will update gemfile.lock with the correct version and all dependency changes Run docs-src/makesite.sh , which re-compiles the documentation and pulls in the changelog and quick reference automatically Commit the above changes to master, but do not push Run bundle exec rake release , which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org .",
466
+ "title": "Maintainer's Notes"
467
+ },
468
+ {
469
+ "location": "/development/license/",
470
+ "text": "How RBCli is Licensed\n\n\nWe want to help the developer community build tooling faster and with less work. That's why RBCli was built. And let's face it - most of us aren't lawyers, and don't want to worry about legal fine print when building awesome software. That's why RBCli is released under the \nGPLv3 License\n. So you're free to use RBCli as you see fit to write free software. If you wish to use RBCli in a commercial offering, please contact me at \nandrew@blacknex.us\n.\n\n\nThe License\n\n\nYou can view the offical license for RBCli \nHere\n.\n\n\nFor more details about the GPLv3 License, see \nHere\n.",
471
+ "title": "License Info"
472
+ },
473
+ {
474
+ "location": "/development/license/#how-rbcli-is-licensed",
475
+ "text": "We want to help the developer community build tooling faster and with less work. That's why RBCli was built. And let's face it - most of us aren't lawyers, and don't want to worry about legal fine print when building awesome software. That's why RBCli is released under the GPLv3 License . So you're free to use RBCli as you see fit to write free software. If you wish to use RBCli in a commercial offering, please contact me at andrew@blacknex.us .",
476
+ "title": "How RBCli is Licensed"
477
+ },
478
+ {
479
+ "location": "/development/license/#the-license",
480
+ "text": "You can view the offical license for RBCli Here . For more details about the GPLv3 License, see Here .",
481
+ "title": "The License"
482
+ },
483
+ {
484
+ "location": "/development/code_of_conduct/",
485
+ "text": "Contributor Covenant Code of Conduct\n\n\nOur Pledge\n\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, gender identity and expression, level of experience,\nnationality, personal appearance, race, religion, or sexual identity and\norientation.\n\n\nOur Standards\n\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n\n\n\nUsing welcoming and inclusive language\n\n\nBeing respectful of differing viewpoints and experiences\n\n\nGracefully accepting constructive criticism\n\n\nFocusing on what is best for the community\n\n\nShowing empathy towards other community members\n\n\n\n\nExamples of unacceptable behavior by participants include:\n\n\n\n\nThe use of sexualized language or imagery and unwelcome sexual attention or\nadvances\n\n\nTrolling, insulting/derogatory comments, and personal or political attacks\n\n\nPublic or private harassment\n\n\nPublishing others' private information, such as a physical or electronic\n address, without explicit permission\n\n\nOther conduct which could reasonably be considered inappropriate in a\n professional setting\n\n\n\n\nOur Responsibilities\n\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n\nScope\n\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n\nEnforcement\n\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at andrew@blacknex.us. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n\nAttribution\n\n\nThis Code of Conduct is adapted from the \nContributor Covenant\n, version 1.4,\navailable at \nhttp://contributor-covenant.org/version/1/4",
486
+ "title": "Code of Conduct"
487
+ },
488
+ {
489
+ "location": "/development/code_of_conduct/#contributor-covenant-code-of-conduct",
490
+ "text": "",
491
+ "title": "Contributor Covenant Code of Conduct"
492
+ },
493
+ {
494
+ "location": "/development/code_of_conduct/#our-pledge",
495
+ "text": "In the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, gender identity and expression, level of experience,\nnationality, personal appearance, race, religion, or sexual identity and\norientation.",
496
+ "title": "Our Pledge"
497
+ },
498
+ {
499
+ "location": "/development/code_of_conduct/#our-standards",
500
+ "text": "Examples of behavior that contributes to creating a positive environment\ninclude: Using welcoming and inclusive language Being respectful of differing viewpoints and experiences Gracefully accepting constructive criticism Focusing on what is best for the community Showing empathy towards other community members Examples of unacceptable behavior by participants include: The use of sexualized language or imagery and unwelcome sexual attention or\nadvances Trolling, insulting/derogatory comments, and personal or political attacks Public or private harassment Publishing others' private information, such as a physical or electronic\n address, without explicit permission Other conduct which could reasonably be considered inappropriate in a\n professional setting",
501
+ "title": "Our Standards"
502
+ },
503
+ {
504
+ "location": "/development/code_of_conduct/#our-responsibilities",
505
+ "text": "Project maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.",
506
+ "title": "Our Responsibilities"
507
+ },
508
+ {
509
+ "location": "/development/code_of_conduct/#scope",
510
+ "text": "This Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.",
511
+ "title": "Scope"
512
+ },
513
+ {
514
+ "location": "/development/code_of_conduct/#enforcement",
515
+ "text": "Instances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at andrew@blacknex.us. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.",
516
+ "title": "Enforcement"
517
+ },
518
+ {
519
+ "location": "/development/code_of_conduct/#attribution",
520
+ "text": "This Code of Conduct is adapted from the Contributor Covenant , version 1.4,\navailable at http://contributor-covenant.org/version/1/4",
521
+ "title": "Attribution"
522
+ },
523
+ {
524
+ "location": "/imported/changelog/",
525
+ "text": "Changelog\n\n\n0.2.0 (Aug 5, 2018)\n\n\nFeatures\n\n\n\n\nOfficial documentation created and hosted with Github Pages\n\n\nRBCli released under GPLv3\n\n\nCopyright/License notice displayed via RBCli tool with \nrbcli license\n in accordance with GPLv3 guidelines\n\n\n\n\nBugfixes\n\n\n\n\nFixed version number loading for projects\n\n\nCleaned up command usage help output\n\n\nFixed script and external command generation\n\n\n\n\nImprovements\n\n\n\n\nA quick reference guide can now be found in README.md\n\n\nCLI tool Autoupdate Enabled; when an upgrade to RBCli is detected, the RBCli CLI tool will notify the developer.\n\n\nAutoupdate feature now allows supplying a custom message\n\n\nDirect Path Mode for External Commands now\n\n\nAdded support for a \nlib\n folder in projects, as a place for custom code, which is automatically added to \n$LOAD_PATH\n for developers\n\n\nImproved language regarding external commands: Documentation now differentiates between Standard, Scripted, and External Commands\n\n\nImproved language regarding user config files: Now called Userspace Config\n\n\nOptions and Parameters now allow specifying the letter to be used for the short version, or to disable it altogether\n\n\nUserspace config can now be disabled by setting the path to nil or removing the declaration\n\n\n\n\nDeprecations/Changes\n\n\n\n\nRemoved deprecated and broken examples from the examples folder",
526
+ "title": "Changelog"
527
+ },
528
+ {
529
+ "location": "/imported/changelog/#changelog",
530
+ "text": "",
531
+ "title": "Changelog"
532
+ },
533
+ {
534
+ "location": "/imported/changelog/#020-aug-5-2018",
535
+ "text": "",
536
+ "title": "0.2.0 (Aug 5, 2018)"
537
+ },
538
+ {
539
+ "location": "/imported/changelog/#features",
540
+ "text": "Official documentation created and hosted with Github Pages RBCli released under GPLv3 Copyright/License notice displayed via RBCli tool with rbcli license in accordance with GPLv3 guidelines",
541
+ "title": "Features"
542
+ },
543
+ {
544
+ "location": "/imported/changelog/#bugfixes",
545
+ "text": "Fixed version number loading for projects Cleaned up command usage help output Fixed script and external command generation",
546
+ "title": "Bugfixes"
547
+ },
548
+ {
549
+ "location": "/imported/changelog/#improvements",
550
+ "text": "A quick reference guide can now be found in README.md CLI tool Autoupdate Enabled; when an upgrade to RBCli is detected, the RBCli CLI tool will notify the developer. Autoupdate feature now allows supplying a custom message Direct Path Mode for External Commands now Added support for a lib folder in projects, as a place for custom code, which is automatically added to $LOAD_PATH for developers Improved language regarding external commands: Documentation now differentiates between Standard, Scripted, and External Commands Improved language regarding user config files: Now called Userspace Config Options and Parameters now allow specifying the letter to be used for the short version, or to disable it altogether Userspace config can now be disabled by setting the path to nil or removing the declaration",
551
+ "title": "Improvements"
552
+ },
553
+ {
554
+ "location": "/imported/changelog/#deprecationschanges",
555
+ "text": "Removed deprecated and broken examples from the examples folder",
556
+ "title": "Deprecations/Changes"
557
+ },
558
+ {
559
+ "location": "/whoami/",
560
+ "text": "My Letter To You\n\n\nMy Fellow Coder,\n\n\nI'm glad to see you are interested in RBCli. I'd like to introduce myself. My name is Andrew, and I've been a technologist since 1992 when my father bought our first family computer -- a 486DX2 which ran at 66Mhz (33Mhz if you turned off the 'turbo' button) and came with MS DOS 5.0, \nQBasic\n, and a game already coded in it called \nNibbles\n (if you care to see the code, die 5 times and don't play again). I didn't like that the game forced my name to be \"Sammy\", and thought, \"hey, if I can see the code, can't I change it?\". So I did what any annoyed child would do and learned to code so I could do just that. I'd tell you what I changed it to, but I was so proud of myself for this simple feat that I changed it every 30 seconds and couldn't settle on just one name. Then I performed my first ever hack, and figured out how to go through walls without dying. All of a sudden the world seemed limitless.\n\n\nI was only a child at the time, but on that day I learned that every \"rule\" in computing was an artifical construct and could be changed to suit your needs. Thus began my career in tech and my obsession to change the world with it. This is why RBCli was born.\n\n\nRBCli started as a collection of code that I would copy-paste between projects, until one day when I wondered if I could just find a framework that suited me. I couldn't - in case you hadn't guessed - so I decided to build my own and give it to the world. I would not have accomplished even half of what I have without the open source community, and this is to be the first of hopefully many contributions back.\n\n\nThe features in RBCli have been chosen from over 25 years of experience writing applications, building features that 3rd parties left out, managing large scale infrastructure, designing embedded systems, integrating enterprise systems, automating CI/CD, scripting my own computers, and so much more. I hope that you can find as much use out of it as I have.\n\n\nIf you'd like to get in touch with me at any time, feel free to email me at \nandrew@blacknex.us\n.\n\n\nAll the best,\n\n\nAndrew\n\n\nP.S.: If you really liked RBCli and want to support it, any amount you can help out with goes a long way.",
561
+ "title": "$ whoami"
562
+ },
563
+ {
564
+ "location": "/whoami/#my-letter-to-you",
565
+ "text": "My Fellow Coder, I'm glad to see you are interested in RBCli. I'd like to introduce myself. My name is Andrew, and I've been a technologist since 1992 when my father bought our first family computer -- a 486DX2 which ran at 66Mhz (33Mhz if you turned off the 'turbo' button) and came with MS DOS 5.0, QBasic , and a game already coded in it called Nibbles (if you care to see the code, die 5 times and don't play again). I didn't like that the game forced my name to be \"Sammy\", and thought, \"hey, if I can see the code, can't I change it?\". So I did what any annoyed child would do and learned to code so I could do just that. I'd tell you what I changed it to, but I was so proud of myself for this simple feat that I changed it every 30 seconds and couldn't settle on just one name. Then I performed my first ever hack, and figured out how to go through walls without dying. All of a sudden the world seemed limitless. I was only a child at the time, but on that day I learned that every \"rule\" in computing was an artifical construct and could be changed to suit your needs. Thus began my career in tech and my obsession to change the world with it. This is why RBCli was born. RBCli started as a collection of code that I would copy-paste between projects, until one day when I wondered if I could just find a framework that suited me. I couldn't - in case you hadn't guessed - so I decided to build my own and give it to the world. I would not have accomplished even half of what I have without the open source community, and this is to be the first of hopefully many contributions back. The features in RBCli have been chosen from over 25 years of experience writing applications, building features that 3rd parties left out, managing large scale infrastructure, designing embedded systems, integrating enterprise systems, automating CI/CD, scripting my own computers, and so much more. I hope that you can find as much use out of it as I have. If you'd like to get in touch with me at any time, feel free to email me at andrew@blacknex.us . All the best, Andrew P.S.: If you really liked RBCli and want to support it, any amount you can help out with goes a long way.",
566
+ "title": "My Letter To You"
567
+ }
568
+ ]
569
+ }