jets 1.1.5 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +10 -6
- data/README/testing.md +5 -1
- data/jets.gemspec +1 -0
- data/lib/jets.rb +5 -1
- data/lib/jets/application.rb +39 -19
- data/lib/jets/aws_services.rb +16 -10
- data/lib/jets/aws_services/stack_status.rb +7 -0
- data/lib/jets/booter.rb +6 -2
- data/lib/jets/builders/code_builder.rb +14 -0
- data/lib/jets/builders/handler_generator.rb +15 -0
- data/lib/jets/builders/shim_vars/app.rb +4 -3
- data/lib/jets/builders/shim_vars/shared.rb +8 -4
- data/lib/jets/builders/templates/shim.js +7 -3
- data/lib/jets/camelizer.rb +2 -1
- data/lib/jets/cfn/builders.rb +0 -1
- data/lib/jets/cfn/builders/api_deployment_builder.rb +27 -0
- data/lib/jets/cfn/builders/api_gateway_builder.rb +22 -2
- data/lib/jets/cfn/ship.rb +38 -6
- data/lib/jets/commands/call.rb +0 -1
- data/lib/jets/commands/call/guesser.rb +0 -3
- data/lib/jets/commands/clean/log.rb +18 -0
- data/lib/jets/commands/console.rb +1 -1
- data/lib/jets/commands/import/sequence.rb +2 -3
- data/lib/jets/commands/runner.rb +1 -1
- data/lib/jets/commands/sequence.rb +0 -1
- data/lib/jets/commands/templates/skeleton/config/application.rb.tt +11 -0
- data/lib/jets/commands/url.rb +32 -7
- data/lib/jets/controller/base.rb +21 -5
- data/lib/jets/controller/layout.rb +0 -3
- data/lib/jets/controller/middleware/local/api_gateway.rb +2 -5
- data/lib/jets/controller/middleware/local/mimic_aws_call.rb +2 -2
- data/lib/jets/controller/params.rb +42 -10
- data/lib/jets/controller/rack/adapter.rb +5 -2
- data/lib/jets/controller/rack/env.rb +17 -8
- data/lib/jets/controller/renderers/rack_renderer.rb +1 -1
- data/lib/jets/controller/rendering.rb +4 -1
- data/lib/jets/core.rb +8 -16
- data/lib/jets/internal/app/functions/jets/base_path.rb +153 -0
- data/lib/jets/klass.rb +38 -5
- data/lib/jets/lambda/dsl.rb +0 -2
- data/lib/jets/mega/request.rb +44 -13
- data/lib/jets/mega/request/source.rb +21 -0
- data/lib/jets/middleware/configurator.rb +1 -1
- data/lib/jets/middleware/default_stack.rb +2 -2
- data/lib/jets/resource.rb +1 -0
- data/lib/jets/resource/api_gateway.rb +5 -3
- data/lib/jets/resource/api_gateway/base_path.rb +5 -0
- data/lib/jets/resource/api_gateway/base_path/function.rb +42 -0
- data/lib/jets/resource/api_gateway/base_path/mapping.rb +44 -0
- data/lib/jets/resource/api_gateway/base_path/role.rb +76 -0
- data/lib/jets/resource/api_gateway/cors.rb +1 -1
- data/lib/jets/resource/api_gateway/deployment.rb +9 -5
- data/lib/jets/resource/api_gateway/domain_name.rb +56 -0
- data/lib/jets/resource/api_gateway/method.rb +3 -4
- data/lib/jets/resource/api_gateway/resource.rb +4 -3
- data/lib/jets/resource/api_gateway/rest_api.rb +42 -14
- data/lib/jets/resource/api_gateway/rest_api/change_detection.rb +42 -0
- data/lib/jets/resource/api_gateway/rest_api/logical_id.rb +59 -0
- data/lib/jets/resource/api_gateway/rest_api/routes.rb +127 -0
- data/lib/jets/resource/child_stack/api_deployment.rb +5 -1
- data/lib/jets/resource/function.rb +3 -20
- data/lib/jets/resource/function/environment.rb +23 -0
- data/lib/jets/resource/iam/application_role.rb +1 -1
- data/lib/jets/resource/route53.rb +3 -0
- data/lib/jets/resource/route53/record_set.rb +70 -0
- data/lib/jets/router.rb +2 -0
- data/lib/jets/ruby_server.rb +6 -3
- data/lib/jets/stack.rb +1 -3
- data/lib/jets/stack/main/dsl.rb +1 -1
- data/lib/jets/stack/main/extensions/lambda.rb +4 -2
- data/lib/jets/turbine.rb +0 -3
- data/lib/jets/version.rb +1 -1
- data/vendor/jets-gems/lib/jets/gems.rb +1 -0
- data/vendor/jets-gems/lib/jets/gems/agree.rb +41 -0
- data/vendor/jets-gems/lib/jets/gems/check.rb +15 -2
- metadata +30 -2
@@ -0,0 +1,42 @@
|
|
1
|
+
class Jets::Resource::ApiGateway::RestApi
|
2
|
+
class ChangeDetection
|
3
|
+
extend Memoist
|
4
|
+
include Jets::AwsServices
|
5
|
+
|
6
|
+
def changed?
|
7
|
+
return false unless parent_stack_exists?
|
8
|
+
current_binary_media_types != new_binary_media_types ||
|
9
|
+
Routes.changed?
|
10
|
+
end
|
11
|
+
|
12
|
+
def new_binary_media_types
|
13
|
+
rest_api = Jets::Resource::ApiGateway::RestApi.new
|
14
|
+
rest_api.binary_media_types
|
15
|
+
end
|
16
|
+
memoize :new_binary_media_types
|
17
|
+
|
18
|
+
# Duplicated in rest_api/change_detection.rb, base_path/role.rb, rest_api/routes.rb
|
19
|
+
def current_binary_media_types
|
20
|
+
return nil unless parent_stack_exists?
|
21
|
+
|
22
|
+
stack = cfn.describe_stacks(stack_name: parent_stack_name).stacks.first
|
23
|
+
|
24
|
+
api_gateway_stack_arn = lookup(stack[:outputs], "ApiGateway")
|
25
|
+
|
26
|
+
stack = cfn.describe_stacks(stack_name: api_gateway_stack_arn).stacks.first
|
27
|
+
rest_api_id = lookup(stack[:outputs], "RestApi")
|
28
|
+
|
29
|
+
resp = apigateway.get_rest_api(rest_api_id: rest_api_id)
|
30
|
+
resp.binary_media_types
|
31
|
+
end
|
32
|
+
memoize :current_binary_media_types
|
33
|
+
|
34
|
+
def parent_stack_exists?
|
35
|
+
stack_exists?(parent_stack_name)
|
36
|
+
end
|
37
|
+
|
38
|
+
def parent_stack_name
|
39
|
+
Jets::Naming.parent_stack_name
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class Jets::Resource::ApiGateway::RestApi
|
2
|
+
class LogicalId
|
3
|
+
extend Memoist
|
4
|
+
include Jets::AwsServices
|
5
|
+
|
6
|
+
def get
|
7
|
+
return default unless stack_exists?(parent_stack_name) && api_gateway_exists?
|
8
|
+
|
9
|
+
change_detection = ChangeDetection.new
|
10
|
+
if change_detection.changed?
|
11
|
+
new_id
|
12
|
+
else
|
13
|
+
current
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Takes current logical id and increments the number that is appended to it.
|
18
|
+
#
|
19
|
+
# Examples:
|
20
|
+
#
|
21
|
+
# RestApi => RestApi1
|
22
|
+
# RestApi1 => RestApi2
|
23
|
+
# RestApi2 => RestApi3
|
24
|
+
# RestApi7 => RestApi8
|
25
|
+
def new_id
|
26
|
+
regexp = /(\d+)/
|
27
|
+
md = current.match(regexp)
|
28
|
+
if md
|
29
|
+
current.gsub(regexp,'') + (md[1].to_i + 1).to_s
|
30
|
+
else
|
31
|
+
current + "1"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def current
|
36
|
+
resources = cfn.describe_stack_resources(stack_name: api_gateway_stack_arn).stack_resources
|
37
|
+
rest_api = resources.find { |r| r.resource_type == 'AWS::ApiGateway::RestApi' }
|
38
|
+
rest_api.logical_resource_id
|
39
|
+
end
|
40
|
+
memoize :current
|
41
|
+
|
42
|
+
def api_gateway_stack_arn
|
43
|
+
stack = cfn.describe_stacks(stack_name: parent_stack_name).stacks.first
|
44
|
+
lookup(stack[:outputs], "ApiGateway") # api_gateway_stack_arn
|
45
|
+
end
|
46
|
+
|
47
|
+
def api_gateway_exists?
|
48
|
+
!!api_gateway_stack_arn
|
49
|
+
end
|
50
|
+
|
51
|
+
def parent_stack_name
|
52
|
+
Jets::Naming.parent_stack_name
|
53
|
+
end
|
54
|
+
|
55
|
+
def default
|
56
|
+
"RestApi"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
class Jets::Resource::ApiGateway::RestApi
|
2
|
+
class Routes
|
3
|
+
extend Memoist
|
4
|
+
include Jets::AwsServices
|
5
|
+
|
6
|
+
def self.changed?
|
7
|
+
new.changed?
|
8
|
+
end
|
9
|
+
|
10
|
+
def changed?
|
11
|
+
deployed_routes = build
|
12
|
+
deployed_routes.each do |deployed_route|
|
13
|
+
new_route = find_comparable_route(deployed_route)
|
14
|
+
if new_route && new_route.to != deployed_route.to
|
15
|
+
# change in already deployed route has been detected, requires bluegreen deploy
|
16
|
+
return true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
false # Reaching here means no routes have been changed in a way that requires a bluegreen deploy
|
20
|
+
end
|
21
|
+
|
22
|
+
# Build up deployed routes from the existing CloudFormation resources.
|
23
|
+
def build
|
24
|
+
routes = []
|
25
|
+
|
26
|
+
resources, position = [], true
|
27
|
+
while position
|
28
|
+
position = nil if position == true # start of loop
|
29
|
+
resp = apigateway.get_resources(
|
30
|
+
rest_api_id: rest_api_id,
|
31
|
+
position: position,
|
32
|
+
)
|
33
|
+
resources += resp.items
|
34
|
+
position = resp.position
|
35
|
+
end
|
36
|
+
|
37
|
+
resources.each do |resource|
|
38
|
+
resource_methods = resource.resource_methods
|
39
|
+
next if resource_methods.nil?
|
40
|
+
|
41
|
+
resource_methods.each do |http_verb, resource_method|
|
42
|
+
# puts "#{http_verb} #{resource.path} | resource.id #{resource.id}"
|
43
|
+
# puts to(resource.id, http_verb)
|
44
|
+
|
45
|
+
# Test changing config.cors and CloudFormation does an in-place update
|
46
|
+
# on the resource. So no need to do bluegreen deployments for OPTIONS.
|
47
|
+
next if http_verb == "OPTIONS"
|
48
|
+
|
49
|
+
path = recreate_path(resource.path)
|
50
|
+
method = http_verb.downcase.to_sym
|
51
|
+
to = to(resource.id, http_verb)
|
52
|
+
route = Jets::Route.new(path: path, method: method, to: to)
|
53
|
+
routes << route
|
54
|
+
end
|
55
|
+
end
|
56
|
+
routes
|
57
|
+
end
|
58
|
+
|
59
|
+
# Find a route that has the same path and method. This is a comparable route
|
60
|
+
# Then we will compare the to or controller action to see if an already
|
61
|
+
# deployed route has been changed.
|
62
|
+
def find_comparable_route(deployed_route)
|
63
|
+
new_routes.find do |new_route|
|
64
|
+
new_route.path == deployed_route.path &&
|
65
|
+
new_route.method == deployed_route.method
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def new_routes
|
70
|
+
Jets::Router.routes
|
71
|
+
end
|
72
|
+
memoize :new_routes
|
73
|
+
|
74
|
+
def recreate_path(path)
|
75
|
+
path = path.gsub(%r{^/},'')
|
76
|
+
path = path.sub(/{(.*)\+}/, '*\1')
|
77
|
+
path.sub(/{(.*)}/, ':\1')
|
78
|
+
end
|
79
|
+
|
80
|
+
def to(resource_id, http_method)
|
81
|
+
uri = method_uri(resource_id, http_method)
|
82
|
+
recreate_to(uri) unless uri.nil?
|
83
|
+
end
|
84
|
+
|
85
|
+
def method_uri(resource_id, http_method)
|
86
|
+
resp = apigateway.get_method(
|
87
|
+
rest_api_id: rest_api_id,
|
88
|
+
resource_id: resource_id,
|
89
|
+
http_method: http_method
|
90
|
+
)
|
91
|
+
resp.method_integration.uri
|
92
|
+
end
|
93
|
+
|
94
|
+
# Parses method uri and recreates a Route to argument.
|
95
|
+
# So:
|
96
|
+
# "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:112233445566:function:demo-test-posts_controller-new/invocations"
|
97
|
+
# Returns:
|
98
|
+
# posts#new
|
99
|
+
def recreate_to(method_uri)
|
100
|
+
md = method_uri.match(/function:(.*)\//)
|
101
|
+
function_name = md[1] # IE: demo-dev-posts_controller-new
|
102
|
+
controller_action = function_name.sub("#{Jets.project_namespace}-", '')
|
103
|
+
md = controller_action.match(/(.*)_controller-(.*)/)
|
104
|
+
controller = md[1]
|
105
|
+
controller = controller.gsub('-','/')
|
106
|
+
action = md[2]
|
107
|
+
"#{controller}##{action}" # IE: posts#new
|
108
|
+
end
|
109
|
+
|
110
|
+
# Duplicated in rest_api/change_detection.rb, base_path/role.rb, rest_api/routes.rb
|
111
|
+
def rest_api_id
|
112
|
+
stack_name = Jets::Naming.parent_stack_name
|
113
|
+
return default unless stack_exists?(stack_name)
|
114
|
+
|
115
|
+
stack = cfn.describe_stacks(stack_name: stack_name).stacks.first
|
116
|
+
|
117
|
+
api_gateway_stack_arn = lookup(stack[:outputs], "ApiGateway")
|
118
|
+
|
119
|
+
# resources = cfn.describe_stack_resources(stack_name: api_gateway_stack_arn).stack_resources
|
120
|
+
stack = cfn.describe_stacks(stack_name: api_gateway_stack_arn).stacks.first
|
121
|
+
rest_api_id = lookup(stack[:outputs], "RestApi")
|
122
|
+
end
|
123
|
+
memoize :rest_api_id
|
124
|
+
|
125
|
+
# apigateway.get_rest_api(rest_api_id: rest_api_id) # resp
|
126
|
+
end
|
127
|
+
end
|
@@ -19,9 +19,13 @@ module Jets::Resource::ChildStack
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def parameters
|
22
|
-
{
|
22
|
+
p = {
|
23
|
+
IamRole: "!GetAtt IamRole.Arn",
|
23
24
|
RestApi: "!GetAtt ApiGateway.Outputs.RestApi",
|
25
|
+
S3Bucket: "!Ref S3Bucket",
|
24
26
|
}
|
27
|
+
p[:DomainName] = "!GetAtt ApiGateway.Outputs.DomainName" if Jets.custom_domain?
|
28
|
+
p
|
25
29
|
end
|
26
30
|
|
27
31
|
def depends_on
|
@@ -1,5 +1,8 @@
|
|
1
1
|
class Jets::Resource
|
2
2
|
class Function < Jets::Resource::Base
|
3
|
+
autoload :Environment, 'jets/resource/function/environment'
|
4
|
+
include Environment
|
5
|
+
|
3
6
|
def initialize(task)
|
4
7
|
@task = task
|
5
8
|
@app_class = task.class_name.to_s
|
@@ -30,26 +33,6 @@ class Jets::Resource
|
|
30
33
|
finalize_properties!(props)
|
31
34
|
end
|
32
35
|
|
33
|
-
def env_properties
|
34
|
-
env_vars = Jets::Dotenv.load!(true)
|
35
|
-
variables = environment.merge(env_vars)
|
36
|
-
{environment: { variables: variables }}
|
37
|
-
end
|
38
|
-
|
39
|
-
def environment
|
40
|
-
env = Jets.config.environment ? Jets.config.environment.to_h : {}
|
41
|
-
env.deep_merge(jets_env)
|
42
|
-
end
|
43
|
-
|
44
|
-
# These jets env variables are always included
|
45
|
-
def jets_env
|
46
|
-
env = {}
|
47
|
-
env[:JETS_ENV] = Jets.env.to_s
|
48
|
-
env[:JETS_ENV_EXTRA] = Jets.config.env_extra if Jets.config.env_extra
|
49
|
-
env[:JETS_STAGE] = Jets::Resource::ApiGateway::Deployment.stage_name
|
50
|
-
env
|
51
|
-
end
|
52
|
-
|
53
36
|
# Global properties example:
|
54
37
|
# jets defaults are in jets/default/application.rb.
|
55
38
|
# Your application's default config/application.rb then get used. Example:
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Jets::Resource::Function
|
2
|
+
module Environment
|
3
|
+
def env_properties
|
4
|
+
env_vars = Jets::Dotenv.load!(true)
|
5
|
+
variables = environment.merge(env_vars)
|
6
|
+
{environment: { variables: variables }}
|
7
|
+
end
|
8
|
+
|
9
|
+
def environment
|
10
|
+
env = Jets.config.environment ? Jets.config.environment.to_h : {}
|
11
|
+
env.deep_merge(jets_env)
|
12
|
+
end
|
13
|
+
|
14
|
+
# These jets env variables are always included
|
15
|
+
def jets_env
|
16
|
+
env = {}
|
17
|
+
env[:JETS_ENV] = Jets.env.to_s
|
18
|
+
env[:JETS_ENV_EXTRA] = Jets.config.env_extra if Jets.config.env_extra
|
19
|
+
env[:JETS_STAGE] = Jets::Resource::ApiGateway::Deployment.stage_name
|
20
|
+
env
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# CloudFormation Docs AWS::Route53::RecordSet: https://amzn.to/2BtP9s5
|
2
|
+
#
|
3
|
+
# Example:
|
4
|
+
#
|
5
|
+
# DnsRecord:
|
6
|
+
# Type: AWS::Route53::RecordSet
|
7
|
+
# Properties:
|
8
|
+
# HostedZoneName: !Ref 'HostedZoneResource'
|
9
|
+
# Comment: DNS name for my instance.
|
10
|
+
# Name: !Join ['', [!Ref 'Ec2Instance', ., !Ref 'AWS::Region', ., !Ref 'HostedZone', .]]
|
11
|
+
# Type: A
|
12
|
+
# TTL: '900'
|
13
|
+
# ResourceRecords:
|
14
|
+
# - !GetAtt Ec2Instance.PublicIp
|
15
|
+
module Jets::Resource::Route53
|
16
|
+
class RecordSet < Jets::Resource::Base
|
17
|
+
def definition
|
18
|
+
{
|
19
|
+
dns_record: {
|
20
|
+
type: "AWS::Route53::RecordSet",
|
21
|
+
properties: {
|
22
|
+
hosted_zone_name: hosted_zone_name,
|
23
|
+
comment: "DNS record managed by Jets",
|
24
|
+
name: name,
|
25
|
+
type: "CNAME",
|
26
|
+
ttl: "60",
|
27
|
+
resource_records: [
|
28
|
+
cname,
|
29
|
+
],
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def cname
|
36
|
+
if endpoint_types.include?("REGIONAL")
|
37
|
+
"!GetAtt DomainName.RegionalDomainName"
|
38
|
+
else
|
39
|
+
"!GetAtt DomainName.DistributionDomainName"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def domain_name
|
44
|
+
Jets::Resource::ApiGateway::DomainName.new
|
45
|
+
end
|
46
|
+
memoize :domain_name
|
47
|
+
|
48
|
+
def endpoint_types
|
49
|
+
domain_name.endpoint_types
|
50
|
+
end
|
51
|
+
|
52
|
+
# IE: demo-dev.mydomain.com
|
53
|
+
def name
|
54
|
+
# Weird looking but correct: domain_name is object and domain_name is also method
|
55
|
+
domain_name.domain_name
|
56
|
+
end
|
57
|
+
|
58
|
+
# IE: mydomain.com
|
59
|
+
def hosted_zone_name
|
60
|
+
name = Jets.config.domain.hosted_zone_name
|
61
|
+
name.ends_with?('.') ? name : "#{name}." # add trailing period if missing
|
62
|
+
end
|
63
|
+
|
64
|
+
def outputs
|
65
|
+
{
|
66
|
+
"DnsRecord" => "!Ref DnsRecord",
|
67
|
+
}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/jets/router.rb
CHANGED
@@ -26,6 +26,8 @@ module Jets
|
|
26
26
|
post "#{name}", to: "#{name}#create"
|
27
27
|
get "#{name}/:id/edit", to: "#{name}#edit" unless api_mode?
|
28
28
|
put "#{name}/:id", to: "#{name}#update"
|
29
|
+
post "#{name}/:id", to: "#{name}#update" # for binary uploads
|
30
|
+
patch "#{name}/:id", to: "#{name}#update"
|
29
31
|
delete "#{name}/:id", to: "#{name}#delete"
|
30
32
|
end
|
31
33
|
|
data/lib/jets/ruby_server.rb
CHANGED
@@ -17,7 +17,6 @@ module Jets
|
|
17
17
|
|
18
18
|
def run
|
19
19
|
Jets.boot(stringio: true) # outside of child process for COW
|
20
|
-
Jets.eager_load!
|
21
20
|
|
22
21
|
# INT - ^C
|
23
22
|
trap('INT') do
|
@@ -94,9 +93,10 @@ module Jets
|
|
94
93
|
loop do
|
95
94
|
client = server.accept # Wait for a client to connect
|
96
95
|
|
97
|
-
input_completed, event, handler = nil, nil, nil
|
96
|
+
input_completed, event, context, handler = nil, nil, nil
|
98
97
|
unless input_completed
|
99
98
|
event = client.gets&.strip # text or nil
|
99
|
+
context = client.gets&.strip # text or nil
|
100
100
|
handler = client.gets&.strip # text or nil
|
101
101
|
# The event is nil when a client connects and immediately disconnects without sending data
|
102
102
|
if event.nil?
|
@@ -107,9 +107,12 @@ module Jets
|
|
107
107
|
input_completed = true
|
108
108
|
end
|
109
109
|
|
110
|
+
# puts "ruby_server.rb event: #{event.inspect}"
|
111
|
+
# puts "ruby_server.rb context: #{context.inspect}"
|
112
|
+
|
110
113
|
result = event['_prewarm'] ?
|
111
114
|
prewarm_request(event) :
|
112
|
-
standard_request(event,
|
115
|
+
standard_request(event, context, handler)
|
113
116
|
|
114
117
|
Jets::IO.flush # flush output and write to disk for node shim
|
115
118
|
|
data/lib/jets/stack.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/concern'
|
2
|
-
|
3
1
|
module Jets
|
4
2
|
class Stack
|
5
3
|
autoload :Definition, 'jets/stack/definition' # Registration and definitions
|
@@ -75,7 +73,7 @@ module Jets
|
|
75
73
|
|
76
74
|
def eager_load_shared_resources!
|
77
75
|
ActiveSupport::Dependencies.autoload_paths += ["#{Jets.root}app/shared/resources"]
|
78
|
-
Dir.glob("#{Jets.root}app/shared/resources
|
76
|
+
Dir.glob("#{Jets.root}app/shared/resources/**/*.rb").select do |path|
|
79
77
|
next if !File.file?(path) or path =~ %r{/javascript/} or path =~ %r{/views/}
|
80
78
|
|
81
79
|
class_name = path
|