faastruby 0.3.5 → 0.3.6
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/Gemfile.lock +1 -1
- data/lib/faastruby/cli/commands/function/new.rb +83 -17
- data/lib/faastruby/version.rb +1 -1
- data/templates/crystal/example-blank/spec/handler_spec.cr +8 -0
- data/templates/crystal/example-blank/spec/helpers/faastruby.cr +77 -0
- data/templates/crystal/example-blank/spec/spec_helper.cr +4 -0
- data/templates/crystal/example-blank/src/handler.cr +25 -0
- data/templates/crystal/example/spec/handler_spec.cr +27 -0
- data/templates/crystal/example/spec/helpers/faastruby.cr +77 -0
- data/templates/crystal/example/spec/spec_helper.cr +4 -0
- data/templates/crystal/example/src/handler.cr +27 -0
- data/{example-blank → templates/ruby/example-blank}/Gemfile +0 -0
- data/{example-blank → templates/ruby/example-blank}/handler.rb +2 -0
- data/{example-blank → templates/ruby/example-blank}/spec/handler_spec.rb +0 -0
- data/{example-blank → templates/ruby/example-blank}/spec/helpers/faastruby.rb +0 -0
- data/{example-blank → templates/ruby/example-blank}/spec/spec_helper.rb +0 -0
- data/{example → templates/ruby/example}/Gemfile +0 -0
- data/{example → templates/ruby/example}/handler.rb +1 -3
- data/{example → templates/ruby/example}/spec/handler_spec.rb +0 -0
- data/{example → templates/ruby/example}/spec/helpers/faastruby.rb +0 -1
- data/{example → templates/ruby/example}/spec/spec_helper.rb +0 -0
- metadata +20 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4086556ca79303b6f5648d703b26a0a7f5170baa4f9736027d9aa728afe1bf47
|
4
|
+
data.tar.gz: 5f8ed48b70913ecd61208b08315ef199492d8f1c02cf7cf7d42101a32313b0ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af818d48b8e17d6d56290f4181b6aadb026a8734bc7ee51d84ce5536dabf52ca728e9c15de7c8c8096e7ea06aff8e8bba2503cd6e44a0dd3b00386ae6bc0c473
|
7
|
+
data.tar.gz: 7f6e33b947949e7d825930e2f5a0d87daf85c0ae2cce858ed01b58da52a39d592b093e52efa9332af4341e9a04b185d4f5d7d849f4d6a09df124de4107177dcd
|
data/Gemfile.lock
CHANGED
@@ -8,29 +8,29 @@ module FaaStRuby
|
|
8
8
|
FaaStRuby::CLI.error(@missing_args, color: nil) if missing_args.any?
|
9
9
|
@function_name = @args.shift
|
10
10
|
@base_dir = "./#{@function_name}"
|
11
|
-
@yaml_content = {
|
12
|
-
'name' => @function_name,
|
13
|
-
'test_command' => 'rspec',
|
14
|
-
'abort_build_when_tests_fail' => true,
|
15
|
-
'abort_deploy_when_tests_fail' => true
|
16
|
-
}
|
17
11
|
parse_options
|
12
|
+
@options['template_path'] ||= 'templates/ruby'
|
18
13
|
@options['template'] ||= 'example'
|
14
|
+
@options['runtime_name'] ||= 'ruby'
|
15
|
+
@options['runtime_version'] ||= '2.5.3'
|
16
|
+
@yaml_content = yaml_for(@options['runtime_name'])
|
19
17
|
end
|
20
18
|
|
21
19
|
def run
|
22
20
|
dir_exists? unless @options['force']
|
23
21
|
copy_template
|
24
22
|
write_yaml
|
25
|
-
|
23
|
+
post_tasks(@options['runtime_name'])
|
26
24
|
end
|
27
25
|
|
28
26
|
def self.help
|
29
|
-
"new".blue + " FUNCTION_NAME [--blank] [--force]" +
|
27
|
+
"new".blue + " FUNCTION_NAME [--blank] [--force] [--runtime]" +
|
30
28
|
<<-EOS
|
31
29
|
|
32
30
|
--blank # Create a blank function
|
33
31
|
--force # Continue if directory already exists and overwrite files
|
32
|
+
--runtime # Choose the runtime. Options are: crystal:0.27.0,
|
33
|
+
# ruby:2.5.3 (default) and ruby:2.6.0
|
34
34
|
EOS
|
35
35
|
end
|
36
36
|
|
@@ -45,6 +45,10 @@ EOS
|
|
45
45
|
while @args.any?
|
46
46
|
option = @args.shift
|
47
47
|
case option
|
48
|
+
when '--runtime'
|
49
|
+
@options['runtime'] = @args.shift
|
50
|
+
@options['runtime_name'], @options['runtime_version'] = @options['runtime'].split(':')
|
51
|
+
@options['template_path'] = "templates/#{@options['runtime_name']}"
|
48
52
|
when '-f', '--force'
|
49
53
|
@options['force'] = true
|
50
54
|
when '--blank'
|
@@ -71,28 +75,90 @@ EOS
|
|
71
75
|
end
|
72
76
|
|
73
77
|
def copy_template
|
74
|
-
source = "#{Gem::Specification.find_by_name("faastruby").gem_dir}/#{@options['template']}"
|
78
|
+
source = "#{Gem::Specification.find_by_name("faastruby").gem_dir}/#{@options['template_path']}/#{@options['template']}"
|
75
79
|
FileUtils.mkdir_p(@base_dir)
|
76
80
|
FileUtils.cp_r("#{source}/.", "#{@base_dir}/")
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
81
|
+
case @options['runtime_name']
|
82
|
+
when 'ruby'
|
83
|
+
puts "+ d #{@base_dir}".green
|
84
|
+
puts "+ d #{@base_dir}/spec".green
|
85
|
+
puts "+ d #{@base_dir}/spec/helpers".green
|
86
|
+
puts "+ f #{@base_dir}/spec/helpers/faastruby.rb".green
|
87
|
+
puts "+ f #{@base_dir}/spec/handler_spec.rb".green
|
88
|
+
puts "+ f #{@base_dir}/spec/spec_helper.rb".green
|
89
|
+
puts "+ f #{@base_dir}/Gemfile".green
|
90
|
+
puts "+ f #{@base_dir}/handler.rb".green
|
91
|
+
when 'crystal'
|
92
|
+
puts "+ d #{@base_dir}".green
|
93
|
+
puts "+ d #{@base_dir}/spec".green
|
94
|
+
puts "+ d #{@base_dir}/spec/helpers".green
|
95
|
+
puts "+ f #{@base_dir}/spec/helpers/faastruby.cr".green
|
96
|
+
puts "+ f #{@base_dir}/spec/handler_spec.cr".green
|
97
|
+
puts "+ f #{@base_dir}/spec/spec_helper.cr".green
|
98
|
+
puts "+ d #{@base_dir}/src".green
|
99
|
+
puts "+ f #{@base_dir}/src/handler.cr".green
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def yaml_for(runtime_name)
|
104
|
+
case runtime_name
|
105
|
+
when 'crystal'
|
106
|
+
test_command = 'crystal spec --no-color'
|
107
|
+
when 'ruby'
|
108
|
+
test_command = 'rspec'
|
109
|
+
else
|
110
|
+
test_command = 'rspec'
|
111
|
+
end
|
112
|
+
{
|
113
|
+
'name' => @function_name,
|
114
|
+
'runtime' => @options['runtime'],
|
115
|
+
'test_command' => test_command,
|
116
|
+
'abort_build_when_tests_fail' => true,
|
117
|
+
'abort_deploy_when_tests_fail' => true
|
118
|
+
}
|
85
119
|
end
|
86
120
|
|
87
121
|
def write_yaml
|
88
122
|
write_file("#{@base_dir}/faastruby.yml", @yaml_content.to_yaml)
|
89
123
|
end
|
90
124
|
|
125
|
+
def post_tasks(runtime_name)
|
126
|
+
case runtime_name
|
127
|
+
when 'ruby'
|
128
|
+
bundle_install
|
129
|
+
when 'crystal'
|
130
|
+
write_shards_file
|
131
|
+
shards_install
|
132
|
+
else
|
133
|
+
bundle_install
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
91
137
|
def bundle_install
|
92
138
|
spinner = spin("Installing gems...")
|
93
139
|
system("bundle install --gemfile=#{@base_dir}/Gemfile > /dev/null")
|
94
140
|
spinner.stop('Done!')
|
95
141
|
end
|
142
|
+
|
143
|
+
def write_shards_file
|
144
|
+
shards = {
|
145
|
+
'name' => @function_name,
|
146
|
+
'version' => '0.1.0',
|
147
|
+
'crystal' => @options['runtime_version'],
|
148
|
+
'targets' => {
|
149
|
+
@function_name => {
|
150
|
+
'main' => 'src/handler.cr'
|
151
|
+
}
|
152
|
+
}
|
153
|
+
}.to_yaml
|
154
|
+
write_file("#{@base_dir}/shard.yml", shards)
|
155
|
+
end
|
156
|
+
|
157
|
+
def shards_install
|
158
|
+
spinner = spin("Installing shards...")
|
159
|
+
system("cd #{@base_dir} && shards install > /dev/null")
|
160
|
+
spinner.stop('Done!')
|
161
|
+
end
|
96
162
|
end
|
97
163
|
end
|
98
164
|
end
|
data/lib/faastruby/version.rb
CHANGED
@@ -0,0 +1,77 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "json"
|
3
|
+
require "base64"
|
4
|
+
|
5
|
+
module FaaStRuby
|
6
|
+
class Event
|
7
|
+
JSON.mapping(
|
8
|
+
body: String?,
|
9
|
+
headers: Hash(String, String),
|
10
|
+
context: String?,
|
11
|
+
query_params: Hash(String, String)
|
12
|
+
)
|
13
|
+
end
|
14
|
+
class Response
|
15
|
+
@@rendered = false
|
16
|
+
property "body"
|
17
|
+
property "status"
|
18
|
+
property "headers"
|
19
|
+
property "io"
|
20
|
+
def initialize(@body : String?, @status : Int32, @headers : Hash(String, String))
|
21
|
+
@io = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(@io : Bytes, @status : Int32, @headers : Hash(String, String))
|
25
|
+
end
|
26
|
+
|
27
|
+
def payload
|
28
|
+
if io
|
29
|
+
hash = {
|
30
|
+
"response" => Base64.encode(io.not_nil!),
|
31
|
+
"status" => status,
|
32
|
+
"headers" => headers
|
33
|
+
}
|
34
|
+
else
|
35
|
+
hash = {
|
36
|
+
"response" => body,
|
37
|
+
"status" => status,
|
38
|
+
"headers" => headers
|
39
|
+
}
|
40
|
+
end
|
41
|
+
hash
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def respond_with(body : String? = nil, status : Int32 = 200, headers : Hash(String, String) = {} of String => String)
|
46
|
+
Response.new(body: body, status: status, headers: headers)
|
47
|
+
end
|
48
|
+
|
49
|
+
def respond_with(io : Bytes, status : Int32 = 200, headers : Hash(String, String) = {} of String => String)
|
50
|
+
Response.new(io: io, status: status, headers: headers)
|
51
|
+
end
|
52
|
+
|
53
|
+
def render(io : Bytes? = nil, js : String? = nil, inline : String? = nil, html : String? = nil, json : String? = nil, yaml : String? = nil, text : String? = nil, status : Int32 = 200, headers : Hash(String, String) = {} of String => String, content_type : String? = nil)
|
54
|
+
headers["Content-Type"] = content_type if content_type
|
55
|
+
case
|
56
|
+
when json
|
57
|
+
headers["Content-Type"] ||= "application/json"
|
58
|
+
resp_body = json
|
59
|
+
when html, inline
|
60
|
+
headers["Content-Type"] ||= "text/html"
|
61
|
+
resp_body = html
|
62
|
+
when text
|
63
|
+
headers["Content-Type"] ||= "text/plain"
|
64
|
+
resp_body = text
|
65
|
+
when yaml
|
66
|
+
headers["Content-Type"] ||= "text/yaml"
|
67
|
+
resp_body = yaml
|
68
|
+
when js
|
69
|
+
headers["Content-Type"] ||= "text/javascript"
|
70
|
+
resp_body = js
|
71
|
+
when io
|
72
|
+
headers["Content-Type"] ||= "application/octet-stream"
|
73
|
+
return respond_with(io: io, status: status, headers: headers)
|
74
|
+
end
|
75
|
+
respond_with(body: resp_body, status: status, headers: headers)
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# To deploy this function, cd into its folder and run:
|
2
|
+
# faastruby deploy-to WORKSPACE_NAME
|
3
|
+
def handler(event : FaaStRuby::Event) : FaaStRuby::Response
|
4
|
+
# event.body : String | Nil
|
5
|
+
# event.headers : Hash(String, String)
|
6
|
+
# event.context : String | Nil
|
7
|
+
# query_params : Hash(String, String)
|
8
|
+
|
9
|
+
# FUNCTION RESPONSE
|
10
|
+
#
|
11
|
+
# You can render text, json, yaml, html or js. Example:
|
12
|
+
# render html: "<p>Hello World!</p>"
|
13
|
+
# render yaml: {"hello" => "world!"}
|
14
|
+
#
|
15
|
+
# Status:
|
16
|
+
# The default status is 200. You can set a custom status like this:
|
17
|
+
# render json: {"error" => "Could not perform the action"}, status: 422
|
18
|
+
#
|
19
|
+
# Headers:
|
20
|
+
# The 'Content-Type' header is automatically set when you use 'render'.
|
21
|
+
# You can set custom headers using a Hash(String, String). Example:
|
22
|
+
# render text: "It Works!", headers: {"TransactionId" => 23928}
|
23
|
+
|
24
|
+
# TODO: Write code here!
|
25
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "./spec_helper"
|
2
|
+
|
3
|
+
describe "handler(event)" do
|
4
|
+
body = {"name" => "Ruby"}.to_json
|
5
|
+
event_hash = {
|
6
|
+
"body" => body,
|
7
|
+
"context" => nil,
|
8
|
+
"headers" => {"Content-Type" => "application/json"},
|
9
|
+
"query_params" => {} of String => String
|
10
|
+
}
|
11
|
+
event = Event.from_json(event_hash.to_json)
|
12
|
+
|
13
|
+
it "should return Hash, String or Array" do
|
14
|
+
body = handler(event).body
|
15
|
+
body.class.should eq(String)
|
16
|
+
end
|
17
|
+
it "should add the name to the response string" do
|
18
|
+
body = handler(event).body
|
19
|
+
body.should eq("Hello, Ruby!\n")
|
20
|
+
end
|
21
|
+
it "should say Hello, World! when name is not present" do
|
22
|
+
event_hash["body"] = nil
|
23
|
+
event = Event.from_json(event_hash.to_json)
|
24
|
+
body = handler(event).body
|
25
|
+
body.should eq("Hello, World!\n")
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "json"
|
3
|
+
require "base64"
|
4
|
+
|
5
|
+
module FaaStRuby
|
6
|
+
class Event
|
7
|
+
JSON.mapping(
|
8
|
+
body: String?,
|
9
|
+
headers: Hash(String, String),
|
10
|
+
context: String?,
|
11
|
+
query_params: Hash(String, String)
|
12
|
+
)
|
13
|
+
end
|
14
|
+
class Response
|
15
|
+
@@rendered = false
|
16
|
+
property "body"
|
17
|
+
property "status"
|
18
|
+
property "headers"
|
19
|
+
property "io"
|
20
|
+
def initialize(@body : String?, @status : Int32, @headers : Hash(String, String))
|
21
|
+
@io = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(@io : Bytes, @status : Int32, @headers : Hash(String, String))
|
25
|
+
end
|
26
|
+
|
27
|
+
def payload
|
28
|
+
if io
|
29
|
+
hash = {
|
30
|
+
"response" => Base64.encode(io.not_nil!),
|
31
|
+
"status" => status,
|
32
|
+
"headers" => headers
|
33
|
+
}
|
34
|
+
else
|
35
|
+
hash = {
|
36
|
+
"response" => body,
|
37
|
+
"status" => status,
|
38
|
+
"headers" => headers
|
39
|
+
}
|
40
|
+
end
|
41
|
+
hash
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def respond_with(body : String? = nil, status : Int32 = 200, headers : Hash(String, String) = {} of String => String)
|
46
|
+
Response.new(body: body, status: status, headers: headers)
|
47
|
+
end
|
48
|
+
|
49
|
+
def respond_with(io : Bytes, status : Int32 = 200, headers : Hash(String, String) = {} of String => String)
|
50
|
+
Response.new(io: io, status: status, headers: headers)
|
51
|
+
end
|
52
|
+
|
53
|
+
def render(io : Bytes? = nil, js : String? = nil, inline : String? = nil, html : String? = nil, json : String? = nil, yaml : String? = nil, text : String? = nil, status : Int32 = 200, headers : Hash(String, String) = {} of String => String, content_type : String? = nil)
|
54
|
+
headers["Content-Type"] = content_type if content_type
|
55
|
+
case
|
56
|
+
when json
|
57
|
+
headers["Content-Type"] ||= "application/json"
|
58
|
+
resp_body = json
|
59
|
+
when html, inline
|
60
|
+
headers["Content-Type"] ||= "text/html"
|
61
|
+
resp_body = html
|
62
|
+
when text
|
63
|
+
headers["Content-Type"] ||= "text/plain"
|
64
|
+
resp_body = text
|
65
|
+
when yaml
|
66
|
+
headers["Content-Type"] ||= "text/yaml"
|
67
|
+
resp_body = yaml
|
68
|
+
when js
|
69
|
+
headers["Content-Type"] ||= "text/javascript"
|
70
|
+
resp_body = js
|
71
|
+
when io
|
72
|
+
headers["Content-Type"] ||= "application/octet-stream"
|
73
|
+
return respond_with(io: io, status: status, headers: headers)
|
74
|
+
end
|
75
|
+
respond_with(body: resp_body, status: status, headers: headers)
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# require "cool-shard"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
# To deploy this function, cd into its folder and run:
|
5
|
+
# faastruby deploy-to WORKSPACE_NAME
|
6
|
+
def handler(event : FaaStRuby::Event) : FaaStRuby::Response
|
7
|
+
# event.body : String | Nil
|
8
|
+
# event.headers : Hash(String, String)
|
9
|
+
# event.context : String | Nil
|
10
|
+
# query_params : Hash(String, String)
|
11
|
+
data = JSON.parse(event.body.not_nil!) rescue {} of String => String
|
12
|
+
# FUNCTION RESPONSE
|
13
|
+
#
|
14
|
+
# You can render text, json, yaml, html or js. Example:
|
15
|
+
# render html: "<p>Hello World!</p>"
|
16
|
+
# render yaml: {"hello" => "world!"}
|
17
|
+
#
|
18
|
+
# Status:
|
19
|
+
# The default status is 200. You can set a custom status like this:
|
20
|
+
# render json: {"error" => "Could not perform the action"}, status: 422
|
21
|
+
#
|
22
|
+
# Headers:
|
23
|
+
# The 'Content-Type' header is automatically set when you use 'render'.
|
24
|
+
# You can set custom headers using a Hash(String, String). Example:
|
25
|
+
# render text: "It Works!", headers: {"TransactionId" => 23928}
|
26
|
+
render text: "Hello, #{data["name"]? || "World"}!\n"
|
27
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,9 +1,7 @@
|
|
1
1
|
# require 'cool-gem'
|
2
2
|
require 'json'
|
3
3
|
|
4
|
-
#
|
5
|
-
# faastruby create-workspace WORKSPACE_NAME
|
6
|
-
# 2) To deploy this function, cd into its folder and run:
|
4
|
+
# To deploy this function, cd into its folder and run:
|
7
5
|
# faastruby deploy-to WORKSPACE_NAME
|
8
6
|
def handler event
|
9
7
|
data = event.body ? JSON.parse(event.body) : {}
|
File without changes
|
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faastruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paulo Arruda
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
11
|
+
date: 2018-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -226,16 +226,6 @@ files:
|
|
226
226
|
- Rakefile
|
227
227
|
- bin/console
|
228
228
|
- bin/setup
|
229
|
-
- example-blank/Gemfile
|
230
|
-
- example-blank/handler.rb
|
231
|
-
- example-blank/spec/handler_spec.rb
|
232
|
-
- example-blank/spec/helpers/faastruby.rb
|
233
|
-
- example-blank/spec/spec_helper.rb
|
234
|
-
- example/Gemfile
|
235
|
-
- example/handler.rb
|
236
|
-
- example/spec/handler_spec.rb
|
237
|
-
- example/spec/helpers/faastruby.rb
|
238
|
-
- example/spec/spec_helper.rb
|
239
229
|
- exe/faastruby
|
240
230
|
- exe/faastruby-server
|
241
231
|
- faastruby.gemspec
|
@@ -268,6 +258,24 @@ files:
|
|
268
258
|
- lib/faastruby/function.rb
|
269
259
|
- lib/faastruby/version.rb
|
270
260
|
- lib/faastruby/workspace.rb
|
261
|
+
- templates/crystal/example-blank/spec/handler_spec.cr
|
262
|
+
- templates/crystal/example-blank/spec/helpers/faastruby.cr
|
263
|
+
- templates/crystal/example-blank/spec/spec_helper.cr
|
264
|
+
- templates/crystal/example-blank/src/handler.cr
|
265
|
+
- templates/crystal/example/spec/handler_spec.cr
|
266
|
+
- templates/crystal/example/spec/helpers/faastruby.cr
|
267
|
+
- templates/crystal/example/spec/spec_helper.cr
|
268
|
+
- templates/crystal/example/src/handler.cr
|
269
|
+
- templates/ruby/example-blank/Gemfile
|
270
|
+
- templates/ruby/example-blank/handler.rb
|
271
|
+
- templates/ruby/example-blank/spec/handler_spec.rb
|
272
|
+
- templates/ruby/example-blank/spec/helpers/faastruby.rb
|
273
|
+
- templates/ruby/example-blank/spec/spec_helper.rb
|
274
|
+
- templates/ruby/example/Gemfile
|
275
|
+
- templates/ruby/example/handler.rb
|
276
|
+
- templates/ruby/example/spec/handler_spec.rb
|
277
|
+
- templates/ruby/example/spec/helpers/faastruby.rb
|
278
|
+
- templates/ruby/example/spec/spec_helper.rb
|
271
279
|
homepage: https://faastruby.io
|
272
280
|
licenses:
|
273
281
|
- MIT
|