rbcli 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (506) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +9 -0
  3. data/LICENSE.txt +5 -670
  4. data/README.md +64 -160
  5. data/VERSION +1 -0
  6. data/exe/rbcli +181 -242
  7. data/lib/rbcli/components/commands/command.rb +120 -0
  8. data/lib/rbcli/components/commands/command.rb.erb +55 -0
  9. data/lib/rbcli/components/commands/command_old.rb +105 -0
  10. data/lib/rbcli/components/commands/script.rb.erb +43 -0
  11. data/{lib-sh → lib/rbcli/components/commands/scriptwrapper}/lib-rbcli.sh +29 -34
  12. data/lib/rbcli/components/commands/scriptwrapper/scriptwrapper.rb +64 -0
  13. data/lib/rbcli/components/config/backend.rb +102 -0
  14. data/lib/rbcli/components/config/backends/env.rb +67 -0
  15. data/lib/rbcli/components/config/backends/helpers/deep_assign.rb +47 -0
  16. data/lib/rbcli/components/config/backends/ini.rb +53 -0
  17. data/lib/rbcli/components/config/backends/json.rb +32 -0
  18. data/lib/rbcli/components/config/backends/null.rb +32 -0
  19. data/lib/rbcli/components/config/backends/toml.rb +38 -0
  20. data/lib/rbcli/components/config/backends/yaml.rb +31 -0
  21. data/lib/rbcli/components/config/component.rb +33 -0
  22. data/lib/rbcli/components/config/config.rb +165 -0
  23. data/lib/rbcli/components/config/config_of_death.rb +12 -0
  24. data/lib/rbcli/components/config/template.rb.erb +36 -0
  25. data/lib/rbcli/components/core/configurate.rb +63 -0
  26. data/lib/rbcli/components/core/engine.rb +30 -0
  27. data/lib/rbcli/components/core/warehouse.rb +18 -0
  28. data/lib/rbcli/components/envvars/component.rb +20 -0
  29. data/lib/rbcli/components/envvars/template.rb.erb +24 -0
  30. data/lib/rbcli/components/hooks/component.rb +36 -0
  31. data/lib/rbcli/components/hooks/template.rb.erb +20 -0
  32. data/lib/rbcli/components/logger/component.rb +32 -0
  33. data/lib/rbcli/components/logger/logger.rb +155 -0
  34. data/lib/rbcli/components/logger/lolcat/lol.rb +71 -0
  35. data/lib/rbcli/components/logger/template.rb.erb +40 -0
  36. data/lib/rbcli/components/parser/component.rb +33 -0
  37. data/lib/rbcli/components/parser/optimist/optimist.rb +1149 -0
  38. data/lib/rbcli/components/parser/parser.rb +178 -0
  39. data/lib/rbcli/components/parser/template.rb.erb +35 -0
  40. data/lib/rbcli/components/updatechecker/common/common.rb +52 -0
  41. data/lib/rbcli/components/updatechecker/component.rb +42 -0
  42. data/lib/rbcli/components/updatechecker/gem_checker.rb +40 -0
  43. data/lib/rbcli/components/updatechecker/github_checker.rb +46 -0
  44. data/lib/rbcli/components/updatechecker/template.rb.erb +14 -0
  45. data/lib/rbcli/util/deprecation_warning.rb +41 -55
  46. data/lib/rbcli/util/errors.rb +12 -0
  47. data/lib/rbcli/util/exit.rb +12 -0
  48. data/lib/rbcli/util/hash_deep_symbolize.rb +26 -41
  49. data/lib/rbcli/util/string_compression.rb +10 -0
  50. data/lib/rbcli/version.rb +5 -20
  51. data/lib/rbcli-tool/helpers.rb +58 -0
  52. data/lib/rbcli-tool/skeletons/gem.rb.erb +17 -0
  53. data/lib/rbcli-tool/skeletons/portable.rb.erb +48 -0
  54. data/lib/rbcli.rb +19 -50
  55. data/sig/rbcli.rbs +9 -0
  56. metadata +125 -495
  57. data/.gitignore +0 -60
  58. data/.rakeTasks +0 -7
  59. data/.rbenv-gemsets +0 -1
  60. data/.travis.yml +0 -5
  61. data/CHANGELOG.md +0 -181
  62. data/CODE_OF_CONDUCT.md +0 -74
  63. data/Gemfile +0 -6
  64. data/Gemfile.lock +0 -78
  65. data/Rakefile +0 -10
  66. data/bin/console +0 -33
  67. data/bin/setup +0 -28
  68. data/docs/404.html +0 -59
  69. data/docs/advanced/automatic_updates/index.html +0 -1174
  70. data/docs/advanced/command_types/index.html +0 -1262
  71. data/docs/advanced/distributed_state_locking/index.html +0 -1176
  72. data/docs/advanced/hooks/index.html +0 -1192
  73. data/docs/advanced/index.html +0 -1140
  74. data/docs/advanced/index.xml +0 -113
  75. data/docs/advanced/interactive_commands/index.html +0 -1177
  76. data/docs/advanced/logging/index.html +0 -1184
  77. data/docs/advanced/remote_execution/index.html +0 -1190
  78. data/docs/advanced/state_storage/index.html +0 -1281
  79. data/docs/advanced/user_config_files/index.html +0 -1209
  80. data/docs/categories/index.html +0 -1146
  81. data/docs/categories/index.xml +0 -10
  82. data/docs/css/atom-one-dark-reasonable.css +0 -77
  83. data/docs/css/auto-complete.css +0 -47
  84. data/docs/css/featherlight.min.css +0 -8
  85. data/docs/css/fontawesome-all.min.css +0 -1
  86. data/docs/css/hugo-theme.css +0 -254
  87. data/docs/css/hybrid.css +0 -102
  88. data/docs/css/nucleus.css +0 -615
  89. data/docs/css/perfect-scrollbar.min.css +0 -2
  90. data/docs/css/tags.css +0 -49
  91. data/docs/css/theme-blue.css +0 -111
  92. data/docs/css/theme-green.css +0 -111
  93. data/docs/css/theme-red.css +0 -111
  94. data/docs/css/theme.css +0 -1136
  95. data/docs/development/changelog/index.html +0 -1389
  96. data/docs/development/code_of_conduct/index.html +0 -1222
  97. data/docs/development/contributing/index.html +0 -1201
  98. data/docs/development/index.html +0 -1140
  99. data/docs/development/index.xml +0 -50
  100. data/docs/development/license/index.html +0 -1165
  101. data/docs/fonts/Inconsolata.eot +0 -0
  102. data/docs/fonts/Inconsolata.svg +0 -1
  103. data/docs/fonts/Inconsolata.ttf +0 -0
  104. data/docs/fonts/Inconsolata.woff +0 -0
  105. data/docs/fonts/Novecentosanswide-Normal-webfont.eot +0 -0
  106. data/docs/fonts/Novecentosanswide-Normal-webfont.svg +0 -1
  107. data/docs/fonts/Novecentosanswide-Normal-webfont.ttf +0 -0
  108. data/docs/fonts/Novecentosanswide-Normal-webfont.woff +0 -0
  109. data/docs/fonts/Novecentosanswide-Normal-webfont.woff2 +0 -0
  110. data/docs/fonts/Novecentosanswide-UltraLight-webfont.eot +0 -0
  111. data/docs/fonts/Novecentosanswide-UltraLight-webfont.svg +0 -1
  112. data/docs/fonts/Novecentosanswide-UltraLight-webfont.ttf +0 -0
  113. data/docs/fonts/Novecentosanswide-UltraLight-webfont.woff +0 -0
  114. data/docs/fonts/Novecentosanswide-UltraLight-webfont.woff2 +0 -0
  115. data/docs/fonts/Work_Sans_200.eot +0 -0
  116. data/docs/fonts/Work_Sans_200.svg +0 -1
  117. data/docs/fonts/Work_Sans_200.ttf +0 -0
  118. data/docs/fonts/Work_Sans_200.woff +0 -0
  119. data/docs/fonts/Work_Sans_200.woff2 +0 -0
  120. data/docs/fonts/Work_Sans_300.eot +0 -0
  121. data/docs/fonts/Work_Sans_300.svg +0 -1
  122. data/docs/fonts/Work_Sans_300.ttf +0 -0
  123. data/docs/fonts/Work_Sans_300.woff +0 -0
  124. data/docs/fonts/Work_Sans_300.woff2 +0 -0
  125. data/docs/fonts/Work_Sans_500.eot +0 -0
  126. data/docs/fonts/Work_Sans_500.svg +0 -1
  127. data/docs/fonts/Work_Sans_500.ttf +0 -0
  128. data/docs/fonts/Work_Sans_500.woff +0 -0
  129. data/docs/fonts/Work_Sans_500.woff2 +0 -0
  130. data/docs/images/clippy.svg +0 -1
  131. data/docs/images/favicon.png +0 -0
  132. data/docs/images/gopher-404.jpg +0 -0
  133. data/docs/imported/changelog/index.html +0 -1449
  134. data/docs/imported/index.html +0 -1191
  135. data/docs/imported/index.xml +0 -23
  136. data/docs/index.html +0 -1138
  137. data/docs/index.json +0 -183
  138. data/docs/index.xml +0 -208
  139. data/docs/js/auto-complete.js +0 -3
  140. data/docs/js/clipboard.min.js +0 -7
  141. data/docs/js/featherlight.min.js +0 -9
  142. data/docs/js/highlight.pack.js +0 -6
  143. data/docs/js/html5shiv-printshiv.min.js +0 -4
  144. data/docs/js/hugo-learn.js +0 -94
  145. data/docs/js/jquery-3.3.1.min.js +0 -2
  146. data/docs/js/jquery.sticky.js +0 -288
  147. data/docs/js/learn.js +0 -459
  148. data/docs/js/lunr.min.js +0 -6
  149. data/docs/js/modernizr.custom-3.6.0.js +0 -3
  150. data/docs/js/perfect-scrollbar.jquery.min.js +0 -2
  151. data/docs/js/perfect-scrollbar.min.js +0 -2
  152. data/docs/js/search.js +0 -93
  153. data/docs/mermaid/mermaid.css +0 -277
  154. data/docs/mermaid/mermaid.dark.css +0 -278
  155. data/docs/mermaid/mermaid.forest.css +0 -356
  156. data/docs/mermaid/mermaid.js +0 -8
  157. data/docs/quick_reference/index.html +0 -1246
  158. data/docs/quick_reference/index.xml +0 -11
  159. data/docs/sitemap.xml +0 -82
  160. data/docs/tags/index.html +0 -1146
  161. data/docs/tags/index.xml +0 -10
  162. data/docs/tutorial/10-getting_started/index.html +0 -1174
  163. data/docs/tutorial/20-project_layout/index.html +0 -1299
  164. data/docs/tutorial/30-your_first_command/index.html +0 -1263
  165. data/docs/tutorial/40-options_parameters_and_arguments/index.html +0 -1384
  166. data/docs/tutorial/50-publishing/index.html +0 -1187
  167. data/docs/tutorial/index.html +0 -1140
  168. data/docs/tutorial/index.xml +0 -67
  169. data/docs/webfonts/fa-brands-400.eot +0 -0
  170. data/docs/webfonts/fa-brands-400.svg +0 -1
  171. data/docs/webfonts/fa-brands-400.ttf +0 -0
  172. data/docs/webfonts/fa-brands-400.woff +0 -0
  173. data/docs/webfonts/fa-brands-400.woff2 +0 -0
  174. data/docs/webfonts/fa-regular-400.eot +0 -0
  175. data/docs/webfonts/fa-regular-400.svg +0 -1
  176. data/docs/webfonts/fa-regular-400.ttf +0 -0
  177. data/docs/webfonts/fa-regular-400.woff +0 -0
  178. data/docs/webfonts/fa-regular-400.woff2 +0 -0
  179. data/docs/webfonts/fa-solid-900.eot +0 -0
  180. data/docs/webfonts/fa-solid-900.svg +0 -1
  181. data/docs/webfonts/fa-solid-900.ttf +0 -0
  182. data/docs/webfonts/fa-solid-900.woff +0 -0
  183. data/docs/webfonts/fa-solid-900.woff2 +0 -0
  184. data/docs/whoami/index.html +0 -1155
  185. data/docs/whoami/index.xml +0 -11
  186. data/docs-src/archetypes/default.md +0 -6
  187. data/docs-src/config.toml +0 -37
  188. data/docs-src/content/_index.md +0 -40
  189. data/docs-src/content/advanced/_index.md +0 -11
  190. data/docs-src/content/advanced/automatic_updates.md +0 -46
  191. data/docs-src/content/advanced/command_types.md +0 -148
  192. data/docs-src/content/advanced/distributed_state_locking.md +0 -37
  193. data/docs-src/content/advanced/hooks.md +0 -69
  194. data/docs-src/content/advanced/interactive_commands.md +0 -41
  195. data/docs-src/content/advanced/logging.md +0 -39
  196. data/docs-src/content/advanced/remote_execution.md +0 -60
  197. data/docs-src/content/advanced/state_storage.md +0 -120
  198. data/docs-src/content/advanced/user_config_files.md +0 -51
  199. data/docs-src/content/development/_index.md +0 -11
  200. data/docs-src/content/development/changelog.md +0 -179
  201. data/docs-src/content/development/code_of_conduct.md +0 -81
  202. data/docs-src/content/development/contributing.md +0 -88
  203. data/docs-src/content/development/license.md +0 -17
  204. data/docs-src/content/quick_reference/_index.md +0 -180
  205. data/docs-src/content/tutorial/10-getting_started.md +0 -47
  206. data/docs-src/content/tutorial/20-project_layout.md +0 -123
  207. data/docs-src/content/tutorial/30-your_first_command.md +0 -132
  208. data/docs-src/content/tutorial/40-options_parameters_and_arguments.md +0 -282
  209. data/docs-src/content/tutorial/50-publishing.md +0 -53
  210. data/docs-src/content/tutorial/_index.md +0 -11
  211. data/docs-src/content/whoami/_index.md +0 -34
  212. data/docs-src/layouts/partials/logo.html +0 -3
  213. data/docs-src/makesite.sh +0 -40
  214. data/docs-src/mkdocs-archived.tar.gz +0 -0
  215. data/docs-src/runsite.sh +0 -8
  216. data/docs-src/themes/hugo-theme-learn/.editorconfig +0 -16
  217. data/docs-src/themes/hugo-theme-learn/.gitignore +0 -3
  218. data/docs-src/themes/hugo-theme-learn/.grenrc.yml +0 -25
  219. data/docs-src/themes/hugo-theme-learn/CHANGELOG.md +0 -226
  220. data/docs-src/themes/hugo-theme-learn/LICENSE.md +0 -22
  221. data/docs-src/themes/hugo-theme-learn/README.md +0 -97
  222. data/docs-src/themes/hugo-theme-learn/archetypes/chapter.md +0 -13
  223. data/docs-src/themes/hugo-theme-learn/archetypes/default.md +0 -7
  224. data/docs-src/themes/hugo-theme-learn/exampleSite/LICENSE.md +0 -20
  225. data/docs-src/themes/hugo-theme-learn/exampleSite/config.toml +0 -102
  226. data/docs-src/themes/hugo-theme-learn/exampleSite/content/_index.en.md +0 -41
  227. data/docs-src/themes/hugo-theme-learn/exampleSite/content/_index.fr.md +0 -43
  228. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/_index.en.md +0 -12
  229. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/_index.fr.md +0 -12
  230. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/_index.zh.md +0 -12
  231. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/configuration/_index.en.md +0 -60
  232. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/configuration/_index.fr.md +0 -56
  233. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/installation/_index.en.md +0 -102
  234. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/installation/_index.fr.md +0 -100
  235. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/installation/images/chapter.png +0 -0
  236. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/requirements/_index.en.md +0 -11
  237. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/requirements/_index.fr.md +0 -11
  238. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/requirements/images/magic.gif +0 -0
  239. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/_index.en.md +0 -194
  240. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/_index.fr.md +0 -194
  241. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/images/blue-variant.png +0 -0
  242. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/images/green-variant.png +0 -0
  243. data/docs-src/themes/hugo-theme-learn/exampleSite/content/basics/style-customization/images/red-variant.png +0 -0
  244. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/_index.en.md +0 -12
  245. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/_index.fr.md +0 -12
  246. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/archetypes.en.md +0 -57
  247. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/archetypes.fr.md +0 -57
  248. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/i18n/_index.en.md +0 -78
  249. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/i18n/_index.fr.md +0 -78
  250. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/i18n/images/i18n-menu.gif +0 -0
  251. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/icons.en.md +0 -41
  252. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/markdown.en.md +0 -692
  253. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/markdown.fr.md +0 -666
  254. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/menushortcuts.en.md +0 -109
  255. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/menushortcuts.fr.md +0 -109
  256. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/_index.en.md +0 -166
  257. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/_index.fr.md +0 -146
  258. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/images/frontmatter-icon.png +0 -0
  259. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/images/pages-chapter.png +0 -0
  260. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/pages/images/pages-default.png +0 -0
  261. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/syntaxhighlight.en.md +0 -89
  262. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/tags.en.md +0 -39
  263. data/docs-src/themes/hugo-theme-learn/exampleSite/content/cont/tags.fr.md +0 -40
  264. data/docs-src/themes/hugo-theme-learn/exampleSite/content/credits.en.md +0 -28
  265. data/docs-src/themes/hugo-theme-learn/exampleSite/content/credits.fr.md +0 -28
  266. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/_index.en.md +0 -16
  267. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/_index.fr.md +0 -16
  268. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/BachGavotteShort.mp3 +0 -0
  269. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/Carroll_AliceAuPaysDesMerveilles.pdf +0 -0
  270. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/adivorciarsetoca00cape.pdf +0 -0
  271. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/hugo.png +0 -0
  272. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.files/movieselectricsheep-flock-244-32500-2.mp4 +0 -0
  273. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.en.md +0 -85
  274. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/BachGavotteShort.mp3 +0 -0
  275. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/Carroll_AliceAuPaysDesMerveilles.pdf +0 -0
  276. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/adivorciarsetoca00cape.pdf +0 -0
  277. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/hugo.png +0 -0
  278. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.files/movieselectricsheep-flock-244-32500-2.mp4 +0 -0
  279. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/attachments.fr.md +0 -85
  280. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/button.en.md +0 -16
  281. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/button.fr.md +0 -16
  282. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/_index.en.md +0 -45
  283. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/_index.fr.md +0 -45
  284. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/_index.en.md +0 -6
  285. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/_index.fr.md +0 -6
  286. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/_index.en.md +0 -6
  287. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/_index.fr.md +0 -6
  288. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/_index.en.md +0 -6
  289. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/_index.fr.md +0 -6
  290. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/children-1-1-1-1/_index.en.md +0 -6
  291. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/children-1-1-1-1/_index.fr.md +0 -6
  292. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/children-1-1-1-1/children-1-1-1-1-1/_index.en.md +0 -6
  293. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-1/children-1-1/children-1-1-1/children-1-1-1-1/children-1-1-1-1-1/_index.fr.md +0 -6
  294. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-2/_index.en.md +0 -11
  295. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-2/_index.fr.md +0 -11
  296. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-2/test3.en.md +0 -6
  297. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-2/test3.fr.md +0 -6
  298. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-3/_index.en.md +0 -6
  299. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-3/_index.fr.md +0 -6
  300. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-4/_index.en.md +0 -7
  301. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/children-4/_index.fr.md +0 -7
  302. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/test.en.md +0 -6
  303. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/children/test.fr.md +0 -6
  304. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/expand.en.md +0 -45
  305. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/expand.fr.md +0 -45
  306. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/mermaid.en.md +0 -283
  307. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/mermaid.fr.md +0 -283
  308. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/notice.en.md +0 -62
  309. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/notice.fr.md +0 -62
  310. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/siteparam.en.md +0 -23
  311. data/docs-src/themes/hugo-theme-learn/exampleSite/content/shortcodes/siteparam.fr.md +0 -23
  312. data/docs-src/themes/hugo-theme-learn/exampleSite/content/showcase.en.md +0 -13
  313. data/docs-src/themes/hugo-theme-learn/exampleSite/content/showcase.fr.md +0 -14
  314. data/docs-src/themes/hugo-theme-learn/exampleSite/layouts/partials/custom-footer.html +0 -10
  315. data/docs-src/themes/hugo-theme-learn/exampleSite/layouts/partials/logo.html +0 -39
  316. data/docs-src/themes/hugo-theme-learn/exampleSite/layouts/partials/menu-footer.html +0 -14
  317. data/docs-src/themes/hugo-theme-learn/exampleSite/layouts/shortcodes/ghcontributors.html +0 -31
  318. data/docs-src/themes/hugo-theme-learn/exampleSite/static/css/theme-mine.css +0 -104
  319. data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.eot +0 -0
  320. data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.svg +0 -1
  321. data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.ttf +0 -0
  322. data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.woff +0 -0
  323. data/docs-src/themes/hugo-theme-learn/exampleSite/static/fonts/monogramos-webfont.woff2 +0 -0
  324. data/docs-src/themes/hugo-theme-learn/exampleSite/static/images/showcase/inteliver_docs.png +0 -0
  325. data/docs-src/themes/hugo-theme-learn/exampleSite/static/images/showcase/tat.png +0 -0
  326. data/docs-src/themes/hugo-theme-learn/exampleSite/static/images/showcase/tshark_dev.png +0 -0
  327. data/docs-src/themes/hugo-theme-learn/i18n/ar.toml +0 -26
  328. data/docs-src/themes/hugo-theme-learn/i18n/de.toml +0 -26
  329. data/docs-src/themes/hugo-theme-learn/i18n/en.toml +0 -26
  330. data/docs-src/themes/hugo-theme-learn/i18n/es.toml +0 -26
  331. data/docs-src/themes/hugo-theme-learn/i18n/fr.toml +0 -26
  332. data/docs-src/themes/hugo-theme-learn/i18n/hi.toml +0 -26
  333. data/docs-src/themes/hugo-theme-learn/i18n/id.toml +0 -26
  334. data/docs-src/themes/hugo-theme-learn/i18n/ja.toml +0 -26
  335. data/docs-src/themes/hugo-theme-learn/i18n/nl.toml +0 -26
  336. data/docs-src/themes/hugo-theme-learn/i18n/pt.toml +0 -26
  337. data/docs-src/themes/hugo-theme-learn/i18n/ru.toml +0 -26
  338. data/docs-src/themes/hugo-theme-learn/i18n/tr.toml +0 -26
  339. data/docs-src/themes/hugo-theme-learn/i18n/zh-cn.toml +0 -26
  340. data/docs-src/themes/hugo-theme-learn/images/screenshot.png +0 -0
  341. data/docs-src/themes/hugo-theme-learn/images/tn.png +0 -0
  342. data/docs-src/themes/hugo-theme-learn/layouts/404.html +0 -56
  343. data/docs-src/themes/hugo-theme-learn/layouts/_default/list.html +0 -22
  344. data/docs-src/themes/hugo-theme-learn/layouts/_default/single.html +0 -12
  345. data/docs-src/themes/hugo-theme-learn/layouts/index.html +0 -31
  346. data/docs-src/themes/hugo-theme-learn/layouts/index.json +0 -12
  347. data/docs-src/themes/hugo-theme-learn/layouts/partials/custom-comments.html +0 -3
  348. data/docs-src/themes/hugo-theme-learn/layouts/partials/custom-footer.html +0 -5
  349. data/docs-src/themes/hugo-theme-learn/layouts/partials/custom-header.html +0 -5
  350. data/docs-src/themes/hugo-theme-learn/layouts/partials/favicon.html +0 -1
  351. data/docs-src/themes/hugo-theme-learn/layouts/partials/footer.html +0 -77
  352. data/docs-src/themes/hugo-theme-learn/layouts/partials/header.html +0 -111
  353. data/docs-src/themes/hugo-theme-learn/layouts/partials/logo.html +0 -19
  354. data/docs-src/themes/hugo-theme-learn/layouts/partials/menu-footer.html +0 -1
  355. data/docs-src/themes/hugo-theme-learn/layouts/partials/menu.html +0 -151
  356. data/docs-src/themes/hugo-theme-learn/layouts/partials/meta.html +0 -2
  357. data/docs-src/themes/hugo-theme-learn/layouts/partials/search.html +0 -16
  358. data/docs-src/themes/hugo-theme-learn/layouts/partials/tags.html +0 -7
  359. data/docs-src/themes/hugo-theme-learn/layouts/partials/toc.html +0 -5
  360. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/attachments.html +0 -36
  361. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/button.html +0 -14
  362. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/children.html +0 -101
  363. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/expand.html +0 -17
  364. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/mermaid.html +0 -2
  365. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/notice.html +0 -2
  366. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/ref.html +0 -14
  367. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/relref.html +0 -14
  368. data/docs-src/themes/hugo-theme-learn/layouts/shortcodes/siteparam.html +0 -7
  369. data/docs-src/themes/hugo-theme-learn/netlify.toml +0 -23
  370. data/docs-src/themes/hugo-theme-learn/static/css/atom-one-dark-reasonable.css +0 -77
  371. data/docs-src/themes/hugo-theme-learn/static/css/auto-complete.css +0 -47
  372. data/docs-src/themes/hugo-theme-learn/static/css/featherlight.min.css +0 -8
  373. data/docs-src/themes/hugo-theme-learn/static/css/fontawesome-all.min.css +0 -1
  374. data/docs-src/themes/hugo-theme-learn/static/css/hugo-theme.css +0 -254
  375. data/docs-src/themes/hugo-theme-learn/static/css/hybrid.css +0 -102
  376. data/docs-src/themes/hugo-theme-learn/static/css/nucleus.css +0 -615
  377. data/docs-src/themes/hugo-theme-learn/static/css/perfect-scrollbar.min.css +0 -2
  378. data/docs-src/themes/hugo-theme-learn/static/css/tags.css +0 -49
  379. data/docs-src/themes/hugo-theme-learn/static/css/theme-blue.css +0 -111
  380. data/docs-src/themes/hugo-theme-learn/static/css/theme-green.css +0 -111
  381. data/docs-src/themes/hugo-theme-learn/static/css/theme-red.css +0 -111
  382. data/docs-src/themes/hugo-theme-learn/static/css/theme.css +0 -1136
  383. data/docs-src/themes/hugo-theme-learn/static/fonts/Inconsolata.eot +0 -0
  384. data/docs-src/themes/hugo-theme-learn/static/fonts/Inconsolata.svg +0 -1
  385. data/docs-src/themes/hugo-theme-learn/static/fonts/Inconsolata.ttf +0 -0
  386. data/docs-src/themes/hugo-theme-learn/static/fonts/Inconsolata.woff +0 -0
  387. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.eot +0 -0
  388. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.svg +0 -1
  389. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.ttf +0 -0
  390. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.woff +0 -0
  391. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-Normal-webfont.woff2 +0 -0
  392. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.eot +0 -0
  393. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.svg +0 -1
  394. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.ttf +0 -0
  395. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.woff +0 -0
  396. data/docs-src/themes/hugo-theme-learn/static/fonts/Novecentosanswide-UltraLight-webfont.woff2 +0 -0
  397. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.eot +0 -0
  398. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.svg +0 -1
  399. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.ttf +0 -0
  400. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.woff +0 -0
  401. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_200.woff2 +0 -0
  402. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.eot +0 -0
  403. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.svg +0 -1
  404. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.ttf +0 -0
  405. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.woff +0 -0
  406. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_300.woff2 +0 -0
  407. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.eot +0 -0
  408. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.svg +0 -1
  409. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.ttf +0 -0
  410. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.woff +0 -0
  411. data/docs-src/themes/hugo-theme-learn/static/fonts/Work_Sans_500.woff2 +0 -0
  412. data/docs-src/themes/hugo-theme-learn/static/images/clippy.svg +0 -1
  413. data/docs-src/themes/hugo-theme-learn/static/images/favicon.png +0 -0
  414. data/docs-src/themes/hugo-theme-learn/static/images/gopher-404.jpg +0 -0
  415. data/docs-src/themes/hugo-theme-learn/static/js/auto-complete.js +0 -3
  416. data/docs-src/themes/hugo-theme-learn/static/js/clipboard.min.js +0 -7
  417. data/docs-src/themes/hugo-theme-learn/static/js/featherlight.min.js +0 -9
  418. data/docs-src/themes/hugo-theme-learn/static/js/highlight.pack.js +0 -6
  419. data/docs-src/themes/hugo-theme-learn/static/js/hugo-learn.js +0 -94
  420. data/docs-src/themes/hugo-theme-learn/static/js/jquery-3.3.1.min.js +0 -2
  421. data/docs-src/themes/hugo-theme-learn/static/js/jquery.sticky.js +0 -288
  422. data/docs-src/themes/hugo-theme-learn/static/js/learn.js +0 -459
  423. data/docs-src/themes/hugo-theme-learn/static/js/lunr.min.js +0 -6
  424. data/docs-src/themes/hugo-theme-learn/static/js/modernizr.custom-3.6.0.js +0 -3
  425. data/docs-src/themes/hugo-theme-learn/static/js/perfect-scrollbar.jquery.min.js +0 -2
  426. data/docs-src/themes/hugo-theme-learn/static/js/perfect-scrollbar.min.js +0 -2
  427. data/docs-src/themes/hugo-theme-learn/static/js/search.js +0 -93
  428. data/docs-src/themes/hugo-theme-learn/static/mermaid/mermaid.css +0 -277
  429. data/docs-src/themes/hugo-theme-learn/static/mermaid/mermaid.dark.css +0 -278
  430. data/docs-src/themes/hugo-theme-learn/static/mermaid/mermaid.forest.css +0 -356
  431. data/docs-src/themes/hugo-theme-learn/static/mermaid/mermaid.js +0 -8
  432. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.eot +0 -0
  433. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.svg +0 -1
  434. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.ttf +0 -0
  435. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.woff +0 -0
  436. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-brands-400.woff2 +0 -0
  437. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.eot +0 -0
  438. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.svg +0 -1
  439. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.ttf +0 -0
  440. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.woff +0 -0
  441. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-regular-400.woff2 +0 -0
  442. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.eot +0 -0
  443. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.svg +0 -1
  444. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.ttf +0 -0
  445. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.woff +0 -0
  446. data/docs-src/themes/hugo-theme-learn/static/webfonts/fa-solid-900.woff2 +0 -0
  447. data/docs-src/themes/hugo-theme-learn/theme.toml +0 -21
  448. data/docs-src/themes/hugo-theme-learn/wercker.yml +0 -16
  449. data/lib/rbcli/configuration/configurate.rb +0 -85
  450. data/lib/rbcli/configuration/configurate_blocks/hooks.rb +0 -52
  451. data/lib/rbcli/configuration/configurate_blocks/me.rb +0 -122
  452. data/lib/rbcli/configuration/configurate_blocks/storage.rb +0 -50
  453. data/lib/rbcli/engine/command.rb +0 -251
  454. data/lib/rbcli/engine/load_project.rb +0 -45
  455. data/lib/rbcli/engine/parser.rb +0 -114
  456. data/lib/rbcli/features/autoupdate/common/autoupdate.rb +0 -50
  457. data/lib/rbcli/features/autoupdate/gem_updater.rb +0 -62
  458. data/lib/rbcli/features/autoupdate/github_updater.rb +0 -76
  459. data/lib/rbcli/features/logging.rb +0 -98
  460. data/lib/rbcli/features/remote_exec.rb +0 -187
  461. data/lib/rbcli/features/scriptwrapper.rb +0 -75
  462. data/lib/rbcli/features/userconfig.rb +0 -163
  463. data/lib/rbcli/state_storage/common/state_storage.rb +0 -138
  464. data/lib/rbcli/state_storage/localstate.rb +0 -77
  465. data/lib/rbcli/state_storage/placeholders.rb +0 -29
  466. data/lib/rbcli/state_storage/remote_state_connectors/dynamodb.rb +0 -272
  467. data/lib/rbcli/state_storage/remotestate_dynamodb.rb +0 -115
  468. data/lib/rbcli/util/msg.rb +0 -55
  469. data/lib/rbcli/util/string_colorize.rb +0 -45
  470. data/lib/rbcli/util/trollop.rb +0 -1050
  471. data/lib/rbcli-tool/generators.rb +0 -105
  472. data/lib/rbcli-tool/mdless_fix.rb +0 -406
  473. data/lib/rbcli-tool/project.rb +0 -120
  474. data/lib/rbcli-tool/util.rb +0 -70
  475. data/lib/rbcli-tool.rb +0 -37
  476. data/rbcli.gemspec +0 -69
  477. data/skeletons/micro/executable +0 -127
  478. data/skeletons/mini/executable +0 -242
  479. data/skeletons/project/.gitignore +0 -11
  480. data/skeletons/project/.rakeTasks +0 -7
  481. data/skeletons/project/.rspec +0 -3
  482. data/skeletons/project/CODE_OF_CONDUCT.md +0 -74
  483. data/skeletons/project/Gemfile +0 -6
  484. data/skeletons/project/README.md +0 -46
  485. data/skeletons/project/Rakefile +0 -6
  486. data/skeletons/project/application/commands/command.erb +0 -28
  487. data/skeletons/project/application/commands/script.erb +0 -30
  488. data/skeletons/project/application/commands/scripts/script.sh +0 -60
  489. data/skeletons/project/application/options.rb +0 -34
  490. data/skeletons/project/config/autoupdate.rb +0 -35
  491. data/skeletons/project/config/general.rb +0 -17
  492. data/skeletons/project/config/logging.rb +0 -19
  493. data/skeletons/project/config/storage.rb +0 -35
  494. data/skeletons/project/config/userspace.rb +0 -33
  495. data/skeletons/project/config/version.rb +0 -3
  496. data/skeletons/project/exe/executable +0 -53
  497. data/skeletons/project/hooks/default_action.rb +0 -16
  498. data/skeletons/project/hooks/first_run.rb +0 -16
  499. data/skeletons/project/hooks/post_execution.rb +0 -14
  500. data/skeletons/project/hooks/pre_execution.rb +0 -14
  501. data/skeletons/project/lib/lib.erb +0 -9
  502. data/skeletons/project/spec/spec_helper.rb +0 -14
  503. data/skeletons/project/spec/untitled_spec.rb +0 -9
  504. data/skeletons/project/untitled.gemspec +0 -40
  505. data/skeletons/project/userconf/user_defaults.yml +0 -6
  506. /data/{skeletons/project/.rbcli → lib/rbcli/plugins/.keep} +0 -0
@@ -0,0 +1,1149 @@
1
+ # This file pulled and modified from: https://github.com/ManageIQ/optimist/blob/master/lib/optimist.rb
2
+
3
+ # lib/optimist.rb -- optimist command-line processing library
4
+ # Copyright (c) 2008-2014 William Morgan.
5
+ # Copyright (c) 2014 Red Hat, Inc.
6
+ # optimist is licensed under the MIT license.
7
+
8
+ require 'date'
9
+
10
+ module Optimist
11
+ VERSION = "3.1.0"
12
+
13
+ ## Thrown by Parser in the event of a commandline error. Not needed if
14
+ ## you're using the Optimist::options entry.
15
+ class CommandlineError < StandardError
16
+ attr_reader :error_code
17
+
18
+ def initialize(msg, error_code = nil)
19
+ super(msg)
20
+ @error_code = error_code
21
+ end
22
+ end
23
+
24
+ ## Thrown by Parser if the user passes in '-h' or '--help'. Handled
25
+ ## automatically by Optimist#options.
26
+ class HelpNeeded < StandardError
27
+ end
28
+
29
+ ## Thrown by Parser if the user passes in '-v' or '--version'. Handled
30
+ ## automatically by Optimist#options.
31
+ class VersionNeeded < StandardError
32
+ end
33
+
34
+ ## Regex for floating point numbers
35
+ FLOAT_RE = /^-?((\d+(\.\d+)?)|(\.\d+))([eE][-+]?[\d]+)?$/
36
+
37
+ ## Regex for parameters
38
+ PARAM_RE = /^-(-|\.$|[^\d\.])/
39
+
40
+ ## The commandline parser. In typical usage, the methods in this class
41
+ ## will be handled internally by Optimist::options. In this case, only the
42
+ ## #opt, #banner and #version, #depends, and #conflicts methods will
43
+ ## typically be called.
44
+ ##
45
+ ## If you want to instantiate this class yourself (for more complicated
46
+ ## argument-parsing logic), call #parse to actually produce the output hash,
47
+ ## and consider calling it from within
48
+ ## Optimist::with_standard_exception_handling.
49
+ class Parser
50
+
51
+ ## The registry is a class-instance-variable map of option aliases to their subclassed Option class.
52
+ @registry = {}
53
+
54
+ ## The Option subclasses are responsible for registering themselves using this function.
55
+ def self.register(lookup, klass)
56
+ @registry[lookup.to_sym] = klass
57
+ end
58
+
59
+ ## Gets the class from the registry.
60
+ ## Can be given either a class-name, e.g. Integer, a string, e.g "integer", or a symbol, e.g :integer
61
+ def self.registry_getopttype(type)
62
+ return nil unless type
63
+ if type.respond_to?(:name)
64
+ type = type.name
65
+ lookup = type.downcase.to_sym
66
+ else
67
+ lookup = type.to_sym
68
+ end
69
+ raise ArgumentError, "Unsupported argument type '#{type}', registry lookup '#{lookup}'" unless @registry.key?(lookup)
70
+ return @registry[lookup].new
71
+ end
72
+
73
+ INVALID_SHORT_ARG_REGEX = /[\d-]/ #:nodoc:
74
+
75
+ ## The values from the commandline that were not interpreted by #parse.
76
+ attr_reader :leftovers
77
+
78
+ ## The complete configuration hashes for each option. (Mainly useful
79
+ ## for testing.)
80
+ attr_reader :specs
81
+
82
+ ## A flag that determines whether or not to raise an error if the parser is passed one or more
83
+ ## options that were not registered ahead of time. If 'true', then the parser will simply
84
+ ## ignore options that it does not recognize.
85
+ attr_accessor :ignore_invalid_options
86
+
87
+ ## Initializes the parser, and instance-evaluates any block given.
88
+ def initialize(*a, &b)
89
+ @version = nil
90
+ @leftovers = []
91
+ @specs = {}
92
+ @long = {}
93
+ @short = {}
94
+ @order = []
95
+ @constraints = []
96
+ @stop_words = []
97
+ @stop_on_unknown = false
98
+ @educate_on_error = false
99
+ @synopsis = nil
100
+ @usage = nil
101
+
102
+ # instance_eval(&b) if b # can't take arguments
103
+ cloaker(&b).bind(self).call(*a) if b
104
+ end
105
+
106
+ ## Define an option. +name+ is the option name, a unique identifier
107
+ ## for the option that you will use internally, which should be a
108
+ ## symbol or a string. +desc+ is a string description which will be
109
+ ## displayed in help messages.
110
+ ##
111
+ ## Takes the following optional arguments:
112
+ ##
113
+ ## [+:long+] Specify the long form of the argument, i.e. the form with two dashes. If unspecified, will be automatically derived based on the argument name by turning the +name+ option into a string, and replacing any _'s by -'s.
114
+ ## [+:short+] Specify the short form of the argument, i.e. the form with one dash. If unspecified, will be automatically derived from +name+. Use :none: to not have a short value.
115
+ ## [+:type+] Require that the argument take a parameter or parameters of type +type+. For a single parameter, the value can be a member of +SINGLE_ARG_TYPES+, or a corresponding Ruby class (e.g. +Integer+ for +:int+). For multiple-argument parameters, the value can be any member of +MULTI_ARG_TYPES+ constant. If unset, the default argument type is +:flag+, meaning that the argument does not take a parameter. The specification of +:type+ is not necessary if a +:default+ is given.
116
+ ## [+:default+] Set the default value for an argument. Without a default value, the hash returned by #parse (and thus Optimist::options) will have a +nil+ value for this key unless the argument is given on the commandline. The argument type is derived automatically from the class of the default value given, so specifying a +:type+ is not necessary if a +:default+ is given. (But see below for an important caveat when +:multi+: is specified too.) If the argument is a flag, and the default is set to +true+, then if it is specified on the the commandline the value will be +false+.
117
+ ## [+:required+] If set to +true+, the argument must be provided on the commandline.
118
+ ## [+:multi+] If set to +true+, allows multiple occurrences of the option on the commandline. Otherwise, only a single instance of the option is allowed. (Note that this is different from taking multiple parameters. See below.)
119
+ ## [+:permitted+] Specify an Array of permitted values for an option. If the user provides a value outside this list, an error is thrown.
120
+ ##
121
+ ## Note that there are two types of argument multiplicity: an argument
122
+ ## can take multiple values, e.g. "--arg 1 2 3". An argument can also
123
+ ## be allowed to occur multiple times, e.g. "--arg 1 --arg 2".
124
+ ##
125
+ ## Arguments that take multiple values should have a +:type+ parameter
126
+ ## drawn from +MULTI_ARG_TYPES+ (e.g. +:strings+), or a +:default:+
127
+ ## value of an array of the correct type (e.g. [String]). The
128
+ ## value of this argument will be an array of the parameters on the
129
+ ## commandline.
130
+ ##
131
+ ## Arguments that can occur multiple times should be marked with
132
+ ## +:multi+ => +true+. The value of this argument will also be an array.
133
+ ## In contrast with regular non-multi options, if not specified on
134
+ ## the commandline, the default value will be [], not nil.
135
+ ##
136
+ ## These two attributes can be combined (e.g. +:type+ => +:strings+,
137
+ ## +:multi+ => +true+), in which case the value of the argument will be
138
+ ## an array of arrays.
139
+ ##
140
+ ## There's one ambiguous case to be aware of: when +:multi+: is true and a
141
+ ## +:default+ is set to an array (of something), it's ambiguous whether this
142
+ ## is a multi-value argument as well as a multi-occurrence argument.
143
+ ## In thise case, Optimist assumes that it's not a multi-value argument.
144
+ ## If you want a multi-value, multi-occurrence argument with a default
145
+ ## value, you must specify +:type+ as well.
146
+
147
+ def opt(name, desc = "", opts = {}, &b)
148
+ opts[:callback] ||= b if block_given?
149
+ opts[:desc] ||= desc
150
+
151
+ o = Option.create(name, desc, opts)
152
+
153
+ raise ArgumentError, "you already have an argument named '#{name}'" if @specs.member? o.name
154
+ raise ArgumentError, "long option name #{o.long.inspect} is already taken; please specify a (different) :long" if @long[o.long]
155
+ raise ArgumentError, "short option name #{o.short.inspect} is already taken; please specify a (different) :short" if @short[o.short]
156
+ raise ArgumentError, "permitted values for option #{o.long.inspect} must be either nil or an array;" unless o.permitted.nil? or o.permitted.is_a? Array
157
+ @long[o.long] = o.name
158
+ @short[o.short] = o.name if o.short?
159
+ @specs[o.name] = o
160
+ @order << [:opt, o.name]
161
+ end
162
+
163
+ ## Sets the version string. If set, the user can request the version
164
+ ## on the commandline. Should probably be of the form "<program name>
165
+ ## <version number>".
166
+ def version(s = nil)
167
+ s ? @version = s : @version
168
+ end
169
+
170
+ ## Sets the usage string. If set the message will be printed as the
171
+ ## first line in the help (educate) output and ending in two new
172
+ ## lines.
173
+ def usage(s = nil)
174
+ s ? @usage = s : @usage
175
+ end
176
+
177
+ ## Adds a synopsis (command summary description) right below the
178
+ ## usage line, or as the first line if usage isn't specified.
179
+ def synopsis(s = nil)
180
+ s ? @synopsis = s : @synopsis
181
+ end
182
+
183
+ ## Adds text to the help display. Can be interspersed with calls to
184
+ ## #opt to build a multi-section help page.
185
+ def banner(s)
186
+ @order << [:text, s]
187
+ end
188
+
189
+ alias_method :text, :banner
190
+
191
+ ## Marks two (or more!) options as requiring each other. Only handles
192
+ ## undirected (i.e., mutual) dependencies. Directed dependencies are
193
+ ## better modeled with Optimist::die.
194
+ def depends(*syms)
195
+ syms.each { |sym| raise ArgumentError, "unknown option '#{sym}'" unless @specs[sym] }
196
+ @constraints << [:depends, syms]
197
+ end
198
+
199
+ ## Marks two (or more!) options as conflicting.
200
+ def conflicts(*syms)
201
+ syms.each { |sym| raise ArgumentError, "unknown option '#{sym}'" unless @specs[sym] }
202
+ @constraints << [:conflicts, syms]
203
+ end
204
+
205
+ ## Marks two (or more!) options as required but mutually exclusive.
206
+ def either(*syms)
207
+ syms.each { |sym| raise ArgumentError, "unknown option '#{sym}'" unless @specs[sym] }
208
+ @constraints << [:conflicts, syms]
209
+ @constraints << [:either, syms]
210
+ end
211
+
212
+ ## Defines a set of words which cause parsing to terminate when
213
+ ## encountered, such that any options to the left of the word are
214
+ ## parsed as usual, and options to the right of the word are left
215
+ ## intact.
216
+ ##
217
+ ## A typical use case would be for subcommand support, where these
218
+ ## would be set to the list of subcommands. A subsequent Optimist
219
+ ## invocation would then be used to parse subcommand options, after
220
+ ## shifting the subcommand off of ARGV.
221
+ def stop_on(*words)
222
+ @stop_words = [*words].flatten
223
+ end
224
+
225
+ ## Similar to #stop_on, but stops on any unknown word when encountered
226
+ ## (unless it is a parameter for an argument). This is useful for
227
+ ## cases where you don't know the set of subcommands ahead of time,
228
+ ## i.e., without first parsing the global options.
229
+ def stop_on_unknown
230
+ @stop_on_unknown = true
231
+ end
232
+
233
+ ## Instead of displaying "Try --help for help." on an error
234
+ ## display the usage (via educate)
235
+ def educate_on_error
236
+ @educate_on_error = true
237
+ end
238
+
239
+ ## Parses the commandline. Typically called by Optimist::options,
240
+ ## but you can call it directly if you need more control.
241
+ ##
242
+ ## throws CommandlineError, HelpNeeded, and VersionNeeded exceptions.
243
+ def parse(cmdline = ARGV)
244
+ vals = {}
245
+ required = {}
246
+
247
+ opt :version, "Print version and exit" if @version && !(@specs[:version] || @long["version"])
248
+ opt :help, "Show this message" unless @specs[:help] || @long["help"]
249
+
250
+ @specs.each do |sym, opts|
251
+ required[sym] = true if opts.required?
252
+ vals[sym] = opts.default
253
+ vals[sym] = [] if opts.multi && !opts.default && !opts.flag? # multi arguments default to [], not nil
254
+ vals[sym] = 0 if opts.multi && !opts.default && opts.flag? # multi argument flags default to 0 because they return a count
255
+ end
256
+
257
+ resolve_default_short_options!
258
+
259
+ ## resolve symbols
260
+ given_args = {}
261
+ @leftovers = each_arg cmdline do |arg, params|
262
+ ## handle --no- forms
263
+ arg, negative_given = if arg =~ /^--no-([^-]\S*)$/
264
+ ["--#{$1}", true]
265
+ else
266
+ [arg, false]
267
+ end
268
+
269
+ sym = case arg
270
+ when /^-([^-])$/ then @short[$1]
271
+ when /^--([^-]\S*)$/ then @long[$1] || @long["no-#{$1}"]
272
+ else raise CommandlineError, "invalid argument syntax: '#{arg}'"
273
+ end
274
+
275
+ sym = nil if arg =~ /--no-/ # explicitly invalidate --no-no- arguments
276
+
277
+ next nil if ignore_invalid_options && !sym
278
+ raise CommandlineError, "unknown argument '#{arg}'" unless sym
279
+
280
+ if given_args.include?(sym) && !@specs[sym].multi?
281
+ raise CommandlineError, "option '#{arg}' specified multiple times"
282
+ end
283
+
284
+ given_args[sym] ||= {}
285
+ given_args[sym][:arg] = arg
286
+ given_args[sym][:negative_given] = negative_given
287
+ given_args[sym][:params] ||= []
288
+
289
+ # The block returns the number of parameters taken.
290
+ num_params_taken = 0
291
+
292
+ if @specs[sym].multi? && @specs[sym].flag?
293
+ given_args[sym][:params][0] ||= 0
294
+ given_args[sym][:params][0] += 1
295
+ end
296
+
297
+ unless params.empty?
298
+ if @specs[sym].single_arg?
299
+ given_args[sym][:params] << params[0, 1] # take the first parameter
300
+ num_params_taken = 1
301
+ elsif @specs[sym].multi_arg?
302
+ given_args[sym][:params] << params # take all the parameters
303
+ num_params_taken = params.size
304
+ end
305
+ end
306
+
307
+ num_params_taken
308
+ end
309
+
310
+ ## check for version and help args
311
+ raise VersionNeeded if given_args.include? :version
312
+ raise HelpNeeded if given_args.include? :help
313
+
314
+ ## check constraint satisfaction
315
+ @constraints.each do |type, syms|
316
+ constraint_sym = syms.find { |sym| given_args[sym] }
317
+
318
+ case type
319
+ when :depends
320
+ next unless constraint_sym
321
+ syms.each { |sym| raise CommandlineError, "--#{@specs[constraint_sym].long} requires --#{@specs[sym].long}" unless given_args.include? sym }
322
+ when :conflicts
323
+ next unless constraint_sym
324
+ syms.each { |sym| raise CommandlineError, "--#{@specs[constraint_sym].long} conflicts with --#{@specs[sym].long}" if given_args.include?(sym) && (sym != constraint_sym) }
325
+ when :either
326
+ raise CommandlineError, "one of #{syms.map { |sym| "--#{@specs[sym].long}" }.join(', ') } is required" if (syms & given_args.keys).size != 1
327
+ end
328
+ end
329
+
330
+ required.each do |sym, val|
331
+ raise CommandlineError, "option --#{@specs[sym].long} must be specified" unless given_args.include? sym
332
+ end
333
+
334
+ ## parse parameters
335
+ given_args.each do |sym, given_data|
336
+ arg, params, negative_given = given_data.values_at :arg, :params, :negative_given
337
+
338
+ opts = @specs[sym]
339
+ if params.empty? && !opts.flag?
340
+ raise CommandlineError, "option '#{arg}' needs a parameter" unless opts.default
341
+ params << (opts.array_default? ? opts.default.clone : [opts.default])
342
+ end
343
+
344
+ params[0].each do |p|
345
+ raise CommandlineError, "option '#{arg}' only accepts one of: #{opts.permitted.join(', ')}" unless opts.permitted.include? p
346
+ end unless opts.permitted.nil?
347
+
348
+ vals["#{sym}_given".intern] = true # mark argument as specified on the commandline
349
+
350
+ vals[sym] = opts.parse(params, negative_given)
351
+
352
+ if opts.single_arg?
353
+ if opts.multi? # multiple options, each with a single parameter
354
+ vals[sym] = vals[sym].map { |p| p[0] }
355
+ else
356
+ # single parameter
357
+ vals[sym] = vals[sym][0][0]
358
+ end
359
+ elsif opts.multi_arg? && !opts.multi?
360
+ vals[sym] = vals[sym][0] # single option, with multiple parameters
361
+ end
362
+ # else: multiple options, with multiple parameters
363
+
364
+ opts.callback.call(vals[sym]) if opts.callback
365
+ end
366
+
367
+ ## modify input in place with only those
368
+ ## arguments we didn't process
369
+ cmdline.clear
370
+ @leftovers.each { |l| cmdline << l }
371
+
372
+ ## allow openstruct-style accessors
373
+ class << vals
374
+ def method_missing(m, *_args)
375
+ self[m] || self[m.to_s]
376
+ end
377
+ end
378
+
379
+ vals
380
+ end
381
+
382
+ ## Print the help message to +stream+.
383
+ def educate(stream = $stdout)
384
+ width # hack: calculate it now; otherwise we have to be careful not to
385
+ # call this unless the cursor's at the beginning of a line.
386
+
387
+ left = {}
388
+ @specs.each { |name, spec| left[name] = spec.educate }
389
+
390
+ leftcol_width = left.values.map(&:length).max || 0
391
+ rightcol_start = leftcol_width + 6 # spaces
392
+
393
+ unless @order.size > 0 && @order.first.first == :text
394
+ command_name = File.basename($0).gsub(/\.[^.]+$/, '')
395
+ stream.puts "Usage: #{command_name} #{@usage}\n" if @usage
396
+ stream.puts "#{@synopsis}\n" if @synopsis
397
+ stream.puts if @usage || @synopsis
398
+ stream.puts "#{@version}\n" if @version
399
+ stream.puts "Options:"
400
+ end
401
+
402
+ @order.each do |what, opt|
403
+ if what == :text
404
+ stream.puts wrap(opt)
405
+ next
406
+ end
407
+
408
+ spec = @specs[opt]
409
+ stream.printf " %-#{leftcol_width}s ", left[opt]
410
+ desc = spec.full_description
411
+
412
+ stream.puts wrap(desc, :width => width - rightcol_start - 1, :prefix => rightcol_start)
413
+ end
414
+ end
415
+
416
+ def width #:nodoc:
417
+ @width ||= if $stdout.tty?
418
+ begin
419
+ require 'io/console'
420
+ w = IO.console.winsize.last
421
+ w.to_i > 0 ? w : 80
422
+ rescue LoadError, NoMethodError, Errno::ENOTTY, Errno::EBADF, Errno::EINVAL
423
+ legacy_width
424
+ end
425
+ else
426
+ 80
427
+ end
428
+ end
429
+
430
+ def legacy_width
431
+ # Support for older Rubies where io/console is not available
432
+ `tput cols`.to_i
433
+ rescue Errno::ENOENT
434
+ 80
435
+ end
436
+
437
+ private :legacy_width
438
+
439
+ def wrap(str, opts = {})
440
+ # :nodoc:
441
+ if str == ""
442
+ [""]
443
+ else
444
+ inner = false
445
+ str.split("\n").map do |s|
446
+ line = wrap_line s, opts.merge(:inner => inner)
447
+ inner = true
448
+ line
449
+ end.flatten
450
+ end
451
+ end
452
+
453
+ ## The per-parser version of Optimist::die (see that for documentation).
454
+ def die(arg, msg = nil, error_code = nil)
455
+ msg, error_code = nil, msg if msg.kind_of?(Integer)
456
+ if msg
457
+ $stderr.puts "Error: argument --#{@specs[arg].long} #{msg}."
458
+ else
459
+ $stderr.puts "Error: #{arg}."
460
+ end
461
+ if @educate_on_error
462
+ $stderr.puts
463
+ educate $stderr
464
+ else
465
+ $stderr.puts "Try --help for help."
466
+ end
467
+ exit(error_code || -1)
468
+ end
469
+
470
+ private
471
+
472
+ ## yield successive arg, parameter pairs
473
+ def each_arg(args)
474
+ remains = []
475
+ i = 0
476
+
477
+ until i >= args.length
478
+ return remains += args[i..-1] if @stop_words.member? args[i]
479
+ case args[i]
480
+ when /^--$/ # arg terminator
481
+ return remains += args[(i + 1)..-1]
482
+ when /^--(\S+?)=(.*)$/ # long argument with equals
483
+ num_params_taken = yield "--#{$1}", [$2]
484
+ if num_params_taken.nil?
485
+ remains << args[i]
486
+ if @stop_on_unknown
487
+ return remains += args[i + 1..-1]
488
+ end
489
+ end
490
+ i += 1
491
+ when /^--(\S+)$/ # long argument
492
+ params = collect_argument_parameters(args, i + 1)
493
+ num_params_taken = yield args[i], params
494
+
495
+ if num_params_taken.nil?
496
+ remains << args[i]
497
+ if @stop_on_unknown
498
+ return remains += args[i + 1..-1]
499
+ end
500
+ else
501
+ i += num_params_taken
502
+ end
503
+ i += 1
504
+ when /^-(\S+)$/ # one or more short arguments
505
+ short_remaining = ""
506
+ shortargs = $1.split(//)
507
+ shortargs.each_with_index do |a, j|
508
+ if j == (shortargs.length - 1)
509
+ params = collect_argument_parameters(args, i + 1)
510
+
511
+ num_params_taken = yield "-#{a}", params
512
+ unless num_params_taken
513
+ short_remaining << a
514
+ if @stop_on_unknown
515
+ remains << "-#{short_remaining}"
516
+ return remains += args[i + 1..-1]
517
+ end
518
+ else
519
+ i += num_params_taken
520
+ end
521
+ else
522
+ unless yield "-#{a}", []
523
+ short_remaining << a
524
+ if @stop_on_unknown
525
+ short_remaining += shortargs[j + 1..-1].join
526
+ remains << "-#{short_remaining}"
527
+ return remains += args[i + 1..-1]
528
+ end
529
+ end
530
+ end
531
+ end
532
+
533
+ unless short_remaining.empty?
534
+ remains << "-#{short_remaining}"
535
+ end
536
+ i += 1
537
+ else
538
+ if @stop_on_unknown
539
+ return remains += args[i..-1]
540
+ else
541
+ remains << args[i]
542
+ i += 1
543
+ end
544
+ end
545
+ end
546
+
547
+ remains
548
+ end
549
+
550
+ def collect_argument_parameters(args, start_at)
551
+ params = []
552
+ pos = start_at
553
+ while args[pos] && args[pos] !~ PARAM_RE && !@stop_words.member?(args[pos]) do
554
+ params << args[pos]
555
+ pos += 1
556
+ end
557
+ params
558
+ end
559
+
560
+ def resolve_default_short_options!
561
+ @order.each do |type, name|
562
+ opts = @specs[name]
563
+ next if type != :opt || opts.short
564
+
565
+ c = opts.long.split(//).find { |d| d !~ INVALID_SHORT_ARG_REGEX && !@short.member?(d) }
566
+ if c # found a character to use
567
+ opts.short = c
568
+ @short[c] = name
569
+ end
570
+ end
571
+ end
572
+
573
+ def wrap_line(str, opts = {})
574
+ prefix = opts[:prefix] || 0
575
+ width = opts[:width] || (self.width - 1)
576
+ start = 0
577
+ ret = []
578
+ until start > str.length
579
+ nextt =
580
+ if start + width >= str.length
581
+ str.length
582
+ else
583
+ x = str.rindex(/\s/, start + width)
584
+ x = str.index(/\s/, start) if x && x < start
585
+ x || str.length
586
+ end
587
+ ret << ((ret.empty? && !opts[:inner]) ? "" : " " * prefix) + str[start...nextt]
588
+ start = nextt + 1
589
+ end
590
+ ret
591
+ end
592
+
593
+ ## instance_eval but with ability to handle block arguments
594
+ ## thanks to _why: http://redhanded.hobix.com/inspect/aBlockCostume.html
595
+ def cloaker(&b)
596
+ (
597
+ class << self
598
+ self;
599
+ end).class_eval do
600
+ define_method :cloaker_, &b
601
+ meth = instance_method :cloaker_
602
+ remove_method :cloaker_
603
+ meth
604
+ end
605
+ end
606
+ end
607
+
608
+ class Option
609
+
610
+ attr_accessor :name, :short, :long, :default, :permitted
611
+ attr_writer :multi_given
612
+
613
+ def initialize
614
+ @long = nil
615
+ @short = nil
616
+ @name = nil
617
+ @multi_given = false
618
+ @hidden = false
619
+ @default = nil
620
+ @permitted = nil
621
+ @optshash = Hash.new()
622
+ end
623
+
624
+ def opts(key)
625
+ @optshash[key]
626
+ end
627
+
628
+ def opts=(o)
629
+ @optshash = o
630
+ end
631
+
632
+ ## Indicates a flag option, which is an option without an argument
633
+ def flag?
634
+ false;
635
+ end
636
+
637
+ def single_arg?
638
+ !self.multi_arg? && !self.flag?
639
+ end
640
+
641
+ def multi
642
+ @multi_given;
643
+ end
644
+
645
+ alias multi? multi
646
+
647
+ ## Indicates that this is a multivalued (Array type) argument
648
+ def multi_arg?
649
+ false;
650
+ end
651
+
652
+ ## note: Option-Types with both multi_arg? and flag? false are single-parameter (normal) options.
653
+
654
+ def array_default?
655
+ self.default.kind_of?(Array);
656
+ end
657
+
658
+ def short?
659
+ short && short != :none;
660
+ end
661
+
662
+ def callback
663
+ opts(:callback);
664
+ end
665
+
666
+ def desc
667
+ opts(:desc);
668
+ end
669
+
670
+ def required?
671
+ opts(:required);
672
+ end
673
+
674
+ def parse(_paramlist, _neg_given)
675
+ raise NotImplementedError, "parse must be overridden for newly registered type"
676
+ end
677
+
678
+ # provide type-format string. default to empty, but user should probably override it
679
+ def type_format
680
+ "";
681
+ end
682
+
683
+ def educate
684
+ (short? ? "-#{short}, " : " ") + "--#{long}" + type_format + (flag? && default ? ", --no-#{long}" : "")
685
+ end
686
+
687
+ ## Format the educate-line description including the default and permitted value(s)
688
+ def full_description
689
+ desc_str = desc
690
+ desc_str += default_description_str(desc) if default
691
+ desc_str += permitted_description_str(desc) if permitted
692
+ desc_str
693
+ end
694
+
695
+ ## Generate the default value string for the educate line
696
+ private def default_description_str str
697
+ default_s = case default
698
+ when $stdout then '<stdout>'
699
+ when $stdin then '<stdin>'
700
+ when $stderr then '<stderr>'
701
+ when Array
702
+ default.join(', ')
703
+ else
704
+ default.to_s
705
+ end
706
+ defword = str.end_with?('.') ? 'Default' : 'default'
707
+ " (#{defword}: #{default_s})"
708
+ end
709
+
710
+ ## Generate the permitted values string for the educate line
711
+ private def permitted_description_str str
712
+ permitted_s = permitted.map do |p|
713
+ case p
714
+ when $stdout then '<stdout>'
715
+ when $stdin then '<stdin>'
716
+ when $stderr then '<stderr>'
717
+ else
718
+ p.to_s
719
+ end
720
+ end.join(', ')
721
+ permword = str.end_with?('.') ? 'Permitted' : 'permitted'
722
+ " (#{permword}: #{permitted_s})"
723
+ end
724
+
725
+ ## Provide a way to register symbol aliases to the Parser
726
+ def self.register_alias(*alias_keys)
727
+ alias_keys.each do |alias_key|
728
+ # pass in the alias-key and the class
729
+ Parser.register(alias_key, self)
730
+ end
731
+ end
732
+
733
+ ## Factory class methods ...
734
+
735
+ # Determines which type of object to create based on arguments passed
736
+ # to +Optimist::opt+. This is trickier in Optimist, than other cmdline
737
+ # parsers (e.g. Slop) because we allow the +default:+ to be able to
738
+ # set the option's type.
739
+ def self.create(name, desc = "", opts = {}, settings = {})
740
+
741
+ opttype = Optimist::Parser.registry_getopttype(opts[:type])
742
+ opttype_from_default = get_klass_from_default(opts, opttype)
743
+
744
+ raise ArgumentError, ":type specification and default type don't match (default type is #{opttype_from_default.class})" if opttype && opttype_from_default && (opttype.class != opttype_from_default.class)
745
+
746
+ opt_inst = (opttype || opttype_from_default || Optimist::BooleanOption.new)
747
+
748
+ ## fill in :long
749
+ opt_inst.long = handle_long_opt(opts[:long], name)
750
+
751
+ ## fill in :short
752
+ opt_inst.short = handle_short_opt(opts[:short])
753
+
754
+ ## fill in :multi
755
+ multi_given = opts[:multi] || false
756
+ opt_inst.multi_given = multi_given
757
+
758
+ ## fill in :default for flags
759
+ defvalue = opts[:default] || opt_inst.default
760
+
761
+ ## fill in permitted values
762
+ permitted = opts[:permitted] || nil
763
+
764
+ ## autobox :default for :multi (multi-occurrence) arguments
765
+ defvalue = [defvalue] if defvalue && multi_given && !defvalue.kind_of?(Array)
766
+ opt_inst.permitted = permitted
767
+ opt_inst.default = defvalue
768
+ opt_inst.name = name
769
+ opt_inst.opts = opts
770
+ opt_inst
771
+ end
772
+
773
+ private
774
+
775
+ def self.get_type_from_disdef(optdef, opttype, disambiguated_default)
776
+ if disambiguated_default.is_a? Array
777
+ return(optdef.first.class.name.downcase + "s") if !optdef.empty?
778
+ if opttype
779
+ raise ArgumentError, "multiple argument type must be plural" unless opttype.multi_arg?
780
+ return nil
781
+ else
782
+ raise ArgumentError, "multiple argument type cannot be deduced from an empty array"
783
+ end
784
+ end
785
+ return disambiguated_default.class.name.downcase
786
+ end
787
+
788
+ def self.get_klass_from_default(opts, opttype)
789
+ ## for options with :multi => true, an array default doesn't imply
790
+ ## a multi-valued argument. for that you have to specify a :type
791
+ ## as well. (this is how we disambiguate an ambiguous situation;
792
+ ## see the docs for Parser#opt for details.)
793
+
794
+ disambiguated_default = if opts[:multi] && opts[:default].is_a?(Array) && opttype.nil?
795
+ opts[:default].first
796
+ else
797
+ opts[:default]
798
+ end
799
+
800
+ return nil if disambiguated_default.nil?
801
+ type_from_default = get_type_from_disdef(opts[:default], opttype, disambiguated_default)
802
+ return Optimist::Parser.registry_getopttype(type_from_default)
803
+ end
804
+
805
+ def self.handle_long_opt(lopt, name)
806
+ lopt = lopt ? lopt.to_s : name.to_s.gsub("_", "-")
807
+ lopt = case lopt
808
+ when /^--([^-].*)$/ then $1
809
+ when /^[^-]/ then lopt
810
+ else raise ArgumentError, "invalid long option name #{lopt.inspect}"
811
+ end
812
+ end
813
+
814
+ def self.handle_short_opt(sopt)
815
+ sopt = sopt.to_s if sopt && sopt != :none
816
+ sopt = case sopt
817
+ when /^-(.)$/ then $1
818
+ when nil, :none, /^.$/ then sopt
819
+ else raise ArgumentError, "invalid short option name '#{sopt.inspect}'"
820
+ end
821
+
822
+ if sopt
823
+ raise ArgumentError, "a short option name can't be a number or a dash" if sopt =~ ::Optimist::Parser::INVALID_SHORT_ARG_REGEX
824
+ end
825
+ return sopt
826
+ end
827
+
828
+ end
829
+
830
+ # Flag option. Has no arguments. Can be negated with "no-".
831
+ class BooleanOption < Option
832
+ register_alias :flag, :bool, :boolean, :trueclass, :falseclass
833
+
834
+ def initialize
835
+ super()
836
+ @default = false
837
+ end
838
+
839
+ def flag?
840
+ true;
841
+ end
842
+
843
+ def parse(_paramlist, neg_given)
844
+ return _paramlist[0] if @multi_given
845
+ return(self.name.to_s =~ /^no_/ ? neg_given : !neg_given)
846
+ end
847
+ end
848
+
849
+ # Floating point number option class.
850
+ class FloatOption < Option
851
+ register_alias :float, :double
852
+
853
+ def type_format
854
+ "=<f>";
855
+ end
856
+
857
+ def parse(paramlist, _neg_given)
858
+ paramlist.map do |pg|
859
+ pg.map do |param|
860
+ raise CommandlineError, "option '#{self.name}' needs a floating-point number" unless param.is_a?(Numeric) || param =~ FLOAT_RE
861
+ param.to_f
862
+ end
863
+ end
864
+ end
865
+ end
866
+
867
+ # Integer number option class.
868
+ class IntegerOption < Option
869
+ register_alias :int, :integer, :fixnum
870
+
871
+ def type_format
872
+ "=<i>";
873
+ end
874
+
875
+ def parse(paramlist, _neg_given)
876
+ paramlist.map do |pg|
877
+ pg.map do |param|
878
+ raise CommandlineError, "option '#{self.name}' needs an integer" unless param.is_a?(Numeric) || param =~ /^-?[\d_]+$/
879
+ param.to_i
880
+ end
881
+ end
882
+ end
883
+ end
884
+
885
+ # Option class for handling IO objects and URLs.
886
+ # Note that this will return the file-handle, not the file-name
887
+ # in the case of file-paths given to it.
888
+ class IOOption < Option
889
+ register_alias :io
890
+
891
+ def type_format
892
+ "=<filename/uri>";
893
+ end
894
+
895
+ def parse(paramlist, _neg_given)
896
+ paramlist.map do |pg|
897
+ pg.map do |param|
898
+ if param =~ /^(stdin|-)$/i
899
+ $stdin
900
+ else
901
+ require 'open-uri'
902
+ begin
903
+ open param
904
+ rescue SystemCallError => e
905
+ raise CommandlineError, "file or url for option '#{self.name}' cannot be opened: #{e.message}"
906
+ end
907
+ end
908
+ end
909
+ end
910
+ end
911
+ end
912
+
913
+ # Option class for handling Strings.
914
+ class StringOption < Option
915
+ register_alias :string
916
+
917
+ def type_format
918
+ "=<s>";
919
+ end
920
+
921
+ def parse(paramlist, _neg_given)
922
+ paramlist.map { |pg| pg.map(&:to_s) }
923
+ end
924
+ end
925
+
926
+ # Option for dates. Uses Chronic if it exists.
927
+ class DateOption < Option
928
+ register_alias :date
929
+
930
+ def type_format
931
+ "=<date>";
932
+ end
933
+
934
+ def parse(paramlist, _neg_given)
935
+ paramlist.map do |pg|
936
+ pg.map do |param|
937
+ next param if param.is_a?(Date)
938
+ begin
939
+ begin
940
+ require 'chronic'
941
+ time = Chronic.parse(param)
942
+ rescue LoadError
943
+ # chronic is not available
944
+ end
945
+ time ? Date.new(time.year, time.month, time.day) : Date.parse(param)
946
+ rescue ArgumentError
947
+ raise CommandlineError, "option '#{self.name}' needs a date"
948
+ end
949
+ end
950
+ end
951
+ end
952
+ end
953
+
954
+ ### MULTI_OPT_TYPES :
955
+ ## The set of values that indicate a multiple-parameter option (i.e., that
956
+ ## takes multiple space-separated values on the commandline) when passed as
957
+ ## the +:type+ parameter of #opt.
958
+
959
+ # Option class for handling multiple Integers
960
+ class IntegerArrayOption < IntegerOption
961
+ register_alias :fixnums, :ints, :integers
962
+
963
+ def type_format
964
+ "=<i+>";
965
+ end
966
+
967
+ def multi_arg?
968
+ true;
969
+ end
970
+ end
971
+
972
+ # Option class for handling multiple Floats
973
+ class FloatArrayOption < FloatOption
974
+ register_alias :doubles, :floats
975
+
976
+ def type_format
977
+ "=<f+>";
978
+ end
979
+
980
+ def multi_arg?
981
+ true;
982
+ end
983
+ end
984
+
985
+ # Option class for handling multiple Strings
986
+ class StringArrayOption < StringOption
987
+ register_alias :strings
988
+
989
+ def type_format
990
+ "=<s+>";
991
+ end
992
+
993
+ def multi_arg?
994
+ true;
995
+ end
996
+ end
997
+
998
+ # Option class for handling multiple dates
999
+ class DateArrayOption < DateOption
1000
+ register_alias :dates
1001
+
1002
+ def type_format
1003
+ "=<date+>";
1004
+ end
1005
+
1006
+ def multi_arg?
1007
+ true;
1008
+ end
1009
+ end
1010
+
1011
+ # Option class for handling Files/URLs via 'open'
1012
+ class IOArrayOption < IOOption
1013
+ register_alias :ios
1014
+
1015
+ def type_format
1016
+ "=<filename/uri+>";
1017
+ end
1018
+
1019
+ def multi_arg?
1020
+ true;
1021
+ end
1022
+ end
1023
+
1024
+ ## The easy, syntactic-sugary entry method into Optimist. Creates a Parser,
1025
+ ## passes the block to it, then parses +args+ with it, handling any errors or
1026
+ ## requests for help or version information appropriately (and then exiting).
1027
+ ## Modifies +args+ in place. Returns a hash of option values.
1028
+ ##
1029
+ ## The block passed in should contain zero or more calls to +opt+
1030
+ ## (Parser#opt), zero or more calls to +text+ (Parser#text), and
1031
+ ## probably a call to +version+ (Parser#version).
1032
+ ##
1033
+ ## The returned block contains a value for every option specified with
1034
+ ## +opt+. The value will be the value given on the commandline, or the
1035
+ ## default value if the option was not specified on the commandline. For
1036
+ ## every option specified on the commandline, a key "<option
1037
+ ## name>_given" will also be set in the hash.
1038
+ ##
1039
+ ## Example:
1040
+ ##
1041
+ ## require 'optimist'
1042
+ ## opts = Optimist::options do
1043
+ ## opt :monkey, "Use monkey mode" # a flag --monkey, defaulting to false
1044
+ ## opt :name, "Monkey name", :type => :string # a string --name <s>, defaulting to nil
1045
+ ## opt :num_limbs, "Number of limbs", :default => 4 # an integer --num-limbs <i>, defaulting to 4
1046
+ ## end
1047
+ ##
1048
+ ## ## if called with no arguments
1049
+ ## p opts # => {:monkey=>false, :name=>nil, :num_limbs=>4, :help=>false}
1050
+ ##
1051
+ ## ## if called with --monkey
1052
+ ## p opts # => {:monkey=>true, :name=>nil, :num_limbs=>4, :help=>false, :monkey_given=>true}
1053
+ ##
1054
+ ## See more examples at http://optimist.rubyforge.org.
1055
+ def options(args = ARGV, *a, &b)
1056
+ @last_parser = Parser.new(*a, &b)
1057
+ with_standard_exception_handling(@last_parser) { @last_parser.parse args }
1058
+ end
1059
+
1060
+ ## If Optimist::options doesn't do quite what you want, you can create a Parser
1061
+ ## object and call Parser#parse on it. That method will throw CommandlineError,
1062
+ ## HelpNeeded and VersionNeeded exceptions when necessary; if you want to
1063
+ ## have these handled for you in the standard manner (e.g. show the help
1064
+ ## and then exit upon an HelpNeeded exception), call your code from within
1065
+ ## a block passed to this method.
1066
+ ##
1067
+ ## Note that this method will call System#exit after handling an exception!
1068
+ ##
1069
+ ## Usage example:
1070
+ ##
1071
+ ## require 'optimist'
1072
+ ## p = Optimist::Parser.new do
1073
+ ## opt :monkey, "Use monkey mode" # a flag --monkey, defaulting to false
1074
+ ## opt :goat, "Use goat mode", :default => true # a flag --goat, defaulting to true
1075
+ ## end
1076
+ ##
1077
+ ## opts = Optimist::with_standard_exception_handling p do
1078
+ ## o = p.parse ARGV
1079
+ ## raise Optimist::HelpNeeded if ARGV.empty? # show help screen
1080
+ ## o
1081
+ ## end
1082
+ ##
1083
+ ## Requires passing in the parser object.
1084
+
1085
+ def with_standard_exception_handling(parser)
1086
+ yield
1087
+ rescue CommandlineError => e
1088
+ parser.die(e.message, nil, e.error_code)
1089
+ rescue HelpNeeded
1090
+ parser.educate
1091
+ exit
1092
+ rescue VersionNeeded
1093
+ puts parser.version
1094
+ exit
1095
+ end
1096
+
1097
+ ## Informs the user that their usage of 'arg' was wrong, as detailed by
1098
+ ## 'msg', and dies. Example:
1099
+ ##
1100
+ ## options do
1101
+ ## opt :volume, :default => 0.0
1102
+ ## end
1103
+ ##
1104
+ ## die :volume, "too loud" if opts[:volume] > 10.0
1105
+ ## die :volume, "too soft" if opts[:volume] < 0.1
1106
+ ##
1107
+ ## In the one-argument case, simply print that message, a notice
1108
+ ## about -h, and die. Example:
1109
+ ##
1110
+ ## options do
1111
+ ## opt :whatever # ...
1112
+ ## end
1113
+ ##
1114
+ ## Optimist::die "need at least one filename" if ARGV.empty?
1115
+ ##
1116
+ ## An exit code can be provide if needed
1117
+ ##
1118
+ ## Optimist::die "need at least one filename", -2 if ARGV.empty?
1119
+ def die(arg, msg = nil, error_code = nil)
1120
+ if @last_parser
1121
+ @last_parser.die arg, msg, error_code
1122
+ else
1123
+ raise ArgumentError, "Optimist::die can only be called after Optimist::options"
1124
+ end
1125
+ end
1126
+
1127
+ ## Displays the help message and dies. Example:
1128
+ ##
1129
+ ## options do
1130
+ ## opt :volume, :default => 0.0
1131
+ ## banner <<-EOS
1132
+ ## Usage:
1133
+ ## #$0 [options] <name>
1134
+ ## where [options] are:
1135
+ ## EOS
1136
+ ## end
1137
+ ##
1138
+ ## Optimist::educate if ARGV.empty?
1139
+ def educate
1140
+ if @last_parser
1141
+ @last_parser.educate
1142
+ exit
1143
+ else
1144
+ raise ArgumentError, "Optimist::educate can only be called after Optimist::options"
1145
+ end
1146
+ end
1147
+
1148
+ module_function :options, :die, :educate, :with_standard_exception_handling
1149
+ end # module