rbcli 0.2.8 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (443) hide show
  1. checksums.yaml +4 -4
  2. data/.rakeTasks +7 -0
  3. data/.rbenv-gemsets +1 -0
  4. data/CHANGELOG.md +37 -0
  5. data/Gemfile.lock +46 -46
  6. data/README.md +2 -2
  7. data/docs-src/archetypes/default.md +6 -0
  8. data/docs-src/config.toml +37 -0
  9. data/docs-src/{docs/index.md → content/_index.md} +4 -4
  10. data/docs-src/content/advanced/_index.md +11 -0
  11. data/docs-src/{docs → content}/advanced/automatic_updates.md +6 -2
  12. data/docs-src/{docs → content}/advanced/command_types.md +8 -4
  13. data/docs-src/{docs → content}/advanced/distributed_state_locking.md +6 -2
  14. data/docs-src/{docs → content}/advanced/hooks.md +6 -2
  15. data/docs-src/{docs → content}/advanced/interactive_commands.md +5 -1
  16. data/docs-src/{docs → content}/advanced/logging.md +6 -2
  17. data/docs-src/{docs → content}/advanced/remote_execution.md +5 -1
  18. data/docs-src/{docs → content}/advanced/state_storage.md +6 -3
  19. data/docs-src/{docs → content}/advanced/user_config_files.md +5 -1
  20. data/docs-src/content/development/_index.md +11 -0
  21. data/docs-src/{docs/imported → content/development}/changelog.md +73 -6
  22. data/docs-src/{docs → content}/development/code_of_conduct.md +8 -1
  23. data/docs-src/{docs → content}/development/contributing.md +16 -1
  24. data/docs-src/{docs → content}/development/license.md +9 -2
  25. data/docs-src/{docs/imported/quick_reference.md → content/quick_reference/_index.md} +8 -1
  26. data/docs-src/{docs → content}/tutorial/10-getting_started.md +7 -1
  27. data/docs-src/{docs → content}/tutorial/20-project_layout.md +10 -2
  28. data/docs-src/{docs → content}/tutorial/30-your_first_command.md +10 -4
  29. data/docs-src/{docs → content}/tutorial/40-options_parameters_and_arguments.md +9 -3
  30. data/docs-src/{docs → content}/tutorial/50-publishing.md +9 -3
  31. data/docs-src/content/tutorial/_index.md +11 -0
  32. data/docs-src/{docs/whoami.md → content/whoami/_index.md} +11 -5
  33. data/docs-src/layouts/partials/logo.html +3 -0
  34. data/docs-src/makesite.sh +33 -7
  35. data/docs-src/mkdocs-archived.tar.gz +0 -0
  36. data/docs-src/runsite.sh +6 -1
  37. data/docs-src/themes/hugo-theme-learn/.editorconfig +16 -0
  38. data/docs-src/themes/hugo-theme-learn/.gitignore +3 -0
  39. data/docs-src/themes/hugo-theme-learn/.grenrc.yml +25 -0
  40. data/docs-src/themes/hugo-theme-learn/CHANGELOG.md +226 -0
  41. data/docs-src/themes/hugo-theme-learn/LICENSE.md +22 -0
  42. data/docs-src/themes/hugo-theme-learn/README.md +97 -0
  43. data/docs-src/themes/hugo-theme-learn/archetypes/chapter.md +13 -0
  44. data/docs-src/themes/hugo-theme-learn/archetypes/default.md +7 -0
  45. data/docs-src/themes/hugo-theme-learn/exampleSite/LICENSE.md +20 -0
  46. data/docs-src/themes/hugo-theme-learn/exampleSite/config.toml +102 -0
  47. data/docs-src/themes/hugo-theme-learn/exampleSite/content/_index.en.md +41 -0
  48. data/docs-src/themes/hugo-theme-learn/exampleSite/content/_index.fr.md +43 -0
  49. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/_index.en.md +12 -0
  50. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/_index.fr.md +12 -0
  51. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/_index.zh.md +12 -0
  52. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/configuration/_index.en.md +60 -0
  53. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/configuration/_index.fr.md +56 -0
  54. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/installation/_index.en.md +102 -0
  55. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/installation/_index.fr.md +100 -0
  56. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/installation/images/chapter.png +0 -0
  57. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/requirements/_index.en.md +11 -0
  58. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/requirements/_index.fr.md +11 -0
  59. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/requirements/images/magic.gif +0 -0
  60. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/_index.en.md +194 -0
  61. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/_index.fr.md +194 -0
  62. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/images/blue-variant.png +0 -0
  63. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/images/green-variant.png +0 -0
  64. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/images/red-variant.png +0 -0
  65. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/_index.en.md +12 -0
  66. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/_index.fr.md +12 -0
  67. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/archetypes.en.md +57 -0
  68. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/archetypes.fr.md +57 -0
  69. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/i18n/_index.en.md +78 -0
  70. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/i18n/_index.fr.md +78 -0
  71. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/i18n/images/i18n-menu.gif +0 -0
  72. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/icons.en.md +41 -0
  73. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/markdown.en.md +692 -0
  74. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/markdown.fr.md +666 -0
  75. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/menushortcuts.en.md +109 -0
  76. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/menushortcuts.fr.md +109 -0
  77. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/_index.en.md +166 -0
  78. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/_index.fr.md +146 -0
  79. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/images/frontmatter-icon.png +0 -0
  80. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/images/pages-chapter.png +0 -0
  81. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/images/pages-default.png +0 -0
  82. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/syntaxhighlight.en.md +89 -0
  83. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/tags.en.md +39 -0
  84. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/tags.fr.md +40 -0
  85. data/docs-src/themes/hugo-theme-learn/exampleSite/content/credits.en.md +28 -0
  86. data/docs-src/themes/hugo-theme-learn/exampleSite/content/credits.fr.md +28 -0
  87. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/_index.en.md +16 -0
  88. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/_index.fr.md +16 -0
  89. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/BachGavotteShort.mp3 +0 -0
  90. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/Carroll_AliceAuPaysDesMerveilles.pdf +0 -0
  91. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/adivorciarsetoca00cape.pdf +0 -0
  92. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/hugo.png +0 -0
  93. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/movieselectricsheep-flock-244-32500-2.mp4 +0 -0
  94. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.md +85 -0
  95. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/BachGavotteShort.mp3 +0 -0
  96. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/Carroll_AliceAuPaysDesMerveilles.pdf +0 -0
  97. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/adivorciarsetoca00cape.pdf +0 -0
  98. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/hugo.png +0 -0
  99. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/movieselectricsheep-flock-244-32500-2.mp4 +0 -0
  100. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.md +85 -0
  101. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/button.en.md +16 -0
  102. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/button.fr.md +16 -0
  103. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/_index.en.md +45 -0
  104. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/_index.fr.md +45 -0
  105. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/_index.en.md +6 -0
  106. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/_index.fr.md +6 -0
  107. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/_index.en.md +6 -0
  108. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/_index.fr.md +6 -0
  109. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/_index.en.md +6 -0
  110. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/_index.fr.md +6 -0
  111. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/children-1-1-1-1/_index.en.md +6 -0
  112. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/children-1-1-1-1/_index.fr.md +6 -0
  113. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/children-1-1-1-1/children-1-1-1-1-1/_index.en.md +6 -0
  114. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/children-1-1-1-1/children-1-1-1-1-1/_index.fr.md +6 -0
  115. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-2/_index.en.md +11 -0
  116. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-2/_index.fr.md +11 -0
  117. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-2/test3.en.md +6 -0
  118. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-2/test3.fr.md +6 -0
  119. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-3/_index.en.md +6 -0
  120. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-3/_index.fr.md +6 -0
  121. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-4/_index.en.md +7 -0
  122. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-4/_index.fr.md +7 -0
  123. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/test.en.md +6 -0
  124. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/test.fr.md +6 -0
  125. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/expand.en.md +45 -0
  126. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/expand.fr.md +45 -0
  127. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/mermaid.en.md +283 -0
  128. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/mermaid.fr.md +283 -0
  129. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/notice.en.md +62 -0
  130. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/notice.fr.md +62 -0
  131. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/siteparam.en.md +23 -0
  132. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/siteparam.fr.md +23 -0
  133. data/docs-src/themes/hugo-theme-learn/exampleSite/content/showcase.en.md +13 -0
  134. data/docs-src/themes/hugo-theme-learn/exampleSite/content/showcase.fr.md +14 -0
  135. data/docs-src/themes/hugo-theme-learn/exampleSite/layouts/partials/custom-footer.html +10 -0
  136. data/docs-src/themes/hugo-theme-learn/exampleSite/layouts/partials/logo.html +39 -0
  137. data/docs-src/themes/hugo-theme-learn/exampleSite/layouts/partials/menu-footer.html +14 -0
  138. data/docs-src/themes/hugo-theme-learn/exampleSite/layouts/shortcodes/ghcontributors.html +31 -0
  139. data/docs-src/themes/hugo-theme-learn/exampleSite/static/css/theme-mine.css +104 -0
  140. data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.eot +0 -0
  141. data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.svg +1 -0
  142. data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.ttf +0 -0
  143. data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.woff +0 -0
  144. data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.woff2 +0 -0
  145. data/docs-src/themes/hugo-theme-learn/exampleSite/static/images/showcase/inteliver_docs.png +0 -0
  146. data/docs-src/themes/hugo-theme-learn/exampleSite/static/images/showcase/tat.png +0 -0
  147. data/docs-src/themes/hugo-theme-learn/exampleSite/static/images/showcase/tshark_dev.png +0 -0
  148. data/docs-src/themes/hugo-theme-learn/i18n/ar.toml +26 -0
  149. data/docs-src/themes/hugo-theme-learn/i18n/de.toml +26 -0
  150. data/docs-src/themes/hugo-theme-learn/i18n/en.toml +26 -0
  151. data/docs-src/themes/hugo-theme-learn/i18n/es.toml +26 -0
  152. data/docs-src/themes/hugo-theme-learn/i18n/fr.toml +26 -0
  153. data/docs-src/themes/hugo-theme-learn/i18n/hi.toml +26 -0
  154. data/docs-src/themes/hugo-theme-learn/i18n/id.toml +26 -0
  155. data/docs-src/themes/hugo-theme-learn/i18n/ja.toml +26 -0
  156. data/docs-src/themes/hugo-theme-learn/i18n/nl.toml +26 -0
  157. data/docs-src/themes/hugo-theme-learn/i18n/pt.toml +26 -0
  158. data/docs-src/themes/hugo-theme-learn/i18n/ru.toml +26 -0
  159. data/docs-src/themes/hugo-theme-learn/i18n/tr.toml +26 -0
  160. data/docs-src/themes/hugo-theme-learn/i18n/zh-cn.toml +26 -0
  161. data/docs-src/themes/hugo-theme-learn/images/screenshot.png +0 -0
  162. data/docs-src/themes/hugo-theme-learn/images/tn.png +0 -0
  163. data/docs-src/themes/hugo-theme-learn/layouts/404.html +56 -0
  164. data/docs-src/themes/hugo-theme-learn/layouts/_default/list.html +22 -0
  165. data/docs-src/themes/hugo-theme-learn/layouts/_default/single.html +12 -0
  166. data/docs-src/themes/hugo-theme-learn/layouts/index.html +31 -0
  167. data/docs-src/themes/hugo-theme-learn/layouts/index.json +12 -0
  168. data/docs-src/themes/hugo-theme-learn/layouts/partials/custom-comments.html +3 -0
  169. data/docs-src/themes/hugo-theme-learn/layouts/partials/custom-footer.html +5 -0
  170. data/docs-src/themes/hugo-theme-learn/layouts/partials/custom-header.html +5 -0
  171. data/docs-src/themes/hugo-theme-learn/layouts/partials/favicon.html +1 -0
  172. data/docs-src/themes/hugo-theme-learn/layouts/partials/footer.html +77 -0
  173. data/docs-src/themes/hugo-theme-learn/layouts/partials/header.html +111 -0
  174. data/docs-src/themes/hugo-theme-learn/layouts/partials/logo.html +19 -0
  175. data/docs-src/themes/hugo-theme-learn/layouts/partials/menu-footer.html +1 -0
  176. data/docs-src/themes/hugo-theme-learn/layouts/partials/menu.html +151 -0
  177. data/docs-src/themes/hugo-theme-learn/layouts/partials/meta.html +2 -0
  178. data/docs-src/themes/hugo-theme-learn/layouts/partials/search.html +16 -0
  179. data/docs-src/themes/hugo-theme-learn/layouts/partials/tags.html +7 -0
  180. data/docs-src/themes/hugo-theme-learn/layouts/partials/toc.html +5 -0
  181. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/attachments.html +36 -0
  182. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/button.html +14 -0
  183. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/children.html +101 -0
  184. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/expand.html +17 -0
  185. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/mermaid.html +2 -0
  186. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/notice.html +2 -0
  187. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/ref.html +14 -0
  188. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/relref.html +14 -0
  189. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/siteparam.html +7 -0
  190. data/docs-src/themes/hugo-theme-learn/netlify.toml +23 -0
  191. data/docs-src/themes/hugo-theme-learn/static/css/atom-one-dark-reasonable.css +77 -0
  192. data/docs-src/themes/hugo-theme-learn/static/css/auto-complete.css +47 -0
  193. data/docs-src/themes/hugo-theme-learn/static/css/featherlight.min.css +8 -0
  194. data/docs-src/themes/hugo-theme-learn/static/css/fontawesome-all.min.css +1 -0
  195. data/docs-src/themes/hugo-theme-learn/static/css/hugo-theme.css +254 -0
  196. data/docs-src/themes/hugo-theme-learn/static/css/hybrid.css +102 -0
  197. data/docs-src/themes/hugo-theme-learn/static/css/nucleus.css +615 -0
  198. data/docs-src/themes/hugo-theme-learn/static/css/perfect-scrollbar.min.css +2 -0
  199. data/docs-src/themes/hugo-theme-learn/static/css/tags.css +49 -0
  200. data/docs-src/themes/hugo-theme-learn/static/css/theme-blue.css +111 -0
  201. data/docs-src/themes/hugo-theme-learn/static/css/theme-green.css +111 -0
  202. data/docs-src/themes/hugo-theme-learn/static/css/theme-red.css +111 -0
  203. data/docs-src/themes/hugo-theme-learn/static/css/theme.css +1136 -0
  204. data/docs-src/themes/hugo-theme-learn/static/fonts/Inconsolata.eot +0 -0
  205. data/docs-src/themes/hugo-theme-learn/static/fonts/Inconsolata.svg +1 -0
  206. data/docs-src/themes/hugo-theme-learn/static/fonts/Inconsolata.ttf +0 -0
  207. data/docs-src/themes/hugo-theme-learn/static/fonts/Inconsolata.woff +0 -0
  208. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.eot +0 -0
  209. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.svg +1 -0
  210. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.ttf +0 -0
  211. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.woff +0 -0
  212. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.woff2 +0 -0
  213. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.eot +0 -0
  214. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.svg +1 -0
  215. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.ttf +0 -0
  216. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.woff +0 -0
  217. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.woff2 +0 -0
  218. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.eot +0 -0
  219. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.svg +1 -0
  220. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.ttf +0 -0
  221. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.woff +0 -0
  222. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.woff2 +0 -0
  223. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.eot +0 -0
  224. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.svg +1 -0
  225. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.ttf +0 -0
  226. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.woff +0 -0
  227. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.woff2 +0 -0
  228. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.eot +0 -0
  229. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.svg +1 -0
  230. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.ttf +0 -0
  231. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.woff +0 -0
  232. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.woff2 +0 -0
  233. data/docs-src/themes/hugo-theme-learn/static/images/clippy.svg +1 -0
  234. data/docs-src/themes/hugo-theme-learn/static/images/favicon.png +0 -0
  235. data/docs-src/themes/hugo-theme-learn/static/images/gopher-404.jpg +0 -0
  236. data/docs-src/themes/hugo-theme-learn/static/js/auto-complete.js +3 -0
  237. data/docs-src/themes/hugo-theme-learn/static/js/clipboard.min.js +7 -0
  238. data/docs-src/themes/hugo-theme-learn/static/js/featherlight.min.js +9 -0
  239. data/docs-src/themes/hugo-theme-learn/static/js/highlight.pack.js +6 -0
  240. data/docs-src/themes/hugo-theme-learn/static/js/hugo-learn.js +94 -0
  241. data/docs-src/themes/hugo-theme-learn/static/js/jquery-3.3.1.min.js +2 -0
  242. data/docs-src/themes/hugo-theme-learn/static/js/jquery.sticky.js +288 -0
  243. data/docs-src/themes/hugo-theme-learn/static/js/learn.js +459 -0
  244. data/docs-src/themes/hugo-theme-learn/static/js/lunr.min.js +6 -0
  245. data/docs-src/themes/hugo-theme-learn/static/js/modernizr.custom-3.6.0.js +3 -0
  246. data/docs-src/themes/hugo-theme-learn/static/js/perfect-scrollbar.jquery.min.js +2 -0
  247. data/docs-src/themes/hugo-theme-learn/static/js/perfect-scrollbar.min.js +2 -0
  248. data/docs-src/themes/hugo-theme-learn/static/js/search.js +93 -0
  249. data/docs-src/themes/hugo-theme-learn/static/mermaid/mermaid.css +277 -0
  250. data/docs-src/themes/hugo-theme-learn/static/mermaid/mermaid.dark.css +278 -0
  251. data/docs-src/themes/hugo-theme-learn/static/mermaid/mermaid.forest.css +356 -0
  252. data/docs-src/themes/hugo-theme-learn/static/mermaid/mermaid.js +8 -0
  253. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.eot +0 -0
  254. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.svg +1 -0
  255. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.ttf +0 -0
  256. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.woff +0 -0
  257. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.woff2 +0 -0
  258. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.eot +0 -0
  259. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.svg +1 -0
  260. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.ttf +0 -0
  261. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.woff +0 -0
  262. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.woff2 +0 -0
  263. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.eot +0 -0
  264. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.svg +1 -0
  265. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.ttf +0 -0
  266. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.woff +0 -0
  267. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.woff2 +0 -0
  268. data/docs-src/themes/hugo-theme-learn/theme.toml +21 -0
  269. data/docs-src/themes/hugo-theme-learn/wercker.yml +16 -0
  270. data/docs/404.html +54 -670
  271. data/docs/advanced/automatic_updates/index.html +998 -651
  272. data/docs/advanced/command_types/index.html +1022 -742
  273. data/docs/advanced/distributed_state_locking/index.html +998 -635
  274. data/docs/advanced/hooks/index.html +1011 -691
  275. data/docs/advanced/index.html +1140 -0
  276. data/docs/advanced/index.xml +117 -0
  277. data/docs/advanced/interactive_commands/index.html +1000 -652
  278. data/docs/advanced/logging/index.html +1006 -655
  279. data/docs/advanced/remote_execution/index.html +1010 -666
  280. data/docs/advanced/state_storage/index.html +1009 -721
  281. data/docs/advanced/user_config_files/index.html +981 -626
  282. data/docs/categories/index.html +1146 -0
  283. data/docs/categories/index.xml +14 -0
  284. data/docs/css/atom-one-dark-reasonable.css +77 -0
  285. data/docs/css/auto-complete.css +47 -0
  286. data/docs/css/featherlight.min.css +8 -0
  287. data/docs/css/fontawesome-all.min.css +1 -0
  288. data/docs/css/hugo-theme.css +254 -0
  289. data/docs/css/hybrid.css +102 -0
  290. data/docs/css/nucleus.css +615 -0
  291. data/docs/css/perfect-scrollbar.min.css +2 -0
  292. data/docs/css/tags.css +49 -0
  293. data/docs/css/theme-blue.css +111 -0
  294. data/docs/css/theme-green.css +111 -0
  295. data/docs/css/theme-red.css +111 -0
  296. data/docs/css/theme.css +1136 -0
  297. data/docs/development/changelog/index.html +1376 -0
  298. data/docs/development/code_of_conduct/index.html +974 -671
  299. data/docs/development/contributing/index.html +989 -583
  300. data/docs/development/index.html +1140 -0
  301. data/docs/development/index.xml +54 -0
  302. data/docs/development/license/index.html +973 -559
  303. data/docs/fonts/Inconsolata.eot +0 -0
  304. data/docs/fonts/Inconsolata.svg +1 -0
  305. data/docs/fonts/Inconsolata.ttf +0 -0
  306. data/docs/fonts/Inconsolata.woff +0 -0
  307. data/docs/fonts/Novecentosanswide-Normal-webfont.eot +0 -0
  308. data/docs/fonts/Novecentosanswide-Normal-webfont.svg +1 -0
  309. data/docs/fonts/Novecentosanswide-Normal-webfont.ttf +0 -0
  310. data/docs/fonts/Novecentosanswide-Normal-webfont.woff +0 -0
  311. data/docs/fonts/Novecentosanswide-Normal-webfont.woff2 +0 -0
  312. data/docs/fonts/Novecentosanswide-UltraLight-webfont.eot +0 -0
  313. data/docs/fonts/Novecentosanswide-UltraLight-webfont.svg +1 -0
  314. data/docs/fonts/Novecentosanswide-UltraLight-webfont.ttf +0 -0
  315. data/docs/fonts/Novecentosanswide-UltraLight-webfont.woff +0 -0
  316. data/docs/fonts/Novecentosanswide-UltraLight-webfont.woff2 +0 -0
  317. data/docs/fonts/Work_Sans_200.eot +0 -0
  318. data/docs/fonts/Work_Sans_200.svg +1 -0
  319. data/docs/fonts/Work_Sans_200.ttf +0 -0
  320. data/docs/fonts/Work_Sans_200.woff +0 -0
  321. data/docs/fonts/Work_Sans_200.woff2 +0 -0
  322. data/docs/fonts/Work_Sans_300.eot +0 -0
  323. data/docs/fonts/Work_Sans_300.svg +1 -0
  324. data/docs/fonts/Work_Sans_300.ttf +0 -0
  325. data/docs/fonts/Work_Sans_300.woff +0 -0
  326. data/docs/fonts/Work_Sans_300.woff2 +0 -0
  327. data/docs/fonts/Work_Sans_500.eot +0 -0
  328. data/docs/fonts/Work_Sans_500.svg +1 -0
  329. data/docs/fonts/Work_Sans_500.ttf +0 -0
  330. data/docs/fonts/Work_Sans_500.woff +0 -0
  331. data/docs/fonts/Work_Sans_500.woff2 +0 -0
  332. data/docs/images/clippy.svg +1 -0
  333. data/docs/images/favicon.png +0 -0
  334. data/docs/images/gopher-404.jpg +0 -0
  335. data/docs/imported/changelog/index.html +1208 -1020
  336. data/docs/imported/index.html +1191 -0
  337. data/docs/imported/index.xml +23 -0
  338. data/docs/index.html +925 -558
  339. data/docs/index.json +183 -0
  340. data/docs/index.xml +212 -0
  341. data/docs/js/auto-complete.js +3 -0
  342. data/docs/js/clipboard.min.js +7 -0
  343. data/docs/js/featherlight.min.js +9 -0
  344. data/docs/js/highlight.pack.js +6 -0
  345. data/docs/js/html5shiv-printshiv.min.js +4 -0
  346. data/docs/js/hugo-learn.js +94 -0
  347. data/docs/js/jquery-3.3.1.min.js +2 -0
  348. data/docs/js/jquery.sticky.js +288 -0
  349. data/docs/js/learn.js +459 -0
  350. data/docs/js/lunr.min.js +6 -0
  351. data/docs/js/modernizr.custom-3.6.0.js +3 -0
  352. data/docs/js/perfect-scrollbar.jquery.min.js +2 -0
  353. data/docs/js/perfect-scrollbar.min.js +2 -0
  354. data/docs/js/search.js +93 -0
  355. data/docs/mermaid/mermaid.css +277 -0
  356. data/docs/mermaid/mermaid.dark.css +278 -0
  357. data/docs/mermaid/mermaid.forest.css +356 -0
  358. data/docs/mermaid/mermaid.js +8 -0
  359. data/docs/quick_reference/index.html +1246 -0
  360. data/docs/quick_reference/index.xml +15 -0
  361. data/docs/sitemap.xml +133 -107
  362. data/docs/tags/index.html +1146 -0
  363. data/docs/tags/index.xml +14 -0
  364. data/docs/tutorial/10-getting_started/index.html +994 -662
  365. data/docs/tutorial/20-project_layout/index.html +1013 -722
  366. data/docs/tutorial/30-your_first_command/index.html +1055 -734
  367. data/docs/tutorial/40-options_parameters_and_arguments/index.html +1136 -878
  368. data/docs/tutorial/50-publishing/index.html +984 -671
  369. data/docs/tutorial/index.html +1140 -0
  370. data/docs/tutorial/index.xml +71 -0
  371. data/docs/webfonts/fa-brands-400.eot +0 -0
  372. data/docs/webfonts/fa-brands-400.svg +1 -0
  373. data/docs/webfonts/fa-brands-400.ttf +0 -0
  374. data/docs/webfonts/fa-brands-400.woff +0 -0
  375. data/docs/webfonts/fa-brands-400.woff2 +0 -0
  376. data/docs/webfonts/fa-regular-400.eot +0 -0
  377. data/docs/webfonts/fa-regular-400.svg +1 -0
  378. data/docs/webfonts/fa-regular-400.ttf +0 -0
  379. data/docs/webfonts/fa-regular-400.woff +0 -0
  380. data/docs/webfonts/fa-regular-400.woff2 +0 -0
  381. data/docs/webfonts/fa-solid-900.eot +0 -0
  382. data/docs/webfonts/fa-solid-900.svg +1 -0
  383. data/docs/webfonts/fa-solid-900.ttf +0 -0
  384. data/docs/webfonts/fa-solid-900.woff +0 -0
  385. data/docs/webfonts/fa-solid-900.woff2 +0 -0
  386. data/docs/whoami/index.html +965 -555
  387. data/docs/whoami/index.xml +15 -0
  388. data/exe/rbcli +1 -0
  389. data/lib/rbcli-tool/project.rb +6 -2
  390. data/lib/rbcli/configuration/configurate_blocks/me.rb +5 -5
  391. data/lib/rbcli/engine/command.rb +1 -1
  392. data/lib/rbcli/util/deprecation_warning.rb +21 -4
  393. data/lib/rbcli/util/msg.rb +2 -2
  394. data/lib/rbcli/version.rb +1 -1
  395. data/rbcli.gemspec +12 -13
  396. data/skeletons/project/.rakeTasks +7 -0
  397. data/skeletons/project/Gemfile +1 -1
  398. data/skeletons/project/config/general.rb +1 -1
  399. data/skeletons/project/exe/executable +1 -3
  400. data/skeletons/project/lib/lib.erb +9 -0
  401. data/skeletons/project/spec/spec_helper.rb +7 -7
  402. data/skeletons/project/spec/untitled_spec.rb +6 -6
  403. data/skeletons/project/untitled.gemspec +30 -30
  404. metadata +381 -95
  405. data/docs-src/mkdocs.yml +0 -79
  406. data/docs/assets/fonts/font-awesome.css +0 -4
  407. data/docs/assets/fonts/material-icons.css +0 -13
  408. data/docs/assets/fonts/specimen/FontAwesome.ttf +0 -0
  409. data/docs/assets/fonts/specimen/FontAwesome.woff +0 -0
  410. data/docs/assets/fonts/specimen/FontAwesome.woff2 +0 -0
  411. data/docs/assets/fonts/specimen/MaterialIcons-Regular.ttf +0 -0
  412. data/docs/assets/fonts/specimen/MaterialIcons-Regular.woff +0 -0
  413. data/docs/assets/fonts/specimen/MaterialIcons-Regular.woff2 +0 -0
  414. data/docs/assets/images/favicon.png +0 -0
  415. data/docs/assets/images/icons/bitbucket.1b09e088.svg +0 -20
  416. data/docs/assets/images/icons/github.f0b8504a.svg +0 -18
  417. data/docs/assets/images/icons/gitlab.6dd19c00.svg +0 -38
  418. data/docs/assets/javascripts/application.583bbe55.js +0 -1
  419. data/docs/assets/javascripts/lunr/lunr.da.js +0 -1
  420. data/docs/assets/javascripts/lunr/lunr.de.js +0 -1
  421. data/docs/assets/javascripts/lunr/lunr.du.js +0 -1
  422. data/docs/assets/javascripts/lunr/lunr.es.js +0 -1
  423. data/docs/assets/javascripts/lunr/lunr.fi.js +0 -1
  424. data/docs/assets/javascripts/lunr/lunr.fr.js +0 -1
  425. data/docs/assets/javascripts/lunr/lunr.hu.js +0 -1
  426. data/docs/assets/javascripts/lunr/lunr.it.js +0 -1
  427. data/docs/assets/javascripts/lunr/lunr.jp.js +0 -1
  428. data/docs/assets/javascripts/lunr/lunr.multi.js +0 -1
  429. data/docs/assets/javascripts/lunr/lunr.no.js +0 -1
  430. data/docs/assets/javascripts/lunr/lunr.pt.js +0 -1
  431. data/docs/assets/javascripts/lunr/lunr.ro.js +0 -1
  432. data/docs/assets/javascripts/lunr/lunr.ru.js +0 -1
  433. data/docs/assets/javascripts/lunr/lunr.stemmer.support.js +0 -1
  434. data/docs/assets/javascripts/lunr/lunr.sv.js +0 -1
  435. data/docs/assets/javascripts/lunr/lunr.tr.js +0 -1
  436. data/docs/assets/javascripts/lunr/tinyseg.js +0 -1
  437. data/docs/assets/javascripts/modernizr.1aa3b519.js +0 -1
  438. data/docs/assets/stylesheets/application-palette.22915126.css +0 -1176
  439. data/docs/assets/stylesheets/application.451f80e5.css +0 -2552
  440. data/docs/imported/quick_reference/index.html +0 -1120
  441. data/docs/search/search_index.json +0 -1
  442. data/docs/sitemap.xml.gz +0 -0
  443. data/skeletons/project/lib/.keep +0 -0
@@ -1 +0,0 @@
1
- {"config":{"lang":["en"],"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"This is RBCli 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! Remote Execution : Automatically execute commands on remote machines via SSH 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.","title":"Home"},{"location":"#this-is-rbcli","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! Remote Execution : Automatically execute commands on remote machines via SSH 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.","title":"This is RBCli"},{"location":"whoami/","text":"My Letter To You 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.","title":"whoami"},{"location":"whoami/#my-letter-to-you","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.","title":"My Letter To You"},{"location":"advanced/automatic_updates/","text":"Automatic Updates 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 . GitHub Update Check 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. Rubygems.org Update Check 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.","title":"Automatic Updates"},{"location":"advanced/automatic_updates/#automatic-updates","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 .","title":"Automatic Updates"},{"location":"advanced/automatic_updates/#github-update-check","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.","title":"GitHub Update Check"},{"location":"advanced/automatic_updates/#rubygemsorg-update-check","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.","title":"Rubygems.org Update Check"},{"location":"advanced/command_types/","text":"Advanced Command Types 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 . General Command Structure 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 description 'TODO: Description goes here' # (Required) Short description for the global help usage -EOF TODO: Usage text goes here EOF # (Required) Long description for the command-specific help parameter :force, 'Force testing', type: :boolean, default: false, required: false # (Optional, Multiple) Add a command-specific CLI parameter. Can be called multiple times 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. # 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 end 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 Standard Commands Standard commands are written as ruby code. To create a standard command called list , run: rbcli command --name=list #or rbcli command -n list A standard command can be identified by the presence of an action block in the definition: class List Rbcli::Command action do |params, args, global_opts, config| # Code goes here end end 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 . Scripted Commands 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 script end 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 rbcli args rbcli global_opts rbcli config rbcli myvars echo Usage Examples: echo Log Level: $(rbcli config .logger.log_level) echo Log Target: $(rbcli config .logger.log_target) echo 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 . External Commands 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. Direct Path Mode 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 class List Rbcli::Command extern path: 'path/to/application', envvars: {MYVAR: 'some_value'} # (Required) Runs a given application, with optional environment variables, when the user runs the command. end Here, we supply a string to run the command. We can optioanlly provide environment variables which will be set for the external application. Variable Path Mode 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 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. cmd = '/path/to/application' cmd += ' --test-script foo --ignore-errors' if params[:force] cmd end end 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.","title":"Command Types"},{"location":"advanced/command_types/#advanced-command-types","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 .","title":"Advanced Command Types"},{"location":"advanced/command_types/#general-command-structure","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 description 'TODO: Description goes here' # (Required) Short description for the global help usage -EOF TODO: Usage text goes here EOF # (Required) Long description for the command-specific help parameter :force, 'Force testing', type: :boolean, default: false, required: false # (Optional, Multiple) Add a command-specific CLI parameter. Can be called multiple times 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. # 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 end 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","title":"General Command Structure"},{"location":"advanced/command_types/#standard-commands","text":"Standard commands are written as ruby code. To create a standard command called list , run: rbcli command --name=list #or rbcli command -n list A standard command can be identified by the presence of an action block in the definition: class List Rbcli::Command action do |params, args, global_opts, config| # Code goes here end end 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 .","title":"Standard Commands"},{"location":"advanced/command_types/#scripted-commands","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 script end 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 rbcli args rbcli global_opts rbcli config rbcli myvars echo Usage Examples: echo Log Level: $(rbcli config .logger.log_level) echo Log Target: $(rbcli config .logger.log_target) echo 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 .","title":"Scripted Commands"},{"location":"advanced/command_types/#external-commands","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.","title":"External Commands"},{"location":"advanced/command_types/#direct-path-mode","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 class List Rbcli::Command extern path: 'path/to/application', envvars: {MYVAR: 'some_value'} # (Required) Runs a given application, with optional environment variables, when the user runs the command. end Here, we supply a string to run the command. We can optioanlly provide environment variables which will be set for the external application.","title":"Direct Path Mode"},{"location":"advanced/command_types/#variable-path-mode","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 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. cmd = '/path/to/application' cmd += ' --test-script foo --ignore-errors' if params[:force] cmd end end 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.","title":"Variable Path Mode"},{"location":"advanced/distributed_state_locking/","text":"Distributed Locking and State Sharing 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. Manual Locking 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.","title":"Distributed State Locking"},{"location":"advanced/distributed_state_locking/#distributed-locking-and-state-sharing","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.","title":"Distributed Locking and State Sharing"},{"location":"advanced/distributed_state_locking/#manual-locking","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.","title":"Manual Locking"},{"location":"advanced/hooks/","text":"Execution Hooks 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. The Defailt Action Hook 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 # or rbcli hook -d You will then find the hook under hooks/default_action.rb . The Pre-Execution Hook 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 # or rbcli hook -p You will then find the hook under hooks/pre_execution.rb . The Post-Execution Hook The Pre-Execution hook is called after a command is executed. To create it in your project, run: rbcli hook --post # or rbcli hook -o You will then find the hook under hooks/post_execution.rb . The First-Run Hook 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 # or rbcli hook -f You will then find the hook under hooks/first_run.rb .","title":"Hooks"},{"location":"advanced/hooks/#execution-hooks","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.","title":"Execution Hooks"},{"location":"advanced/hooks/#the-defailt-action-hook","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 # or rbcli hook -d You will then find the hook under hooks/default_action.rb .","title":"The Defailt Action Hook"},{"location":"advanced/hooks/#the-pre-execution-hook","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 # or rbcli hook -p You will then find the hook under hooks/pre_execution.rb .","title":"The Pre-Execution Hook"},{"location":"advanced/hooks/#the-post-execution-hook","text":"The Pre-Execution hook is called after a command is executed. To create it in your project, run: rbcli hook --post # or rbcli hook -o You will then find the hook under hooks/post_execution.rb .","title":"The Post-Execution Hook"},{"location":"advanced/hooks/#the-first-run-hook","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 # or rbcli hook -f You will then find the hook under hooks/first_run.rb .","title":"The First-Run Hook"},{"location":"advanced/interactive_commands/","text":"Interactive Commands Why interactive commands? When catering to an audience of users who are not accustomed to scripting, you may want to prompt them for the information directly (the typical CS-101 'puts' and 'gets' pattern). This can be a lot more straightforward than having to read the help texts of your tool, and trying multiple times to enter all of the required data. Of course, we want to make sure that scripting with the tool still works well (headless interaction). We accomplish this by extending our parameters with a prompt option; RBCli will continue to accept the parameter as usual, but if the parameter is omitted then it will prompt the user with the given text. How to do it with Rbcli There is an option when declaring a command's parameters to prompt the user for a value if not entered on the command line. This can be done with the prompt: keyword. For example: class Mycmd Rbcli::Command parameter :sort, 'Sort output alphabetically', type: :boolean, default: false, prompt: Sort output alphabetically? action do |params, args, global_opts, config| puts params[:sort] end end Now, if we run the command while omitting the --sort parameter, as such: mytool mycmd That should give you the prompt: Sort output alphabetically? (y/N): Because we set the parameter to default to false the default here is N , which is used if the user hits enter without entering a letter. If the default was set to true , then the Y would be capitalized and be the default. String parameters behave similarly, but default to the string defined instead of a boolean value.","title":"Interactive Commands"},{"location":"advanced/interactive_commands/#interactive-commands","text":"","title":"Interactive Commands"},{"location":"advanced/interactive_commands/#why-interactive-commands","text":"When catering to an audience of users who are not accustomed to scripting, you may want to prompt them for the information directly (the typical CS-101 'puts' and 'gets' pattern). This can be a lot more straightforward than having to read the help texts of your tool, and trying multiple times to enter all of the required data. Of course, we want to make sure that scripting with the tool still works well (headless interaction). We accomplish this by extending our parameters with a prompt option; RBCli will continue to accept the parameter as usual, but if the parameter is omitted then it will prompt the user with the given text.","title":"Why interactive commands?"},{"location":"advanced/interactive_commands/#how-to-do-it-with-rbcli","text":"There is an option when declaring a command's parameters to prompt the user for a value if not entered on the command line. This can be done with the prompt: keyword. For example: class Mycmd Rbcli::Command parameter :sort, 'Sort output alphabetically', type: :boolean, default: false, prompt: Sort output alphabetically? action do |params, args, global_opts, config| puts params[:sort] end end Now, if we run the command while omitting the --sort parameter, as such: mytool mycmd That should give you the prompt: Sort output alphabetically? (y/N): Because we set the parameter to default to false the default here is N , which is used if the user hits enter without entering a letter. If the default was set to true , then the Y would be capitalized and be the default. String parameters behave similarly, but default to the string defined instead of a boolean value.","title":"How to do it with Rbcli"},{"location":"advanced/logging/","text":"Logging Logging with RBCli is straightforward - it looks at the config file for logging settings, and instantiates a single, globally accessible Logger object. You can access it within a standard command like this: Rbcli::log.info { 'These logs can go to STDERR, STDOUT, or a file' } Enabling Logging To enable logging, simply set the default values in the config/logging.rb file: log_level :info log_target 'stderr' log_level You can set the default log level using either numeric or standard Ruby logger levels: 0-5, or DEBUG INFO WARN ERROR FATAL UNKNOWN log_target This specifies where the logs will be placed. Valid values are nil (disables logging), 'STDOUT', 'STDERR', or a file path (all as strings). Userspace Config Overrides If Userspace Configuration is enabled, these options will also be present in the user's config file to override defaults: # Log Settings logger: log_level: warn # 0-5, or DEBUG INFO WARN ERROR FATAL UNKNOWN log_target: stderr # STDOUT, STDERR, or a file path","title":"Logging"},{"location":"advanced/logging/#logging","text":"Logging with RBCli is straightforward - it looks at the config file for logging settings, and instantiates a single, globally accessible Logger object. You can access it within a standard command like this: Rbcli::log.info { 'These logs can go to STDERR, STDOUT, or a file' }","title":"Logging"},{"location":"advanced/logging/#enabling-logging","text":"To enable logging, simply set the default values in the config/logging.rb file: log_level :info log_target 'stderr' log_level You can set the default log level using either numeric or standard Ruby logger levels: 0-5, or DEBUG INFO WARN ERROR FATAL UNKNOWN log_target This specifies where the logs will be placed. Valid values are nil (disables logging), 'STDOUT', 'STDERR', or a file path (all as strings).","title":"Enabling Logging"},{"location":"advanced/logging/#userspace-config-overrides","text":"If Userspace Configuration is enabled, these options will also be present in the user's config file to override defaults: # Log Settings logger: log_level: warn # 0-5, or DEBUG INFO WARN ERROR FATAL UNKNOWN log_target: stderr # STDOUT, STDERR, or a file path","title":"Userspace Config Overrides"},{"location":"advanced/remote_execution/","text":"Remote Execution RBCli can be configured to execute commands on a remote machine via SSH instead of locally. Currently, only script and extern commands are supported. Configuration To allow remote execution, go to config/general.rb and change the following line to true : remote_execution permitted: false Then, for each command that you would like to enable remote execution for, add the following directive to the command class declaration: remote_permitted Usage Your end users can now execute a command remotely by specifying the connection string and credentials on the command line as follows: mytool --remote-exec [user@]host[:port] --identity (/path/to/private/ssh/key or password) command # or mytool -r [user@]host[:port] -i (/path/to/private/ssh/key or password) command Some valid examples are: mytool -r example.com -i myPassword showuserfiles -u MyUser mytool -r root@server.local -i ~/.ssh/id_rsa update mytool -r admin@172.16.0.1:2202 -i ~/.ssh/mykey cleartemp If the end user is unsure of which commands can or can not be executed remotely, they can check by running mytool -h . Commands that have remote execution enabled will have an asterisk (*) by their name: $ mytool -h A simple command line tool. For more information on individual commands, run `mytool command -h`. Usage: foo [options] command [parameters] Commands: bar TODO: Description goes here * baz TODO: Description goes here ... In this example, the command baz is available for remote execution","title":"Remote Execution"},{"location":"advanced/remote_execution/#remote-execution","text":"RBCli can be configured to execute commands on a remote machine via SSH instead of locally. Currently, only script and extern commands are supported.","title":"Remote Execution"},{"location":"advanced/remote_execution/#configuration","text":"To allow remote execution, go to config/general.rb and change the following line to true : remote_execution permitted: false Then, for each command that you would like to enable remote execution for, add the following directive to the command class declaration: remote_permitted","title":"Configuration"},{"location":"advanced/remote_execution/#usage","text":"Your end users can now execute a command remotely by specifying the connection string and credentials on the command line as follows: mytool --remote-exec [user@]host[:port] --identity (/path/to/private/ssh/key or password) command # or mytool -r [user@]host[:port] -i (/path/to/private/ssh/key or password) command Some valid examples are: mytool -r example.com -i myPassword showuserfiles -u MyUser mytool -r root@server.local -i ~/.ssh/id_rsa update mytool -r admin@172.16.0.1:2202 -i ~/.ssh/mykey cleartemp If the end user is unsure of which commands can or can not be executed remotely, they can check by running mytool -h . Commands that have remote execution enabled will have an asterisk (*) by their name: $ mytool -h A simple command line tool. For more information on individual commands, run `mytool command -h`. Usage: foo [options] command [parameters] Commands: bar TODO: Description goes here * baz TODO: Description goes here ... In this example, the command baz is available for remote execution","title":"Usage"},{"location":"advanced/state_storage/","text":"State Storage RBCli supports both local and remote state storage. This is done by synchronizing a Hash with either the local disk or a remote database. Local State RBCli's local state storage gives you access to a hash that is automatically persisted to disk when changes are made. Configuration 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. Access and Usage 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. Remote State 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. Configuration 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 . Access and Usage 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","title":"State Storage"},{"location":"advanced/state_storage/#state-storage","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.","title":"State Storage"},{"location":"advanced/state_storage/#local-state","text":"RBCli's local state storage gives you access to a hash that is automatically persisted to disk when changes are made.","title":"Local State"},{"location":"advanced/state_storage/#configuration","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.","title":"Configuration"},{"location":"advanced/state_storage/#access-and-usage","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.","title":"Access and Usage"},{"location":"advanced/state_storage/#remote-state","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.","title":"Remote State"},{"location":"advanced/state_storage/#configuration_1","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 .","title":"Configuration"},{"location":"advanced/state_storage/#access-and-usage_1","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","title":"Access and Usage"},{"location":"advanced/user_config_files/","text":"Configuration Files 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 . Defaults chain 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 ' User chain 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 , default settings override user 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.","title":"User Config Files"},{"location":"advanced/user_config_files/#configuration-files","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 .","title":"Configuration Files"},{"location":"advanced/user_config_files/#defaults-chain","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 '","title":"Defaults chain"},{"location":"advanced/user_config_files/#user-chain","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 , default settings override user 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.","title":"User chain"},{"location":"development/code_of_conduct/","text":"Contributor Covenant Code of Conduct Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. Our Standards Examples of behavior that contributes to creating a positive environment include: 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 advances Trolling, insulting/derogatory comments, and personal or political attacks Public or private harassment Publishing others' private information, such as a physical or electronic address, without explicit permission Other conduct which could reasonably be considered inappropriate in a professional setting Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at andrew@blacknex.us. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. Attribution This Code of Conduct is adapted from the Contributor Covenant , version 1.4, available at http://contributor-covenant.org/version/1/4","title":"Code of Conduct"},{"location":"development/code_of_conduct/#contributor-covenant-code-of-conduct","text":"","title":"Contributor Covenant Code of Conduct"},{"location":"development/code_of_conduct/#our-pledge","text":"In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.","title":"Our Pledge"},{"location":"development/code_of_conduct/#our-standards","text":"Examples of behavior that contributes to creating a positive environment include: 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 advances Trolling, insulting/derogatory comments, and personal or political attacks Public or private harassment Publishing others' private information, such as a physical or electronic address, without explicit permission Other conduct which could reasonably be considered inappropriate in a professional setting","title":"Our Standards"},{"location":"development/code_of_conduct/#our-responsibilities","text":"Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.","title":"Our Responsibilities"},{"location":"development/code_of_conduct/#scope","text":"This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.","title":"Scope"},{"location":"development/code_of_conduct/#enforcement","text":"Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at andrew@blacknex.us. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.","title":"Enforcement"},{"location":"development/code_of_conduct/#attribution","text":"This Code of Conduct is adapted from the Contributor Covenant , version 1.4, available at http://contributor-covenant.org/version/1/4","title":"Attribution"},{"location":"development/contributing/","text":"Contribution Guide 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. Code Acceptance Criteria Tabs, Not Spaces 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. Documentation for User Features 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. Deprecations If a feature needs to be deprecated, RBCli has a built-in deprecation message feature. You can leverage it by calling the following code when a deprecated command is called: Rbcli::DeprecationWarning.new deprecated_command, message, version_when_code_will_be_removed So, for example: Rbcli::DeprecationWarning.new 'Rbcli::Configurate.me--first_run', 'Please use `RBCli::Configurate.hooks` as the parent block instead.', '0.3.0' will display the following message to the user, in red, any any time the application is run: DEPRECATION WRNING: The feature `Rbcli::Configurate.me--post_hook` has been deprecated. Please use `RBCli::Configurate.hooks` as the parent block instead. This feature will be removed in version 0.3.0. Additionally, it will place the same line in the logs using Rbcli.logger.warn if logging is enabled. If a deprecation warning has been added, please remember to mention it in the pull request so that others can update it later. Maintainer's Notes 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 with a commit message of \"vX.X.X\" (where X.X.X is the version number), 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 .","title":"Contribution Guide"},{"location":"development/contributing/#contribution-guide","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.","title":"Contribution Guide"},{"location":"development/contributing/#code-acceptance-criteria","text":"","title":"Code Acceptance Criteria"},{"location":"development/contributing/#tabs-not-spaces","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.","title":"Tabs, Not Spaces"},{"location":"development/contributing/#documentation-for-user-features","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.","title":"Documentation for User Features"},{"location":"development/contributing/#deprecations","text":"If a feature needs to be deprecated, RBCli has a built-in deprecation message feature. You can leverage it by calling the following code when a deprecated command is called: Rbcli::DeprecationWarning.new deprecated_command, message, version_when_code_will_be_removed So, for example: Rbcli::DeprecationWarning.new 'Rbcli::Configurate.me--first_run', 'Please use `RBCli::Configurate.hooks` as the parent block instead.', '0.3.0' will display the following message to the user, in red, any any time the application is run: DEPRECATION WRNING: The feature `Rbcli::Configurate.me--post_hook` has been deprecated. Please use `RBCli::Configurate.hooks` as the parent block instead. This feature will be removed in version 0.3.0. Additionally, it will place the same line in the logs using Rbcli.logger.warn if logging is enabled. If a deprecation warning has been added, please remember to mention it in the pull request so that others can update it later.","title":"Deprecations"},{"location":"development/contributing/#maintainers-notes","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 with a commit message of \"vX.X.X\" (where X.X.X is the version number), 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 .","title":"Maintainer's Notes"},{"location":"development/license/","text":"How RBCli is Licensed 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 . The License You can view the offical license for RBCli Here . For more details about the GPLv3 License, see Here .","title":"License Info"},{"location":"development/license/#how-rbcli-is-licensed","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 .","title":"How RBCli is Licensed"},{"location":"development/license/#the-license","text":"You can view the offical license for RBCli Here . For more details about the GPLv3 License, see Here .","title":"The License"},{"location":"imported/changelog/","text":"Changelog 0.2.6 (UNRELEASED) Bugfixes Fixed a bug that caused the rbcli tool not to detect project folders correctly. Command parameter prompt: now works when required is set to true . Changes The rbcli init command now initializes into the current working directory instead of creating a new one. Fixed erroneous documentation about the 'merge' setting on userspace config. 0.2.5 (Oct 8, 2018) Improvements Added a useful error message when local or remote state is used but not initialized. Bugfixes Fixed a bug in the Github Updater where RBCli crashed when a version tag was not present in the repo. Fixed a bug where deleting a state key would crash Rbcli Fixed a bug where remote state crashed with certain configurations 0.2.4 (Sep 4, 2018) This is a dummy release required to update the License in the Gemspec file. The license has not changed (GPLv3). 0.2.3 (Sep 4, 2018) Features Interactive Commands -- Prompt the user for parameters with a given value Improvements Added documentation on logging 0.2.2 (Aug 22, 2018) Features Bugfixes Fixed a bug that caused the logger's target and level not to be configured properly via the Configurate block. Improvements Lazy-loading has been implemented in optional modules such as autoupdates, remote storage, etc. This means that if you do not enable them in the code, they will not be loaded into memory. This significantly improves loding times for applications. Abstraction system created for configuration. This has significantly simplified the existing codebase and makes future development easier. Deprecation warning system added. This allows for RBCli contributors to notify users of breaking changes that may impact their code. Folder structure has been simplified to ease development. Much of the code has been refactored. Deprecations/Changes The Rbcli module is now RBCli to better match the branding. The original Rbcli module will still work for this current release, with a warning, but future releases will require code changes. Hooks are now defined under the RBCli.Configurate.hooks block instead of RBCli.Configurate.me . The logger is now silent by default. To enable it, it must be configured either via the Configurate block or via the user's config file. 0.2.1 (Aug 8, 2018) Features Remote Execution added for Script and External commands Bugfixes Fixed a bug that caused RBCli to crash if a direct path mode script's environment variables were declared as symbols 0.2.0 (Aug 5, 2018) Features CLI tool Autoupdate Enabled; when an upgrade to RBCli is detected, the RBCli CLI tool will notify the developer. 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 Bugfixes Fixed version number loading for projects Cleaned up command usage help output Fixed script and external command generation Improvements A quick reference guide can now be found in README.md 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 Deprecations/Changes Removed deprecated and broken examples from the examples folder","title":"Changelog"},{"location":"imported/changelog/#changelog","text":"","title":"Changelog"},{"location":"imported/changelog/#026-unreleased","text":"","title":"0.2.6 (UNRELEASED)"},{"location":"imported/changelog/#bugfixes","text":"Fixed a bug that caused the rbcli tool not to detect project folders correctly. Command parameter prompt: now works when required is set to true .","title":"Bugfixes"},{"location":"imported/changelog/#changes","text":"The rbcli init command now initializes into the current working directory instead of creating a new one. Fixed erroneous documentation about the 'merge' setting on userspace config.","title":"Changes"},{"location":"imported/changelog/#025-oct-8-2018","text":"","title":"0.2.5 (Oct 8, 2018)"},{"location":"imported/changelog/#improvements","text":"Added a useful error message when local or remote state is used but not initialized.","title":"Improvements"},{"location":"imported/changelog/#bugfixes_1","text":"Fixed a bug in the Github Updater where RBCli crashed when a version tag was not present in the repo. Fixed a bug where deleting a state key would crash Rbcli Fixed a bug where remote state crashed with certain configurations","title":"Bugfixes"},{"location":"imported/changelog/#024-sep-4-2018","text":"This is a dummy release required to update the License in the Gemspec file. The license has not changed (GPLv3).","title":"0.2.4 (Sep 4, 2018)"},{"location":"imported/changelog/#023-sep-4-2018","text":"","title":"0.2.3 (Sep 4, 2018)"},{"location":"imported/changelog/#features","text":"Interactive Commands -- Prompt the user for parameters with a given value","title":"Features"},{"location":"imported/changelog/#improvements_1","text":"Added documentation on logging","title":"Improvements"},{"location":"imported/changelog/#022-aug-22-2018","text":"","title":"0.2.2 (Aug 22, 2018)"},{"location":"imported/changelog/#features_1","text":"","title":"Features"},{"location":"imported/changelog/#bugfixes_2","text":"Fixed a bug that caused the logger's target and level not to be configured properly via the Configurate block.","title":"Bugfixes"},{"location":"imported/changelog/#improvements_2","text":"Lazy-loading has been implemented in optional modules such as autoupdates, remote storage, etc. This means that if you do not enable them in the code, they will not be loaded into memory. This significantly improves loding times for applications. Abstraction system created for configuration. This has significantly simplified the existing codebase and makes future development easier. Deprecation warning system added. This allows for RBCli contributors to notify users of breaking changes that may impact their code. Folder structure has been simplified to ease development. Much of the code has been refactored.","title":"Improvements"},{"location":"imported/changelog/#deprecationschanges","text":"The Rbcli module is now RBCli to better match the branding. The original Rbcli module will still work for this current release, with a warning, but future releases will require code changes. Hooks are now defined under the RBCli.Configurate.hooks block instead of RBCli.Configurate.me . The logger is now silent by default. To enable it, it must be configured either via the Configurate block or via the user's config file.","title":"Deprecations/Changes"},{"location":"imported/changelog/#021-aug-8-2018","text":"","title":"0.2.1 (Aug 8, 2018)"},{"location":"imported/changelog/#features_2","text":"Remote Execution added for Script and External commands","title":"Features"},{"location":"imported/changelog/#bugfixes_3","text":"Fixed a bug that caused RBCli to crash if a direct path mode script's environment variables were declared as symbols","title":"Bugfixes"},{"location":"imported/changelog/#020-aug-5-2018","text":"","title":"0.2.0 (Aug 5, 2018)"},{"location":"imported/changelog/#features_3","text":"CLI tool Autoupdate Enabled; when an upgrade to RBCli is detected, the RBCli CLI tool will notify the developer. 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","title":"Features"},{"location":"imported/changelog/#bugfixes_4","text":"Fixed version number loading for projects Cleaned up command usage help output Fixed script and external command generation","title":"Bugfixes"},{"location":"imported/changelog/#improvements_3","text":"A quick reference guide can now be found in README.md 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","title":"Improvements"},{"location":"imported/changelog/#deprecationschanges_1","text":"Removed deprecated and broken examples from the examples folder","title":"Deprecations/Changes"},{"location":"imported/quick_reference/","text":"Quick Reference Installation 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 . Creating a command 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 Standard Commands 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. Scripted Commands 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. External Commands 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. Hooks 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 rbcli hook --pre # Runs before any command rbcli hook --post # Runs after any command rbcli hook --firstrun # Runs the first time a user runs your application. Requires userspace config. rbcli hook -dpof # Create all hooks at once Storage RBCli supports both local and remote state storage. This is done by synchronizing a Hash with either the local disk or a remote database. Local State 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] . Remote State 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] . Userspace Configuration Files 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. Logging RBCli's logger is configured in config/logging.rb . log_level :info log_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. Automatic Update Check 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. Remote Execution RBCli can automatically execute script and extern commands on remote machines via SSH. Enable this feature in config/general.rb by changing the following line to true : remote_execution permitted: false Then for each command you want to enable remote execution for, add the following directive: remote_permitted Users can then execute commands remotly by specifying the connection string and credentials on the command line: mytool --remote-exec [user@]host[:port] --identity (/path/to/private/ssh/key or password) command ... Development and Contributing For more information about development and contributing, please see the Official Development Documentation License The gem is available as open source under the terms of the GPLv3 . Full Documentation You can find the Official Documentation for RBCli Here.","title":"Quick Reference"},{"location":"imported/quick_reference/#quick-reference","text":"","title":"Quick Reference"},{"location":"imported/quick_reference/#installation","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 .","title":"Installation"},{"location":"imported/quick_reference/#creating-a-command","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","title":"Creating a command"},{"location":"imported/quick_reference/#standard-commands","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.","title":"Standard Commands"},{"location":"imported/quick_reference/#scripted-commands","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.","title":"Scripted Commands"},{"location":"imported/quick_reference/#external-commands","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.","title":"External Commands"},{"location":"imported/quick_reference/#hooks","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 rbcli hook --pre # Runs before any command rbcli hook --post # Runs after any command rbcli hook --firstrun # Runs the first time a user runs your application. Requires userspace config. rbcli hook -dpof # Create all hooks at once","title":"Hooks"},{"location":"imported/quick_reference/#storage","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.","title":"Storage"},{"location":"imported/quick_reference/#local-state","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] .","title":"Local State"},{"location":"imported/quick_reference/#remote-state","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] .","title":"Remote State"},{"location":"imported/quick_reference/#userspace-configuration-files","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.","title":"Userspace Configuration Files"},{"location":"imported/quick_reference/#logging","text":"RBCli's logger is configured in config/logging.rb . log_level :info log_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.","title":"Logging"},{"location":"imported/quick_reference/#automatic-update-check","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.","title":"Automatic Update Check"},{"location":"imported/quick_reference/#remote-execution","text":"RBCli can automatically execute script and extern commands on remote machines via SSH. Enable this feature in config/general.rb by changing the following line to true : remote_execution permitted: false Then for each command you want to enable remote execution for, add the following directive: remote_permitted Users can then execute commands remotly by specifying the connection string and credentials on the command line: mytool --remote-exec [user@]host[:port] --identity (/path/to/private/ssh/key or password) command ...","title":"Remote Execution"},{"location":"imported/quick_reference/#development-and-contributing","text":"For more information about development and contributing, please see the Official Development Documentation","title":"Development and Contributing"},{"location":"imported/quick_reference/#license","text":"The gem is available as open source under the terms of the GPLv3 .","title":"License"},{"location":"imported/quick_reference/#full-documentation","text":"You can find the Official Documentation for RBCli Here.","title":"Full Documentation"},{"location":"tutorial/10-getting_started/","text":"Getting Started 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. Supported Ruby Versions 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. Installation 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 ls -ahl Congratulations! This is the beginning of your first project. Next Steps Next, you will learn about the layout of an RBCli project and how to code with it.","title":"Getting Started"},{"location":"tutorial/10-getting_started/#getting-started","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.","title":"Getting Started"},{"location":"tutorial/10-getting_started/#supported-ruby-versions","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.","title":"Supported Ruby Versions"},{"location":"tutorial/10-getting_started/#installation","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 ls -ahl Congratulations! This is the beginning of your first project.","title":"Installation"},{"location":"tutorial/10-getting_started/#next-steps","text":"Next, you will learn about the layout of an RBCli project and how to code with it.","title":"Next Steps"},{"location":"tutorial/20-project_layout/","text":"The Project Layout Now we will learn about what an RBCli project looks like and how to start using it. Project Initialization Types RBCli can initialize a tool in three different modes: Project Mode (default) Mini Mode Micro Mode Project Mode 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. Mini Micro Modes 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 # or rbcli 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. Project Mode Structure An RBCli project has the following structure: name / |--- application/ | |--- commands/ | | |--- scripts/ | |--- options.rb |--- config/ |--- exe/ | |--- name |--- hooks/ |--- lib/ |--- spec/ |--- userconf/ |--- .gitignore |--- .rbcli |--- .rspec |--- CODE_OF_CONDUCT.md |--- Gemfile |--- README.md |--- Rakefile |--- name .gemspec Git, RubyGems, and rspec 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 . RBCli Folders 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. Next Steps 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!","title":"The Project Layout"},{"location":"tutorial/20-project_layout/#the-project-layout","text":"Now we will learn about what an RBCli project looks like and how to start using it.","title":"The Project Layout"},{"location":"tutorial/20-project_layout/#project-initialization-types","text":"RBCli can initialize a tool in three different modes: Project Mode (default) Mini Mode Micro Mode","title":"Project Initialization Types"},{"location":"tutorial/20-project_layout/#project-mode","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.","title":"Project Mode"},{"location":"tutorial/20-project_layout/#mini-micro-modes","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 # or rbcli 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.","title":"Mini & Micro Modes"},{"location":"tutorial/20-project_layout/#project-mode-structure","text":"An RBCli project has the following structure: name / |--- application/ | |--- commands/ | | |--- scripts/ | |--- options.rb |--- config/ |--- exe/ | |--- name |--- hooks/ |--- lib/ |--- spec/ |--- userconf/ |--- .gitignore |--- .rbcli |--- .rspec |--- CODE_OF_CONDUCT.md |--- Gemfile |--- README.md |--- Rakefile |--- name .gemspec","title":"Project Mode Structure"},{"location":"tutorial/20-project_layout/#git-rubygems-and-rspec","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 .","title":"Git, RubyGems, and rspec"},{"location":"tutorial/20-project_layout/#rbcli-folders","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.","title":"RBCli Folders"},{"location":"tutorial/20-project_layout/#next-steps","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!","title":"Next Steps"},{"location":"tutorial/30-your_first_command/","text":"Your First Command Creating the Command Creating the command is straightforward: rbcli command --name=list #or rbcli 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. The Command Declaration 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 description 'TODO: Description goes here' # (Required) Short description for the global help usage -EOF TODO: Usage text goes here EOF # (Required) Long description for the command-specific help parameter :force, 'Force testing', type: :boolean, default: false, required: false # (Optional, Multiple) Add a command-specific CLI parameter. Can be called multiple times 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. # 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 action do |params, args, global_opts, config| # (Required) Block to execute if the command is called. Rbcli::log.info { 'These logs can go to STDERR, STDOUT, or a file' } # Example log. Interface is identical to Ruby's logger puts \\nArgs:\\n#{args} # Arguments that came after the command on the CLI (i.e.: `mytool test bar baz` will yield args=['bar', 'baz']) puts Params:\\n#{params} # Parameters, as described through the option statements above puts Global opts:\\n#{global_opts} # Global Parameters, as descirbed in the Configurate section puts Config:\\n#{config} # Config file values puts LocalState:\\n#{Rbcli.local_state} # Local persistent state storage (when available) -- if unsure use Rbcli.local_state.nil? puts RemoteState:\\n#{Rbcli.remote_state} # Remote persistent state storage (when available) -- if unsure use Rbcli.remote_state.nil? puts \\nDone!!! end end 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 Creating the \"list\" Command 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 description %q{List files in current directory} usage -EOF Ever wanted to see your files? Now you can! EOF action do |params, args, global_opts, config| filelist = [] # We store a list of the files in an array, including dotfiles if specified Dir.glob ./* do |filename| outname = filename.split('/')[1] outname += '/' if File.directory? filename filelist.append outname end # Apply color filelist.map! do |filename| if File.directory? filename filename.light_blue elsif File.executable? filename filename.light_green else filename end end if global_opts[:color] puts filelist end end 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. Next Steps 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.","title":"Your First Command"},{"location":"tutorial/30-your_first_command/#your-first-command","text":"","title":"Your First Command"},{"location":"tutorial/30-your_first_command/#creating-the-command","text":"Creating the command is straightforward: rbcli command --name=list #or rbcli 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.","title":"Creating the Command"},{"location":"tutorial/30-your_first_command/#the-command-declaration","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 description 'TODO: Description goes here' # (Required) Short description for the global help usage -EOF TODO: Usage text goes here EOF # (Required) Long description for the command-specific help parameter :force, 'Force testing', type: :boolean, default: false, required: false # (Optional, Multiple) Add a command-specific CLI parameter. Can be called multiple times 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. # 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 action do |params, args, global_opts, config| # (Required) Block to execute if the command is called. Rbcli::log.info { 'These logs can go to STDERR, STDOUT, or a file' } # Example log. Interface is identical to Ruby's logger puts \\nArgs:\\n#{args} # Arguments that came after the command on the CLI (i.e.: `mytool test bar baz` will yield args=['bar', 'baz']) puts Params:\\n#{params} # Parameters, as described through the option statements above puts Global opts:\\n#{global_opts} # Global Parameters, as descirbed in the Configurate section puts Config:\\n#{config} # Config file values puts LocalState:\\n#{Rbcli.local_state} # Local persistent state storage (when available) -- if unsure use Rbcli.local_state.nil? puts RemoteState:\\n#{Rbcli.remote_state} # Remote persistent state storage (when available) -- if unsure use Rbcli.remote_state.nil? puts \\nDone!!! end end 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","title":"The Command Declaration"},{"location":"tutorial/30-your_first_command/#creating-the-list-command","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 description %q{List files in current directory} usage -EOF Ever wanted to see your files? Now you can! EOF action do |params, args, global_opts, config| filelist = [] # We store a list of the files in an array, including dotfiles if specified Dir.glob ./* do |filename| outname = filename.split('/')[1] outname += '/' if File.directory? filename filelist.append outname end # Apply color filelist.map! do |filename| if File.directory? filename filename.light_blue elsif File.executable? filename filename.light_green else filename end end if global_opts[:color] puts filelist end end 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.","title":"Creating the \"list\" Command"},{"location":"tutorial/30-your_first_command/#next-steps","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.","title":"Next Steps"},{"location":"tutorial/40-options_parameters_and_arguments/","text":"Options, Paramters, and Arguments If you're already an experienced coder, you can jump to the last section of this document, the Simplified Reference (TLDR) Command Line Structure 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 mytool parse foo.txt mytool 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. Options 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| Dir.glob ./* do |filename| outname = filename.split('/')[1] outname += '/' if File.directory? filename # We change the color based on the kind of file shown if global_opts[:color] if File.directory? filename outname = outname.light_blue elsif File.executable? filename outname = outname.light_green end end puts outname end 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 Parameters 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 parameter :all, 'Show hidden files', type: :boolean, default: false parameter :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| filelist = [] # We include dotfiles if specified include_dotfiles = (params[:all]) ? File::FNM_DOTMATCH : 0 # We store a list of the files in an array, including dotfiles if specified Dir.glob ./* , include_dotfiles do |filename| outname = filename.split('/')[1] outname += '/' if File.directory? filename filelist.append outname end # Sort alphabetically if specified filelist.sort! if params[:sort] # Put directories first if specified if params[:directoriesfirst] files = []; dirs = [] filelist.each do |filename| if File.directory? filename dirs.append(filename) else files.append(filename) end end filelist = dirs + files end # Apply color. We do this at the end now because color codes can alter the sorting. filelist.map! do |filename| if File.directory? filename filename.light_blue elsif File.executable? filename filename.light_green else filename end end if global_opts[:color] puts filelist 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. User Prompting There is an additional option when declaring parameters to prompt the user for a value if not entered on the command line. This can be done with the prompt: keyword. Let's change one of our parameters to utilize it: parameter :sort, 'Sort output alphabetically', type: :boolean, default: false, prompt: Sort output alphabetically? Now, let's run the tool while omitting the --sort parameter, as such: mytool -c list -ad This should give you the prompt: Sort output alphabetically? (y/N): Because we set the parameter to default to false the default here is N , which is used if the user hits enter without entering a letter. If the default was set to true , then the Y would be capitalized and be the default. For more information, see the documentation on Interactive Commands . Arguments 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 description %q{List files in current directory} usage -EOF To list only specific files, you can enter filenames as arguments mytool list filename1 filename2... EOF parameter :sort, 'Sort output alphabetically', type: :boolean, default: false parameter :all, 'Show hidden files', type: :boolean, default: false parameter :directoriesfirst, 'Show directories on top', type: :boolean, default: false action do |params, args, global_opts, config| filelist = [] # We include dotfiles if specified include_dotfiles = (params[:all]) ? File::FNM_DOTMATCH : 0 # We store a list of the files in an array, including dotfiles if specified Dir.glob ./* , include_dotfiles do |filename| outname = filename.split('/')[1] next unless args.include? outname if args.length 0 outname += '/' if File.directory? filename filelist.append outname end # Sort alphabetically if specified filelist.sort! if params[:sort] # Put directories first if specified if params[:directoriesfirst] files = []; dirs = [] filelist.each do |filename| if File.directory? filename dirs.append(filename) else files.append(filename) end end filelist = dirs + files end # Apply color. We do this at the end because color codes can alter the sorting filelist.map! do |filename| if File.directory? filename filename.light_blue elsif File.executable? filename filename.light_green else filename end end if global_opts[:color] puts filelist end end Simplified Reference (TLDR) 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] parameter : 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) Next Steps Next, we're going to take a quick look at how to publish and distribute your application, both publicly and within your organization.","title":"Options, Parameters, and Arguments"},{"location":"tutorial/40-options_parameters_and_arguments/#options-paramters-and-arguments","text":"If you're already an experienced coder, you can jump to the last section of this document, the Simplified Reference (TLDR)","title":"Options, Paramters, and Arguments"},{"location":"tutorial/40-options_parameters_and_arguments/#command-line-structure","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 mytool parse foo.txt mytool 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.","title":"Command Line Structure"},{"location":"tutorial/40-options_parameters_and_arguments/#options","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| Dir.glob ./* do |filename| outname = filename.split('/')[1] outname += '/' if File.directory? filename # We change the color based on the kind of file shown if global_opts[:color] if File.directory? filename outname = outname.light_blue elsif File.executable? filename outname = outname.light_green end end puts outname end 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","title":"Options"},{"location":"tutorial/40-options_parameters_and_arguments/#parameters","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 parameter :all, 'Show hidden files', type: :boolean, default: false parameter :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| filelist = [] # We include dotfiles if specified include_dotfiles = (params[:all]) ? File::FNM_DOTMATCH : 0 # We store a list of the files in an array, including dotfiles if specified Dir.glob ./* , include_dotfiles do |filename| outname = filename.split('/')[1] outname += '/' if File.directory? filename filelist.append outname end # Sort alphabetically if specified filelist.sort! if params[:sort] # Put directories first if specified if params[:directoriesfirst] files = []; dirs = [] filelist.each do |filename| if File.directory? filename dirs.append(filename) else files.append(filename) end end filelist = dirs + files end # Apply color. We do this at the end now because color codes can alter the sorting. filelist.map! do |filename| if File.directory? filename filename.light_blue elsif File.executable? filename filename.light_green else filename end end if global_opts[:color] puts filelist 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.","title":"Parameters"},{"location":"tutorial/40-options_parameters_and_arguments/#user-prompting","text":"There is an additional option when declaring parameters to prompt the user for a value if not entered on the command line. This can be done with the prompt: keyword. Let's change one of our parameters to utilize it: parameter :sort, 'Sort output alphabetically', type: :boolean, default: false, prompt: Sort output alphabetically? Now, let's run the tool while omitting the --sort parameter, as such: mytool -c list -ad This should give you the prompt: Sort output alphabetically? (y/N): Because we set the parameter to default to false the default here is N , which is used if the user hits enter without entering a letter. If the default was set to true , then the Y would be capitalized and be the default. For more information, see the documentation on Interactive Commands .","title":"User Prompting"},{"location":"tutorial/40-options_parameters_and_arguments/#arguments","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 description %q{List files in current directory} usage -EOF To list only specific files, you can enter filenames as arguments mytool list filename1 filename2... EOF parameter :sort, 'Sort output alphabetically', type: :boolean, default: false parameter :all, 'Show hidden files', type: :boolean, default: false parameter :directoriesfirst, 'Show directories on top', type: :boolean, default: false action do |params, args, global_opts, config| filelist = [] # We include dotfiles if specified include_dotfiles = (params[:all]) ? File::FNM_DOTMATCH : 0 # We store a list of the files in an array, including dotfiles if specified Dir.glob ./* , include_dotfiles do |filename| outname = filename.split('/')[1] next unless args.include? outname if args.length 0 outname += '/' if File.directory? filename filelist.append outname end # Sort alphabetically if specified filelist.sort! if params[:sort] # Put directories first if specified if params[:directoriesfirst] files = []; dirs = [] filelist.each do |filename| if File.directory? filename dirs.append(filename) else files.append(filename) end end filelist = dirs + files end # Apply color. We do this at the end because color codes can alter the sorting filelist.map! do |filename| if File.directory? filename filename.light_blue elsif File.executable? filename filename.light_green else filename end end if global_opts[:color] puts filelist end end","title":"Arguments"},{"location":"tutorial/40-options_parameters_and_arguments/#simplified-reference-tldr","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] parameter : 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)","title":"Simplified Reference (TLDR)"},{"location":"tutorial/40-options_parameters_and_arguments/#next-steps","text":"Next, we're going to take a quick look at how to publish and distribute your application, both publicly and within your organization.","title":"Next Steps"},{"location":"tutorial/50-publishing/","text":"Publishing Your Application RBCli creates projects designed to be easily distributed via either source control or as a gem. We'll go over both methods. Common Tasks 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). Source Control Distribution 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 gem build mytool.gemspec gem 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. Rubygems.org Distribution 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 . Recommended Platforms 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. Next Steps 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.","title":"Publishing and Distribution"},{"location":"tutorial/50-publishing/#publishing-your-application","text":"RBCli creates projects designed to be easily distributed via either source control or as a gem. We'll go over both methods.","title":"Publishing Your Application"},{"location":"tutorial/50-publishing/#common-tasks","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).","title":"Common Tasks"},{"location":"tutorial/50-publishing/#source-control-distribution","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 gem build mytool.gemspec gem 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.","title":"Source Control Distribution"},{"location":"tutorial/50-publishing/#rubygemsorg-distribution","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 .","title":"Rubygems.org Distribution"},{"location":"tutorial/50-publishing/#recommended-platforms","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.","title":"Recommended Platforms"},{"location":"tutorial/50-publishing/#next-steps","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.","title":"Next Steps"}]}
Binary file
File without changes