faastruby 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +67 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/example-blank/Gemfile +5 -0
- data/example-blank/handler.rb +4 -0
- data/example-blank/spec/handler_spec.rb +11 -0
- data/example-blank/spec/helpers/faastruby.rb +23 -0
- data/example-blank/spec/spec_helper.rb +2 -0
- data/example/Gemfile +5 -0
- data/example/handler.rb +17 -0
- data/example/spec/handler_spec.rb +20 -0
- data/example/spec/helpers/faastruby.rb +23 -0
- data/example/spec/spec_helper.rb +2 -0
- data/exe/faastruby +5 -0
- data/faastruby.gemspec +41 -0
- data/lib/faastruby.rb +6 -0
- data/lib/faastruby/api.rb +94 -0
- data/lib/faastruby/base.rb +53 -0
- data/lib/faastruby/cli.rb +42 -0
- data/lib/faastruby/cli/commands.rb +61 -0
- data/lib/faastruby/cli/commands/function.rb +31 -0
- data/lib/faastruby/cli/commands/function/build.rb +65 -0
- data/lib/faastruby/cli/commands/function/deploy.rb +62 -0
- data/lib/faastruby/cli/commands/function/new.rb +99 -0
- data/lib/faastruby/cli/commands/function/remove_from.rb +71 -0
- data/lib/faastruby/cli/commands/function/run.rb +135 -0
- data/lib/faastruby/cli/commands/function/test.rb +42 -0
- data/lib/faastruby/cli/commands/function/update_context.rb +67 -0
- data/lib/faastruby/cli/commands/function/upgrade.rb +69 -0
- data/lib/faastruby/cli/commands/help.rb +31 -0
- data/lib/faastruby/cli/commands/version.rb +13 -0
- data/lib/faastruby/cli/commands/workspace.rb +12 -0
- data/lib/faastruby/cli/commands/workspace/create.rb +70 -0
- data/lib/faastruby/cli/commands/workspace/destroy.rb +66 -0
- data/lib/faastruby/cli/commands/workspace/list.rb +54 -0
- data/lib/faastruby/cli/credentials.rb +49 -0
- data/lib/faastruby/cli/package.rb +46 -0
- data/lib/faastruby/function.rb +27 -0
- data/lib/faastruby/version.rb +3 -0
- data/lib/faastruby/workspace.rb +49 -0
- metadata +203 -0
@@ -0,0 +1,135 @@
|
|
1
|
+
module FaaStRuby
|
2
|
+
module Command
|
3
|
+
module Function
|
4
|
+
class Run < FunctionBaseCommand
|
5
|
+
def initialize(args)
|
6
|
+
@args = args
|
7
|
+
@missing_args = []
|
8
|
+
FaaStRuby::CLI.error(@missing_args, color: nil) if missing_args.any?
|
9
|
+
@options = {}
|
10
|
+
@options['workspace_name'] = @args.shift
|
11
|
+
load_yaml
|
12
|
+
@function_name = @yaml_config['name']
|
13
|
+
parse_options
|
14
|
+
@options['query'] = "?#{@options['query'].join('&')}" if @options['query']&.any?
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
return curl if @options['curl']
|
19
|
+
function = FaaStRuby::Function.new(name: @function_name)
|
20
|
+
response = function.run(@options)
|
21
|
+
puts response.body
|
22
|
+
end
|
23
|
+
|
24
|
+
def curl
|
25
|
+
command = ["curl"]
|
26
|
+
command << "-X #{@options['method'].upcase}" if @options['method']
|
27
|
+
@options['headers']&.each {|h,v| command << "-H '#{h}: #{v}'"}
|
28
|
+
command << "-d '#{@options['body']}'" if @options['body']
|
29
|
+
command << "'#{HOST}/#{@options['workspace_name']}/#{@function_name}#{@options['query']}'"
|
30
|
+
puts command.join(" ")
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.help
|
34
|
+
'run'.blue + ' WORKSPACE_NAME [OPTIONS]' +
|
35
|
+
<<-EOS
|
36
|
+
|
37
|
+
Options:
|
38
|
+
-b, --body 'DATA' # The request body
|
39
|
+
--stdin # Read the request body from STDIN
|
40
|
+
-m, --method METHOD # The request method
|
41
|
+
-h, --header 'Header: Value' # Set a header. Can be used multiple times.
|
42
|
+
-f, --form 'a=1&b=2' # Send form data and set header 'Content-Type: application/x-www-form-urlencoded'
|
43
|
+
-j, --json '{"a":"1"}' # Send JSON data and set header 'Content-Type: application/json'
|
44
|
+
-t, --time # Return function run time in the response
|
45
|
+
-q, --query 'foo=bar' # Set a query parameter for the request. Can be used multiple times.
|
46
|
+
--curl # Return the CURL command equivalent for the request
|
47
|
+
EOS
|
48
|
+
end
|
49
|
+
|
50
|
+
def usage
|
51
|
+
"Usage: faastruby #{self.class.help}"
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def parse_options
|
57
|
+
while @args.any?
|
58
|
+
option = @args.shift
|
59
|
+
case option
|
60
|
+
when '-b', '--body'
|
61
|
+
set_body
|
62
|
+
when '-j', '--json'
|
63
|
+
set_json
|
64
|
+
when '-f', '--form'
|
65
|
+
set_form
|
66
|
+
when '--stdin'
|
67
|
+
set_stdin
|
68
|
+
when '-m', '--method'
|
69
|
+
@options['method'] = @args.shift.downcase
|
70
|
+
when '-h', '--header'
|
71
|
+
set_header
|
72
|
+
when '-t', '--time'
|
73
|
+
@options['time'] = true
|
74
|
+
when '--curl'
|
75
|
+
@options['curl'] = true
|
76
|
+
when '-q', '--query'
|
77
|
+
set_query
|
78
|
+
else
|
79
|
+
FaaStRuby::CLI.error(["Unknown argument: #{option}".red, usage], color: nil)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def set_body
|
85
|
+
@options['method'] ||= 'post'
|
86
|
+
@options['body'] = @args.shift
|
87
|
+
default_content_type = 'text/plain'
|
88
|
+
@options['headers'] ? @options['headers']['Content-Type'] = default_content_type : @options['headers'] = {'Content-Type' => default_content_type}
|
89
|
+
end
|
90
|
+
|
91
|
+
def set_json
|
92
|
+
content_type = 'application/json'
|
93
|
+
@options['method'] ||= 'post'
|
94
|
+
@options['body'] = @args.shift
|
95
|
+
@options['headers'] ? @options['headers']['Content-Type'] = content_type : @options['headers'] = {'Content-Type' => content_type}
|
96
|
+
end
|
97
|
+
|
98
|
+
def set_form
|
99
|
+
content_type = 'application/x-www-form-urlencoded'
|
100
|
+
@options['method'] ||= 'post'
|
101
|
+
@options['body'] = @args.shift
|
102
|
+
@options['headers'] ? @options['headers']['Content-Type'] = content_type : @options['headers'] = {'Content-Type' => content_type}
|
103
|
+
end
|
104
|
+
|
105
|
+
def set_stdin
|
106
|
+
@options['method'] ||= 'post'
|
107
|
+
@options['body'] = STDIN.gets.chomp
|
108
|
+
content_type = 'text/plain'
|
109
|
+
@options['headers'] ? @options['headers']['Content-Type'] = content_type : @options['headers'] = {'Content-Type' => content_type}
|
110
|
+
end
|
111
|
+
|
112
|
+
def set_query
|
113
|
+
query = "#{@args.shift}"
|
114
|
+
@options['query'] ? @options['query'] << query : @options['query'] = [query]
|
115
|
+
end
|
116
|
+
|
117
|
+
def set_header
|
118
|
+
header = @args.shift
|
119
|
+
key, value = header.split(":")
|
120
|
+
value.strip!
|
121
|
+
@options['headers'] ? @options['headers'][key] = value : @options['headers'] = {key => value}
|
122
|
+
end
|
123
|
+
|
124
|
+
def missing_args
|
125
|
+
if @args.empty?
|
126
|
+
@missing_args << "Missing argument: WORKSPACE_NAME".red
|
127
|
+
@missing_args << usage
|
128
|
+
end
|
129
|
+
FaaStRuby::CLI.error(["'#{@args.first}' is not a valid workspace name.".red, usage], color: nil) if @args.first =~ /^-.*/
|
130
|
+
@missing_args
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'open3'
|
2
|
+
module FaaStRuby
|
3
|
+
module Command
|
4
|
+
module Function
|
5
|
+
class Test < FunctionBaseCommand
|
6
|
+
def initialize(args)
|
7
|
+
@args = args
|
8
|
+
load_yaml
|
9
|
+
@function_name = @yaml_config['name']
|
10
|
+
@test_command = @yaml_config['test_command']
|
11
|
+
end
|
12
|
+
|
13
|
+
def run(do_not_exit: false)
|
14
|
+
unless @test_command
|
15
|
+
puts "[skipped] You have no 'test_command' key/value in 'faastruby.yml'. Please consider using rspec!".yellow
|
16
|
+
return true
|
17
|
+
end
|
18
|
+
spinner = spin("Running tests...")
|
19
|
+
output, status = Open3.capture2e(@test_command)
|
20
|
+
if status == 0
|
21
|
+
spinner.stop('Passed!')
|
22
|
+
puts output
|
23
|
+
return true
|
24
|
+
else
|
25
|
+
spinner.stop('Failed :(')
|
26
|
+
FaaStRuby::CLI.error(output, color: nil) unless do_not_exit
|
27
|
+
puts output if do_not_exit
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.help
|
33
|
+
'test'.blue
|
34
|
+
end
|
35
|
+
|
36
|
+
def usage
|
37
|
+
"Usage: faastruby #{self.class.help}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module FaaStRuby
|
2
|
+
module Command
|
3
|
+
module Function
|
4
|
+
class UpdateContext < FunctionBaseCommand
|
5
|
+
def initialize(args)
|
6
|
+
@args = args
|
7
|
+
@missing_args = []
|
8
|
+
FaaStRuby::CLI.error(@missing_args, color: nil) if missing_args.any?
|
9
|
+
@workspace_name = @args.shift
|
10
|
+
load_yaml
|
11
|
+
@function_name = @yaml_config['name']
|
12
|
+
FaaStRuby::Credentials.load_for(@workspace_name)
|
13
|
+
parse_options(require_options: {'data' => 'context data'} )
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
spinner = spin("Uploading context data to '#{@workspace_name}'...")
|
18
|
+
workspace = FaaStRuby::Workspace.new(name: @workspace_name)
|
19
|
+
function = FaaStRuby::Function.new(name: @function_name, workspace: workspace, context: @options['data'])
|
20
|
+
function.update
|
21
|
+
if function.errors.any?
|
22
|
+
spinner.stop('Failed :(')
|
23
|
+
FaaStRuby::CLI.error(function.errors)
|
24
|
+
end
|
25
|
+
spinner.stop('Done!')
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.help
|
29
|
+
"update-context".blue + " WORKSPACE_NAME [-d, --data 'STRING'] [--stdin]"
|
30
|
+
end
|
31
|
+
|
32
|
+
def usage
|
33
|
+
"Usage: faastruby #{self.class.help}"
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def missing_args
|
39
|
+
if @args.empty?
|
40
|
+
@missing_args << "Missing argument: WORKSPACE_NAME".red
|
41
|
+
@missing_args << usage
|
42
|
+
end
|
43
|
+
FaaStRuby::CLI.error(["'#{@args.first}' is not a valid workspace name.".red, usage], color: nil) if @args.first =~ /^-.*/
|
44
|
+
@missing_args
|
45
|
+
end
|
46
|
+
|
47
|
+
def parse_options(require_options: {})
|
48
|
+
@options = {}
|
49
|
+
while @args.any?
|
50
|
+
option = @args.shift
|
51
|
+
case option
|
52
|
+
when '-d', '--data'
|
53
|
+
@options['data'] = @args.shift
|
54
|
+
when '--stdin'
|
55
|
+
@options['data'] = STDIN.gets.chomp
|
56
|
+
else
|
57
|
+
FaaStRuby::CLI.error("Unknown argument: #{option}")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
require_options.keys.each do |option|
|
61
|
+
FaaStRuby::CLI.error(["Missing #{require_options[option]}".red, usage], color: nil) unless @options[option]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module FaaStRuby
|
2
|
+
module Command
|
3
|
+
module Function
|
4
|
+
class Upgrade < FunctionBaseCommand
|
5
|
+
def initialize(args)
|
6
|
+
@args = args
|
7
|
+
end
|
8
|
+
|
9
|
+
def run
|
10
|
+
check_function_name
|
11
|
+
set_yaml_content
|
12
|
+
write_yaml
|
13
|
+
write_gemfile
|
14
|
+
copy_spec_folder
|
15
|
+
puts "Upgrade complete. Please read the documentation at https://faastruby.io/tutorial.html to learn about the changes."
|
16
|
+
puts "To deploy, run 'faastruby deploy-to WORKSPACE_NAME'."
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_yaml_content
|
20
|
+
@yaml_content = {
|
21
|
+
'name' => @function_name,
|
22
|
+
'test_command' => nil,
|
23
|
+
'abort_build_when_tests_fail' => false,
|
24
|
+
'abort_deploy_when_tests_fail' => false
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def check_function_name
|
29
|
+
FaaStRuby::CLI.error('You need to run this command from the function directory') unless File.file?('handler.rb')
|
30
|
+
@function_name = Dir.pwd.split('/').last
|
31
|
+
unless @function_name
|
32
|
+
puts "What's the name of this function? (accepts only letters, numbers, - or _)"
|
33
|
+
print "Enter function name: "
|
34
|
+
@function_name = STDIN.gets.chomp
|
35
|
+
end
|
36
|
+
FaaStRuby::CLI.error('You need to provide a valid function name (letters, numbers, - or _)') unless @function_name.match(/^[a-zA-Z\-_0-9]{1,}$/)
|
37
|
+
end
|
38
|
+
|
39
|
+
def write_yaml
|
40
|
+
write_file("./faastruby.yml", @yaml_content.to_yaml)
|
41
|
+
end
|
42
|
+
|
43
|
+
def write_gemfile
|
44
|
+
content = "\n# Added by 'faastruby upgrade'\ngroup :test do\n gem 'rspec'\nend\n"
|
45
|
+
write_file("./Gemfile", content, 'a')
|
46
|
+
end
|
47
|
+
|
48
|
+
def copy_spec_folder
|
49
|
+
@base_dir = '.'
|
50
|
+
source = "#{Gem::Specification.find_by_name("faastruby").gem_dir}/example-blank"
|
51
|
+
FileUtils.cp_r("#{source}/spec", "#{@base_dir}/")
|
52
|
+
puts "+ d #{@base_dir}/spec".green
|
53
|
+
puts "+ d #{@base_dir}/spec/helpers".green
|
54
|
+
puts "+ f #{@base_dir}/spec/helpers/faastruby.rb".green
|
55
|
+
puts "+ f #{@base_dir}/spec/handler_spec.rb".green
|
56
|
+
puts "+ f #{@base_dir}/spec/spec_helper.rb".green
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.help
|
60
|
+
"upgrade".blue
|
61
|
+
end
|
62
|
+
|
63
|
+
def usage
|
64
|
+
"Usage: faastruby #{self.class.help}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module FaaStRuby
|
2
|
+
module Command
|
3
|
+
class Help < BaseCommand
|
4
|
+
def initialize(args)
|
5
|
+
@args = args
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
puts "FaaStRuby CLI - Manage workspaces and functions hosted at faastruby.io"
|
10
|
+
puts
|
11
|
+
puts 'help, -h, --help # Displays this help'
|
12
|
+
puts '-v # Print version and exit'
|
13
|
+
puts
|
14
|
+
workspaces = ["Workspaces:"]
|
15
|
+
functions = ["Functions:"]
|
16
|
+
FaaStRuby::Command::COMMANDS.each do |command, klass|
|
17
|
+
next if command == 'upgrade'
|
18
|
+
next if klass.to_s.match(/.+Command::Help$/)
|
19
|
+
next if klass.to_s.match(/.+Command::Version$/)
|
20
|
+
section = functions if klass.to_s.match(/.+::Function::.+/)
|
21
|
+
section = workspaces if klass.to_s.match(/.+::Workspace::.+/)
|
22
|
+
section << " #{klass.help}"
|
23
|
+
end
|
24
|
+
puts workspaces
|
25
|
+
puts
|
26
|
+
puts functions
|
27
|
+
puts
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module FaaStRuby
|
2
|
+
module Command
|
3
|
+
module Workspace
|
4
|
+
class WorkspaceBaseCommand < BaseCommand
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'faastruby/cli/commands/workspace/create'
|
11
|
+
require 'faastruby/cli/commands/workspace/destroy'
|
12
|
+
require 'faastruby/cli/commands/workspace/list'
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module FaaStRuby
|
2
|
+
module Command
|
3
|
+
module Workspace
|
4
|
+
class Create < WorkspaceBaseCommand
|
5
|
+
def initialize(args)
|
6
|
+
@args = args
|
7
|
+
@missing_args = []
|
8
|
+
FaaStRuby::CLI.error(@missing_args, color: nil) if missing_args.any?
|
9
|
+
@workspace_name = @args.shift
|
10
|
+
parse_options
|
11
|
+
@options['credentials_file'] ||= FAASTRUBY_CREDENTIALS
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
spinner = spin("Requesting credentials...")
|
16
|
+
workspace = FaaStRuby::Workspace.create(name: @workspace_name, email: @options['email'])
|
17
|
+
spinner.stop("Done!")
|
18
|
+
FaaStRuby::CLI.error(workspace.errors) if workspace.errors.any?
|
19
|
+
if @options['stdout']
|
20
|
+
puts "IMPORTANT: Please store the credentials below in a safe place. If you lose them you will not be able to manage your workspace.".yellow
|
21
|
+
puts "API_KEY: #{workspace.credentials['api_key']}"
|
22
|
+
puts "API_SECRET: #{workspace.credentials['api_secret']}"
|
23
|
+
else
|
24
|
+
puts "Writing credentials to #{@options['credentials_file']}"
|
25
|
+
FaaStRuby::Credentials.add(@workspace_name, workspace.credentials, @options['credentials_file'])
|
26
|
+
end
|
27
|
+
puts "Workspace '#{@workspace_name}' created"
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.help
|
31
|
+
"create-workspace".blue + " WORKSPACE_NAME [--stdout|-o, --output-file] [-e, --email YOUR_EMAIL_ADDRESS]"
|
32
|
+
end
|
33
|
+
|
34
|
+
def usage
|
35
|
+
"Usage: faastruby #{self.class.help}"
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def missing_args
|
41
|
+
if @args.empty?
|
42
|
+
@missing_args << "Missing argument: WORKSPACE_NAME".red
|
43
|
+
@missing_args << "Usage: faastruby create-workspace WORKSPACE_NAME"
|
44
|
+
end
|
45
|
+
FaaStRuby::CLI.error(["'#{@args.first}' is not a valid workspace name.".red, usage], color: nil) if @args.first =~ /^-.*/
|
46
|
+
@missing_args
|
47
|
+
end
|
48
|
+
|
49
|
+
def parse_options
|
50
|
+
@options = {}
|
51
|
+
while @args.any?
|
52
|
+
option = @args.shift
|
53
|
+
case option
|
54
|
+
# when '--file'
|
55
|
+
# @options['credentials_file'] = @args.shift
|
56
|
+
when '--stdout'
|
57
|
+
@options['stdout'] = true
|
58
|
+
when '-o', '--output-file'
|
59
|
+
@options['credentials_file'] = @args.shift
|
60
|
+
when '-e', '--email'
|
61
|
+
@options['email'] = @args.shift
|
62
|
+
else
|
63
|
+
FaaStRuby.error("Unknown argument: #{option}")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|