vermillion-client 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.hound.yml +2 -0
  4. data/.rubocop.yml +320 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +26 -0
  7. data/README.md +55 -0
  8. data/Rakefile +10 -0
  9. data/bin/setup +7 -0
  10. data/bin/vermillion +16 -0
  11. data/doc/ChangeBranchTest.html +240 -0
  12. data/doc/ConfigurationTest.html +277 -0
  13. data/doc/CreateTest.html +240 -0
  14. data/doc/Gemfile.html +145 -0
  15. data/doc/Gemfile_lock.html +173 -0
  16. data/doc/README_md.html +216 -0
  17. data/doc/Rakefile.html +151 -0
  18. data/doc/UpdateTest.html +280 -0
  19. data/doc/Vermillion.html +272 -0
  20. data/doc/Vermillion/Cfg.html +362 -0
  21. data/doc/Vermillion/Controller.html +185 -0
  22. data/doc/Vermillion/Controller/Base.html +503 -0
  23. data/doc/Vermillion/Controller/Change.html +301 -0
  24. data/doc/Vermillion/Controller/Create.html +301 -0
  25. data/doc/Vermillion/Controller/Firstrun.html +256 -0
  26. data/doc/Vermillion/Controller/Status.html +308 -0
  27. data/doc/Vermillion/Controller/Update.html +326 -0
  28. data/doc/Vermillion/Helper.html +252 -0
  29. data/doc/Vermillion/Helper/ApiCommunication.html +307 -0
  30. data/doc/Vermillion/Helper/Endpoint.html +506 -0
  31. data/doc/Vermillion/Helper/Formatting.html +250 -0
  32. data/doc/Vermillion/Helper/Network.html +304 -0
  33. data/doc/Vermillion/Helper/Results.html +341 -0
  34. data/doc/Vermillion/Helper/Time.html +295 -0
  35. data/doc/Vermillion/Request.html +332 -0
  36. data/doc/Vermillion/Router.html +351 -0
  37. data/doc/Vermillion/Test.html +183 -0
  38. data/doc/Vermillion/Test/Base.html +260 -0
  39. data/doc/Vermillion/Utils.html +247 -0
  40. data/doc/bin/setup.html +147 -0
  41. data/doc/created.rid +33 -0
  42. data/doc/images/add.png +0 -0
  43. data/doc/images/arrow_up.png +0 -0
  44. data/doc/images/brick.png +0 -0
  45. data/doc/images/brick_link.png +0 -0
  46. data/doc/images/bug.png +0 -0
  47. data/doc/images/bullet_black.png +0 -0
  48. data/doc/images/bullet_toggle_minus.png +0 -0
  49. data/doc/images/bullet_toggle_plus.png +0 -0
  50. data/doc/images/date.png +0 -0
  51. data/doc/images/delete.png +0 -0
  52. data/doc/images/find.png +0 -0
  53. data/doc/images/loadingAnimation.gif +0 -0
  54. data/doc/images/macFFBgHack.png +0 -0
  55. data/doc/images/package.png +0 -0
  56. data/doc/images/page_green.png +0 -0
  57. data/doc/images/page_white_text.png +0 -0
  58. data/doc/images/page_white_width.png +0 -0
  59. data/doc/images/plugin.png +0 -0
  60. data/doc/images/ruby.png +0 -0
  61. data/doc/images/tag_blue.png +0 -0
  62. data/doc/images/tag_green.png +0 -0
  63. data/doc/images/transparent.png +0 -0
  64. data/doc/images/wrench.png +0 -0
  65. data/doc/images/wrench_orange.png +0 -0
  66. data/doc/images/zoom.png +0 -0
  67. data/doc/index.html +138 -0
  68. data/doc/js/darkfish.js +155 -0
  69. data/doc/js/jquery.js +4 -0
  70. data/doc/js/navigation.js +142 -0
  71. data/doc/js/search.js +94 -0
  72. data/doc/js/search_index.js +1 -0
  73. data/doc/js/searcher.js +228 -0
  74. data/doc/rdoc.css +595 -0
  75. data/doc/table_of_contents.html +255 -0
  76. data/doc/vermillion-client_gemspec.html +166 -0
  77. data/lib/client.rb +35 -0
  78. data/lib/client/config.rb +58 -0
  79. data/lib/client/controller.rb +68 -0
  80. data/lib/client/controller/change.rb +26 -0
  81. data/lib/client/controller/create.rb +26 -0
  82. data/lib/client/controller/firstrun.rb +30 -0
  83. data/lib/client/controller/status.rb +43 -0
  84. data/lib/client/controller/update.rb +26 -0
  85. data/lib/client/helper.rb +21 -0
  86. data/lib/client/helper/apicommunication.rb +78 -0
  87. data/lib/client/helper/endpoint.rb +61 -0
  88. data/lib/client/helper/formatting.rb +23 -0
  89. data/lib/client/helper/network.rb +54 -0
  90. data/lib/client/helper/results.rb +28 -0
  91. data/lib/client/helper/time.rb +33 -0
  92. data/lib/client/request.rb +22 -0
  93. data/lib/client/router.rb +56 -0
  94. data/lib/client/utils.rb +18 -0
  95. data/lib/client/version.rb +4 -0
  96. data/lib/test.rb +13 -0
  97. data/lib/test/base.rb +17 -0
  98. data/test/test_change_branch.rb +14 -0
  99. data/test/test_configuration.rb +21 -0
  100. data/test/test_create.rb +14 -0
  101. data/test/test_update.rb +24 -0
  102. data/vermillion-client.gemspec +23 -0
  103. 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