lam 0.0.1 → 0.1.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -16
  3. data/Gemfile +3 -3
  4. data/README.md +17 -19
  5. data/Rakefile +0 -4
  6. data/bin/console +14 -0
  7. data/bin/setup +8 -0
  8. data/lam.gemspec +20 -18
  9. data/lib/lam.rb +1 -10
  10. data/lib/lam/version.rb +1 -1
  11. metadata +21 -189
  12. data/.rspec +0 -2
  13. data/.ruby-version +0 -1
  14. data/Gemfile.lock +0 -107
  15. data/Guardfile +0 -22
  16. data/LICENSE.txt +0 -22
  17. data/bin/lam +0 -14
  18. data/lib/lam/base_controller.rb +0 -54
  19. data/lib/lam/build.rb +0 -43
  20. data/lib/lam/build/handler_generator.rb +0 -34
  21. data/lib/lam/build/lambda_deducer.rb +0 -47
  22. data/lib/lam/build/templates/handler.js +0 -156
  23. data/lib/lam/build/traveling_ruby.rb +0 -108
  24. data/lib/lam/cli.rb +0 -23
  25. data/lib/lam/cli/help.rb +0 -19
  26. data/lib/lam/command.rb +0 -25
  27. data/lib/lam/process.rb +0 -18
  28. data/lib/lam/process/base_processor.rb +0 -23
  29. data/lib/lam/process/controller_processor.rb +0 -36
  30. data/lib/lam/process/help.rb +0 -11
  31. data/lib/lam/process/processor_deducer.rb +0 -52
  32. data/lib/lam/util.rb +0 -13
  33. data/notes/design.md +0 -43
  34. data/notes/traveling-ruby-packaging-lam.md +0 -26
  35. data/notes/traveling-ruby-packaging.md +0 -103
  36. data/notes/traveling-ruby.md +0 -82
  37. data/spec/fixtures/project/.gitignore +0 -3
  38. data/spec/fixtures/project/.ruby-version +0 -1
  39. data/spec/fixtures/project/Gemfile +0 -4
  40. data/spec/fixtures/project/Gemfile.lock +0 -35
  41. data/spec/fixtures/project/app/controllers/application_controller.rb +0 -2
  42. data/spec/fixtures/project/app/controllers/posts_controller.rb +0 -12
  43. data/spec/fixtures/project/bin/lam +0 -22
  44. data/spec/fixtures/project/handlers/controllers/posts.js +0 -156
  45. data/spec/lib/cli_spec.rb +0 -20
  46. data/spec/lib/lam/base_controller_spec.rb +0 -18
  47. data/spec/lib/lam/build/lambda_deducer_spec.rb +0 -20
  48. data/spec/lib/lam/build_spec.rb +0 -29
  49. data/spec/lib/lam/process/controller_processor_spec.rb +0 -22
  50. data/spec/lib/lam/process/infer_spec.rb +0 -24
  51. data/spec/lib/lam/process_spec.rb +0 -18
  52. data/spec/spec_helper.rb +0 -25
@@ -1,108 +0,0 @@
1
- require "fileutils"
2
- require "open-uri"
3
- require "colorize"
4
-
5
- class Lam::Build
6
- TRAVELING_RUBY_VERSION = 'http://d6r77u77i8pq3.cloudfront.net/releases/traveling-ruby-20150715-2.2.2-linux-x86_64.tar.gz'.freeze
7
- TEMP_BUILD_DIR = '/tmp/lam_build'.freeze
8
-
9
- class TravelingRuby
10
- def build
11
- if File.exist?("#{Lam.root}bundled")
12
- puts "Ruby bundled already exists."
13
- puts "To force rebundling: rm -rf bundled"
14
- return
15
- end
16
-
17
- check_ruby_version
18
-
19
- FileUtils.mkdir_p(TEMP_BUILD_DIR)
20
- copy_gemfiles
21
-
22
- Dir.chdir(TEMP_BUILD_DIR) do
23
- download_traveling_ruby
24
- unpack_traveling_ruby
25
- bundle_install
26
- end
27
-
28
- move_bundled_to_project
29
- end
30
-
31
- def check_ruby_version
32
- return if ENV['LAM_SKIP_RUBY_CHECK'] # only use if you absolutely need to
33
- traveling_version = TRAVELING_RUBY_VERSION.match(/-((\d+)\.(\d+)\.(\d+))-/)[1]
34
- if RUBY_VERSION != traveling_version
35
- puts "You are using ruby version #{RUBY_VERSION}."
36
- abort("You must use ruby #{traveling_version} to build the project because it's what Traveling Ruby uses.".colorize(:red))
37
- end
38
- end
39
-
40
- def copy_gemfiles
41
- FileUtils.cp("#{Lam.root}Gemfile", "#{TEMP_BUILD_DIR}/")
42
- FileUtils.cp("#{Lam.root}Gemfile.lock", "#{TEMP_BUILD_DIR}/")
43
- end
44
-
45
- def download_traveling_ruby
46
- puts "Downloading traveling ruby from #{traveling_ruby_url}."
47
-
48
- FileUtils.rm_rf("#{TEMP_BUILD_DIR}/#{bundled_ruby_dest}")
49
- File.open(traveling_ruby_tar_file, 'wb') do |saved_file|
50
- # the following "open" is provided by open-uri
51
- open(traveling_ruby_url, 'rb') do |read_file|
52
- saved_file.write(read_file.read)
53
- end
54
- end
55
-
56
- puts 'Download complete.'
57
- end
58
-
59
- def unpack_traveling_ruby
60
- puts 'Unpacking traveling ruby.'
61
-
62
- FileUtils.mkdir_p(bundled_ruby_dest)
63
-
64
- success = system("tar -xzf #{traveling_ruby_tar_file} -C #{bundled_ruby_dest}")
65
- abort('Unpacking traveling ruby failed') unless success
66
- puts 'Unpacking traveling ruby successful.'
67
-
68
- puts 'Removing tar.'
69
- FileUtils.rm_rf(traveling_ruby_tar_file)
70
- end
71
-
72
- def bundle_install
73
- puts 'Installing bundle.'
74
- require "bundler" # dynamicaly require bundler so user can use any bundler
75
- Bundler.with_clean_env do
76
- success = system(
77
- "cd #{TEMP_BUILD_DIR} && " \
78
- 'env BUNDLE_IGNORE_CONFIG=1 bundle install --path bundled/gems --without development'
79
- )
80
-
81
- abort('Bundle install failed, exiting.') unless success
82
- end
83
-
84
- puts 'Bundle install success.'
85
- end
86
-
87
- def move_bundled_to_project
88
- if File.exist?("#{Lam.root}bundled")
89
- puts "Removing current bundled folder"
90
- FileUtils.rm_rf("#{Lam.root}bundled")
91
- end
92
- puts "Moving bundled ruby to your project."
93
- FileUtils.mv("#{TEMP_BUILD_DIR}/bundled", Lam.root)
94
- end
95
-
96
- def bundled_ruby_dest
97
- "bundled/ruby"
98
- end
99
-
100
- def traveling_ruby_url
101
- TRAVELING_RUBY_VERSION
102
- end
103
-
104
- def traveling_ruby_tar_file
105
- File.basename(traveling_ruby_url)
106
- end
107
- end
108
- end
@@ -1,23 +0,0 @@
1
- require "thor"
2
- require "lam/cli/help"
3
-
4
- module Lam
5
-
6
- class CLI < Command
7
- class_option :verbose, type: :boolean
8
- class_option :noop, type: :boolean
9
-
10
- desc "build", "Builds and prepares project for Lambda"
11
- long_desc Help.build
12
- option :force, type: :boolean, aliases: "-f", desc: "override existing starter files"
13
- option :quiet, type: :boolean, aliases: "-q", desc: "silence the output"
14
- option :format, type: :string, default: "yaml", desc: "starter project template format: json or yaml"
15
- def build
16
- Lam::Build.new(options).run
17
- end
18
-
19
- desc "process TYPE", "process subcommand tasks"
20
- long_desc Help.process
21
- subcommand "process", Lam::Process
22
- end
23
- end
@@ -1,19 +0,0 @@
1
- module Lam
2
- class CLI < Command
3
- class Help
4
- class << self
5
- def build
6
- <<-EOL
7
- Builds and prepares project for AWS Lambda. Generates a node shim and vendors Traveling Ruby. Creates a zip file to be uploaded to Lambda for each handler.
8
- EOL
9
- end
10
-
11
- def process
12
- <<-EOL
13
- TODO: update process help menu
14
- EOL
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,25 +0,0 @@
1
- require "thor"
2
-
3
- module Lam
4
- class Command < Thor
5
- class << self
6
- def dispatch(m, args, options, config)
7
- # Allow calling for help via:
8
- # lam command help
9
- # lam command -h
10
- # lam command --help
11
- # lam command -D
12
- #
13
- # as well thor's normal way:
14
- #
15
- # lam help command
16
- help_flags = Thor::HELP_MAPPINGS + ["help"]
17
- if args.length > 1 && !(args & help_flags).empty?
18
- args -= help_flags
19
- args.insert(-2, "help")
20
- end
21
- super
22
- end
23
- end
24
- end
25
- end
@@ -1,18 +0,0 @@
1
- class Lam::Process < Lam::Command
2
- autoload :Help, 'lam/process/help'
3
- autoload :ProcessorDeducer, 'lam/process/processor_deducer'
4
- autoload :BaseProcessor, 'lam/process/base_processor'
5
- autoload :ControllerProcessor, 'lam/process/controller_processor'
6
-
7
- class_option :verbose, type: :boolean
8
- class_option :noop, type: :boolean
9
- class_option :project_root, desc: "Project folder. Defaults to current directory", default: "."
10
- class_option :region, desc: "AWS region"
11
-
12
- desc "create STACK", "create a CloudFormation stack"
13
- option :randomize_stack_name, type: :boolean, desc: "tack on random string at the end of the stack name", default: nil
14
- long_desc Help.controller
15
- def controller(event, context, handler)
16
- ControllerProcessor.new(event, context, handler).run
17
- end
18
- end
@@ -1,23 +0,0 @@
1
- require 'json'
2
- require_relative 'processor_deducer'
3
-
4
- # Global overrides for Lambda processing
5
- $stdout.sync = true
6
- # This might seem weird but we want puts to write to stderr which is set in
7
- # the node shim to write to stderr. This directs the output to Lambda logs.
8
- # Printing to stdout can managle up the payload returned from Lambda function.
9
- # This is not desired if you want to return say a json payload to API Gateway
10
- # eventually.
11
- def puts(text)
12
- $stderr.puts(text)
13
- end
14
-
15
- class Lam::Process::BaseProcessor
16
- attr_reader :event, :context, :handler
17
- def initialize(event, context, handler)
18
- # assume valid json from Lambda
19
- @event = JSON.parse(event)
20
- @context = JSON.parse(context)
21
- @handler = handler
22
- end
23
- end
@@ -1,36 +0,0 @@
1
- require_relative "base_processor"
2
-
3
- class Lam::Process
4
- class ControllerProcessor < Lam::Process::BaseProcessor
5
- def run
6
- # Use the handler value (ie: posts.create) to deduce the user's business
7
- # code to require and run.
8
- deducer = ProcessorDeducer.new(handler)
9
- path = deducer.controller[:path]
10
- code = deducer.controller[:code]
11
-
12
- begin
13
- require path # require "app/controllers/posts_controller.rb"
14
- # Puts the return value of user's code to stdout because this is
15
- # what eventually gets used by API Gateway.
16
- # Explicitly using $stdout since puts redirected to $stderr.
17
-
18
- # result = PostsController.new(event, context).create
19
- result = instance_eval(code, path)
20
-
21
- # JSON.dump is pretty robust. If it cannot dump the structure into a
22
- # json string, it just dumps it to a plain text string.
23
- $stdout.puts JSON.dump(result) # only place where we write to stdout.
24
- rescue Exception => e
25
- # Customize error message slightly so nodejs shim can process the
26
- # returned error message.
27
- # The "RubyError: " is a marker that the javascript shim scans for.
28
- $stderr.puts("RubyError: #{e.class}: #{e.message}") # js needs this as the first line
29
- backtrace = e.backtrace.map {|l| " #{l}" }
30
- $stderr.puts(backtrace)
31
- # $stderr.puts("END OF RUBY OUTPUT")
32
- exit 1 # instead of re-raising to control the error backtrace output
33
- end
34
- end
35
- end
36
- end
@@ -1,11 +0,0 @@
1
- class Lam::Process::Help
2
- class << self
3
- def controller
4
- <<-EOL
5
- Examples:
6
-
7
- lam process controller '{ "we" : "love", "using" : "Lambda" }' '{"test": "1"}' "handlers/controllers/posts.create"
8
- EOL
9
- end
10
- end
11
- end
@@ -1,52 +0,0 @@
1
- class Lam::Process::ProcessorDeducer
2
- def initialize(handler)
3
- @handler = handler
4
- end
5
-
6
- # Deduces the path and method from the handler. Example:
7
- #
8
- # ProcessorDeducer.new("handlers/functions/posts.create").function
9
- # => {path: "app/functions/posts.rb", code: "create(event, context)"}
10
- #
11
- # Summary:
12
- #
13
- # Input:
14
- # handler: handlers/functions/posts.create
15
- # Output:
16
- # path: app/functions/posts.rb
17
- # code: create(event, context) # code to instance_eval
18
- #
19
- # Returns: {path: path, code: code}
20
- def function
21
- path, meth = @handler.split('.')
22
- path = Lam.root + path.sub("handlers", "app") + ".rb"
23
- code = "#{meth}(event, context)"
24
- {path: path, code: code}
25
- end
26
-
27
- # Deduces the path and method from the handler. Example:
28
- #
29
- # ProcessorDeducer.new("handlers/controllers/posts.create").controller
30
- # => {path: "controllers/posts_controller.rb", code: "create"}
31
- #
32
- # Summary:
33
- #
34
- # Input:
35
- # handler: handlers/controllers/posts.create
36
- # Output:
37
- # path: app/controllers/posts_controller.rb
38
- # code: create # code to instance_eval
39
- #
40
- # Returns: {path: path, code: code}
41
- def controller
42
- handler_path, meth = @handler.split('.')
43
-
44
- path = Lam.root + handler_path.sub("handlers", "app") + "_controller.rb"
45
-
46
- controller_name = handler_path.sub(%r{.*handlers/controllers/}, "") + "_controller" # posts_controller
47
- controller_class = controller_name.split('_').collect(&:capitalize).join # PostsController
48
- code = "#{controller_class}.new(event, context).#{meth}" # PostsController.new(event, context).create
49
-
50
- {path: path, code: code, class_name: controller_class}
51
- end
52
- end
@@ -1,13 +0,0 @@
1
- module Lam::Util
2
- # Ensures trailing slash
3
- # Useful for appending a './' in front of a path or leaving it alone.
4
- # Returns: '/path/with/trailing/slash/' or './'
5
- @@root = nil
6
- def root
7
- return @@root if @@root
8
- @@root = ENV['PROJECT_ROOT'].to_s
9
- @@root = '.' if @@root == ''
10
- @@root = "#{@@root}/" unless @@root.ends_with?('/')
11
- @@root
12
- end
13
- end
@@ -1,43 +0,0 @@
1
- ## Project Structure
2
-
3
- TODO: make this a table
4
-
5
- ```sh
6
- app/controllers
7
- app/workers
8
- app/functions
9
- config/project.yml
10
- config/events.yml
11
- config/routes.rb
12
- ```
13
-
14
-
15
- ## Usage
16
-
17
- ```sh
18
- lam build
19
- lam deploy
20
- ```
21
-
22
- ## Testing
23
-
24
- Testing controller processing without node shim.
25
-
26
- ```
27
- lam process controller '{ "we" : "love", "using" : "Lambda" }' '{"test": "1"}' "handlers/controllers/posts.create"
28
- ```
29
-
30
- Testing the generated node shim handler and the controller processing.
31
-
32
- ```
33
- cd spec/fixtures/project
34
- lam build # generates the handlers
35
- node handlers/controllers/posts.js
36
- ```
37
-
38
- VS
39
-
40
- ```sh
41
- processors/controller_processor.rb '{ "we" : "love", "using" : "Lambda" }' '{"test": "1"}' "handlers/controllers/posts.create" | jq '.'
42
- ```
43
-
@@ -1,26 +0,0 @@
1
- # start off at project root
2
-
3
- mkdir -p /tmp/lam_build
4
- cp Gemfile* /tmp/lam_build/
5
- cd /tmp/lam_build # cd into there to build TravelingRuby
6
-
7
- wget http://d6r77u77i8pq3.cloudfront.net/releases/traveling-ruby-20150715-2.2.2-linux-x86_64.tar.gz .
8
- mkdir -p bundled/ruby # tmp/lam_build/bundled/ruby
9
- tar -xvf traveling-ruby-20150715-2.2.2-linux-x86_64.tar.gz -C bundled/ruby
10
- # ls ruby => bin bin.real info lib
11
- # bundled/ruby/bin/ruby -v # works now :)
12
-
13
- # had to modify Gemfile and update the local path for linux
14
- bundle install --path bundled/gems
15
-
16
- # DONT THINK THAT I NEED TO COPY THE Gemfile into bundled/gems...
17
- # mv Gemfile* bundled/gems/ # copy Gemfile from the project to bundled/gems
18
- # IMPORTANT: the Gemfile must be in the same bundled/gems folder
19
-
20
- # now we have both bundled/gems bundled/ruby :)
21
- bundled/gems/ruby/2.2.0/bin/print_ruby_info # should work
22
-
23
-
24
- # Let's move back to the project and test the wrapper, it should work also
25
- mv bundled ~/lam-test/lam/spec/fixtures/project/
26
- cd ~/lam-test/lam/spec/fixtures/project # back to project root
@@ -1,103 +0,0 @@
1
- ### Packaging Gems Info
2
-
3
- ### Structure
4
-
5
- This is the structure that TravelingRuby uses in it's tutorial.
6
-
7
- ```sh
8
- PROJECT/YOUR_BINARY_WRAPPER (hello)
9
- PROJECT/lib/ruby/bin/ruby -> PROJECT/lib/ruby/bin.real/ruby
10
- PROJECT/lib/vendor/ruby/2.2.0/bin/print_ruby_info # the gem binaries are here
11
- ```
12
-
13
- * Instead calling the ruby binary `lam process` command directly.
14
- * Lam will require 'bundler/setup' so the user's gems will be required properly
15
- * Skip the overhead of having another wrapper
16
-
17
- ```sh
18
- PROJECT/vendor/ruby/2.2.0/bin/lam # the gem binaries are here
19
- ```
20
-
21
- ### Packaging Gems Commands
22
-
23
- ```
24
- mkdir packaging/tmp
25
- cp Gemfile Gemfile.lock packaging/tmp/ # this are from the user's project
26
- cd packaging/tmp
27
-
28
- # here's where the gems are instaleld into packaging/vendor/
29
- BUNDLE_IGNORE_CONFIG=1 bundle install --path ../vendor --without development
30
- # IMPORTANT: Think I'll make the user switch to 2.2.0 and error the build proccess.
31
-
32
- ##############
33
- I can call ruby bin files directly.
34
- I was WRONG. Cannot call gem bin files directly because I need to make sure that
35
- bundler/setup gets loaded before calling the gem bin.
36
- Tried moving bundler/setup into the lam library itself but get all sorts of warnings.
37
-
38
- hello-1.0.0-linux-x86_64/lib/vendor/ruby/2.2.0/bin/lam help
39
- BUT the shabang line has: #!/usr/bin/env ruby2.0 .. but only on linux..
40
- Simply cannot rename the darn ruby version folder.
41
- #############
42
-
43
-
44
- cd ../..
45
- rm -rf packaging/tmp # remove working space
46
-
47
- # reduce the zip package size!
48
- rm -f packaging/vendor/*/*/cache/*
49
- ```
50
-
51
- Now we can copy over the generated vendored files
52
-
53
- ##################################
54
- # clean
55
- rm -rf packaging/vendor/
56
-
57
- bundle update
58
- rake package:linux:x86_64 DIR_ONLY=1
59
-
60
- mkdir packaging/tmp
61
- cp Gemfile Gemfile.lock packaging/tmp/
62
- cd packaging/tmp
63
- BUNDLE_IGNORE_CONFIG=1 bundle install --path ../vendor --without development
64
- cd ../..
65
-
66
- cp -pR packaging/vendor hello-1.0.0-linux-x86_64/lib/
67
- cp Gemfile Gemfile.lock hello-1.0.0-linux-x86_64/lib/vendor/
68
- mkdir hello-1.0.0-linux-x86_64/lib/vendor/.bundle
69
- cp packaging/bundler-config hello-1.0.0-linux-x86_64/lib/vendor/.bundle/config
70
-
71
- find . -name print_ruby_info
72
-
73
-
74
- # Wrapper script `lam`
75
-
76
- ```bash
77
- #!/bin/bash
78
- set -e
79
-
80
- # Figure out where this script is located.
81
- SELFDIR="`dirname \"$0\"`"
82
- SELFDIR="`cd \"$SELFDIR\" && pwd`"
83
-
84
- # Tell Bundler where the Gemfile and gems are.
85
- export BUNDLE_GEMFILE="$SELFDIR/lib/vendor/Gemfile"
86
- unset BUNDLE_IGNORE_CONFIG
87
-
88
- # Run the actual app using the bundled Ruby interpreter, with Bundler activated.
89
- exec "$SELFDIR/lib/ruby/bin/ruby" -rbundler/setup "$SELFDIR/lib/app/hello.rb"
90
- ```
91
-
92
-
93
- ### Building Ruby
94
- http://cache.ruby-lang.org/pub/ruby/2.2/
95
-
96
- ```sh
97
- wget http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.2.tar.gz
98
- tar xvfvz ruby-2.2.2.tar.gz
99
- cd ruby-2.2.2
100
- ./configure
101
- make
102
- sudo make install
103
- ```