jets 0.0.1 → 0.2.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 +4 -4
- data/.ruby-version +1 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +63 -0
- data/Guardfile +19 -9
- data/README.md +9 -16
- data/jets.gemspec +11 -7
- data/lib/jets.rb +11 -0
- data/lib/jets/base_controller.rb +54 -0
- data/lib/jets/build.rb +46 -0
- data/lib/jets/build/handler_generator.rb +46 -0
- data/lib/jets/build/lambda_deducer.rb +23 -0
- data/lib/jets/build/templates/handler.js +149 -0
- data/lib/jets/build/traveling_ruby.rb +133 -0
- data/lib/jets/cfn.rb +5 -0
- data/lib/jets/cfn/base.rb +17 -0
- data/lib/jets/cfn/builder.rb +53 -0
- data/lib/jets/cfn/namer.rb +30 -0
- data/lib/jets/cli.rb +10 -6
- data/lib/jets/cli/help.rb +8 -2
- data/lib/jets/process.rb +18 -0
- data/lib/jets/process/base_processor.rb +23 -0
- data/lib/jets/process/controller_processor.rb +36 -0
- data/lib/jets/process/help.rb +11 -0
- data/lib/jets/process/processor_deducer.rb +51 -0
- data/lib/jets/project.rb +23 -0
- data/lib/jets/util.rb +13 -0
- data/lib/jets/version.rb +1 -1
- data/notes/design.md +107 -0
- data/notes/faq.md +3 -0
- data/notes/lambda_ruby_info.md +34 -0
- data/notes/traveling-ruby-packaging-jets.md +26 -0
- data/notes/traveling-ruby-packaging.md +103 -0
- data/notes/traveling-ruby-structure.md +6 -0
- data/notes/traveling-ruby.md +82 -0
- data/spec/fixtures/classes.rb +5 -0
- data/spec/fixtures/project/.gitignore +3 -0
- data/spec/fixtures/project/.ruby-version +1 -0
- data/spec/fixtures/project/Gemfile +4 -0
- data/spec/fixtures/project/Gemfile.lock +23 -0
- data/spec/fixtures/project/app/controllers/application_controller.rb +2 -0
- data/spec/fixtures/project/app/controllers/posts_controller.rb +12 -0
- data/spec/fixtures/project/bin/jets +22 -0
- data/spec/fixtures/project/config/routes.rb +6 -0
- data/spec/fixtures/project/handlers/controllers/posts.js +212 -0
- data/spec/lib/cli_spec.rb +5 -4
- data/spec/lib/jets/base_controller_spec.rb +18 -0
- data/spec/lib/jets/build/handler_generator_spec.rb +20 -0
- data/spec/lib/jets/build/lambda_deducer_spec.rb +15 -0
- data/spec/lib/jets/build_spec.rb +34 -0
- data/spec/lib/jets/cfn/builder_spec.rb +18 -0
- data/spec/lib/jets/cfn/namer_spec.rb +16 -0
- data/spec/lib/jets/process/controller_processor_spec.rb +22 -0
- data/spec/lib/jets/process/infer_spec.rb +24 -0
- data/spec/lib/jets/process_spec.rb +18 -0
- data/spec/lib/jets/project_spec.rb +14 -0
- data/spec/spec_helper.rb +8 -2
- metadata +82 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1960e461a36b47bd872fe91a5c58569569c4a1e9
|
|
4
|
+
data.tar.gz: cb9d30dfd4cf492849a3927afcaf6d4297defa90
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 65362fbb12abc9d06b55af768278ecaaeebcd5467d444c97a2de4b733cf802daa078f81b3d493e1ca383e7e8a858aa5fd54e1da11e28bc2dcd88e112df56b608
|
|
7
|
+
data.tar.gz: c6083ef3edcc89f4354d3f84b4cd2b8c079fcad914164f9c1862d8055f10df4fdc8d9c489e54141b1d9d51ca85d1a69c09e054782e14595f8b8d65ae7f26fed0
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.2.2
|
data/CHANGELOG.md
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
jets (0.2.0)
|
|
5
|
+
activesupport
|
|
6
|
+
colorize
|
|
7
|
+
hashie
|
|
8
|
+
thor
|
|
9
|
+
|
|
10
|
+
GEM
|
|
11
|
+
remote: https://rubygems.org/
|
|
12
|
+
specs:
|
|
13
|
+
activesupport (5.1.4)
|
|
14
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
15
|
+
i18n (~> 0.7)
|
|
16
|
+
minitest (~> 5.1)
|
|
17
|
+
tzinfo (~> 1.1)
|
|
18
|
+
byebug (9.1.0)
|
|
19
|
+
codeclimate-test-reporter (1.0.8)
|
|
20
|
+
simplecov (<= 0.13)
|
|
21
|
+
colorize (0.8.1)
|
|
22
|
+
concurrent-ruby (1.0.5)
|
|
23
|
+
diff-lcs (1.3)
|
|
24
|
+
docile (1.1.5)
|
|
25
|
+
hashie (3.5.6)
|
|
26
|
+
i18n (0.9.0)
|
|
27
|
+
concurrent-ruby (~> 1.0)
|
|
28
|
+
json (2.1.0)
|
|
29
|
+
minitest (5.10.3)
|
|
30
|
+
rake (12.2.1)
|
|
31
|
+
rspec (3.7.0)
|
|
32
|
+
rspec-core (~> 3.7.0)
|
|
33
|
+
rspec-expectations (~> 3.7.0)
|
|
34
|
+
rspec-mocks (~> 3.7.0)
|
|
35
|
+
rspec-core (3.7.0)
|
|
36
|
+
rspec-support (~> 3.7.0)
|
|
37
|
+
rspec-expectations (3.7.0)
|
|
38
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
39
|
+
rspec-support (~> 3.7.0)
|
|
40
|
+
rspec-mocks (3.7.0)
|
|
41
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
42
|
+
rspec-support (~> 3.7.0)
|
|
43
|
+
rspec-support (3.7.0)
|
|
44
|
+
simplecov (0.13.0)
|
|
45
|
+
docile (~> 1.1.0)
|
|
46
|
+
json (>= 1.8, < 3)
|
|
47
|
+
simplecov-html (~> 0.10.0)
|
|
48
|
+
simplecov-html (0.10.2)
|
|
49
|
+
thor (0.20.0)
|
|
50
|
+
thread_safe (0.3.6)
|
|
51
|
+
tzinfo (1.2.3)
|
|
52
|
+
thread_safe (~> 0.1)
|
|
53
|
+
|
|
54
|
+
PLATFORMS
|
|
55
|
+
ruby
|
|
56
|
+
|
|
57
|
+
DEPENDENCIES
|
|
58
|
+
bundler
|
|
59
|
+
byebug
|
|
60
|
+
codeclimate-test-reporter
|
|
61
|
+
jets!
|
|
62
|
+
rake
|
|
63
|
+
rspec
|
data/Guardfile
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
|
-
guard "
|
|
2
|
-
watch(%r{^spec/.+_spec\.rb$})
|
|
3
|
-
watch(%r{^lib/(.+)\.rb$}) { "spec/jets_spec.rb" }
|
|
4
|
-
watch(%r{^lib/jets/(.+)\.rb$}) { "spec/jets_spec.rb" }
|
|
5
|
-
watch("spec/spec_helper.rb") { "spec/jets_spec.rb" }
|
|
6
|
-
watch(%r{^lib/jets/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
guard "bundler" do
|
|
1
|
+
guard "bundler", cmd: "bundle" do
|
|
10
2
|
watch("Gemfile")
|
|
11
3
|
watch(/^.+\.gemspec/)
|
|
12
4
|
end
|
|
5
|
+
|
|
6
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
|
7
|
+
require "guard/rspec/dsl"
|
|
8
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
|
9
|
+
|
|
10
|
+
# RSpec files
|
|
11
|
+
rspec = dsl.rspec
|
|
12
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
|
13
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
|
14
|
+
watch(rspec.spec_files)
|
|
15
|
+
|
|
16
|
+
# Ruby files
|
|
17
|
+
ruby = dsl.ruby
|
|
18
|
+
puts "ruby.lib_files #{ruby.lib_files.inspect}"
|
|
19
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
|
20
|
+
|
|
21
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
|
22
|
+
end
|
data/README.md
CHANGED
|
@@ -12,28 +12,21 @@ TODO: Write a gem description
|
|
|
12
12
|
|
|
13
13
|
Add this line to your application's Gemfile:
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
```sh
|
|
16
|
+
gem "jets"
|
|
17
|
+
```
|
|
16
18
|
|
|
17
19
|
And then execute:
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
```sh
|
|
22
|
+
$ bundle
|
|
23
|
+
```
|
|
20
24
|
|
|
21
25
|
Or install it yourself as:
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<pre>
|
|
28
|
-
git clone https://github.com/tongueroo/jets.git
|
|
29
|
-
mv jets <project_name>
|
|
30
|
-
cd <project_name>
|
|
31
|
-
rake rename
|
|
32
|
-
rm -rf .git
|
|
33
|
-
git init
|
|
34
|
-
git add .
|
|
35
|
-
git commit -m "init commit"
|
|
36
|
-
</pre>
|
|
27
|
+
```
|
|
28
|
+
$ gem install jets
|
|
29
|
+
```
|
|
37
30
|
|
|
38
31
|
## Contributing
|
|
39
32
|
|
data/jets.gemspec
CHANGED
|
@@ -8,9 +8,9 @@ Gem::Specification.new do |spec|
|
|
|
8
8
|
spec.version = Jets::VERSION
|
|
9
9
|
spec.authors = ["Tung Nguyen"]
|
|
10
10
|
spec.email = ["tongueroo@gmail.com"]
|
|
11
|
-
spec.description = %q{}
|
|
12
|
-
spec.summary = %q{}
|
|
13
|
-
spec.homepage = ""
|
|
11
|
+
spec.description = %q{Test}
|
|
12
|
+
spec.summary = %q{Test}
|
|
13
|
+
spec.homepage = "https://github.com/tongueroo/jets"
|
|
14
14
|
spec.license = "MIT"
|
|
15
15
|
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
|
@@ -21,10 +21,14 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
spec.add_dependency "thor"
|
|
22
22
|
spec.add_dependency "hashie"
|
|
23
23
|
spec.add_dependency "colorize"
|
|
24
|
+
spec.add_dependency "activesupport"
|
|
24
25
|
|
|
25
|
-
spec.add_development_dependency "bundler"
|
|
26
|
+
spec.add_development_dependency "bundler"
|
|
27
|
+
spec.add_development_dependency "byebug"
|
|
26
28
|
spec.add_development_dependency "rake"
|
|
27
|
-
spec.add_development_dependency "
|
|
28
|
-
|
|
29
|
-
spec.add_development_dependency "guard
|
|
29
|
+
spec.add_development_dependency "rspec"
|
|
30
|
+
# ruby_dep-1.5.0 requires ruby version >= 2.2.5, which is incompatible with the current version, ruby 2.2.2p95
|
|
31
|
+
# spec.add_development_dependency "guard"
|
|
32
|
+
# spec.add_development_dependency "guard-bundler"
|
|
33
|
+
# spec.add_development_dependency "guard-rspec"
|
|
30
34
|
end
|
data/lib/jets.rb
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
$:.unshift(File.expand_path("../", __FILE__))
|
|
2
2
|
require "jets/version"
|
|
3
|
+
require "active_support/core_ext/string"
|
|
4
|
+
require "colorize"
|
|
5
|
+
require 'pp'
|
|
3
6
|
|
|
4
7
|
module Jets
|
|
8
|
+
autoload :Util, "jets/util"
|
|
5
9
|
autoload :Command, "jets/command"
|
|
6
10
|
autoload :CLI, "jets/cli"
|
|
11
|
+
autoload :Build, 'jets/build'
|
|
12
|
+
autoload :Process, 'jets/process'
|
|
13
|
+
autoload :BaseController, 'jets/base_controller'
|
|
14
|
+
autoload :Project, 'jets/project'
|
|
15
|
+
autoload :Cfn, 'jets/cfn'
|
|
16
|
+
|
|
17
|
+
extend Util
|
|
7
18
|
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
module Jets
|
|
4
|
+
class BaseController
|
|
5
|
+
attr_reader :event, :context
|
|
6
|
+
def initialize(event, context)
|
|
7
|
+
@event = event
|
|
8
|
+
@context = context
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# The public methods defined in the user's custom class will become
|
|
12
|
+
# lambda functions.
|
|
13
|
+
# Returns Example:
|
|
14
|
+
# ["FakeController#handler1", "FakeController#handler2"]
|
|
15
|
+
def lambda_functions
|
|
16
|
+
# public_instance_methods(false) - to not include inherited methods
|
|
17
|
+
self.class.public_instance_methods(false) - Object.public_instance_methods
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.lambda_functions
|
|
21
|
+
new(nil, nil).lambda_functions
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
def render(options={})
|
|
26
|
+
# render json: {"mytestdata": "value1"}, status: 200, headers: {...}
|
|
27
|
+
if options.has_key?(:json)
|
|
28
|
+
# Transform the structure to Lambda Proxy structure
|
|
29
|
+
# {statusCode: ..., body: ..., headers: }
|
|
30
|
+
status = options.delete(:status)
|
|
31
|
+
body = options.delete(:json)
|
|
32
|
+
result = options.merge(
|
|
33
|
+
statusCode: status,
|
|
34
|
+
body: body
|
|
35
|
+
)
|
|
36
|
+
# render text: "text"
|
|
37
|
+
elsif options.has_key?(:text)
|
|
38
|
+
result = options.delete(:text)
|
|
39
|
+
else
|
|
40
|
+
raise "Unsupported render option. Only :text and :json supported. options #{options.inspect}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
result
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# API Gateway LAMBDA_PROXY wraps the event in its own structure.
|
|
47
|
+
# We unwrap the "body" before sending it back
|
|
48
|
+
# For regular Lambda function calls, no need to unwrap but need to
|
|
49
|
+
# transform it to a string with JSON.dump.
|
|
50
|
+
def normalize_event_body(event)
|
|
51
|
+
body = event.has_key?("body") ? event["body"] : JSON.dump(event)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
data/lib/jets/build.rb
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
class Jets::Build
|
|
2
|
+
autoload :LambdaDeducer, "jets/build/lambda_deducer"
|
|
3
|
+
autoload :HandlerGenerator, "jets/build/handler_generator"
|
|
4
|
+
autoload :TravelingRuby, "jets/build/traveling_ruby"
|
|
5
|
+
|
|
6
|
+
def initialize(options)
|
|
7
|
+
@options = options
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def run
|
|
11
|
+
puts "Building project for Lambda..."
|
|
12
|
+
build
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def build
|
|
16
|
+
puts "Building node shim handlers..."
|
|
17
|
+
controller_paths.each do |path|
|
|
18
|
+
deducer = LambdaDeducer.new(path)
|
|
19
|
+
generator = HandlerGenerator.new(deducer.class_name, *deducer.functions)
|
|
20
|
+
generator.run
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
puts "Building TravelingRuby..."
|
|
24
|
+
TravelingRuby.new.build unless @options[:noop]
|
|
25
|
+
|
|
26
|
+
puts "Building Lambda functions as CloudFormation templates"
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def controller_paths
|
|
31
|
+
paths = []
|
|
32
|
+
expression = "#{Jets.root}app/controllers/**/*.rb"
|
|
33
|
+
Dir.glob(expression).each do |path|
|
|
34
|
+
next unless File.file?(path)
|
|
35
|
+
next if path.include?("application_controller.rb")
|
|
36
|
+
|
|
37
|
+
paths << relative_path(path)
|
|
38
|
+
end
|
|
39
|
+
paths
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Rids of the Jets.root at beginning
|
|
43
|
+
def relative_path(path)
|
|
44
|
+
path.sub(Jets.root, '')
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require "fileutils"
|
|
2
|
+
require "erb"
|
|
3
|
+
|
|
4
|
+
class Jets::Build
|
|
5
|
+
class HandlerGenerator
|
|
6
|
+
# Jets::Build::HandlerGenerator.new(
|
|
7
|
+
# "PostsController",
|
|
8
|
+
# :create, :update
|
|
9
|
+
# )
|
|
10
|
+
def initialize(class_name, *methods)
|
|
11
|
+
@class_name = class_name
|
|
12
|
+
@methods = methods
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def run
|
|
16
|
+
js_path = "#{Jets.root}handlers/#{process_type.pluralize}/#{module_name}.js"
|
|
17
|
+
FileUtils.mkdir_p(File.dirname(js_path))
|
|
18
|
+
|
|
19
|
+
template_path = File.expand_path('../templates/handler.js', __FILE__)
|
|
20
|
+
template = IO.read(template_path)
|
|
21
|
+
|
|
22
|
+
# Set used ERB variables:
|
|
23
|
+
@process_type = process_type
|
|
24
|
+
@functions = @methods.map do |m|
|
|
25
|
+
{
|
|
26
|
+
name: m,
|
|
27
|
+
handler: handler(m)
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
result = ERB.new(template, nil, "-").result(binding)
|
|
31
|
+
IO.write(js_path, result)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def process_type
|
|
35
|
+
@class_name.underscore.split('_').last
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def handler(method)
|
|
39
|
+
"handlers/#{process_type.pluralize}/#{module_name}.#{method}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def module_name
|
|
43
|
+
@class_name.sub(/Controller$/,'').underscore
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# TODO: move the handler_generator.rb deducing methods into here
|
|
2
|
+
class Jets::Build
|
|
3
|
+
class LambdaDeducer
|
|
4
|
+
attr_reader :handlers
|
|
5
|
+
def initialize(path)
|
|
6
|
+
@path = path
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def class_name
|
|
10
|
+
@path.sub(%r{app/(\w+)/},'').sub('.rb','').classify
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def functions
|
|
14
|
+
# Example: require "./app/controllers/posts_controller.rb"
|
|
15
|
+
require_path = @path.starts_with?('/') ? @path : "#{Jets.root}#{@path}"
|
|
16
|
+
require require_path
|
|
17
|
+
|
|
18
|
+
class_name
|
|
19
|
+
klass = class_name.constantize
|
|
20
|
+
klass.lambda_functions
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const spawn = require('child_process').spawn;
|
|
4
|
+
|
|
5
|
+
// Once hooked up to API Gateway can use the curl command to test:
|
|
6
|
+
// curl -s -X POST -d @event.json https://endpoint | jq .
|
|
7
|
+
|
|
8
|
+
// Filters out lines so only the error lines remain.
|
|
9
|
+
// Uses the "RubyError: " marker to find the starting error lines.
|
|
10
|
+
//
|
|
11
|
+
// Input: String
|
|
12
|
+
// random line
|
|
13
|
+
// RubyError: RuntimeError: error in submethod
|
|
14
|
+
// line1
|
|
15
|
+
// line2
|
|
16
|
+
// line3
|
|
17
|
+
//
|
|
18
|
+
// Output: String
|
|
19
|
+
// RubyError: RuntimeError: error in submethod
|
|
20
|
+
// line1
|
|
21
|
+
// line2
|
|
22
|
+
// line3
|
|
23
|
+
function filterErrorLines(text) {
|
|
24
|
+
var lines = text.split("\n")
|
|
25
|
+
var markerIndex = lines.findIndex(line => line.startsWith("RubyError: ") )
|
|
26
|
+
lines = lines.filter((line, index) => index >= markerIndex )
|
|
27
|
+
return lines.join("\n")
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Produces an Error object that displays in the AWS Lambda test console nicely.
|
|
31
|
+
// The backtrace are the ruby lines, not the nodejs shim error lines.
|
|
32
|
+
// The json payload in the Lambda console looks something like this:
|
|
33
|
+
//
|
|
34
|
+
// {
|
|
35
|
+
// "errorMessage": "RubyError: RuntimeError: error in submethod",
|
|
36
|
+
// "errorType": "RubyError",
|
|
37
|
+
// "stackTrace": [
|
|
38
|
+
// [
|
|
39
|
+
// "line1",
|
|
40
|
+
// "line2",
|
|
41
|
+
// "line3"
|
|
42
|
+
// ]
|
|
43
|
+
// ]
|
|
44
|
+
// }
|
|
45
|
+
//
|
|
46
|
+
// Input: String
|
|
47
|
+
// RubyError: RuntimeError: error in submethod
|
|
48
|
+
// line1
|
|
49
|
+
// line2
|
|
50
|
+
// line3
|
|
51
|
+
//
|
|
52
|
+
// Output: Error object
|
|
53
|
+
// { RubyError: RuntimeError: error in submethod
|
|
54
|
+
// line1
|
|
55
|
+
// line2
|
|
56
|
+
// line3 name: 'RubyError' }
|
|
57
|
+
function customError(text) {
|
|
58
|
+
text = filterErrorLines(text) // filter for error lines only
|
|
59
|
+
var lines = text.split("\n")
|
|
60
|
+
var message = lines[0]
|
|
61
|
+
var error = new Error(message)
|
|
62
|
+
error.name = message.split(':')[0]
|
|
63
|
+
error.stack = lines.slice(0, lines.length-1) // drop final empty line
|
|
64
|
+
.map(e => e.replace(/^\s+/g,'')) // trim leading whitespaces
|
|
65
|
+
.join("\n")
|
|
66
|
+
return error
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
<% @functions.each do |function| %>
|
|
70
|
+
module.exports.<%= function[:name] %> = (event, context, callback) => {
|
|
71
|
+
// Command: bin/jets process controller [event] [context] [handler]
|
|
72
|
+
var args = [
|
|
73
|
+
"process",
|
|
74
|
+
"<%= @process_type %>", // controller (singular)
|
|
75
|
+
JSON.stringify(event), // event
|
|
76
|
+
JSON.stringify(context), // context
|
|
77
|
+
"<%= function[:handler] %>" // IE: handlers/controllers/posts.update
|
|
78
|
+
]
|
|
79
|
+
var ruby = spawn("bin/jets", args);
|
|
80
|
+
|
|
81
|
+
// string concatation in javascript is faster than array concatation
|
|
82
|
+
// http://bit.ly/2gBMDs6
|
|
83
|
+
var stdout_buffer = ""; // stdout buffer
|
|
84
|
+
// In the processor_command we do NOT call puts directly and write to stdout
|
|
85
|
+
// because it will mess up the eventual response that we want API Gateway to
|
|
86
|
+
// process.
|
|
87
|
+
// The Lambda prints out function to whatever the return value the ruby method
|
|
88
|
+
ruby.stdout.on('data', function(data) {
|
|
89
|
+
// Not using console.log because it decorates output with a newline.
|
|
90
|
+
//
|
|
91
|
+
// Uncomment process.stdout.write to see stdout streamed for debugging.
|
|
92
|
+
// process.stdout.write(data)
|
|
93
|
+
stdout_buffer += data;
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// react to potential errors
|
|
97
|
+
var stderr_buffer = "";
|
|
98
|
+
ruby.stderr.on('data', function(data) {
|
|
99
|
+
// not using console.error because it decorates output with a newline
|
|
100
|
+
stderr_buffer += data
|
|
101
|
+
process.stderr.write(data)
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
//finalize when ruby process is done.
|
|
105
|
+
ruby.on('close', function(exit_code) {
|
|
106
|
+
// http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html#nodejs-prog-model-handler-callback
|
|
107
|
+
|
|
108
|
+
// succcess
|
|
109
|
+
if (exit_code == 0) {
|
|
110
|
+
var result
|
|
111
|
+
try {
|
|
112
|
+
result = JSON.parse(stdout_buffer)
|
|
113
|
+
} catch(e) {
|
|
114
|
+
// if json cannot be parse assume simple text output intended
|
|
115
|
+
process.stderr.write("WARN: error parsing json, assuming plain text is desired.")
|
|
116
|
+
result = stdout_buffer
|
|
117
|
+
}
|
|
118
|
+
callback(null, result);
|
|
119
|
+
|
|
120
|
+
// callback(null, stdout_buffer);
|
|
121
|
+
} else {
|
|
122
|
+
|
|
123
|
+
// TODO: if this works, allow a way to not decorate the error in case
|
|
124
|
+
// it actually errors in javascript land
|
|
125
|
+
// Customize error object with ruby error info
|
|
126
|
+
var error = customError(stderr_buffer)
|
|
127
|
+
callback(error);
|
|
128
|
+
// console.log("error!")
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
<% end %>
|
|
133
|
+
|
|
134
|
+
// for local testing
|
|
135
|
+
if (process.platform == "darwin") {
|
|
136
|
+
// fake event and context
|
|
137
|
+
var event = {"hello": "world"}
|
|
138
|
+
// var event = {"body": {"hello": "world"}} // API Gateway wrapper structure
|
|
139
|
+
var context = {"fake": "context"}
|
|
140
|
+
module.exports.<%= @functions.first[:name] %>(event, context, (error, message) => {
|
|
141
|
+
console.error("\nLOCAL TESTING OUTPUT")
|
|
142
|
+
if (error) {
|
|
143
|
+
console.error("error message: %o", error)
|
|
144
|
+
} else {
|
|
145
|
+
console.error("success message %o", message)
|
|
146
|
+
// console.log(JSON.stringify(message)) // stringify
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
}
|