ops_team 0.10.1 → 0.11.0.pre2

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: 802441d64eb1dc1403011f6b912898ba1caebcfada19bb1241928ad879c1f086
4
- data.tar.gz: 47fa8c46b9114dfe577dcf8a9f43525abaf01ad76c809ffb239449400a866202
3
+ metadata.gz: 0a5f98b47649c277f4c0b29228d9d9ced79c985301bde206ec9a9a1cdad1990c
4
+ data.tar.gz: 6a5f36ef9a54b6a31dc745922888996f2420959a1a414f95318e6374fa162cc0
5
5
  SHA512:
6
- metadata.gz: f107e6877affa1afc72481239e9e3d7e3a7e6e8b4722ee2e8e5f21af789e200ab271ef974904ced2e0e06931485c62ceeb67c5b3435efc376e8229e2d61535c0
7
- data.tar.gz: 06e406cdbde8295490977e552bd7cef0f2a53652a1d818d6892ec68c749d4788d2079a9916c1bf6619a583b3bc500bb0f7cf28a3773bf3f3ce702e5b9a23378e
6
+ metadata.gz: a0869b884b7c8bda06c1ae664c3a056610776326ca7a0f87adfa64c9f45f4d4deb53d5e64000ffcdd0528865153da7b0a4155a92d20c4939cd38a8224ac3aa7f
7
+ data.tar.gz: 444234f4870cc90c6d56233763a69973de5f6f78c92eada37324bb5da354d09ae4493a49b04f15bf09f5d471f4669595f558e9de52e7f75ee287f9b1a05964fd
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class AppConfig
4
+ class ParsingError < StandardError; end
5
+
4
6
  class << self
5
7
  def load
6
8
  new(app_config_path).load
@@ -36,8 +38,7 @@ class AppConfig
36
38
  def config
37
39
  @config ||= file_contents ? YAML.safe_load(file_contents) : {}
38
40
  rescue YAML::SyntaxError => e
39
- Output.error("Error parsing config data: #{e}")
40
- {}
41
+ raise ParsingError, "Error parsing config data: #{e}"
41
42
  end
42
43
 
43
44
  def file_contents
@@ -32,12 +32,18 @@ module Builtins
32
32
 
33
33
  private
34
34
 
35
- def template_name_arg
35
+ def template_name
36
36
  @args[0]
37
37
  end
38
38
 
39
39
  def template_path
40
- format(OPS_YML_TEMPLATE, template_name: template_name_arg || DEFAULT_TEMPLATE_NAME)
40
+ return template_name if template_name && File.exist?(template_name)
41
+
42
+ builtin_template_path
43
+ end
44
+
45
+ def builtin_template_path
46
+ format(OPS_YML_TEMPLATE, template_name: template_name || DEFAULT_TEMPLATE_NAME)
41
47
  end
42
48
 
43
49
  def template_name_list
@@ -4,11 +4,12 @@ require 'open3'
4
4
  require 'English'
5
5
 
6
6
  require 'output'
7
+ require 'executor'
7
8
 
8
9
  class Dependency
9
10
  DESCRIPTION_TYPE_WIDTH = 8
10
11
 
11
- attr_reader :name, :output, :exit_code
12
+ attr_reader :name
12
13
 
13
14
  def initialize(name)
14
15
  @name = name
@@ -45,15 +46,23 @@ class Dependency
45
46
  end
46
47
 
47
48
  def success?
48
- @exit_code.nil? ? true : @exit_code.zero?
49
+ @executor.nil? ? true : @executor.success?
50
+ end
51
+
52
+ def output
53
+ @executor&.output
54
+ end
55
+
56
+ def exit_code
57
+ @executor&.exit_code
49
58
  end
50
59
 
51
60
  private
52
61
 
53
62
  def execute(cmd)
54
- @output, status = Open3.capture2e(cmd)
55
- @exit_code = status.exitstatus
63
+ @executor = Executor.new(cmd)
64
+ @executor.execute
56
65
 
57
- success?
66
+ @executor.success?
58
67
  end
59
68
  end
@@ -6,6 +6,7 @@ class Environment
6
6
  end
7
7
 
8
8
  def set_variables
9
+ set_ops_variables
9
10
  set_environment_aliases
10
11
  set_configured_variables
11
12
  end
@@ -18,6 +19,10 @@ class Environment
18
19
 
19
20
  private
20
21
 
22
+ def set_ops_variables
23
+ ENV["OPS_YML_DIR"] = Dir.pwd
24
+ end
25
+
21
26
  def set_environment_aliases
22
27
  environment_aliases.each do |alias_name|
23
28
  ENV[alias_name] = environment
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Executor
4
+ attr_reader :output, :exit_code
5
+
6
+ class << self
7
+ def execute(command)
8
+ @output, status = Open3.capture2e(command)
9
+ @exit_code = status.exitstatus
10
+
11
+ [@output, @exit_code]
12
+ end
13
+ end
14
+
15
+ def initialize(command)
16
+ @command = command
17
+ end
18
+
19
+ def execute
20
+ @output, status = Open3.capture2e(@command)
21
+ @exit_code = status.exitstatus
22
+
23
+ success?
24
+ end
25
+
26
+ def success?
27
+ @exit_code.nil? ? true : @exit_code.zero?
28
+ end
29
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ class HookHandler
4
+ class HookConfigError < StandardError; end
5
+ class HookExecError < StandardError; end
6
+
7
+ def initialize(config)
8
+ @config = config
9
+ end
10
+
11
+ def do_hooks(name)
12
+ raise HookConfigError, "'hooks.#{name}' must be a list" unless hooks(name).is_a?(Array)
13
+
14
+ execute_hooks(name)
15
+ end
16
+
17
+ private
18
+
19
+ def hooks(name)
20
+ @config.dig("hooks", name) || []
21
+ end
22
+
23
+ def execute_hooks(name)
24
+ hooks(name).each do |hook|
25
+ output, exit_code = Executor.execute(hook)
26
+
27
+ next if exit_code.zero?
28
+
29
+ raise HookExecError, "#{name} hook '#{hook}' failed with exit code #{exit_code}:\n#{output}"
30
+ end
31
+ end
32
+ end
data/lib/ops.rb CHANGED
@@ -4,6 +4,7 @@
4
4
  require 'yaml'
5
5
  require 'require_all'
6
6
 
7
+ require 'hook_handler'
7
8
  require 'action'
8
9
  require 'output'
9
10
  require 'options'
@@ -18,6 +19,7 @@ class Ops
18
19
 
19
20
  INVALID_SYNTAX_EXIT_CODE = 64
20
21
  UNKNOWN_ACTION_EXIT_CODE = 65
22
+ ERROR_LOADING_APP_CONFIG_EXIT_CODE = 66
21
23
 
22
24
  class << self
23
25
  def project_name
@@ -53,13 +55,25 @@ class Ops
53
55
  end
54
56
 
55
57
  def run_action
56
- environment.set_variables
57
- AppConfig.load
58
+ do_before_run_action
58
59
 
59
60
  return builtin.run if builtin
60
61
 
61
62
  Output.notice("Running '#{action}' from #{CONFIG_FILE} in environment '#{ENV['environment']}'...")
62
63
  action.run
64
+ rescue AppConfig::ParsingError => e
65
+ Output.error("Error parsing app config: #{e}")
66
+ exit(ERROR_LOADING_APP_CONFIG_EXIT_CODE)
67
+ end
68
+
69
+ def do_before_run_action
70
+ environment.set_variables
71
+ AppConfig.load
72
+ hook_handler.do_hooks("before")
73
+ end
74
+
75
+ def hook_handler
76
+ @hook_handler ||= HookHandler.new(config)
63
77
  end
64
78
 
65
79
  def builtin
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
+ require 'open3'
4
5
 
5
6
  require 'output'
6
7
  require 'app_config'
@@ -38,6 +39,19 @@ class Secrets < AppConfig
38
39
  end
39
40
 
40
41
  def file_contents
41
- @file_contents ||= @filename.match(/\.ejson$/) ? `ejson decrypt #{@filename}` : super
42
+ @file_contents ||= begin
43
+ @filename.match(/\.ejson$/) ? ejson_contents : super
44
+ end
45
+ end
46
+
47
+ def ejson_contents
48
+ @ejson_contents ||= begin
49
+ out, err, _status = Open3.capture3("ejson decrypt #{@filename}")
50
+
51
+ # TODO: err is only nil in testing, but I can't figure out why the stubbing isn't working
52
+ raise ParsingError, "Error decrypting EJSON file: #{err}" unless err.nil? || err.empty?
53
+
54
+ out
55
+ end
42
56
  end
43
57
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'ops_team'
5
- s.version = '0.10.1'
5
+ s.version = '0.11.0.pre2'
6
6
  s.authors = [
7
7
  'nickthecook@gmail.com'
8
8
  ]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ops_team
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 0.11.0.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - nickthecook@gmail.com
@@ -170,6 +170,8 @@ files:
170
170
  - lib/dependencies/sshkey.rb
171
171
  - lib/dependency.rb
172
172
  - lib/environment.rb
173
+ - lib/executor.rb
174
+ - lib/hook_handler.rb
173
175
  - lib/ops.rb
174
176
  - lib/options.rb
175
177
  - lib/output.rb
@@ -191,9 +193,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
191
193
  version: '2.5'
192
194
  required_rubygems_version: !ruby/object:Gem::Requirement
193
195
  requirements:
194
- - - ">="
196
+ - - ">"
195
197
  - !ruby/object:Gem::Version
196
- version: '0'
198
+ version: 1.3.1
197
199
  requirements: []
198
200
  rubygems_version: 3.0.3
199
201
  signing_key: