jets 0.2.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.circleci/bin/commit_docs.sh +26 -0
- data/.circleci/config.yml +126 -0
- data/.codebuild/README.md +57 -0
- data/.codebuild/bin/jets +3 -0
- data/.codebuild/buildspec-base.yml +14 -0
- data/.codebuild/integration.sh +54 -0
- data/.codebuild/jets.postman_collection.json +323 -0
- data/.codebuild/scripts/install-docker.sh +12 -0
- data/.codebuild/scripts/install-dynamodb-local.sh +22 -0
- data/.codebuild/scripts/install-java.sh +20 -0
- data/.codebuild/scripts/install-node.sh +4 -0
- data/.gitignore +3 -0
- data/.gitmodules +9 -0
- data/.python-version +1 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +3 -0
- data/Dockerfile +16 -0
- data/Dockerfile.base +53 -0
- data/Gemfile +8 -1
- data/Gemfile.lock +132 -28
- data/LICENSE.txt +1 -1
- data/Procfile +2 -0
- data/README.md +116 -17
- data/Rakefile +6 -0
- data/buildspec.yml +18 -0
- data/exe/jets +14 -0
- data/jets.gemspec +31 -3
- data/lib/jets.rb +56 -8
- data/lib/jets/application.rb +121 -0
- data/lib/jets/application/middleware.rb +23 -0
- data/lib/jets/aws_services.rb +71 -0
- data/lib/jets/booter.rb +95 -0
- data/lib/jets/builders.rb +6 -0
- data/lib/jets/builders/code_builder.rb +431 -0
- data/lib/jets/builders/deducer.rb +73 -0
- data/lib/jets/builders/gem_replacer.rb +154 -0
- data/lib/jets/builders/handler_generator.rb +76 -0
- data/lib/jets/builders/node-hello.js +73 -0
- data/lib/jets/builders/node-shim.js +151 -0
- data/lib/jets/cfn.rb +5 -4
- data/lib/jets/cfn/ship.rb +178 -0
- data/lib/jets/cfn/status.rb +208 -0
- data/lib/jets/cfn/template_builders.rb +21 -0
- data/lib/jets/cfn/template_builders/api_gateway_builder.rb +73 -0
- data/lib/jets/cfn/template_builders/api_gateway_deployment_builder.rb +38 -0
- data/lib/jets/cfn/template_builders/base_child_builder.rb +38 -0
- data/lib/jets/cfn/template_builders/controller_builder.rb +107 -0
- data/lib/jets/cfn/template_builders/function_builder.rb +20 -0
- data/lib/jets/cfn/template_builders/function_properties.rb +6 -0
- data/lib/jets/cfn/template_builders/function_properties/base_builder.rb +106 -0
- data/lib/jets/cfn/template_builders/function_properties/node_builder.rb +12 -0
- data/lib/jets/cfn/template_builders/function_properties/python_builder.rb +12 -0
- data/lib/jets/cfn/template_builders/function_properties/ruby_builder.rb +13 -0
- data/lib/jets/cfn/template_builders/interface.rb +91 -0
- data/lib/jets/cfn/template_builders/job_builder.rb +63 -0
- data/lib/jets/cfn/template_builders/parent_builder.rb +97 -0
- data/lib/jets/cfn/template_builders/rule_builder.rb +55 -0
- data/lib/jets/cfn/template_builders/templates/minimal-stack.yml +45 -0
- data/lib/jets/cfn/template_mappers.rb +23 -0
- data/lib/jets/cfn/template_mappers/api_gateway_deployment_mapper.rb +48 -0
- data/lib/jets/cfn/template_mappers/api_gateway_mapper.rb +4 -0
- data/lib/jets/cfn/template_mappers/child_mapper.rb +41 -0
- data/lib/jets/cfn/template_mappers/config_rule_mapper.rb +34 -0
- data/lib/jets/cfn/template_mappers/controller_mapper.rb +36 -0
- data/lib/jets/cfn/template_mappers/events_rule_mapper.rb +40 -0
- data/lib/jets/cfn/template_mappers/function_mapper.rb +4 -0
- data/lib/jets/cfn/template_mappers/gateway_method_mapper.rb +56 -0
- data/lib/jets/cfn/template_mappers/gateway_resource_mapper.rb +62 -0
- data/lib/jets/cfn/template_mappers/job_mapper.rb +4 -0
- data/lib/jets/cfn/template_mappers/lambda_function_mapper.rb +50 -0
- data/lib/jets/cfn/template_mappers/rule_mapper.rb +5 -0
- data/lib/jets/cli.rb +180 -15
- data/lib/jets/commands.rb +22 -0
- data/lib/jets/commands/base.rb +151 -0
- data/lib/jets/commands/build.rb +186 -0
- data/lib/jets/commands/call.rb +175 -0
- data/lib/jets/commands/call/anonymous_guesser.rb +96 -0
- data/lib/jets/commands/call/autoload_guesser.rb +112 -0
- data/lib/jets/commands/call/base_guesser.rb +33 -0
- data/lib/jets/commands/call/guesser.rb +51 -0
- data/lib/jets/commands/console.rb +12 -0
- data/lib/jets/commands/db.rb +15 -0
- data/lib/jets/commands/db/environment-task.rake +3 -0
- data/lib/jets/commands/db/tasks.rb +30 -0
- data/lib/jets/commands/dbconsole.rb +131 -0
- data/lib/jets/commands/delete.rb +119 -0
- data/lib/jets/commands/deploy.rb +53 -0
- data/lib/jets/commands/dynamodb.rb +22 -0
- data/lib/jets/commands/dynamodb/migrate.rb +9 -0
- data/lib/jets/commands/dynamodb/migrator.rb +36 -0
- data/lib/jets/commands/help.rb +9 -0
- data/lib/jets/commands/help/build.md +1 -0
- data/lib/jets/commands/help/call.md +55 -0
- data/lib/jets/commands/help/console.md +4 -0
- data/lib/jets/commands/help/db/generate.md +8 -0
- data/lib/jets/commands/help/dbconsole.md +5 -0
- data/lib/jets/commands/help/delete.md +9 -0
- data/lib/jets/commands/help/deploy.md +5 -0
- data/lib/jets/commands/help/dynamodb/generate.md +50 -0
- data/lib/jets/commands/help/dynamodb/migrate.md +4 -0
- data/lib/jets/commands/help/generate.md +5 -0
- data/lib/jets/commands/help/new.md +9 -0
- data/lib/jets/commands/help/process/controller.md +6 -0
- data/lib/jets/commands/help/process/function.md +5 -0
- data/lib/jets/commands/help/process/job.md +5 -0
- data/lib/jets/commands/help/process/rule.md +5 -0
- data/lib/jets/commands/help/routes.md +3 -0
- data/lib/jets/commands/help/server.md +6 -0
- data/lib/jets/commands/help/status.md +1 -0
- data/lib/jets/commands/help/url.md +5 -0
- data/lib/jets/commands/main.rb +111 -0
- data/lib/jets/commands/markdown.rb +8 -0
- data/lib/jets/commands/markdown/creator.rb +58 -0
- data/lib/jets/commands/markdown/index.rb +27 -0
- data/lib/jets/commands/markdown/page.rb +125 -0
- data/lib/jets/commands/markdown/shell.rb +11 -0
- data/lib/jets/commands/new.rb +110 -0
- data/lib/jets/commands/rake_command.rb +61 -0
- data/lib/jets/commands/rake_tasks.rb +45 -0
- data/lib/jets/commands/sequence.rb +44 -0
- data/lib/jets/commands/stack_info.rb +30 -0
- data/lib/jets/commands/templates/skeleton/.env +2 -0
- data/lib/jets/commands/templates/skeleton/.env.development.tt +3 -0
- data/lib/jets/commands/templates/skeleton/.env.test +3 -0
- data/lib/jets/commands/templates/skeleton/.gitignore +14 -0
- data/lib/jets/commands/templates/skeleton/.jetskeep +1 -0
- data/lib/jets/commands/templates/skeleton/Gemfile.tt +27 -0
- data/lib/jets/commands/templates/skeleton/Procfile +7 -0
- data/lib/jets/commands/templates/skeleton/README.md +4 -0
- data/lib/jets/commands/templates/skeleton/Rakefile +2 -0
- data/lib/jets/commands/templates/skeleton/app/controllers/application_controller.rb +2 -0
- data/lib/jets/commands/templates/skeleton/app/helpers/application_helper.rb +2 -0
- data/lib/jets/commands/templates/skeleton/app/jobs/application_job.rb +2 -0
- data/lib/jets/commands/templates/skeleton/app/models/application_item.rb +2 -0
- data/lib/jets/commands/templates/skeleton/app/models/application_record.rb +3 -0
- data/lib/jets/commands/templates/skeleton/app/views/layouts/application.html.erb.tt +24 -0
- data/lib/jets/commands/templates/skeleton/bin/ruby_server +18 -0
- data/lib/jets/commands/templates/skeleton/bin/ruby_server.rb +2 -0
- data/lib/jets/commands/templates/skeleton/config.ru +4 -0
- data/lib/jets/commands/templates/skeleton/config/application.rb.tt +26 -0
- data/lib/jets/commands/templates/skeleton/config/database.yml.tt +27 -0
- data/lib/jets/commands/templates/skeleton/config/dynamodb.yml +25 -0
- data/lib/jets/commands/templates/skeleton/config/routes.rb +8 -0
- data/lib/jets/commands/templates/skeleton/db/.gitkeep +0 -0
- data/lib/jets/commands/templates/skeleton/public/404.html +67 -0
- data/lib/jets/commands/templates/skeleton/public/422.html +67 -0
- data/lib/jets/commands/templates/skeleton/public/500.html +66 -0
- data/lib/jets/commands/templates/skeleton/public/favicon.ico +0 -0
- data/lib/jets/commands/templates/skeleton/public/index.html.tt +79 -0
- data/lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb +18 -0
- data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-index.json +51 -0
- data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-show.json +53 -0
- data/lib/jets/commands/templates/skeleton/spec/spec_helper.rb.tt +27 -0
- data/lib/jets/commands/templates/webpacker/app/javascript/packs/application.js.tt +14 -0
- data/lib/jets/commands/templates/webpacker/app/javascript/packs/theme.scss.tt +24 -0
- data/lib/jets/commands/templates/webpacker/app/javascript/src/jets/crud.js +87 -0
- data/lib/jets/commands/url.rb +45 -0
- data/lib/jets/commands/webpacker_template.rb +19 -0
- data/lib/jets/controller.rb +9 -0
- data/lib/jets/controller/base.rb +50 -0
- data/lib/jets/controller/callbacks.rb +43 -0
- data/lib/jets/controller/layout.rb +17 -0
- data/lib/jets/controller/params.rb +53 -0
- data/lib/jets/controller/redirection.rb +55 -0
- data/lib/jets/controller/renderers.rb +5 -0
- data/lib/jets/controller/renderers/aws_proxy_renderer.rb +69 -0
- data/lib/jets/controller/renderers/base_renderer.rb +16 -0
- data/lib/jets/controller/renderers/template_renderer.rb +107 -0
- data/lib/jets/controller/rendering.rb +80 -0
- data/lib/jets/controller/request.rb +55 -0
- data/lib/jets/core.rb +81 -0
- data/lib/jets/default/application.rb +20 -0
- data/lib/jets/dotenv.rb +37 -0
- data/lib/jets/erb.rb +51 -0
- data/lib/jets/generator.rb +40 -0
- data/lib/jets/generator/templates/erb/controller/view.html.erb +2 -0
- data/lib/jets/generator/templates/erb/scaffold/_form.html.erb +39 -0
- data/lib/jets/generator/templates/erb/scaffold/edit.html.erb +6 -0
- data/lib/jets/generator/templates/erb/scaffold/index.html.erb +29 -0
- data/lib/jets/generator/templates/erb/scaffold/new.html.erb +5 -0
- data/lib/jets/generator/templates/erb/scaffold/show.html.erb +9 -0
- data/lib/jets/generator/templates/rails/assets/javascript.js +2 -0
- data/lib/jets/generator/templates/rails/assets/stylesheet.css +4 -0
- data/lib/jets/generator/templates/rails/controller/controller.rb +13 -0
- data/lib/jets/generator/templates/rails/helper/helper.rb +4 -0
- data/lib/jets/generator/templates/rails/scaffold/scaffold.css +80 -0
- data/lib/jets/generator/templates/rails/scaffold_controller/api_controller.rb +62 -0
- data/lib/jets/generator/templates/rails/scaffold_controller/controller.rb +71 -0
- data/lib/jets/internal/app/controllers/jets/public_controller.rb +30 -0
- data/lib/jets/internal/app/controllers/jets/public_controller/python/show.py +47 -0
- data/lib/jets/internal/app/controllers/jets/public_controller/python/show.pyc +0 -0
- data/lib/jets/internal/app/controllers/jets/welcome_controller.rb +22 -0
- data/lib/jets/internal/app/controllers/jets/welcome_controller/python/index.py +24 -0
- data/lib/jets/internal/app/jobs/jets/preheat_job.rb +52 -0
- data/lib/jets/job.rb +5 -0
- data/lib/jets/job/base.rb +29 -0
- data/lib/jets/job/dsl.rb +58 -0
- data/lib/jets/job/task.rb +17 -0
- data/lib/jets/klass.rb +71 -0
- data/lib/jets/lambda.rb +18 -0
- data/lib/jets/lambda/dsl.rb +153 -0
- data/lib/jets/lambda/function.rb +29 -0
- data/lib/jets/lambda/function_constructor.rb +60 -0
- data/lib/jets/lambda/functions.rb +22 -0
- data/lib/jets/lambda/task.rb +77 -0
- data/lib/jets/naming.rb +61 -0
- data/lib/jets/pascalize.rb +30 -0
- data/lib/jets/poly_fun.rb +61 -0
- data/lib/jets/poly_fun/base_executor.rb +129 -0
- data/lib/jets/poly_fun/lambda_executor.rb +16 -0
- data/lib/jets/poly_fun/node_error.rb +8 -0
- data/lib/jets/poly_fun/node_executor.rb +54 -0
- data/lib/jets/poly_fun/python_error.rb +8 -0
- data/lib/jets/poly_fun/python_executor.rb +23 -0
- data/lib/jets/preheat.rb +72 -0
- data/lib/jets/processors.rb +4 -0
- data/lib/jets/processors/deducer.rb +54 -0
- data/lib/jets/processors/main_processor.rb +57 -0
- data/lib/jets/rails_overrides.rb +4 -0
- data/lib/jets/rails_overrides/asset_tag_helper.rb +41 -0
- data/lib/jets/rails_overrides/common_methods.rb +13 -0
- data/lib/jets/rails_overrides/rendering_helper.rb +26 -0
- data/lib/jets/rails_overrides/url_helper.rb +26 -0
- data/lib/jets/route.rb +145 -0
- data/lib/jets/router.rb +115 -0
- data/lib/jets/ruby_server.rb +91 -0
- data/lib/jets/rule.rb +5 -0
- data/lib/jets/rule/base.rb +19 -0
- data/lib/jets/rule/dsl.rb +64 -0
- data/lib/jets/rule/task.rb +44 -0
- data/lib/jets/server.rb +16 -0
- data/lib/jets/server/api_gateway.rb +39 -0
- data/lib/jets/server/lambda_aws_proxy.rb +122 -0
- data/lib/jets/server/route_matcher.rb +96 -0
- data/lib/jets/server/timing_middleware.rb +16 -0
- data/lib/jets/server/webpacker_setup.rb +7 -0
- data/lib/jets/timing.rb +65 -0
- data/lib/jets/timing/report.rb +82 -0
- data/lib/jets/util.rb +7 -12
- data/lib/jets/version.rb +1 -1
- data/support/clean +3 -0
- data/support/console +3 -0
- metadata +473 -76
- data/bin/jets +0 -14
- data/lib/jets/base_controller.rb +0 -54
- data/lib/jets/build.rb +0 -46
- data/lib/jets/build/handler_generator.rb +0 -46
- data/lib/jets/build/lambda_deducer.rb +0 -23
- data/lib/jets/build/templates/handler.js +0 -149
- data/lib/jets/build/traveling_ruby.rb +0 -133
- data/lib/jets/cfn/base.rb +0 -17
- data/lib/jets/cfn/builder.rb +0 -53
- data/lib/jets/cfn/namer.rb +0 -30
- data/lib/jets/cli/help.rb +0 -19
- data/lib/jets/command.rb +0 -25
- data/lib/jets/process.rb +0 -18
- data/lib/jets/process/base_processor.rb +0 -23
- data/lib/jets/process/controller_processor.rb +0 -36
- data/lib/jets/process/help.rb +0 -11
- data/lib/jets/process/processor_deducer.rb +0 -51
- data/lib/jets/project.rb +0 -23
- data/notes/design.md +0 -107
- data/notes/faq.md +0 -3
- data/notes/lambda_ruby_info.md +0 -34
- data/notes/traveling-ruby-packaging-jets.md +0 -26
- data/notes/traveling-ruby-packaging.md +0 -103
- data/notes/traveling-ruby-structure.md +0 -6
- data/notes/traveling-ruby.md +0 -82
- data/spec/fixtures/classes.rb +0 -5
- data/spec/fixtures/project/.gitignore +0 -3
- data/spec/fixtures/project/.ruby-version +0 -1
- data/spec/fixtures/project/Gemfile +0 -4
- data/spec/fixtures/project/Gemfile.lock +0 -23
- data/spec/fixtures/project/app/controllers/application_controller.rb +0 -2
- data/spec/fixtures/project/app/controllers/posts_controller.rb +0 -12
- data/spec/fixtures/project/bin/jets +0 -22
- data/spec/fixtures/project/config/routes.rb +0 -6
- data/spec/fixtures/project/handlers/controllers/posts.js +0 -212
- data/spec/lib/cli_spec.rb +0 -20
- data/spec/lib/jets/base_controller_spec.rb +0 -18
- data/spec/lib/jets/build/handler_generator_spec.rb +0 -20
- data/spec/lib/jets/build/lambda_deducer_spec.rb +0 -15
- data/spec/lib/jets/build_spec.rb +0 -34
- data/spec/lib/jets/cfn/builder_spec.rb +0 -18
- data/spec/lib/jets/cfn/namer_spec.rb +0 -16
- data/spec/lib/jets/process/controller_processor_spec.rb +0 -22
- data/spec/lib/jets/process/infer_spec.rb +0 -24
- data/spec/lib/jets/process_spec.rb +0 -18
- data/spec/lib/jets/project_spec.rb +0 -14
- data/spec/spec_helper.rb +0 -28
@@ -0,0 +1,154 @@
|
|
1
|
+
# def extract_gems
|
2
|
+
# headline "Replacing compiled gems with Lambda Linux versions."
|
3
|
+
# Lambdagem::Extract::Gem.new(JETS_RUBY_VERSION,
|
4
|
+
# s3: "lambdagems",
|
5
|
+
# dest: full(cache_area),
|
6
|
+
# ).run
|
7
|
+
# end
|
8
|
+
class Jets::Builders
|
9
|
+
class GemReplacer
|
10
|
+
extend Memoist
|
11
|
+
attr_reader :missing_gems
|
12
|
+
def initialize(ruby_version, options)
|
13
|
+
@ruby_version = ruby_version
|
14
|
+
@options = options
|
15
|
+
@missing_gems = [] # keeps track of gems that are not found in any of the lambdagems sources
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
# Checks whether the gem is found on at least one of the lambdagems sources.
|
20
|
+
# By the time the loop finishes, found_gems will hold a map of gem names to found
|
21
|
+
# url sources. Example:
|
22
|
+
#
|
23
|
+
# found_gems = {
|
24
|
+
# "nokogiri-1.8.4" => "https://lambdagems.com",
|
25
|
+
# "pg-0.21.0" => "https://anothersource.com",
|
26
|
+
# }
|
27
|
+
#
|
28
|
+
found_gems = {}
|
29
|
+
compiled_gems.each do |gem_name|
|
30
|
+
gem_exists = false
|
31
|
+
Jets.config.lambdagems.sources.each do |source|
|
32
|
+
exist = Lambdagem::Exist.new(lambdagems_url: source)
|
33
|
+
found = exist.check(gem_name)
|
34
|
+
# gem exists on at least of the lambdagem sources
|
35
|
+
if found
|
36
|
+
gem_exists = true
|
37
|
+
found_gems[gem_name] = source
|
38
|
+
break
|
39
|
+
end
|
40
|
+
end
|
41
|
+
unless gem_exists
|
42
|
+
@missing_gems << gem_name
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Exits early if not all the linux gems are available.
|
47
|
+
# It better to error now than deploy a broken package to AWS Lambda.
|
48
|
+
# Provide users with message about using their own lambdagems source.
|
49
|
+
unless @missing_gems.empty?
|
50
|
+
puts missing_gems_message
|
51
|
+
exit 1
|
52
|
+
end
|
53
|
+
|
54
|
+
# Reaching here means we can download and extract the gems
|
55
|
+
found_gems.each do |gem_name, source|
|
56
|
+
gem_extractor = Lambdagem::Extract::Gem.new(gem_name, @options.merge(lambdagems_url: source))
|
57
|
+
gem_extractor.run
|
58
|
+
end
|
59
|
+
|
60
|
+
tidy
|
61
|
+
end
|
62
|
+
|
63
|
+
def missing_gems_message
|
64
|
+
template = <<-EOL
|
65
|
+
Your project requires compiled gems were not available in any of your lambdagems sources. Unavailable pre-compiled gems:
|
66
|
+
<% missing_gems.each do |gem| %>
|
67
|
+
* <%= gem -%>
|
68
|
+
<% end %>
|
69
|
+
|
70
|
+
Your current lambdagems sources:
|
71
|
+
<% Jets.config.lambdagems.sources.map do |source| %>
|
72
|
+
* <%= source -%>
|
73
|
+
<% end %>
|
74
|
+
|
75
|
+
Jets is unable to build a deployment package that will work on AWS Lambda without the required pre-compiled gems. To remedy this, you can:
|
76
|
+
|
77
|
+
* Build the gem yourself and add it to your own custom lambdagems sources. Refer to the Lambda Gems Docs: http://rubyonjets.com/docs/lambdagems
|
78
|
+
* Wait until it added to lambdagems.com. No need to report this to us, as we've already been notified.
|
79
|
+
* Use another gem that does not require compilation.
|
80
|
+
|
81
|
+
Compiled gems usually take some time to figure out how to build as they each depend on different libraries and packages. We make an effort add new gems as soon as we can. You can support us by going to: http://rubyonjets.com/support-jets/
|
82
|
+
EOL
|
83
|
+
erb = ERB.new(template, nil, '-') # trim mode https://stackoverflow.com/questions/4632879/erb-template-removing-the-trailing-line
|
84
|
+
erb.result(binding)
|
85
|
+
end
|
86
|
+
|
87
|
+
# remove unnecessary files to reduce package size
|
88
|
+
def tidy
|
89
|
+
tidy_gems("#{@options[:project_root]}/bundled/gems/ruby/*/gems/*")
|
90
|
+
tidy_gems("#{@options[:project_root]}/bundled/gems/ruby/*/bundler/gems/*")
|
91
|
+
end
|
92
|
+
|
93
|
+
def tidy_gems(gems_path)
|
94
|
+
Dir.glob(gems_path).each do |gem_path|
|
95
|
+
tidy_gem(gem_path)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Clean up some unneeded files to try to keep the package size down
|
100
|
+
# In a generated jets app this made a decent 9% difference:
|
101
|
+
# 175M test2
|
102
|
+
# 191M test3
|
103
|
+
def tidy_gem(path)
|
104
|
+
# remove top level tests and cache folders
|
105
|
+
Dir.glob("#{path}/*").each do |path|
|
106
|
+
next unless File.directory?(path)
|
107
|
+
folder = File.basename(path)
|
108
|
+
if %w[test tests spec features benchmark cache doc].include?(folder)
|
109
|
+
FileUtils.rm_rf(path)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
Dir.glob("#{path}/**/*").each do |path|
|
114
|
+
next unless File.file?(path)
|
115
|
+
ext = File.extname(path)
|
116
|
+
if %w[.rdoc .md .markdown].include?(ext) or
|
117
|
+
path =~ /LICENSE|CHANGELOG|README/
|
118
|
+
FileUtils.rm_f(path)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# If there are subfolders compiled_gem_paths might have files deeper
|
124
|
+
# in the directory tree. So lets grab the gem name and figure out the
|
125
|
+
# unique paths of the compiled gems from there.
|
126
|
+
def compiled_gems
|
127
|
+
compiled_gem_paths.map { |p| gem_name_from_path(p) }.uniq# + ["whatever-0.0.1"]
|
128
|
+
end
|
129
|
+
memoize :compiled_gems
|
130
|
+
|
131
|
+
# Use pre-compiled gem because the gem could have development header shared
|
132
|
+
# object file dependencies. The shared dependencies are packaged up as part
|
133
|
+
# of the pre-compiled gem so it is available in the Lambda execution environment.
|
134
|
+
#
|
135
|
+
# Example paths:
|
136
|
+
# Macosx:
|
137
|
+
# bundled/gems/ruby/2.5.0/extensions/x86_64-darwin-16/2.5.0-static/nokogiri-1.8.1
|
138
|
+
# bundled/gems/ruby/2.5.0/extensions/x86_64-darwin-16/2.5.0-static/byebug-9.1.0
|
139
|
+
# Official AWS Lambda Linux AMI:
|
140
|
+
# bundled/gems/ruby/2.5.0/extensions/x86_64-linux/2.5.0-static/nokogiri-1.8.1
|
141
|
+
# Circleci Ubuntu based Linux:
|
142
|
+
# bundled/gems/ruby/2.5.0/extensions/x86_64-linux/2.5.0/pg-0.21.0
|
143
|
+
def compiled_gem_paths
|
144
|
+
Dir.glob("#{Jets.build_root}/cache/bundled/gems/ruby/*/extensions/**/**/*.{so,bundle}")
|
145
|
+
end
|
146
|
+
|
147
|
+
# Input: bundled/gems/ruby/2.5.0/extensions/x86_64-darwin-16/2.5.0-static/byebug-9.1.0
|
148
|
+
# Output: byebug-9.1.0
|
149
|
+
def gem_name_from_path(path)
|
150
|
+
regexp = /gems\/ruby\/\d+\.\d+\.\d+\/extensions\/.*?\/.*?\/(.*?)\//
|
151
|
+
gem_name = path.match(regexp)[1]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "erb"
|
3
|
+
|
4
|
+
# Example:
|
5
|
+
#
|
6
|
+
# Jets::Builders::HandlerGenerator.new(
|
7
|
+
# "PostsController",
|
8
|
+
# :create, :update
|
9
|
+
# )
|
10
|
+
class Jets::Builders
|
11
|
+
class HandlerGenerator
|
12
|
+
def initialize(path)
|
13
|
+
@path = path
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate
|
17
|
+
poly_shims
|
18
|
+
ruby_node_shim
|
19
|
+
end
|
20
|
+
|
21
|
+
def poly_shims
|
22
|
+
missing = []
|
23
|
+
|
24
|
+
deducer = Jets::Builders::Deducer.new(@path)
|
25
|
+
poly_tasks = deducer.klass.tasks.select { |t| t.lang != :ruby }
|
26
|
+
poly_tasks.each do |task|
|
27
|
+
source_path = get_source_path(@path, task)
|
28
|
+
if File.exist?(source_path)
|
29
|
+
native_function(@path, task)
|
30
|
+
else
|
31
|
+
missing << source_path
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
unless missing.empty?
|
36
|
+
puts "ERROR: Missing source files. Please make sure these source files exist or remove their declarations".colorize(:red)
|
37
|
+
puts missing
|
38
|
+
exit 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_source_path(original_path, task)
|
43
|
+
folder = original_path.sub(/\.rb$/,'')
|
44
|
+
lang_folder = "#{folder}/#{task.lang}"
|
45
|
+
root = Jets.root unless original_path.include?("lib/jets/internal")
|
46
|
+
"#{root}#{lang_folder}/#{task.meth}#{task.lang_ext}"
|
47
|
+
end
|
48
|
+
|
49
|
+
# Builds and copies over the native source code: python or node
|
50
|
+
def native_function(original_path, task)
|
51
|
+
source_path = get_source_path(original_path, task)
|
52
|
+
# Handler: handlers/controllers/posts_controller.handle
|
53
|
+
dest_path = "#{tmp_app_root}/#{task.handler_path}"
|
54
|
+
FileUtils.mkdir_p(File.dirname(dest_path))
|
55
|
+
FileUtils.cp(source_path, dest_path)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Generates one big node shim for a entire controller.
|
59
|
+
def ruby_node_shim
|
60
|
+
deducer = Jets::Builders::Deducer.new(@path)
|
61
|
+
|
62
|
+
js_path = "#{tmp_app_root}/#{deducer.js_path}"
|
63
|
+
FileUtils.mkdir_p(File.dirname(js_path))
|
64
|
+
|
65
|
+
template_path = File.expand_path('../node-shim.js', __FILE__)
|
66
|
+
result = Jets::Erb.result(template_path, deducer: deducer)
|
67
|
+
|
68
|
+
IO.write(js_path, result)
|
69
|
+
end
|
70
|
+
|
71
|
+
# TODO: move CodeBuilder.tmp_app_root to a common level for HandlerGenerator and CodeBuilder
|
72
|
+
def tmp_app_root
|
73
|
+
"#{Jets.build_root}/#{CodeBuilder.tmp_app_root}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
'use strict';
|
2
|
+
console.log('Loading hello world function');
|
3
|
+
|
4
|
+
// https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html
|
5
|
+
|
6
|
+
exports.handler = function(event, context, callback) {
|
7
|
+
let name = "you";
|
8
|
+
let city = 'World';
|
9
|
+
let time = 'day';
|
10
|
+
let day = '';
|
11
|
+
let responseCode = 200;
|
12
|
+
console.log("request: " + JSON.stringify(event));
|
13
|
+
|
14
|
+
// This is a simple illustration of app-specific logic to return the response.
|
15
|
+
// Although only 'event.queryStringParameters' are used here, other request data,
|
16
|
+
// such as 'event.headers', 'event.pathParameters', 'event.body', 'event.stageVariables',
|
17
|
+
// and 'event.requestContext' can be used to determine what response to return.
|
18
|
+
//
|
19
|
+
if (event.queryStringParameters !== null && event.queryStringParameters !== undefined) {
|
20
|
+
if (event.queryStringParameters.name !== undefined &&
|
21
|
+
event.queryStringParameters.name !== null &&
|
22
|
+
event.queryStringParameters.name !== "") {
|
23
|
+
console.log("Received name: " + event.queryStringParameters.name);
|
24
|
+
name = event.queryStringParameters.name;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
if (event.pathParameters !== null && event.pathParameters !== undefined) {
|
29
|
+
if (event.pathParameters.proxy !== undefined &&
|
30
|
+
event.pathParameters.proxy !== null &&
|
31
|
+
event.pathParameters.proxy !== "") {
|
32
|
+
console.log("Received proxy: " + event.pathParameters.proxy);
|
33
|
+
city = event.pathParameters.proxy;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
if (event.headers !== null && event.headers !== undefined) {
|
38
|
+
if (event.headers['day'] !== undefined && event.headers['day'] !== null && event.headers['day'] !== "") {
|
39
|
+
console.log("Received day: " + event.headers.day);
|
40
|
+
day = event.headers.day;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
if (event.body !== null && event.body !== undefined) {
|
45
|
+
let body = JSON.parse(event.body)
|
46
|
+
if (body.time)
|
47
|
+
time = body.time;
|
48
|
+
}
|
49
|
+
|
50
|
+
let greeting = 'Good ' + time + ', ' + name + ' of ' + city + '. ';
|
51
|
+
if (day) greeting += 'Happy ' + day + '!';
|
52
|
+
|
53
|
+
var responseBody = {
|
54
|
+
message: greeting,
|
55
|
+
input: event
|
56
|
+
};
|
57
|
+
|
58
|
+
// The output from a Lambda proxy integration must be
|
59
|
+
// of the following JSON object. The 'headers' property
|
60
|
+
// is for custom response headers in addition to standard
|
61
|
+
// ones. The 'body' property must be a JSON string. For
|
62
|
+
// base64-encoded payload, you must also set the 'isBase64Encoded'
|
63
|
+
// property to 'true'.
|
64
|
+
var response = {
|
65
|
+
statusCode: responseCode,
|
66
|
+
headers: {
|
67
|
+
"x-custom-header" : "my custom header value"
|
68
|
+
},
|
69
|
+
body: JSON.stringify(responseBody)
|
70
|
+
};
|
71
|
+
console.log("response: " + JSON.stringify(response))
|
72
|
+
callback(null, response);
|
73
|
+
};
|
@@ -0,0 +1,151 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
const spawn = require('child_process').spawn;
|
4
|
+
const fs = require('fs');
|
5
|
+
const TMP_LOG_PATH = '/tmp/shim-subprocess.log';
|
6
|
+
const subprocess_out = fs.openSync(TMP_LOG_PATH, 'a');
|
7
|
+
const subprocess_err = fs.openSync(TMP_LOG_PATH, 'a');
|
8
|
+
|
9
|
+
function once() {
|
10
|
+
// Uncomment fake run once locally. No need to do this on real lambda environment.
|
11
|
+
// var filename = '/tmp/once.txt';
|
12
|
+
// if (fs.existsSync(filename)) {
|
13
|
+
// return;
|
14
|
+
// }
|
15
|
+
// fs.closeSync(fs.openSync(filename, 'w'));
|
16
|
+
|
17
|
+
// start tcp server and detach
|
18
|
+
const subprocess = spawn('bin/ruby_server', {
|
19
|
+
detached: true,
|
20
|
+
stdio: [ 'ignore', subprocess_out, subprocess_err ]
|
21
|
+
});
|
22
|
+
subprocess.on('error', function(err) {
|
23
|
+
log('bin/ruby_server error', err);
|
24
|
+
});
|
25
|
+
|
26
|
+
subprocess.on('close', function(exit_code) {
|
27
|
+
log("Subprocess was shut down or deattached!");
|
28
|
+
});
|
29
|
+
|
30
|
+
// prevent the parent from waiting for a subprocess to exit
|
31
|
+
// https://nodejs.org/api/child_process.html
|
32
|
+
subprocess.unref();
|
33
|
+
}
|
34
|
+
|
35
|
+
once();
|
36
|
+
|
37
|
+
// Produces an Error object that displays in the AWS Lambda test console nicely.
|
38
|
+
// The backtrace are the ruby lines, not the nodejs shim error lines.
|
39
|
+
// The json payload in the Lambda console looks something like this:
|
40
|
+
//
|
41
|
+
// {
|
42
|
+
// "errorMessage": "RubyError: RuntimeError: error in submethod",
|
43
|
+
// "errorType": "RubyError",
|
44
|
+
// "stackTrace": [
|
45
|
+
// [
|
46
|
+
// "line1",
|
47
|
+
// "line2",
|
48
|
+
// "line3"
|
49
|
+
// ]
|
50
|
+
// ]
|
51
|
+
// }
|
52
|
+
//
|
53
|
+
function rubyError(resp) {
|
54
|
+
var name = resp["errorType"]
|
55
|
+
var message = resp["errorMessage"]
|
56
|
+
var lines = resp["stackTrace"]
|
57
|
+
|
58
|
+
var error = new Error(message)
|
59
|
+
error.name = name
|
60
|
+
error.stack = lines.join("\n")
|
61
|
+
return error
|
62
|
+
}
|
63
|
+
|
64
|
+
// On AWS Lambda, we can log to either stdout or stderr and we're okay.
|
65
|
+
// But locally when we're testing the shim, the log output can mess up piping
|
66
|
+
// to jq. So not logging to stdout because when testing this shim locally the
|
67
|
+
// stdout output messes up a pipe to jq.
|
68
|
+
function log(text) {
|
69
|
+
console.error(text);
|
70
|
+
}
|
71
|
+
|
72
|
+
////////////////////////////
|
73
|
+
// main logic for handler
|
74
|
+
const net = require('net');
|
75
|
+
const PORT = 8080;
|
76
|
+
const HOST = '127.0.0.1';
|
77
|
+
|
78
|
+
function request(event, handler, callback) {
|
79
|
+
log("event:");
|
80
|
+
log(event);
|
81
|
+
var client = new net.Socket();
|
82
|
+
client.connect(PORT, HOST, function() {
|
83
|
+
log('Connected to socket');
|
84
|
+
client.write(JSON.stringify(event));
|
85
|
+
client.write("\r\n") // important: \r\n is how server knows input is done
|
86
|
+
client.write(handler);
|
87
|
+
client.write("\r\n") // important: \r\n is how server knows input is done
|
88
|
+
});
|
89
|
+
|
90
|
+
// string concatation in javascript is faster than array concatation
|
91
|
+
// http://bit.ly/2gBMDs6
|
92
|
+
var stdout_buffer = ""; // stdout buffer
|
93
|
+
client.on('data', function(buffer) {
|
94
|
+
log('Received data from socket: ' + buffer);
|
95
|
+
stdout_buffer += buffer;
|
96
|
+
});
|
97
|
+
|
98
|
+
client.on('close', function() {
|
99
|
+
log('Socket connection closed');
|
100
|
+
// If server is not yet running, socket immediately closes and stdout_buffer
|
101
|
+
// is still empty. Return right away for this case, so request can retry.
|
102
|
+
if (stdout_buffer == "") {
|
103
|
+
return;
|
104
|
+
}
|
105
|
+
|
106
|
+
var resp = JSON.parse(stdout_buffer);
|
107
|
+
if (resp["errorMessage"]) {
|
108
|
+
// Customize error object for lambda format
|
109
|
+
var error = rubyError(resp)
|
110
|
+
callback(error);
|
111
|
+
} else {
|
112
|
+
callback(null, resp);
|
113
|
+
}
|
114
|
+
client.destroy(); // kill client after server's response
|
115
|
+
});
|
116
|
+
|
117
|
+
client.on('error', function(error) {
|
118
|
+
log("Socket error %o", error);
|
119
|
+
log("Retrying request");
|
120
|
+
setTimeout(function() {
|
121
|
+
if (fs.existsSync(TMP_LOG_PATH)) {
|
122
|
+
var contents = fs.readFileSync(TMP_LOG_PATH, 'utf8');
|
123
|
+
log("subprocess output:");
|
124
|
+
log(contents);
|
125
|
+
}
|
126
|
+
request(event, handler, callback);
|
127
|
+
}, 500);
|
128
|
+
});
|
129
|
+
};
|
130
|
+
|
131
|
+
<% @deducer.functions.each do |function_name| %>
|
132
|
+
exports.<%= function_name %> = (event, context, callback) => {
|
133
|
+
request(event, "<%= @deducer.handler_for(function_name) %>", callback);
|
134
|
+
}
|
135
|
+
<% end %>
|
136
|
+
|
137
|
+
// for local testing
|
138
|
+
if (require.main === module) {
|
139
|
+
// fake event and context
|
140
|
+
var event = {"hello": "world"}
|
141
|
+
// var event = {"body": {"hello": "world"}} // API Gateway wrapper structure
|
142
|
+
var context = {"fake": "context"}
|
143
|
+
exports.<%= @deducer.functions.first %>(event, context, (error, message) => {
|
144
|
+
log("\nLOCAL TESTING OUTPUT")
|
145
|
+
if (error) {
|
146
|
+
console.log("error message: %o", error)
|
147
|
+
} else {
|
148
|
+
console.log(JSON.stringify(message)) // stringify
|
149
|
+
}
|
150
|
+
})
|
151
|
+
}
|