faastruby 0.2.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 +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
|