req-cli 0.0.1
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/bin/req +5 -0
- data/lib/config.rb +44 -0
- data/lib/context.rb +10 -0
- data/lib/curl_backend.rb +30 -0
- data/lib/environment.rb +12 -0
- data/lib/prepared_request.rb +18 -0
- data/lib/req-cli.rb +139 -0
- data/lib/request.rb +15 -0
- data/lib/request_factory.rb +42 -0
- data/lib/state.rb +8 -0
- data/lib/variable_interpolator.rb +16 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9ce6c0c76b2d31aa7e45b63fd8d8af40c40ec826
|
4
|
+
data.tar.gz: d742a1985e3bf964678a5475a1fd0529bc1ee423
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a019e10f8e119d44d24c816ce7b1dcdc4614f54806744a099eaf1c39c24ef12eabd54874f3312c2d13e9f87a6e2b7cc669887e29bb52bf0723cfd0f54351d6c4
|
7
|
+
data.tar.gz: ccac9284dceeb3c273cfedb42d614c7413dce65e6c126d6fd0646d67268ef0925a0762288143e5d10312a9746dabcc889056c12d592dc36822ff6768da194ea7
|
data/bin/req
ADDED
data/lib/config.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
class Config
|
3
|
+
attr_accessor :contexts, :environments, :requests
|
4
|
+
|
5
|
+
def initialize(hash)
|
6
|
+
@contexts = hash[:contexts] || hash['contexts'] || {}
|
7
|
+
@contexts = @contexts.map {|ctx| Context.new(ctx) }
|
8
|
+
|
9
|
+
@environments = hash[:environments] || hash['environments'] || {}
|
10
|
+
@environments = @environments.map { |env| Environment.new(env) }
|
11
|
+
|
12
|
+
@requests = hash[:requests] || hash['requests'] || {}
|
13
|
+
@requests = @requests.map { |req| Request.new(req) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.create_from_yaml(yaml_string)
|
17
|
+
return Config.new YAML.load(yaml_string)
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_context?(ctx_name)
|
21
|
+
@contexts.any? {|ctx| ctx.name == ctx_name }
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_context(ctx_name)
|
25
|
+
@contexts.find {|ctx| ctx.name == ctx_name }
|
26
|
+
end
|
27
|
+
|
28
|
+
def has_environment?(env_name)
|
29
|
+
@environments.any? {|env| env.name == env_name }
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_environment(env_name)
|
33
|
+
@environments.find {|env| env.name == env_name }
|
34
|
+
end
|
35
|
+
|
36
|
+
def has_request?(env_name)
|
37
|
+
@requests.any? {|env| env.name == env_name }
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_request(env_name)
|
41
|
+
@requests.find {|env| env.name == env_name }
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/lib/context.rb
ADDED
data/lib/curl_backend.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
class CurlBackend
|
2
|
+
|
3
|
+
def initialize(prepared_request, options={})
|
4
|
+
@request = prepared_request
|
5
|
+
@curl_options = parse_curl_options(options)
|
6
|
+
end
|
7
|
+
|
8
|
+
def execute
|
9
|
+
header_string = @request.headers.map {|key, val| "-H '#{key}: #{val}'"}.join ' '
|
10
|
+
data_string = @request.data ? "-d '#{@request.data}'" : ""
|
11
|
+
|
12
|
+
curl_command = "curl -X #{@request.method.upcase} #{header_string} #{data_string} #{@curl_options} #{@request.uri}"
|
13
|
+
system curl_command
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse_curl_options(options)
|
17
|
+
opts = ''
|
18
|
+
|
19
|
+
if options.has_key? 'verbose'
|
20
|
+
opts += '--verbose '
|
21
|
+
end
|
22
|
+
|
23
|
+
if options.has_key? 'head'
|
24
|
+
opts += ' --head '
|
25
|
+
end
|
26
|
+
|
27
|
+
opts
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/lib/environment.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
class Environment
|
2
|
+
attr_accessor :name, :variables, :endpoint, :headers
|
3
|
+
|
4
|
+
def initialize(hash)
|
5
|
+
@name = hash[:name] || hash['name'] || ''
|
6
|
+
@endpoint = hash[:endpoint] || hash['endpoint'] || ''
|
7
|
+
@variables = hash[:vars] || hash['vars'] || {}
|
8
|
+
@headers = hash[:headers] || hash['headers'] || {}
|
9
|
+
|
10
|
+
# TODO raise exceptions when @name or @endpoint is nil or empty
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class PreparedRequest
|
2
|
+
|
3
|
+
attr_accessor :headers, :uri, :method, :data
|
4
|
+
|
5
|
+
def initialize(options={})
|
6
|
+
@headers = options[:headers] || {}
|
7
|
+
@uri = options[:uri] || ''
|
8
|
+
@method = options[:method] || :get
|
9
|
+
@data = options[:data] || nil
|
10
|
+
end
|
11
|
+
|
12
|
+
# Hash of HTTP headers
|
13
|
+
|
14
|
+
# string with full request URI
|
15
|
+
|
16
|
+
# symbol :get, :post, :put, :delete
|
17
|
+
|
18
|
+
end
|
data/lib/req-cli.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
require 'context'
|
5
|
+
require 'environment'
|
6
|
+
require 'request'
|
7
|
+
require 'state'
|
8
|
+
require 'config'
|
9
|
+
require 'prepared_request'
|
10
|
+
require 'request_factory'
|
11
|
+
require 'variable_interpolator'
|
12
|
+
require 'curl_backend'
|
13
|
+
|
14
|
+
STATEFILE = '.reqstate'
|
15
|
+
REQFILE = 'Reqfile'
|
16
|
+
|
17
|
+
|
18
|
+
class Req < Thor
|
19
|
+
|
20
|
+
attr_accessor :config, :state
|
21
|
+
@config = nil
|
22
|
+
@state = nil
|
23
|
+
|
24
|
+
def self.create_with_config(config)
|
25
|
+
req = Req.new
|
26
|
+
req.config = config
|
27
|
+
req.state = State.new
|
28
|
+
req
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "contexts", "list all contexts"
|
32
|
+
def contexts
|
33
|
+
init # TODO avoid this
|
34
|
+
@config.contexts.each {|ctx| puts ctx.name }
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "context NAME", "switch to context NAME"
|
38
|
+
def context(name)
|
39
|
+
init
|
40
|
+
if @config.contexts.any? { |ctx| ctx.name == name }
|
41
|
+
puts "switching to context #{name}"
|
42
|
+
@state.context = name
|
43
|
+
save_state
|
44
|
+
else
|
45
|
+
puts "context not found"
|
46
|
+
exit 1
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "environments", "list all environments"
|
51
|
+
def environments
|
52
|
+
init
|
53
|
+
@config.environments.each {|env| puts env.name }
|
54
|
+
end
|
55
|
+
|
56
|
+
desc "environment", "switch to environment"
|
57
|
+
def environment(name)
|
58
|
+
init
|
59
|
+
if @config.has_environment? name
|
60
|
+
puts "switching to environment #{name}"
|
61
|
+
@state.environment = name
|
62
|
+
save_state
|
63
|
+
else
|
64
|
+
puts "environment not found"
|
65
|
+
exit 1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
desc "variable NAME VALUE", "add variable with key NAME and value VALUE"
|
70
|
+
def variable(name, value)
|
71
|
+
init
|
72
|
+
@state.variables[name] = value
|
73
|
+
save_state
|
74
|
+
end
|
75
|
+
|
76
|
+
desc "variables", "list all custom variables"
|
77
|
+
def variables
|
78
|
+
init
|
79
|
+
@state.variables.each {|key, val| put "#{key}: #{val}" }
|
80
|
+
end
|
81
|
+
|
82
|
+
desc "status", "print current environment and context info"
|
83
|
+
def status
|
84
|
+
init
|
85
|
+
puts "context: #{@state.context}"
|
86
|
+
puts "environment: #{@state.environment}"
|
87
|
+
puts "variables: "
|
88
|
+
@state.variables.each { |key,val| puts " #{key}: #{val}" }
|
89
|
+
end
|
90
|
+
|
91
|
+
desc "clear", "clear current context, environment and vars"
|
92
|
+
def clear
|
93
|
+
@state = State.new
|
94
|
+
save_state
|
95
|
+
end
|
96
|
+
|
97
|
+
desc "exec REQUESTNAME", "execute request with name REQUESTNAME"
|
98
|
+
option :verbose, aliases: '-v'
|
99
|
+
option :head, aliases: '-I'
|
100
|
+
def exec(requestname)
|
101
|
+
init
|
102
|
+
valid_for_execution?
|
103
|
+
request = @config.get_request(requestname)
|
104
|
+
prepared_request = RequestFactory.create(@config, @state, request)
|
105
|
+
backend = CurlBackend.new prepared_request, options
|
106
|
+
backend.execute
|
107
|
+
end
|
108
|
+
|
109
|
+
desc "requests", "list all requests"
|
110
|
+
def requests
|
111
|
+
init
|
112
|
+
@config.requests.each {|req| puts "#{req.name} \t#{req.method} \t#{req.path}"}
|
113
|
+
end
|
114
|
+
|
115
|
+
no_commands do
|
116
|
+
def init
|
117
|
+
return if @config
|
118
|
+
@state = State.new
|
119
|
+
@config = Config.create_from_yaml(File.read(REQFILE))
|
120
|
+
if File.exist? '.reqstate'
|
121
|
+
@state = YAML.load(File.read(STATEFILE))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def valid_for_execution?
|
126
|
+
env = @config.get_environment(@state.environment)
|
127
|
+
puts "No valid environment specified, use req environment NAME to choose an environment" if env.nil?
|
128
|
+
exit 1 if env.nil?
|
129
|
+
|
130
|
+
ctx = @config.get_context(@state.context)
|
131
|
+
puts "No valid context specified, use req context NAME to choose a context" if ctx.nil?
|
132
|
+
exit 1 if ctx.nil?
|
133
|
+
end
|
134
|
+
|
135
|
+
def save_state
|
136
|
+
File.write(STATEFILE, @state.to_yaml)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
data/lib/request.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
class Request
|
2
|
+
attr_accessor :name, :path, :method, :headers, :variables, :data
|
3
|
+
|
4
|
+
def initialize(hash)
|
5
|
+
@name = hash[:name] || hash['name'] || ''
|
6
|
+
@path = hash[:path] || hash['path'] || ''
|
7
|
+
@method = hash[:method] || hash['method'] || ''
|
8
|
+
|
9
|
+
@headers = hash[:headers] || hash['headers'] || {}
|
10
|
+
@variables = hash[:vars] || hash['vars'] || {}
|
11
|
+
@data = hash[:data] || hash['data'] || nil
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class RequestFactory
|
2
|
+
def self.create(config, state, request)
|
3
|
+
environment = config.get_environment(state.environment) || Environment.new
|
4
|
+
context = config.get_context(state.context) || Context.new
|
5
|
+
|
6
|
+
variables = merge_variables(environment, context, request, state.variables)
|
7
|
+
interpolator = VariableInterpolator.new(variables)
|
8
|
+
|
9
|
+
PreparedRequest.new({
|
10
|
+
headers: build_headers(environment, context, request, interpolator),
|
11
|
+
method: request.method.downcase.to_sym,
|
12
|
+
uri: build_uri(environment, context, request, interpolator),
|
13
|
+
data: build_data(request, interpolator)
|
14
|
+
})
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.merge_variables(environment, context, request, custom_variables)
|
18
|
+
(environment.variables || {})
|
19
|
+
.merge(context.variables || {})
|
20
|
+
.merge(request.variables || {})
|
21
|
+
.merge(custom_variables || {})
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.build_headers(environment, context, request, interpolator)
|
25
|
+
environment.headers
|
26
|
+
.merge(context.headers)
|
27
|
+
.merge(request.headers)
|
28
|
+
.map {|key, value| [key, interpolator.interpolate(value)]}.to_h
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.build_uri(environment, context, request, interpolator)
|
32
|
+
uri = environment.endpoint + request.path
|
33
|
+
interpolator.interpolate(uri)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.build_data(request, interpolator)
|
37
|
+
return nil if request.data.nil?
|
38
|
+
|
39
|
+
interpolator.interpolate(request.data)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
data/lib/state.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
class VariableInterpolator
|
2
|
+
|
3
|
+
attr_accessor :variables
|
4
|
+
|
5
|
+
def initialize(variables = {})
|
6
|
+
@variables = variables.map { |key, value| [key.to_sym, value] }.to_h
|
7
|
+
end
|
8
|
+
|
9
|
+
def interpolate(input)
|
10
|
+
input.gsub(/\${[a-zA-Z0-9\-_]*}/) do |m|
|
11
|
+
var = m.scan(/[a-zA-Z0-9\-_]+/).first.to_sym
|
12
|
+
variables[var]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: req-cli
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Steven Van Bael
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.19'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.19'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: httparty
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.14'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.14'
|
41
|
+
description: ''
|
42
|
+
email: steven@quantus.io
|
43
|
+
executables:
|
44
|
+
- req
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- bin/req
|
49
|
+
- lib/config.rb
|
50
|
+
- lib/context.rb
|
51
|
+
- lib/curl_backend.rb
|
52
|
+
- lib/environment.rb
|
53
|
+
- lib/prepared_request.rb
|
54
|
+
- lib/req-cli.rb
|
55
|
+
- lib/request.rb
|
56
|
+
- lib/request_factory.rb
|
57
|
+
- lib/state.rb
|
58
|
+
- lib/variable_interpolator.rb
|
59
|
+
homepage: http://github.com/vbsteven/req
|
60
|
+
licenses:
|
61
|
+
- MIT
|
62
|
+
metadata: {}
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 2.5.1
|
80
|
+
signing_key:
|
81
|
+
specification_version: 4
|
82
|
+
summary: CLI tool for templating HTTP requests from a config file and execute them
|
83
|
+
with curl.
|
84
|
+
test_files: []
|