ops_team 0.10.3 → 0.12.0

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: a78e3661dac6cc0796d00dc840eeb9fedbbc7f358bf3c6af4609d37175e8d53e
4
- data.tar.gz: f919b18cdcec154a9dac78020c20f229771b3bd870baf86ef020002c74394acc
3
+ metadata.gz: f4fd4661f8ea9e234bed8f61e205e625a232d301786557ce3c645519885c068a
4
+ data.tar.gz: af58d1ede9274d7a1aa884f036bc2dc6b93f7deff66307484bbcaae30806eea9
5
5
  SHA512:
6
- metadata.gz: 54d21b402bce3e50963b679be2393a7cf1cd993fa51c2c73481c348c4fa019748d5511a4654d9c94c175a985bb7545580cf000594fd2a7c05c7a43d849895cdd
7
- data.tar.gz: 64ef22c5c1a2264b3734166fef0b0752c2cc3ae18003ee376d1a86e0cba97d49fdb1c3de74606e0eb0aef050899d8e20c306165190d5cefc78dc030abe26997c
6
+ metadata.gz: bc505145b87e405a8a714196966ed2652bfd341fa8deec285c12ad6aa5fb07e01eb4797b888bc7ea5b253d90987b335e4fb6d45a5650af09b23fc74bac3086ed
7
+ data.tar.gz: 1227db2ce9be14ba4ee5bb1be55750fa6acbe92678a847b9d88a4e19bae6e465909bfa268b1700a73142946f4e0b751a69834630f8e6571860a6b8900403a8da
@@ -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
@@ -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,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
@@ -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,9 +59,23 @@ 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_run_action
59
79
 
60
80
  return builtin.run if builtin
61
81
 
@@ -66,6 +86,16 @@ class Ops
66
86
  exit(ERROR_LOADING_APP_CONFIG_EXIT_CODE)
67
87
  end
68
88
 
89
+ def do_before_run_action
90
+ environment.set_variables
91
+ AppConfig.load
92
+ hook_handler.do_hooks("before")
93
+ end
94
+
95
+ def hook_handler
96
+ @hook_handler ||= HookHandler.new(config)
97
+ end
98
+
69
99
  def builtin
70
100
  @builtin ||= Builtin.class_for(name: @action_name).new(@args, config)
71
101
  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.3'
5
+ s.version = '0.12.0'
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.3
4
+ version: 0.12.0
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