rbcli 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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