deployhq 2.0.3 → 2.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 806781a3e039b0c27a95bb0128b8ac1a5a8bcade
4
- data.tar.gz: fcc05ab94ec7adcc1ced3005acec05686844b307
2
+ SHA256:
3
+ metadata.gz: 7822d0dc6c5d8d2ba5b4dc65e955badf2e80fb3634897c5671155035ba6dbbe3
4
+ data.tar.gz: 17493bebc4b52686ce52bbbec87736084746eb97392fa7942913f31b508b1e5d
5
5
  SHA512:
6
- metadata.gz: 90dda81926d93cf8eea3b8fd4367c9c81b4aa41615a37562e313881e92453276f8074403c408003312de930c350dade1d40579f4c80ff957af44018c4699aacb
7
- data.tar.gz: 60d447c667e83d23dac4c8ac1a2096dff581d0d8d5648e2b781f6498ca4bb00a8b1a754dde324bcb33975736e3de411104cd8bea64eb142e57d8a3212c47c20c
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)|
160
- r[key] = value if value.is_a?(String) || value.is_a?(Integer) || value.is_a?(Fixnum)
161
- r
170
+ attributes.each_with_object({}) do |(key, value), r|
171
+ r[key] = value if value.is_a?(String) || value.is_a?(Integer)
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.3".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.3
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-17 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: '1.7'
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: '1.7'
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,15 +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
- rubyforge_project:
100
- rubygems_version: 2.6.14.3
99
+ rubygems_version: 3.3.26
101
100
  signing_key:
102
101
  specification_version: 4
103
102
  summary: API and CLI client for the DeployHQ