ops_team 0.10.4 → 0.12.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: 6f2b052b1a1dfd1e4cc30acca43495993be28499f2b1fa9eb8e587da57931d3a
4
- data.tar.gz: 27b21a20f77b1a0bf416f3d3a56be4142baa0b7553b3161e0b916da61b0f3422
3
+ metadata.gz: 684c6b13e7c5440f067ed372f28f592fc24616aaeb42284ec30465166bd1ce79
4
+ data.tar.gz: 67ba1850a8f28e7025bc3d179bdb33d6506dffa0c5a94b2aa50fce20e0c20dce
5
5
  SHA512:
6
- metadata.gz: 67f1395a225c91a2ee619ecd1eb6eb26e16ca05bafb5f82916508875a7b58c0eafe40be120f83ec2b55a42aa3695bcb91cf1b1ca5973c521029bd377f9c02c86
7
- data.tar.gz: cf644c0878ce56c6f11c6e45719044a72aa71a566bca492c5f51966436ef25010ec19dd6c5d8f5a0f4cd408177a114975f4e3160b27977bda3360db4ce456282
6
+ metadata.gz: 747a3dfac949e43f25f3ee19b31bb60d9824b25265b5c8d09c0af9f298a514b2fec0fd48cace35c4ebc553847ebd9bf9b6ea246433a5efb51b7c4918bbc39628
7
+ data.tar.gz: 32d665f336d2d31d7189b5bc9569155c00c4d27ba8b2260d282295c3e2664d0ead0729454996275a2d189f446a2afebc9ae6f9f66303d38245e511978ee58b88
@@ -32,6 +32,10 @@ class Action
32
32
  @config["description"]
33
33
  end
34
34
 
35
+ def skip_hooks?(name)
36
+ @config["skip_#{name}_hooks"]
37
+ end
38
+
35
39
  private
36
40
 
37
41
  def load_secrets?
@@ -1,13 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rubygems"
4
-
5
3
  require "output"
4
+ require "version"
6
5
 
7
6
  module Builtins
8
7
  class Version < Builtin
9
- GEMSPEC_FILE = "#{__dir__}/../../ops_team.gemspec"
10
-
11
8
  class << self
12
9
  def description
13
10
  "prints the version of ops that is running"
@@ -15,18 +12,7 @@ module Builtins
15
12
  end
16
13
 
17
14
  def run
18
- unless gemspec
19
- Output.error("Unable to load gemspec at '#{GEMSPEC_FILE}")
20
- return false
21
- end
22
-
23
- Output.out(gemspec.version)
24
- end
25
-
26
- private
27
-
28
- def gemspec
29
- @gemspec ||= Gem::Specification.load(GEMSPEC_FILE)
15
+ Output.out(::Version.version)
30
16
  end
31
17
  end
32
18
  end
@@ -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
@@ -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,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'output'
4
+
5
+ class HookHandler
6
+ class HookConfigError < StandardError; end
7
+ class HookExecError < StandardError; end
8
+
9
+ def initialize(config)
10
+ @config = config
11
+ end
12
+
13
+ def do_hooks(name)
14
+ raise HookConfigError, "'hooks.#{name}' must be a list" unless hooks(name).is_a?(Array)
15
+
16
+ execute_hooks(name)
17
+ end
18
+
19
+ private
20
+
21
+ def hooks(name)
22
+ @config.dig("hooks", name) || []
23
+ end
24
+
25
+ def execute_hooks(name)
26
+ hooks(name).each do |hook|
27
+ Output.notice("Running #{name} hook: #{hook}")
28
+ output, exit_code = Executor.execute(hook)
29
+
30
+ next if exit_code.zero?
31
+
32
+ raise HookExecError, "#{name} hook '#{hook}' failed with exit code #{exit_code}:\n#{output}"
33
+ end
34
+ end
35
+ end
data/lib/ops.rb CHANGED
@@ -3,11 +3,14 @@
3
3
 
4
4
  require 'yaml'
5
5
  require 'require_all'
6
+ require "rubygems"
6
7
 
8
+ require 'hook_handler'
7
9
  require 'action'
8
10
  require 'output'
9
11
  require 'options'
10
12
  require 'environment'
13
+ require 'version'
11
14
  require_rel "builtins"
12
15
 
13
16
  # executes commands based on local `ops.yml`
@@ -19,6 +22,7 @@ class Ops
19
22
  INVALID_SYNTAX_EXIT_CODE = 64
20
23
  UNKNOWN_ACTION_EXIT_CODE = 65
21
24
  ERROR_LOADING_APP_CONFIG_EXIT_CODE = 66
25
+ MIN_VERSION_NOT_MET_EXIT_CODE = 67
22
26
 
23
27
  class << self
24
28
  def project_name
@@ -34,7 +38,9 @@ class Ops
34
38
  end
35
39
 
36
40
  def run
41
+ # "return" is here to allow specs to stub "exit"
37
42
  return exit(INVALID_SYNTAX_EXIT_CODE) unless syntax_valid?
43
+ return exit(MIN_VERSION_NOT_MET_EXIT_CODE) unless min_version_met?
38
44
 
39
45
  run_action
40
46
  rescue UnknownActionError => e
@@ -53,12 +59,28 @@ class Ops
53
59
  end
54
60
  end
55
61
 
62
+ def min_version_met?
63
+ return true unless min_version
64
+
65
+ if Version.min_version_met?(min_version)
66
+ true
67
+ else
68
+ Output.error("ops.yml specifies minimum version of #{min_version}, but ops version is #{Version.version}")
69
+ false
70
+ end
71
+ end
72
+
73
+ def min_version
74
+ config["min_version"]
75
+ end
76
+
56
77
  def run_action
57
- environment.set_variables
58
- AppConfig.load
78
+ do_before_all
59
79
 
60
80
  return builtin.run if builtin
61
81
 
82
+ do_before_action
83
+
62
84
  Output.notice("Running '#{action}' from #{CONFIG_FILE} in environment '#{ENV['environment']}'...")
63
85
  action.run
64
86
  rescue AppConfig::ParsingError => e
@@ -66,6 +88,22 @@ class Ops
66
88
  exit(ERROR_LOADING_APP_CONFIG_EXIT_CODE)
67
89
  end
68
90
 
91
+ def do_before_all
92
+ environment.set_variables
93
+ AppConfig.load
94
+ end
95
+
96
+ def do_before_action
97
+ hook_handler.do_hooks("before") unless ENV["OPS_RUNNING"] || action.skip_hooks?("before")
98
+
99
+ # this prevents before hooks from running in ops executed by ops
100
+ ENV["OPS_RUNNING"] = "1"
101
+ end
102
+
103
+ def hook_handler
104
+ @hook_handler ||= HookHandler.new(config)
105
+ end
106
+
69
107
  def builtin
70
108
  @builtin ||= Builtin.class_for(name: @action_name).new(@args, config)
71
109
  rescue NameError
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubygems"
4
+
5
+ class Version
6
+ GEMSPEC_FILE = "#{__dir__}/../ops_team.gemspec"
7
+
8
+ class << self
9
+ # these class methods exist because I don't want to have to call `Version.new.version` elsewhere
10
+ def version
11
+ new.send(:version)
12
+ end
13
+
14
+ def min_version_met?(min_version)
15
+ new.send(:min_version_met?, min_version)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ # these instance methods exist so that I don't have to clear class variables between tests
22
+ def version
23
+ unless gemspec
24
+ Output.error("Unable to load gemspec at '#{GEMSPEC_FILE}")
25
+ return nil
26
+ end
27
+
28
+ gemspec.version
29
+ end
30
+
31
+ def min_version_met?(min_version)
32
+ Gem::Version.new(version) >= Gem::Version.new(min_version)
33
+ end
34
+
35
+ def gemspec
36
+ @gemspec ||= Gem::Specification.load(GEMSPEC_FILE)
37
+ end
38
+ 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.4'
5
+ s.version = '0.12.2'
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.4
4
+ version: 0.12.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - nickthecook@gmail.com
@@ -170,10 +170,13 @@ 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
176
178
  - lib/secrets.rb
179
+ - lib/version.rb
177
180
  - loader.rb
178
181
  - ops_team.gemspec
179
182
  homepage: https://github.com/nickthecook/ops