rise-cli 0.2.7 → 0.2.8
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/.gitignore +2 -2
- data/.rspec_status +7 -7
- data/.rubocop.yml +2 -2
- data/.travis.yml +9 -9
- data/CONTRIBUTING.md +27 -27
- data/Gemfile +16 -16
- data/Gemfile.lock +97 -95
- data/LICENSE +21 -21
- data/README.md +62 -63
- data/Rakefile +6 -6
- data/TODO.txt +6 -7
- data/bin/console +14 -14
- data/bin/rise +112 -112
- data/bin/setup +0 -0
- data/lib/core/constants.rb +17 -17
- data/lib/core/text.rb +23 -23
- data/lib/core/transport.rb +75 -73
- data/lib/core/util.rb +137 -137
- data/lib/core.rb +9 -9
- data/rise-cli.gemspec +27 -27
- data/scripts/test_and_build.sh +15 -15
- metadata +3 -3
data/bin/rise
CHANGED
@@ -1,112 +1,112 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'core'
|
4
|
-
|
5
|
-
options = {}
|
6
|
-
options[:open] = false
|
7
|
-
options[:ignore_files] = nil
|
8
|
-
OptionParser.new do |opts|
|
9
|
-
opts.banner = "\nUsage: #{File.basename($PROGRAM_NAME)} [options] [task]\nRise version: #{Rise::Constants::VERSION}"
|
10
|
-
opts.separator Paint["\nGlobal Options: ", '#95a5a6']
|
11
|
-
|
12
|
-
opts.on('-d DIR', '--dir DIR', String, 'Upload files in DIR (Defaults to the current directory)') do |d|
|
13
|
-
options[:directory] = d unless d.nil?
|
14
|
-
end
|
15
|
-
|
16
|
-
opts.on('-q', '--quiet', 'Run with very little output (only shows result URL)') do
|
17
|
-
options[:quiet] = true
|
18
|
-
end
|
19
|
-
|
20
|
-
opts.on('-v', '--version', 'Show the rise version and exit') do
|
21
|
-
puts "Rise version: #{Paint[Rise::Constants::VERSION, '#2ecc71']}"
|
22
|
-
exit 0
|
23
|
-
end
|
24
|
-
|
25
|
-
opts.on('--verbose', 'Run verbosely') do
|
26
|
-
ENV['RISE_VERBOSE'] = 'yes'
|
27
|
-
end
|
28
|
-
|
29
|
-
opts.on('-i', '--ignore FILES', Array, 'Ignore the given files in the upload. These will be ignored if there is a .riseignore file.') do |a|
|
30
|
-
options[:ignored_files] = a unless a.nil?
|
31
|
-
puts "Reminder: You can add the files to .riseignore instead of using the -i flag"
|
32
|
-
end
|
33
|
-
|
34
|
-
opts.on('-o', '--open', 'Open the deployment in a browser if possible') do
|
35
|
-
options[:open] = true
|
36
|
-
end
|
37
|
-
|
38
|
-
opts.on('-u', '--update', 'Check if rise has a newer version and install it (aliased by `update` task)') do
|
39
|
-
Rise::Util.check_for_update!
|
40
|
-
exit 0
|
41
|
-
end
|
42
|
-
|
43
|
-
opts.on('-h', '--help', 'Show this help message') do
|
44
|
-
puts opts
|
45
|
-
puts Rise::Text::TASKS_HELP
|
46
|
-
exit
|
47
|
-
end
|
48
|
-
|
49
|
-
opts.separator Paint["\nTasks: ", '#95a5a6']
|
50
|
-
|
51
|
-
end.parse!(ARGV)
|
52
|
-
|
53
|
-
# Ladies and gentlemen, this is what
|
54
|
-
# happens when optparse doesn't have
|
55
|
-
# good subcommand/task syntax support
|
56
|
-
while (opt = ARGV.shift) do
|
57
|
-
case opt
|
58
|
-
when 'init'
|
59
|
-
Rise::Util.setup(false)
|
60
|
-
exit 0
|
61
|
-
when 'update'
|
62
|
-
Rise::Util.check_for_update!
|
63
|
-
exit 0
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
|
68
|
-
if Rise::Util.first_run?
|
69
|
-
Rise::Util.setup
|
70
|
-
exit 0
|
71
|
-
end
|
72
|
-
Rise::Util.check_for_update!
|
73
|
-
dir = options[:directory] || Dir.pwd
|
74
|
-
ignored = nil
|
75
|
-
result_url = ''
|
76
|
-
|
77
|
-
begin
|
78
|
-
ignored = File.read(File.join(dir, '.riseignore')).split("\n").map { |a| a.gsub!(' ', '')}
|
79
|
-
rescue Errno::ENOENT
|
80
|
-
ignored = options[:ignored_files]
|
81
|
-
end
|
82
|
-
|
83
|
-
key = JSON.parse(File.read(File.join(RISE_DATA_DIR, 'auth', 'creds.json')))['hash']
|
84
|
-
uploader = Rise::Transport::Uploader.new(dir, key, ignored)
|
85
|
-
|
86
|
-
if uploader.total_files_size > 52428800
|
87
|
-
puts Paint["Max file size reached (#{uploader.total_files_size} > 50MB)", '#FF0000']
|
88
|
-
exit 0
|
89
|
-
end
|
90
|
-
|
91
|
-
if options[:quiet]
|
92
|
-
result_url = uploader.upload!
|
93
|
-
Clipboard.copy(result_url)
|
94
|
-
print Paint["Your url is: #{result_url} (copied to clipboard) ", :bold]
|
95
|
-
exit 0
|
96
|
-
end
|
97
|
-
|
98
|
-
puts Paint['Thanks for using Rise! Your local source for serverless deployment!', '#95a5a6']
|
99
|
-
|
100
|
-
Whirly.start(spinner: 'dots', status: "Uploading files (#{uploader.total_files} total files)") do
|
101
|
-
beginning_time = Time.now
|
102
|
-
result_url = uploader.upload! # Do the file upload
|
103
|
-
|
104
|
-
Whirly.status = "Done!\n"
|
105
|
-
Clipboard.copy(result_url)
|
106
|
-
print Paint["Your url is: #{result_url} (copied to clipboard) ", :bold]
|
107
|
-
puts Paint["[#{((Time.now - beginning_time)).round(2)}s]", '#95a5a6']
|
108
|
-
|
109
|
-
puts Paint['Deployment successful!', '#3498db']
|
110
|
-
|
111
|
-
Rise::Util.open_deployment_in_browser(result_url) if options[:open]
|
112
|
-
end
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'core'
|
4
|
+
|
5
|
+
options = {}
|
6
|
+
options[:open] = false
|
7
|
+
options[:ignore_files] = nil
|
8
|
+
OptionParser.new do |opts|
|
9
|
+
opts.banner = "\nUsage: #{File.basename($PROGRAM_NAME)} [options] [task]\nRise version: #{Rise::Constants::VERSION}"
|
10
|
+
opts.separator Paint["\nGlobal Options: ", '#95a5a6']
|
11
|
+
|
12
|
+
opts.on('-d DIR', '--dir DIR', String, 'Upload files in DIR (Defaults to the current directory)') do |d|
|
13
|
+
options[:directory] = d unless d.nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
opts.on('-q', '--quiet', 'Run with very little output (only shows result URL)') do
|
17
|
+
options[:quiet] = true
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on('-v', '--version', 'Show the rise version and exit') do
|
21
|
+
puts "Rise version: #{Paint[Rise::Constants::VERSION, '#2ecc71']}"
|
22
|
+
exit 0
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on('--verbose', 'Run verbosely') do
|
26
|
+
ENV['RISE_VERBOSE'] = 'yes'
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on('-i', '--ignore FILES', Array, 'Ignore the given files in the upload. These will be ignored if there is a .riseignore file.') do |a|
|
30
|
+
options[:ignored_files] = a unless a.nil?
|
31
|
+
puts "Reminder: You can add the files to .riseignore instead of using the -i flag"
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on('-o', '--open', 'Open the deployment in a browser if possible') do
|
35
|
+
options[:open] = true
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on('-u', '--update', 'Check if rise has a newer version and install it (aliased by `update` task)') do
|
39
|
+
Rise::Util.check_for_update!
|
40
|
+
exit 0
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.on('-h', '--help', 'Show this help message') do
|
44
|
+
puts opts
|
45
|
+
puts Rise::Text::TASKS_HELP
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
|
49
|
+
opts.separator Paint["\nTasks: ", '#95a5a6']
|
50
|
+
|
51
|
+
end.parse!(ARGV)
|
52
|
+
|
53
|
+
# Ladies and gentlemen, this is what
|
54
|
+
# happens when optparse doesn't have
|
55
|
+
# good subcommand/task syntax support
|
56
|
+
while (opt = ARGV.shift) do
|
57
|
+
case opt
|
58
|
+
when 'init'
|
59
|
+
Rise::Util.setup(false)
|
60
|
+
exit 0
|
61
|
+
when 'update'
|
62
|
+
Rise::Util.check_for_update!
|
63
|
+
exit 0
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
if Rise::Util.first_run?
|
69
|
+
Rise::Util.setup
|
70
|
+
exit 0
|
71
|
+
end
|
72
|
+
Rise::Util.check_for_update!
|
73
|
+
dir = options[:directory] || Dir.pwd
|
74
|
+
ignored = nil
|
75
|
+
result_url = ''
|
76
|
+
|
77
|
+
begin
|
78
|
+
ignored = File.read(File.join(dir, '.riseignore')).split("\n").map { |a| a.gsub!(' ', '')}
|
79
|
+
rescue Errno::ENOENT
|
80
|
+
ignored = options[:ignored_files]
|
81
|
+
end
|
82
|
+
|
83
|
+
key = JSON.parse(File.read(File.join(RISE_DATA_DIR, 'auth', 'creds.json')))['hash']
|
84
|
+
uploader = Rise::Transport::Uploader.new(dir, key, ignored)
|
85
|
+
|
86
|
+
if uploader.total_files_size > 52428800
|
87
|
+
puts Paint["Max file size reached (#{uploader.total_files_size} > 50MB)", '#FF0000']
|
88
|
+
exit 0
|
89
|
+
end
|
90
|
+
|
91
|
+
if options[:quiet]
|
92
|
+
result_url = uploader.upload!
|
93
|
+
Clipboard.copy(result_url)
|
94
|
+
print Paint["Your url is: #{result_url} (copied to clipboard) ", :bold]
|
95
|
+
exit 0
|
96
|
+
end
|
97
|
+
|
98
|
+
puts Paint['Thanks for using Rise! Your local source for serverless deployment!', '#95a5a6']
|
99
|
+
|
100
|
+
Whirly.start(spinner: 'dots', status: "Uploading files (#{uploader.total_files} total files)") do
|
101
|
+
beginning_time = Time.now
|
102
|
+
result_url = uploader.upload! # Do the file upload
|
103
|
+
|
104
|
+
Whirly.status = "Done!\n"
|
105
|
+
Clipboard.copy(result_url)
|
106
|
+
print Paint["Your url is: #{result_url} (copied to clipboard) ", :bold]
|
107
|
+
puts Paint["[#{((Time.now - beginning_time)).round(2)}s]", '#95a5a6']
|
108
|
+
|
109
|
+
puts Paint['Deployment successful!', '#3498db']
|
110
|
+
|
111
|
+
Rise::Util.open_deployment_in_browser(result_url) if options[:open]
|
112
|
+
end
|
data/bin/setup
CHANGED
File without changes
|
data/lib/core/constants.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
RISE_DATA_DIR = File.join(Dir.home, '.rise')
|
2
|
-
DOMAIN = 'rise.sh'.freeze
|
3
|
-
AUTH_PORT = 4567
|
4
|
-
UPLOAD_PORT = 8080
|
5
|
-
|
6
|
-
module Rise
|
7
|
-
#
|
8
|
-
# Holds constants used throughout the framework
|
9
|
-
#
|
10
|
-
module Constants
|
11
|
-
VERSION = '0.2.
|
12
|
-
EMAIL = '0xCB@protonmail.com'.freeze
|
13
|
-
AUTHORS = ['Carter Brainerd']
|
14
|
-
NAME = 'rise-cli'.freeze
|
15
|
-
RISE_DIR = File.join(File.dirname(__FILE__), '..', '..')
|
16
|
-
end
|
17
|
-
end
|
1
|
+
RISE_DATA_DIR = File.join(Dir.home, '.rise')
|
2
|
+
DOMAIN = 'rise.sh'.freeze
|
3
|
+
AUTH_PORT = 4567
|
4
|
+
UPLOAD_PORT = 8080
|
5
|
+
|
6
|
+
module Rise
|
7
|
+
#
|
8
|
+
# Holds constants used throughout the framework
|
9
|
+
#
|
10
|
+
module Constants
|
11
|
+
VERSION = '0.2.8'.freeze
|
12
|
+
EMAIL = '0xCB@protonmail.com'.freeze
|
13
|
+
AUTHORS = ['Carter Brainerd']
|
14
|
+
NAME = 'rise-cli'.freeze
|
15
|
+
RISE_DIR = File.join(File.dirname(__FILE__), '..', '..')
|
16
|
+
end
|
17
|
+
end
|
data/lib/core/text.rb
CHANGED
@@ -1,23 +1,23 @@
|
|
1
|
-
require 'paint'
|
2
|
-
#
|
3
|
-
# Text and printing utility methods
|
4
|
-
#
|
5
|
-
module Rise
|
6
|
-
module Text
|
7
|
-
TASKS_HELP =
|
8
|
-
%Q{ init Reinitialize your password hash. (You will lose you old hash FOREVER)
|
9
|
-
update Updates the current rise-cli installation (aliased by -u)
|
10
|
-
|
11
|
-
#{Paint['Examples:', '#95a5a6']}
|
12
|
-
#{Paint['$ rise init --verbose', '#2ecc71']} Reinitializes your password with verbose output
|
13
|
-
#{Paint['$ rise -d ../my-project -o', '#2ecc71']} Will upload all files in `../my-project` and open it in a browser
|
14
|
-
}
|
15
|
-
|
16
|
-
#
|
17
|
-
# Prints +msg+ if the +RISE_VERBOSE+ environment variable is set to 'yes' (set with --verbose)
|
18
|
-
#
|
19
|
-
def self.vputs(msg='')
|
20
|
-
puts msg if ENV['RISE_VERBOSE'] == 'yes'
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
1
|
+
require 'paint'
|
2
|
+
#
|
3
|
+
# Text and printing utility methods
|
4
|
+
#
|
5
|
+
module Rise
|
6
|
+
module Text
|
7
|
+
TASKS_HELP =
|
8
|
+
%Q{ init Reinitialize your password hash. (You will lose you old hash FOREVER)
|
9
|
+
update Updates the current rise-cli installation (aliased by -u)
|
10
|
+
|
11
|
+
#{Paint['Examples:', '#95a5a6']}
|
12
|
+
#{Paint['$ rise init --verbose', '#2ecc71']} Reinitializes your password with verbose output
|
13
|
+
#{Paint['$ rise -d ../my-project -o', '#2ecc71']} Will upload all files in `../my-project` and open it in a browser
|
14
|
+
}
|
15
|
+
|
16
|
+
#
|
17
|
+
# Prints +msg+ if the +RISE_VERBOSE+ environment variable is set to 'yes' (set with --verbose)
|
18
|
+
#
|
19
|
+
def self.vputs(msg='')
|
20
|
+
puts msg if ENV['RISE_VERBOSE'] == 'yes'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/core/transport.rb
CHANGED
@@ -1,73 +1,75 @@
|
|
1
|
-
require 'rex/text'
|
2
|
-
require 'uri'
|
3
|
-
require 'json'
|
4
|
-
require 'http'
|
5
|
-
require 'active_support'
|
6
|
-
|
7
|
-
|
8
|
-
module Rise
|
9
|
-
#
|
10
|
-
# Handles all communication with the rise upload server
|
11
|
-
#
|
12
|
-
module Transport
|
13
|
-
# Handles uploading files
|
14
|
-
class Uploader
|
15
|
-
attr_reader :folder_path, :total_files, :include_folder
|
16
|
-
attr_reader :uuid, :current_file, :total_files_size, :key
|
17
|
-
attr_accessor :files
|
18
|
-
|
19
|
-
def initialize(folder_path, key, excluded_files = [], include_folder = true)
|
20
|
-
excluded_files.map! do |a|
|
21
|
-
File.join(File.absolute_path(folder_path), a)
|
22
|
-
end unless excluded_files.nil?
|
23
|
-
@folder_path = folder_path
|
24
|
-
@files = Dir.glob("#{File.absolute_path(folder_path)}/**/*")
|
25
|
-
@files -= excluded_files unless excluded_files.nil?
|
26
|
-
@total_files = @files.length
|
27
|
-
@total_files_size = calculate_files_size
|
28
|
-
@include_folder = include_folder
|
29
|
-
@uuid = "#{File.basename(File.absolute_path(folder_path)).gsub('_', '-')}-#{Rex::Text.rand_text_alphanumeric(8)}" # Structure: foldername-8RNDLTRS
|
30
|
-
@key = key
|
31
|
-
end
|
32
|
-
|
33
|
-
# This makes a HTTP +PUT+ request on port 8080 to the /api/v1/ endpoint
|
34
|
-
# for each file in the selected folder.
|
35
|
-
#
|
36
|
-
# The body of the request is the contents of the file.
|
37
|
-
#
|
38
|
-
# The +Authorization+ request header is used for making the .keyfile on the serverside
|
39
|
-
# for the future file deletion method.
|
40
|
-
# @return String the final URL of the uploaded contents
|
41
|
-
#
|
42
|
-
def upload!
|
43
|
-
upload_uri_base = "http://rise.sh
|
44
|
-
access_uri = "https://rise.sh/#{@uuid}"
|
45
|
-
uri = ''
|
46
|
-
|
47
|
-
# This sorts the files by (file path) length.
|
48
|
-
# It is supposed to make the server make the first layer of files
|
49
|
-
# before the rest of the layers.
|
50
|
-
ordered_files = files.sort_by(&:length)
|
51
|
-
ordered_files.each do |f|
|
52
|
-
isdir = File.directory?(f)
|
53
|
-
final_path = File.absolute_path(f).gsub(
|
54
|
-
File.expand_path(folder_path), '')
|
55
|
-
uri = URI.parse("#{upload_uri_base}/#{final_path.gsub(' ', '')}?dir=#{isdir}")
|
56
|
-
begin
|
57
|
-
HTTP.auth("#{key}").put(uri.to_s, body: ActiveSupport::Gzip.compress(File.read(f)))
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
1
|
+
require 'rex/text'
|
2
|
+
require 'uri'
|
3
|
+
require 'json'
|
4
|
+
require 'http'
|
5
|
+
require 'active_support'
|
6
|
+
|
7
|
+
|
8
|
+
module Rise
|
9
|
+
#
|
10
|
+
# Handles all communication with the rise upload server
|
11
|
+
#
|
12
|
+
module Transport
|
13
|
+
# Handles uploading files
|
14
|
+
class Uploader
|
15
|
+
attr_reader :folder_path, :total_files, :include_folder
|
16
|
+
attr_reader :uuid, :current_file, :total_files_size, :key
|
17
|
+
attr_accessor :files
|
18
|
+
|
19
|
+
def initialize(folder_path, key, excluded_files = [], include_folder = true)
|
20
|
+
excluded_files.map! do |a|
|
21
|
+
File.join(File.absolute_path(folder_path), a)
|
22
|
+
end unless excluded_files.nil?
|
23
|
+
@folder_path = folder_path
|
24
|
+
@files = Dir.glob("#{File.absolute_path(folder_path)}/**/*")
|
25
|
+
@files -= excluded_files unless excluded_files.nil?
|
26
|
+
@total_files = @files.length
|
27
|
+
@total_files_size = calculate_files_size
|
28
|
+
@include_folder = include_folder
|
29
|
+
@uuid = "#{File.basename(File.absolute_path(folder_path)).gsub('_', '-')}-#{Rex::Text.rand_text_alphanumeric(8)}" # Structure: foldername-8RNDLTRS
|
30
|
+
@key = key
|
31
|
+
end
|
32
|
+
|
33
|
+
# This makes a HTTP +PUT+ request on port 8080 to the /api/v1/ endpoint
|
34
|
+
# for each file in the selected folder.
|
35
|
+
#
|
36
|
+
# The body of the request is the contents of the file.
|
37
|
+
#
|
38
|
+
# The +Authorization+ request header is used for making the .keyfile on the serverside
|
39
|
+
# for the future file deletion method.
|
40
|
+
# @return String the final URL of the uploaded contents
|
41
|
+
#
|
42
|
+
def upload!
|
43
|
+
upload_uri_base = "http://rise.sh/api/v1/#{@uuid}"
|
44
|
+
access_uri = "https://rise.sh/#{@uuid}"
|
45
|
+
uri = ''
|
46
|
+
|
47
|
+
# This sorts the files by (file path) length.
|
48
|
+
# It is supposed to make the server make the first layer of files
|
49
|
+
# before the rest of the layers.
|
50
|
+
ordered_files = files.sort_by(&:length)
|
51
|
+
ordered_files.each do |f|
|
52
|
+
isdir = File.directory?(f)
|
53
|
+
final_path = File.absolute_path(f).gsub(
|
54
|
+
File.expand_path(folder_path), '')
|
55
|
+
uri = URI.parse("#{upload_uri_base}/#{final_path.gsub(' ', '')}?dir=#{isdir}")
|
56
|
+
begin
|
57
|
+
res = HTTP.auth("#{key}").put(uri.to_s, body: ActiveSupport::Gzip.compress(File.read(f)))
|
58
|
+
abort(Paint["Upload failed. Got error code #{res.code} with message: #{JSON.parse(res)['message']}", :red]) unless (!res.code.nil? && res.code == 200)
|
59
|
+
rescue Errno::EISDIR
|
60
|
+
res = HTTP.auth("#{key}").put(uri.to_s, body: '')
|
61
|
+
abort(Paint["Upload failed. Got error code #{res.code} with message: #{JSON.parse(res)['message']}", :red]) unless (!res.code.nil? && res.code == 200)
|
62
|
+
next
|
63
|
+
end
|
64
|
+
end
|
65
|
+
access_uri
|
66
|
+
end
|
67
|
+
|
68
|
+
protected
|
69
|
+
|
70
|
+
def calculate_files_size
|
71
|
+
@files.inject(0){|sum, file| sum + File.size(file)}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|