jets-fs 1.6.10

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 (379) 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 +73 -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 +6 -0
  21. data/.python-version +1 -0
  22. data/.rspec +4 -0
  23. data/.ruby-version +1 -0
  24. data/CHANGELOG.md +533 -0
  25. data/Dockerfile +16 -0
  26. data/Dockerfile.base +53 -0
  27. data/Gemfile +14 -0
  28. data/Gemfile.lock +190 -0
  29. data/Guardfile +22 -0
  30. data/LICENSE.txt +22 -0
  31. data/Procfile +2 -0
  32. data/README.md +203 -0
  33. data/Rakefile +21 -0
  34. data/backers.md +16 -0
  35. data/bin/release +9 -0
  36. data/buildspec.yml +18 -0
  37. data/exe/jets +14 -0
  38. data/jets.gemspec +61 -0
  39. data/lib/jets.rb +71 -0
  40. data/lib/jets/application.rb +308 -0
  41. data/lib/jets/aws_info.rb +111 -0
  42. data/lib/jets/aws_services.rb +60 -0
  43. data/lib/jets/aws_services/stack_status.rb +59 -0
  44. data/lib/jets/booter.rb +130 -0
  45. data/lib/jets/builders.rb +16 -0
  46. data/lib/jets/builders/code_builder.rb +379 -0
  47. data/lib/jets/builders/code_size.rb +57 -0
  48. data/lib/jets/builders/gem_replacer.rb +76 -0
  49. data/lib/jets/builders/handler_generator.rb +172 -0
  50. data/lib/jets/builders/lambda_layer.rb +69 -0
  51. data/lib/jets/builders/md5.rb +60 -0
  52. data/lib/jets/builders/md5_zip.rb +61 -0
  53. data/lib/jets/builders/purger.rb +35 -0
  54. data/lib/jets/builders/rack_packager.rb +51 -0
  55. data/lib/jets/builders/rackup_wrappers/rackup +19 -0
  56. data/lib/jets/builders/rackup_wrappers/rackup.rb +7 -0
  57. data/lib/jets/builders/reconfigure_rails.rb +114 -0
  58. data/lib/jets/builders/reconfigure_rails/config/initializers/jets.rb +16 -0
  59. data/lib/jets/builders/ruby_packager.rb +207 -0
  60. data/lib/jets/builders/shim_vars.rb +5 -0
  61. data/lib/jets/builders/shim_vars/app.rb +78 -0
  62. data/lib/jets/builders/shim_vars/base.rb +25 -0
  63. data/lib/jets/builders/shim_vars/shared.rb +37 -0
  64. data/lib/jets/builders/templates/handler.rb +12 -0
  65. data/lib/jets/builders/tidy.rb +107 -0
  66. data/lib/jets/builders/util.rb +31 -0
  67. data/lib/jets/camelizer.rb +67 -0
  68. data/lib/jets/cfn.rb +6 -0
  69. data/lib/jets/cfn/builders.rb +20 -0
  70. data/lib/jets/cfn/builders/api_deployment_builder.rb +58 -0
  71. data/lib/jets/cfn/builders/api_gateway_builder.rb +80 -0
  72. data/lib/jets/cfn/builders/base_child_builder.rb +82 -0
  73. data/lib/jets/cfn/builders/controller_builder.rb +42 -0
  74. data/lib/jets/cfn/builders/function_builder.rb +14 -0
  75. data/lib/jets/cfn/builders/interface.rb +127 -0
  76. data/lib/jets/cfn/builders/job_builder.rb +14 -0
  77. data/lib/jets/cfn/builders/parent_builder.rb +93 -0
  78. data/lib/jets/cfn/builders/rule_builder.rb +24 -0
  79. data/lib/jets/cfn/builders/shared_builder.rb +14 -0
  80. data/lib/jets/cfn/ship.rb +189 -0
  81. data/lib/jets/cfn/status.rb +212 -0
  82. data/lib/jets/cfn/upload.rb +139 -0
  83. data/lib/jets/cli.rb +189 -0
  84. data/lib/jets/commands.rb +27 -0
  85. data/lib/jets/commands/base.rb +164 -0
  86. data/lib/jets/commands/build.rb +217 -0
  87. data/lib/jets/commands/call.rb +174 -0
  88. data/lib/jets/commands/call/anonymous_guesser.rb +96 -0
  89. data/lib/jets/commands/call/autoload_guesser.rb +112 -0
  90. data/lib/jets/commands/call/base_guesser.rb +33 -0
  91. data/lib/jets/commands/call/guesser.rb +48 -0
  92. data/lib/jets/commands/clean.rb +23 -0
  93. data/lib/jets/commands/clean/base.rb +24 -0
  94. data/lib/jets/commands/clean/build.rb +13 -0
  95. data/lib/jets/commands/clean/log.rb +107 -0
  96. data/lib/jets/commands/console.rb +13 -0
  97. data/lib/jets/commands/db.rb +15 -0
  98. data/lib/jets/commands/db/environment-task.rake +3 -0
  99. data/lib/jets/commands/db/tasks.rb +44 -0
  100. data/lib/jets/commands/dbconsole.rb +131 -0
  101. data/lib/jets/commands/delete.rb +143 -0
  102. data/lib/jets/commands/deploy.rb +131 -0
  103. data/lib/jets/commands/dynamodb.rb +22 -0
  104. data/lib/jets/commands/dynamodb/migrate.rb +9 -0
  105. data/lib/jets/commands/dynamodb/migrator.rb +36 -0
  106. data/lib/jets/commands/gems.rb +21 -0
  107. data/lib/jets/commands/help.rb +9 -0
  108. data/lib/jets/commands/help/build.md +6 -0
  109. data/lib/jets/commands/help/call.md +61 -0
  110. data/lib/jets/commands/help/clean/build.md +5 -0
  111. data/lib/jets/commands/help/clean/log.md +5 -0
  112. data/lib/jets/commands/help/console.md +18 -0
  113. data/lib/jets/commands/help/db/generate.md +8 -0
  114. data/lib/jets/commands/help/dbconsole.md +9 -0
  115. data/lib/jets/commands/help/delete.md +22 -0
  116. data/lib/jets/commands/help/deploy.md +32 -0
  117. data/lib/jets/commands/help/dynamodb/generate.md +52 -0
  118. data/lib/jets/commands/help/dynamodb/migrate.md +4 -0
  119. data/lib/jets/commands/help/gems/check.md +8 -0
  120. data/lib/jets/commands/help/generate.md +22 -0
  121. data/lib/jets/commands/help/import/rack.md +13 -0
  122. data/lib/jets/commands/help/import/rails.md +11 -0
  123. data/lib/jets/commands/help/new.md +42 -0
  124. data/lib/jets/commands/help/routes.md +16 -0
  125. data/lib/jets/commands/help/runner.md +17 -0
  126. data/lib/jets/commands/help/server.md +15 -0
  127. data/lib/jets/commands/help/status.md +14 -0
  128. data/lib/jets/commands/help/upgrade.md +5 -0
  129. data/lib/jets/commands/help/url.md +6 -0
  130. data/lib/jets/commands/import.rb +18 -0
  131. data/lib/jets/commands/import/base.rb +49 -0
  132. data/lib/jets/commands/import/cheatsheet.rb +35 -0
  133. data/lib/jets/commands/import/rack.rb +16 -0
  134. data/lib/jets/commands/import/rail.rb +74 -0
  135. data/lib/jets/commands/import/sequence.rb +90 -0
  136. data/lib/jets/commands/import/templates/config/database.yml +26 -0
  137. data/lib/jets/commands/import/templates/submodules-cheatsheet.md +89 -0
  138. data/lib/jets/commands/main.rb +152 -0
  139. data/lib/jets/commands/markdown.rb +8 -0
  140. data/lib/jets/commands/markdown/creator.rb +58 -0
  141. data/lib/jets/commands/markdown/index.rb +27 -0
  142. data/lib/jets/commands/markdown/page.rb +125 -0
  143. data/lib/jets/commands/markdown/shell.rb +11 -0
  144. data/lib/jets/commands/new.rb +157 -0
  145. data/lib/jets/commands/rake_command.rb +61 -0
  146. data/lib/jets/commands/rake_tasks.rb +45 -0
  147. data/lib/jets/commands/runner.rb +18 -0
  148. data/lib/jets/commands/sequence.rb +99 -0
  149. data/lib/jets/commands/stack_info.rb +30 -0
  150. data/lib/jets/commands/templates/skeleton/.gitignore +12 -0
  151. data/lib/jets/commands/templates/skeleton/.jetskeep +1 -0
  152. data/lib/jets/commands/templates/skeleton/.rspec +3 -0
  153. data/lib/jets/commands/templates/skeleton/Gemfile.tt +35 -0
  154. data/lib/jets/commands/templates/skeleton/Procfile +7 -0
  155. data/lib/jets/commands/templates/skeleton/README.md +11 -0
  156. data/lib/jets/commands/templates/skeleton/Rakefile +2 -0
  157. data/lib/jets/commands/templates/skeleton/app/controllers/application_controller.rb +2 -0
  158. data/lib/jets/commands/templates/skeleton/app/helpers/application_helper.rb +2 -0
  159. data/lib/jets/commands/templates/skeleton/app/jobs/application_job.rb +4 -0
  160. data/lib/jets/commands/templates/skeleton/app/models/application_item.rb +2 -0
  161. data/lib/jets/commands/templates/skeleton/app/models/application_record.rb +3 -0
  162. data/lib/jets/commands/templates/skeleton/app/views/layouts/application.html.erb.tt +25 -0
  163. data/lib/jets/commands/templates/skeleton/config.ru +5 -0
  164. data/lib/jets/commands/templates/skeleton/config/application.rb.tt +66 -0
  165. data/lib/jets/commands/templates/skeleton/config/database.yml.tt +26 -0
  166. data/lib/jets/commands/templates/skeleton/config/dynamodb.yml +22 -0
  167. data/lib/jets/commands/templates/skeleton/config/environments/development.rb +4 -0
  168. data/lib/jets/commands/templates/skeleton/config/environments/production.rb +4 -0
  169. data/lib/jets/commands/templates/skeleton/config/routes.rb +9 -0
  170. data/lib/jets/commands/templates/skeleton/db/.gitkeep +0 -0
  171. data/lib/jets/commands/templates/skeleton/public/404.html +67 -0
  172. data/lib/jets/commands/templates/skeleton/public/422.html +67 -0
  173. data/lib/jets/commands/templates/skeleton/public/500.html +66 -0
  174. data/lib/jets/commands/templates/skeleton/public/favicon.ico +0 -0
  175. data/lib/jets/commands/templates/skeleton/public/index.html.tt +91 -0
  176. data/lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb +15 -0
  177. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-index.json +51 -0
  178. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-show.json +53 -0
  179. data/lib/jets/commands/templates/skeleton/spec/spec_helper.rb.tt +30 -0
  180. data/lib/jets/commands/templates/webpacker/app/javascript/packs/application.js.tt +14 -0
  181. data/lib/jets/commands/templates/webpacker/app/javascript/packs/theme.scss.tt +24 -0
  182. data/lib/jets/commands/templates/webpacker/app/javascript/src/jets/crud.js +87 -0
  183. data/lib/jets/commands/upgrade.rb +146 -0
  184. data/lib/jets/commands/upgrade/templates/bin/webpack +19 -0
  185. data/lib/jets/commands/upgrade/templates/bin/webpack-dev-server +19 -0
  186. data/lib/jets/commands/url.rb +68 -0
  187. data/lib/jets/commands/webpacker_template.rb +18 -0
  188. data/lib/jets/controller.rb +16 -0
  189. data/lib/jets/controller/base.rb +103 -0
  190. data/lib/jets/controller/callbacks.rb +62 -0
  191. data/lib/jets/controller/cookies.rb +40 -0
  192. data/lib/jets/controller/cookies/jar.rb +269 -0
  193. data/lib/jets/controller/layout.rb +17 -0
  194. data/lib/jets/controller/middleware.rb +5 -0
  195. data/lib/jets/controller/middleware/cors.rb +60 -0
  196. data/lib/jets/controller/middleware/local.rb +119 -0
  197. data/lib/jets/controller/middleware/local/api_gateway.rb +93 -0
  198. data/lib/jets/controller/middleware/local/mimic_aws_call.rb +38 -0
  199. data/lib/jets/controller/middleware/local/route_matcher.rb +97 -0
  200. data/lib/jets/controller/middleware/main.rb +46 -0
  201. data/lib/jets/controller/middleware/webpacker_setup.rb +6 -0
  202. data/lib/jets/controller/params.rb +87 -0
  203. data/lib/jets/controller/rack.rb +5 -0
  204. data/lib/jets/controller/rack/adapter.rb +63 -0
  205. data/lib/jets/controller/rack/env.rb +105 -0
  206. data/lib/jets/controller/redirection.rb +55 -0
  207. data/lib/jets/controller/rendering.rb +84 -0
  208. data/lib/jets/controller/rendering/rack_renderer.rb +238 -0
  209. data/lib/jets/controller/request.rb +29 -0
  210. data/lib/jets/controller/response.rb +61 -0
  211. data/lib/jets/core.rb +211 -0
  212. data/lib/jets/core_ext/kernel.rb +56 -0
  213. data/lib/jets/db.rb +15 -0
  214. data/lib/jets/dotenv.rb +39 -0
  215. data/lib/jets/erb.rb +51 -0
  216. data/lib/jets/generator.rb +41 -0
  217. data/lib/jets/generator/templates/erb/controller/view.html.erb +2 -0
  218. data/lib/jets/generator/templates/erb/scaffold/_form.html.erb +39 -0
  219. data/lib/jets/generator/templates/erb/scaffold/edit.html.erb +6 -0
  220. data/lib/jets/generator/templates/erb/scaffold/index.html.erb +29 -0
  221. data/lib/jets/generator/templates/erb/scaffold/new.html.erb +5 -0
  222. data/lib/jets/generator/templates/erb/scaffold/show.html.erb +9 -0
  223. data/lib/jets/generator/templates/rails/assets/javascript.js +2 -0
  224. data/lib/jets/generator/templates/rails/assets/stylesheet.css +4 -0
  225. data/lib/jets/generator/templates/rails/controller/controller.rb +13 -0
  226. data/lib/jets/generator/templates/rails/helper/helper.rb +4 -0
  227. data/lib/jets/generator/templates/rails/scaffold/scaffold.css +80 -0
  228. data/lib/jets/generator/templates/rails/scaffold_controller/api_controller.rb +62 -0
  229. data/lib/jets/generator/templates/rails/scaffold_controller/controller.rb +79 -0
  230. data/lib/jets/inflections.rb +32 -0
  231. data/lib/jets/internal/app/controllers/jets/public_controller.rb +31 -0
  232. data/lib/jets/internal/app/controllers/jets/rack_controller.rb +25 -0
  233. data/lib/jets/internal/app/functions/jets/base_path.rb +153 -0
  234. data/lib/jets/internal/app/jobs/jets/preheat_job.rb +62 -0
  235. data/lib/jets/io.rb +14 -0
  236. data/lib/jets/job.rb +4 -0
  237. data/lib/jets/job/base.rb +29 -0
  238. data/lib/jets/job/dsl.rb +108 -0
  239. data/lib/jets/klass.rb +109 -0
  240. data/lib/jets/lambda.rb +18 -0
  241. data/lib/jets/lambda/dsl.rb +384 -0
  242. data/lib/jets/lambda/function.rb +29 -0
  243. data/lib/jets/lambda/function_constructor.rb +55 -0
  244. data/lib/jets/lambda/functions.rb +34 -0
  245. data/lib/jets/lambda/task.rb +111 -0
  246. data/lib/jets/logger.rb +24 -0
  247. data/lib/jets/mega.rb +7 -0
  248. data/lib/jets/mega/hash_converter.rb +25 -0
  249. data/lib/jets/mega/request.rb +140 -0
  250. data/lib/jets/mega/request/source.rb +21 -0
  251. data/lib/jets/middleware.rb +38 -0
  252. data/lib/jets/middleware/configurator.rb +84 -0
  253. data/lib/jets/middleware/default_stack.rb +49 -0
  254. data/lib/jets/middleware/layer.rb +34 -0
  255. data/lib/jets/middleware/stack.rb +77 -0
  256. data/lib/jets/naming.rb +49 -0
  257. data/lib/jets/overrides/lambda.rb +1 -0
  258. data/lib/jets/overrides/lambda/marshaller.rb +31 -0
  259. data/lib/jets/overrides/rails.rb +4 -0
  260. data/lib/jets/overrides/rails/asset_tag_helper.rb +114 -0
  261. data/lib/jets/overrides/rails/common_methods.rb +20 -0
  262. data/lib/jets/overrides/rails/rendering_helper.rb +26 -0
  263. data/lib/jets/overrides/rails/url_helper.rb +25 -0
  264. data/lib/jets/poly_fun.rb +82 -0
  265. data/lib/jets/poly_fun/base_executor.rb +125 -0
  266. data/lib/jets/poly_fun/lambda_executor.rb +16 -0
  267. data/lib/jets/poly_fun/node_error.rb +8 -0
  268. data/lib/jets/poly_fun/node_executor.rb +54 -0
  269. data/lib/jets/poly_fun/python_error.rb +8 -0
  270. data/lib/jets/poly_fun/python_executor.rb +23 -0
  271. data/lib/jets/preheat.rb +117 -0
  272. data/lib/jets/processors.rb +4 -0
  273. data/lib/jets/processors/deducer.rb +65 -0
  274. data/lib/jets/processors/main_processor.rb +59 -0
  275. data/lib/jets/rack_server.rb +80 -0
  276. data/lib/jets/rdoc.rb +30 -0
  277. data/lib/jets/resource.rb +74 -0
  278. data/lib/jets/resource/api_gateway.rb +9 -0
  279. data/lib/jets/resource/api_gateway/base_path.rb +5 -0
  280. data/lib/jets/resource/api_gateway/base_path/function.rb +42 -0
  281. data/lib/jets/resource/api_gateway/base_path/mapping.rb +44 -0
  282. data/lib/jets/resource/api_gateway/base_path/role.rb +76 -0
  283. data/lib/jets/resource/api_gateway/cors.rb +61 -0
  284. data/lib/jets/resource/api_gateway/deployment.rb +78 -0
  285. data/lib/jets/resource/api_gateway/domain_name.rb +59 -0
  286. data/lib/jets/resource/api_gateway/method.rb +98 -0
  287. data/lib/jets/resource/api_gateway/resource.rb +78 -0
  288. data/lib/jets/resource/api_gateway/rest_api.rb +60 -0
  289. data/lib/jets/resource/api_gateway/rest_api/change_detection.rb +42 -0
  290. data/lib/jets/resource/api_gateway/rest_api/logical_id.rb +63 -0
  291. data/lib/jets/resource/api_gateway/rest_api/routes.rb +11 -0
  292. data/lib/jets/resource/api_gateway/rest_api/routes/change.rb +12 -0
  293. data/lib/jets/resource/api_gateway/rest_api/routes/change/base.rb +130 -0
  294. data/lib/jets/resource/api_gateway/rest_api/routes/change/to.rb +29 -0
  295. data/lib/jets/resource/api_gateway/rest_api/routes/change/variable.rb +39 -0
  296. data/lib/jets/resource/api_gateway/rest_api/routes/collision.rb +123 -0
  297. data/lib/jets/resource/api_gateway/rest_api/routes/collision/variable_exception.rb +7 -0
  298. data/lib/jets/resource/associated.rb +26 -0
  299. data/lib/jets/resource/base.rb +28 -0
  300. data/lib/jets/resource/child_stack.rb +7 -0
  301. data/lib/jets/resource/child_stack/api_deployment.rb +56 -0
  302. data/lib/jets/resource/child_stack/api_gateway.rb +29 -0
  303. data/lib/jets/resource/child_stack/app_class.rb +112 -0
  304. data/lib/jets/resource/child_stack/base.rb +24 -0
  305. data/lib/jets/resource/child_stack/shared.rb +90 -0
  306. data/lib/jets/resource/config.rb +4 -0
  307. data/lib/jets/resource/config/config_rule.rb +74 -0
  308. data/lib/jets/resource/config/managed_rule.rb +15 -0
  309. data/lib/jets/resource/events.rb +3 -0
  310. data/lib/jets/resource/events/rule.rb +31 -0
  311. data/lib/jets/resource/iam.rb +8 -0
  312. data/lib/jets/resource/iam/application_role.rb +27 -0
  313. data/lib/jets/resource/iam/base_role_definition.rb +47 -0
  314. data/lib/jets/resource/iam/class_role.rb +74 -0
  315. data/lib/jets/resource/iam/function_role.rb +54 -0
  316. data/lib/jets/resource/iam/managed_policy.rb +22 -0
  317. data/lib/jets/resource/iam/policy_document.rb +41 -0
  318. data/lib/jets/resource/lambda.rb +5 -0
  319. data/lib/jets/resource/lambda/function.rb +216 -0
  320. data/lib/jets/resource/lambda/function/environment.rb +61 -0
  321. data/lib/jets/resource/lambda/gem_layer.rb +17 -0
  322. data/lib/jets/resource/lambda/layer_version.rb +44 -0
  323. data/lib/jets/resource/permission.rb +45 -0
  324. data/lib/jets/resource/replacer.rb +77 -0
  325. data/lib/jets/resource/route53.rb +3 -0
  326. data/lib/jets/resource/route53/record_set.rb +70 -0
  327. data/lib/jets/resource/s3.rb +17 -0
  328. data/lib/jets/resource/sns.rb +3 -0
  329. data/lib/jets/resource/sqs.rb +3 -0
  330. data/lib/jets/resource/standardizer.rb +42 -0
  331. data/lib/jets/route.rb +166 -0
  332. data/lib/jets/router.rb +175 -0
  333. data/lib/jets/router/scope.rb +30 -0
  334. data/lib/jets/rule.rb +4 -0
  335. data/lib/jets/rule/base.rb +19 -0
  336. data/lib/jets/rule/dsl.rb +110 -0
  337. data/lib/jets/spec_helpers.rb +52 -0
  338. data/lib/jets/spec_helpers/params.rb +10 -0
  339. data/lib/jets/spec_helpers/request.rb +98 -0
  340. data/lib/jets/spec_helpers/response.rb +5 -0
  341. data/lib/jets/stack.rb +103 -0
  342. data/lib/jets/stack/builder.rb +38 -0
  343. data/lib/jets/stack/definition.rb +50 -0
  344. data/lib/jets/stack/function.rb +60 -0
  345. data/lib/jets/stack/main.rb +5 -0
  346. data/lib/jets/stack/main/dsl.rb +33 -0
  347. data/lib/jets/stack/main/extensions/base.rb +45 -0
  348. data/lib/jets/stack/main/extensions/cloudwatch.rb +19 -0
  349. data/lib/jets/stack/main/extensions/lambda.rb +71 -0
  350. data/lib/jets/stack/main/extensions/sns.rb +12 -0
  351. data/lib/jets/stack/main/extensions/sqs.rb +36 -0
  352. data/lib/jets/stack/output.rb +38 -0
  353. data/lib/jets/stack/output/dsl.rb +19 -0
  354. data/lib/jets/stack/output/lookup.rb +36 -0
  355. data/lib/jets/stack/parameter.rb +38 -0
  356. data/lib/jets/stack/parameter/dsl.rb +42 -0
  357. data/lib/jets/stack/resource.rb +32 -0
  358. data/lib/jets/stack/resource/dsl.rb +19 -0
  359. data/lib/jets/tmp_loader.rb +52 -0
  360. data/lib/jets/turbine.rb +30 -0
  361. data/lib/jets/turbo.rb +47 -0
  362. data/lib/jets/turbo/database_yaml.rb +41 -0
  363. data/lib/jets/turbo/project/.gitignore +12 -0
  364. data/lib/jets/turbo/project/.jetskeep +1 -0
  365. data/lib/jets/turbo/project/Gemfile +16 -0
  366. data/lib/jets/turbo/project/Rakefile +2 -0
  367. data/lib/jets/turbo/project/app/controllers/application_controller.rb +2 -0
  368. data/lib/jets/turbo/project/app/helpers/application_helper.rb +2 -0
  369. data/lib/jets/turbo/project/app/jobs/application_job.rb +4 -0
  370. data/lib/jets/turbo/project/config.ru +5 -0
  371. data/lib/jets/turbo/project/config/application.rb +4 -0
  372. data/lib/jets/turbo/project/config/routes.rb +4 -0
  373. data/lib/jets/turbo/rail.rb +113 -0
  374. data/lib/jets/turbo/templates/config/database.yml +26 -0
  375. data/lib/jets/util.rb +38 -0
  376. data/lib/jets/version.rb +3 -0
  377. data/readme/prerelease.md +6 -0
  378. data/readme/testing.md +60 -0
  379. metadata +859 -0
@@ -0,0 +1,111 @@
1
+
2
+ module Jets
3
+ class AwsInfo
4
+ extend Memoist
5
+ include AwsServices
6
+
7
+ def region
8
+ return 'us-east-1' if test?
9
+
10
+ return ENV['JETS_AWS_REGION'] if ENV['JETS_AWS_REGION'] # highest precedence
11
+ return ENV['AWS_REGION'] if ENV['AWS_REGION']
12
+
13
+ region = nil
14
+
15
+ # First if aws binary is available
16
+ # try to get it from the ~/.aws/config
17
+ if which('aws')
18
+ region = `aws configure get region 2>&1`.strip rescue nil
19
+ exit_code = $?.exitstatus
20
+ if exit_code != 0
21
+ exception_message = region.split("\n").grep(/botocore\.exceptions/).first
22
+ if exception_message
23
+ puts "WARN: #{exception_message}".color(:yellow)
24
+ else
25
+ # show full message as warning
26
+ puts region.color(:yellow)
27
+ end
28
+ puts "You can also get rid of this message by setting AWS_REGION or configuring ~/.aws/config with the region"
29
+ region = nil
30
+ end
31
+ region = nil if region == ''
32
+ return region if region
33
+ end
34
+
35
+ # Second try the metadata endpoint, should be available on AWS Lambda environment
36
+ # https://stackoverflow.com/questions/4249488/find-region-from-within-an-ec2-instance
37
+ begin
38
+ az = `curl -s --max-time 3 --connect-timeout 5 http://169.254.169.254/latest/meta-data/placement/availability-zone`
39
+ region = az.strip.chop # remove last char
40
+ region = nil if region == ''
41
+ rescue
42
+ end
43
+ return region if region
44
+
45
+ 'us-east-1' # default if all else fails
46
+ end
47
+ memoize :region
48
+
49
+ # aws sts get-caller-identity
50
+ def account
51
+ return '123456789' if test?
52
+ # ensure region set, required for sts.get_caller_identity.account to work
53
+ ENV['AWS_REGION'] ||= region
54
+ begin
55
+ sts.get_caller_identity.account
56
+ rescue Aws::Errors::MissingCredentialsError
57
+ puts "INFO: You're missing AWS credentials. Only local services are currently available"
58
+ end
59
+ end
60
+ memoize :account
61
+
62
+ # If bucket does not exist, do not use the cache value and check for the bucket again.
63
+ # This is because we can build the app before deploying it for the first time.
64
+ # The deploy sequence ensure an minimal stack exists and will return a s3 bucket
65
+ # value for real deployments though, just not for the `jets build` only command.
66
+ BUCKET_DOES_NOT_YET_EXIST = "bucket-does-not-yet-exist" # use const to save from misspellings
67
+ @@s3_bucket = BUCKET_DOES_NOT_YET_EXIST
68
+ def s3_bucket
69
+ return "fake-test-s3-bucket" if ENV['TEST']
70
+ return @@s3_bucket unless @@s3_bucket == BUCKET_DOES_NOT_YET_EXIST
71
+
72
+ resp = cfn.describe_stacks(stack_name: Jets::Naming.parent_stack_name)
73
+ stack = resp.stacks.first
74
+ output = stack["outputs"].find { |o| o["output_key"] == "S3Bucket" }
75
+ @@s3_bucket = output["output_value"] # s3_bucket
76
+ rescue Exception => e
77
+ # When user uses Jets::Application.default_iam_policy in their config/application.rb
78
+ # it looks up the s3 bucket for the iam policy, but the project name has
79
+ # not been loaded in the config yet. We do some trickery with loading
80
+ # the config twice in Application#load_app_config
81
+ # The first load will result in a Aws::CloudFormation::Errors::ValidationError
82
+ # since the Jets::Naming.parent_stack_name has not been properly set yet.
83
+ #
84
+ # Rescuing all exceptions in case there are other exceptions dont know about yet
85
+ # Here are the known ones: Aws::CloudFormation::Errors::ValidationError, Aws::CloudFormation::Errors::InvalidClientTokenId
86
+ BUCKET_DOES_NOT_YET_EXIST
87
+ end
88
+
89
+ def test?
90
+ ENV['TEST'] || ENV['CIRCLECI']
91
+ end
92
+
93
+ private
94
+
95
+ # Cross-platform way of finding an executable in the $PATH.
96
+ #
97
+ # which('ruby') #=> /usr/bin/ruby
98
+ #
99
+ # source: https://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
100
+ def which(cmd)
101
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
102
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
103
+ exts.each { |ext|
104
+ exe = File.join(path, "#{cmd}#{ext}")
105
+ return exe if File.executable?(exe) && !File.directory?(exe)
106
+ }
107
+ end
108
+ return nil
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,60 @@
1
+ require "aws-sdk-apigateway"
2
+ require "aws-sdk-cloudformation"
3
+ require "aws-sdk-cloudwatchlogs"
4
+ require "aws-sdk-lambda"
5
+ require "aws-sdk-s3"
6
+ require "aws-sdk-sts"
7
+ # Not used in Jets internally but convenient for shared resources
8
+ require "aws-sdk-sns"
9
+ require "aws-sdk-sqs"
10
+
11
+ module Jets::AwsServices
12
+ autoload :StackStatus, 'jets/aws_services/stack_status'
13
+ include StackStatus
14
+ extend Memoist
15
+
16
+ def apigateway
17
+ Aws::APIGateway::Client.new
18
+ end
19
+ memoize :apigateway
20
+
21
+ def cfn
22
+ Aws::CloudFormation::Client.new
23
+ end
24
+ memoize :cfn
25
+
26
+ def lambda
27
+ Aws::Lambda::Client.new
28
+ end
29
+ memoize :lambda
30
+
31
+ def logs
32
+ Aws::CloudWatchLogs::Client.new
33
+ end
34
+ memoize :logs
35
+
36
+ def s3
37
+ Aws::S3::Client.new
38
+ end
39
+ memoize :s3
40
+
41
+ def s3_resource
42
+ Aws::S3::Resource.new
43
+ end
44
+ memoize :s3_resource
45
+
46
+ def sns
47
+ Aws::SNS::Client.new
48
+ end
49
+ memoize :sns
50
+
51
+ def sqs
52
+ Aws::SQS::Client.new
53
+ end
54
+ memoize :sqs
55
+
56
+ def sts
57
+ Aws::STS::Client.new
58
+ end
59
+ memoize :sts
60
+ end
@@ -0,0 +1,59 @@
1
+ module Jets::AwsServices
2
+ module StackStatus
3
+ def stack_exists?(stack_name)
4
+ return false if ENV['TEST']
5
+
6
+ exist = nil
7
+ begin
8
+ # When the stack does not exist an exception is raised. Example:
9
+ # Aws::CloudFormation::Errors::ValidationError: Stack with id blah does not exist
10
+ resp = cfn.describe_stacks(stack_name: stack_name)
11
+ exist = true
12
+ rescue Aws::CloudFormation::Errors::ValidationError => e
13
+ if e.message =~ /does not exist/
14
+ exist = false
15
+ elsif e.message.include?("'stackName' failed to satisfy constraint")
16
+ # Example of e.message when describe_stack with invalid stack name
17
+ # "1 validation error detected: Value 'instance_and_route53' at 'stackName' failed to satisfy constraint: Member must satisfy regular expression pattern: [a-zA-Z][-a-zA-Z0-9]*|arn:[-a-zA-Z0-9:/._+]*"
18
+ puts "Invalid stack name: #{stack_name}"
19
+ puts "Full error message: #{e.message}"
20
+ exit 1
21
+ else
22
+ raise # re-raise exception because unsure what other errors can happen
23
+ end
24
+ end
25
+ exist
26
+ end
27
+
28
+ # All CloudFormation states listed here: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-describing-stacks.html
29
+ #
30
+ # Returns resp so we can use it to grab data about the stack without calling api again.
31
+ def stack_in_progress?(stack_name)
32
+ return true if !stack_exists?(stack_name)
33
+
34
+ # Assumes stack exists
35
+ resp = cfn.describe_stacks(stack_name: stack_name)
36
+ status = resp.stacks[0].stack_status
37
+ if status =~ /_IN_PROGRESS$/
38
+ puts "The '#{stack_name}' stack status is #{status}. " \
39
+ "Please wait until the stack is ready and try again.".color(:red)
40
+ exit 0
41
+ elsif resp.stacks[0].outputs.empty? && status != 'ROLLBACK_COMPLETE'
42
+ # This Happens when the miminal stack fails at the very beginning.
43
+ # There is no s3 bucket at all. User should delete the stack.
44
+ puts "The minimal stack failed to create. Please delete the stack first and try again. " \
45
+ "You can delete the CloudFormation stack or use the `jets delete` command"
46
+ exit 0
47
+ else
48
+ true
49
+ end
50
+ end
51
+
52
+ # Lookup output value.
53
+ # Used in Jets::Resource::ApiGateway::RestApi::* andJets::Commands::Url
54
+ def lookup(outputs, key)
55
+ out = outputs.find { |o| o.output_key == key }
56
+ out&.output_value
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,130 @@
1
+ class Jets::Booter
2
+ class << self
3
+ @booted = false
4
+ def boot!(options={})
5
+ return if @booted
6
+
7
+ turbo_charge
8
+ confirm_jets_project!
9
+ require_bundle_gems unless bypass_bundler_setup?
10
+ Jets::Dotenv.load!
11
+
12
+ Jets.application.setup!
13
+ app_initializers
14
+ turbine_initializers
15
+ Jets.application.finish!
16
+
17
+ Jets.eager_load!
18
+ setup_db
19
+ # build_middleware_stack # TODO: figure out how to build middleware during Jets.boot without breaking jets new and webpacker:install
20
+
21
+ @booted = true
22
+ end
23
+
24
+ def bypass_bundler_setup?
25
+ command = ARGV.first
26
+ %w[build delete deploy url].include?(command)
27
+ end
28
+
29
+ def turbo_charge
30
+ turbo = Jets::Turbo.new
31
+ turbo.charge
32
+ end
33
+
34
+ # Builds and memoize stack so it only gets built on bootup
35
+ def build_middleware_stack
36
+ Jets.application.build_stack
37
+ end
38
+
39
+ def turbine_initializers
40
+ Jets::Turbine.subclasses.each do |subclass|
41
+ subclass.initializers.each do |label, block|
42
+ block.call(Jets.application)
43
+ end
44
+ end
45
+ end
46
+
47
+ def app_initializers
48
+ Dir.glob("#{Jets.root}/config/initializers/**/*").each do |path|
49
+ load path
50
+ end
51
+ end
52
+
53
+ # require_bundle_gems called when environment boots up via Jets.boot. It
54
+ # also useful for when to loading Rake tasks in
55
+ # Jets::Commands::RakeTasks.load!
56
+ #
57
+ # For example, some gems like webpacker that load rake tasks are specified
58
+ # with a git based source:
59
+ #
60
+ # gem "webpacker", git: "https://github.com/tongueroo/webpacker.git"
61
+ #
62
+ # This results in the user having to specific bundle exec in front of
63
+ # jets for those rake tasks to show up in jets help.
64
+ #
65
+ # Instead, when the user is within the project folder, jets automatically
66
+ # requires bundler for the user. So the rake tasks show up when calling
67
+ # jets help.
68
+ #
69
+ # When the user calls jets help from outside the project folder, bundler
70
+ # is not used and the load errors get rescued gracefully. This is done in
71
+ # Jets::Commands::RakeTasks.load! In the case when there are in another
72
+ # project with another Gemfile, the load errors will still be rescued.
73
+ def require_bundle_gems
74
+ # NOTE: Dont think ENV['BUNDLE_GEMFILE'] is quite working right. We still need
75
+ # to be in the project directory. Leaving logic in here for when it gets fix.
76
+ if ENV['BUNDLE_GEMFILE'] || File.exist?("Gemfile")
77
+ require "bundler/setup"
78
+ Bundler.require(*bundler_groups)
79
+ end
80
+ end
81
+
82
+ # Only connects connect to database for ActiveRecord and when
83
+ # config/database.yml exists.
84
+ # Dynomite handles connecting to the clients lazily.
85
+ def setup_db
86
+ return unless File.exist?("#{Jets.root}/config/database.yml")
87
+
88
+ db_configs = Jets.application.config.database
89
+ # DatabaseTasks.database_configuration for db:create db:migrate tasks
90
+ # Documented in DatabaseTasks that this is the right way to set it when
91
+ # using ActiveRecord rake tasks outside of Rails.
92
+ ActiveRecord::Tasks::DatabaseTasks.database_configuration = db_configs
93
+
94
+ current_config = db_configs[Jets.env]
95
+ if current_config.empty?
96
+ abort("ERROR: config/database.yml exists but no environment section configured for #{Jets.env}")
97
+ end
98
+ # Using ActiveRecord rake tasks outside of Rails, so we need to set up the
99
+ # db connection ourselves
100
+ ActiveRecord::Base.establish_connection(current_config)
101
+ end
102
+
103
+ def bundler_groups
104
+ [:default, Jets.env.to_sym]
105
+ end
106
+
107
+ # Cannot call this for the jets new
108
+ def confirm_jets_project!
109
+ unless File.exist?("#{Jets.root}/config/application.rb")
110
+ puts "It does not look like you are running this command within a jets project. Please confirm that you are in a jets project and try again.".color(:red)
111
+ exit 1
112
+ end
113
+ end
114
+
115
+ def message
116
+ "Jets booting up in #{Jets.env.color(:green)} mode!"
117
+ end
118
+
119
+ def check_config_ru!
120
+ config_ru = File.read("#{Jets.root}/config.ru")
121
+ unless config_ru.include?("Jets.boot")
122
+ puts 'The config.ru file is missing Jets.boot. Please add Jets.boot after require "jets"'.color(:red)
123
+ puts "This was changed as made in Jets v1.1.0."
124
+ puts "To have Jets update the config.fu file for you, you can run:\n\n"
125
+ puts " jets upgrade"
126
+ exit 1
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,16 @@
1
+ class Jets::Builders
2
+ autoload :CodeBuilder, "jets/builders/code_builder"
3
+ autoload :CodeSize, "jets/builders/code_size"
4
+ autoload :GemReplacer, "jets/builders/gem_replacer"
5
+ autoload :HandlerGenerator, "jets/builders/handler_generator"
6
+ autoload :LambdaLayer, "jets/builders/lambda_layer"
7
+ autoload :Md5, "jets/builders/md5"
8
+ autoload :Md5Zip, "jets/builders/md5_zip"
9
+ autoload :Purger, "jets/builders/purger"
10
+ autoload :RackPackager, "jets/builders/rack_packager"
11
+ autoload :ReconfigureRails, "jets/builders/reconfigure_rails"
12
+ autoload :RubyPackager, "jets/builders/ruby_packager"
13
+ autoload :ShimVars, "jets/builders/shim_vars"
14
+ autoload :Tidy, "jets/builders/tidy"
15
+ autoload :Util, "jets/builders/util"
16
+ end
@@ -0,0 +1,379 @@
1
+ require "action_view"
2
+ require "fileutils"
3
+ require "net/http"
4
+ require "open-uri"
5
+ require "socket"
6
+
7
+ # Some important folders to help understand how jets builds a project:
8
+ #
9
+ # /tmp/jets: build root where different jets projects get built.
10
+ # /tmp/jets/project: each jets project gets built in a different subdirectory.
11
+ #
12
+ # The rest of the folders are subfolders under /tmp/jets/project.
13
+ #
14
+ class Jets::Builders
15
+ class CodeBuilder
16
+ include Jets::AwsServices
17
+ include Util
18
+ extend Memoist
19
+
20
+ attr_reader :full_project_path
21
+ def initialize
22
+ # Expanding to the full path and capture now.
23
+ # Dir.chdir gets called later and we'll lose this info.
24
+ @full_project_path = File.expand_path(Jets.root) + "/"
25
+ @version_purger = Purger.new
26
+ end
27
+
28
+ def build
29
+ check_ruby_version
30
+ @version_purger.purge
31
+ cache_check_message
32
+
33
+ clean_start
34
+ compile_assets # easier to do before we copy the project because node and yarn has been likely setup in the that dir
35
+ compile_rails_assets
36
+ copy_project
37
+ Dir.chdir("#{stage_area}/code") do
38
+ # These commands run from project root
39
+ code_setup
40
+ package_ruby
41
+ code_finish
42
+ end
43
+ end
44
+
45
+ # Resolves the chicken-and-egg problem with md5 checksums. The handlers need
46
+ # to reference files with the md5 checksum. The files are the:
47
+ #
48
+ # jets/code/rack-checksum.zip
49
+ # jets/code/opt-checksum.zip
50
+ #
51
+ # We compute the checksums before we generate the node shim handlers.
52
+ def calculate_md5s
53
+ Md5.compute! # populates Md5.checksums hash
54
+ end
55
+
56
+ def generate_node_shims
57
+ headline "Generating shims in the handlers folder."
58
+ # Crucial that the Dir.pwd is in the tmp_code because for
59
+ # Jets::Builders::app_files because Jets.boot set ups
60
+ # autoload_paths and this is how project classes are loaded.
61
+ Jets::Builders::HandlerGenerator.build!
62
+ end
63
+
64
+ def create_zip_files
65
+ folders = Md5.stage_folders
66
+ # Md5.stage_folders ["stage/bundled", "stage/code"]
67
+ folders.each do |folder|
68
+ zip = Md5Zip.new(folder)
69
+ if exist_on_s3?(zip.md5_name)
70
+ puts "Already exists: s3://#{s3_bucket}/jets/code/#{zip.md5_name}"
71
+ else
72
+ zip = Md5Zip.new(folder)
73
+ zip.create
74
+ end
75
+ end
76
+ end
77
+
78
+ def exist_on_s3?(filename)
79
+ s3_key = "jets/code/#{filename}"
80
+ begin
81
+ s3.head_object(bucket: s3_bucket, key: s3_key)
82
+ true
83
+ rescue Aws::S3::Errors::NotFound
84
+ false
85
+ end
86
+ end
87
+
88
+ def code_setup
89
+ reconfigure_development_webpacker
90
+ end
91
+
92
+ def code_finish
93
+ # Reconfigure code
94
+ store_s3_base_url
95
+ disable_webpacker_middleware
96
+ copy_internal_jets_code
97
+
98
+ # Code prep and zipping
99
+ check_code_size!
100
+ calculate_md5s # must be called before generate_node_shims and create_zip_files
101
+ generate_node_shims
102
+ create_zip_files
103
+ end
104
+
105
+ def check_code_size!
106
+ CodeSize.check!
107
+ end
108
+
109
+ # We copy the files into the project because we cannot require simple functions
110
+ # directly since they are wrapped by an anonymous class.
111
+ # TODO: Do this with the other files we required the same way.
112
+ def copy_internal_jets_code
113
+ files = []
114
+ files.each do |relative_path|
115
+ src = File.expand_path("../internal/#{relative_path}", File.dirname(__FILE__))
116
+ dest = "#{"#{stage_area}/code"}/#{relative_path}"
117
+ FileUtils.mkdir_p(File.dirname(dest))
118
+ FileUtils.cp(src, dest)
119
+ end
120
+ end
121
+
122
+ # Thanks https://stackoverflow.com/questions/9354595/recursively-getting-the-size-of-a-directory
123
+ # Seems to overestimate a little bit but close enough.
124
+ def dir_size(folder)
125
+ Dir.glob(File.join(folder, '**', '*'))
126
+ .select { |f| File.file?(f) }
127
+ .map{ |f| File.size(f) }
128
+ .inject(:+)
129
+ end
130
+
131
+ # Store s3 base url is needed for asset serving from s3 later. Need to package this
132
+ # as part of the code so we have a reference to it.
133
+ # At this point the minimal stack exists, so we can grab it with the AWS API.
134
+ # We do not want to grab this as part of the live request because it is slow.
135
+ def store_s3_base_url
136
+ write_s3_base_url("#{stage_area}/code/config/s3_base_url.txt")
137
+ write_s3_base_url("#{stage_area}/rack/config/s3_base_url.txt") if Jets.rack?
138
+ end
139
+
140
+ def write_s3_base_url(full_path)
141
+ FileUtils.mkdir_p(File.dirname(full_path))
142
+ IO.write(full_path, s3_base_url)
143
+ end
144
+
145
+ def s3_base_url
146
+ # Allow user to set assets.base_url
147
+ #
148
+ # Jets.application.configure do
149
+ # config.assets.base_url = "https://cloudfront.com/my/base/path"
150
+ # end
151
+ #
152
+ return Jets.config.assets.base_url if Jets.config.assets.base_url
153
+
154
+ region = Jets.aws.region
155
+
156
+ asset_base_url = region == 'us-east-1' ?
157
+ "https://s3.amazonaws.com" :
158
+ "https://s3-#{region}.amazonaws.com"
159
+ "#{asset_base_url}/#{s3_bucket}/jets" # s3_base_url
160
+ end
161
+
162
+ def s3_bucket
163
+ Jets.aws.s3_bucket
164
+ end
165
+
166
+ def disable_webpacker_middleware
167
+ full_path = "#{"#{stage_area}/code"}/config/disable-webpacker-middleware.txt"
168
+ FileUtils.mkdir_p(File.dirname(full_path))
169
+ FileUtils.touch(full_path)
170
+ end
171
+
172
+ # This happens in the current app directory not the tmp code for simplicity.
173
+ # This is because the node and yarn has likely been set up correctly there.
174
+ def compile_assets
175
+ if ENV['JETS_SKIP_ASSETS']
176
+ puts "Skip compiling assets".color(:yellow) # useful for debugging
177
+ return
178
+ end
179
+
180
+ headline "Compling assets in current project directory"
181
+ return unless webpacker_included?
182
+
183
+ sh("yarn install")
184
+ webpack_command = File.exist?("#{Jets.root}/bin/webpack") ?
185
+ "bin/webpack" :
186
+ `which webpack`.strip
187
+ sh "JETS_ENV=#{Jets.env} #{webpack_command}"
188
+ end
189
+
190
+ def webpacker_included?
191
+ # Old code, leaving around for now:
192
+ # Thanks: https://stackoverflow.com/questions/4195735/get-list-of-gems-being-used-by-a-bundler-project
193
+ # webpacker_loaded = Gem.loaded_specs.keys.include?("webpacker")
194
+ # return unless webpacker_loaded
195
+
196
+ # Checking this way because when using jets standalone for Afterburner mode we don't want to run into
197
+ # bundler gem collisions. TODO: figure out the a better way to handle the collisions.
198
+ lines = IO.readlines("#{Jets.root}/Gemfile")
199
+ lines.detect { |l| l =~ /webpacker/ }
200
+ end
201
+
202
+ # This happens in the current app directory not the tmp code for simplicity
203
+ # This is because the node likely been set up correctly there.
204
+ def compile_rails_assets
205
+ return unless Jets.rack? && rails? && !rails_api?
206
+
207
+ if ENV['JETS_SKIP_ASSETS']
208
+ puts "Skip compiling rack assets".color(:yellow) # useful for debugging
209
+ return
210
+ end
211
+
212
+ # Need to capture JETS_ROOT since can be changed by Turbo mode
213
+ jets_root = Jets.root
214
+ Bundler.with_clean_env do
215
+ # Switch gemfile for Afterburner mode
216
+ gemfile = ENV['BUNDLE_GEMFILE']
217
+ ENV['BUNDLE_GEMFILE'] = "#{jets_root}/rack/Gemfile"
218
+ sh "cd #{jets_root} && bundle install"
219
+ ENV['BUNDLE_GEMFILE'] = gemfile
220
+
221
+ rails_assets(:clobber, jets_root: jets_root)
222
+ rails_assets(:precompile, jets_root: jets_root)
223
+ end
224
+ end
225
+
226
+ def rails_assets(cmd, jets_root:)
227
+ # rake is available in both rails 4 and 5. rails command only in 5
228
+ command = "bundle exec rake assets:#{cmd} --trace"
229
+ command = "RAILS_ENV=#{Jets.env} #{command}" unless Jets.env.development?
230
+ sh("cd #{jets_root}/rack && #{command}")
231
+ end
232
+
233
+ # Rudimentary rails detection
234
+ # Duplicated in builders/reconfigure_rails.rb
235
+ def rails?
236
+ config_ru = "#{Jets.root}/rack/config.ru"
237
+ return false unless File.exist?(config_ru)
238
+ !IO.readlines(config_ru).grep(/Rails.application/).empty?
239
+ end
240
+
241
+ # Rudimentary rails api detection
242
+ # Duplicated in builders/reconfigure_rails.rb
243
+ # Another way of checking is loading a rails console and checking Rails.application.config.api_only
244
+ # Using this way for simplicity.
245
+ def rails_api?
246
+ config_app = "#{Jets.root}/rack/config/application.rb"
247
+ return false unless File.exist?(config_app)
248
+ !IO.readlines(config_app).grep(/config.api_only.*=.*true/).empty?
249
+ end
250
+
251
+ # Cleans out non-cached files like code-*.zip in Jets.build_root
252
+ # for a clean start. Also ensure that the /tmp/jets/project build root exists.
253
+ #
254
+ # Most files are kept around after the build process for inspection and
255
+ # debugging. So we have to clean out the files. But we only want to clean out
256
+ # some of the files.
257
+ def clean_start
258
+ Dir.glob("#{Jets.build_root}/code/code-*.zip").each { |f| FileUtils.rm_f(f) }
259
+ FileUtils.mkdir_p(Jets.build_root) # /tmp/jets/demo
260
+ end
261
+
262
+ # Copy project into temporary directory. Do this so we can keep the project
263
+ # directory untouched and we can also remove a bunch of unnecessary files like
264
+ # logs before zipping it up.
265
+ def copy_project
266
+ headline "Copying current project directory to temporary build area: #{"#{stage_area}/code"}"
267
+ FileUtils.rm_rf("#{build_area}/stage") # clear out from previous build's stage area
268
+ FileUtils.mkdir_p("#{build_area}/stage")
269
+ FileUtils.rm_rf("#{stage_area}/code") # remove current code folder
270
+ move_node_modules(Jets.root, Jets.build_root)
271
+ begin
272
+ # puts "cp -r #{@full_project_path} #{"#{stage_area}/code"}".color(:yellow) # uncomment to debug
273
+ Jets::Util.cp_r(@full_project_path, "#{stage_area}/code")
274
+ ensure
275
+ move_node_modules(Jets.build_root, Jets.root) # move node_modules directory back
276
+ end
277
+ end
278
+
279
+ # Move the node modules to the tmp build folder to speed up project copying.
280
+ # A little bit risky because a ctrl-c in the middle of the project copying
281
+ # results in a missing node_modules but user can easily rebuild that.
282
+ #
283
+ # Tesing shows 6.623413 vs 0.027754 speed improvement.
284
+ def move_node_modules(source_folder, dest_folder)
285
+ source = "#{source_folder}/node_modules"
286
+ dest = "#{dest_folder}/node_modules"
287
+ if File.exist?(source)
288
+ FileUtils.mv(source, dest)
289
+ end
290
+ end
291
+
292
+ # Bit hacky but this saves the user from accidentally forgetting to change this
293
+ # when they deploy a jets project in development mode
294
+ def reconfigure_development_webpacker
295
+ return unless Jets.env.development?
296
+ headline "Reconfiguring webpacker development settings for AWS Lambda."
297
+
298
+ webpacker_yml = "#{"#{stage_area}/code"}/config/webpacker.yml"
299
+ return unless File.exist?(webpacker_yml)
300
+
301
+ config = YAML.load_file(webpacker_yml)
302
+ config["development"]["compile"] = false # force this to be false for deployment
303
+ new_yaml = YAML.dump(config)
304
+ IO.write(webpacker_yml, new_yaml)
305
+ end
306
+
307
+ def ruby_packager
308
+ RubyPackager.new(tmp_code)
309
+ end
310
+ memoize :ruby_packager
311
+
312
+ def rack_packager
313
+ RackPackager.new("#{tmp_code}/rack")
314
+ end
315
+ memoize :rack_packager
316
+
317
+ def package_ruby
318
+ return if Jets.poly_only?
319
+
320
+ check_agree
321
+ ruby_packager.install
322
+ reconfigure_rails # call here after "#{stage_area}/code" is available
323
+ rack_packager.install
324
+ ruby_packager.finish # by this time we have a /tmp/jets/demo/stage/code/vendor/gems
325
+ rack_packager.finish
326
+
327
+ build_lambda_layer
328
+ end
329
+
330
+ def check_agree
331
+ agree = Jets::Gems::Agree.new
332
+ agree.prompt
333
+ end
334
+
335
+ def build_lambda_layer
336
+ return if Jets.poly_only?
337
+ lambda_layer = LambdaLayer.new
338
+ lambda_layer.build
339
+ end
340
+
341
+ # TODO: Move logic into plugin instead
342
+ def reconfigure_rails
343
+ ReconfigureRails.new("#{"#{stage_area}/code"}/rack").run
344
+ end
345
+
346
+ def cache_check_message
347
+ if File.exist?("#{Jets.build_root}/cache")
348
+ puts "The #{Jets.build_root}/cache folder exists. Incrementally re-building the jets using the cache. To clear the cache: rm -rf #{Jets.build_root}/cache"
349
+ end
350
+ end
351
+
352
+ def check_ruby_version
353
+ unless ruby_version_supported?
354
+ puts "You are using Ruby version #{RUBY_VERSION} which is not supported by Jets."
355
+ ruby_variant = Jets::RUBY_VERSION.split('.')[0..1].join('.') + '.x'
356
+ abort("Jets uses Ruby #{Jets::RUBY_VERSION}. You should use a variant of Ruby #{ruby_variant}".color(:red))
357
+ end
358
+ end
359
+
360
+ def ruby_version_supported?
361
+ pattern = /(\d+)\.(\d+)\.(\d+)/
362
+ md = RUBY_VERSION.match(pattern)
363
+ ruby = {major: md[1], minor: md[2]}
364
+ md = Jets::RUBY_VERSION.match(pattern)
365
+ jets = {major: md[1], minor: md[2]}
366
+
367
+ ruby[:major] == jets[:major] && ruby[:minor] == jets[:minor]
368
+ end
369
+
370
+ # Group all the path settings together here
371
+ def self.tmp_code
372
+ Jets::Commands::Build.tmp_code
373
+ end
374
+
375
+ def tmp_code
376
+ self.class.tmp_code
377
+ end
378
+ end
379
+ end