jets 0.2.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,151 @@
|
|
|
1
|
+
require "thor"
|
|
2
|
+
|
|
3
|
+
# Override thor's long_desc identation behavior
|
|
4
|
+
# https://github.com/erikhuda/thor/issues/398
|
|
5
|
+
class Thor
|
|
6
|
+
module Shell
|
|
7
|
+
class Basic
|
|
8
|
+
def print_wrapped(message, options = {})
|
|
9
|
+
message = "\n#{message}" unless message.starts_with?("\n")
|
|
10
|
+
stdout.puts message
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class Jets::Commands::Base < Thor
|
|
17
|
+
class << self
|
|
18
|
+
# thor_args is an array of commands. Examples:
|
|
19
|
+
# ["help"]
|
|
20
|
+
# ["dynamodb:migrate"]
|
|
21
|
+
#
|
|
22
|
+
# Same signature as RakeCommand.perform. Not using full_command.
|
|
23
|
+
def perform(full_command, thor_args)
|
|
24
|
+
config = {} # doesnt seem like config is used
|
|
25
|
+
dispatch(nil, thor_args, nil, config)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Hacky way to handle error for 'jets new' when no project name is passed in to avoid
|
|
29
|
+
# this error:
|
|
30
|
+
#
|
|
31
|
+
# required arguments 'project_name' (Thor::RequiredArgumentMissingError)
|
|
32
|
+
def dispatch(command, given_args, given_opts, config)
|
|
33
|
+
if given_args.reject{|s| s =~ /^-/} == ['new'] # user forgot to pass a project name
|
|
34
|
+
given_args = ['help', 'new']
|
|
35
|
+
end
|
|
36
|
+
super
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Track all command subclasses.
|
|
40
|
+
def subclasses
|
|
41
|
+
@subclasses ||= []
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def inherited(base)
|
|
45
|
+
super
|
|
46
|
+
|
|
47
|
+
if base.name
|
|
48
|
+
self.subclasses << base
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Useful for help menu when we need to have all the definitions loaded.
|
|
53
|
+
# Using constantize instead of require so we dont care about
|
|
54
|
+
# order. The eager load actually uses autoloading.
|
|
55
|
+
def eager_load!
|
|
56
|
+
path = File.expand_path("../../", __FILE__)
|
|
57
|
+
Dir.glob("#{path}/commands/**/*.rb").select do |path|
|
|
58
|
+
next if !File.file?(path) or path =~ /templates/ or path =~ %r{/markdown/}
|
|
59
|
+
|
|
60
|
+
class_name = path
|
|
61
|
+
.sub(/\.rb$/,'')
|
|
62
|
+
.sub(%r{.*/jets/commands}, 'jets/commands')
|
|
63
|
+
.classify
|
|
64
|
+
class_name.sub!(/Task$/, "Tasks") # special rule here for Tasks class
|
|
65
|
+
# NOTE: Weird thing where Jets::Commands::Db::Task => Thor::Command
|
|
66
|
+
# because Task is a class available to Thor I believe.
|
|
67
|
+
puts "eager_load! loading path: #{path} class_name: #{class_name}" if ENV['DEBUG']
|
|
68
|
+
class_name.constantize # dont have to worry about order.
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Fully qualifed task names. Examples:
|
|
73
|
+
# build
|
|
74
|
+
# process:controller
|
|
75
|
+
# dynamodb:migrate:down
|
|
76
|
+
def namespaced_commands
|
|
77
|
+
eager_load!
|
|
78
|
+
subclasses.map do |klass|
|
|
79
|
+
klass.all_tasks.keys.map do |task_name|
|
|
80
|
+
klass = klass.to_s.sub('Jets::Commands::','')
|
|
81
|
+
namespace = klass =~ /^Main/ ? nil : klass.underscore.gsub('/',':')
|
|
82
|
+
[namespace, task_name].compact.join(':')
|
|
83
|
+
end
|
|
84
|
+
end.flatten.sort
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Use Jets banner instead of Thor to account for namespaces in commands.
|
|
88
|
+
def banner(command, namespace = nil, subcommand = false)
|
|
89
|
+
namespace = namespace_from_class(self)
|
|
90
|
+
command_name = command.usage # set with desc when defining tht Thor class
|
|
91
|
+
namespaced_command = [namespace, command_name].compact.join(':')
|
|
92
|
+
|
|
93
|
+
"jets #{namespaced_command}"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def namespace_from_class(klass)
|
|
97
|
+
namespace = klass.to_s.sub('Jets::Commands::', '').underscore.gsub('/',':')
|
|
98
|
+
namespace unless namespace == "main"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def help_list(all=false)
|
|
102
|
+
# hack to show hidden comands when requested
|
|
103
|
+
Thor::HiddenCommand.class_eval do
|
|
104
|
+
def hidden?; false; end
|
|
105
|
+
end if all
|
|
106
|
+
|
|
107
|
+
list = []
|
|
108
|
+
eager_load!
|
|
109
|
+
subclasses.each do |klass|
|
|
110
|
+
commands = klass.printable_commands(true, false)
|
|
111
|
+
commands.reject! { |array| array[0].include?(':help') }
|
|
112
|
+
list += commands
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
list.sort_by! { |array| array[0] }
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def klass_from_namespace(namespace)
|
|
119
|
+
if namespace.nil?
|
|
120
|
+
Jets::Commands::Main
|
|
121
|
+
else
|
|
122
|
+
class_name = namespace.gsub(':','/')
|
|
123
|
+
class_name = "Jets::Commands::#{class_name.classify}"
|
|
124
|
+
class_name.constantize
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# If this fails to match then it'l just return the original full command
|
|
129
|
+
def autocomplete(full_command)
|
|
130
|
+
return nil if full_command.nil? # jets help
|
|
131
|
+
|
|
132
|
+
eager_load!
|
|
133
|
+
|
|
134
|
+
words = full_command.split(':')
|
|
135
|
+
namespace = words[0..-2].join(':') if words.size > 1
|
|
136
|
+
command = words.last
|
|
137
|
+
|
|
138
|
+
# Thor's normalize_command_name autocompletes the command but then we need to add the namespace back
|
|
139
|
+
begin
|
|
140
|
+
thor_subclass = klass_from_namespace(namespace) # could NameError
|
|
141
|
+
command = thor_subclass.normalize_command_name(command) # could Thor::AmbiguousCommandError
|
|
142
|
+
[namespace, command].compact.join(':')
|
|
143
|
+
rescue NameError
|
|
144
|
+
full_command # return original full_command
|
|
145
|
+
rescue Thor::AmbiguousCommandError => e
|
|
146
|
+
puts "Unable to autodetect the command name. #{e.message}."
|
|
147
|
+
full_command # return original full_command
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
require 'digest'
|
|
2
|
+
|
|
3
|
+
module Jets::Commands
|
|
4
|
+
class Build
|
|
5
|
+
include Jets::Timing
|
|
6
|
+
include StackInfo
|
|
7
|
+
|
|
8
|
+
def initialize(options)
|
|
9
|
+
@options = options.dup
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def run
|
|
13
|
+
puts "Building project for Lambda..."
|
|
14
|
+
return if @options[:noop]
|
|
15
|
+
# run gets called from the CLI and does not have all the stack_options yet.
|
|
16
|
+
# We compute it and change the options early here.
|
|
17
|
+
@options.merge!(stack_type: stack_type, s3_bucket: s3_bucket)
|
|
18
|
+
build
|
|
19
|
+
end
|
|
20
|
+
time :run
|
|
21
|
+
|
|
22
|
+
def build
|
|
23
|
+
build_code unless @options[:templates_only]
|
|
24
|
+
build_templates
|
|
25
|
+
end
|
|
26
|
+
time :build
|
|
27
|
+
|
|
28
|
+
def build_code
|
|
29
|
+
Jets::Builders::CodeBuilder.new.build unless @options[:noop]
|
|
30
|
+
end
|
|
31
|
+
time :build_code
|
|
32
|
+
|
|
33
|
+
def build_templates
|
|
34
|
+
if @options[:stack_type] == :minimal
|
|
35
|
+
build_minimal_template
|
|
36
|
+
else
|
|
37
|
+
build_all_templates
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
time :build_templates
|
|
41
|
+
|
|
42
|
+
def build_all_templates
|
|
43
|
+
clean_templates
|
|
44
|
+
# TODO: move this build.rb logic to cfn/builder.rb
|
|
45
|
+
## CloudFormation templates
|
|
46
|
+
puts "Building Lambda functions as CloudFormation templates."
|
|
47
|
+
# 1. Shared templates - child templates needs them
|
|
48
|
+
build_api_gateway_templates
|
|
49
|
+
# 2. Child templates - parent template needs them
|
|
50
|
+
build_child_templates
|
|
51
|
+
# 3. Finally parent template
|
|
52
|
+
build_parent_template # must be called at the end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def build_minimal_template
|
|
56
|
+
parent = Jets::Cfn::TemplateBuilders::ParentBuilder.new(@options)
|
|
57
|
+
parent.build
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def build_api_gateway_templates
|
|
61
|
+
gateway = Jets::Cfn::TemplateBuilders::ApiGatewayBuilder.new(@options)
|
|
62
|
+
gateway.build
|
|
63
|
+
deployment = Jets::Cfn::TemplateBuilders::ApiGatewayDeploymentBuilder.new(@options)
|
|
64
|
+
deployment.build
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def build_child_templates
|
|
68
|
+
app_files.each do |path|
|
|
69
|
+
build_child_template(path)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# path: app/controllers/comments_controller.rb
|
|
74
|
+
# path: app/jobs/easy_job.rb
|
|
75
|
+
def build_child_template(path)
|
|
76
|
+
class_path = path.sub(%r{.*app/\w+/},'').sub(/\.rb$/,'')
|
|
77
|
+
class_name = class_path.classify
|
|
78
|
+
class_name.constantize # load app/**/* class definition
|
|
79
|
+
|
|
80
|
+
md = path.match(%r{app/(.*?)/}) # extract: controller, job or function
|
|
81
|
+
process_class = md[1].classify
|
|
82
|
+
builder_class = "Jets::Cfn::TemplateBuilders::#{process_class}Builder".constantize
|
|
83
|
+
|
|
84
|
+
# Examples:
|
|
85
|
+
# Jets::Cfn::TemplateBuilders::JobBuilder.new(EasyJob)
|
|
86
|
+
# Jets::Cfn::TemplateBuilders::ControllerBuilder.new(PostsController)
|
|
87
|
+
# Jets::Cfn::TemplateBuilders::FunctionBuilder.new(Hello)
|
|
88
|
+
# Jets::Cfn::TemplateBuilders::FunctionBuilder.new(HelloFunction)
|
|
89
|
+
app_klass = Jets::Klass.from_path(path)
|
|
90
|
+
builder = builder_class.new(app_klass)
|
|
91
|
+
builder.build
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def build_parent_template
|
|
95
|
+
parent = Jets::Cfn::TemplateBuilders::ParentBuilder.new(@options)
|
|
96
|
+
parent.build
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def clean_templates
|
|
100
|
+
FileUtils.rm_rf("#{Jets.build_root}/templates")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def app_files
|
|
104
|
+
self.class.app_files
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Crucial that the Dir.pwd is in the tmp_app_root because for
|
|
108
|
+
# because Jets.boot set ups autoload_paths and this is how project
|
|
109
|
+
# classes are loaded.
|
|
110
|
+
# TODO: rework code so this is not the case.
|
|
111
|
+
def self.app_files
|
|
112
|
+
paths = []
|
|
113
|
+
expression = "#{Jets.root}app/**/**/*.rb"
|
|
114
|
+
Dir.glob(expression).each do |path|
|
|
115
|
+
return false unless File.file?(path)
|
|
116
|
+
next unless app_file?(path)
|
|
117
|
+
|
|
118
|
+
relative_path = path.sub(Jets.root.to_s, '')
|
|
119
|
+
# Rids of the Jets.root at beginning
|
|
120
|
+
paths << relative_path
|
|
121
|
+
end
|
|
122
|
+
paths += internal_app_files
|
|
123
|
+
paths
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def self.poly_only?
|
|
127
|
+
# Scans all the app code and look for any methods that are ruby.
|
|
128
|
+
# If any method is written in ruby then we know the app is not a
|
|
129
|
+
# soley polymorphic non-ruby app.
|
|
130
|
+
has_ruby = app_files.detect do |path|
|
|
131
|
+
# 1. remove app/controllers or app/jobs, etc
|
|
132
|
+
# 2. remove .rb extension
|
|
133
|
+
app_file = path.sub(%r{app/\w+/},'').sub(/\.rb$/,'')
|
|
134
|
+
# Internal jets controllers like Welcome and Public need a different regexp
|
|
135
|
+
app_file = app_file.sub(%r{.*lib/jets/internal/},'')
|
|
136
|
+
app_klass = app_file.classify.constantize # IE: PostsController, Jets::PublicController
|
|
137
|
+
langs = app_klass.tasks.map(&:lang)
|
|
138
|
+
langs.include?(:ruby)
|
|
139
|
+
end
|
|
140
|
+
!has_ruby
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Add internal Jets controllers if they are being used
|
|
144
|
+
def self.internal_app_files
|
|
145
|
+
paths = []
|
|
146
|
+
controllers = File.expand_path("../../internal/app/controllers/jets", __FILE__)
|
|
147
|
+
|
|
148
|
+
welcome = Jets::Router.has_controller?("Jets::WelcomeController")
|
|
149
|
+
paths << "#{controllers}/public_controller.rb" if welcome
|
|
150
|
+
|
|
151
|
+
public_catchall = Jets::Router.has_controller?("Jets::PublicController")
|
|
152
|
+
paths << "#{controllers}/welcome_controller.rb" if public_catchall
|
|
153
|
+
|
|
154
|
+
jobs = File.expand_path("../../internal/app/jobs/jets", __FILE__)
|
|
155
|
+
paths << "#{jobs}/preheat_job.rb"
|
|
156
|
+
|
|
157
|
+
paths
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def self.app_file?(path)
|
|
161
|
+
return false unless File.extname(path) == ".rb"
|
|
162
|
+
# Do not define lamda functions for the application_controller.rb or
|
|
163
|
+
# application_job.rb
|
|
164
|
+
excludes = %w[
|
|
165
|
+
application_controller.rb
|
|
166
|
+
application_job.rb
|
|
167
|
+
]
|
|
168
|
+
return false if excludes.detect { |p| path.include?(p) }
|
|
169
|
+
|
|
170
|
+
includes = %w[
|
|
171
|
+
app/controllers
|
|
172
|
+
app/jobs
|
|
173
|
+
app/functions
|
|
174
|
+
app/rules
|
|
175
|
+
]
|
|
176
|
+
return true if includes.detect { |p| path.include?(p) }
|
|
177
|
+
|
|
178
|
+
false
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def self.tmp_app_root(full_build_path=false)
|
|
182
|
+
full_build_path ? "#{Jets.build_root}/app_root" : "app_root"
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
end
|
|
186
|
+
end
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
require "base64"
|
|
2
|
+
require "json"
|
|
3
|
+
require "active_support/core_ext/string"
|
|
4
|
+
|
|
5
|
+
class Jets::Commands::Call
|
|
6
|
+
autoload :BaseGuesser, "jets/commands/call/base_guesser"
|
|
7
|
+
autoload :AutoloadGuesser, "jets/commands/call/autoload_guesser"
|
|
8
|
+
autoload :AnonymousGuesser, "jets/commands/call/anonymous_guesser"
|
|
9
|
+
autoload :Guesser, "jets/commands/call/guesser"
|
|
10
|
+
|
|
11
|
+
include Jets::AwsServices
|
|
12
|
+
|
|
13
|
+
def initialize(provided_function_name, event, options={})
|
|
14
|
+
@options = options
|
|
15
|
+
@guess = @options[:guess].nil? ? true : @options[:guess]
|
|
16
|
+
|
|
17
|
+
@provided_function_name = provided_function_name
|
|
18
|
+
@event = event
|
|
19
|
+
|
|
20
|
+
@invocation_type = options[:invocation_type] || "RequestResponse"
|
|
21
|
+
@log_type = options[:log_type] || "Tail"
|
|
22
|
+
@qualifier = @qualifier
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def function_name
|
|
26
|
+
if @guess
|
|
27
|
+
ensure_guesses_found! # possibly exits here
|
|
28
|
+
guesser.function_name # guesser adds namespace already
|
|
29
|
+
else
|
|
30
|
+
[Jets.config.project_namespace, @provided_function_name].join('-')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def run
|
|
35
|
+
@options[:local] ? local_run : remote_run
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# With local mode there is no way to bypass the guesser
|
|
39
|
+
def local_run
|
|
40
|
+
puts "Local mode enabled!"
|
|
41
|
+
ensure_guesses_found! # possibly exits here
|
|
42
|
+
klass = guesser.class_name.constantize
|
|
43
|
+
# Example:
|
|
44
|
+
# PostsController.process(event, context, meth)
|
|
45
|
+
event = JSON.load(transformed_event) || {} # transformed_event is JSON text String
|
|
46
|
+
|
|
47
|
+
fun = Jets::PolyFun.new(klass, guesser.method_name)
|
|
48
|
+
result = fun.run(event) # check the logs for polymorphic function errors
|
|
49
|
+
# Note: even though data might not always be json, the JSON.dump does a
|
|
50
|
+
# good job of not bombing, so always calling it to simplify code.
|
|
51
|
+
|
|
52
|
+
text = Jets::Util.normalize_result(result)
|
|
53
|
+
STDOUT.puts text
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def remote_run
|
|
57
|
+
puts "Calling lambda function #{function_name} on AWS" unless @options[:mute]
|
|
58
|
+
return if @options[:noop]
|
|
59
|
+
|
|
60
|
+
options = {
|
|
61
|
+
# client_context: client_context,
|
|
62
|
+
function_name: function_name,
|
|
63
|
+
invocation_type: @invocation_type, # "Event", # RequestResponse
|
|
64
|
+
log_type: @log_type, # pretty sweet
|
|
65
|
+
payload: transformed_event, # "fileb://file-path/input.json", <= JSON
|
|
66
|
+
qualifier: @qualifier, # "1",
|
|
67
|
+
}
|
|
68
|
+
begin
|
|
69
|
+
resp = lambda.invoke(options)
|
|
70
|
+
rescue Aws::Lambda::Errors::ResourceNotFoundException
|
|
71
|
+
puts "The function #{function_name} was not found. Maybe check the spelling?".colorize(:red)
|
|
72
|
+
exit
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
if @options[:show_log]
|
|
76
|
+
puts "Last 4KB of log in the x-amz-log-result header:".colorize(:green)
|
|
77
|
+
puts Base64.decode64(resp.log_result)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
add_console_link_to_clipboard
|
|
81
|
+
result = resp.payload.read # already been normalized/JSON.dump by AWS
|
|
82
|
+
unless @options[:mute_output]
|
|
83
|
+
STDOUT.puts result # only thing that goes to stdout
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def guesser
|
|
88
|
+
@guesser ||= Guesser.new(@provided_function_name)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def ensure_guesses_found!
|
|
92
|
+
unless guesser.class_name and guesser.method_name
|
|
93
|
+
puts guesser.error_message
|
|
94
|
+
exit
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# @event is String because it can be the file:// notation
|
|
99
|
+
# Returns text String for the lambda.invoke payload.
|
|
100
|
+
def transformed_event
|
|
101
|
+
text = @event
|
|
102
|
+
if text && text.include?("file://")
|
|
103
|
+
text = load_event_from_file(text)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
check_valid_json!(text)
|
|
107
|
+
|
|
108
|
+
puts "Function name: #{function_name.colorize(:green)}" unless @options[:mute]
|
|
109
|
+
return text unless function_name.include?("_controller-")
|
|
110
|
+
return text if @options[:lambda_proxy] == false
|
|
111
|
+
|
|
112
|
+
event = JSON.load(text)
|
|
113
|
+
lambda_proxy = {"queryStringParameters" => event}
|
|
114
|
+
JSON.dump(lambda_proxy)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def load_event_from_file(text)
|
|
118
|
+
path = text.gsub('file://','')
|
|
119
|
+
path = "#{Jets.root}#{path}" unless path[0..0] == '/'
|
|
120
|
+
unless File.exist?(path)
|
|
121
|
+
puts "File #{path} does not exist. Are you sure the file exists?".colorize(:red)
|
|
122
|
+
exit
|
|
123
|
+
end
|
|
124
|
+
text = IO.read(path)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Exits with friendly error message when user provides bad just
|
|
128
|
+
def check_valid_json!(text)
|
|
129
|
+
JSON.load(text)
|
|
130
|
+
rescue JSON::ParserError => e
|
|
131
|
+
puts "Invalid json provided:\n '#{text}'"
|
|
132
|
+
puts "Exiting... Please try again and provide valid json."
|
|
133
|
+
exit 1
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# So use can quickly paste this into their browser if they want to see the function
|
|
137
|
+
# via the Lambda console
|
|
138
|
+
def add_console_link_to_clipboard
|
|
139
|
+
return unless RUBY_PLATFORM =~ /darwin/
|
|
140
|
+
return unless system("type pbcopy > /dev/null")
|
|
141
|
+
|
|
142
|
+
# TODO: for add_console_link_to_clipboard get the region from the ~/.aws/config and AWS_PROFILE setting
|
|
143
|
+
region = Aws.config[:region] || 'us-east-1'
|
|
144
|
+
link = "https://console.aws.amazon.com/lambda/homepage?region=#{region}#/functions/#{function_name}?tab=configuration"
|
|
145
|
+
system("echo #{link} | pbcopy")
|
|
146
|
+
puts "Pro tip: The Lambda Console Link to the #{function_name} function has been added to your clipboard." unless @options[:mute]
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Client context must be a valid Base64-encoded JSON object
|
|
150
|
+
# Example: http://docs.aws.amazon.com/mobileanalytics/latest/ug/PutEvents.html
|
|
151
|
+
# TODO: figure out how to sign client_context
|
|
152
|
+
def client_context
|
|
153
|
+
context = {
|
|
154
|
+
"client" => {
|
|
155
|
+
"client_id" => "Jets",
|
|
156
|
+
"app_title" => "jets call cli",
|
|
157
|
+
"app_version_name" => Jets::VERSION,
|
|
158
|
+
},
|
|
159
|
+
"custom" => {},
|
|
160
|
+
"env" =>{
|
|
161
|
+
"platform" => RUBY_PLATFORM,
|
|
162
|
+
"platform_version" => RUBY_VERSION,
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
Base64.encode64(JSON.dump(context))
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# For this class redirect puts to stderr so user can pipe output to tools like
|
|
169
|
+
# jq. Example:
|
|
170
|
+
# jets call posts_controller-index '{"test":1}' | jq .
|
|
171
|
+
def puts(text)
|
|
172
|
+
$stderr.puts(text)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
end
|