jets_bb_fork 0.0.4

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 (398) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/bin/commit_docs.sh +26 -0
  3. data/.circleci/config.yml +126 -0
  4. data/.codebuild/README.md +68 -0
  5. data/.codebuild/bin/jets +3 -0
  6. data/.codebuild/buildspec-base.yml +14 -0
  7. data/.codebuild/integration.sh +72 -0
  8. data/.codebuild/jets.postman_collection.json +323 -0
  9. data/.codebuild/scripts/install-docker.sh +12 -0
  10. data/.codebuild/scripts/install-dynamodb-local.sh +22 -0
  11. data/.codebuild/scripts/install-java.sh +22 -0
  12. data/.codebuild/scripts/install-node.sh +4 -0
  13. data/.github/ISSUE_TEMPLATE.md +7 -0
  14. data/.github/ISSUE_TEMPLATE/bug_report.md +84 -0
  15. data/.github/ISSUE_TEMPLATE/documentation.md +27 -0
  16. data/.github/ISSUE_TEMPLATE/feature_request.md +64 -0
  17. data/.github/ISSUE_TEMPLATE/question.md +16 -0
  18. data/.github/PULL_REQUEST_TEMPLATE.md +42 -0
  19. data/.gitignore +24 -0
  20. data/.gitmodules +0 -0
  21. data/.python-version +1 -0
  22. data/.rspec +4 -0
  23. data/.ruby-version +1 -0
  24. data/CHANGELOG.md +734 -0
  25. data/CONDUCT.md +1 -0
  26. data/CONTRIBUTING.md +1 -0
  27. data/Dockerfile +16 -0
  28. data/Dockerfile.base +53 -0
  29. data/Gemfile +14 -0
  30. data/Guardfile +22 -0
  31. data/LICENSE.txt +22 -0
  32. data/Procfile +2 -0
  33. data/README.md +203 -0
  34. data/Rakefile +24 -0
  35. data/backers.md +16 -0
  36. data/bin/release +9 -0
  37. data/buildspec.yml +18 -0
  38. data/exe/jets_bb_fork +14 -0
  39. data/jets.gemspec +68 -0
  40. data/lib/jets.rb +27 -0
  41. data/lib/jets/application.rb +216 -0
  42. data/lib/jets/application/defaults.rb +172 -0
  43. data/lib/jets/autoloaders.rb +97 -0
  44. data/lib/jets/aws_info.rb +113 -0
  45. data/lib/jets/aws_services.rb +65 -0
  46. data/lib/jets/aws_services/global_memoist.rb +57 -0
  47. data/lib/jets/aws_services/s3_bucket.rb +34 -0
  48. data/lib/jets/aws_services/stack_status.rb +59 -0
  49. data/lib/jets/booter.rb +119 -0
  50. data/lib/jets/builders/code_builder.rb +399 -0
  51. data/lib/jets/builders/code_size.rb +57 -0
  52. data/lib/jets/builders/gem_replacer.rb +76 -0
  53. data/lib/jets/builders/handler_generator.rb +186 -0
  54. data/lib/jets/builders/lambda_layer.rb +69 -0
  55. data/lib/jets/builders/md5.rb +60 -0
  56. data/lib/jets/builders/md5_zip.rb +61 -0
  57. data/lib/jets/builders/purger.rb +35 -0
  58. data/lib/jets/builders/rack_packager.rb +51 -0
  59. data/lib/jets/builders/rackup_wrappers/rackup +19 -0
  60. data/lib/jets/builders/rackup_wrappers/rackup.rb +7 -0
  61. data/lib/jets/builders/reconfigure_rails.rb +114 -0
  62. data/lib/jets/builders/reconfigure_rails/config/initializers/jets.rb +16 -0
  63. data/lib/jets/builders/ruby_packager.rb +207 -0
  64. data/lib/jets/builders/shim_vars/app.rb +78 -0
  65. data/lib/jets/builders/shim_vars/base.rb +25 -0
  66. data/lib/jets/builders/shim_vars/shared.rb +37 -0
  67. data/lib/jets/builders/templates/handler.rb +12 -0
  68. data/lib/jets/builders/tidy.rb +107 -0
  69. data/lib/jets/builders/util.rb +31 -0
  70. data/lib/jets/bundle.rb +82 -0
  71. data/lib/jets/camelizer.rb +71 -0
  72. data/lib/jets/cfn/builders/api_deployment_builder.rb +63 -0
  73. data/lib/jets/cfn/builders/api_gateway_builder.rb +157 -0
  74. data/lib/jets/cfn/builders/base_child_builder.rb +75 -0
  75. data/lib/jets/cfn/builders/controller_builder.rb +42 -0
  76. data/lib/jets/cfn/builders/function_builder.rb +14 -0
  77. data/lib/jets/cfn/builders/interface.rb +137 -0
  78. data/lib/jets/cfn/builders/job_builder.rb +14 -0
  79. data/lib/jets/cfn/builders/paged.rb +37 -0
  80. data/lib/jets/cfn/builders/parent_builder.rb +100 -0
  81. data/lib/jets/cfn/builders/rule_builder.rb +24 -0
  82. data/lib/jets/cfn/builders/shared_builder.rb +14 -0
  83. data/lib/jets/cfn/ship.rb +185 -0
  84. data/lib/jets/cfn/status.rb +212 -0
  85. data/lib/jets/cfn/upload.rb +139 -0
  86. data/lib/jets/cli.rb +194 -0
  87. data/lib/jets/commands/base.rb +146 -0
  88. data/lib/jets/commands/build.rb +234 -0
  89. data/lib/jets/commands/call.rb +169 -0
  90. data/lib/jets/commands/call/anonymous_guesser.rb +96 -0
  91. data/lib/jets/commands/call/autoload_guesser.rb +136 -0
  92. data/lib/jets/commands/call/base_guesser.rb +60 -0
  93. data/lib/jets/commands/call/guesser.rb +48 -0
  94. data/lib/jets/commands/clean.rb +19 -0
  95. data/lib/jets/commands/clean/base.rb +24 -0
  96. data/lib/jets/commands/clean/build.rb +13 -0
  97. data/lib/jets/commands/clean/log.rb +107 -0
  98. data/lib/jets/commands/console.rb +12 -0
  99. data/lib/jets/commands/db.rb +13 -0
  100. data/lib/jets/commands/db/environment-task.rake +3 -0
  101. data/lib/jets/commands/db/tasks.rb +44 -0
  102. data/lib/jets/commands/dbconsole.rb +131 -0
  103. data/lib/jets/commands/delete.rb +143 -0
  104. data/lib/jets/commands/deploy.rb +141 -0
  105. data/lib/jets/commands/dynamodb.rb +19 -0
  106. data/lib/jets/commands/dynamodb/migrate.rb +9 -0
  107. data/lib/jets/commands/dynamodb/migrator.rb +36 -0
  108. data/lib/jets/commands/gems.rb +21 -0
  109. data/lib/jets/commands/help.rb +9 -0
  110. data/lib/jets/commands/help/build.md +6 -0
  111. data/lib/jets/commands/help/call.md +61 -0
  112. data/lib/jets/commands/help/clean/build.md +5 -0
  113. data/lib/jets/commands/help/clean/log.md +5 -0
  114. data/lib/jets/commands/help/console.md +18 -0
  115. data/lib/jets/commands/help/db/generate.md +8 -0
  116. data/lib/jets/commands/help/dbconsole.md +9 -0
  117. data/lib/jets/commands/help/delete.md +22 -0
  118. data/lib/jets/commands/help/deploy.md +32 -0
  119. data/lib/jets/commands/help/destroy.md +16 -0
  120. data/lib/jets/commands/help/dynamodb/generate.md +52 -0
  121. data/lib/jets/commands/help/dynamodb/migrate.md +4 -0
  122. data/lib/jets/commands/help/gems/check.md +8 -0
  123. data/lib/jets/commands/help/generate.md +22 -0
  124. data/lib/jets/commands/help/import/rack.md +13 -0
  125. data/lib/jets/commands/help/import/rails.md +11 -0
  126. data/lib/jets/commands/help/new.md +42 -0
  127. data/lib/jets/commands/help/routes.md +16 -0
  128. data/lib/jets/commands/help/runner.md +17 -0
  129. data/lib/jets/commands/help/server.md +15 -0
  130. data/lib/jets/commands/help/status.md +14 -0
  131. data/lib/jets/commands/help/upgrade.md +5 -0
  132. data/lib/jets/commands/help/url.md +6 -0
  133. data/lib/jets/commands/import.rb +12 -0
  134. data/lib/jets/commands/import/base.rb +49 -0
  135. data/lib/jets/commands/import/cheatsheet.rb +35 -0
  136. data/lib/jets/commands/import/rack.rb +16 -0
  137. data/lib/jets/commands/import/rails.rb +74 -0
  138. data/lib/jets/commands/import/sequence.rb +90 -0
  139. data/lib/jets/commands/import/templates/config/database.yml +26 -0
  140. data/lib/jets/commands/import/templates/submodules-cheatsheet.md +89 -0
  141. data/lib/jets/commands/main.rb +157 -0
  142. data/lib/jets/commands/markdown/creator.rb +58 -0
  143. data/lib/jets/commands/markdown/index.rb +27 -0
  144. data/lib/jets/commands/markdown/page.rb +125 -0
  145. data/lib/jets/commands/markdown/shell.rb +11 -0
  146. data/lib/jets/commands/new.rb +157 -0
  147. data/lib/jets/commands/rake_command.rb +61 -0
  148. data/lib/jets/commands/rake_tasks.rb +46 -0
  149. data/lib/jets/commands/runner.rb +16 -0
  150. data/lib/jets/commands/sequence.rb +99 -0
  151. data/lib/jets/commands/stack_info.rb +30 -0
  152. data/lib/jets/commands/templates/skeleton/.gitignore +12 -0
  153. data/lib/jets/commands/templates/skeleton/.jetskeep +1 -0
  154. data/lib/jets/commands/templates/skeleton/.rspec +3 -0
  155. data/lib/jets/commands/templates/skeleton/Gemfile.tt +38 -0
  156. data/lib/jets/commands/templates/skeleton/Procfile +7 -0
  157. data/lib/jets/commands/templates/skeleton/README.md +11 -0
  158. data/lib/jets/commands/templates/skeleton/Rakefile +2 -0
  159. data/lib/jets/commands/templates/skeleton/app/controllers/application_controller.rb +2 -0
  160. data/lib/jets/commands/templates/skeleton/app/helpers/application_helper.rb +2 -0
  161. data/lib/jets/commands/templates/skeleton/app/jobs/application_job.rb +4 -0
  162. data/lib/jets/commands/templates/skeleton/app/models/application_item.rb +2 -0
  163. data/lib/jets/commands/templates/skeleton/app/models/application_record.rb +3 -0
  164. data/lib/jets/commands/templates/skeleton/app/views/layouts/application.html.erb.tt +25 -0
  165. data/lib/jets/commands/templates/skeleton/config.ru +5 -0
  166. data/lib/jets/commands/templates/skeleton/config/application.rb.tt +67 -0
  167. data/lib/jets/commands/templates/skeleton/config/database.yml.tt +26 -0
  168. data/lib/jets/commands/templates/skeleton/config/dynamodb.yml +22 -0
  169. data/lib/jets/commands/templates/skeleton/config/environments/development.rb +7 -0
  170. data/lib/jets/commands/templates/skeleton/config/environments/production.rb +9 -0
  171. data/lib/jets/commands/templates/skeleton/config/environments/test.rb +7 -0
  172. data/lib/jets/commands/templates/skeleton/config/routes.rb +9 -0
  173. data/lib/jets/commands/templates/skeleton/db/.gitkeep +0 -0
  174. data/lib/jets/commands/templates/skeleton/public/404.html +67 -0
  175. data/lib/jets/commands/templates/skeleton/public/422.html +67 -0
  176. data/lib/jets/commands/templates/skeleton/public/500.html +66 -0
  177. data/lib/jets/commands/templates/skeleton/public/favicon.ico +0 -0
  178. data/lib/jets/commands/templates/skeleton/public/index.html.tt +91 -0
  179. data/lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb +15 -0
  180. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-index.json +51 -0
  181. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-show.json +53 -0
  182. data/lib/jets/commands/templates/skeleton/spec/spec_helper.rb.tt +30 -0
  183. data/lib/jets/commands/templates/webpacker/app/javascript/packs/application.js.tt +14 -0
  184. data/lib/jets/commands/templates/webpacker/app/javascript/packs/theme.scss.tt +24 -0
  185. data/lib/jets/commands/templates/webpacker/app/javascript/src/jets/crud.js +87 -0
  186. data/lib/jets/commands/upgrade.rb +145 -0
  187. data/lib/jets/commands/upgrade/templates/bin/webpack +19 -0
  188. data/lib/jets/commands/upgrade/templates/bin/webpack-dev-server +19 -0
  189. data/lib/jets/commands/url.rb +68 -0
  190. data/lib/jets/commands/webpacker_template.rb +18 -0
  191. data/lib/jets/controller.rb +3 -0
  192. data/lib/jets/controller/base.rb +108 -0
  193. data/lib/jets/controller/callbacks.rb +68 -0
  194. data/lib/jets/controller/cookies.rb +38 -0
  195. data/lib/jets/controller/cookies/jar.rb +269 -0
  196. data/lib/jets/controller/layout.rb +17 -0
  197. data/lib/jets/controller/middleware/cors.rb +60 -0
  198. data/lib/jets/controller/middleware/local.rb +116 -0
  199. data/lib/jets/controller/middleware/local/api_gateway.rb +93 -0
  200. data/lib/jets/controller/middleware/local/mimic_aws_call.rb +38 -0
  201. data/lib/jets/controller/middleware/local/route_matcher.rb +106 -0
  202. data/lib/jets/controller/middleware/main.rb +46 -0
  203. data/lib/jets/controller/middleware/reloader.rb +15 -0
  204. data/lib/jets/controller/middleware/webpacker_setup.rb +6 -0
  205. data/lib/jets/controller/params.rb +87 -0
  206. data/lib/jets/controller/rack/adapter.rb +88 -0
  207. data/lib/jets/controller/rack/env.rb +105 -0
  208. data/lib/jets/controller/redirection.rb +55 -0
  209. data/lib/jets/controller/rendering.rb +79 -0
  210. data/lib/jets/controller/rendering/rack_renderer.rb +250 -0
  211. data/lib/jets/controller/request.rb +29 -0
  212. data/lib/jets/controller/response.rb +61 -0
  213. data/lib/jets/controller/stage.rb +33 -0
  214. data/lib/jets/core.rb +149 -0
  215. data/lib/jets/core_ext/kernel.rb +13 -0
  216. data/lib/jets/db.rb +15 -0
  217. data/lib/jets/dotenv.rb +48 -0
  218. data/lib/jets/dotenv/ssm.rb +48 -0
  219. data/lib/jets/erb.rb +51 -0
  220. data/lib/jets/generator.rb +48 -0
  221. data/lib/jets/generator/templates/erb/controller/view.html.erb +2 -0
  222. data/lib/jets/generator/templates/erb/scaffold/_form.html.erb +39 -0
  223. data/lib/jets/generator/templates/erb/scaffold/edit.html.erb +6 -0
  224. data/lib/jets/generator/templates/erb/scaffold/index.html.erb +29 -0
  225. data/lib/jets/generator/templates/erb/scaffold/new.html.erb +5 -0
  226. data/lib/jets/generator/templates/erb/scaffold/show.html.erb +9 -0
  227. data/lib/jets/generator/templates/rails/assets/javascript.js +2 -0
  228. data/lib/jets/generator/templates/rails/assets/stylesheet.css +4 -0
  229. data/lib/jets/generator/templates/rails/controller/controller.rb +13 -0
  230. data/lib/jets/generator/templates/rails/helper/helper.rb +4 -0
  231. data/lib/jets/generator/templates/rails/scaffold/scaffold.css +80 -0
  232. data/lib/jets/generator/templates/rails/scaffold_controller/api_controller.rb +62 -0
  233. data/lib/jets/generator/templates/rails/scaffold_controller/controller.rb +79 -0
  234. data/lib/jets/inflections.rb +32 -0
  235. data/lib/jets/internal/app/controllers/jets/mailers_controller.rb +97 -0
  236. data/lib/jets/internal/app/controllers/jets/public_controller.rb +31 -0
  237. data/lib/jets/internal/app/controllers/jets/rack_controller.rb +25 -0
  238. data/lib/jets/internal/app/functions/jets/base_path.rb +157 -0
  239. data/lib/jets/internal/app/helpers/jets/mailers_helper.rb +9 -0
  240. data/lib/jets/internal/app/jobs/jets/preheat_job.rb +70 -0
  241. data/lib/jets/internal/app/shared/functions/jets/s3_bucket_config.rb +43 -0
  242. data/lib/jets/internal/app/views/jets/mailers/email.html.erb +145 -0
  243. data/lib/jets/internal/app/views/jets/mailers/index.html.erb +8 -0
  244. data/lib/jets/internal/app/views/jets/mailers/mailer.html.erb +6 -0
  245. data/lib/jets/internal/turbines/jets/mailer.rb +51 -0
  246. data/lib/jets/job/base.rb +39 -0
  247. data/lib/jets/job/dsl.rb +40 -0
  248. data/lib/jets/job/dsl/dynamodb_event.rb +65 -0
  249. data/lib/jets/job/dsl/event_source_mapping.rb +11 -0
  250. data/lib/jets/job/dsl/iot_event.rb +24 -0
  251. data/lib/jets/job/dsl/kinesis_event.rb +46 -0
  252. data/lib/jets/job/dsl/log_event.rb +15 -0
  253. data/lib/jets/job/dsl/rule_event.rb +75 -0
  254. data/lib/jets/job/dsl/s3_event.rb +36 -0
  255. data/lib/jets/job/dsl/sns_event.rb +54 -0
  256. data/lib/jets/job/dsl/sqs_event.rb +96 -0
  257. data/lib/jets/job/helpers/kinesis_event_helper.rb +13 -0
  258. data/lib/jets/job/helpers/log_event_helper.rb +17 -0
  259. data/lib/jets/job/helpers/s3_event_helper.rb +13 -0
  260. data/lib/jets/klass.rb +109 -0
  261. data/lib/jets/lambda/dsl.rb +419 -0
  262. data/lib/jets/lambda/function.rb +29 -0
  263. data/lib/jets/lambda/function_constructor.rb +55 -0
  264. data/lib/jets/lambda/functions.rb +34 -0
  265. data/lib/jets/lambda/task.rb +111 -0
  266. data/lib/jets/logger.rb +21 -0
  267. data/lib/jets/mega/hash_converter.rb +25 -0
  268. data/lib/jets/mega/request.rb +139 -0
  269. data/lib/jets/mega/request/source.rb +21 -0
  270. data/lib/jets/middleware.rb +33 -0
  271. data/lib/jets/middleware/configurator.rb +84 -0
  272. data/lib/jets/middleware/default_stack.rb +51 -0
  273. data/lib/jets/middleware/layer.rb +34 -0
  274. data/lib/jets/middleware/stack.rb +77 -0
  275. data/lib/jets/naming.rb +49 -0
  276. data/lib/jets/overrides/lambda.rb +1 -0
  277. data/lib/jets/overrides/lambda/marshaller.rb +31 -0
  278. data/lib/jets/overrides/rails.rb +4 -0
  279. data/lib/jets/overrides/rails/asset_tag_helper.rb +114 -0
  280. data/lib/jets/overrides/rails/common_methods.rb +13 -0
  281. data/lib/jets/overrides/rails/rendering_helper.rb +26 -0
  282. data/lib/jets/overrides/rails/url_helper.rb +25 -0
  283. data/lib/jets/poly_fun.rb +73 -0
  284. data/lib/jets/poly_fun/base_executor.rb +125 -0
  285. data/lib/jets/poly_fun/lambda_executor.rb +16 -0
  286. data/lib/jets/poly_fun/node_error.rb +8 -0
  287. data/lib/jets/poly_fun/node_executor.rb +54 -0
  288. data/lib/jets/poly_fun/python_error.rb +8 -0
  289. data/lib/jets/poly_fun/python_executor.rb +23 -0
  290. data/lib/jets/preheat.rb +117 -0
  291. data/lib/jets/processors/deducer.rb +65 -0
  292. data/lib/jets/processors/main_processor.rb +61 -0
  293. data/lib/jets/rack_server.rb +86 -0
  294. data/lib/jets/rdoc.rb +30 -0
  295. data/lib/jets/resource.rb +71 -0
  296. data/lib/jets/resource/api_gateway/base_path/function.rb +42 -0
  297. data/lib/jets/resource/api_gateway/base_path/mapping.rb +44 -0
  298. data/lib/jets/resource/api_gateway/base_path/role.rb +76 -0
  299. data/lib/jets/resource/api_gateway/cors.rb +61 -0
  300. data/lib/jets/resource/api_gateway/deployment.rb +78 -0
  301. data/lib/jets/resource/api_gateway/domain_name.rb +59 -0
  302. data/lib/jets/resource/api_gateway/method.rb +98 -0
  303. data/lib/jets/resource/api_gateway/resource.rb +101 -0
  304. data/lib/jets/resource/api_gateway/rest_api.rb +56 -0
  305. data/lib/jets/resource/api_gateway/rest_api/change_detection.rb +42 -0
  306. data/lib/jets/resource/api_gateway/rest_api/logical_id.rb +63 -0
  307. data/lib/jets/resource/api_gateway/rest_api/routes.rb +7 -0
  308. data/lib/jets/resource/api_gateway/rest_api/routes/change.rb +8 -0
  309. data/lib/jets/resource/api_gateway/rest_api/routes/change/base.rb +130 -0
  310. data/lib/jets/resource/api_gateway/rest_api/routes/change/to.rb +29 -0
  311. data/lib/jets/resource/api_gateway/rest_api/routes/change/variable.rb +39 -0
  312. data/lib/jets/resource/api_gateway/rest_api/routes/collision.rb +121 -0
  313. data/lib/jets/resource/api_gateway/rest_api/routes/collision/variable_exception.rb +7 -0
  314. data/lib/jets/resource/associated.rb +37 -0
  315. data/lib/jets/resource/base.rb +28 -0
  316. data/lib/jets/resource/child_stack/api_deployment.rb +56 -0
  317. data/lib/jets/resource/child_stack/api_gateway.rb +53 -0
  318. data/lib/jets/resource/child_stack/app_class.rb +107 -0
  319. data/lib/jets/resource/child_stack/base.rb +24 -0
  320. data/lib/jets/resource/child_stack/shared.rb +92 -0
  321. data/lib/jets/resource/config/config_rule.rb +74 -0
  322. data/lib/jets/resource/config/managed_rule.rb +15 -0
  323. data/lib/jets/resource/events/rule.rb +31 -0
  324. data/lib/jets/resource/iam/application_role.rb +27 -0
  325. data/lib/jets/resource/iam/base_role_definition.rb +47 -0
  326. data/lib/jets/resource/iam/class_role.rb +74 -0
  327. data/lib/jets/resource/iam/function_role.rb +54 -0
  328. data/lib/jets/resource/iam/managed_policy.rb +22 -0
  329. data/lib/jets/resource/iam/policy_document.rb +41 -0
  330. data/lib/jets/resource/iot/topic_rule.rb +34 -0
  331. data/lib/jets/resource/lambda/event_source_mapping.rb +31 -0
  332. data/lib/jets/resource/lambda/function.rb +214 -0
  333. data/lib/jets/resource/lambda/function/environment.rb +62 -0
  334. data/lib/jets/resource/lambda/gem_layer.rb +17 -0
  335. data/lib/jets/resource/lambda/layer_version.rb +44 -0
  336. data/lib/jets/resource/logs/subscription_filter.rb +31 -0
  337. data/lib/jets/resource/permission.rb +45 -0
  338. data/lib/jets/resource/replacer.rb +85 -0
  339. data/lib/jets/resource/route53/record_set.rb +70 -0
  340. data/lib/jets/resource/s3/bucket.rb +24 -0
  341. data/lib/jets/resource/sns/subscription.rb +29 -0
  342. data/lib/jets/resource/sns/topic.rb +35 -0
  343. data/lib/jets/resource/sns/topic_policy.rb +40 -0
  344. data/lib/jets/resource/sqs/queue.rb +21 -0
  345. data/lib/jets/resource/standardizer.rb +42 -0
  346. data/lib/jets/route.rb +166 -0
  347. data/lib/jets/router.rb +177 -0
  348. data/lib/jets/router/scope.rb +30 -0
  349. data/lib/jets/rule/base.rb +19 -0
  350. data/lib/jets/rule/dsl.rb +110 -0
  351. data/lib/jets/spec_helpers.rb +54 -0
  352. data/lib/jets/spec_helpers/params.rb +10 -0
  353. data/lib/jets/spec_helpers/request.rb +78 -0
  354. data/lib/jets/spec_helpers/response.rb +5 -0
  355. data/lib/jets/stack.rb +88 -0
  356. data/lib/jets/stack/builder.rb +43 -0
  357. data/lib/jets/stack/definition.rb +50 -0
  358. data/lib/jets/stack/depends.rb +34 -0
  359. data/lib/jets/stack/depends/item.rb +9 -0
  360. data/lib/jets/stack/function.rb +69 -0
  361. data/lib/jets/stack/main.rb +4 -0
  362. data/lib/jets/stack/main/dsl.rb +28 -0
  363. data/lib/jets/stack/main/dsl/base.rb +49 -0
  364. data/lib/jets/stack/main/dsl/cloudwatch.rb +19 -0
  365. data/lib/jets/stack/main/dsl/iam.rb +8 -0
  366. data/lib/jets/stack/main/dsl/lambda.rb +83 -0
  367. data/lib/jets/stack/main/dsl/s3.rb +12 -0
  368. data/lib/jets/stack/main/dsl/sns.rb +16 -0
  369. data/lib/jets/stack/main/dsl/sqs.rb +10 -0
  370. data/lib/jets/stack/output.rb +35 -0
  371. data/lib/jets/stack/output/dsl.rb +19 -0
  372. data/lib/jets/stack/output/lookup.rb +36 -0
  373. data/lib/jets/stack/parameter.rb +37 -0
  374. data/lib/jets/stack/parameter/dsl.rb +42 -0
  375. data/lib/jets/stack/resource.rb +31 -0
  376. data/lib/jets/stack/resource/dsl.rb +19 -0
  377. data/lib/jets/stack/s3_event.rb +87 -0
  378. data/lib/jets/tmp_loader.rb +52 -0
  379. data/lib/jets/turbine.rb +41 -0
  380. data/lib/jets/turbo.rb +55 -0
  381. data/lib/jets/turbo/database_yaml.rb +41 -0
  382. data/lib/jets/turbo/project/.gitignore +12 -0
  383. data/lib/jets/turbo/project/.jetskeep +1 -0
  384. data/lib/jets/turbo/project/Gemfile +16 -0
  385. data/lib/jets/turbo/project/Rakefile +2 -0
  386. data/lib/jets/turbo/project/app/controllers/application_controller.rb +2 -0
  387. data/lib/jets/turbo/project/app/helpers/application_helper.rb +2 -0
  388. data/lib/jets/turbo/project/app/jobs/application_job.rb +4 -0
  389. data/lib/jets/turbo/project/config.ru +5 -0
  390. data/lib/jets/turbo/project/config/application.rb +4 -0
  391. data/lib/jets/turbo/project/config/routes.rb +4 -0
  392. data/lib/jets/turbo/rails.rb +127 -0
  393. data/lib/jets/turbo/templates/config/database.yml +26 -0
  394. data/lib/jets/util.rb +38 -0
  395. data/lib/jets/version.rb +3 -0
  396. data/readme/prerelease.md +6 -0
  397. data/readme/testing.md +60 -0
  398. metadata +1004 -0
@@ -0,0 +1,96 @@
1
+ # ## Event Source Mapping
2
+ #
3
+ # Underneath the hood, the `sqs_event` method sets up a [Lambda::EventSourceMapping](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html). So:
4
+ #
5
+ # ```ruby
6
+ # class HardJob
7
+ # class_timeout 30 # must be less than or equal to the SQS queue default timeout
8
+ #
9
+ # sqs_event "hello-queue"
10
+ # def dig
11
+ # puts "dig event #{JSON.dump(event)}"
12
+ # end
13
+ # end
14
+ # ```
15
+ #
16
+ # Cloud also be written with something like this:
17
+ #
18
+ # ```ruby
19
+ # class HardJob
20
+ # class_timeout 30 # must be less than or equal to the SQS queue default timeout
21
+ #
22
+ # event_source_mapping(
23
+ # event_source_arn: "arn:aws:sqs:us-west-2:112233445566:hello-queue",
24
+ # )
25
+ # iam_policy(
26
+ # action: ["sqs:ReceiveMessage",
27
+ # "sqs:DeleteMessage",
28
+ # "sqs:GetQueueAttributes"],
29
+ # effect: "Allow",
30
+ # resource: "arn:aws:sqs:us-west-2:112233445566:hello-queue",
31
+ # )
32
+ # def dig
33
+ # puts "dig event #{JSON.dump(event)}"
34
+ # end
35
+ # end
36
+ # ```
37
+ #
38
+ module Jets::Job::Dsl
39
+ module SqsEvent
40
+ def sqs_event(queue_name, options={})
41
+ if queue_name.to_s =~ /generate/
42
+ queue_arn = "!GetAtt {namespace}SqsQueue.Arn"
43
+ default_iam_policy = default_sqs_iam_policy('*') # Dont have access to full ARN on initial creation
44
+ declare_sqs_queue(options.delete(:queue_properties)) # delete to avoid using them for event_source_mapping
45
+ elsif queue_name.include?('!Ref') # reference shared resource
46
+ queue_arn = queue_name
47
+ default_iam_policy = default_sqs_iam_policy('*') # Dont have access to full ARN on initial creation
48
+ else # existing queue: short name or full arn
49
+ queue_arn = full_sqs_queue_arn(queue_name)
50
+ default_iam_policy = default_sqs_iam_policy(queue_arn)
51
+ end
52
+
53
+ # Create iam policy allows access to queue
54
+ # Allow disabling in case use wants to add permission application-wide and not have extra IAM policy
55
+ iam_policy_props = options.delete(:iam_policy) || @iam_policy || default_iam_policy
56
+ iam_policy(iam_policy_props) unless iam_policy_props == :disable
57
+
58
+ props = options # by this time options only has EventSourceMapping properties
59
+ default = {
60
+ event_source_arn: queue_arn
61
+ }
62
+ props = default.merge(props)
63
+
64
+ event_source_mapping(props)
65
+ end
66
+
67
+ def declare_sqs_queue(props)
68
+ props ||= {} # since options.delete(:queue_properties) can be nil
69
+ r = Jets::Resource::Sqs::Queue.new(props)
70
+ with_fresh_properties do
71
+ resource(r.definition) # add associated resource immediately
72
+ end
73
+ end
74
+
75
+ # Expands simple queue name to full arn. Example:
76
+ #
77
+ # hello-queue
78
+ # To:
79
+ # arn:aws:sqs:us-west-2:112233445566:hello-queue
80
+ def full_sqs_queue_arn(queue_name)
81
+ return queue_name if queue_name.include?("arn:aws:sqs")
82
+
83
+ "arn:aws:sqs:#{Jets.aws.region}:#{Jets.aws.account}:#{queue_name}"
84
+ end
85
+
86
+ def default_sqs_iam_policy(queue_name_arn='*')
87
+ {
88
+ action: ["sqs:ReceiveMessage",
89
+ "sqs:DeleteMessage",
90
+ "sqs:GetQueueAttributes"],
91
+ effect: "Allow",
92
+ resource: queue_name_arn,
93
+ }
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,13 @@
1
+ require 'base64'
2
+
3
+ module Jets::Job::Helpers
4
+ module KinesisEventHelper
5
+ def kinesis_data
6
+ records = event["Records"]
7
+ records.map do |record|
8
+ encoded = record["kinesis"]["data"]
9
+ Base64.decode64(encoded) # data
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ require 'base64'
2
+ require 'json'
3
+ require 'stringio'
4
+ require 'zlib'
5
+
6
+ module Jets::Job::Helpers
7
+ module LogEventHelper
8
+ def log_event
9
+ encoded = event["awslogs"]["data"]
10
+ compressed_string = Base64.decode64(encoded)
11
+ gz = Zlib::GzipReader.new(StringIO.new(compressed_string))
12
+ uncompressed_string = gz.read
13
+ data = JSON.load(uncompressed_string)
14
+ ActiveSupport::HashWithIndifferentAccess.new(data)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ module Jets::Job::Helpers
2
+ module S3EventHelper
3
+ def s3_event
4
+ message = event["Records"][0]["Sns"]["Message"]
5
+ h = JSON.load(message)
6
+ ActiveSupport::HashWithIndifferentAccess.new(h)
7
+ end
8
+
9
+ def s3_object
10
+ s3_event["Records"][0]["s3"]["object"]
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,109 @@
1
+ # Loading a class can usually be loaded via .constantize.
2
+ # But app/functions files are anonymous ruby classes created with
3
+ # Class.new. Anonymous classes cannot be loaded via .constantize and
4
+ # go through standard autoloading.
5
+ #
6
+ # Jets::Klass provides a way to load app classes in app/controllers, app/jobs,
7
+ # app/functions in a consistent way without having to worry about the anonymous
8
+ # class loading quirk. Classes that are not anonymously defined like controllers
9
+ # and jobs are loaded via autoloading with .constantize. Anonymously defined
10
+ # classes like functions are loaded via Object.const_set.
11
+ #
12
+ # Examples:
13
+ #
14
+ # Jets::Klass.from_path("app/controllers/posts_controller.rb")
15
+ # Jets::Klass.from_path("app/jobs/hard_job.rb")
16
+ # Jets::Klass.from_path("app/functions/hello.rb")
17
+ # Jets::Klass.from_path("app/functions/hello_function.rb")
18
+ # Jets::Klass.from_path("app/shared/functions/whatever.rb")
19
+ #
20
+ # Jets::Klass.from_task(task)
21
+ #
22
+ # The from_task method takes a Jets::Lambda::Task as an argument and is useful
23
+ # for the CloudFormation child stack generation there the registered task info
24
+ # is available but the path info is now.
25
+ class Jets::Klass
26
+ class << self
27
+ # from_path allows us to load any app classes in consistent way for
28
+ # app/controllers, app/jobs, and app/functions.
29
+ def from_path(path)
30
+ class_name = class_name(path)
31
+ if path.include?("/functions/") # simple function
32
+ class_name = load_anonymous_class(class_name, path)
33
+ class_name.constantize # removed :: for anonymous classes
34
+ else
35
+ class_name.constantize # autoload
36
+ end
37
+ end
38
+
39
+ # app/controllers/posts_controller.rb => PostsController
40
+ def class_name(path)
41
+ if path.include?("/shared/")
42
+ path.sub(%r{.*app/shared/(.*?)/},'').sub(/\.rb$/,'').camelize
43
+ else
44
+ path.sub(%r{.*app/(.*?)/},'').sub(/\.rb$/,'').camelize
45
+ end
46
+ end
47
+
48
+ def from_task(task)
49
+ class_name = task.class_name
50
+ filename = class_name.underscore
51
+
52
+ # Examples of filename: posts_controller, hard_job, security_rule,
53
+ # hello_function, hello
54
+ valid_types = %w[controller job rule]
55
+ type = filename.split('_').last
56
+ type = "function" unless valid_types.include?(type)
57
+
58
+ path = "app/#{type.pluralize}/#{filename}.rb"
59
+ from_path(path)
60
+ end
61
+
62
+ @@loaded_anonymous_classes = []
63
+ def load_anonymous_class(class_name, path)
64
+ parent_mod = modularize(class_name)
65
+
66
+ constructor = Jets::Lambda::FunctionConstructor.new(path)
67
+ # Dont load anonyomous class more than once to avoid these warnings:
68
+ # warning: already initialized constant Hello
69
+ # warning: previous definition of Hello was here
70
+ unless @@loaded_anonymous_classes.include?(class_name)
71
+ # use class_name as the variable name for prettier class name.
72
+ leaf_class_name = class_name.split('::').last
73
+ parent_mod.const_set(leaf_class_name, constructor.build)
74
+ @@loaded_anonymous_classes << class_name
75
+ end
76
+
77
+ class_name
78
+ end
79
+
80
+ # Ensures the parent namespace modules are defined. Example:
81
+ #
82
+ # modularize("Foo::Bar::Test")
83
+ # => Foo::Bar # is a now defined as a module if it wasnt before
84
+ #
85
+ # Also returns the parent module, so we can use it to do a const_set if needed. IE:
86
+ #
87
+ # parent_mod = modularize("Foo::Bar::Test")
88
+ # parent_mod.const_set("Test")
89
+ def modularize(class_name)
90
+ leaves = []
91
+ mods = class_name.split('::')[0..-2] # drop the last word
92
+ # puts "mods: #{mods}"
93
+ return Object if mods.empty?
94
+
95
+ leaves = []
96
+ mods.each do |leaf_mod|
97
+ leaves += [leaf_mod]
98
+ namespace = leaves.join('::')
99
+ previous_namespace = leaves[0..-2].join('::')
100
+ previous_namespace = "Object" if previous_namespace.empty?
101
+ previous_namespace = previous_namespace.constantize
102
+ previous_namespace.const_set(leaf_mod, Module.new) unless Object.const_defined?(namespace)
103
+ end
104
+
105
+ mods.join('::').constantize
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1,419 @@
1
+ # Other dsl that rely on this must implement
2
+ #
3
+ # default_associated_resource_definition
4
+ #
5
+ module Jets::Lambda::Dsl
6
+ extend ActiveSupport::Concern
7
+
8
+ def lambda_functions
9
+ self.class.lambda_functions
10
+ end
11
+
12
+ included do
13
+ class << self
14
+ extend Memoist
15
+
16
+ def class_properties(options=nil)
17
+ if options
18
+ @class_properties ||= {}
19
+ @class_properties.deep_merge!(options)
20
+ else
21
+ @class_properties || {}
22
+ end
23
+ end
24
+ alias_method :class_props, :class_properties
25
+
26
+ def properties(options={})
27
+ @properties ||= {}
28
+ @properties.deep_merge!(options)
29
+ end
30
+ alias_method :props, :properties
31
+
32
+ def class_environment(hash)
33
+ environment = standardize_env(hash)
34
+ class_properties(environment: environment)
35
+ end
36
+ alias_method :class_env, :class_environment
37
+
38
+ def environment(hash)
39
+ environment = standardize_env(hash)
40
+ properties(environment: environment)
41
+ end
42
+ alias_method :env, :environment
43
+
44
+ # Allows user to pass in hash with or without the :variables key.
45
+ def standardize_env(hash)
46
+ return hash if hash.key?(:variables)
47
+
48
+ environment = {}
49
+ environment[:variables] ||= {}
50
+ environment[:variables].merge!(hash)
51
+ environment
52
+ end
53
+
54
+ # Convenience method that set properties. List based on https://amzn.to/2oSph1P
55
+ # Not all properites are included because some properties are not meant to be set
56
+ # directly. For example, function_name is a calculated setting by Jets.
57
+ PROPERTIES = %W[
58
+ dead_letter_config
59
+ description
60
+ handler
61
+ kms_key_arn
62
+ memory_size
63
+ reserved_concurrent_executions
64
+ role
65
+ runtime
66
+ timeout
67
+ tracing_config
68
+ vpc_config
69
+ tags
70
+ ]
71
+ PROPERTIES.each do |property|
72
+ # Example:
73
+ # def timeout(value)
74
+ # properties(timeout: value)
75
+ # end
76
+ #
77
+ # def class_timeout(value)
78
+ # class_properties(timeout: value)
79
+ # end
80
+ class_eval <<~CODE
81
+ def #{property}(value)
82
+ properties(#{property}: value)
83
+ end
84
+
85
+ def class_#{property}(value)
86
+ class_properties(#{property}: value)
87
+ end
88
+ CODE
89
+ end
90
+ # More convenience aliases
91
+ alias_method :memory, :memory_size
92
+ alias_method :class_memory, :class_memory_size
93
+ alias_method :desc, :description
94
+ alias_method :class_desc, :class_description
95
+
96
+ # definitions: one or more definitions
97
+ def iam_policy(*definitions)
98
+ if definitions.empty?
99
+ @iam_policy
100
+ else
101
+ @iam_policy = definitions.flatten
102
+ end
103
+ end
104
+
105
+ # definitions: one or more definitions
106
+ def class_iam_policy(*definitions)
107
+ if definitions.empty?
108
+ @class_iam_policy
109
+ else
110
+ @class_iam_policy = definitions.flatten
111
+ end
112
+ end
113
+
114
+ # definitions: one or more definitions
115
+ def managed_iam_policy(*definitions)
116
+ if definitions.empty?
117
+ @managed_iam_policy
118
+ else
119
+ @managed_iam_policy = definitions.flatten
120
+ end
121
+ end
122
+
123
+ # definitions: one or more definitions
124
+ def class_managed_iam_policy(*definitions)
125
+ if definitions.empty?
126
+ @class_managed_iam_policy
127
+ else
128
+ @class_managed_iam_policy = definitions.flatten
129
+ end
130
+ end
131
+
132
+ def build_class_iam?
133
+ !!(class_iam_policy || class_managed_iam_policy)
134
+ end
135
+
136
+ #############################
137
+ # Main method that registers resources associated with the Lambda function.
138
+ # All resources methods lead here.
139
+ def associated_resources(*definitions)
140
+ if definitions == [nil] # when associated_resources called with no arguments
141
+ @associated_resources || []
142
+ else
143
+ @associated_resources ||= []
144
+ associated_resource = Jets::Resource::Associated.new(definitions)
145
+ associated_resource.multiple_resources = @multiple_resources
146
+ @associated_resources << associated_resource
147
+ @associated_resources.flatten!
148
+ end
149
+ end
150
+ # User-friendly short resource method. Users will use this.
151
+ alias_method :resource, :associated_resources
152
+
153
+ # Using this odd way of setting these properties so we can keep the
154
+ # resource(*definitions) signature simple. Using keyword arguments at the end
155
+ # interfere with being able to pass in any keys for the properties hash at the end.
156
+ #
157
+ # TODO: If there's a cleaner way of doing this, let me know.
158
+ def with_fresh_properties(fresh_properties: true, multiple_resources: true)
159
+ @associated_properties = nil if fresh_properties # dont use any current associated_properties
160
+ @multiple_resources = multiple_resources
161
+
162
+ yield
163
+
164
+ @multiple_resources = false
165
+ @associated_properties = nil if fresh_properties # reset for next definition, since we're defining eagerly
166
+ end
167
+
168
+ # Properties belonging to the associated resource
169
+ def associated_properties(options={})
170
+ @associated_properties ||= {}
171
+ @associated_properties.deep_merge!(options)
172
+ end
173
+ alias_method :associated_props, :associated_properties
174
+
175
+ # meta definition
176
+ def self.define_associated_properties(associated_properties)
177
+ associated_properties.each do |property|
178
+ # Example:
179
+ # def config_rule_name(value)
180
+ # associated_properties(config_rule_name: value)
181
+ # end
182
+ class_eval <<~CODE
183
+ def #{property}(value)
184
+ associated_properties(#{property}: value)
185
+ end
186
+ CODE
187
+ end
188
+ end
189
+
190
+ def add_logical_id_counter?
191
+ return false unless @associated_resources
192
+ # Only takes one associated resource with multiple set to true to return false of this check
193
+ return false if @associated_resources.detect { |associated| associated.multiple_resources }
194
+ # Otherwise check if there is more than 1 @associated_resources
195
+ @associated_resources.size > 1
196
+ end
197
+
198
+ # Loop back through the resources and add a counter to the end of the id
199
+ # to handle multiple events.
200
+ # Then replace @associated_resources entirely
201
+ def add_logical_id_counter
202
+ numbered_resources = []
203
+ n = 1
204
+ @associated_resources.map do |associated|
205
+ logical_id = associated.logical_id
206
+ attributes = associated.attributes
207
+
208
+ logical_id = logical_id.to_s.sub(/\d+$/,'')
209
+ new_definition = { "#{logical_id}#{n}" => attributes }
210
+ numbered_resources << Jets::Resource::Associated.new(new_definition)
211
+ n += 1
212
+ end
213
+ @associated_resources = numbered_resources
214
+ end
215
+
216
+ # Examples:
217
+ #
218
+ # depends_on :custom
219
+ # depends_on :custom, :alert
220
+ # depends_on :custom, class_prefix: true
221
+ # depends_on :custom, :alert, class_prefix: true
222
+ #
223
+ def depends_on(*stacks)
224
+ if stacks == []
225
+ @depends_on
226
+ else
227
+ @depends_on ||= []
228
+ options = stacks.last.is_a?(Hash) ? stacks.pop : {}
229
+ stacks.each do |stack|
230
+ @depends_on << Jets::Stack::Depends::Item.new(stack, options)
231
+ end
232
+ end
233
+ end
234
+
235
+ def ref(name)
236
+ "!Ref #{name.to_s.camelize}"
237
+ end
238
+
239
+ # meth is a Symbol
240
+ def method_added(meth)
241
+ return if %w[initialize method_missing].include?(meth.to_s)
242
+ return unless public_method_defined?(meth)
243
+
244
+ register_task(meth)
245
+ end
246
+
247
+ def register_task(meth, lang=:ruby)
248
+ # Note: for anonymous classes like for app/functions self.name is ""
249
+ # We adjust the class name when we build the functions later in
250
+ # FunctionContstructor#adjust_tasks.
251
+
252
+ # At this point we can use the current associated_properties and defined the
253
+ # associated resource with the Lambda function.
254
+ unless associated_properties.empty?
255
+ associated_resources(default_associated_resource_definition(meth))
256
+ end
257
+
258
+ # Unsure why but we have to use @associated_resources vs associated_resources
259
+ # associated_resources is always nil
260
+ if add_logical_id_counter?
261
+ add_logical_id_counter
262
+ end
263
+
264
+ all_tasks[meth] = Jets::Lambda::Task.new(self.name, meth,
265
+ properties: @properties, # lambda function properties
266
+ iam_policy: @iam_policy,
267
+ managed_iam_policy: @managed_iam_policy,
268
+ associated_resources: @associated_resources,
269
+ lang: lang,
270
+ replacements: replacements(meth))
271
+
272
+ # Done storing options, clear out for the next added method.
273
+ clear_properties
274
+ # Important to clear @properties at the end of registering outside of
275
+ # register_task because register_task is overridden in Jets::Job::Dsl
276
+ #
277
+ # Jets::Job::Base < Jets::Lambda::Functions
278
+ #
279
+ # Both Jets::Job::Base and Jets::Lambda::Functions have Dsl modules included.
280
+ # So the Jets::Job::Dsl overrides some of the Jets::Lambda::Dsl behavior.
281
+
282
+ true
283
+ end
284
+
285
+ # Meant to be overridden to add more custom replacements based on the app class type
286
+ def replacements(meth)
287
+ {}
288
+ end
289
+
290
+ def clear_properties
291
+ @properties = nil
292
+ @iam_policy = nil
293
+ @managed_iam_policy = nil
294
+ @associated_resources = nil
295
+ @associated_properties = nil
296
+ end
297
+
298
+ # Returns the all tasks for this class with their method names as keys.
299
+ #
300
+ # ==== Returns
301
+ # OrderedHash:: An ordered hash with tasks names as keys and Task
302
+ # objects as values.
303
+ #
304
+ def all_tasks
305
+ @all_tasks ||= ActiveSupport::OrderedHash.new
306
+ end
307
+ # Do not call all tasks outside this class, instead use: tasks or lambda functions
308
+ private :all_tasks
309
+
310
+ # Goes up the class inheritance chain to build the tasks.
311
+ #
312
+ # Example heirarchy:
313
+ #
314
+ # Jets::Lambda::Functions > Jets::Controller::Base > ApplicationController ...
315
+ # > PostsController > ChildPostsController
316
+ #
317
+ # Do not include tasks from the direct subclasses of Jets::Lambda::Functions
318
+ # because those classes are abstract. Dont want those methods to be included.
319
+ def find_all_tasks(public: true)
320
+ klass = self
321
+ direct_subclasses = Jets::Lambda::Functions.subclasses
322
+ lookup = []
323
+
324
+ # Go up class inheritance and builds lookup structure in memory
325
+ until direct_subclasses.include?(klass)
326
+ lookup << klass.send(:all_tasks) # one place we want to call private all_tasks method
327
+ klass = klass.superclass
328
+ end
329
+ merged_tasks = ActiveSupport::OrderedHash.new
330
+ # Go back down the class inheritance chain in reverse order and merge the tasks
331
+ lookup.reverse.each do |tasks_hash|
332
+ # tasks_hash is a result of all_tasks. Example: PostsController.all_tasks
333
+ merged_tasks.merge!(tasks_hash)
334
+ end
335
+
336
+ # The cfn builders required the right final child class to build the lambda functions correctly.
337
+ merged_tasks.each do |meth, task|
338
+ # Override the class name for the cfn builders
339
+ task = task.clone # do not stomp over current tasks since things are usually looked by reference
340
+ task.instance_variable_set(:@class_name, self.name)
341
+ merged_tasks[meth] = task
342
+ end
343
+
344
+ # Methods can be made private with the :private keyword after the method has been defined.
345
+ # To account for this, loop back thorugh all the methods and check if the method is indeed public.
346
+ tasks = ActiveSupport::OrderedHash.new
347
+ merged_tasks.each do |meth, task|
348
+ if public
349
+ tasks[meth] = task if task.public_meth?
350
+ else
351
+ tasks[meth] = task unless task.public_meth?
352
+ end
353
+ end
354
+ tasks
355
+ end
356
+ memoize :find_all_tasks
357
+
358
+ def all_public_tasks
359
+ find_all_tasks(public: true)
360
+ end
361
+
362
+ def all_private_tasks
363
+ find_all_tasks(public: false)
364
+ end
365
+
366
+ # Returns the tasks for this class in Array form.
367
+ #
368
+ # ==== Returns
369
+ # Array of task objects
370
+ #
371
+ def tasks
372
+ all_public_tasks.values
373
+ end
374
+
375
+ # The public methods defined in the project app class ulimately become
376
+ # lambda functions.
377
+ #
378
+ # Example return value:
379
+ # [:index, :new, :create, :show]
380
+ def lambda_functions
381
+ all_public_tasks.keys
382
+ end
383
+
384
+ # Used in Jets::Cfn::Builders::Interface#build
385
+ # Overridden in rule/dsl.rb
386
+ def build?
387
+ !tasks.empty?
388
+ end
389
+
390
+ # Polymorphic support
391
+ def defpoly(lang, meth)
392
+ register_task(meth, lang)
393
+ end
394
+
395
+ def python(meth)
396
+ defpoly(:python, meth)
397
+ end
398
+
399
+ def node(meth)
400
+ defpoly(:node, meth)
401
+ end
402
+ end # end of class << self
403
+ end # end of included
404
+
405
+ def self.add_custom_resource_extensions(base)
406
+ base_path = "#{Jets.root}/app/extensions"
407
+ Dir.glob("#{base_path}/**/*.rb").each do |path|
408
+ next unless File.file?(path)
409
+
410
+ class_name = path.sub("#{base_path}/", '').sub(/\.rb/,'').camelize
411
+ klass = class_name.constantize # autoload
412
+ base.extend(klass)
413
+ end
414
+ end
415
+
416
+ def self.included(base)
417
+ add_custom_resource_extensions(base)
418
+ end
419
+ end