vermillion-client 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.hound.yml +2 -0
- data/.rubocop.yml +320 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +26 -0
- data/README.md +55 -0
- data/Rakefile +10 -0
- data/bin/setup +7 -0
- data/bin/vermillion +16 -0
- data/doc/ChangeBranchTest.html +240 -0
- data/doc/ConfigurationTest.html +277 -0
- data/doc/CreateTest.html +240 -0
- data/doc/Gemfile.html +145 -0
- data/doc/Gemfile_lock.html +173 -0
- data/doc/README_md.html +216 -0
- data/doc/Rakefile.html +151 -0
- data/doc/UpdateTest.html +280 -0
- data/doc/Vermillion.html +272 -0
- data/doc/Vermillion/Cfg.html +362 -0
- data/doc/Vermillion/Controller.html +185 -0
- data/doc/Vermillion/Controller/Base.html +503 -0
- data/doc/Vermillion/Controller/Change.html +301 -0
- data/doc/Vermillion/Controller/Create.html +301 -0
- data/doc/Vermillion/Controller/Firstrun.html +256 -0
- data/doc/Vermillion/Controller/Status.html +308 -0
- data/doc/Vermillion/Controller/Update.html +326 -0
- data/doc/Vermillion/Helper.html +252 -0
- data/doc/Vermillion/Helper/ApiCommunication.html +307 -0
- data/doc/Vermillion/Helper/Endpoint.html +506 -0
- data/doc/Vermillion/Helper/Formatting.html +250 -0
- data/doc/Vermillion/Helper/Network.html +304 -0
- data/doc/Vermillion/Helper/Results.html +341 -0
- data/doc/Vermillion/Helper/Time.html +295 -0
- data/doc/Vermillion/Request.html +332 -0
- data/doc/Vermillion/Router.html +351 -0
- data/doc/Vermillion/Test.html +183 -0
- data/doc/Vermillion/Test/Base.html +260 -0
- data/doc/Vermillion/Utils.html +247 -0
- data/doc/bin/setup.html +147 -0
- data/doc/created.rid +33 -0
- data/doc/images/add.png +0 -0
- data/doc/images/arrow_up.png +0 -0
- data/doc/images/brick.png +0 -0
- data/doc/images/brick_link.png +0 -0
- data/doc/images/bug.png +0 -0
- data/doc/images/bullet_black.png +0 -0
- data/doc/images/bullet_toggle_minus.png +0 -0
- data/doc/images/bullet_toggle_plus.png +0 -0
- data/doc/images/date.png +0 -0
- data/doc/images/delete.png +0 -0
- data/doc/images/find.png +0 -0
- data/doc/images/loadingAnimation.gif +0 -0
- data/doc/images/macFFBgHack.png +0 -0
- data/doc/images/package.png +0 -0
- data/doc/images/page_green.png +0 -0
- data/doc/images/page_white_text.png +0 -0
- data/doc/images/page_white_width.png +0 -0
- data/doc/images/plugin.png +0 -0
- data/doc/images/ruby.png +0 -0
- data/doc/images/tag_blue.png +0 -0
- data/doc/images/tag_green.png +0 -0
- data/doc/images/transparent.png +0 -0
- data/doc/images/wrench.png +0 -0
- data/doc/images/wrench_orange.png +0 -0
- data/doc/images/zoom.png +0 -0
- data/doc/index.html +138 -0
- data/doc/js/darkfish.js +155 -0
- data/doc/js/jquery.js +4 -0
- data/doc/js/navigation.js +142 -0
- data/doc/js/search.js +94 -0
- data/doc/js/search_index.js +1 -0
- data/doc/js/searcher.js +228 -0
- data/doc/rdoc.css +595 -0
- data/doc/table_of_contents.html +255 -0
- data/doc/vermillion-client_gemspec.html +166 -0
- data/lib/client.rb +35 -0
- data/lib/client/config.rb +58 -0
- data/lib/client/controller.rb +68 -0
- data/lib/client/controller/change.rb +26 -0
- data/lib/client/controller/create.rb +26 -0
- data/lib/client/controller/firstrun.rb +30 -0
- data/lib/client/controller/status.rb +43 -0
- data/lib/client/controller/update.rb +26 -0
- data/lib/client/helper.rb +21 -0
- data/lib/client/helper/apicommunication.rb +78 -0
- data/lib/client/helper/endpoint.rb +61 -0
- data/lib/client/helper/formatting.rb +23 -0
- data/lib/client/helper/network.rb +54 -0
- data/lib/client/helper/results.rb +28 -0
- data/lib/client/helper/time.rb +33 -0
- data/lib/client/request.rb +22 -0
- data/lib/client/router.rb +56 -0
- data/lib/client/utils.rb +18 -0
- data/lib/client/version.rb +4 -0
- data/lib/test.rb +13 -0
- data/lib/test/base.rb +17 -0
- data/test/test_change_branch.rb +14 -0
- data/test/test_configuration.rb +21 -0
- data/test/test_create.rb +14 -0
- data/test/test_update.rb +24 -0
- data/vermillion-client.gemspec +23 -0
- metadata +201 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
module Vermillion
|
2
|
+
# Flag for enabling more verbose output from certain methods
|
3
|
+
DEBUG = false
|
4
|
+
|
5
|
+
class Cfg
|
6
|
+
# Perform first run tasks and create or read config file values
|
7
|
+
def bootstrap!
|
8
|
+
populate_config
|
9
|
+
|
10
|
+
return if valid_config?
|
11
|
+
|
12
|
+
# no config file found, lets create one using the firstrun controller
|
13
|
+
require 'client/controller/firstrun'
|
14
|
+
|
15
|
+
controller = Vermillion::Controller::Firstrun.new
|
16
|
+
controller.default
|
17
|
+
|
18
|
+
populate_config
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns a hash of all module constants and their values
|
22
|
+
def options
|
23
|
+
keys = Vermillion.constants.select { |name| constant?(name) }
|
24
|
+
hash = {}
|
25
|
+
|
26
|
+
keys.each { |key| hash[key] = Vermillion.const_get(key) }
|
27
|
+
hash
|
28
|
+
end
|
29
|
+
|
30
|
+
# Populates the internal hash which stores any values set in the config file
|
31
|
+
def populate_config
|
32
|
+
file = File.expand_path("~/.vermillion.yml")
|
33
|
+
fmt = Vermillion::Helper.load('formatting')
|
34
|
+
|
35
|
+
@yml = fmt.symbolize(::YAML.load_file(file))
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
# Get a specific value from the config file data
|
40
|
+
# Params:
|
41
|
+
# +name+:: String/symbol key value
|
42
|
+
def get(name)
|
43
|
+
@yml[name.to_sym]
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Check if configuration data exists
|
49
|
+
def valid_config?
|
50
|
+
!@yml.nil?
|
51
|
+
end
|
52
|
+
|
53
|
+
# Checks if string is a constant
|
54
|
+
def constant?(name)
|
55
|
+
name == name.upcase
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Vermillion
|
2
|
+
module Controller
|
3
|
+
class Base
|
4
|
+
attr_accessor :config, :request
|
5
|
+
|
6
|
+
# Exit code to indicate everything is ok!
|
7
|
+
OK = 0
|
8
|
+
# Exit code to indicate a force quit (exit) call, meaning the program
|
9
|
+
# quit with an error
|
10
|
+
QUIT = 1
|
11
|
+
# Exit code to indicate that the program exited with a non-zero exit code,
|
12
|
+
# but not one that resulted in a force quit
|
13
|
+
QUIT_SOFT = 2
|
14
|
+
|
15
|
+
# Setup internal variables that will be used in subclasses
|
16
|
+
# Params:
|
17
|
+
# +config+:: Instance of Vermillion::Cfg to enable access to config file
|
18
|
+
# +request+:: Instance of Vermillion::Request, enables access to request
|
19
|
+
# parameters
|
20
|
+
def initialize(config, request)
|
21
|
+
@config = config
|
22
|
+
@request = request
|
23
|
+
|
24
|
+
pre_exec
|
25
|
+
end
|
26
|
+
|
27
|
+
# Perform pre-run tasks
|
28
|
+
def pre_exec
|
29
|
+
@format = Vermillion::Helper.load('formatting')
|
30
|
+
@network = Vermillion::Helper.load('network')
|
31
|
+
@network.config = @config
|
32
|
+
end
|
33
|
+
|
34
|
+
# Handle the request
|
35
|
+
def exec
|
36
|
+
if @request.param.nil?
|
37
|
+
send(@method.to_sym)
|
38
|
+
else
|
39
|
+
send(@method.to_sym, @request.param)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Perform post-run cleanup tasks, such as deleting old logs
|
44
|
+
def post_exec
|
45
|
+
end
|
46
|
+
|
47
|
+
# Determines if the command can execute
|
48
|
+
# Params:
|
49
|
+
# +command+:: Symbol containing the command we want to execute
|
50
|
+
def can_exec?(command)
|
51
|
+
# no command was passed, check if controller has a default method
|
52
|
+
if command.nil? && respond_to?(:default)
|
53
|
+
@method = :default
|
54
|
+
elsif respond_to? command
|
55
|
+
# check the controller for the requested method
|
56
|
+
@method = command
|
57
|
+
else
|
58
|
+
raise NoMethodError, "Invalid method: #{command}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Default method called by exec if no argument is passed
|
63
|
+
def sample
|
64
|
+
Notify.warning("Method not implemented")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Vermillion
|
2
|
+
module Controller
|
3
|
+
class Change < Controller::Base
|
4
|
+
include Helper::ApiCommunication
|
5
|
+
|
6
|
+
# Prepare to execute the requested method
|
7
|
+
def pre_exec
|
8
|
+
OptionParser.new do |opt|
|
9
|
+
opt.banner = "vermillion change [...-flags]"
|
10
|
+
|
11
|
+
opt.on("-t", "--to=TO", "Branch to change to") { |o| @to = o }
|
12
|
+
end.parse!
|
13
|
+
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
# Change branches on the selected server
|
18
|
+
# +server+:: Symbol representing the server you want to access
|
19
|
+
# +to+:: Optional symbol, what branch should we change to?
|
20
|
+
def branch(server, to = nil)
|
21
|
+
@to = to || @to
|
22
|
+
send_to_one(server, :change_branch, to: @to)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Vermillion
|
2
|
+
module Controller
|
3
|
+
class Create < Controller::Base
|
4
|
+
include Helper::ApiCommunication
|
5
|
+
|
6
|
+
# Prepare to execute the requested method
|
7
|
+
def pre_exec
|
8
|
+
OptionParser.new do |opt|
|
9
|
+
opt.banner = "vermillion create [...-flags]"
|
10
|
+
|
11
|
+
opt.on("-n", "--name=NAME", "Directory to be created") { |o| @name = o }
|
12
|
+
end.parse!
|
13
|
+
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
# Create a new project on the requested server
|
18
|
+
# +server+:: Symbol representing the server you want to access
|
19
|
+
# +name+:: Optional symbol, the name of the project
|
20
|
+
def one(server, name = nil)
|
21
|
+
@name = name || @name
|
22
|
+
send_to_one(server, :create, name: @name)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Vermillion
|
2
|
+
module Controller
|
3
|
+
class Firstrun < Controller::Base
|
4
|
+
# Create the configuration file if it does not exist
|
5
|
+
def default
|
6
|
+
if File.exist?(Dir.home + '/.vermillion.yml')
|
7
|
+
Notify.error("Configuration already exists, this is not the first run! Exiting.", show_time: false)
|
8
|
+
end
|
9
|
+
|
10
|
+
File.open(Dir.home + '/.vermillion.yml', "w") do |f|
|
11
|
+
f.write <<-'CONTENTS'
|
12
|
+
servers:
|
13
|
+
-
|
14
|
+
name: dev
|
15
|
+
address: 192.168.0.74
|
16
|
+
https: false
|
17
|
+
key: EDIT_ME
|
18
|
+
-
|
19
|
+
name: local
|
20
|
+
address: localhost:8000
|
21
|
+
https: false
|
22
|
+
key: EDIT_ME
|
23
|
+
user:
|
24
|
+
test@example.com
|
25
|
+
CONTENTS
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Vermillion
|
2
|
+
module Controller
|
3
|
+
class Status < Controller::Base
|
4
|
+
# Prints both configuration and server information, returns status code 0
|
5
|
+
def default
|
6
|
+
print_config
|
7
|
+
print_servers
|
8
|
+
|
9
|
+
OK
|
10
|
+
end
|
11
|
+
|
12
|
+
# Print configuration information
|
13
|
+
def config
|
14
|
+
print_config
|
15
|
+
end
|
16
|
+
|
17
|
+
# Print configured server information
|
18
|
+
def servers
|
19
|
+
print_servers
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# Process and print config values
|
25
|
+
def print_config
|
26
|
+
Notify.info("Configuration values")
|
27
|
+
|
28
|
+
@config.options.each_pair do |key, value|
|
29
|
+
Notify.spit " - #{key}: #{value}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Process and print server values
|
34
|
+
def print_servers
|
35
|
+
Notify.info('Sites')
|
36
|
+
|
37
|
+
@config.get(:servers).each do |server|
|
38
|
+
Notify.spit(" - Name: #{server[:name]}, Address: #{server[:address]}, HTTPS: #{server[:https]}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Vermillion
|
2
|
+
module Controller
|
3
|
+
class Update < Controller::Base
|
4
|
+
include Helper::ApiCommunication
|
5
|
+
|
6
|
+
# Update all sites in the manifest
|
7
|
+
def all
|
8
|
+
send_to_all(:update)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Update just one server
|
12
|
+
# Params:
|
13
|
+
# +server+:: Symbol representing the server you want to update
|
14
|
+
def one(server)
|
15
|
+
send_to_one(server, :update)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Update the configuration manifest for one server
|
19
|
+
# Params:
|
20
|
+
# +server+:: Symbol representing the server you want to update
|
21
|
+
def config(server)
|
22
|
+
send_to_one(server, :update_config)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Vermillion
|
2
|
+
module Helper
|
3
|
+
# Loads a helper class
|
4
|
+
# Params:
|
5
|
+
# +klass+:: String representing the class helper subclass you want to load
|
6
|
+
# +args+:: Optional arguments to pass to the class instance
|
7
|
+
def self.load(klass, args = nil)
|
8
|
+
klass_instance = Vermillion::Helper.const_get(klass.capitalize)
|
9
|
+
|
10
|
+
if klass_instance
|
11
|
+
if args.nil?
|
12
|
+
klass_instance.new
|
13
|
+
else
|
14
|
+
klass_instance.new(args)
|
15
|
+
end
|
16
|
+
else
|
17
|
+
Notify.error("Class not found: #{klass.capitalize}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Vermillion
|
2
|
+
module Helper
|
3
|
+
module ApiCommunication
|
4
|
+
# Send an HTTP request to one server
|
5
|
+
# Params:
|
6
|
+
# +input+:: The server you want to connect to
|
7
|
+
# +endpoint+:: The REST endpoint you'd like to send a request to
|
8
|
+
# +args+:: Any specific configuration data to send along with the request
|
9
|
+
def send_to_one(input, endpoint, args = {})
|
10
|
+
server, endpoint = setup(input, endpoint, args)
|
11
|
+
|
12
|
+
begin
|
13
|
+
resp = @network.post(endpoint.to_s, server[:key])
|
14
|
+
|
15
|
+
Notify.spit(endpoint.to_s) if DEBUG
|
16
|
+
Notify.spit(resp.body) if DEBUG
|
17
|
+
|
18
|
+
# generic failure for invalid response type
|
19
|
+
raise Errno::ECONNREFUSED if resp["Content-Type"] != "application/json"
|
20
|
+
|
21
|
+
# handle JSON response
|
22
|
+
response_data = @format.symbolize(JSON.parse(resp.body))
|
23
|
+
|
24
|
+
if response_data[:_code] == 200
|
25
|
+
Notify.success("#{server[:name]} (#{server[:address]}) update succeeded")
|
26
|
+
elsif !response_data[:message].nil?
|
27
|
+
# work around a messaging issue with vermillion-server
|
28
|
+
Notify.warning("Error: #{response_data[:message]}")
|
29
|
+
else
|
30
|
+
Notify.warning("#{response_data[:_title]}: #{response_data[:_message]}")
|
31
|
+
end
|
32
|
+
rescue Errno::ECONNREFUSED
|
33
|
+
Notify.warning("Request failed for #{server[:name]} (#{server[:address]})")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Send HTTP requests to all servers in the local manifest
|
38
|
+
# Params:
|
39
|
+
# +endpoint+:: The REST endpoint you'd like to send a request to
|
40
|
+
# +args+:: Any specific configuration data to send along with the request
|
41
|
+
def send_to_all(endpoint, args = {})
|
42
|
+
@config.get(:servers).each do |server|
|
43
|
+
send_to_one(server[:name], endpoint, args) if server[:name]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# Perform setup tasks in ApiCommuniction.send_to_one
|
50
|
+
# Params:
|
51
|
+
# +input+:: The server you want to connect to
|
52
|
+
# +endpoint+:: The REST endpoint you'd like to send a request to
|
53
|
+
# +args+:: Any specific configuration data to send along with the request
|
54
|
+
def setup(input, endpoint, args = {})
|
55
|
+
server_name = input
|
56
|
+
remote_site = nil
|
57
|
+
server_name, remote_site = input.split('/') if input.to_s.include?('/')
|
58
|
+
|
59
|
+
server = @config.get(:servers).select { |hash| hash[:name].to_sym == server_name.to_sym }.first
|
60
|
+
|
61
|
+
# warn user if the server is not defined
|
62
|
+
return Notify.warning("Server not found: #{server_name}") unless server
|
63
|
+
# warn user if the site does not have a secret key property set
|
64
|
+
return Notify.warning("The server configuration must contain a key property to send requests") unless server[:key]
|
65
|
+
# warn user if the user key is not defined
|
66
|
+
return Notify.warning("The configuration file must contain a user") unless @config.get(:user)
|
67
|
+
|
68
|
+
endpoint = Endpoint.new("/api/#{endpoint}/")
|
69
|
+
endpoint.server = server[:address]
|
70
|
+
endpoint.protocol = server[:https]
|
71
|
+
endpoint.add(:remote, remote_site) if remote_site
|
72
|
+
endpoint.add(:query_string, Utils.to_query_string(args))
|
73
|
+
|
74
|
+
[server, endpoint]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Vermillion
|
2
|
+
module Helper
|
3
|
+
class Endpoint
|
4
|
+
attr_writer :server
|
5
|
+
|
6
|
+
# Creates the Endpoint object with default values for internal variables
|
7
|
+
# Params:
|
8
|
+
# +initial_path+:: Starting point of the URL this class will build
|
9
|
+
def initialize(initial_path)
|
10
|
+
@path = { default: initial_path }
|
11
|
+
@server = nil
|
12
|
+
@protocol = "http://"
|
13
|
+
end
|
14
|
+
|
15
|
+
# Set endpoint protocol
|
16
|
+
# Params:
|
17
|
+
# +use_https+:: Boolean value for whether to use HTTPS
|
18
|
+
def protocol=(use_https)
|
19
|
+
@protocol = 'https://' if use_https
|
20
|
+
end
|
21
|
+
|
22
|
+
# Add a section to the path
|
23
|
+
# Params:
|
24
|
+
# +key+:: Symbol, the key to identify the section
|
25
|
+
# +value+:: Any value to store with the associated key
|
26
|
+
def add(key, value)
|
27
|
+
@path[key.to_sym] = value
|
28
|
+
end
|
29
|
+
|
30
|
+
# Return a value based on the provided key
|
31
|
+
# Params:
|
32
|
+
# +key+:: Symbol, the key to identify the section
|
33
|
+
def get(key)
|
34
|
+
@path[key.to_sym]
|
35
|
+
end
|
36
|
+
|
37
|
+
# Deletes a value from the internal hash based on a key
|
38
|
+
# Params:
|
39
|
+
# +key+:: Symbol, the key to identify the section
|
40
|
+
def delete(key)
|
41
|
+
@path.delete(key)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Checks whether a key exists
|
45
|
+
# Params:
|
46
|
+
# +key+:: Symbol, the key to identify the section
|
47
|
+
def exists?(key)
|
48
|
+
@path.key? key
|
49
|
+
end
|
50
|
+
|
51
|
+
# Override the to_s method to return an endpoint fragment
|
52
|
+
def to_s
|
53
|
+
output = @protocol + @server
|
54
|
+
@path.each_pair do |_k, value|
|
55
|
+
output += value
|
56
|
+
end
|
57
|
+
output
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|