jets 2.3.19 → 3.0.4

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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +0 -3
  3. data/.python-version +1 -1
  4. data/.ruby-version +1 -1
  5. data/CHANGELOG.md +45 -2
  6. data/LICENSE.txt +1 -1
  7. data/README.md +9 -3
  8. data/backers.md +1 -0
  9. data/jets.gemspec +12 -11
  10. data/lib/jets.rb +9 -13
  11. data/lib/jets/application.rb +9 -2
  12. data/lib/jets/application/defaults.rb +17 -15
  13. data/lib/jets/autoloaders.rb +15 -1
  14. data/lib/jets/booter.rb +3 -3
  15. data/lib/jets/builders/code_builder.rb +16 -15
  16. data/lib/jets/builders/gem_replacer.rb +3 -4
  17. data/lib/jets/builders/lambda_layer.rb +4 -5
  18. data/lib/jets/builders/md5_zip.rb +1 -1
  19. data/lib/jets/builders/ruby_packager.rb +16 -18
  20. data/lib/jets/builders/tidy.rb +1 -2
  21. data/lib/jets/bundle.rb +6 -0
  22. data/lib/jets/cfn/builders/api_gateway_builder.rb +61 -7
  23. data/lib/jets/cfn/ship.rb +2 -1
  24. data/lib/jets/cli.rb +6 -1
  25. data/lib/jets/commands/base.rb +1 -1
  26. data/lib/jets/commands/call.rb +14 -1
  27. data/lib/jets/commands/clean.rb +1 -1
  28. data/lib/jets/commands/clean/base.rb +1 -1
  29. data/lib/jets/commands/configure.rb +51 -0
  30. data/lib/jets/commands/delete.rb +2 -2
  31. data/lib/jets/commands/gems.rb +2 -10
  32. data/lib/jets/commands/help/call.md +8 -0
  33. data/lib/jets/commands/help/gems/check.md +3 -5
  34. data/lib/jets/commands/main.rb +9 -1
  35. data/lib/jets/commands/new.rb +9 -1
  36. data/lib/jets/commands/sequence.rb +6 -0
  37. data/lib/jets/commands/templates/skeleton/Gemfile.tt +1 -1
  38. data/lib/jets/commands/templates/skeleton/config/application.rb.tt +1 -1
  39. data/lib/jets/commands/templates/skeleton/public/index.html.tt +1 -1
  40. data/lib/jets/commands/url.rb +1 -0
  41. data/lib/jets/controller/base.rb +14 -4
  42. data/lib/jets/controller/middleware/main.rb +2 -1
  43. data/lib/jets/controller/params.rb +26 -4
  44. data/lib/jets/controller/rack/env.rb +18 -1
  45. data/lib/jets/controller/rendering.rb +5 -2
  46. data/lib/jets/controller/rendering/rack_renderer.rb +7 -1
  47. data/lib/jets/core.rb +12 -4
  48. data/lib/jets/dotenv/ssm.rb +18 -4
  49. data/lib/jets/generator.rb +2 -3
  50. data/lib/jets/internal/app/controllers/jets/public_controller.rb +2 -2
  51. data/lib/jets/internal/app/functions/jets/base_path.rb +10 -149
  52. data/lib/jets/internal/app/functions/jets/base_path_mapping.rb +81 -0
  53. data/lib/jets/internal/app/shared/functions/jets/s3_bucket_config.rb +14 -24
  54. data/lib/jets/overrides/rails/migration_checker.rb +6 -2
  55. data/lib/jets/resource/api_gateway/base_path/function.rb +6 -1
  56. data/lib/jets/resource/api_gateway/deployment.rb +2 -0
  57. data/lib/jets/resource/api_gateway/rest_api/logical_id.rb +34 -0
  58. data/lib/jets/resource/api_gateway/rest_api/logical_id/message.rb +49 -0
  59. data/lib/jets/resource/child_stack/api_deployment.rb +2 -0
  60. data/lib/jets/resource/lambda/function.rb +1 -1
  61. data/lib/jets/router/dsl.rb +7 -1
  62. data/lib/jets/router/method_creator/code.rb +1 -1
  63. data/lib/jets/router/scope.rb +7 -3
  64. data/lib/jets/spec_helpers/controllers.rb +11 -3
  65. data/lib/jets/spec_helpers/controllers/request.rb +23 -10
  66. data/lib/jets/stack/main/dsl/lambda.rb +1 -1
  67. data/lib/jets/turbo.rb +1 -0
  68. data/lib/jets/version.rb +1 -1
  69. metadata +51 -58
  70. data/vendor/cfn-status/CHANGELOG.md +0 -14
  71. data/vendor/cfn-status/Gemfile +0 -4
  72. data/vendor/cfn-status/LICENSE.txt +0 -21
  73. data/vendor/cfn-status/README.md +0 -56
  74. data/vendor/cfn-status/Rakefile +0 -6
  75. data/vendor/cfn-status/bin/console +0 -14
  76. data/vendor/cfn-status/bin/setup +0 -8
  77. data/vendor/cfn-status/cfn-status.gemspec +0 -30
  78. data/vendor/cfn-status/lib/cfn-status.rb +0 -1
  79. data/vendor/cfn-status/lib/cfn_status.rb +0 -245
  80. data/vendor/cfn-status/lib/cfn_status/aws_service.rb +0 -51
  81. data/vendor/cfn-status/lib/cfn_status/version.rb +0 -3
  82. data/vendor/cfn-status/spec/fixtures/cfn/pages/fresh/describe_stack_events-1.json +0 -1103
  83. data/vendor/cfn-status/spec/fixtures/cfn/pages/fresh/describe_stack_events-2.json +0 -1104
  84. data/vendor/cfn-status/spec/fixtures/cfn/pages/fresh/describe_stack_events-3.json +0 -1103
  85. data/vendor/cfn-status/spec/fixtures/cfn/pages/updating/describe_stack_events-1.json +0 -1103
  86. data/vendor/cfn-status/spec/fixtures/cfn/pages/updating/describe_stack_events-2.json +0 -1104
  87. data/vendor/cfn-status/spec/fixtures/cfn/pages/updating/describe_stack_events-3.json +0 -1103
  88. data/vendor/cfn-status/spec/fixtures/cfn/stack-events-complete.json +0 -1080
  89. data/vendor/cfn-status/spec/fixtures/cfn/stack-events-in-progress.json +0 -1080
  90. data/vendor/cfn-status/spec/fixtures/cfn/stack-events-update-rollback-complete.json +0 -1086
  91. data/vendor/cfn-status/spec/lib/cfn_status_spec.rb +0 -153
  92. data/vendor/cfn-status/spec/spec_helper.rb +0 -14
@@ -2,20 +2,12 @@ module Jets::Commands
2
2
  class Gems < Jets::Commands::Base
3
3
  desc "check", "Check if pre-built Lambda gems are available from the sources"
4
4
  long_desc Help.text("gems:check")
5
+ option :show_source, type: :boolean, desc: "Show source"
5
6
  def check
6
- check = Jets::Gems::Check.new
7
+ check = Jets::Gems::Check.new(@options)
7
8
  check.run! # exits early if missing gems found
8
9
  # If reach here, means all gems are ok.
9
10
  puts "Congrats! All gems are available in as pre-built Lambda gems 👍"
10
11
  end
11
-
12
- desc "sources", "List pre-built Lambda gem sources"
13
- long_desc Help.text("gems:sources")
14
- def sources
15
- puts "Your pre-built Lambda gem sources are:"
16
- Jets.config.gems.sources.each do |source|
17
- puts " #{source}"
18
- end
19
- end
20
12
  end
21
13
  end
@@ -53,6 +53,14 @@ Jets figures out what functions to call by evaluating the app code and finds if
53
53
 
54
54
  jets call admin-related_pages_controller-index --no-guess
55
55
 
56
+ If you want to call a function which runs too long time, you can set `read_timeout`.
57
+
58
+ jets call some_long_job-index --read_timeout 900
59
+
60
+ And you can set `retry_limit`. If you don't want to retry you can set 0.
61
+
62
+ jets call some_long_job-index --retry_limit 0
63
+
56
64
  ## Local mode
57
65
 
58
66
  Instead of calling AWS lambda remote, you can also have `jets call` use the code directly on your machine. To enable this, use the `--local` flag. Example:
@@ -1,8 +1,6 @@
1
- You can configure additional gem sources in config/application.rb:
1
+ Check if pre-built Lambda gems are available from the gems source. You can configure the gem in config/application.rb:
2
2
 
3
3
  # Sources for check for pre-compiled Lambda gems. Checks the list in order.
4
4
  Jets.application.configure do
5
- config.gems.sources = [
6
- "https://gems2.lambdagems.com"
7
- ]
8
- end
5
+ config.gems.source = "https://api.serverlessgems.com/api/v1"
6
+ end
@@ -12,6 +12,12 @@ module Jets::Commands
12
12
  Build.new(options).run
13
13
  end
14
14
 
15
+ desc "configure [TOKEN]", "configure token and updates ~/.jets/config.yml"
16
+ long_desc Help.text(:configure)
17
+ def configure(token=nil)
18
+ Configure.new(options.merge(token: token)).run
19
+ end
20
+
15
21
  desc "deploy [environment]", "Builds and deploys project to AWS Lambda"
16
22
  long_desc Help.text(:deploy)
17
23
  # Note the environment is here to trick the Thor parser to allowing an
@@ -23,7 +29,7 @@ module Jets::Commands
23
29
 
24
30
  desc "delete", "Delete the Jets project and all its resources"
25
31
  long_desc Help.text(:delete)
26
- option :sure, type: :boolean, desc: "Skip are you sure prompt."
32
+ option :yes, aliases: %w[y], type: :boolean, desc: "Skip are you sure prompt."
27
33
  option :wait, type: :boolean, default: true, desc: "Wait for stack deletion to complete."
28
34
  # Note the environment is here to trick the Thor parser to allowing an
29
35
  # environment parameter. It is not actually set here. It is set earlier
@@ -83,6 +89,8 @@ module Jets::Commands
83
89
  option :lambda_proxy, type: :boolean, default: true, desc: "Enables automatic Lambda proxy transformation of the event payload"
84
90
  option :guess, type: :boolean, default: true, desc: "Enables guess mode. Uses inference to allows use of all dashes to specify functions. Guess mode verifies that the function exists in the code base."
85
91
  option :local, type: :boolean, desc: "Enables local mode. Instead of invoke the AWS Lambda function, the method gets called locally with current app code. With local mode guess mode is always used."
92
+ option :retry_limit, type: :numeric, default: nil, desc: "Retry count of invoking function. It work with remote call"
93
+ option :read_timeout, type: :numeric, default: nil, desc: " The number of seconds to wait for response data. It work with remote call"
86
94
  def call(function_name, payload='')
87
95
  # Printing to stdout can mangle up the response when piping
88
96
  # the value to jq. For example:
@@ -89,6 +89,14 @@ module Jets::Commands
89
89
  run(command)
90
90
  end
91
91
 
92
+ def update_package_json
93
+ path = "package.json"
94
+ return unless File.exist?(path)
95
+ data = JSON.load(IO.read(path))
96
+ data["private"] = true
97
+ IO.write(path, JSON.pretty_generate(data))
98
+ end
99
+
92
100
  # bootstrap is dependent on webpacker, options[:bootstrap] is used
93
101
  # in webpacker_install.
94
102
  def bootstrap_install
@@ -106,7 +114,7 @@ JS
106
114
  after = "const { environment } = require('@rails/webpacker')\n"
107
115
  insert_into_file("config/webpack/environment.js", jquery, after: after)
108
116
 
109
- run("yarn add bootstrap@4.0.0-beta jquery popper.js postcss-cssnext")
117
+ run("yarn add bootstrap jquery popper.js postcss-cssnext")
110
118
  end
111
119
 
112
120
  def git_init
@@ -10,6 +10,12 @@ class Jets::Commands::Sequence < Thor::Group
10
10
  end
11
11
 
12
12
  private
13
+ def jets_minor_version
14
+ md = Jets::VERSION.match(/(\d+)\.(\d+)\.\d+/)
15
+ major, minor = md[1], md[2]
16
+ [major, minor, '0'].join('.')
17
+ end
18
+
13
19
  def clone_project
14
20
  unless git_installed?
15
21
  abort "Unable to detect git installation on your system. Git needs to be installed in order to use the --repo option."
@@ -1,6 +1,6 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "jets"
3
+ gem "jets", "~> <%= jets_minor_version %>"
4
4
 
5
5
  <% if @webpacker -%>
6
6
  # Include jetpacker if you are building html pages
@@ -63,7 +63,7 @@ Jets.application.configure do
63
63
  # By default logger needs to log to $stderr for CloudWatch to receive Lambda messages, but for
64
64
  # local testing environment you may want to log these messages to 'test.log' file to keep your
65
65
  # testing suite output readable.
66
- # config.logger = Jets::Logger.new($strerr)
66
+ # config.logger = Jets::Logger.new($stderr)
67
67
 
68
68
  <% if @options[:mode] == 'api' -%>
69
69
  config.controllers.default_protect_from_forgery = false
@@ -84,7 +84,7 @@
84
84
  </div>
85
85
  <p class="version">
86
86
  <strong>Jets version:</strong> <%= Jets.version %><br />
87
- <strong>Ruby version:</strong> <%= Jets::RUBY_VERSION %>
87
+ <strong>Ruby version:</strong> <%= RUBY_VERSION %>
88
88
  </p>
89
89
  </div>
90
90
  </body>
@@ -44,6 +44,7 @@ module Jets::Commands
44
44
  # domain_name is a method on the Jets::Resource::ApiGateway::Domain instance
45
45
  url = "https://#{domain_name.domain_name}"
46
46
  puts "Custom Domain: #{url}"
47
+ puts "App Domain: #{Jets.config.app.domain}" if Jets.config.app.domain
47
48
  end
48
49
 
49
50
  def endpoint_unavailable?
@@ -76,7 +76,7 @@ class Jets::Controller
76
76
  #
77
77
  def dispatch!
78
78
  t1 = Time.now
79
- log_info_start
79
+ log_start
80
80
 
81
81
  begin
82
82
  if run_before_actions(break_if: -> { @rendered })
@@ -95,13 +95,13 @@ class Jets::Controller
95
95
 
96
96
  took = Time.now - t1
97
97
  status = triplet[0]
98
- Jets.logger.info "Completed Status Code #{status} in #{took}s"
98
+ log_finish(status: status, took: took)
99
99
  triplet # status, headers, body
100
100
  end
101
101
 
102
- def log_info_start
102
+ # Documented interface method, careful not to rename
103
+ def log_start
103
104
  # JSON.dump makes logging look pretty in CloudWatch logs because it keeps it on 1 line
104
-
105
105
  ip = request.ip
106
106
  Jets.logger.info "Started #{@event['httpMethod']} \"#{@event['path']}\" for #{ip} at #{Time.now}"
107
107
  Jets.logger.info "Processing #{self.class.name}##{@meth}"
@@ -109,6 +109,12 @@ class Jets::Controller
109
109
  Jets.logger.info " Parameters: #{JSON.dump(filtered_parameters.to_h)}"
110
110
  end
111
111
 
112
+ # Documented interface method, careful not to rename
113
+ def log_finish(options={})
114
+ status, took = options[:status], options[:took]
115
+ Jets.logger.info "Completed Status Code #{status} in #{took}s"
116
+ end
117
+
112
118
  def event_log
113
119
  display_event = @event.dup
114
120
 
@@ -141,6 +147,10 @@ class Jets::Controller
141
147
  paths
142
148
  end
143
149
 
150
+ def controller_name
151
+ self.class.to_s.underscore
152
+ end
153
+
144
154
  def action_name
145
155
  @meth
146
156
  end
@@ -40,7 +40,8 @@ module Jets::Controller::Middleware
40
40
  end
41
41
 
42
42
  def jets_host
43
- default = "#{@env['rack.url_scheme']}://#{@env['HTTP_HOST']}"
43
+ protocol = @event.dig('headers', 'X-Forwarded-Proto') || @env['rack.url_scheme']
44
+ default = "#{protocol}://#{@env['HTTP_HOST']}"
44
45
  Jets.config.helpers.host || default
45
46
  end
46
47
 
@@ -14,11 +14,9 @@ class Jets::Controller
14
14
  # 2. query string parameters
15
15
  # 3. body parameters
16
16
  def params(raw: false, path_parameters: true, body_parameters: true)
17
- path_params = event["pathParameters"] || {}
18
-
19
17
  params = {}
20
18
  params = params.deep_merge(body_params) if body_parameters
21
- params = params.deep_merge(query_parameters) # always
19
+ params = params.deep_merge(unescape_recursively(query_params)) # always
22
20
  params = params.deep_merge(path_params) if path_parameters
23
21
 
24
22
  if raw
@@ -29,13 +27,36 @@ class Jets::Controller
29
27
  end
30
28
  end
31
29
 
30
+ def unescape_recursively(obj)
31
+ case obj
32
+ when Hash then obj.map { |k, v| [k, unescape_recursively(v)] }.to_h
33
+ when Array then obj.map { |v| unescape_recursively(v) }
34
+ else CGI.unescape(obj.to_s)
35
+ end
36
+ end
37
+
32
38
  def filtered_parameters(**kwargs)
33
39
  parameter_filter.filter params(**kwargs, raw: true) # Always filter raw hash
34
40
  end
35
41
 
36
- def query_parameters
42
+ def path_params
43
+ path_params = event["pathParameters"] || {}
44
+ path_params = path_params.map { |k, path| [k, CGI.unescape(path)] }.to_h
45
+ end
46
+ alias_method :path_parameters, :path_params
47
+
48
+ def query_params
37
49
  event["queryStringParameters"] || {}
38
50
  end
51
+ alias_method :query_parameters, :query_params
52
+
53
+ def request_params
54
+ {
55
+ controller: controller_name,
56
+ action: action_name,
57
+ }
58
+ end
59
+ alias_method :request_parameters, :request_params
39
60
 
40
61
  def body_params
41
62
  body = event['isBase64Encoded'] ? base64_decode(event["body"]) : event["body"]
@@ -58,6 +79,7 @@ class Jets::Controller
58
79
  {} # fallback to empty Hash
59
80
  end
60
81
  memoize :body_params
82
+ alias_method :body_parameters, :body_params
61
83
 
62
84
  private
63
85
 
@@ -13,7 +13,8 @@ module Jets::Controller::Rack
13
13
  options = {}
14
14
  options = add_top_level(options)
15
15
  options = add_http_headers(options)
16
- path = @event['path'] || '/' # always set by API Gateway but might not be when testing shim, so setting it to make testing easier
16
+ path = path_with_base_path || @event['path'] || '/' # always set by API Gateway but might not be when testing shim, so setting it to make testing easier
17
+
17
18
  env = Rack::MockRequest.env_for(path, options)
18
19
  if @options[:adapter]
19
20
  env['adapter.event'] = @event
@@ -23,6 +24,22 @@ module Jets::Controller::Rack
23
24
  end
24
25
 
25
26
  private
27
+ def path_with_base_path
28
+ resource = @event['resource']
29
+ pathParameters = @event['pathParameters']
30
+
31
+ if(!pathParameters.nil? and !resource.nil?)
32
+ resource = pathParameters.reduce(resource) {|resource, parameter|
33
+ key, value = parameter
34
+ key = key.eql?("catchall") ? "{#{key}+}" : "{#{key}}"
35
+ resource = resource.gsub(key, value)
36
+ resource
37
+ }
38
+ end
39
+
40
+ resource
41
+ end
42
+
26
43
  def add_top_level(options)
27
44
  map = {
28
45
  'CONTENT_TYPE' => content_type,
@@ -71,9 +71,12 @@ class Jets::Controller
71
71
  add_stage_name(url)
72
72
  end
73
73
 
74
+ # Actual host can be headers["origin"] when cloudfront is in front.
75
+ # Remember to set custom header "origin" header in cloudfront distribution.
76
+ # Can also override with Jets.config.app.domain.
77
+ # The actual_host value is used by redirect_to.
74
78
  def actual_host
75
- # actually host is in headers["origin"] when cloudfront is in front
76
- headers["origin"] || headers["host"]
79
+ Jets.config.app.domain || headers["origin"] || headers["host"]
77
80
  end
78
81
 
79
82
  end
@@ -63,6 +63,12 @@ module Jets::Controller::Rendering
63
63
 
64
64
  # Note @options[:method] uses @options vs options on purpose
65
65
  @options[:method] = event["httpMethod"].downcase if event["httpMethod"]
66
+
67
+ # This is how we pass parameters to actionpack. IE: params to the view.
68
+ # This is because renderer_options is actually the env that is passed to the rack request.
69
+ options.merge!("action_dispatch.request.path_parameters" => @controller.path_parameters)
70
+ options.merge!("action_dispatch.request.query_parameters" => @controller.query_parameters)
71
+ options.merge!("action_dispatch.request.request_parameters" => @controller.request_parameters)
66
72
  options
67
73
  end
68
74
 
@@ -98,7 +104,7 @@ module Jets::Controller::Rendering
98
104
 
99
105
  # PostsController => "posts" is the namespace
100
106
  def template_namespace
101
- @controller.class.to_s.sub('Controller','').underscore.pluralize
107
+ @controller.class.to_s.sub('Controller','').underscore
102
108
  end
103
109
 
104
110
  # Takes headers and adds HTTP_ to front of the keys because that is what rack
data/lib/jets/core.rb CHANGED
@@ -139,11 +139,19 @@ module Jets::Core
139
139
  rack.wait_for_socket
140
140
  end
141
141
 
142
- def default_gems_source
143
- "https://gems2.lambdagems.com"
144
- end
145
-
146
142
  def override_lambda_ruby_runtime
147
143
  require "jets/overrides/lambda"
148
144
  end
145
+
146
+ def ruby_folder
147
+ RUBY_VERSION.split('.')[0..1].join('.') + '.0'
148
+ end
149
+
150
+ # used to configure internal lambda functions
151
+ # current ruby runtime that user is running
152
+ # IE: ruby2.5 ruby2.7
153
+ def ruby_runtime
154
+ version = RUBY_VERSION.split('.')[0..1].join('.')
155
+ "ruby#{version}"
156
+ end
149
157
  end
@@ -2,7 +2,7 @@ require 'aws-sdk-ssm'
2
2
 
3
3
  class Jets::Dotenv
4
4
  class Ssm
5
- SSM_VARIABLE_REGEXP = /^ssm:(.*)/
5
+ SSM_VARIABLE_REGEXP = /^ssm:(.*)/i
6
6
 
7
7
  def initialize(variables={})
8
8
  @variables = variables
@@ -13,6 +13,8 @@ class Jets::Dotenv
13
13
  interpolated_variables = @variables.map do |key, value|
14
14
  if value[SSM_VARIABLE_REGEXP]
15
15
  value = fetch_ssm_value(key, $1)
16
+ elsif value == "SSM"
17
+ value = fetch_ssm_value(key, "SSM")
16
18
  end
17
19
 
18
20
  [key, value]
@@ -26,7 +28,10 @@ class Jets::Dotenv
26
28
  interpolated_variables.to_h.sort_by { |k,_| k }.to_h # success
27
29
  else
28
30
  message = "Error loading .env variables. No matching SSM parameters found for:\n".color(:red)
29
- message += @missing.map { |k,v,n| " #{k}=ssm:#{v} # ssm name: #{n}"}.join("\n")
31
+ message += @missing.map do |k,v,n|
32
+ value = v == "SSM" ? v : "ssm:#{v}"
33
+ " #{k}=#{value} # ssm name: #{n}"
34
+ end.join("\n")
30
35
  abort message
31
36
  end
32
37
  end
@@ -34,8 +39,7 @@ class Jets::Dotenv
34
39
  def fetch_ssm_value(key, value)
35
40
  return "fake-ssm-value" if ENV['JETS_BUILD_NO_INTERNET']
36
41
 
37
- name = value.start_with?("/") ? value :
38
- "/#{Jets.config.project_name}/#{Jets.env}/#{value}"
42
+ name = ssm_name(key, value)
39
43
  response = ssm.get_parameter(name: name, with_decryption: true)
40
44
  response.parameter.value
41
45
  rescue Aws::SSM::Errors::ParameterNotFound
@@ -43,6 +47,16 @@ class Jets::Dotenv
43
47
  ''
44
48
  end
45
49
 
50
+ def ssm_name(key, value)
51
+ if value == "SSM"
52
+ "/#{Jets.config.project_name}/#{Jets.env}/#{key}"
53
+ else
54
+ value.start_with?("/") ?
55
+ value :
56
+ "/#{Jets.config.project_name}/#{Jets.env}/#{value}"
57
+ end
58
+ end
59
+
46
60
  def ssm
47
61
  @ssm ||= Aws::SSM::Client.new
48
62
  end
@@ -89,9 +89,8 @@ class Jets::Generator
89
89
  g = Rails::Configuration::Generators.new
90
90
  g.orm :active_record, migration: true, timestamps: true
91
91
  # TODO: support g.orm :dynamodb
92
- g.test_framework false #:test_unit, fixture: false
93
- # g.test_framework :rspec # need to
94
- # TODO: load rspec configuration to use rspec
92
+ g.test_framework nil #:test_unit, fixture: false
93
+ # g.test_framework :rspec # TODO: load rspec configuration to use rspec
95
94
  g.stylesheets false
96
95
  g.javascripts false
97
96
  g.assets false