jets 0.10.4 → 1.0.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/CHANGELOG.md +16 -0
- data/Gemfile.lock +12 -12
- data/README.md +4 -2
- data/exe/jets +2 -2
- data/lib/jets/application.rb +41 -5
- data/lib/jets/aws_info.rb +20 -0
- data/lib/jets/builders/code_builder.rb +201 -296
- data/lib/jets/builders/gem_replacer.rb +1 -1
- data/lib/jets/builders/handler_generator.rb +62 -43
- data/lib/jets/builders/md5.rb +55 -0
- data/lib/jets/builders/md5_zip.rb +60 -0
- data/lib/jets/builders/rack_packager.rb +29 -0
- data/lib/jets/builders/rackup_wrappers/rackup +23 -0
- data/lib/jets/builders/rackup_wrappers/rackup.rb +7 -0
- data/lib/jets/builders/reconfigure_rails/config/initializers/jets.rb +14 -0
- data/lib/jets/builders/reconfigure_rails.rb +99 -0
- data/lib/jets/builders/ruby_packager.rb +198 -0
- data/lib/jets/builders/{deducer.rb → shim_vars/app.rb} +14 -10
- data/lib/jets/builders/shim_vars/base.rb +24 -0
- data/lib/jets/builders/{shared_deducer.rb → shim_vars/shared.rb} +4 -3
- data/lib/jets/builders/shim_vars.rb +5 -0
- data/lib/jets/builders/templates/handler.js +9 -0
- data/lib/jets/builders/templates/shim.js +271 -0
- data/lib/jets/builders/tidy.rb +80 -0
- data/lib/jets/builders/util.rb +28 -0
- data/lib/jets/builders.rb +8 -2
- data/lib/jets/cfn/builders/function_builder.rb +0 -10
- data/lib/jets/cfn/builders/parent_builder.rb +7 -6
- data/lib/jets/cfn/ship.rb +9 -103
- data/lib/jets/cfn/upload.rb +139 -0
- data/lib/jets/cfn.rb +1 -0
- data/lib/jets/commands/build.rb +17 -19
- data/lib/jets/commands/deploy.rb +2 -0
- data/lib/jets/commands/help/deploy.md +2 -2
- data/lib/jets/commands/help/import/rack.md +13 -0
- data/lib/jets/commands/help/import/rails.md +11 -0
- data/lib/jets/commands/import/base.rb +39 -0
- data/lib/jets/commands/import/rack.rb +16 -0
- data/lib/jets/commands/import/rail.rb +68 -0
- data/lib/jets/commands/import/sequence.rb +68 -0
- data/lib/jets/commands/import.rb +14 -0
- data/lib/jets/commands/main.rb +2 -1
- data/lib/jets/commands/new.rb +1 -1
- data/lib/jets/commands/sequence.rb +26 -22
- data/lib/jets/commands/templates/skeleton/Gemfile.tt +5 -2
- data/lib/jets/commands/templates/skeleton/README.md +11 -2
- data/lib/jets/commands/templates/skeleton/app/jobs/application_job.rb +1 -1
- data/lib/jets/commands/templates/skeleton/app/views/layouts/application.html.erb.tt +1 -1
- data/lib/jets/commands/templates/skeleton/config/application.rb.tt +12 -5
- data/lib/jets/commands/templates/skeleton/config/database.yml.tt +5 -1
- data/lib/jets/commands/templates/skeleton/config/environments/development.rb +3 -0
- data/lib/jets/commands/templates/skeleton/config/environments/production.rb +5 -0
- data/lib/jets/commands/templates/skeleton/public/{images/favicon.ico → favicon.ico} +0 -0
- data/lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb +1 -3
- data/lib/jets/commands.rb +1 -0
- data/lib/jets/controller/base.rb +1 -1
- data/lib/jets/controller/layout.rb +3 -0
- data/lib/jets/controller/params.rb +3 -2
- data/lib/jets/controller/request.rb +4 -0
- data/lib/jets/core.rb +20 -18
- data/lib/jets/core_ext/kernel.rb +9 -5
- data/lib/jets/default/application.rb +1 -1
- data/lib/jets/inflections.rb +16 -8
- data/lib/jets/internal/app/controllers/jets/public_controller.rb +17 -22
- data/lib/jets/internal/app/controllers/jets/rack_controller.rb +15 -0
- data/lib/jets/naming.rb +0 -23
- data/lib/jets/rack/hash_converter.rb +25 -0
- data/lib/jets/rack/request.rb +71 -0
- data/lib/jets/rack/server.rb +47 -0
- data/lib/jets/rack.rb +7 -0
- data/lib/jets/rails_overrides/asset_tag_helper.rb +12 -11
- data/lib/jets/resource/function.rb +13 -5
- data/lib/jets/router.rb +1 -1
- data/lib/jets/ruby_server.rb +63 -18
- data/lib/jets/server/api_gateway.rb +1 -1
- data/lib/jets/stack/resource.rb +3 -1
- data/lib/jets/version.rb +1 -1
- data/lib/jets.rb +3 -5
- metadata +34 -9
- data/lib/jets/builders/node-hello.js +0 -73
- data/lib/jets/builders/node-shim.js +0 -182
- data/lib/jets/internal/app/controllers/jets/public_controller/python/show.py +0 -47
- data/lib/jets/internal/app/controllers/jets/public_controller/python/show.pyc +0 -0
|
@@ -9,16 +9,52 @@ require "erb"
|
|
|
9
9
|
# )
|
|
10
10
|
class Jets::Builders
|
|
11
11
|
class HandlerGenerator
|
|
12
|
-
def
|
|
13
|
-
|
|
12
|
+
def self.build!
|
|
13
|
+
new.build
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def
|
|
16
|
+
def build
|
|
17
|
+
common_base_shim
|
|
18
|
+
app_ruby_shims
|
|
17
19
|
poly_shims
|
|
18
|
-
app_ruby_shim
|
|
19
20
|
shared_shims
|
|
20
21
|
end
|
|
21
22
|
|
|
23
|
+
def app_ruby_shims
|
|
24
|
+
app_files.each do |path|
|
|
25
|
+
# Generates one big node shim for a entire controller.
|
|
26
|
+
vars = Jets::Builders::ShimVars::App.new(path)
|
|
27
|
+
generate_handler(vars)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def app_files
|
|
32
|
+
Jets::Commands::Build.app_files
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def poly_shims
|
|
36
|
+
missing = []
|
|
37
|
+
|
|
38
|
+
app_files.each do |path|
|
|
39
|
+
vars = Jets::Builders::ShimVars::App.new(path)
|
|
40
|
+
poly_tasks = vars.klass.tasks.select { |t| t.lang != :ruby }
|
|
41
|
+
poly_tasks.each do |task|
|
|
42
|
+
source_path = get_source_path(path, task)
|
|
43
|
+
if File.exist?(source_path)
|
|
44
|
+
native_function(path, task)
|
|
45
|
+
else
|
|
46
|
+
missing << source_path
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
unless missing.empty?
|
|
51
|
+
puts "ERROR: Missing source files. Please make sure these source files exist or remove their declarations".colorize(:red)
|
|
52
|
+
puts missing
|
|
53
|
+
exit 1
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
22
58
|
def shared_shims
|
|
23
59
|
Jets::Stack.subclasses.each do |subclass|
|
|
24
60
|
subclass.functions.each do |fun|
|
|
@@ -41,32 +77,11 @@ class Jets::Builders
|
|
|
41
77
|
return
|
|
42
78
|
end
|
|
43
79
|
|
|
44
|
-
dest_path = "#{
|
|
80
|
+
dest_path = "#{tmp_code}/#{fun.handler_dest}"
|
|
45
81
|
FileUtils.mkdir_p(File.dirname(dest_path))
|
|
46
82
|
FileUtils.cp(source_path, dest_path)
|
|
47
83
|
end
|
|
48
84
|
|
|
49
|
-
def poly_shims
|
|
50
|
-
missing = []
|
|
51
|
-
|
|
52
|
-
deducer = Jets::Builders::Deducer.new(@path)
|
|
53
|
-
poly_tasks = deducer.klass.tasks.select { |t| t.lang != :ruby }
|
|
54
|
-
poly_tasks.each do |task|
|
|
55
|
-
source_path = get_source_path(@path, task)
|
|
56
|
-
if File.exist?(source_path)
|
|
57
|
-
native_function(@path, task)
|
|
58
|
-
else
|
|
59
|
-
missing << source_path
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
unless missing.empty?
|
|
64
|
-
puts "ERROR: Missing source files. Please make sure these source files exist or remove their declarations".colorize(:red)
|
|
65
|
-
puts missing
|
|
66
|
-
exit 1
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
85
|
def get_source_path(original_path, task)
|
|
71
86
|
folder = original_path.sub(/\.rb$/,'')
|
|
72
87
|
lang_folder = "#{folder}/#{task.lang}"
|
|
@@ -78,35 +93,39 @@ class Jets::Builders
|
|
|
78
93
|
def native_function(original_path, task)
|
|
79
94
|
source_path = get_source_path(original_path, task)
|
|
80
95
|
# Handler: handlers/controllers/posts_controller.handle
|
|
81
|
-
dest_path = "#{
|
|
96
|
+
dest_path = "#{tmp_code}/#{task.handler_path}"
|
|
82
97
|
FileUtils.mkdir_p(File.dirname(dest_path))
|
|
83
98
|
FileUtils.cp(source_path, dest_path)
|
|
84
99
|
end
|
|
85
100
|
|
|
86
101
|
def shared_ruby_shim(fun)
|
|
87
|
-
|
|
88
|
-
|
|
102
|
+
vars = Jets::Builders::ShimVars::Shared.new(fun)
|
|
103
|
+
generate_handler(vars)
|
|
89
104
|
end
|
|
90
105
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
106
|
+
def common_base_shim
|
|
107
|
+
vars = Jets::Builders::ShimVars::Base.new
|
|
108
|
+
result = evaluate_template("shim.js", vars)
|
|
109
|
+
dest = "#{tmp_code}/handlers/shim.js"
|
|
110
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
|
111
|
+
IO.write(dest, result)
|
|
95
112
|
end
|
|
96
113
|
|
|
97
|
-
def
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
114
|
+
def generate_handler(vars)
|
|
115
|
+
result = evaluate_template("handler.js", vars)
|
|
116
|
+
dest = "#{tmp_code}/#{vars.js_path}"
|
|
117
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
|
118
|
+
IO.write(dest, result)
|
|
119
|
+
end
|
|
103
120
|
|
|
104
|
-
|
|
121
|
+
def evaluate_template(template_file, vars)
|
|
122
|
+
template_path = File.expand_path("../templates/#{template_file}", __FILE__)
|
|
123
|
+
Jets::Erb.result(template_path, vars: vars)
|
|
105
124
|
end
|
|
106
125
|
|
|
107
|
-
# TODO: move CodeBuilder.
|
|
108
|
-
def
|
|
109
|
-
"#{Jets.build_root}/#{CodeBuilder.
|
|
126
|
+
# TODO: move CodeBuilder.tmp_code to a common level for HandlerGenerator and CodeBuilder
|
|
127
|
+
def tmp_code
|
|
128
|
+
"#{Jets.build_root}/#{CodeBuilder.tmp_code}"
|
|
110
129
|
end
|
|
111
130
|
end
|
|
112
131
|
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'digest'
|
|
2
|
+
|
|
3
|
+
# Resolves the chicken-and-egg problem with md5 checksums. The handlers need
|
|
4
|
+
# to reference files with the md5 checksum. The files are the:
|
|
5
|
+
#
|
|
6
|
+
# jets/code/rack-checksum.zip
|
|
7
|
+
# jets/code/bundled-checksum.zip
|
|
8
|
+
#
|
|
9
|
+
# We compute the checksums before we generate the node shim handlers.
|
|
10
|
+
class Jets::Builders
|
|
11
|
+
class Md5
|
|
12
|
+
class << self
|
|
13
|
+
@@checksums = {}
|
|
14
|
+
def checksums
|
|
15
|
+
@@checksums
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def stage_folders
|
|
19
|
+
paths = []
|
|
20
|
+
paths << "stage/bundled" if Jets.lazy_load?
|
|
21
|
+
paths << "stage/rack" if Jets.rack?
|
|
22
|
+
# Important to have stage/code at the end, since it will use the other
|
|
23
|
+
# 'symlinked' folders to adjust the md5 hash.
|
|
24
|
+
paths << "stage/code"
|
|
25
|
+
paths
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def compute!
|
|
29
|
+
stage_folders.each do |path|
|
|
30
|
+
@@checksums[path] = dir(path)
|
|
31
|
+
end
|
|
32
|
+
@@checksums
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def dir(short_path)
|
|
36
|
+
path = "#{Jets.build_root}/#{short_path}"
|
|
37
|
+
files = Dir["#{path}/**/*"]
|
|
38
|
+
files.reject! { |f| File.directory?(f) }
|
|
39
|
+
.reject! { |f| File.symlink?(f) }
|
|
40
|
+
content = files.map do |f|
|
|
41
|
+
Digest::MD5.file(f).to_s[0..7]
|
|
42
|
+
end.join
|
|
43
|
+
|
|
44
|
+
# The stage/code md5 sha depends on the other 'symlinked' folders.
|
|
45
|
+
if short_path == "stage/code"
|
|
46
|
+
content += @@checksums.values.join
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
md5 = Digest::MD5.new
|
|
50
|
+
md5.update(content)
|
|
51
|
+
md5.hexdigest.to_s[0..7]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'action_view'
|
|
2
|
+
|
|
3
|
+
# Examples:
|
|
4
|
+
#
|
|
5
|
+
# zip = Jets::Builders::Md5Zip.new("/tmp/jets/demo/stage/code")
|
|
6
|
+
# zip.create
|
|
7
|
+
#
|
|
8
|
+
# zip = Jets::Builders::Md5Zip.new("/tmp/jets/demo/stage/bundled")
|
|
9
|
+
# zip.create
|
|
10
|
+
#
|
|
11
|
+
class Jets::Builders
|
|
12
|
+
class Md5Zip
|
|
13
|
+
include ActionView::Helpers::NumberHelper # number_to_human_size
|
|
14
|
+
include Util
|
|
15
|
+
|
|
16
|
+
def initialize(folder)
|
|
17
|
+
@path = "#{Jets.build_root}/#{folder}"
|
|
18
|
+
@checksum = Md5.checksums[folder]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def create
|
|
22
|
+
headline "Creating zip file for #{@path}"
|
|
23
|
+
|
|
24
|
+
# https://serverfault.com/questions/265675/how-can-i-zip-compress-a-symlink
|
|
25
|
+
command = "cd #{@path} && zip --symlinks -rq #{zip_file} ."
|
|
26
|
+
sh(command)
|
|
27
|
+
# move out of the lower folder to the stage folder
|
|
28
|
+
# mv /tmp/jets/demo/stage/code/code.zip /tmp/jets/demo/stage/code.zip
|
|
29
|
+
FileUtils.mkdir_p(File.dirname(zip_dest))
|
|
30
|
+
FileUtils.mv("#{@path}/#{zip_file}", zip_dest)
|
|
31
|
+
|
|
32
|
+
# mv /tmp/jets/demo/stage/zips/code.zip /tmp/jets/demo/stage/zips/code-a8a604aa.zip
|
|
33
|
+
FileUtils.mv(zip_dest, md5_dest)
|
|
34
|
+
|
|
35
|
+
file_size = number_to_human_size(File.size(md5_dest))
|
|
36
|
+
puts "Zip file created at: #{md5_dest.colorize(:green)} (#{file_size})"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# /tmp/jets/demo/stage/zips/code.zip
|
|
40
|
+
def zip_dest
|
|
41
|
+
stage_area, filename = File.dirname(@path), File.basename(@path)
|
|
42
|
+
zip_area = stage_area + '/zips' # /tmp/jets/demo/stage/zips
|
|
43
|
+
zip_file = filename + '.zip' # code.zip
|
|
44
|
+
"#{zip_area}/#{zip_file}" # /tmp/jets/demo/stage/zips/code.zip
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def zip_file
|
|
48
|
+
File.basename(zip_dest)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# /tmp/jets/demo/stage/zips/code-SHA.zip
|
|
52
|
+
def md5_dest
|
|
53
|
+
zip_dest.sub(".zip", "-#{@checksum}.zip")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def md5_name
|
|
57
|
+
File.basename(md5_dest)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
class Jets::Builders
|
|
2
|
+
class RackPackager < RubyPackager
|
|
3
|
+
def finish
|
|
4
|
+
return unless gemfile_exist?
|
|
5
|
+
|
|
6
|
+
symlink_rack_bundled
|
|
7
|
+
copy_rackup_wrappers
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def symlink_rack_bundled
|
|
11
|
+
# IE: @full_app_root: /tmp/jets/demo/stage/code/rack
|
|
12
|
+
rack_bundled = "#{@full_app_root}/bundled"
|
|
13
|
+
FileUtils.rm_f(rack_bundled) # looks like FileUtils.ln_sf doesnt remove existing symlinks
|
|
14
|
+
FileUtils.ln_sf("/var/task/bundled", rack_bundled)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def copy_rackup_wrappers
|
|
18
|
+
# IE: @full_app_root: /tmp/jets/demo/stage/code/rack
|
|
19
|
+
rack_bin = "#{@full_app_root}/bin"
|
|
20
|
+
%w[rackup rackup.rb].each do |file|
|
|
21
|
+
src = File.expand_path("./rackup_wrappers/#{file}", File.dirname(__FILE__))
|
|
22
|
+
dest = "#{rack_bin}/#{file}"
|
|
23
|
+
FileUtils.mkdir_p(rack_bin) unless File.exist?(rack_bin)
|
|
24
|
+
FileUtils.cp(src, dest)
|
|
25
|
+
FileUtils.chmod 0755, dest
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
export JETS_MEGA=1
|
|
6
|
+
|
|
7
|
+
# Figure out where this script is located.
|
|
8
|
+
PROJECTDIR="`dirname \"$0\"`"
|
|
9
|
+
PROJECTDIR="`cd \"$PROJECTDIR/..\" && pwd`"
|
|
10
|
+
|
|
11
|
+
unset BUNDLE_IGNORE_CONFIG
|
|
12
|
+
# When jets packages the app code it creates .bundle/config in the project root.
|
|
13
|
+
# We want that to be used.
|
|
14
|
+
|
|
15
|
+
# Drop a pidfile
|
|
16
|
+
# echo $$ > /tmp/jets-rackup.pid
|
|
17
|
+
|
|
18
|
+
# Run the actual app using the bundled Ruby interpreter, with Bundler activated.
|
|
19
|
+
if [ -n "$C9_USER" ]; then
|
|
20
|
+
exec ruby -rbundler/setup bin/rackup.rb "$@"
|
|
21
|
+
else
|
|
22
|
+
exec "$PROJECTDIR/bundled/rbenv/shims/ruby" -rbundler/setup "$PROJECTDIR/bin/rackup.rb" "$@"
|
|
23
|
+
fi
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
JetsRails.stage = ENV['JETS_STAGE'] || 'dev' # for jets-rails StageMiddleware
|
|
2
|
+
|
|
3
|
+
# config/s3_base_url.txt is generated as part of jets build process
|
|
4
|
+
s3_base_url = IO.read("#{Rails.root}/config/s3_base_url.txt").strip rescue "s3_base_url_placeholder"
|
|
5
|
+
asset_host = "#{s3_base_url}/rack/public"
|
|
6
|
+
Rails.application.config.action_controller.asset_host = asset_host
|
|
7
|
+
|
|
8
|
+
# Rails.application.config.assets.quiet = false
|
|
9
|
+
Rails.application.config.assets.debug = false
|
|
10
|
+
Rails.application.config.assets.compile = false
|
|
11
|
+
Rails.application.config.public_file_server.enabled = true
|
|
12
|
+
|
|
13
|
+
# Looks better without colorizatiion in CloudWatch logs
|
|
14
|
+
Rails.application.config.colorize_logging = false
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# TODO: Move logic into plugin instead
|
|
2
|
+
class Jets::Builders
|
|
3
|
+
class ReconfigureRails
|
|
4
|
+
def initialize(full_app_root)
|
|
5
|
+
# IE: @app_root: /tmp/jets/demo/stage/code/rack
|
|
6
|
+
@app_root = full_app_root
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Only support Rails right now. Maybe move into plugin when adding support
|
|
10
|
+
# to more frameworks. Or maybe better to just abstract but maintain in Jets.
|
|
11
|
+
def run
|
|
12
|
+
return unless rails?
|
|
13
|
+
|
|
14
|
+
puts "Mega Mode: Reconfiguring Rails app."
|
|
15
|
+
copy_initializer
|
|
16
|
+
update_gemfile
|
|
17
|
+
update_development_environment
|
|
18
|
+
set_favicon
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def copy_initializer
|
|
22
|
+
templates = File.expand_path("./reconfigure_rails", File.dirname(__FILE__))
|
|
23
|
+
relative_path = "config/initializers/jets.rb"
|
|
24
|
+
src = "#{templates}/#{relative_path}"
|
|
25
|
+
dest = "#{@app_root}/#{relative_path}"
|
|
26
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
|
27
|
+
FileUtils.cp(src, dest)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def update_gemfile
|
|
31
|
+
gemfile = "#{@app_root}/Gemfile"
|
|
32
|
+
lines = IO.readlines(gemfile)
|
|
33
|
+
lines = add_jets_rails_gem(lines)
|
|
34
|
+
lines = comment_out_ruby_declaration(lines)
|
|
35
|
+
write_content(gemfile, lines)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def add_jets_rails_gem(lines)
|
|
39
|
+
return lines if lines.detect { |l| l =~ /jets-rails/ }
|
|
40
|
+
lines << "\n"
|
|
41
|
+
lines << %Q|gem "jets-rails"\n|
|
|
42
|
+
lines
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Jets packages up and uses only one version of ruby and different declarations
|
|
46
|
+
# of ruby can cause issues.
|
|
47
|
+
def comment_out_ruby_declaration(lines)
|
|
48
|
+
lines.map do |l|
|
|
49
|
+
l =~ /^(ruby[ (].*)/ ? "# #{$1} # commented out by jets" : l
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def update_development_environment
|
|
54
|
+
env_file = "#{@app_root}/config/environments/development.rb"
|
|
55
|
+
lines = IO.readlines(env_file)
|
|
56
|
+
new_lines = lines.map do |line|
|
|
57
|
+
if line =~ /(config\.file_watcher.*)/
|
|
58
|
+
" # #{$1} # commented out by jets\n"
|
|
59
|
+
else
|
|
60
|
+
line
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
write_content(env_file, new_lines)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Evaluate the application layout and see if has a custom favicon defined yet.
|
|
67
|
+
# If not insert one and rewrite the application layout.
|
|
68
|
+
#
|
|
69
|
+
# This avoids serving binary assets from API gateway, instead serve it from s3 directly.
|
|
70
|
+
def set_favicon
|
|
71
|
+
app_layout = "#{@app_root}/app/views/layouts/application.html.erb"
|
|
72
|
+
return unless File.exist?(app_layout)
|
|
73
|
+
|
|
74
|
+
favicon = '<link rel="shortcut icon" href="<%= asset_path("/favicon.ico") %>">'
|
|
75
|
+
|
|
76
|
+
lines = IO.readlines(app_layout)
|
|
77
|
+
has_favicon = !!lines.find { |l| l.include?(favicon) }
|
|
78
|
+
return if has_favicon
|
|
79
|
+
|
|
80
|
+
content = IO.read(app_layout)
|
|
81
|
+
content = content.sub('</head>', "\n #{favicon}\n </head>")
|
|
82
|
+
|
|
83
|
+
IO.write(app_layout, content)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# lines is an Array
|
|
87
|
+
def write_content(path, lines)
|
|
88
|
+
content = lines.join + "\n"
|
|
89
|
+
IO.write(path, content)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Rudimentary rails detection
|
|
93
|
+
def rails?
|
|
94
|
+
config_ru = "#{@app_root}/config.ru"
|
|
95
|
+
return false unless File.exist?(config_ru)
|
|
96
|
+
!IO.readlines(config_ru).grep(/Rails.application/).empty?
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
require "bundler" # for clean_old_submodules only
|
|
2
|
+
|
|
3
|
+
class Jets::Builders
|
|
4
|
+
class RubyPackager
|
|
5
|
+
include Util
|
|
6
|
+
|
|
7
|
+
attr_reader :full_app_root
|
|
8
|
+
def initialize(relative_app_root)
|
|
9
|
+
@full_app_root = full(relative_app_root)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def install
|
|
13
|
+
return unless gemfile_exist?
|
|
14
|
+
|
|
15
|
+
reconfigure_ruby_version
|
|
16
|
+
clean_old_submodules
|
|
17
|
+
bundle_install
|
|
18
|
+
setup_bundle_config
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def finish
|
|
22
|
+
return unless gemfile_exist?
|
|
23
|
+
|
|
24
|
+
copy_bundled_cache
|
|
25
|
+
extract_ruby
|
|
26
|
+
extract_gems
|
|
27
|
+
tidy
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def gemfile_exist?
|
|
31
|
+
gemfile_path = "#{@full_app_root}/Gemfile"
|
|
32
|
+
File.exist?(gemfile_path)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Installs gems on the current target system: both compiled and non-compiled.
|
|
36
|
+
# If user is on a macosx machine, macosx gems will be installed.
|
|
37
|
+
# If user is on a linux machine, linux gems will be installed.
|
|
38
|
+
#
|
|
39
|
+
# Copies Gemfile* to /tmp/jetss/demo/bundled folder and installs
|
|
40
|
+
# gems with bundle install from there.
|
|
41
|
+
#
|
|
42
|
+
# We take the time to copy Gemfile and bundle into a separate directory
|
|
43
|
+
# because it gets left around to act as a 'cache'. So, when the builds the
|
|
44
|
+
# project gets built again not all the gems from get installed from the
|
|
45
|
+
# beginning.
|
|
46
|
+
def bundle_install
|
|
47
|
+
return if poly_only?
|
|
48
|
+
|
|
49
|
+
full_project_path = @full_app_root
|
|
50
|
+
headline "Bundling: running bundle install in cache area: #{cache_area}."
|
|
51
|
+
|
|
52
|
+
copy_gemfiles(full_project_path)
|
|
53
|
+
|
|
54
|
+
require "bundler" # dynamically require bundler so user can use any bundler
|
|
55
|
+
Bundler.with_clean_env do
|
|
56
|
+
# cd /tmp/jets/demo
|
|
57
|
+
sh(
|
|
58
|
+
"cd #{cache_area} && " \
|
|
59
|
+
"env BUNDLE_IGNORE_CONFIG=1 bundle install --path bundled/gems --without development test"
|
|
60
|
+
)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Copy the Gemfile.lock back to the project in case it was updated.
|
|
64
|
+
# For example we add the jets-rails to the Gemfile.
|
|
65
|
+
copy_gemfile_lock
|
|
66
|
+
|
|
67
|
+
puts 'Bundle install success.'
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def copy_gemfile_lock
|
|
71
|
+
src = "#{cache_area}/Gemfile.lock"
|
|
72
|
+
dest = "#{@full_app_root}/Gemfile.lock"
|
|
73
|
+
FileUtils.cp_r(src, dest)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Clean up extra unneeded files to reduce package size
|
|
77
|
+
# Because we're removing files (something dangerous) use full paths.
|
|
78
|
+
def tidy
|
|
79
|
+
puts "Tidying project: removing ignored files to reduce package size."
|
|
80
|
+
tidy_project(@full_app_root)
|
|
81
|
+
# The rack sub project has it's own gitignore.
|
|
82
|
+
tidy_project(@full_app_root+"/rack")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def tidy_project(path)
|
|
86
|
+
Tidy.new(path).cleanup!
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# This is in case the user has a 2.5.x variant.
|
|
90
|
+
# Force usage of ruby version that jets supports
|
|
91
|
+
# The lambda server only has ruby 2.5.0 installed.
|
|
92
|
+
def reconfigure_ruby_version
|
|
93
|
+
ruby_version = "#{@full_app_root}/.ruby-version"
|
|
94
|
+
IO.write(ruby_version, Jets::RUBY_VERSION)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# When using submodules, bundler leaves old submodules behind. Over time this inflates
|
|
98
|
+
# the size of the the bundled gems. So we'll clean it up.
|
|
99
|
+
def clean_old_submodules
|
|
100
|
+
# https://stackoverflow.com/questions/38800129/parsing-a-gemfile-lock-with-bundler
|
|
101
|
+
lockfile = "#{cache_area}/Gemfile.lock"
|
|
102
|
+
return unless File.exist?(lockfile)
|
|
103
|
+
|
|
104
|
+
parser = Bundler::LockfileParser.new(Bundler.read_file(lockfile))
|
|
105
|
+
specs = parser.specs
|
|
106
|
+
|
|
107
|
+
# specs = Bundler.load.specs
|
|
108
|
+
# IE: spec.source.to_s: "https://github.com/tongueroo/webpacker.git (at jets@a8c4661)"
|
|
109
|
+
submoduled_specs = specs.select do |spec|
|
|
110
|
+
spec.source.to_s =~ /@\w+\)/
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# find git shas to keep
|
|
114
|
+
# IE: ["a8c4661", "abc4661"]
|
|
115
|
+
git_shas = submoduled_specs.map do |spec|
|
|
116
|
+
md = spec.source.to_s.match(/@(\w+)\)/)
|
|
117
|
+
md[1] # git_sha
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# IE: /tmp/jets/demo/cache/bundled/gems/ruby/2.5.0/bundler/gems/webpacker-a8c46614c675
|
|
121
|
+
Dir.glob("#{cache_area}/bundled/gems/ruby/2.5.0/bundler/gems/*").each do |path|
|
|
122
|
+
sha = path.split('-').last[0..6] # only first 7 chars of the git sha
|
|
123
|
+
unless git_shas.include?(sha)
|
|
124
|
+
# puts "Removing old submoduled gem: #{path}" # uncomment to see and debug
|
|
125
|
+
FileUtils.rm_rf(path) # REMOVE old submodule directory
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def copy_gemfiles(full_project_path)
|
|
131
|
+
FileUtils.mkdir_p(cache_area)
|
|
132
|
+
FileUtils.cp("#{full_project_path}/Gemfile", "#{cache_area}/Gemfile")
|
|
133
|
+
FileUtils.cp("#{full_project_path}/Gemfile.lock", "#{cache_area}/Gemfile.lock")
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def setup_bundle_config
|
|
137
|
+
ensure_build_cache_bundle_config_exists!
|
|
138
|
+
|
|
139
|
+
# Override project's .bundle/config and ensure that .bundle/config matches
|
|
140
|
+
# at these 2 spots:
|
|
141
|
+
# app_root/.bundle/config
|
|
142
|
+
# bundled/gems/.bundle/config
|
|
143
|
+
cache_bundle_config = "#{cache_area}/.bundle/config"
|
|
144
|
+
app_bundle_config = "#{@full_app_root}/.bundle/config"
|
|
145
|
+
FileUtils.mkdir_p(File.dirname(app_bundle_config))
|
|
146
|
+
FileUtils.cp(cache_bundle_config, app_bundle_config)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# On circleci the "#{Jets.build_root}/.bundle/config" doesnt exist
|
|
150
|
+
# this only happens with ssh debugging, not when the ci.sh script gets ran.
|
|
151
|
+
# But on macosx it exists.
|
|
152
|
+
# Dont know why this is the case.
|
|
153
|
+
def ensure_build_cache_bundle_config_exists!
|
|
154
|
+
text =<<-EOL
|
|
155
|
+
---
|
|
156
|
+
BUNDLE_PATH: "bundled/gems"
|
|
157
|
+
BUNDLE_WITHOUT: "development:test"
|
|
158
|
+
EOL
|
|
159
|
+
bundle_config = "#{cache_area}/.bundle/config"
|
|
160
|
+
FileUtils.mkdir_p(File.dirname(bundle_config))
|
|
161
|
+
IO.write(bundle_config, text)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def lambdagem_options
|
|
165
|
+
{
|
|
166
|
+
s3: "lambdagems",
|
|
167
|
+
build_root: cache_area, # used in lambdagem
|
|
168
|
+
project_root: @full_app_root, # used in gem_replacer and lambdagem
|
|
169
|
+
}
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def extract_ruby
|
|
173
|
+
headline "Setting up a vendored copy of ruby."
|
|
174
|
+
Lambdagem.log_level = :info
|
|
175
|
+
Lambdagem::Extract::Ruby.new(Jets::RUBY_VERSION, lambdagem_options).run
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def extract_gems
|
|
179
|
+
headline "Replacing compiled gems with AWS Lambda Linux compiled versions."
|
|
180
|
+
GemReplacer.new(Jets::RUBY_VERSION, lambdagem_options).run
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def copy_bundled_cache
|
|
184
|
+
app_root_bundled = "#{@full_app_root}/bundled"
|
|
185
|
+
if File.exist?(app_root_bundled)
|
|
186
|
+
puts "Removing current bundled from project"
|
|
187
|
+
FileUtils.rm_rf(app_root_bundled)
|
|
188
|
+
end
|
|
189
|
+
# Leave #{Jets.build_root}/bundled behind to act as cache
|
|
190
|
+
FileUtils.cp_r("#{cache_area}/bundled", app_root_bundled)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
private
|
|
194
|
+
def cache_area
|
|
195
|
+
"#{Jets.build_root}/cache" # cleaner to use full path for this setting
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# Jets::Builders::ShimVars::Shared.new(path)
|
|
2
|
+
#
|
|
3
|
+
# @vars.functions.each do |function_name|
|
|
4
|
+
# @vars.handler_for(function_name)
|
|
5
|
+
# end
|
|
6
|
+
#
|
|
7
|
+
# Implements:
|
|
8
|
+
#
|
|
9
|
+
# functions
|
|
10
|
+
# handler_for(function_name)
|
|
11
|
+
# js_path
|
|
12
|
+
#
|
|
13
|
+
module Jets::Builders::ShimVars
|
|
14
|
+
class App < Base
|
|
4
15
|
# Allow user to specify relative or full path. The right path gets used
|
|
5
16
|
# internally. Example paths:
|
|
6
17
|
# app/controllers/posts_controller.rb
|
|
@@ -37,13 +48,6 @@ class Jets::Builders
|
|
|
37
48
|
# Returns the public methods of the child_class.
|
|
38
49
|
# Example: [:create, :update]
|
|
39
50
|
def functions
|
|
40
|
-
# Example: require: /tmp/jets/demo/app_root/app/controllers/admin/posts_controller.rb
|
|
41
|
-
class_name = @full_path.sub(/.*\/app\/\w+\//,'').sub(/\.rb/,'') # admin/posts_controller
|
|
42
|
-
class_name = class_name.classify # Admin::PostsController
|
|
43
|
-
# Autoload instead of require to avoid accidentallly double requiring and
|
|
44
|
-
# it resulting WARNINGs when there are constants already defined
|
|
45
|
-
klass = class_name.constantize # autoload
|
|
46
|
-
|
|
47
51
|
klass.lambda_functions
|
|
48
52
|
end
|
|
49
53
|
|