rise-cli 0.1.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 +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +8 -0
- data/CONTRIBUTING.md +21 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +58 -0
- data/LICENSE +21 -0
- data/README.md +53 -0
- data/bin/rise +56 -0
- data/img/rise_logo.png +0 -0
- data/lib/core/constants.rb +4 -0
- data/lib/core/transport.rb +52 -0
- data/lib/core/util.rb +88 -0
- data/lib/core.rb +10 -0
- data/rise-cli.gemspec +15 -0
- metadata +58 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: f7286a03eca652a914158802a4d627fd984477c9
|
|
4
|
+
data.tar.gz: afdd779d5dcf909d314bb404aa3515093b8c0bad
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 0da0599524d7d0f1cdce93bd08d713e24b24d9a51009fa14312a0b89591c5caba6cb0e2545fb42ceb127daa6c4170321257619760df80315febc377e426d2a7b
|
|
7
|
+
data.tar.gz: b34df62a02a923da1f53144522bfc25903a4b5aecd56e3a0dce32aec9a5e782cdeb9246b729fea7d176b3384597d759f6ba647d06dadab2c0a5d9c7aa8aed394
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## Thanks!
|
|
2
|
+
Thank you for wanting to contribute to rise!
|
|
3
|
+
If you want to contribute, there are a few guidelines that
|
|
4
|
+
should generally be followed.
|
|
5
|
+
|
|
6
|
+
### Code contributions
|
|
7
|
+
* **Do** your best to stick to the [Ruby style guide]
|
|
8
|
+
* **Do** follow the [50/72 rule] for Git commit messages.
|
|
9
|
+
* **Do** make sure that there are no rubocop warnings on your new code
|
|
10
|
+
|
|
11
|
+
### Pull Requests
|
|
12
|
+
* **Do** have a clear, concise title
|
|
13
|
+
* **Do** include as many details as possible in the pull request body
|
|
14
|
+
* **Do** include console output (if applicable) in your pull request (asciinema if possible)
|
|
15
|
+
* **Do** `require` your new file in `lib/core.rb` and place the file in `lib/core/`if you are adding new library code.
|
|
16
|
+
* **Don't** leave your pull request descriptions blank.
|
|
17
|
+
* **Don't** go radio silent on pull requests, try to reply fast so we can land your code quicker
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
[Ruby style guide]:https://github.com/bbatsov/ruby-style-guide
|
|
21
|
+
[50/72]:http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: https://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
addressable (2.5.2)
|
|
5
|
+
public_suffix (>= 2.0.2, < 4.0)
|
|
6
|
+
ast (2.3.0)
|
|
7
|
+
clipboard (1.1.1)
|
|
8
|
+
domain_name (0.5.20170404)
|
|
9
|
+
unf (>= 0.0.5, < 1.0.0)
|
|
10
|
+
http (3.0.0)
|
|
11
|
+
addressable (~> 2.3)
|
|
12
|
+
http-cookie (~> 1.0)
|
|
13
|
+
http-form_data (>= 2.0.0.pre.pre2, < 3)
|
|
14
|
+
http_parser.rb (~> 0.6.0)
|
|
15
|
+
http-cookie (1.0.3)
|
|
16
|
+
domain_name (~> 0.5)
|
|
17
|
+
http-form_data (2.0.0)
|
|
18
|
+
http_parser.rb (0.6.0)
|
|
19
|
+
paint (2.0.0)
|
|
20
|
+
parallel (1.12.0)
|
|
21
|
+
parser (2.4.0.0)
|
|
22
|
+
ast (~> 2.2)
|
|
23
|
+
powerpack (0.1.1)
|
|
24
|
+
public_suffix (3.0.0)
|
|
25
|
+
rainbow (2.2.2)
|
|
26
|
+
rake
|
|
27
|
+
rake (12.0.0)
|
|
28
|
+
rex-text (0.2.15)
|
|
29
|
+
rubocop (0.50.0)
|
|
30
|
+
parallel (~> 1.10)
|
|
31
|
+
parser (>= 2.3.3.1, < 3.0)
|
|
32
|
+
powerpack (~> 0.1)
|
|
33
|
+
rainbow (>= 2.2.2, < 3.0)
|
|
34
|
+
ruby-progressbar (~> 1.7)
|
|
35
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
|
36
|
+
ruby-progressbar (1.9.0)
|
|
37
|
+
unf (0.1.4)
|
|
38
|
+
unf_ext
|
|
39
|
+
unf_ext (0.0.7.4)
|
|
40
|
+
unf_ext (0.0.7.4-x64-mingw32)
|
|
41
|
+
unicode-display_width (1.3.0)
|
|
42
|
+
whirly (0.2.5)
|
|
43
|
+
unicode-display_width (~> 1.1)
|
|
44
|
+
|
|
45
|
+
PLATFORMS
|
|
46
|
+
ruby
|
|
47
|
+
x64-mingw32
|
|
48
|
+
|
|
49
|
+
DEPENDENCIES
|
|
50
|
+
clipboard
|
|
51
|
+
http
|
|
52
|
+
paint
|
|
53
|
+
rex-text
|
|
54
|
+
rubocop
|
|
55
|
+
whirly
|
|
56
|
+
|
|
57
|
+
BUNDLED WITH
|
|
58
|
+
1.15.4
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 Carter Brainerd
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+

|
|
2
|
+
[](https://codeclimate.com/github/cbrnrd/rise)
|
|
3
|
+
[](https://travis-ci.org/cbrnrd/rise)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# Usage
|
|
7
|
+
|
|
8
|
+
Using rise is simple, just run the `rise` command
|
|
9
|
+
|
|
10
|
+
[](https://asciinema.org/a/KfCcwzkm5b5gKOkfJ9vfBcPQz)
|
|
11
|
+
|
|
12
|
+
## Installing
|
|
13
|
+
|
|
14
|
+
In order to get rise up and running, there's 2 ways you can install it.
|
|
15
|
+
|
|
16
|
+
1. Download the gem
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
gem install rise-cli
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
2. Build from source
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
$ git clone https://github.com/cbrnrd/rise
|
|
26
|
+
$ bundle install
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Built With
|
|
30
|
+
|
|
31
|
+
- [Rubygems](https://rubygems.org) - the Ruby community's gem hosting service
|
|
32
|
+
- [Atom](https://atom.io/) - A hackable text editor for the 21st Century
|
|
33
|
+
- [DigitalOcean](https://digitalocean.com) - Used for server hosting
|
|
34
|
+
|
|
35
|
+
## Contributing
|
|
36
|
+
|
|
37
|
+
Please read [CONTRIBUTING.md](https://github.com/cbrnrd/rise/blob/master/CONTRIBUTING.md) for details on our code of conduct, and the process for submitting a pull requests.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## Coming soon
|
|
41
|
+
- rise.sh registration and 24/7 server uptime
|
|
42
|
+
- gzip file transfer
|
|
43
|
+
- actual use of the password hash for secure uploads
|
|
44
|
+
|
|
45
|
+
## Authors
|
|
46
|
+
|
|
47
|
+
- **Carter Brainerd** - [Website](https://carterbrainerd.me)
|
|
48
|
+
|
|
49
|
+
See also the list of [contributors](https://github.com/cbrnrd/rise/contributors) who participated in this project.
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
|
|
53
|
+
This project is licensed under the MIT License - see the [LICENSE](https://github.com/cbrnrd/rise/blob/master/LICENSE) file for details
|
data/bin/rise
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# TODO
|
|
4
|
+
# => fix recursive upload bug where it only uploads the first layer of files (dirs are just blank files)
|
|
5
|
+
# => UPDATE: dirs are now dirs, but theyre empty, details on server/server.rb:23-24
|
|
6
|
+
# => Try to fix spinner bug on Windows (may be a weird interaction with \r)
|
|
7
|
+
|
|
8
|
+
# Put all our core library files in the require path
|
|
9
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
|
10
|
+
|
|
11
|
+
require 'core'
|
|
12
|
+
|
|
13
|
+
options = {}
|
|
14
|
+
OptionParser.new do |opts|
|
|
15
|
+
opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
|
|
16
|
+
|
|
17
|
+
opts.separator Paint['\nGeneral Options: ', '#95a5a6']
|
|
18
|
+
opts.on('-v', '--verbose', 'Run verbosely') do |v|
|
|
19
|
+
options[:verbose] = v
|
|
20
|
+
end
|
|
21
|
+
# directory flag
|
|
22
|
+
opts.on('-d DIR', '--dir DIR', String, 'Upload files in DIR') do |d|
|
|
23
|
+
options[:directory] = d unless d.nil?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
opts.on('-h', '--help', 'Show this help message') do
|
|
27
|
+
puts opts
|
|
28
|
+
exit
|
|
29
|
+
end
|
|
30
|
+
end.parse!(ARGV)
|
|
31
|
+
|
|
32
|
+
if Rise::Util.is_first_run?
|
|
33
|
+
Rise::Util.setup
|
|
34
|
+
puts '\nPlease run the `rise` command again to upload your files.'
|
|
35
|
+
exit 0
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
result_url = ''
|
|
39
|
+
uploader = Rise::Transport::Uploader.new(options[:directory]) unless options[:directory].nil?
|
|
40
|
+
uploader = Rise::Transport::Uploader.new(Dir.pwd) if options[:directory].nil?
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
puts Paint['Thanks for using Rise! Your local source for serverless deployment!', '#95a5a6']
|
|
44
|
+
|
|
45
|
+
Whirly.start(spinner: 'dots', status: "Uploading files (#{uploader.total_files} total files)") do
|
|
46
|
+
beginning_time = Time.now
|
|
47
|
+
sleep 1 # Just to see the spinner if the files are small
|
|
48
|
+
result_url = uploader.upload!(options[:verbose]) # Do the file upload
|
|
49
|
+
|
|
50
|
+
Whirly.status = 'Done!\n'
|
|
51
|
+
Clipboard.copy(result_url)
|
|
52
|
+
print Paint["Your url is: #{result_url} (copied to clipboard) ", :bold]
|
|
53
|
+
puts Paint["[#{((Time.now - beginning_time)).round(2)}s]", "#95a5a6"]
|
|
54
|
+
|
|
55
|
+
puts Paint['Deployment successful!', '#3498db']
|
|
56
|
+
end
|
data/img/rise_logo.png
ADDED
|
Binary file
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
##
|
|
2
|
+
# This file handles all communication to the Upto servers
|
|
3
|
+
##
|
|
4
|
+
require 'colorize'
|
|
5
|
+
require 'rex/text'
|
|
6
|
+
require 'uri'
|
|
7
|
+
require 'json'
|
|
8
|
+
require 'http'
|
|
9
|
+
|
|
10
|
+
module Rise
|
|
11
|
+
module Transport
|
|
12
|
+
|
|
13
|
+
# Handles uploading files
|
|
14
|
+
class Uploader
|
|
15
|
+
|
|
16
|
+
attr_reader :folder_path, :total_files, :include_folder, :uuid, :current_file
|
|
17
|
+
attr_accessor :files
|
|
18
|
+
|
|
19
|
+
def initialize(folder_path, include_folder=true)
|
|
20
|
+
@folder_path = folder_path
|
|
21
|
+
@files = Dir.glob("#{File.absolute_path(folder_path)}/**/*")
|
|
22
|
+
@total_files = @files.length
|
|
23
|
+
@include_folder = include_folder
|
|
24
|
+
@uuid = "#{File.basename(File.absolute_path(folder_path))}-#{Rex::Text::rand_text_alphanumeric(8)}" # Structure: foldername-8RNDLTRS
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def upload!(*)
|
|
28
|
+
upload_uri_base = "http://rise.sh:8080/api/v1/#{@uuid}"
|
|
29
|
+
access_uri = "http://rise.sh/#{@uuid}"
|
|
30
|
+
uri = ''
|
|
31
|
+
|
|
32
|
+
# This sorts the files by (file path) length.
|
|
33
|
+
# It is supposed to make the server make the first layer of files
|
|
34
|
+
# before the rest of the layers.
|
|
35
|
+
ordered_files = files.sort_by(&:length)
|
|
36
|
+
ordered_files.each do |f|
|
|
37
|
+
isdir = File.directory?(f)
|
|
38
|
+
final_path = File.absolute_path(f).gsub(File.expand_path(folder_path), '')
|
|
39
|
+
uri = URI.parse("#{upload_uri_base}/#{final_path}?dir=#{isdir}")
|
|
40
|
+
begin
|
|
41
|
+
HTTP.put(uri.to_s, :body => File.read(f))
|
|
42
|
+
rescue Errno::EISDIR
|
|
43
|
+
HTTP.put(uri.to_s, :body => '')
|
|
44
|
+
next
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
return access_uri
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
data/lib/core/util.rb
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'paint'
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'http'
|
|
5
|
+
require 'digest'
|
|
6
|
+
require 'io/console'
|
|
7
|
+
require_relative 'constants'
|
|
8
|
+
|
|
9
|
+
#
|
|
10
|
+
# Utility methods
|
|
11
|
+
#
|
|
12
|
+
module Rise
|
|
13
|
+
module Util
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# Checks if rise is being run for the first time
|
|
17
|
+
#
|
|
18
|
+
def self.is_first_run?
|
|
19
|
+
!File.directory?(File.join(Dir.home, '.rise'))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#
|
|
23
|
+
# Creates all of the necessary files and login information
|
|
24
|
+
#
|
|
25
|
+
def self.setup
|
|
26
|
+
puts Paint['Detected first time setup, creating necessary files...', :blue]
|
|
27
|
+
FileUtils.mkdir(RISE_DATA_DIR)
|
|
28
|
+
FileUtils.mkdir(File.join(RISE_DATA_DIR, 'auth'))
|
|
29
|
+
|
|
30
|
+
# Get the input from the user
|
|
31
|
+
print Paint['1. Log in\n2. Sign up\n > ', :bold]
|
|
32
|
+
while (choice = gets.chomp!)
|
|
33
|
+
if choice == '1'
|
|
34
|
+
login
|
|
35
|
+
break
|
|
36
|
+
elsif choice == '2'
|
|
37
|
+
signup
|
|
38
|
+
break
|
|
39
|
+
else
|
|
40
|
+
puts Paint['Please type `1` or `2`', :red]
|
|
41
|
+
next
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# DO NOT USE
|
|
51
|
+
def login
|
|
52
|
+
|
|
53
|
+
print '\nEmail: '
|
|
54
|
+
email = gets.chomp!
|
|
55
|
+
print '\nPassword: '
|
|
56
|
+
password = STDIN.noecho(&:gets)
|
|
57
|
+
hash = Digest::SHA256.hexdigest(password)
|
|
58
|
+
res = HTTP.post("http://#{DOMAIN}:#{AUTH_PORT}/login?email=#{email}&hash=#{hash}")
|
|
59
|
+
if res.code == 200
|
|
60
|
+
puts Paint['\nLogin successful!', :green, :bold]
|
|
61
|
+
else
|
|
62
|
+
puts Paint['\nLogin failed!', :red, :bold]
|
|
63
|
+
puts "Printing error: #{res.code}: #{res.body}"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# DO NOT USE
|
|
68
|
+
def signup
|
|
69
|
+
print '\nEmail: '
|
|
70
|
+
email = gets.chomp!
|
|
71
|
+
print '\nPassword: '
|
|
72
|
+
password = STDIN.noecho(&:gets)
|
|
73
|
+
hash = Digest::SHA256.hexdigest(password)
|
|
74
|
+
res = HTTP.post("http://#{DOMAIN}:#{AUTH_PORT}/signup?email=#{email}&hash=#{hash}")
|
|
75
|
+
if res.code == 200
|
|
76
|
+
puts Paint['\nSignup successful!', :green, :bold]
|
|
77
|
+
File.open(File.join(RISE_DATA_DIR, 'auth', 'creds.json'), 'a') do |f|
|
|
78
|
+
creds_hash = {
|
|
79
|
+
'email' => email,
|
|
80
|
+
'hash' => hash
|
|
81
|
+
}
|
|
82
|
+
f.puts(creds_hash.to_json)
|
|
83
|
+
end
|
|
84
|
+
elsif res.code == 409 # user already exists
|
|
85
|
+
puts Paint['\nSignup failed!', :red, :bold]
|
|
86
|
+
puts "Printing error: #{res.body}"
|
|
87
|
+
end
|
|
88
|
+
end
|
data/lib/core.rb
ADDED
data/rise-cli.gemspec
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Gem::Specification.new do |s|
|
|
2
|
+
s.name = 'rise-cli'
|
|
3
|
+
s.version = '0.1.0'
|
|
4
|
+
s.executables << 'rise'
|
|
5
|
+
s.date = '2017-10-04'
|
|
6
|
+
s.summary = "Simple serverless website deployment"
|
|
7
|
+
s.authors = ["Carter Brainerd"]
|
|
8
|
+
s.email = '0xCB@protonmail.com'
|
|
9
|
+
s.files = `git ls-files`.split($/).reject { |file|
|
|
10
|
+
file =~ /^server|rise.gemspec/
|
|
11
|
+
}
|
|
12
|
+
s.homepage =
|
|
13
|
+
'http://rubygems.org/gems/rise-cli'
|
|
14
|
+
s.license = 'MIT'
|
|
15
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rise-cli
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Carter Brainerd
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2017-10-04 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description:
|
|
14
|
+
email: 0xCB@protonmail.com
|
|
15
|
+
executables:
|
|
16
|
+
- rise
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- ".gitignore"
|
|
21
|
+
- ".travis.yml"
|
|
22
|
+
- CONTRIBUTING.md
|
|
23
|
+
- Gemfile
|
|
24
|
+
- Gemfile.lock
|
|
25
|
+
- LICENSE
|
|
26
|
+
- README.md
|
|
27
|
+
- bin/rise
|
|
28
|
+
- img/rise_logo.png
|
|
29
|
+
- lib/core.rb
|
|
30
|
+
- lib/core/constants.rb
|
|
31
|
+
- lib/core/transport.rb
|
|
32
|
+
- lib/core/util.rb
|
|
33
|
+
- rise-cli.gemspec
|
|
34
|
+
homepage: http://rubygems.org/gems/rise-cli
|
|
35
|
+
licenses:
|
|
36
|
+
- MIT
|
|
37
|
+
metadata: {}
|
|
38
|
+
post_install_message:
|
|
39
|
+
rdoc_options: []
|
|
40
|
+
require_paths:
|
|
41
|
+
- lib
|
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
48
|
+
requirements:
|
|
49
|
+
- - ">="
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: '0'
|
|
52
|
+
requirements: []
|
|
53
|
+
rubyforge_project:
|
|
54
|
+
rubygems_version: 2.5.2
|
|
55
|
+
signing_key:
|
|
56
|
+
specification_version: 4
|
|
57
|
+
summary: Simple serverless website deployment
|
|
58
|
+
test_files: []
|