faastruby 0.4.18 → 0.5.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 +6 -3
- data/Gemfile.lock +28 -4
- data/README.md +63 -5
- data/faastruby.gemspec +5 -1
- data/lib/faastruby.rb +1 -0
- data/lib/faastruby/api.rb +154 -6
- data/lib/faastruby/base.rb +3 -9
- data/lib/faastruby/cli.rb +39 -12
- data/lib/faastruby/cli/base_command.rb +66 -0
- data/lib/faastruby/cli/commands.rb +122 -59
- data/lib/faastruby/cli/commands/account/base_command.rb +10 -0
- data/lib/faastruby/cli/commands/account/confirm.rb +94 -0
- data/lib/faastruby/cli/commands/account/login.rb +86 -0
- data/lib/faastruby/cli/commands/account/logout.rb +59 -0
- data/lib/faastruby/cli/commands/account/signup.rb +76 -0
- data/lib/faastruby/cli/commands/{function.rb → function/base_command.rb} +2 -11
- data/lib/faastruby/cli/commands/function/build.rb +18 -11
- data/lib/faastruby/cli/commands/function/deploy_to.rb +100 -37
- data/lib/faastruby/cli/commands/function/new.rb +89 -36
- data/lib/faastruby/cli/commands/function/remove_from.rb +21 -6
- data/lib/faastruby/cli/commands/function/run.rb +15 -15
- data/lib/faastruby/cli/commands/function/test.rb +5 -4
- data/lib/faastruby/cli/commands/function/update_context.rb +10 -3
- data/lib/faastruby/cli/commands/function/upgrade.rb +62 -61
- data/lib/faastruby/cli/commands/help.rb +33 -20
- data/lib/faastruby/cli/commands/project/base_command.rb +14 -0
- data/lib/faastruby/cli/commands/project/deploy.rb +114 -0
- data/lib/faastruby/cli/commands/project/down.rb +58 -0
- data/lib/faastruby/cli/commands/project/new.rb +237 -0
- data/lib/faastruby/cli/commands/workspace/cp.rb +107 -0
- data/lib/faastruby/cli/commands/workspace/create.rb +35 -27
- data/lib/faastruby/cli/commands/workspace/destroy.rb +14 -7
- data/lib/faastruby/cli/commands/workspace/list.rb +15 -6
- data/lib/faastruby/cli/commands/workspace/migrate.rb +93 -0
- data/lib/faastruby/cli/commands/workspace/rm.rb +81 -0
- data/lib/faastruby/cli/commands/workspace/update.rb +62 -0
- data/lib/faastruby/cli/credentials.rb +58 -57
- data/lib/faastruby/cli/new_credentials.rb +63 -0
- data/lib/faastruby/cli/package.rb +1 -0
- data/lib/faastruby/cli/template.rb +7 -7
- data/lib/faastruby/local.rb +188 -0
- data/lib/faastruby/local/crystal_runtime.cr +170 -0
- data/lib/faastruby/local/functions.rb +7 -0
- data/lib/faastruby/local/functions/crystal.rb +64 -0
- data/lib/faastruby/local/functions/function.rb +173 -0
- data/lib/faastruby/local/functions/ruby.rb +28 -0
- data/lib/faastruby/local/listeners.rb +5 -0
- data/lib/faastruby/local/listeners/listener.rb +104 -0
- data/lib/faastruby/local/logger.rb +37 -0
- data/lib/faastruby/local/monkey_patch.rb +38 -0
- data/lib/faastruby/local/processors.rb +7 -0
- data/lib/faastruby/local/processors/function.rb +151 -0
- data/lib/faastruby/local/processors/processor.rb +116 -0
- data/lib/faastruby/local/processors/static_file.rb +48 -0
- data/lib/faastruby/local/static_files.rb +5 -0
- data/lib/faastruby/local/static_files/static_file.rb +59 -0
- data/lib/faastruby/server.rb +44 -3
- data/lib/faastruby/server/app.rb +107 -0
- data/lib/faastruby/server/concurrency_controller.rb +50 -50
- data/lib/faastruby/server/config.ru +2 -0
- data/lib/faastruby/server/event.rb +3 -0
- data/lib/faastruby/server/event_hub.rb +7 -6
- data/lib/faastruby/server/local.rb +22 -0
- data/lib/faastruby/server/logger.rb +50 -0
- data/lib/faastruby/server/project_config.rb +44 -0
- data/lib/faastruby/server/puma.rb +4 -0
- data/lib/faastruby/server/response.rb +40 -0
- data/lib/faastruby/server/runner.rb +116 -21
- data/lib/faastruby/server/runner_methods.rb +17 -16
- data/lib/faastruby/server/sentinel.rb +496 -0
- data/lib/faastruby/supported_runtimes.rb +8 -0
- data/lib/faastruby/user.rb +77 -0
- data/lib/faastruby/version.rb +1 -1
- data/lib/faastruby/workspace.rb +36 -3
- data/templates/crystal/example-blank/handler.cr +3 -0
- data/templates/crystal/example/spec/handler_spec.cr +11 -6
- data/templates/public-web/assets/images/background.png +0 -0
- data/templates/public-web/assets/images/ruby.png +0 -0
- data/templates/public-web/assets/javascripts/main.js +1 -0
- data/templates/public-web/assets/stylesheets/main.css +70 -0
- data/templates/public-web/favicon.ico +0 -0
- data/templates/ruby/api-404/handler.rb +6 -0
- data/templates/ruby/api-root/handler.rb +6 -0
- data/templates/ruby/example-blank/handler.rb +0 -23
- data/templates/ruby/web-404/404.html +36 -0
- data/templates/ruby/web-404/handler.rb +3 -0
- data/templates/ruby/web-root/handler.rb +10 -0
- data/templates/ruby/web-root/index.html.erb +37 -0
- data/templates/ruby/web-root/template.rb +13 -0
- metadata +102 -21
- data/exe/faastruby-server +0 -76
- data/lib/faastruby/cli/commands/credentials.rb +0 -11
- data/lib/faastruby/cli/commands/credentials/add.rb +0 -58
- data/lib/faastruby/cli/commands/credentials/list.rb +0 -58
- data/lib/faastruby/cli/commands/workspace.rb +0 -13
- data/lib/faastruby/cli/commands/workspace/deploy.rb +0 -50
- data/templates/crystal/example-blank/README.md +0 -22
- data/templates/crystal/example-blank/spec/handler_spec.cr +0 -8
- data/templates/crystal/example-blank/spec/spec_helper.cr +0 -4
- data/templates/crystal/example-blank/src/handler.cr +0 -25
- data/templates/ruby/example-blank/Gemfile +0 -7
- data/templates/ruby/example-blank/README.md +0 -22
- data/templates/ruby/example-blank/spec/handler_spec.rb +0 -16
- data/templates/ruby/example-blank/spec/spec_helper.rb +0 -3
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module FaaStRuby
|
|
2
|
+
module Command
|
|
3
|
+
module Account
|
|
4
|
+
require 'faastruby/cli/commands/account/base_command'
|
|
5
|
+
class Logout < AccountBaseCommand
|
|
6
|
+
def initialize(args)
|
|
7
|
+
@args = args
|
|
8
|
+
parse_options
|
|
9
|
+
@credentials_file = NewCredentials::CredentialsFile.new
|
|
10
|
+
@credentials = @credentials_file.get
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def run
|
|
14
|
+
user = User.new(@credentials)
|
|
15
|
+
unless user.has_credentials?
|
|
16
|
+
puts "Logout successful."
|
|
17
|
+
exit 0
|
|
18
|
+
end
|
|
19
|
+
user.logout(all: @options['all'])
|
|
20
|
+
FaaStRuby::CLI.error(user.errors) if !@options['force'] && user&.errors.any?
|
|
21
|
+
@credentials_file.clear
|
|
22
|
+
puts "Logout successful."
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.help
|
|
26
|
+
"logout [ARGS]"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def usage
|
|
30
|
+
puts "Usage: faastruby #{self.class.help}"
|
|
31
|
+
puts %(
|
|
32
|
+
-a,--all # Logout from all machines
|
|
33
|
+
-f,--force # Logout from all machines
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def parse_options
|
|
40
|
+
@options = {}
|
|
41
|
+
while @args.any?
|
|
42
|
+
option = @args.shift
|
|
43
|
+
case option
|
|
44
|
+
when '-h', '--help', 'help'
|
|
45
|
+
usage
|
|
46
|
+
exit 0
|
|
47
|
+
when '-f', '--force'
|
|
48
|
+
@options['force'] = true
|
|
49
|
+
when '-a', '--all'
|
|
50
|
+
@options['all'] = true
|
|
51
|
+
else
|
|
52
|
+
FaaStRuby::CLI.error(["Unknown argument: #{option}".red, usage], color: nil)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module FaaStRuby
|
|
2
|
+
module Command
|
|
3
|
+
module Account
|
|
4
|
+
PASSWORD_REGEX = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,20}$/
|
|
5
|
+
EMAIL_REGEX = /\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
|
|
6
|
+
require 'faastruby/cli/commands/account/base_command'
|
|
7
|
+
require 'io/console'
|
|
8
|
+
class Signup < AccountBaseCommand
|
|
9
|
+
def initialize(args)
|
|
10
|
+
@args = args
|
|
11
|
+
parse_options
|
|
12
|
+
FaaStRuby::CLI.error("You are currently logged in. Please run 'faastruby logout' to logout, then try again.") if has_user_logged_in?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def run
|
|
16
|
+
puts "\nWelcome to FaaStRuby! Please enter your email address:"
|
|
17
|
+
print "Email: "
|
|
18
|
+
email = STDIN.gets.chomp
|
|
19
|
+
until email_is_valid?(email) do
|
|
20
|
+
puts "You entered an invalid email address. Please try again:".red
|
|
21
|
+
print "Email: "
|
|
22
|
+
email = STDIN.gets.chomp
|
|
23
|
+
end
|
|
24
|
+
puts "\nNow type in a password. It must contain 8 to 20 characters and have at least one uppercase letter, one lowercase letter, one number."
|
|
25
|
+
print "Password: "
|
|
26
|
+
password = STDIN.noecho(&:gets).chomp
|
|
27
|
+
until password_is_valid?(password) do
|
|
28
|
+
puts "\nYour password must contain 8 to 20 characters and have at least one uppercase letter, one lowercase letter, one number. Please try again:".red
|
|
29
|
+
print "Password: "
|
|
30
|
+
password = STDIN.noecho(&:gets).chomp
|
|
31
|
+
end
|
|
32
|
+
spinner = spin("Creating your account...")
|
|
33
|
+
user = User.create(email: email, password: password)
|
|
34
|
+
if user.errors.any?
|
|
35
|
+
spinner.stop(" Failed :(")
|
|
36
|
+
FaaStRuby::CLI.error(user.errors)
|
|
37
|
+
end
|
|
38
|
+
spinner.stop(' Done!')
|
|
39
|
+
exec("faastruby confirm-account --email #{email}")
|
|
40
|
+
exit 0
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def email_is_valid?(email)
|
|
44
|
+
email.match(EMAIL_REGEX)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def password_is_valid?(password)
|
|
48
|
+
password.match(PASSWORD_REGEX)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.help
|
|
52
|
+
"signup"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def usage
|
|
56
|
+
puts "Usage: faastruby #{self.class.help}"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def parse_options
|
|
61
|
+
@options = {}
|
|
62
|
+
while @args.any?
|
|
63
|
+
option = @args.shift
|
|
64
|
+
case option
|
|
65
|
+
when '-h', '--help', 'help'
|
|
66
|
+
usage
|
|
67
|
+
exit 0
|
|
68
|
+
else
|
|
69
|
+
FaaStRuby::CLI.error(["Unknown argument: #{option}".red, usage], color: nil)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -12,20 +12,11 @@ module FaaStRuby
|
|
|
12
12
|
# deploy: false
|
|
13
13
|
def load_yaml
|
|
14
14
|
FaaStRuby::CLI.error("It looks like you created this function with an old version of faastruby. Please run 'faastruby upgrade'.") if File.file?('handler.rb') && !File.file?('faastruby.yml')
|
|
15
|
-
FaaStRuby::CLI.error("Could not find file 'faastruby.yml' in the current directory")
|
|
15
|
+
FaaStRuby::CLI.error("Could not find file 'faastruby.yml' in the current directory") if !File.file?('faastruby.yml') && @options['function_name'].nil?
|
|
16
16
|
@yaml_config = YAML.load(File.read('./faastruby.yml'))
|
|
17
17
|
FaaStRuby::CLI.error("Could read function name from 'faastruby.yml'. Make sure you have a key 'name: FUNCTION_NAME' in that file!") unless @yaml_config['name']
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
require 'faastruby/cli/commands/function/build'
|
|
25
|
-
require 'faastruby/cli/commands/function/deploy_to'
|
|
26
|
-
require 'faastruby/cli/commands/function/new'
|
|
27
|
-
require 'faastruby/cli/commands/function/remove_from'
|
|
28
|
-
require 'faastruby/cli/commands/function/test'
|
|
29
|
-
require 'faastruby/cli/commands/function/update_context'
|
|
30
|
-
require 'faastruby/cli/commands/function/upgrade'
|
|
31
|
-
require 'faastruby/cli/commands/function/run'
|
|
22
|
+
end
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
module FaaStRuby
|
|
2
2
|
module Command
|
|
3
3
|
module Function
|
|
4
|
+
require 'faastruby/cli/commands/function/base_command'
|
|
5
|
+
require 'faastruby/cli/package'
|
|
4
6
|
class Build < FunctionBaseCommand
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
spinner = spin(
|
|
7
|
+
def self.build(source, output_file, function_name, quiet = false)
|
|
8
|
+
# msg = "[#{function_name}] Building package..."
|
|
9
|
+
# quiet ? puts(msg) : spinner = spin(msg)
|
|
8
10
|
FaaStRuby::Package.new(source, output_file).build
|
|
9
|
-
spinner.stop('Done!')
|
|
11
|
+
# quiet ? puts("[#{function_name}] Package created.") : spinner.stop('Done!')
|
|
10
12
|
puts "+ f #{output_file}".green unless quiet
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
def initialize(args)
|
|
14
16
|
@args = args
|
|
15
17
|
load_yaml
|
|
18
|
+
@yaml_config['before_build'] ||= []
|
|
16
19
|
@function_name = @yaml_config['name']
|
|
17
20
|
@abort_when_tests_fail = @yaml_config['abort_build_when_tests_fail']
|
|
18
21
|
parse_options
|
|
19
22
|
@options['source'] ||= '.'
|
|
20
|
-
@
|
|
23
|
+
@package_file = Tempfile.new('package')
|
|
24
|
+
@options['output_file'] ||= @package_file.path
|
|
21
25
|
end
|
|
22
26
|
|
|
23
27
|
def ruby_runtime?
|
|
@@ -37,8 +41,10 @@ module FaaStRuby
|
|
|
37
41
|
end
|
|
38
42
|
tests_passed = run_tests
|
|
39
43
|
FaaStRuby::CLI.error("Build aborted because tests failed and you have 'abort_build_when_tests_fail: true' in 'faastruby.yml'") unless tests_passed || !@abort_when_tests_fail
|
|
40
|
-
puts "Warning: Ignoring failed tests because you have 'abort_build_when_tests_fail: false' in 'faastruby.yml'".yellow if !tests_passed && !@abort_when_tests_fail
|
|
44
|
+
puts "[#{@function_name}] Warning: Ignoring failed tests because you have 'abort_build_when_tests_fail: false' in 'faastruby.yml'".yellow if !tests_passed && !@abort_when_tests_fail
|
|
41
45
|
build(@options['source'], @options['output_file'])
|
|
46
|
+
@package_file.close
|
|
47
|
+
@package_file.unlink
|
|
42
48
|
end
|
|
43
49
|
|
|
44
50
|
def self.help
|
|
@@ -52,27 +58,28 @@ module FaaStRuby
|
|
|
52
58
|
private
|
|
53
59
|
|
|
54
60
|
def build(source, output_file)
|
|
55
|
-
spinner = spin("Running '
|
|
56
|
-
@yaml_config['
|
|
61
|
+
spinner = spin("[#{@function_name}] Running 'before_build' tasks...")
|
|
62
|
+
@yaml_config['before_build']&.each do |command|
|
|
57
63
|
puts `#{command}`
|
|
58
64
|
end
|
|
59
65
|
spinner.stop(' Done!')
|
|
60
|
-
self.class.build(source, output_file)
|
|
66
|
+
self.class.build(source, output_file, @function_name)
|
|
61
67
|
end
|
|
62
68
|
|
|
63
69
|
def shards_install
|
|
64
|
-
puts '[build] Verifying dependencies'
|
|
65
70
|
return true unless File.file?('shard.yml')
|
|
71
|
+
puts "[#{@function_name}] [build] Verifying dependencies"
|
|
66
72
|
system('shards check') || system('shards install')
|
|
67
73
|
end
|
|
68
74
|
|
|
69
75
|
def bundle_install
|
|
70
|
-
puts '[build] Verifying dependencies'
|
|
71
76
|
return true unless File.file?('Gemfile')
|
|
77
|
+
puts "[#{@function_name}] [build] Verifying dependencies"
|
|
72
78
|
system('bundle check') || system('bundle install')
|
|
73
79
|
end
|
|
74
80
|
|
|
75
81
|
def run_tests
|
|
82
|
+
require 'faastruby/cli/commands/function/test'
|
|
76
83
|
FaaStRuby::Command::Function::Test.new(true).run(do_not_exit: true)
|
|
77
84
|
end
|
|
78
85
|
|
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
module FaaStRuby
|
|
2
2
|
module Command
|
|
3
3
|
module Function
|
|
4
|
+
require 'faastruby/cli/commands/function/base_command'
|
|
5
|
+
require 'faastruby/cli/new_credentials'
|
|
4
6
|
class DeployTo < FunctionBaseCommand
|
|
5
7
|
def initialize(args)
|
|
6
8
|
@args = args
|
|
9
|
+
help
|
|
7
10
|
@missing_args = []
|
|
8
11
|
FaaStRuby::CLI.error(@missing_args, color: nil) if missing_args.any?
|
|
9
12
|
@workspace_name = @args.shift
|
|
13
|
+
parse_options
|
|
10
14
|
load_yaml
|
|
15
|
+
@yaml_config['before_build'] ||= []
|
|
11
16
|
@function_name = @yaml_config['name']
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
unless @yaml_config['serve_static']
|
|
18
|
+
@options['root_to'] = @function_name if @options['is_root']
|
|
19
|
+
@options['catch_all'] = @function_name if @options['is_catch_all']
|
|
20
|
+
# @abort_when_tests_fail = true #@yaml_config['abort_deploy_when_tests_fail']
|
|
21
|
+
end
|
|
22
|
+
load_credentials
|
|
23
|
+
@package_file = Tempfile.new('package')
|
|
14
24
|
end
|
|
15
25
|
|
|
16
26
|
def ruby_runtime?
|
|
@@ -18,69 +28,92 @@ module FaaStRuby
|
|
|
18
28
|
end
|
|
19
29
|
|
|
20
30
|
def crystal_runtime?
|
|
31
|
+
return false if @yaml_config['runtime'].nil?
|
|
21
32
|
@yaml_config['runtime'].match(/^crystal/)
|
|
22
33
|
end
|
|
23
34
|
|
|
35
|
+
def runtime_name
|
|
36
|
+
return 'Ruby' if ruby_runtime?
|
|
37
|
+
return 'Crystal' if crystal_runtime?
|
|
38
|
+
return 'Ruby'
|
|
39
|
+
end
|
|
40
|
+
|
|
24
41
|
def run
|
|
25
42
|
create_or_use_workspace
|
|
26
|
-
if
|
|
27
|
-
|
|
43
|
+
if @yaml_config['serve_static']
|
|
44
|
+
package_file_name = build_package
|
|
45
|
+
spinner = say("[#{@function_name}] Deploying static files '#{@function_name}' to workspace '#{@workspace_name}'...", quiet: @options['quiet'])
|
|
46
|
+
workspace = FaaStRuby::Workspace.new(name: @workspace_name).deploy(package_file_name)
|
|
47
|
+
else
|
|
48
|
+
if ruby_runtime?
|
|
49
|
+
FaaStRuby::CLI.error('Please fix the problems above and try again') unless bundle_install
|
|
50
|
+
end
|
|
51
|
+
if crystal_runtime?
|
|
52
|
+
FaaStRuby::CLI.error('Please fix the problems above and try again') unless shards_install
|
|
53
|
+
end
|
|
54
|
+
FaaStRuby::CLI.error("[#{@function_name}] Deploy aborted because 'test_command' exited non-zero.") unless run_tests
|
|
55
|
+
package_file_name = build_package
|
|
56
|
+
spinner = say("[#{@function_name}] Deploying #{runtime_name} function '#{@function_name}' to workspace '#{@workspace_name}'...", quiet: @options['quiet'])
|
|
57
|
+
workspace = FaaStRuby::Workspace.new(name: @workspace_name).deploy(package_file_name, root_to: @options['root_to'], catch_all: @options['catch_all'], context: @options['context'])
|
|
28
58
|
end
|
|
29
|
-
if crystal_runtime?
|
|
30
|
-
FaaStRuby::CLI.error('Please fix the problems above and try again') unless shards_install
|
|
31
|
-
end
|
|
32
|
-
tests_passed = run_tests
|
|
33
|
-
FaaStRuby::CLI.error("Deploy aborted because tests failed and you have 'abort_deploy_when_tests_fail: true' in 'faastruby.yml'") unless tests_passed || !@abort_when_tests_fail
|
|
34
|
-
puts "Warning: Ignoring failed tests because you have 'abort_deploy_when_tests_fail: false' in 'faastruby.yml'".yellow if !tests_passed && !@abort_when_tests_fail
|
|
35
|
-
package_file_name = build_package
|
|
36
|
-
spinner = spin("Deploying '#{@workspace_name}/#{@function_name}'")
|
|
37
|
-
workspace = FaaStRuby::Workspace.new(name: @workspace_name).deploy(package_file_name)
|
|
38
59
|
if workspace.errors.any?
|
|
39
|
-
spinner
|
|
60
|
+
puts ' Failed :(' unless spinner&.stop(' Failed :(')
|
|
61
|
+
@package_file.unlink
|
|
40
62
|
FaaStRuby::CLI.error(workspace.errors)
|
|
41
63
|
end
|
|
42
|
-
spinner.stop('Done!')
|
|
43
|
-
|
|
64
|
+
spinner.stop(' Done!') unless @options['quiet']
|
|
65
|
+
@package_file.unlink
|
|
66
|
+
puts "* [#{@function_name}] Deploy OK".green
|
|
67
|
+
unless @yaml_config['serve_static']
|
|
68
|
+
puts "* [#{@function_name}] Workspace: #{@workspace_name}".green
|
|
69
|
+
puts "* [#{@function_name}] Endpoint: #{FaaStRuby.workspace_host_for(@workspace_name)}/#{@function_name unless @options['root_to']}".green
|
|
70
|
+
end
|
|
71
|
+
puts '---'
|
|
44
72
|
exit 0
|
|
45
73
|
end
|
|
46
74
|
|
|
47
75
|
def self.help
|
|
48
|
-
"deploy-to
|
|
76
|
+
"deploy-to WORKSPACE_NAME [ARGS]"
|
|
49
77
|
end
|
|
50
78
|
|
|
51
79
|
def usage
|
|
52
|
-
"
|
|
80
|
+
puts "\nUsage: faastruby #{self.class.help}"
|
|
81
|
+
puts %(
|
|
82
|
+
-f,--function PATH/TO/FUNCTION # Specify the directory where the function is.
|
|
83
|
+
--context DATA # The data to be stored as context in the cloud,
|
|
84
|
+
# accessible via 'event.context' from within your function.
|
|
85
|
+
--set-root # Set the function as the root route of the workspace/
|
|
86
|
+
--set-catch-all # Set the function as the catch-all route of the workspace.
|
|
87
|
+
--dont-create-workspace # Don't try to create the workspace if it doesn't exist.
|
|
88
|
+
)
|
|
53
89
|
end
|
|
54
90
|
|
|
55
91
|
private
|
|
56
92
|
|
|
57
|
-
def load_credentials(exit_on_error:)
|
|
58
|
-
@has_credentials = FaaStRuby::Credentials.load_for(@workspace_name, exit_on_error: exit_on_error)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
93
|
def create_or_use_workspace
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
94
|
+
return true if @options['dont_create_workspace']
|
|
95
|
+
require 'faastruby/cli/commands/workspace/create'
|
|
96
|
+
# puts "[#{@function_name}] Attemping to create workspace '#{@workspace_name}'"
|
|
97
|
+
cmd = FaaStRuby::Command::Workspace::Create.new([@workspace_name])
|
|
98
|
+
result = cmd.run(create_directory: false, exit_on_error: false)
|
|
99
|
+
if result
|
|
67
100
|
# Give a little bit of time after creating the workspace
|
|
68
101
|
# for consistency. This is temporary until the API gets patched.
|
|
69
|
-
spinner =
|
|
102
|
+
spinner = say("[#{@function_name}] Waiting for the workspace '#{@workspace_name}' to be ready...", quiet: @options['quiet'])
|
|
70
103
|
sleep 2
|
|
71
|
-
spinner
|
|
104
|
+
puts ' Done!' unless spinner&.stop(' Done!')
|
|
72
105
|
end
|
|
73
106
|
end
|
|
74
107
|
|
|
75
108
|
def shards_install
|
|
76
|
-
puts '[build] Verifying dependencies'
|
|
77
109
|
return true unless File.file?('shard.yml')
|
|
110
|
+
puts "[#{@function_name}] [build] Verifying dependencies"
|
|
78
111
|
system('shards check') || system('shards install')
|
|
79
112
|
end
|
|
80
113
|
|
|
81
114
|
def bundle_install
|
|
82
|
-
puts '[build] Verifying dependencies'
|
|
83
115
|
return true unless File.file?('Gemfile')
|
|
116
|
+
puts "[#{@function_name}] [build] Verifying dependencies"
|
|
84
117
|
system('bundle check') || system('bundle install')
|
|
85
118
|
end
|
|
86
119
|
|
|
@@ -94,20 +127,50 @@ module FaaStRuby
|
|
|
94
127
|
end
|
|
95
128
|
|
|
96
129
|
def run_tests
|
|
130
|
+
return true unless @yaml_config['test_command']
|
|
131
|
+
require 'faastruby/cli/commands/function/test'
|
|
97
132
|
FaaStRuby::Command::Function::Test.new(true).run(do_not_exit: true)
|
|
98
133
|
end
|
|
99
134
|
|
|
100
135
|
def build_package
|
|
101
136
|
source = '.'
|
|
102
|
-
output_file =
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
137
|
+
output_file = @package_file.path
|
|
138
|
+
if @yaml_config['before_build'].any?
|
|
139
|
+
spinner = say("[#{@function_name}] Running 'before_build' tasks...", quiet: @options['quiet'])
|
|
140
|
+
@yaml_config['before_build']&.each do |command|
|
|
141
|
+
puts `#{command}`
|
|
142
|
+
end
|
|
143
|
+
spinner&.stop(' Done!')
|
|
106
144
|
end
|
|
107
|
-
|
|
108
|
-
FaaStRuby::Command::Function::Build.build(source, output_file, true)
|
|
145
|
+
require 'faastruby/cli/commands/function/build'
|
|
146
|
+
FaaStRuby::Command::Function::Build.build(source, output_file, @function_name, true)
|
|
147
|
+
@package_file.close
|
|
109
148
|
output_file
|
|
110
149
|
end
|
|
150
|
+
|
|
151
|
+
def parse_options
|
|
152
|
+
@options = {}
|
|
153
|
+
while @args.any?
|
|
154
|
+
option = @args.shift
|
|
155
|
+
case option
|
|
156
|
+
when '-f', '--function'
|
|
157
|
+
Dir.chdir @args.shift
|
|
158
|
+
when '--context'
|
|
159
|
+
@options['context'] = @args.shift
|
|
160
|
+
when '--quiet', '-q'
|
|
161
|
+
@options['quiet'] = true
|
|
162
|
+
when '--set-root'
|
|
163
|
+
@options['is_root'] = true
|
|
164
|
+
when '--set-catch-all'
|
|
165
|
+
@options['is_catch_all'] = true
|
|
166
|
+
when '--dont-create-workspace'
|
|
167
|
+
@options['dont_create_workspace'] = true
|
|
168
|
+
else
|
|
169
|
+
FaaStRuby::CLI.error("Unknown argument: #{option}")
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
111
174
|
end
|
|
112
175
|
end
|
|
113
176
|
end
|
|
@@ -1,21 +1,33 @@
|
|
|
1
|
+
require 'erb'
|
|
1
2
|
module FaaStRuby
|
|
3
|
+
require 'faastruby/version'
|
|
2
4
|
module Command
|
|
3
5
|
module Function
|
|
6
|
+
require 'faastruby/supported_runtimes'
|
|
7
|
+
require 'faastruby/cli/commands/function/base_command'
|
|
8
|
+
require 'faastruby/cli/template'
|
|
4
9
|
class New < FunctionBaseCommand
|
|
5
10
|
def initialize(args)
|
|
6
11
|
@args = args
|
|
12
|
+
help
|
|
7
13
|
@missing_args = []
|
|
8
14
|
FaaStRuby::CLI.error(@missing_args, color: nil) if missing_args.any?
|
|
9
15
|
@function_name = @args.shift
|
|
16
|
+
FaaStRuby::CLI.error("The function name must have at least one character and can only contain letters, numbers, -, _, . and /. Names with just a period are not allowed. Invalid name: #{@function_name}") unless name_valid?
|
|
10
17
|
parse_options
|
|
11
18
|
@base_dir ||= @function_name
|
|
12
19
|
@options['runtime_name'] ||= 'ruby'
|
|
13
20
|
@options['runtime_version'] ||= '2.5.3'
|
|
14
|
-
|
|
21
|
+
if @options['blank_template']
|
|
22
|
+
@options['template'] = FaaStRuby::Template.new(type: 'local', source: Template.gem_template_path_for('example-blank', runtime: @options['runtime_name'] || 'ruby'))
|
|
23
|
+
else
|
|
24
|
+
@options['template'] ||= FaaStRuby::Template.new(type: 'local', source: Template.gem_template_path_for('example', runtime: @options['runtime_name']))
|
|
25
|
+
end
|
|
15
26
|
end
|
|
16
27
|
|
|
17
|
-
def run
|
|
18
|
-
@options['
|
|
28
|
+
def run(print_base_dir: false, blank_template: false)
|
|
29
|
+
@options['blank_template'] ||= blank_template
|
|
30
|
+
@options['template'].install(to: @base_dir, force: @options['force'], print_base_dir: print_base_dir)
|
|
19
31
|
faastruby_yaml = "#{@base_dir}/faastruby.yml"
|
|
20
32
|
if File.file?(faastruby_yaml)
|
|
21
33
|
@yaml_content = YAML.load(File.read(faastruby_yaml))
|
|
@@ -26,32 +38,28 @@ module FaaStRuby
|
|
|
26
38
|
else
|
|
27
39
|
@yaml_content = yaml_for(@options['runtime_name'])
|
|
28
40
|
end
|
|
29
|
-
write_yaml
|
|
41
|
+
write_yaml(print_base_dir: print_base_dir)
|
|
30
42
|
post_tasks(@options['runtime_name'])
|
|
31
43
|
end
|
|
32
44
|
|
|
33
45
|
def self.help
|
|
34
|
-
"new
|
|
35
|
-
<<-EOS
|
|
36
|
-
|
|
37
|
-
--blank
|
|
38
|
-
Create a blank function
|
|
39
|
-
--force
|
|
40
|
-
Continue if directory already exists and overwrite files
|
|
41
|
-
-g
|
|
42
|
-
Initialize a Git repository.
|
|
43
|
-
--runtime
|
|
44
|
-
Choose the runtime. Options are: #{SUPPORTED_RUNTIMES.join(', ')}
|
|
45
|
-
--template TYPE(local|git|github):SOURCE
|
|
46
|
-
Use another function as template. Examples:
|
|
47
|
-
--template local:/path/to/folder
|
|
48
|
-
--template git:git@github.com:user/repo.git
|
|
49
|
-
--template github:user/repo
|
|
50
|
-
EOS
|
|
46
|
+
"new FUNCTION_NAME [ARGS]"
|
|
51
47
|
end
|
|
52
48
|
|
|
53
49
|
def usage
|
|
54
|
-
"
|
|
50
|
+
puts "\nUsage: faastruby #{self.class.help}"
|
|
51
|
+
puts %(
|
|
52
|
+
--blank # Create a blank function
|
|
53
|
+
--force # Continue if directory already exists and overwrite files
|
|
54
|
+
-g, --git # Initialize a Git repository.
|
|
55
|
+
--runtime # Set the language runtime.
|
|
56
|
+
# Options are: #{SUPPORTED_RUNTIMES.join(', ')}
|
|
57
|
+
--template TYPE(local|git|github):SOURCE # Initialize the function using a template
|
|
58
|
+
# Examples:
|
|
59
|
+
# --template local:/path/to/folder
|
|
60
|
+
# --template git:git@github.com:user/repo.git
|
|
61
|
+
# --template github:user/repo
|
|
62
|
+
)
|
|
55
63
|
end
|
|
56
64
|
|
|
57
65
|
private
|
|
@@ -61,7 +69,7 @@ EOS
|
|
|
61
69
|
while @args.any?
|
|
62
70
|
option = @args.shift
|
|
63
71
|
case option
|
|
64
|
-
when '-g'
|
|
72
|
+
when '-g', '--git'
|
|
65
73
|
@options['git_init'] = true
|
|
66
74
|
when '--template'
|
|
67
75
|
FaaStRuby::CLI.error("Option '--template' can't be used with '--blank' or '--runtime'.".red) if @options['runtime'] || @options['blank_template']
|
|
@@ -70,7 +78,7 @@ EOS
|
|
|
70
78
|
source = source.join(':')
|
|
71
79
|
@options['template'] = FaaStRuby::Template.new(type: type, source: source)
|
|
72
80
|
when '--runtime'
|
|
73
|
-
FaaStRuby::CLI.error("Option '--
|
|
81
|
+
FaaStRuby::CLI.error("Option '--runtime' can't be used with '--template' or '--blank'.".red) if @options['template']
|
|
74
82
|
@options['runtime'] = @args.shift
|
|
75
83
|
@options['runtime_name'], @options['runtime_version'] = @options['runtime'].split(':')
|
|
76
84
|
template_name = @options['blank_template'] ? 'example-blank' : 'example'
|
|
@@ -79,9 +87,9 @@ EOS
|
|
|
79
87
|
when '-f', '--force'
|
|
80
88
|
@options['force'] = true
|
|
81
89
|
when '--blank'
|
|
82
|
-
|
|
90
|
+
@options['template'] = nil
|
|
91
|
+
FaaStRuby::CLI.error("Option '--blank' can't be used with '--blank' or '--template'.".red) if @options['template']
|
|
83
92
|
@options['blank_template'] = true
|
|
84
|
-
@options['template'] = FaaStRuby::Template.new(type: 'local', source: Template.gem_template_path_for('example-blank', runtime: @options['runtime_name'] || 'ruby'))
|
|
85
93
|
else
|
|
86
94
|
FaaStRuby::CLI.error(["Unknown argument: #{option}".red, usage], color: nil)
|
|
87
95
|
end
|
|
@@ -96,6 +104,28 @@ EOS
|
|
|
96
104
|
@missing_args
|
|
97
105
|
end
|
|
98
106
|
|
|
107
|
+
def yaml_comments
|
|
108
|
+
[
|
|
109
|
+
'## You can add commands to run locally before building the deployment package.',
|
|
110
|
+
"## Some use cases are:",
|
|
111
|
+
"## * minifying Javascript/CSS",
|
|
112
|
+
"## * downloading a file to be included in the package.",
|
|
113
|
+
"# before_build:",
|
|
114
|
+
"# - curl https://some.url --output some.file",
|
|
115
|
+
"# - uglifyjs your.js -c -m -o your.min.js",
|
|
116
|
+
'',
|
|
117
|
+
'# To schedule periodic runs, follow the example below:',
|
|
118
|
+
'# schedule:',
|
|
119
|
+
'# job1:',
|
|
120
|
+
'# when: every 2 hours',
|
|
121
|
+
'# body: {"foo": "bar"}',
|
|
122
|
+
'# method: POST',
|
|
123
|
+
'# query_params: {"param": "value"}',
|
|
124
|
+
'# headers: {"Content-Type": "application/json"}',
|
|
125
|
+
'# job2: ...'
|
|
126
|
+
].join("\n")
|
|
127
|
+
end
|
|
128
|
+
|
|
99
129
|
def yaml_for(runtime_name)
|
|
100
130
|
case runtime_name
|
|
101
131
|
when 'crystal'
|
|
@@ -105,21 +135,29 @@ EOS
|
|
|
105
135
|
else
|
|
106
136
|
test_command = 'rspec'
|
|
107
137
|
end
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
138
|
+
if @options['blank_template']
|
|
139
|
+
{
|
|
140
|
+
'cli_version' => FaaStRuby::VERSION,
|
|
141
|
+
'name' => @function_name,
|
|
142
|
+
'runtime' => @options['runtime'] || 'ruby:2.5.3'
|
|
143
|
+
}
|
|
144
|
+
else
|
|
145
|
+
{
|
|
146
|
+
'cli_version' => FaaStRuby::VERSION,
|
|
147
|
+
'name' => @function_name,
|
|
148
|
+
'before_build' => [],
|
|
149
|
+
'runtime' => @options['runtime'] || 'ruby:2.5.3',
|
|
150
|
+
'test_command' => test_command
|
|
151
|
+
}
|
|
152
|
+
end
|
|
116
153
|
end
|
|
117
154
|
|
|
118
|
-
def write_yaml
|
|
119
|
-
write_file("#{@function_name}/faastruby.yml", @yaml_content.to_yaml)
|
|
155
|
+
def write_yaml(print_base_dir: false)
|
|
156
|
+
write_file("#{@function_name}/faastruby.yml", @yaml_content.to_yaml, print_base_dir: print_base_dir, extra_content: yaml_comments)
|
|
120
157
|
end
|
|
121
158
|
|
|
122
159
|
def post_tasks(runtime_name)
|
|
160
|
+
return true if @options['blank_template']
|
|
123
161
|
update_readme
|
|
124
162
|
puts `git init #{@base_dir}` if @options['git_init']
|
|
125
163
|
case runtime_name
|
|
@@ -141,6 +179,7 @@ EOS
|
|
|
141
179
|
end
|
|
142
180
|
|
|
143
181
|
def bundle_install
|
|
182
|
+
return true unless File.file?("#{@base_dir}/Gemfile")
|
|
144
183
|
spinner = spin("Installing gems...")
|
|
145
184
|
system("bundle install --gemfile=#{@base_dir}/Gemfile > /dev/null")
|
|
146
185
|
spinner.stop('Done!')
|
|
@@ -167,10 +206,24 @@ EOS
|
|
|
167
206
|
end
|
|
168
207
|
|
|
169
208
|
def shards_install
|
|
209
|
+
return true unless File.file?("#{@base_dir}/shard.yml")
|
|
170
210
|
spinner = spin("Installing shards...")
|
|
171
211
|
system("cd #{@base_dir} && shards install > /dev/null")
|
|
172
212
|
spinner.stop('Done!')
|
|
173
213
|
end
|
|
214
|
+
|
|
215
|
+
def name_valid?
|
|
216
|
+
return false unless @function_name.match(/^#{FUNCTION_NAME_REGEX}$/)
|
|
217
|
+
while @function_name.match(/\.\./) || @function_name.match(/^\.\//) || @function_name.match(/(^\/|\/$)/)
|
|
218
|
+
@function_name.gsub!('..', '.')
|
|
219
|
+
@function_name.gsub!(/^\.\//, '')
|
|
220
|
+
@function_name.gsub!(/(^\/|\/$)/, '')
|
|
221
|
+
end
|
|
222
|
+
if @function_name == '.' || @function_name == '' || @function_name.match(/\.\./)
|
|
223
|
+
return false
|
|
224
|
+
end
|
|
225
|
+
return true
|
|
226
|
+
end
|
|
174
227
|
end
|
|
175
228
|
end
|
|
176
229
|
end
|