deployhq 2.0.4 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2960dfa1052e55bb3174a4f45ffe857918dfd624016c1536215ceeccd5ff541f
4
- data.tar.gz: ac02d56e4afb69f993453f470626f5abaa2c8229e7e24213d0d73d8449d453b6
3
+ metadata.gz: 7822d0dc6c5d8d2ba5b4dc65e955badf2e80fb3634897c5671155035ba6dbbe3
4
+ data.tar.gz: 17493bebc4b52686ce52bbbec87736084746eb97392fa7942913f31b508b1e5d
5
5
  SHA512:
6
- metadata.gz: 5344ddc86c626f64a4b3a5c943c07ec92f9a6861eb06c012a810ea384983d1061ab4a8d9e38a15cf4b006c6a62cebbc2f47027c69bee48b525cc66b16853a307
7
- data.tar.gz: 664c4a3d67eb79addcf3b880520a70261c1665f1b41251d94e96bd04350fa7443b04c4d79c6d7998d08cc3a855c8867ba3cfe5c40bc04f9f1b5cfb134c855904
6
+ metadata.gz: 7b533389d7fa5604510a5ced8f9b1e22187df73cc23a6d79a2e2e9b98c0ea2ee1f0875816babbd7a5e3c6b66928274e14ac5777397283d5e6e3f7a1ba8c6c753
7
+ data.tar.gz: b5d3ec552dd78c0caceed18f64b6a1753480c54665cf50ebbf28c8aa26249ed144133915f02c645a147e14b20d9cf0662cf6de2991125da694764519fc0480dc
data/bin/deployhq CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
- libdir = File.expand_path('../../lib', __FILE__)
2
+ # frozen_string_literal: true
3
+
4
+ libdir = File.expand_path('../lib', __dir__)
3
5
  $LOAD_PATH.unshift(libdir)
4
6
 
5
7
  require 'deploy/cli'
@@ -1,9 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Deploy
2
4
  class CLI
5
+
3
6
  class DeploymentProgressOutput
7
+
4
8
  SERVER_TAG_COLOURS = %w[32 33 34 35 36].cycle
5
9
 
6
- attr_reader :deployment, :step_index, :server_tags
10
+ attr_reader :deployment
11
+ attr_reader :step_index
12
+ attr_reader :server_tags
7
13
 
8
14
  def initialize(deployment)
9
15
  @deployment = deployment
@@ -26,13 +32,14 @@ module Deploy
26
32
 
27
33
  private
28
34
 
35
+ # rubocop:disable Metrics/AbcSize
29
36
  def handle_log_entry(payload)
30
37
  step = step_index[payload['step']]
31
38
  server_tag = server_tags[step.server]
32
39
 
33
- line = "\n"
34
- line << server_tag if server_tag
35
- line << payload['message']
40
+ lines = ["\n"]
41
+ lines << server_tag
42
+ lines << payload['message']
36
43
 
37
44
  if payload['detail']
38
45
  padding_width = 0
@@ -40,22 +47,25 @@ module Deploy
40
47
  padding = ' ' * padding_width
41
48
 
42
49
  payload['detail'].split("\n").each do |detail_line|
43
- line << "\n#{padding}| #{detail_line}"
50
+ lines << "\n#{padding}| #{detail_line}"
44
51
  end
45
52
  end
46
53
 
47
- STDOUT.print line
54
+ $stdout.print lines.join
48
55
  end
56
+ # rubocop:enable Metrics/AbcSize
49
57
 
50
58
  def handle_status_change(payload)
51
59
  if payload['status'] == 'completed'
52
- STDOUT.print "\nDeployment has finished successfully!\n"
60
+ $stdout.print "\nDeployment has finished successfully!\n"
53
61
  elsif payload['status'] == 'failed'
54
- STDOUT.print "\nDeployment has failed!\n"
62
+ $stdout.print "\nDeployment has failed!\n"
55
63
  end
56
64
 
57
65
  throw(:finished) if %w[completed failed].include?(payload['status'])
58
66
  end
67
+
59
68
  end
69
+
60
70
  end
61
71
  end
@@ -1,14 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'websocket-eventmachine-client'
2
4
  require 'logger'
3
5
 
4
6
  module Deploy
5
7
  class CLI
8
+
6
9
  # Manages a connection and associated subscriptions to DeployHQ's websocket
7
10
  class WebsocketClient
11
+
8
12
  attr_reader :subscriptions
9
13
 
10
14
  class Subscription
11
- attr_reader :exchange, :routing_key
15
+
16
+ attr_reader :exchange
17
+ attr_reader :routing_key
12
18
 
13
19
  def initialize(exchange, routing_key)
14
20
  @exchange = exchange
@@ -36,6 +42,7 @@ module Deploy
36
42
  def subscribed!
37
43
  @subscribed = true
38
44
  end
45
+
39
46
  end
40
47
 
41
48
  def initialize
@@ -51,10 +58,10 @@ module Deploy
51
58
  catch(:finished) do
52
59
  EM.run do
53
60
  connection.onopen do
54
- logger.info "connected"
61
+ logger.info 'connected'
55
62
  end
56
63
 
57
- connection.onmessage do |msg, type|
64
+ connection.onmessage do |msg, _type|
58
65
  receive(msg)
59
66
  end
60
67
 
@@ -68,7 +75,7 @@ module Deploy
68
75
 
69
76
  private
70
77
 
71
- def dispatch(event, payload, mq = nil)
78
+ def dispatch(event, payload, rmq = nil)
72
79
  case event
73
80
  when 'Welcome'
74
81
  authenticate
@@ -79,7 +86,7 @@ module Deploy
79
86
  when 'Error', 'InternalError'
80
87
  websocket_error(payload)
81
88
  else
82
- subscription_event(event, payload, mq) if mq
89
+ subscription_event(event, payload, rmq) if rmq
83
90
  end
84
91
  end
85
92
 
@@ -96,17 +103,17 @@ module Deploy
96
103
  def successful_subscription(payload)
97
104
  key = subscription_key(payload['exchange'], payload['routing_key'])
98
105
  subscription = subscriptions[key]
99
- subscription.subscribed! if subscription
106
+ subscription&.subscribed!
100
107
  end
101
108
 
102
109
  def websocket_error(payload)
103
110
  raise Deploy::Errors::WebsocketError, payload['error']
104
111
  end
105
112
 
106
- def subscription_event(event, payload, mq)
107
- key = subscription_key(mq["e"], mq["rk"])
113
+ def subscription_event(event, payload, rmq)
114
+ key = subscription_key(rmq['e'], rmq['rk'])
108
115
  subscription = subscriptions[key]
109
- subscription.dispatch(event, payload) if subscription
116
+ subscription&.dispatch(event, payload)
110
117
  end
111
118
 
112
119
  def receive(msg)
@@ -131,7 +138,7 @@ module Deploy
131
138
  end
132
139
 
133
140
  def logger
134
- @logger ||= Logger.new(STDOUT)
141
+ @logger ||= Logger.new($stdout)
135
142
  @logger.level = Logger::ERROR
136
143
  @logger
137
144
  end
@@ -139,6 +146,8 @@ module Deploy
139
146
  def subscription_key(exchange, routing_key)
140
147
  [exchange, routing_key].join('-')
141
148
  end
149
+
142
150
  end
151
+
143
152
  end
144
153
  end
data/lib/deploy/cli.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'optparse'
2
4
  require 'highline/import'
3
5
 
@@ -5,43 +7,50 @@ require 'deploy'
5
7
  require 'deploy/cli/websocket_client'
6
8
  require 'deploy/cli/deployment_progress_output'
7
9
 
8
- HighLine.colorize_strings
10
+ OptionsStruct = Struct.new(:config_file, :project)
9
11
 
12
+ # rubocop:disable Metrics/ClassLength
13
+ # rubocop:disable Metrics/AbcSize
14
+ # rubocop:disable Metrics/CyclomaticComplexity
15
+ # rubocop:disable Metrics/MethodLength
16
+ # rubocop:disable Metrics/PerceivedComplexity
10
17
  module Deploy
11
18
  class CLI
19
+
12
20
  ## Constants for formatting output
13
- PROTOCOL_NAME = {:ssh => "SSH/SFTP", :ftp => "FTP", :s3 => "Amazon S3", :rackspace => "Rackspace CloudFiles"}
21
+ PROTOCOL_NAME = { ssh: 'SSH/SFTP', ftp: 'FTP', s3: 'Amazon S3', rackspace: 'Rackspace CloudFiles' }.freeze
14
22
 
15
23
  class << self
24
+
16
25
  def invoke(args)
17
- @options = OpenStruct.new
26
+ @options = OptionsStruct.new
18
27
 
19
28
  parser = OptionParser.new do |opts|
20
- opts.banner = "Usage: deployhq [options] command"
21
- opts.separator ""
22
- opts.separator "Commands:"
29
+ opts.banner = 'Usage: deployhq [options] command'
30
+ opts.separator ''
31
+ opts.separator 'Commands:'
23
32
  opts.separator "deploy\t\t Start a new deployment"
24
33
  opts.separator "servers\t\t List configured servers and server groups"
25
34
  opts.separator "configure\t\t Create a new configuration file for this tool"
26
- opts.separator ""
27
- opts.separator "Common Options:"
35
+ opts.separator ''
36
+ opts.separator 'Common Options:'
28
37
 
29
38
  @options.config_file = './Deployfile'
30
- opts.on("-c", "--config path", 'Configuration file path') do |config_file_path|
39
+ opts.on('-c', '--config path', 'Configuration file path') do |config_file_path|
31
40
  @options.config_file = config_file_path
32
41
  end
33
42
 
34
- opts.on("-p", "--project project",
35
- "Project to operate on (default is read from project: in config file)") do |project_permalink|
43
+ opts.on('-p', '--project project',
44
+ 'Project to operate on (default is read from project: in config file)') do |project_permalink|
36
45
  @options.project = project_permalink
37
46
  end
38
47
 
39
- opts.on_tail('-v', '--version', "Shows Version") do
48
+ opts.on_tail('-v', '--version', 'Shows Version') do
40
49
  puts Deploy::VERSION
41
50
  exit
42
51
  end
43
52
 
44
- opts.on_tail("-h", "--help", "Displays Help") do
53
+ opts.on_tail('-h', '--help', 'Displays Help') do
45
54
  puts opts
46
55
  exit
47
56
  end
@@ -51,7 +60,7 @@ module Deploy
51
60
  parser.parse!(args)
52
61
  command = args.pop
53
62
  rescue OptionParser::InvalidOption
54
- STDERR.puts parser.to_s
63
+ warn parser
55
64
  exit 1
56
65
  end
57
66
 
@@ -59,13 +68,13 @@ module Deploy
59
68
  begin
60
69
  Deploy.configuration_file = @options.config_file
61
70
  rescue Errno::ENOENT
62
- STDERR.puts "Couldn't find configuration file at #{@options.config_file.inspect}"
71
+ warn "Couldn't find configuration file at #{@options.config_file.inspect}"
63
72
  exit 1
64
73
  end
65
74
 
66
75
  project_permalink = @options.project || Deploy.configuration.project
67
76
  if project_permalink.nil?
68
- STDERR.puts "Project must be specified in config file or as --project argument"
77
+ warn 'Project must be specified in config file or as --project argument'
69
78
  exit 1
70
79
  end
71
80
 
@@ -80,25 +89,25 @@ module Deploy
80
89
  when 'configure'
81
90
  configure
82
91
  else
83
- STDERR.puts parser.to_s
92
+ warn parser
84
93
  end
85
94
  end
86
95
 
87
96
  def server_list
88
97
  @server_groups ||= @project.server_groups
89
- if @server_groups.count > 0
98
+ if @server_groups.count.positive?
90
99
  @server_groups.each do |group|
91
- puts "Group: #{group.name}".bold
92
- puts group.servers.map {|server| format_server(server) }.join("\n\n")
100
+ puts "Group: #{group.name}"
101
+ puts group.servers.map { |server| format_server(server) }.join("\n\n")
93
102
  end
94
103
  end
95
104
 
96
105
  @ungrouped_servers ||= @project.servers
97
- if @ungrouped_servers.count > 0
98
- puts "\n" if @server_groups.count > 0
99
- puts "Ungrouped Servers".bold
100
- puts @ungrouped_servers.map {|server| format_server(server) }.join("\n\n")
101
- end
106
+ return unless @ungrouped_servers.count.positive?
107
+
108
+ puts "\n" if @server_groups.count.positive?
109
+ puts 'Ungrouped Servers'
110
+ puts @ungrouped_servers.map { |server| format_server(server) }.join("\n\n")
102
111
  end
103
112
 
104
113
  def deploy
@@ -108,10 +117,10 @@ module Deploy
108
117
  parent = nil
109
118
  while parent.nil?
110
119
  parent = choose do |menu|
111
- menu.prompt = "Please choose a server or group to deploy to:"
120
+ menu.prompt = 'Please choose a server or group to deploy to:'
112
121
 
113
122
  menu.choices(*(@ungrouped_servers + @server_groups))
114
- menu.choice("List Server Details") do
123
+ menu.choice('List Server Details') do
115
124
  server_list
116
125
  nil
117
126
  end
@@ -121,21 +130,21 @@ module Deploy
121
130
  latest_revision = @project.latest_revision(parent.preferred_branch)
122
131
  deployment = @project.deploy(parent.identifier, parent.last_revision, latest_revision)
123
132
 
124
- STDOUT.print "Waiting for an available deployment slot..."
133
+ $stdout.print 'Waiting for an available deployment slot...'
125
134
  DeploymentProgressOutput.new(deployment).monitor
126
135
  end
127
136
 
128
137
  def configure
129
138
  configuration = {
130
- account: ask_config_question("Account Domain (e.g. https://atech.deployhq.com)",
131
- %r{\Ahttps?://[a-z0-9\.\-]+.deployhq.com\z}),
132
- username: ask_config_question("Username or e-mail address"),
133
- api_key: ask_config_question("API key (You can find this in Settings -> Security)"),
134
- project: ask_config_question("Default project to use (please use permalink from web URL)")
139
+ account: ask_config_question('Account Domain (e.g. https://atech.deployhq.com)',
140
+ /\Ahttps?:\/\/[a-z0-9.-]+.deployhq.com\z/),
141
+ username: ask_config_question('Username or e-mail address'),
142
+ api_key: ask_config_question('API key (You can find this in Settings -> Security)'),
143
+ project: ask_config_question('Default project to use (please use permalink from web URL)')
135
144
  }
136
145
 
137
146
  confirmation = true
138
- if File.exists?(@options.config_file)
147
+ if File.exist?(@options.config_file)
139
148
  confirmation = agree("File already exists at #{@options.config_file}. Overwrite? ")
140
149
  end
141
150
 
@@ -150,7 +159,7 @@ module Deploy
150
159
  question_text = "#{question_text}: "
151
160
  ask(question_text) do |q|
152
161
  q.whitespace = :remove
153
- q.responses[:not_valid] = "That answer is not valid"
162
+ q.responses[:not_valid] = 'That answer is not valid'
154
163
  q.responses[:ask_on_error] = :question
155
164
  q.validate = valid_format
156
165
  end
@@ -161,30 +170,38 @@ module Deploy
161
170
  ## Data formatters
162
171
  def format_server(server)
163
172
  server_params = {
164
- "Name" => server.name,
165
- "Type" => PROTOCOL_NAME[server.protocol_type.to_sym],
166
- "Path" => server.server_path,
167
- "Branch" => server.preferred_branch,
168
- "Current Revision" => server.last_revision,
173
+ 'Name' => server.name,
174
+ 'Type' => PROTOCOL_NAME[server.protocol_type.to_sym],
175
+ 'Path' => server.server_path,
176
+ 'Branch' => server.preferred_branch,
177
+ 'Current Revision' => server.last_revision
169
178
  }
170
- server_params["Hostname"] = [server.hostname, server.port].join(':') if server.hostname
171
- server_params["Bucket"] = server.bucket_name if server.bucket_name
172
- server_params["Region"] = server.region if server.region
173
- server_params["Container"] = server.container_name if server.container_name
179
+ server_params['Hostname'] = [server.hostname, server.port].join(':') if server.hostname
180
+ server_params['Bucket'] = server.bucket_name if server.bucket_name
181
+ server_params['Region'] = server.region if server.region
182
+ server_params['Container'] = server.container_name if server.container_name
174
183
 
175
- Array.new.tap do |a|
184
+ [].tap do |a|
176
185
  a << format_kv_pair(server_params)
177
186
  end.join("\n")
178
187
  end
179
188
 
189
+ # rubocop:disable Lint/FormatParameterMismatch
180
190
  def format_kv_pair(hash)
181
191
  longest_key = hash.keys.map(&:length).max + 2
182
- hash.each_with_index.map do |(k,v), i|
183
- str = sprintf("%#{longest_key}s : %s", k,v)
184
- i == 0 ? str.color(:bold) : str
192
+ hash.each_with_index.map do |(k, v), _i|
193
+ str = format("%#{longest_key}s : %s", k, v)
194
+ str
185
195
  end.join("\n")
186
196
  end
197
+ # rubocop:enable Lint/FormatParameterMismatch
187
198
 
188
199
  end
200
+
189
201
  end
190
202
  end
203
+ # rubocop:enable Metrics/ClassLength
204
+ # rubocop:enable Metrics/AbcSize
205
+ # rubocop:enable Metrics/CyclomaticComplexity
206
+ # rubocop:enable Metrics/MethodLength
207
+ # rubocop:enable Metrics/PerceivedComplexity
@@ -1,6 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Deploy
2
4
  class Configuration
3
- attr_accessor :account, :username, :api_key, :project
5
+
6
+ attr_accessor :account
7
+ attr_accessor :username
8
+ attr_accessor :api_key
9
+ attr_accessor :project
4
10
  attr_writer :websocket_hostname
5
11
 
6
12
  def websocket_hostname
@@ -11,7 +17,7 @@ module Deploy
11
17
  file_contents = File.read(path)
12
18
  parsed_contents = JSON.parse(file_contents)
13
19
 
14
- self.new.tap do |config|
20
+ new.tap do |config|
15
21
  config.account = parsed_contents['account']
16
22
  config.username = parsed_contents['username']
17
23
  config.api_key = parsed_contents['api_key']
@@ -19,5 +25,6 @@ module Deploy
19
25
  config.websocket_hostname = parsed_contents['websocket_hostname']
20
26
  end
21
27
  end
28
+
22
29
  end
23
30
  end
data/lib/deploy/errors.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Deploy
2
4
 
3
5
  ## Base level error which all other deploy errors will inherit from. It may also be
@@ -13,10 +15,12 @@ module Deploy
13
15
  ## Access was denied to the remote service
14
16
  class AccessDenied < Error; end
15
17
 
16
- ## A communication error occured while talking to the Deploy API
18
+ ## A communication error occurred while talking to the Deploy API
17
19
  class CommunicationError < Error; end
18
20
 
19
21
  # Raised from the websocket client when we receive an error event
20
22
  class WebsocketError < Error; end
23
+
21
24
  end
25
+
22
26
  end
@@ -1,7 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ # rubocop:disable Metrics/AbcSize
6
+ # rubocop:disable Metrics/CyclomaticComplexity
7
+ # rubocop:disable Metrics/MethodLength
1
8
  module Deploy
2
9
  class Request
3
10
 
4
- attr_reader :path, :method
11
+ attr_reader :path
12
+ attr_reader :method
5
13
  attr_accessor :data
6
14
 
7
15
  def initialize(path, method = :get)
@@ -23,30 +31,28 @@ module Deploy
23
31
  uri = URI.parse([Deploy.configuration.account, @path].join('/'))
24
32
  http_request = http_class.new(uri.request_uri)
25
33
  http_request.basic_auth(Deploy.configuration.username, Deploy.configuration.api_key)
26
- http_request["Accept"] = "application/json"
27
- http_request["Content-type"] = "application/json"
34
+ http_request['Accept'] = 'application/json'
35
+ http_request['Content-Type'] = 'application/json'
28
36
 
29
37
  http = Net::HTTP.new(uri.host, uri.port)
30
- if uri.scheme == 'https'
31
- http.use_ssl = true
32
- end
38
+ http.use_ssl = true if uri.scheme == 'https'
33
39
 
34
40
  data = self.data.to_json if self.data.is_a?(Hash) && self.data.respond_to?(:to_json)
35
41
  http_result = http.request(http_request, data)
36
42
  @output = http_result.body
37
- @success = case http_result
43
+ case http_result
38
44
  when Net::HTTPSuccess
39
- true
45
+ @success = true
40
46
  when Net::HTTPServiceUnavailable
41
- raise Deploy::Errors::ServiceUnavailable
47
+ @success = raise Deploy::Errors::ServiceUnavailable
42
48
  when Net::HTTPForbidden, Net::HTTPUnauthorized
43
- raise Deploy::Errors::AccessDenied, "Access Denied for '#{Deploy.configuration.username}'"
49
+ @success = raise Deploy::Errors::AccessDenied, "Access Denied for '#{Deploy.configuration.username}'"
44
50
  when Net::HTTPNotFound
45
- raise Deploy::Errors::CommunicationError, "Not Found at #{uri.to_s}"
51
+ @success = raise Deploy::Errors::CommunicationError, "Not Found at #{uri}"
46
52
  when Net::HTTPClientError
47
- false
53
+ @success = false
48
54
  else
49
- raise Deploy::Errors::CommunicationError, http_result.body
55
+ @success = raise Deploy::Errors::CommunicationError, http_result.body
50
56
  end
51
57
  self
52
58
  end
@@ -65,3 +71,6 @@ module Deploy
65
71
 
66
72
  end
67
73
  end
74
+ # rubocop:enable Metrics/AbcSize
75
+ # rubocop:enable Metrics/CyclomaticComplexity
76
+ # rubocop:enable Metrics/MethodLength
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Deploy
2
4
  class Resource
3
5
 
@@ -9,14 +11,18 @@ module Deploy
9
11
  def method_missing(method, *params)
10
12
  set = method.to_s.include?('=')
11
13
  key = method.to_s.sub('=', '')
12
- self.attributes = Hash.new unless self.attributes.is_a?(Hash)
14
+ self.attributes = ({}) unless attributes.is_a?(Hash)
13
15
  if set
14
- self.attributes[key] = params.first
16
+ attributes[key] = params.first
15
17
  else
16
- self.attributes[key]
18
+ attributes[key]
17
19
  end
18
20
  end
19
21
 
22
+ def respond_to_missing?(method_name, include_private = false)
23
+ method_name.to_s.start_with?('user_') || super
24
+ end
25
+
20
26
  class << self
21
27
 
22
28
  ## Find a record or set of records. Passing :all will return all records and passing an integer
@@ -30,11 +36,13 @@ module Deploy
30
36
 
31
37
  ## Find all objects and return an array of objects with the attributes set.
32
38
  def find_all(params)
33
- output = JSON.parse(Request.new(collection_path(params)).make.output)
34
- if output.is_a?(Hash) && output['records'] && output['pagination']
35
- output = output['records']
36
- end
39
+ request = Request.new(collection_path(params))
40
+ output = request.make.output
41
+ output = JSON.parse(output)
42
+
43
+ output = output['records'] if output.is_a?(Hash) && output['records'] && output['pagination']
37
44
  return [] unless output.is_a?(Array)
45
+
38
46
  output.map do |o|
39
47
  create_object(o, params)
40
48
  end
@@ -42,12 +50,13 @@ module Deploy
42
50
 
43
51
  ## Find a single object and return an object for it.
44
52
  def find_single(id, params = {})
45
- o = JSON.parse(Request.new(member_path(id, params)).make.output)
46
- if o.is_a?(Hash)
47
- create_object(o, params)
48
- else
49
- raise Deploy::Errors::NotFound, "Record not found"
50
- end
53
+ request = Request.new(member_path(id, params))
54
+ output = request.make.output
55
+ output = JSON.parse(output)
56
+
57
+ raise Deploy::Errors::NotFound, 'Record not found' unless output.is_a?(Hash)
58
+
59
+ create_object(output, params)
51
60
  end
52
61
 
53
62
  ## Post to the specified object on the collection path
@@ -58,18 +67,18 @@ module Deploy
58
67
  ## Return the collection path for this model. Very lazy pluralizion here
59
68
  ## at the moment, nothing in Deploy needs to be pluralized with anything
60
69
  ## other than just adding an 's'.
61
- def collection_path(params = {})
62
- class_name.downcase + 's'
70
+ def collection_path(_params = {})
71
+ "#{class_name.downcase}s"
63
72
  end
64
73
 
65
74
  ## Return the member path for the passed ID & attributes
66
- def member_path(id, params = {})
75
+ def member_path(id, _params = {})
67
76
  [collection_path, id].join('/')
68
77
  end
69
78
 
70
79
  ## Return the deploy class name
71
80
  def class_name
72
- self.name.to_s.split('::').last.downcase
81
+ name.to_s.split('::').last.downcase
73
82
  end
74
83
 
75
84
  private
@@ -77,20 +86,21 @@ module Deploy
77
86
  ## Create a new object with the specified attributes and getting and ID.
78
87
  ## Returns the newly created object
79
88
  def create_object(attributes, objects = [])
80
- o = self.new
89
+ o = new
81
90
  o.attributes = attributes
82
91
  o.id = attributes['id']
83
- for key, object in objects.select{|k,v| v.kind_of?(Deploy::Resource)}
92
+ objects.select { |_k, v| v.is_a?(Deploy::Resource) }.each do |key, object|
84
93
  o.attributes[key.to_s] = object
85
94
  end
86
95
  o
87
96
  end
97
+
88
98
  end
89
99
 
90
100
  ## Run a post on the member path. Returns the ouput from the post, false if a conflict or raises
91
101
  ## a Deploy::Error. Optionally, pass a second 'data' parameter to send data to the post action.
92
102
  def post(action, data = nil)
93
- path = self.class.member_path(self.id, default_params) + "/" + action.to_s
103
+ path = "#{self.class.member_path(id, default_params)}/#{action}"
94
104
  request = Request.new(path, :post)
95
105
  request.data = data
96
106
  request.make
@@ -99,20 +109,21 @@ module Deploy
99
109
  ## Delete this record from the remote service. Returns true or false depending on the success
100
110
  ## status of the destruction.
101
111
  def destroy
102
- Request.new(self.class.member_path(self.id, default_params), :delete).make.success?
112
+ Request.new(self.class.member_path(id, default_params), :delete).make.success?
103
113
  end
104
114
 
105
115
  def new_record?
106
- self.id.nil?
116
+ id.nil?
107
117
  end
108
118
 
109
119
  def save
110
120
  new_record? ? create : update
111
121
  end
112
122
 
123
+ # rubocop:disable Metrics/AbcSize
113
124
  def create
114
125
  request = Request.new(self.class.collection_path(default_params), :post)
115
- request.data = {self.class.class_name.downcase.to_sym => attributes_to_post}
126
+ request.data = { self.class.class_name.downcase.to_sym => attributes_to_post }
116
127
  if request.make && request.success?
117
128
  new_record = JSON.parse(request.output)
118
129
  self.attributes = new_record
@@ -123,13 +134,14 @@ module Deploy
123
134
  false
124
135
  end
125
136
  end
137
+ # rubocop:enable Metrics/AbcSize
126
138
 
127
139
  ## Push the updated attributes to the remote. Returns true if the record was saved successfully
128
140
  ## other false if not. If not saved successfully, the errors hash will be updated with an array
129
141
  ## of all errors with the submission.
130
142
  def update
131
- request = Request.new(self.class.member_path(self.id, default_params), :put)
132
- request.data = {self.class.class_name.downcase.to_sym => attributes_to_post}
143
+ request = Request.new(self.class.member_path(id, default_params), :put)
144
+ request.data = { self.class.class_name.downcase.to_sym => attributes_to_post }
133
145
  if request.make && request.success?
134
146
  true
135
147
  else
@@ -142,23 +154,21 @@ module Deploy
142
154
 
143
155
  ## Populate the errors hash from the given raw JSON output
144
156
  def populate_errors(json)
145
- self.errors = Hash.new
146
- JSON.parse(json).inject(self.errors) do |r, e|
157
+ self.errors = ({})
158
+ JSON.parse(json).each_with_object(errors) do |e, r|
147
159
  r[e.first] = e.last
148
- r
149
160
  end
150
161
  end
151
162
 
152
163
  ## An array of params which should always be sent with this instances requests
153
164
  def default_params
154
- Hash.new
165
+ {}
155
166
  end
156
167
 
157
168
  ## Attributes which can be passed for update & creation
158
169
  def attributes_to_post
159
- self.attributes.inject(Hash.new) do |r,(key,value)|
170
+ attributes.each_with_object({}) do |(key, value), r|
160
171
  r[key] = value if value.is_a?(String) || value.is_a?(Integer)
161
- r
162
172
  end
163
173
  end
164
174
 
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Deploy
2
4
  class Deployment < Resource
5
+
3
6
  class << self
7
+
4
8
  def collection_path(params = {})
5
9
  "projects/#{params[:project].permalink}/deployments"
6
10
  end
@@ -8,17 +12,16 @@ module Deploy
8
12
  def member_path(id, params = {})
9
13
  "projects/#{params[:project].permalink}/deployments/#{id}"
10
14
  end
15
+
11
16
  end
12
17
 
13
18
  def default_params
14
- {:project => self.project}
19
+ { project: project }
15
20
  end
16
21
 
17
22
  def project
18
- if self.attributes['project'].is_a?(Hash)
19
- self.attributes['project'] = Project.send(:create_object, self.attributes['project'])
20
- end
21
- self.attributes['project']
23
+ attributes['project'] = Project.send(:create_object, attributes['project']) if attributes['project'].is_a?(Hash)
24
+ attributes['project']
22
25
  end
23
26
 
24
27
  def servers
@@ -47,5 +50,6 @@ module Deploy
47
50
  []
48
51
  end
49
52
  end
53
+
50
54
  end
51
55
  end
@@ -1,12 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Deploy
2
4
  class DeploymentStep < Resource
5
+
3
6
  def default_params
4
- { deployment: self.deployment, project: self.deployment.project }
7
+ { deployment: deployment, project: deployment.project }
5
8
  end
6
9
 
7
10
  def logs(params = {})
8
11
  params = default_params.merge(step: self).merge(params)
9
12
  DeploymentStepLog.find(:all, params)
10
13
  end
14
+
11
15
  end
12
16
  end
@@ -1,7 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Deploy
2
4
  class DeploymentStepLog < Resource
5
+
3
6
  def self.collection_path(params = {})
4
- "projects/#{params[:project].permalink}/deployments/#{params[:deployment].identifier}/steps/#{params[:step].identifier}/logs"
7
+ permalink = params[:project].permalink
8
+ project_identifier = params[:project].identifier
9
+ step_identifier = params[:step].identifier
10
+
11
+ "projects/#{permalink}/deployments/#{project_identifier}/steps/#{step_identifier}/logs"
5
12
  end
13
+
6
14
  end
7
15
  end
@@ -1,31 +1,33 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Deploy
2
4
  class Project < Resource
3
5
 
4
6
  ## Return all deployments for this project
5
7
  def deployments
6
- Deployment.find(:all, :project => self)
8
+ Deployment.find(:all, project: self)
7
9
  end
8
10
 
9
11
  ## Return a deployment
10
12
  def deployment(identifier)
11
- Deployment.find(identifier, :project => self)
13
+ Deployment.find(identifier, project: self)
12
14
  end
13
15
 
14
16
  def latest_revision(branch = '')
15
17
  branch ||= 'master'
16
- req = Request.new(self.class.member_path(self.permalink) + "/repository/latest_revision?branch=#{branch}").make
18
+ req = Request.new(self.class.member_path(permalink) + "/repository/latest_revision?branch=#{branch}").make
17
19
  parsed = JSON.parse(req.output)
18
20
  parsed['ref']
19
21
  end
20
22
 
21
- ## Create a deployment in this project (and queue it to run)
23
+ # Create a deployment in this project (and queue it to run)
22
24
  def deploy(server, start_revision, end_revision)
23
25
  run_deployment(server, start_revision, end_revision) do |d|
24
26
  d.mode = 'queue'
25
27
  end
26
28
  end
27
29
 
28
- ##
30
+ # Create a deployment preview
29
31
  def preview(server, start_revision, end_revision)
30
32
  run_deployment(server, start_revision, end_revision) do |d|
31
33
  d.mode = 'preview'
@@ -34,11 +36,11 @@ module Deploy
34
36
 
35
37
  ## Return all servers for this project
36
38
  def servers
37
- Server.find(:all, :project => self)
39
+ Server.find(:all, project: self)
38
40
  end
39
41
 
40
42
  def server_groups
41
- ServerGroup.find(:all, :project => self)
43
+ ServerGroup.find(:all, project: self)
42
44
  end
43
45
 
44
46
  private
@@ -1,28 +1,32 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Deploy
2
4
  class Server < Resource
3
5
 
4
6
  class << self
7
+
5
8
  def collection_path(params = {})
6
9
  "projects/#{params[:project].permalink}/servers"
7
10
  end
8
11
 
9
- def member_path(id, params = {})
12
+ def member_path(_id, params = {})
10
13
  "projects/#{params[:project].permalink}/servers/#{identifier}"
11
14
  end
15
+
12
16
  end
13
17
 
14
18
  def default_params
15
- {:project => self.project}
19
+ { project: project }
16
20
  end
17
21
 
18
22
  def to_s
19
- Array.new.tap do |a|
20
- a << self.name
21
- a << "(branch: #{self.preferred_branch})" if self.preferred_branch
22
- if self.last_revision
23
- a << "(currently: #{self.last_revision})"
23
+ [].tap do |a|
24
+ a << name
25
+ a << "(branch: #{preferred_branch})" if preferred_branch
26
+ if last_revision
27
+ a << "(currently: #{last_revision})"
24
28
  else
25
- a << "(currently undeployed)"
29
+ a << '(currently undeployed)'
26
30
  end
27
31
  end.join(' ')
28
32
  end
@@ -1,32 +1,36 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Deploy
2
4
  class ServerGroup < Resource
3
5
 
4
6
  class << self
7
+
5
8
  def collection_path(params = {})
6
9
  "projects/#{params[:project].permalink}/server_groups"
7
10
  end
8
11
 
9
- def member_path(id, params = {})
12
+ def member_path(_id, params = {})
10
13
  "projects/#{params[:project].permalink}/server_groups/#{identifier}"
11
14
  end
15
+
12
16
  end
13
17
 
14
18
  def default_params
15
- {:project => self.project}
19
+ { project: project }
16
20
  end
17
21
 
18
22
  def servers
19
- @servers ||= self.attributes['servers'].map {|server_attr| Deploy::Server.send(:create_object, server_attr) }
23
+ @servers ||= attributes['servers'].map { |server_attr| Deploy::Server.send(:create_object, server_attr) }
20
24
  end
21
25
 
22
26
  def to_s
23
- Array.new.tap do |a|
24
- a << self.name
25
- a << "(branch: #{self.preferred_branch})" if self.preferred_branch
26
- if self.last_revision
27
- a << "(currently: #{self.last_revision})"
27
+ [].tap do |a|
28
+ a << name
29
+ a << "(branch: #{preferred_branch})" if preferred_branch
30
+ if last_revision
31
+ a << "(currently: #{last_revision})"
28
32
  else
29
- a << "(currently undeployed)"
33
+ a << '(currently undeployed)'
30
34
  end
31
35
  end.join(' ')
32
36
  end
@@ -1,3 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Deploy
2
- VERSION = "2.0.4".freeze
4
+
5
+ VERSION_FILE_ROOT = File.expand_path('../../VERSION', __dir__)
6
+ if File.file?(VERSION_FILE_ROOT)
7
+ VERSION = File.read(VERSION_FILE_ROOT).strip.sub(/\Av/, '')
8
+ else
9
+ VERSION = '0.0.0.dev'
10
+ end
11
+
3
12
  end
data/lib/deploy.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rubygems'
2
4
  require 'bundler'
3
5
 
@@ -25,7 +27,9 @@ require 'deploy/resources/server_group'
25
27
  require 'deploy/version'
26
28
 
27
29
  module Deploy
30
+
28
31
  class << self
32
+
29
33
  def configure
30
34
  @configuration ||= Configuration.new
31
35
  yield @configuration if block_given?
@@ -39,5 +43,7 @@ module Deploy
39
43
  def configuration_file=(file_location)
40
44
  @configuration = Configuration.from_file(file_location)
41
45
  end
46
+
42
47
  end
48
+
43
49
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deployhq
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 2.1.2
5
5
  platform: ruby
6
6
  authors:
7
- - Dan Wentworth
7
+ - Adam Cooke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-18 00:00:00.000000000 Z
11
+ date: 2023-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: json
14
+ name: highline
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.8'
19
+ version: '2.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.8'
26
+ version: '2.1'
27
27
  - !ruby/object:Gem::Dependency
28
- name: highline
28
+ name: json
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.0'
33
+ version: '2.6'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.0'
40
+ version: '2.6'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: websocket-eventmachine-client
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,10 +52,10 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.2'
55
- description: |2
56
- API and CLI client for the DeployHQ deployment platform. Provides the
57
- deployhq executable.
58
- email: dan@atech.io
55
+ description: API and CLI client for the DeployHQ deployment platform. Provides the
56
+ deployhq executable.
57
+ email:
58
+ - adam@k.io
59
59
  executables:
60
60
  - deployhq
61
61
  extensions: []
@@ -77,7 +77,7 @@ files:
77
77
  - lib/deploy/resources/server.rb
78
78
  - lib/deploy/resources/server_group.rb
79
79
  - lib/deploy/version.rb
80
- homepage: https://www.deployhq.com
80
+ homepage: https://github.com/krystal/deployhq-lib
81
81
  licenses:
82
82
  - MIT
83
83
  metadata: {}
@@ -89,14 +89,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
89
89
  requirements:
90
90
  - - ">="
91
91
  - !ruby/object:Gem::Version
92
- version: '0'
92
+ version: '2.7'
93
93
  required_rubygems_version: !ruby/object:Gem::Requirement
94
94
  requirements:
95
95
  - - ">="
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0'
98
98
  requirements: []
99
- rubygems_version: 3.0.3
99
+ rubygems_version: 3.3.26
100
100
  signing_key:
101
101
  specification_version: 4
102
102
  summary: API and CLI client for the DeployHQ