jets 3.2.2 → 4.0.1

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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/jets.gemspec +1 -1
  4. data/lib/jets/application/defaults.rb +2 -0
  5. data/lib/jets/application.rb +6 -7
  6. data/lib/jets/aws_info.rb +2 -2
  7. data/lib/jets/booter.rb +48 -1
  8. data/lib/jets/builders/code_builder.rb +2 -21
  9. data/lib/jets/builders/gem_replacer.rb +2 -7
  10. data/lib/jets/builders/ruby_packager.rb +37 -4
  11. data/lib/jets/cfn/builders/api_deployment_builder.rb +1 -1
  12. data/lib/jets/cfn/builders/api_gateway_builder.rb +25 -22
  13. data/lib/jets/cfn/builders/api_resources_builder.rb +1 -1
  14. data/lib/jets/cfn/builders/authorizer_builder.rb +1 -1
  15. data/lib/jets/cfn/builders/base_child_builder.rb +20 -1
  16. data/lib/jets/cfn/builders/interface.rb +19 -0
  17. data/lib/jets/cfn/builders/parent_builder.rb +3 -3
  18. data/lib/jets/cfn/builders/shared_builder.rb +1 -1
  19. data/lib/jets/cfn/built_template.rb +1 -1
  20. data/lib/jets/cfn/ship.rb +2 -2
  21. data/lib/jets/cfn/status.rb +1 -1
  22. data/lib/jets/cfn/upload.rb +2 -2
  23. data/lib/jets/cli.rb +10 -4
  24. data/lib/jets/commands/call/base_guesser.rb +1 -1
  25. data/lib/jets/commands/clean/log.rb +3 -3
  26. data/lib/jets/commands/configure.rb +1 -1
  27. data/lib/jets/commands/delete.rb +1 -1
  28. data/lib/jets/commands/deploy.rb +2 -2
  29. data/lib/jets/commands/stack_info.rb +1 -1
  30. data/lib/jets/commands/templates/skeleton/config/application.rb.tt +1 -1
  31. data/lib/jets/commands/url.rb +1 -1
  32. data/lib/jets/core.rb +14 -2
  33. data/lib/jets/core_ext/file.rb +9 -0
  34. data/lib/jets/dotenv.rb +2 -2
  35. data/lib/jets/erb.rb +1 -1
  36. data/lib/jets/inflections.rb +1 -1
  37. data/lib/jets/internal/app/controllers/jets/bare_controller.rb +1 -1
  38. data/lib/jets/internal/app/jobs/jets/preheat_job.rb +9 -5
  39. data/lib/jets/lambda/dsl.rb +9 -2
  40. data/lib/jets/{naming.rb → names.rb} +3 -3
  41. data/lib/jets/preheat.rb +9 -6
  42. data/lib/jets/resource/api_gateway/base_path/role.rb +1 -1
  43. data/lib/jets/resource/api_gateway/cors.rb +1 -1
  44. data/lib/jets/resource/api_gateway/deployment.rb +2 -2
  45. data/lib/jets/resource/api_gateway/rest_api/logical_id.rb +1 -1
  46. data/lib/jets/resource/api_gateway/rest_api/routes/change/base.rb +1 -1
  47. data/lib/jets/resource/api_gateway/rest_api/routes/change/media_types.rb +1 -1
  48. data/lib/jets/resource/api_gateway/rest_api/routes/change/page.rb +2 -2
  49. data/lib/jets/resource/api_gateway/rest_api/routes/change.rb +1 -1
  50. data/lib/jets/resource/api_gateway/rest_api.rb +1 -1
  51. data/lib/jets/resource/child_stack/api_deployment.rb +1 -1
  52. data/lib/jets/resource/child_stack/api_resource/page.rb +1 -1
  53. data/lib/jets/resource/child_stack/api_resource.rb +1 -1
  54. data/lib/jets/resource/child_stack/app_class.rb +1 -1
  55. data/lib/jets/resource/child_stack/shared.rb +1 -1
  56. data/lib/jets/resource/iam/base_role_definition.rb +0 -5
  57. data/lib/jets/resource/iam/policy.rb +31 -0
  58. data/lib/jets/resource/lambda/function/environment.rb +2 -1
  59. data/lib/jets/resource/lambda/function.rb +3 -3
  60. data/lib/jets/router/route.rb +16 -4
  61. data/lib/jets/tmp_loader.rb +1 -1
  62. data/lib/jets/turbo/database_yaml.rb +1 -1
  63. data/lib/jets/util/yamler.rb +16 -0
  64. data/lib/jets/version.rb +1 -1
  65. data/lib/jets.rb +1 -0
  66. metadata +7 -9
  67. data/.python-version +0 -1
  68. data/.ruby-version +0 -1
@@ -16,7 +16,7 @@ module Jets::Commands
16
16
 
17
17
  def load_yaml
18
18
  if File.exist?(path)
19
- YAML.load_file(path)
19
+ Jets::Util::Yamler.load_file(path)
20
20
  else
21
21
  {}
22
22
  end
@@ -90,7 +90,7 @@ class Jets::Commands::Delete
90
90
  end
91
91
 
92
92
  def parent_stack_name
93
- Jets::Naming.parent_stack_name
93
+ Jets::Names.parent_stack_name
94
94
  end
95
95
 
96
96
  def are_you_sure?
@@ -81,7 +81,7 @@ module Jets::Commands
81
81
  memoize :status
82
82
 
83
83
  def stack_name
84
- Jets::Naming.parent_stack_name
84
+ Jets::Names.parent_stack_name
85
85
  end
86
86
 
87
87
  # Checks for a few things before deciding to delete the parent stack
@@ -117,7 +117,7 @@ module Jets::Commands
117
117
  def exit_unless_updateable!
118
118
  return if ENV['JETS_FORCE_UPDATEABLE'] # useful for debugging if stack stack updating
119
119
 
120
- stack_name = Jets::Naming.parent_stack_name
120
+ stack_name = Jets::Names.parent_stack_name
121
121
  exists = stack_exists?(stack_name)
122
122
  return unless exists # continue because stack could be updating
123
123
 
@@ -25,6 +25,6 @@ module Jets::Commands::StackInfo
25
25
  end
26
26
 
27
27
  def parent_stack_name
28
- Jets::Naming.parent_stack_name
28
+ Jets::Names.parent_stack_name
29
29
  end
30
30
  end
@@ -11,7 +11,7 @@ Jets.application.configure do
11
11
  # config.prewarm.public_ratio = 3 # default is 3
12
12
  <% end -%>
13
13
 
14
- # config.env_extra = 2 # can also set this with JETS_ENV_EXTRA
14
+ # config.extra = 2 # can also set this with JETS_EXTRA
15
15
  # config.autoload_paths = []
16
16
 
17
17
  # config.asset_base_url = 'https://cloudfront.domain.com/assets' # example
@@ -7,7 +7,7 @@ module Jets::Commands
7
7
  end
8
8
 
9
9
  def display
10
- stack_name = Jets::Naming.parent_stack_name
10
+ stack_name = Jets::Names.parent_stack_name
11
11
  unless stack_exists?(stack_name)
12
12
  puts "Stack for #{Jets.config.project_name.color(:green)} project for environment #{Jets.env.color(:green)}. Couldn't find #{stack_name.color(:green)} stack."
13
13
  exit
data/lib/jets/core.rb CHANGED
@@ -32,7 +32,19 @@ module Jets::Core
32
32
  end
33
33
  memoize :env
34
34
 
35
- def build_root
35
+ @@extra_warning_shown = false
36
+ def extra
37
+ # Keep for backwards compatibility
38
+ unless ENV['JETS_ENV_EXTRA'].blank?
39
+ puts "DEPRECATION WARNING: JETS_ENV_EXTRA is deprecated. Use JETS_EXTRA instead.".color(:yellow) unless @@extra_warning_shown
40
+ @@extra_warning_shown = true
41
+ extra = ENV['JETS_ENV_EXTRA']
42
+ end
43
+ extra = ENV['JETS_EXTRA'] unless ENV['JETS_EXTRA'].blank?
44
+ extra
45
+ end
46
+
47
+ def build_root
36
48
  "/tmp/jets/#{config.project_name}".freeze
37
49
  end
38
50
  memoize :build_root
@@ -76,7 +88,7 @@ module Jets::Core
76
88
  end
77
89
 
78
90
  def project_namespace
79
- [config.project_name, config.short_env, config.env_extra].compact.join('-').gsub('_','-')
91
+ [config.project_name, config.short_env, config.extra].compact.join('-').gsub('_','-')
80
92
  end
81
93
 
82
94
  def rack?
@@ -0,0 +1,9 @@
1
+ class File
2
+ class << self
3
+ # Ruby 3.2 removed File.exists?
4
+ # aws_config/store.rb uses it
5
+ # https://github.com/a2ikm/aws_config/blob/ef9cdd0eda116577f7d358bc421afd8e2f1eb1d3/lib/aws_config/store.rb#L6
6
+ # Probably a bunch of other libraries still use File.exists? also
7
+ alias_method :exists?, :exist?
8
+ end
9
+ end
data/lib/jets/dotenv.rb CHANGED
@@ -36,8 +36,8 @@ class Jets::Dotenv
36
36
  (root.join(".env.#{Jets.env}.local") unless @remote),
37
37
  ]
38
38
  files << root.join(".env.#{Jets.env}.remote") if @remote
39
- if ENV["JETS_ENV_EXTRA"]
40
- files << root.join(".env.#{Jets.env}.#{ENV["JETS_ENV_EXTRA"]}")
39
+ if Jets.extra
40
+ files << root.join(".env.#{Jets.env}.#{Jets.extra}")
41
41
  end
42
42
  files.compact
43
43
  end
data/lib/jets/erb.rb CHANGED
@@ -12,7 +12,7 @@ class Jets::Erb
12
12
  set_template_variables(variables)
13
13
  template = IO.read(path)
14
14
  begin
15
- ERB.new(template, nil, "-").result(binding)
15
+ ERB.new(template, trim_mode: '-').result(binding)
16
16
  rescue Exception => e
17
17
  puts e
18
18
  puts e.backtrace if ENV['JETS_DEBUG']
@@ -25,7 +25,7 @@ module Jets
25
25
  # User defined custom inflections
26
26
  def custom
27
27
  path = "#{Jets.root}/config/inflections.yml"
28
- File.exist?(path) ? YAML.load_file(path) : {}
28
+ File.exist?(path) ? Jets::Util::Yamler.load_file(path) : {}
29
29
  end
30
30
  end
31
31
  end
@@ -10,7 +10,7 @@ private
10
10
  def process!
11
11
  status, headers, body = dispatch!
12
12
  # Use the adapter only to convert the Rack triplet to a API Gateway hash structure
13
- adapter = Jets::Controller::Rack::Adapter.new(event, context, meth)
13
+ adapter = Jets::Controller::Rack::Adapter.new(event, context)
14
14
  adapter.convert_to_api_gateway(status, headers, body)
15
15
  end
16
16
  end
@@ -12,13 +12,17 @@ class Jets::PreheatJob < ApplicationJob
12
12
  sid: "Statement1",
13
13
  action: ["logs:*"],
14
14
  effect: "Allow",
15
- resource: "arn:aws:logs:#{Jets.aws.region}:#{Jets.aws.account}:log-group:#{Jets.config.project_namespace}-*",
15
+ resource: [
16
+ sub("arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${WarmLambdaFunction}"),
17
+ ]
16
18
  },
17
19
  {
18
- sid: "Statement2",
19
- action: ["lambda:InvokeFunction", "lambda:InvokeAsync"],
20
- effect: "Allow",
21
- resource: "arn:aws:lambda:#{Jets.aws.region}:#{Jets.aws.account}:function:#{Jets.config.project_namespace}-*",
20
+ Sid: "Statement2",
21
+ Action: ["lambda:InvokeFunction", "lambda:InvokeAsync"],
22
+ Effect: "Allow",
23
+ Resource: [
24
+ sub("arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:#{Jets.project_namespace}-*")
25
+ ]
22
26
  }
23
27
  )
24
28
 
@@ -234,7 +234,13 @@ module Jets::Lambda::Dsl
234
234
  end
235
235
 
236
236
  def ref(name)
237
- "!Ref #{name.to_s.camelize}"
237
+ name = name.is_a?(Symbol) ? name.to_s.camelize : name
238
+ "!Ref #{name}"
239
+ end
240
+
241
+ def sub(value)
242
+ value = value.is_a?(Symbol) ? value.to_s.camelize : value
243
+ "!Sub #{value}"
238
244
  end
239
245
 
240
246
  # meth is a Symbol
@@ -317,7 +323,8 @@ module Jets::Lambda::Dsl
317
323
  #
318
324
  # Do not include tasks from the direct subclasses of Jets::Lambda::Functions
319
325
  # because those classes are abstract. Dont want those methods to be included.
320
- def find_all_tasks(public: true)
326
+ def find_all_tasks(options={})
327
+ public = options[:public].nil? ? true : options[:public]
321
328
  klass = self
322
329
  direct_subclasses = Jets::Lambda::Functions.subclasses
323
330
  lookup = []
@@ -1,7 +1,7 @@
1
- # This class groups the naming in one place.
2
- # Some naming is for CloudFormation
1
+ # This class groups the names in one place.
2
+ # Some names are for CloudFormation
3
3
  # Some are for the Build process
4
- class Jets::Naming
4
+ class Jets::Names
5
5
  # Mainly used by build.rb
6
6
  class << self
7
7
  extend Memoist
data/lib/jets/preheat.rb CHANGED
@@ -91,12 +91,15 @@ module Jets
91
91
  # ...
92
92
  # ]
93
93
  def all_functions
94
- classes.map do |klass|
95
- tasks = klass.tasks.select { |t| t.lang == :ruby } # only prewarm ruby functions
96
- tasks.map do |task|
97
- meth = task.meth
98
- underscored = klass.to_s.underscore.gsub('/','-')
99
- "#{underscored}-#{meth}" # function_name
94
+ parent_stack = cfn.describe_stack_resources(stack_name: Jets::Names.parent_stack_name)
95
+ parent_resources = parent_stack.stack_resources.select do |resource|
96
+ resource.logical_resource_id =~ /Controller$/ # only controller functions
97
+ end
98
+ physical_resource_ids = parent_resources.map(&:physical_resource_id)
99
+ resources = physical_resource_ids.inject([]) do |acc, physical_resource_id|
100
+ stack_resources = cfn.describe_stack_resources(stack_name: physical_resource_id).stack_resources
101
+ stack_resources.each do |stack_resource|
102
+ acc << stack_resource if stack_resource.logical_resource_id.ends_with?('LambdaFunction') # only functions
100
103
  end
101
104
  end.flatten.uniq.compact
102
105
  end
@@ -54,7 +54,7 @@ module Jets::Resource::ApiGateway::BasePath
54
54
 
55
55
  # Duplicated in rest_api/change_detection.rb, base_path/role.rb, rest_api/routes.rb
56
56
  def rest_api_id
57
- stack_name = Jets::Naming.parent_stack_name
57
+ stack_name = Jets::Names.parent_stack_name
58
58
  return "RestApi" unless stack_exists?(stack_name)
59
59
 
60
60
  stack = cfn.describe_stacks(stack_name: stack_name).stacks.first
@@ -51,7 +51,7 @@ module Jets::Resource::ApiGateway
51
51
  end
52
52
 
53
53
  def cors_authorization_type
54
- Jets.config.api.cors_authorization_type || @route.authorization_type || "NONE"
54
+ Jets.config.api.cors_authorization_type || "NONE"
55
55
  end
56
56
 
57
57
  def cors_logical_id
@@ -33,7 +33,7 @@ module Jets::Resource::ApiGateway
33
33
  end
34
34
 
35
35
  def depends_on
36
- expression = "#{Jets::Naming.template_path_prefix}-*_controller*"
36
+ expression = "#{Jets::Names.template_path_prefix}-*_controller*"
37
37
  controller_logical_ids = []
38
38
  Dir.glob(expression).each do |path|
39
39
  next unless File.file?(path)
@@ -57,7 +57,7 @@ module Jets::Resource::ApiGateway
57
57
 
58
58
  def self.stage_name
59
59
  # Stage name only allows a-zA-Z0-9_
60
- [Jets.config.short_env, Jets.config.env_extra].compact.join('_').gsub('-','_')
60
+ [Jets.config.short_env, Jets.config.extra].compact.join('_').gsub('-','_')
61
61
  end
62
62
 
63
63
  def timestamp
@@ -88,7 +88,7 @@ class Jets::Resource::ApiGateway::RestApi
88
88
  end
89
89
 
90
90
  def parent_stack_name
91
- Jets::Naming.parent_stack_name
91
+ Jets::Names.parent_stack_name
92
92
  end
93
93
 
94
94
  def default
@@ -86,7 +86,7 @@ class Jets::Resource::ApiGateway::RestApi::Routes::Change
86
86
 
87
87
  # Duplicated in rest_api/change_detection.rb, base_path/role.rb, rest_api/routes.rb
88
88
  def rest_api_id
89
- stack_name = Jets::Naming.parent_stack_name
89
+ stack_name = Jets::Names.parent_stack_name
90
90
  return "RestApi" unless stack_exists?(stack_name)
91
91
 
92
92
  stack = cfn.describe_stacks(stack_name: stack_name).stacks.first
@@ -30,7 +30,7 @@ class Jets::Resource::ApiGateway::RestApi::Routes::Change
30
30
  end
31
31
 
32
32
  def parent_stack_name
33
- Jets::Naming.parent_stack_name
33
+ Jets::Names.parent_stack_name
34
34
  end
35
35
  end
36
36
  end
@@ -33,7 +33,7 @@ class Jets::Resource::ApiGateway::RestApi::Routes::Change
33
33
  # logical id to page map
34
34
  # Important: In Cfn::Builders::ApiGatewayBuilder, the add_gateway_routes and ApiResourcesBuilder needs to run
35
35
  # before the parent add_gateway_rest_api method.
36
- def local_logical_ids_map(path_expression="#{Jets::Naming.template_path_prefix}-api-resources-*.yml")
36
+ def local_logical_ids_map(path_expression="#{Jets::Names.template_path_prefix}-api-resources-*.yml")
37
37
  logical_ids = {} # logical id => page number
38
38
 
39
39
  Dir.glob(path_expression).each do |path|
@@ -85,7 +85,7 @@ class Jets::Resource::ApiGateway::RestApi::Routes::Change
85
85
  end
86
86
 
87
87
  def parent_resources
88
- resp = cfn.describe_stack_resources(stack_name: Jets::Naming.parent_stack_name)
88
+ resp = cfn.describe_stack_resources(stack_name: Jets::Names.parent_stack_name)
89
89
  resp.stack_resources
90
90
  end
91
91
  memoize :parent_resources
@@ -10,7 +10,7 @@ class Jets::Resource::ApiGateway::RestApi::Routes
10
10
  end
11
11
 
12
12
  def parent_stack_exists?
13
- stack_exists?(Jets::Naming.parent_stack_name)
13
+ stack_exists?(Jets::Names.parent_stack_name)
14
14
  end
15
15
  end
16
16
  end
@@ -2,7 +2,7 @@ module Jets::Resource::ApiGateway
2
2
  class RestApi < Jets::Resource::Base
3
3
  def definition
4
4
  properties = {
5
- name: Jets::Naming.gateway_api_name,
5
+ name: Jets::Names.gateway_api_name,
6
6
  endpoint_configuration: { types: endpoint_types }
7
7
  }
8
8
  properties[:endpoint_configuration][:vpc_endpoint_ids] = vpce_ids if vpce_ids
@@ -31,7 +31,7 @@ module Jets::Resource::ChildStack
31
31
  end
32
32
 
33
33
  def depends_on
34
- expression = "#{Jets::Naming.template_path_prefix}-*_controller*"
34
+ expression = "#{Jets::Names.template_path_prefix}-*_controller*"
35
35
  controller_logical_ids = []
36
36
  Dir.glob(expression).each do |path|
37
37
  next unless File.file?(path)
@@ -3,7 +3,7 @@ class Jets::Resource::ChildStack::ApiResource
3
3
  # Returns: logical id of ApiResource Page
4
4
  class Page
5
5
  def self.logical_id(parameter)
6
- expression = "#{Jets::Naming.template_path_prefix}-api-resources-*"
6
+ expression = "#{Jets::Names.template_path_prefix}-api-resources-*"
7
7
  # IE: path: #{Jets.build_root}/templates/demo-dev-2-api-resources-1.yml"
8
8
  template_paths = Dir.glob(expression).sort.to_a
9
9
  found_template = template_paths.detect do |path|
@@ -28,7 +28,7 @@ module Jets::Resource::ChildStack
28
28
  # Since dont have all the info required.
29
29
  # Read the template back to find the parameters required.
30
30
  # Actually might be easier to rationalize this approach.
31
- template_path = Jets::Naming.api_resources_template_path(@page)
31
+ template_path = Jets::Names.api_resources_template_path(@page)
32
32
  template = Jets::Cfn::BuiltTemplate.get(template_path)
33
33
  template['Parameters'].keys.each do |p|
34
34
  case p
@@ -125,7 +125,7 @@ module Jets::Resource::ChildStack
125
125
  end
126
126
 
127
127
  def current_app_class
128
- templates_prefix = "#{Jets::Naming.template_path_prefix}-app-"
128
+ templates_prefix = "#{Jets::Names.template_path_prefix}-app-"
129
129
  @path.sub(templates_prefix, '')
130
130
  .sub(/\.yml$/,'')
131
131
  .gsub('-','/')
@@ -63,7 +63,7 @@ module Jets::Resource::ChildStack
63
63
  # IE: app/resource.rb => Resource
64
64
  # Returns Resource class object in the example
65
65
  def current_shared_class
66
- templates_prefix = "#{Jets::Naming.template_path_prefix}-shared-"
66
+ templates_prefix = "#{Jets::Names.template_path_prefix}-shared-"
67
67
  @path.sub(templates_prefix, '')
68
68
  .sub(/\.yml$/,'')
69
69
  .gsub('-','/')
@@ -24,11 +24,6 @@ module Jets::Resource::Iam
24
24
  }
25
25
  }
26
26
 
27
- definition[logical_id][:properties][:policies] = [
28
- policy_name: "#{policy_name[0..127]}", # required, limited to 128-chars
29
- policy_document: policy_document,
30
- ] unless policy_document['Statement'].empty?
31
-
32
27
  unless managed_policy_arns.empty?
33
28
  definition[logical_id][:properties][:managed_policy_arns] = managed_policy_arns
34
29
  end
@@ -0,0 +1,31 @@
1
+ module Jets::Resource::Iam
2
+ class Policy < Jets::Resource::Base
3
+ def initialize(role)
4
+ @role = role
5
+ end
6
+ delegate :policy_document, :policy_name, :role_logical_id, :replacements, to: :@role
7
+
8
+ def policy_logical_id
9
+ role_logical_id.sub(/role$/, "policy")
10
+ end
11
+
12
+ def definition
13
+ logical_id = policy_logical_id
14
+
15
+ # Do not assign pretty role_name because long controller names might hit the 64-char
16
+ # limit. Also, IAM roles are global, so assigning role names prevents cross region deploys.
17
+ definition = {
18
+ logical_id => {
19
+ type: "AWS::IAM::Policy",
20
+ properties: {
21
+ roles: [Ref: role_logical_id.camelize],
22
+ policy_name: "#{policy_name[0..127]}", # required, limited to 128-chars
23
+ policy_document: policy_document,
24
+ }
25
+ }
26
+ }
27
+
28
+ definition
29
+ end
30
+ end
31
+ end
@@ -16,7 +16,8 @@ class Jets::Resource::Lambda::Function
16
16
  def jets_env
17
17
  env = {}
18
18
  env[:JETS_ENV] = Jets.env.to_s
19
- env[:JETS_ENV_EXTRA] = Jets.config.env_extra if Jets.config.env_extra
19
+ env[:JETS_ENV_EXTRA] = Jets.extra if Jets.extra # keep JETS_ENV_EXTRA for backwards compatibility
20
+ env[:JETS_EXTRA] = Jets.extra if Jets.extra
20
21
  env[:JETS_PROJECT_NAME] = ENV['JETS_PROJECT_NAME'] if ENV['JETS_PROJECT_NAME']
21
22
  env[:JETS_STAGE] = Jets::Resource::ApiGateway::Deployment.stage_name
22
23
  env[:JETS_AWS_ACCOUNT] = Jets.aws.account
@@ -136,9 +136,9 @@ module Jets::Resource::Lambda
136
136
  end
137
137
 
138
138
  def get_layers(runtime)
139
- return nil unless runtime =~ /^ruby/
139
+ return nil unless runtime =~ /^ruby/ || runtime =~ /^provided/
140
140
  return Jets.config.lambda.layers if Jets.config.gems.disable
141
-
141
+
142
142
  ["!Ref GemLayer"] + Jets.config.lambda.layers
143
143
  end
144
144
 
@@ -208,7 +208,7 @@ module Jets::Resource::Lambda
208
208
  def get_descripton(props)
209
209
  props[:description] || default_description
210
210
  end
211
-
211
+
212
212
  def default_description
213
213
  # Example values:
214
214
  # @app_class: Admin/PagesController
@@ -16,6 +16,22 @@ class Jets::Router
16
16
  @path = compute_path
17
17
  @to = compute_to
18
18
  @as = compute_as
19
+ # Pretty tricky. The @options[:mount_class] is a class that is mounted.
20
+ # For Grape apps, calling ActiveSupport to_json on a Grape class causes an infinite loop.
21
+ # Can reproduce with `GrapeApp.to_json`
22
+ # There's some type of collision between Grape and ActiveSupport to_json.
23
+ # Coerce mount_class option into a string so that when the route is serialized to JSON
24
+ # it is a string it won't cause an infinite loop. This allows the apigw routes to be
25
+ # saved to s3 and loaded back up at the end of a deploy.
26
+ # Related PR: smarter apigw routes paging calculation #635
27
+ # https://github.com/boltops-tools/jets/pull/635
28
+ # Debugging notes: https://gist.github.com/tongueroo/c9baa7e98d5ad68bbdd770fde4651963
29
+ @options[:mount_class] = @options[:mount_class].to_s if @options[:mount_class]
30
+ end
31
+
32
+ # Constantize back to the original class
33
+ def mount_class
34
+ @options[:mount_class].constantize
19
35
  end
20
36
 
21
37
  def compute_path
@@ -187,10 +203,6 @@ class Jets::Router
187
203
  end.to_h
188
204
  end
189
205
 
190
- def mount_class
191
- @options[:mount_class]
192
- end
193
-
194
206
  def to_h
195
207
  JSON.load(to_json)
196
208
  end
@@ -9,7 +9,7 @@ module Jets
9
9
  def initialize(yaml_path=nil)
10
10
  yaml_path ||= "#{Jets.root}/handlers/data.yml"
11
11
  return unless File.exist?(yaml_path)
12
- @data = YAML.load_file(yaml_path)
12
+ @data = Jets::Util::Yamler.load_file(yaml_path)
13
13
  @s3_bucket = @data['s3_bucket']
14
14
  @rack_zip = @data['rack_zip']
15
15
  end
@@ -5,7 +5,7 @@ class Jets::Turbo
5
5
  return unless File.exist?(current_yaml)
6
6
 
7
7
  vars = {}
8
- current_database = YAML.load_file(current_yaml)
8
+ current_database = Jets::Util::Yamler.load_file(current_yaml)
9
9
  database_names = infer_database_name(current_database)
10
10
  vars.merge!(database_names)
11
11
  vars['adapter'] = current_database['development']['adapter']
@@ -0,0 +1,16 @@
1
+ # Named Yamler to make it clear it's not the YAML class.
2
+ class Jets::Util
3
+ class Yamler
4
+ class << self
5
+ def load(text)
6
+ options = RUBY_VERSION =~ /^3/ ? {aliases: true} : {} # Ruby 3.0.0 deprecates aliases: true
7
+ YAML.load(text, **options)
8
+ end
9
+
10
+ def load_file(path)
11
+ options = RUBY_VERSION =~ /^3/ ? {aliases: true} : {} # Ruby 3.0.0 deprecates aliases: true
12
+ YAML.load_file(path, **options)
13
+ end
14
+ end
15
+ end
16
+ end
data/lib/jets/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Jets
2
- VERSION = "3.2.2"
2
+ VERSION = "4.0.1"
3
3
  end
data/lib/jets.rb CHANGED
@@ -3,6 +3,7 @@ $stdout.sync = true unless ENV["JETS_STDOUT_SYNC"] == "0"
3
3
  $:.unshift(File.expand_path("../", __FILE__))
4
4
 
5
5
  require "jets/core_ext/bundler"
6
+ require "jets/core_ext/file"
6
7
  require "jets/autoloaders"
7
8
  Jets::Autoloaders.log! if ENV["JETS_AUTOLOAD_LOG"]
8
9
  Jets::Autoloaders.once.setup # must be called before cli.setup
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jets
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.2
4
+ version: 4.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-19 00:00:00.000000000 Z
11
+ date: 2023-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionmailer
@@ -599,9 +599,7 @@ files:
599
599
  - ".github/PULL_REQUEST_TEMPLATE.md"
600
600
  - ".gitignore"
601
601
  - ".gitmodules"
602
- - ".python-version"
603
602
  - ".rspec"
604
- - ".ruby-version"
605
603
  - CHANGELOG.md
606
604
  - CONDUCT.md
607
605
  - CONTRIBUTING.md
@@ -814,6 +812,7 @@ files:
814
812
  - lib/jets/controller/stage.rb
815
813
  - lib/jets/core.rb
816
814
  - lib/jets/core_ext/bundler.rb
815
+ - lib/jets/core_ext/file.rb
817
816
  - lib/jets/core_ext/kernel.rb
818
817
  - lib/jets/db.rb
819
818
  - lib/jets/dotenv.rb
@@ -882,7 +881,7 @@ files:
882
881
  - lib/jets/middleware/default_stack.rb
883
882
  - lib/jets/middleware/layer.rb
884
883
  - lib/jets/middleware/stack.rb
885
- - lib/jets/naming.rb
884
+ - lib/jets/names.rb
886
885
  - lib/jets/overrides/lambda.rb
887
886
  - lib/jets/overrides/lambda/marshaller.rb
888
887
  - lib/jets/overrides/rails.rb
@@ -947,6 +946,7 @@ files:
947
946
  - lib/jets/resource/iam/class_role.rb
948
947
  - lib/jets/resource/iam/function_role.rb
949
948
  - lib/jets/resource/iam/managed_policy.rb
949
+ - lib/jets/resource/iam/policy.rb
950
950
  - lib/jets/resource/iam/policy_document.rb
951
951
  - lib/jets/resource/iot/topic_rule.rb
952
952
  - lib/jets/resource/lambda/event_source_mapping.rb
@@ -1038,6 +1038,7 @@ files:
1038
1038
  - lib/jets/turbo/rails.rb
1039
1039
  - lib/jets/turbo/templates/config/database.yml
1040
1040
  - lib/jets/util.rb
1041
+ - lib/jets/util/yamler.rb
1041
1042
  - lib/jets/version.rb
1042
1043
  - readme/prerelease.md
1043
1044
  - readme/testing.md
@@ -1094,16 +1095,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
1094
1095
  - - ">="
1095
1096
  - !ruby/object:Gem::Version
1096
1097
  version: 2.5.0
1097
- - - "<"
1098
- - !ruby/object:Gem::Version
1099
- version: 3.0.0
1100
1098
  required_rubygems_version: !ruby/object:Gem::Requirement
1101
1099
  requirements:
1102
1100
  - - ">="
1103
1101
  - !ruby/object:Gem::Version
1104
1102
  version: '0'
1105
1103
  requirements: []
1106
- rubygems_version: 3.4.13
1104
+ rubygems_version: 3.4.10
1107
1105
  signing_key:
1108
1106
  specification_version: 4
1109
1107
  summary: Ruby Serverless Framework
data/.python-version DELETED
@@ -1 +0,0 @@
1
- 3.8.6
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 2.7.7