faastruby 0.2.2 → 0.2.3
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/.rspec +1 -0
- data/.travis.yml +9 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +29 -2
- data/README.md +1 -0
- data/faastruby.gemspec +2 -0
- data/lib/faastruby/api.rb +32 -31
- data/lib/faastruby/cli/commands/function/update_context.rb +2 -2
- data/lib/faastruby/cli/commands/help.rb +5 -0
- data/lib/faastruby/cli/credentials.rb +1 -0
- data/lib/faastruby/function.rb +8 -8
- data/lib/faastruby/version.rb +1 -1
- data/lib/faastruby/workspace.rb +28 -5
- metadata +32 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 93b8ffe62b7276bfd5a04730fc3d4643b43eb9be2bebced9d9c13a984af3405c
|
|
4
|
+
data.tar.gz: d38f0c66d2d392916870ec2db8d651b887b1281deb0ee5a88e94e6fafae0c92e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2b9e4b1cbb7abc709dbbe25c385aa40b881a0d14217fc6c56276de115f2b97653230e18dc8668255b8f33ad1b92711d3eb5c001b1c3dd9751084e0b69d30dd11
|
|
7
|
+
data.tar.gz: 1ed5d7c3d34154aa334f570b2e8825bf76efd00bdd687f6dd57ab7d9118f9897a0d7434b75cd64d4fd708addf96e7cabef19fb29e2a86f9d21af63b36fdfcd14
|
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--require spec_helper
|
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.3 - Unreleased
|
|
4
|
+
- Added #status_code to Workspace class to hold the API response code after a request
|
|
5
|
+
- Added refresh_credentials endpoint
|
|
6
|
+
- Fix the request headers
|
|
7
|
+
- Fix bug with `faastruby help`
|
|
8
|
+
|
|
3
9
|
## 0.2.2 - Oct 20 2018
|
|
4
10
|
### New
|
|
5
11
|
- Functions can be scheduled via faastruby.yml
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
faastruby (0.2.
|
|
4
|
+
faastruby (0.2.3)
|
|
5
5
|
colorize (~> 0.8)
|
|
6
6
|
oj (~> 3.6)
|
|
7
7
|
rest-client (~> 2.0)
|
|
@@ -12,10 +12,16 @@ PATH
|
|
|
12
12
|
GEM
|
|
13
13
|
remote: https://rubygems.org/
|
|
14
14
|
specs:
|
|
15
|
+
addressable (2.5.2)
|
|
16
|
+
public_suffix (>= 2.0.2, < 4.0)
|
|
15
17
|
colorize (0.8.1)
|
|
18
|
+
crack (0.4.3)
|
|
19
|
+
safe_yaml (~> 1.0.0)
|
|
20
|
+
diff-lcs (1.3)
|
|
16
21
|
domain_name (0.5.20180417)
|
|
17
22
|
unf (>= 0.0.5, < 1.0.0)
|
|
18
23
|
equatable (0.5.0)
|
|
24
|
+
hashdiff (0.3.7)
|
|
19
25
|
http-cookie (1.0.3)
|
|
20
26
|
domain_name (~> 0.5)
|
|
21
27
|
mime-types (3.2.2)
|
|
@@ -23,16 +29,31 @@ GEM
|
|
|
23
29
|
mime-types-data (3.2018.0812)
|
|
24
30
|
necromancer (0.4.0)
|
|
25
31
|
netrc (0.11.0)
|
|
26
|
-
oj (3.6.
|
|
32
|
+
oj (3.6.12)
|
|
27
33
|
pastel (0.7.2)
|
|
28
34
|
equatable (~> 0.5.0)
|
|
29
35
|
tty-color (~> 0.4.0)
|
|
36
|
+
public_suffix (3.0.3)
|
|
30
37
|
rake (10.5.0)
|
|
31
38
|
rest-client (2.0.2)
|
|
32
39
|
http-cookie (>= 1.0.2, < 2.0)
|
|
33
40
|
mime-types (>= 1.16, < 4.0)
|
|
34
41
|
netrc (~> 0.8)
|
|
42
|
+
rspec (3.8.0)
|
|
43
|
+
rspec-core (~> 3.8.0)
|
|
44
|
+
rspec-expectations (~> 3.8.0)
|
|
45
|
+
rspec-mocks (~> 3.8.0)
|
|
46
|
+
rspec-core (3.8.0)
|
|
47
|
+
rspec-support (~> 3.8.0)
|
|
48
|
+
rspec-expectations (3.8.2)
|
|
49
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
50
|
+
rspec-support (~> 3.8.0)
|
|
51
|
+
rspec-mocks (3.8.0)
|
|
52
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
53
|
+
rspec-support (~> 3.8.0)
|
|
54
|
+
rspec-support (3.8.0)
|
|
35
55
|
rubyzip (1.2.2)
|
|
56
|
+
safe_yaml (1.0.4)
|
|
36
57
|
strings (0.1.4)
|
|
37
58
|
strings-ansi (~> 0.1.0)
|
|
38
59
|
unicode-display_width (~> 1.4.0)
|
|
@@ -54,6 +75,10 @@ GEM
|
|
|
54
75
|
unf_ext (0.0.7.5)
|
|
55
76
|
unicode-display_width (1.4.0)
|
|
56
77
|
unicode_utils (1.4.0)
|
|
78
|
+
webmock (3.4.2)
|
|
79
|
+
addressable (>= 2.3.6)
|
|
80
|
+
crack (>= 0.3.2)
|
|
81
|
+
hashdiff
|
|
57
82
|
|
|
58
83
|
PLATFORMS
|
|
59
84
|
ruby
|
|
@@ -62,6 +87,8 @@ DEPENDENCIES
|
|
|
62
87
|
bundler (~> 1.16)
|
|
63
88
|
faastruby!
|
|
64
89
|
rake (~> 10.0)
|
|
90
|
+
rspec (~> 3.8)
|
|
91
|
+
webmock (~> 3.4)
|
|
65
92
|
|
|
66
93
|
BUNDLED WITH
|
|
67
94
|
1.16.5
|
data/README.md
CHANGED
data/faastruby.gemspec
CHANGED
data/lib/faastruby/api.rb
CHANGED
|
@@ -3,16 +3,19 @@ require 'rest-client'
|
|
|
3
3
|
module FaaStRuby
|
|
4
4
|
class API
|
|
5
5
|
@@api_version = 'v2'
|
|
6
|
+
attr_reader :api_url, :credentials, :headers
|
|
6
7
|
def initialize
|
|
7
8
|
@api_url = "#{HOST}/#{@@api_version}"
|
|
8
9
|
@credentials = {'API-KEY' => FaaStRuby.api_key, 'API-SECRET' => FaaStRuby.api_secret}
|
|
9
|
-
@headers = {content_type:
|
|
10
|
+
@headers = {content_type: 'application/json', accept: 'application/json'}.merge(@credentials)
|
|
11
|
+
@struct = Struct.new(:response, :body, :errors, :code)
|
|
10
12
|
end
|
|
11
13
|
|
|
12
|
-
def create_workspace(workspace_name:, email: nil)
|
|
14
|
+
def create_workspace(workspace_name:, email: nil, provider: nil)
|
|
13
15
|
url = "#{@api_url}/workspaces"
|
|
14
16
|
payload = {'name' => workspace_name}
|
|
15
17
|
payload['email'] = email if email
|
|
18
|
+
payload['provider'] = provider if provider
|
|
16
19
|
parse RestClient.post(url, Oj.dump(payload), @headers){|response, request, result| response }
|
|
17
20
|
end
|
|
18
21
|
|
|
@@ -31,21 +34,27 @@ module FaaStRuby
|
|
|
31
34
|
parse RestClient.get(url, @headers){|response, request, result| response }
|
|
32
35
|
end
|
|
33
36
|
|
|
37
|
+
def refresh_credentials(workspace_name)
|
|
38
|
+
url = "#{@api_url}/workspaces/#{workspace_name}/credentials"
|
|
39
|
+
payload = {}
|
|
40
|
+
parse RestClient.put(url, payload, @credentials){|response, request, result| response }
|
|
41
|
+
end
|
|
42
|
+
|
|
34
43
|
def deploy(workspace_name:, package:)
|
|
35
44
|
url = "#{@api_url}/workspaces/#{workspace_name}/deploy"
|
|
36
45
|
payload = {package: File.new(package, 'rb')}
|
|
37
46
|
parse RestClient.post(url, payload, @credentials){|response, request, result| response }
|
|
38
47
|
end
|
|
39
48
|
|
|
40
|
-
def delete_from_workspace(
|
|
41
|
-
url = "#{@api_url}/workspaces/#{
|
|
49
|
+
def delete_from_workspace(function_name:, workspace_name:)
|
|
50
|
+
url = "#{@api_url}/workspaces/#{workspace_name}/functions/#{function_name}"
|
|
42
51
|
parse RestClient.delete(url, @headers){|response, request, result| response }
|
|
43
52
|
end
|
|
44
53
|
|
|
45
|
-
def list_workspace_functions(workspace_name)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
end
|
|
54
|
+
# def list_workspace_functions(workspace_name)
|
|
55
|
+
# url = "#{@api_url}/workspaces/#{workspace_name}/functions"
|
|
56
|
+
# parse RestClient.get(url, @headers){|response, request, result| response }
|
|
57
|
+
# end
|
|
49
58
|
|
|
50
59
|
def run(function_name:, workspace_name:, payload:, method:, headers: {}, time: false, query: nil)
|
|
51
60
|
url = "#{HOST}/#{workspace_name}/#{function_name}#{query}"
|
|
@@ -57,41 +66,33 @@ module FaaStRuby
|
|
|
57
66
|
end
|
|
58
67
|
end
|
|
59
68
|
|
|
60
|
-
def update_function_context(
|
|
69
|
+
def update_function_context(function_name:, workspace_name:, payload:)
|
|
61
70
|
# payload is a string
|
|
62
|
-
url = "#{@api_url}/workspaces/#{
|
|
71
|
+
url = "#{@api_url}/workspaces/#{workspace_name}/functions/#{function_name}"
|
|
63
72
|
parse RestClient.patch(url, Oj.dump(payload), @headers){|response, request, result| response }
|
|
64
73
|
end
|
|
65
74
|
|
|
66
75
|
def parse(response)
|
|
67
|
-
|
|
76
|
+
body = Oj.load(response.body) unless [500, 408].include?(response.code)
|
|
68
77
|
case response.code
|
|
69
|
-
when 401
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
when
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
when 409
|
|
76
|
-
body = Oj.load(response.body)
|
|
77
|
-
return struct.new(nil, nil, ["(409) Conflict - #{body['error']}"], 409)
|
|
78
|
-
when 500
|
|
79
|
-
return struct.new(nil, nil, ["(500) Error"], 500)
|
|
80
|
-
when 408
|
|
81
|
-
return struct.new(nil, nil, ["(408) Request Timeout"], 408)
|
|
78
|
+
when 401 then return error(["(401) Unauthorized - #{body['error']}"], 401)
|
|
79
|
+
when 404 then return error(["(404) Not Found - #{body['error']}"], 404)
|
|
80
|
+
when 409 then return error(["(409) Conflict - #{body['error']}"], 409)
|
|
81
|
+
when 500 then return error(["(500) Error"], 500)
|
|
82
|
+
when 408 then return error(["(408) Request Timeout"], 408)
|
|
83
|
+
when 402 then return error(["(402) Limit Exceeded - #{body['error']}"], 402)
|
|
82
84
|
when 422
|
|
83
|
-
body = Oj.load(response.body)
|
|
84
85
|
errors = ["(422) Unprocessable Entity"]
|
|
85
86
|
errors << body['error'] if body['error']
|
|
86
87
|
errors += body['errors'] if body['errors']
|
|
87
|
-
return
|
|
88
|
-
when 402 # Limit excedeed
|
|
89
|
-
body = Oj.load(response.body)
|
|
90
|
-
return struct.new(nil, nil, ["(402) Limit Exceeded - #{body['error']}"], 402)
|
|
88
|
+
return error(errors, 422)
|
|
91
89
|
else
|
|
92
|
-
|
|
93
|
-
return struct.new(response, body, (body['errors'] || []), response.code)
|
|
90
|
+
return @struct.new(response, body, (body['errors'] || []), response.code)
|
|
94
91
|
end
|
|
95
92
|
end
|
|
93
|
+
|
|
94
|
+
def error(errors, code)
|
|
95
|
+
@struct.new(nil, nil, errors, code)
|
|
96
|
+
end
|
|
96
97
|
end
|
|
97
98
|
end
|
|
@@ -16,8 +16,8 @@ module FaaStRuby
|
|
|
16
16
|
def run
|
|
17
17
|
spinner = spin("Uploading context data to '#{@workspace_name}'...")
|
|
18
18
|
workspace = FaaStRuby::Workspace.new(name: @workspace_name)
|
|
19
|
-
function = FaaStRuby::Function.new(name: @function_name, workspace: workspace
|
|
20
|
-
function.update
|
|
19
|
+
function = FaaStRuby::Function.new(name: @function_name, workspace: workspace)
|
|
20
|
+
function.update(new_context: @options['data'])
|
|
21
21
|
if function.errors.any?
|
|
22
22
|
spinner.stop('Failed :(')
|
|
23
23
|
FaaStRuby::CLI.error(function.errors)
|
|
@@ -13,18 +13,23 @@ module FaaStRuby
|
|
|
13
13
|
puts
|
|
14
14
|
workspaces = ["Workspaces:"]
|
|
15
15
|
functions = ["Functions:"]
|
|
16
|
+
credentials = ["Credentials:"]
|
|
16
17
|
FaaStRuby::Command::COMMANDS.each do |command, klass|
|
|
17
18
|
next if command == 'upgrade'
|
|
18
19
|
next if klass.to_s.match(/.+Command::Help$/)
|
|
19
20
|
next if klass.to_s.match(/.+Command::Version$/)
|
|
20
21
|
section = functions if klass.to_s.match(/.+::Function::.+/)
|
|
21
22
|
section = workspaces if klass.to_s.match(/.+::Workspace::.+/)
|
|
23
|
+
section = credentials if klass.to_s.match(/.+::Credentials::.+/)
|
|
24
|
+
section ||= []
|
|
22
25
|
section << " #{klass.help}"
|
|
23
26
|
end
|
|
24
27
|
puts workspaces
|
|
25
28
|
puts
|
|
26
29
|
puts functions
|
|
27
30
|
puts
|
|
31
|
+
puts credentials
|
|
32
|
+
puts
|
|
28
33
|
end
|
|
29
34
|
end
|
|
30
35
|
end
|
|
@@ -45,6 +45,7 @@ module FaaStRuby
|
|
|
45
45
|
|
|
46
46
|
def self.load_from_env(workspace_name)
|
|
47
47
|
return nil unless ENV['FAASTRUBY_API_KEY'] && ENV['FAASTRUBY_API_SECRET']
|
|
48
|
+
puts "#{"WARNING:".red} Using credentials from env vars FAASTRUBY_API_KEY and FAASTRUBY_API_SECRET"
|
|
48
49
|
{workspace_name => {'api_key' => ENV['FAASTRUBY_API_KEY'], 'api_secret' => ENV['FAASTRUBY_API_SECRET']}}
|
|
49
50
|
end
|
|
50
51
|
end
|
data/lib/faastruby/function.rb
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
module FaaStRuby
|
|
2
2
|
class Function < BaseObject
|
|
3
|
-
attr_accessor :name, :workspace, :errors, :context
|
|
3
|
+
attr_accessor :name, :workspace, :errors, :context, :updated_at, :created_at
|
|
4
4
|
|
|
5
5
|
def run(options)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
response = @api.run(function_name: name, workspace_name: options['workspace_name'], payload: options['body'], method: method, headers: headers, time: options['time'], query: options['query'])
|
|
6
|
+
options['method'] ||= 'get'
|
|
7
|
+
options['headers'] ||= {}
|
|
8
|
+
response = @api.run(function_name: name, workspace_name: options['workspace_name'], payload: options['body'], method: options['method'], headers: options['headers'], time: options['time'], query: options['query'])
|
|
9
9
|
response
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def destroy
|
|
13
|
-
response = @api.delete_from_workspace(
|
|
13
|
+
response = @api.delete_from_workspace(function_name: self.name, workspace_name: @workspace.name)
|
|
14
14
|
@errors += response.errors if response.errors.any?
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def update
|
|
18
|
-
payload = {'context' =>
|
|
19
|
-
response = @api.update_function_context(
|
|
17
|
+
def update(new_context:)
|
|
18
|
+
payload = {'context' => new_context}
|
|
19
|
+
response = @api.update_function_context(function_name: self.name, workspace_name: @workspace.name, payload: payload)
|
|
20
20
|
@errors += response.errors if response.errors.any?
|
|
21
21
|
unless @errors.any?
|
|
22
22
|
self.context = response.body['context']
|
data/lib/faastruby/version.rb
CHANGED
data/lib/faastruby/workspace.rb
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
require 'faastruby/api'
|
|
2
|
+
|
|
1
3
|
module FaaStRuby
|
|
2
4
|
class Workspace < BaseObject
|
|
3
5
|
|
|
4
6
|
##### Class methods
|
|
5
|
-
def self.create(name:, email: nil)
|
|
7
|
+
def self.create(name:, email: nil, provider: nil)
|
|
6
8
|
api = API.new
|
|
7
|
-
workspace = Workspace.new(name: name, email: email, errors: [])
|
|
8
|
-
response = api.create_workspace(workspace_name: name, email: email)
|
|
9
|
+
workspace = Workspace.new(name: name, email: email, errors: [], provider: provider)
|
|
10
|
+
response = api.create_workspace(workspace_name: name, email: email, provider: provider)
|
|
11
|
+
workspace.status_code = response.code
|
|
9
12
|
if response.errors.any?
|
|
10
13
|
workspace.errors += response.errors
|
|
11
14
|
return workspace
|
|
@@ -23,27 +26,47 @@ module FaaStRuby
|
|
|
23
26
|
###################
|
|
24
27
|
|
|
25
28
|
##### Instance methods
|
|
26
|
-
attr_accessor :name, :errors, :functions, :email, :object, :credentials
|
|
29
|
+
attr_accessor :name, :errors, :functions, :email, :object, :credentials, :updated_at, :created_at, :status_code, :provider
|
|
27
30
|
|
|
28
31
|
def destroy
|
|
29
32
|
response = @api.destroy_workspace(@name)
|
|
33
|
+
@status_code = response.code
|
|
30
34
|
@errors += response.errors if response.errors.any?
|
|
31
35
|
end
|
|
32
36
|
|
|
33
37
|
def deploy(package_file_name)
|
|
34
38
|
response = @api.deploy(workspace_name: @name, package: package_file_name)
|
|
39
|
+
@status_code = response.code
|
|
40
|
+
@errors += response.errors if response.errors.any?
|
|
41
|
+
self
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def refresh_credentials
|
|
45
|
+
response = @api.refresh_credentials(@name)
|
|
46
|
+
@status_code = response.code
|
|
47
|
+
@credentials = response.body[@name] unless response.body.nil?
|
|
35
48
|
@errors += response.errors if response.errors.any?
|
|
36
49
|
self
|
|
37
50
|
end
|
|
38
51
|
|
|
39
52
|
def fetch
|
|
40
53
|
response = @api.get_workspace_info(@name)
|
|
54
|
+
@status_code = response.code
|
|
41
55
|
if response.errors.any?
|
|
42
56
|
@errors += response.errors
|
|
43
57
|
else
|
|
44
|
-
|
|
58
|
+
parse_attributes(response.body)
|
|
45
59
|
end
|
|
46
60
|
self
|
|
47
61
|
end
|
|
62
|
+
|
|
63
|
+
def parse_attributes(attributes)
|
|
64
|
+
@functions = attributes['functions']
|
|
65
|
+
@email = attributes['email']
|
|
66
|
+
@object = attributes['object']
|
|
67
|
+
@updated_at = attributes['updated_at']
|
|
68
|
+
@created_at = attributes['created_at']
|
|
69
|
+
@provider = attributes['provider']
|
|
70
|
+
end
|
|
48
71
|
end
|
|
49
72
|
end
|
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.2.
|
|
4
|
+
version: 0.2.3
|
|
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-10-
|
|
11
|
+
date: 2018-10-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rest-client
|
|
@@ -122,6 +122,34 @@ dependencies:
|
|
|
122
122
|
- - "~>"
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
124
|
version: '10.0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: rspec
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '3.8'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '3.8'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: webmock
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - "~>"
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '3.4'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - "~>"
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '3.4'
|
|
125
153
|
description:
|
|
126
154
|
email:
|
|
127
155
|
- parrudaj@gmail.com
|
|
@@ -131,6 +159,8 @@ extensions: []
|
|
|
131
159
|
extra_rdoc_files: []
|
|
132
160
|
files:
|
|
133
161
|
- ".gitignore"
|
|
162
|
+
- ".rspec"
|
|
163
|
+
- ".travis.yml"
|
|
134
164
|
- CHANGELOG.md
|
|
135
165
|
- Gemfile
|
|
136
166
|
- Gemfile.lock
|