ops_team 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ops.rb +34 -104
  3. data/lib/runner.rb +94 -0
  4. data/ops_team.gemspec +1 -1
  5. metadata +2 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e74fe375694383d5cf99385e04c314e804a2ab1aae6b03558b811e78874c65e
4
- data.tar.gz: 4c9f31d818c8bc456c4c9c37d40d42491dde28ef6e038eee77ff0e7c42e7a6da
3
+ metadata.gz: bf2a309a88bc396994795bca23a308043e8e8ec6c16a5e7b85baf0b66e15ed83
4
+ data.tar.gz: 526857c4d776fddf9d20d96c81cf4ab6905a364601d32fb5989467439f366aea
5
5
  SHA512:
6
- metadata.gz: 87320ca1362f2691ad4808bca8b7733b2d1be4bc70b4ca06b650267bf5c50c7d69e64a554fc91d246c821e17454794ae0aadb9cca27ea747f7092f5f636a6492
7
- data.tar.gz: 6b6bee1687f1858a1097931e336ddcf28fe4f50a9b8802cded747a034f4fefddbcab0fd4331bd961a269811384eb574bfca4e4cc69c5cca576a709bcb2cb59e0
6
+ metadata.gz: 815571122a732fcc85046f386ae9918c961033dc1c6141ad8d32334b2beb09ee9775b83640dad88d100d67a463468667a9dd9bbc5875e2b8612dc64fcc0d53e0
7
+ data.tar.gz: 6c4146afc51d45f1f80f91c57093750160589d0d6bf89cd6df2c2f79f6d58e30525edee2a122e3b0059d7bfd2a2f0f2a1b0e3f4ceefe4f1373ad0c1892fead77
data/lib/ops.rb CHANGED
@@ -5,23 +5,15 @@ require 'yaml'
5
5
  require 'require_all'
6
6
  require "rubygems"
7
7
 
8
- require 'hook_handler'
9
- require 'action'
10
8
  require 'output'
11
9
  require 'options'
12
- require 'environment'
13
10
  require 'version'
14
- require 'action_list'
15
- require 'action_suggester'
16
- require 'forwards'
11
+ require 'runner'
17
12
 
18
13
  require_rel "builtins"
19
14
 
20
15
  # executes commands based on local `ops.yml`
21
16
  class Ops
22
- class UnknownActionError < StandardError; end
23
- class ActionConfigError < StandardError; end
24
-
25
17
  CONFIG_FILE = "ops.yml"
26
18
 
27
19
  INVALID_SYNTAX_EXIT_CODE = 64
@@ -47,43 +39,47 @@ class Ops
47
39
  Options.set(config["options"] || {})
48
40
  end
49
41
 
42
+ # rubocop:disable Metrics/MethodLength
43
+ # better to have all the rescues in one place
50
44
  def run
51
45
  # "return" is here to allow specs to stub "exit" without executing everything after it
52
46
  return exit(INVALID_SYNTAX_EXIT_CODE) unless syntax_valid?
53
47
  return exit(MIN_VERSION_NOT_MET_EXIT_CODE) unless min_version_met?
54
48
 
55
- run_action
56
- rescue UnknownActionError => e
49
+ runner.run
50
+ rescue Runner::UnknownActionError => e
57
51
  Output.error(e.to_s)
58
52
  Output.out(RECOMMEND_HELP_TEXT) unless print_did_you_mean
59
53
  exit(UNKNOWN_ACTION_EXIT_CODE)
60
- rescue ActionConfigError => e
54
+ rescue Runner::ActionConfigError => e
61
55
  Output.error("Error(s) running action '#{@action_name}': #{e}")
62
56
  exit(ACTION_CONFIG_ERROR_EXIT_CODE)
57
+ rescue Builtin::ArgumentError => e
58
+ Output.error("Error running builtin '#{@action_name}': #{e}")
59
+ exit(BUILTIN_SYNTAX_ERROR_EXIT_CODE)
60
+ rescue AppConfig::ParsingError => e
61
+ Output.error("Error parsing app config: #{e}")
62
+ exit(ERROR_LOADING_APP_CONFIG_EXIT_CODE)
63
+ rescue Action::NotAllowedInEnvError => e
64
+ Output.error("Error running action #{@action_name}: #{e}")
65
+ exit(ACTION_NOT_ALLOWED_IN_ENV_EXIT_CODE)
63
66
  end
67
+ # rubocop:enable Metrics/MethodLength
64
68
 
65
69
  private
66
70
 
67
71
  def syntax_valid?
68
- if @action_name.nil?
69
- Output.error("Usage: ops <action>")
70
- Output.out(RECOMMEND_HELP_TEXT)
71
- false
72
- else
73
- true
74
- end
72
+ return true unless @action_name.nil?
73
+
74
+ Output.error("Usage: ops <action>")
75
+ Output.out(RECOMMEND_HELP_TEXT)
76
+ false
75
77
  end
76
78
 
77
79
  def print_did_you_mean
78
- suggestions = did_you_mean.check(@action_name)
79
-
80
- Output.out("Did you mean '#{suggestions.join(", ")}'?") if suggestions.any?
80
+ Output.out("Did you mean '#{runner.suggestions.join(", ")}'?") if runner.suggestions.any?
81
81
 
82
- suggestions.any?
83
- end
84
-
85
- def did_you_mean
86
- ActionSuggester.new(action_list.names + action_list.aliases + builtin_names)
82
+ runner.suggestions.any?
87
83
  end
88
84
 
89
85
  def min_version_met?
@@ -101,96 +97,30 @@ class Ops
101
97
  config["min_version"]
102
98
  end
103
99
 
104
- def run_action
105
- return forward.run if forward
106
-
107
- do_before_all
108
-
109
- return builtin.run if builtin
110
-
111
- raise UnknownActionError, "Unknown action: #{@action_name}" unless action
112
- raise ActionConfigError, action.config_errors.join("; ") unless action.config_valid?
113
-
114
- do_before_action
115
- Output.notice("Running '#{action}' from #{CONFIG_FILE} in environment '#{ENV['environment']}'...")
116
- action.run
117
- rescue Builtin::ArgumentError => e
118
- Output.error("Error running builtin '#{@action_name}': #{e}")
119
- exit(BUILTIN_SYNTAX_ERROR_EXIT_CODE)
120
- rescue AppConfig::ParsingError => e
121
- Output.error("Error parsing app config: #{e}")
122
- exit(ERROR_LOADING_APP_CONFIG_EXIT_CODE)
123
- rescue Action::NotAllowedInEnvError => e
124
- Output.error("Error running action #{@action_name}: #{e}")
125
- exit(ACTION_NOT_ALLOWED_IN_ENV_EXIT_CODE)
126
- end
127
-
128
- def do_before_all
129
- AppConfig.load
130
- Secrets.load if action && action.load_secrets?
131
- environment.set_variables
132
- end
133
-
134
- def do_before_action
135
- return if ENV["OPS_RUNNING"] || action.skip_hooks?("before")
136
-
137
- # this prevents before hooks from running in ops executed by ops
138
- ENV["OPS_RUNNING"] = "1"
139
- hook_handler.do_hooks("before")
140
- end
141
-
142
- def hook_handler
143
- @hook_handler ||= HookHandler.new(config)
144
- end
145
-
146
- def builtin
147
- @builtin ||= Builtin.class_for(name: @action_name).new(@args, config)
148
- rescue NameError
149
- # this means there isn't a builtin with that name in that module
150
- nil
151
- end
152
-
153
- def builtin_names
154
- Builtins.constants.select { |c| Builtins.const_get(c).is_a? Class }.map(&:downcase)
155
- end
156
-
157
- def forward
158
- @forward ||= Forwards.new(@config, @args).get(@action_name)
159
- end
160
-
161
- def action
162
- return action_list.get(@action_name) if action_list.get(@action_name)
163
- return action_list.get_by_alias(@action_name) if action_list.get_by_alias(@action_name)
164
- end
165
-
166
- def action_list
167
- @action_list ||= begin
168
- Output.warn("'ops.yml' has no 'actions' defined.") if config.any? && config["actions"].nil?
169
-
170
- ActionList.new(config["actions"], @args)
171
- end
100
+ def runner
101
+ @runner ||= Runner.new(@action_name, @args, config)
172
102
  end
173
103
 
174
104
  def config
175
105
  @config ||= begin
176
- if File.exist?(CONFIG_FILE)
177
- YAML.load_file(CONFIG_FILE)
106
+ if config_file_exists?
107
+ parsed_config_contents
178
108
  else
179
109
  Output.warn("File '#{CONFIG_FILE}' does not exist.") unless @action_name == "init"
180
110
  {}
181
111
  end
182
- rescue StandardError => e
183
- Output.warn("Error parsing '#{CONFIG_FILE}': #{e}")
184
- {}
185
112
  end
186
113
  end
187
114
 
188
- def env_vars
189
- config.dig("options", "environment") || {}
115
+ def parsed_config_contents
116
+ YAML.load_file(CONFIG_FILE)
117
+ rescue StandardError => e
118
+ Output.warn("Error parsing '#{CONFIG_FILE}': #{e}")
119
+ {}
190
120
  end
191
121
 
192
- def environment
193
- @environment ||= Environment.new(env_vars)
122
+ def config_file_exists?
123
+ File.exist?(CONFIG_FILE)
194
124
  end
195
125
  end
196
126
 
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'hook_handler'
4
+ require 'action'
5
+ require 'action_list'
6
+ require 'action_suggester'
7
+ require 'forwards'
8
+ require 'environment'
9
+
10
+ class Runner
11
+ class UnknownActionError < StandardError; end
12
+ class ActionConfigError < StandardError; end
13
+
14
+ def initialize(action_name, args, config)
15
+ @action_name = action_name
16
+ @args = args
17
+ @config = config
18
+ end
19
+
20
+ def run
21
+ return forward.run if forward
22
+
23
+ do_before_all
24
+
25
+ return builtin.run if builtin
26
+
27
+ raise UnknownActionError, "Unknown action: #{@action_name}" unless action
28
+ raise ActionConfigError, action.config_errors.join("; ") unless action.config_valid?
29
+
30
+ do_before_action
31
+ Output.notice("Running '#{action}' in environment '#{ENV['environment']}'...")
32
+ action.run
33
+ end
34
+
35
+ def suggestions
36
+ @suggestions ||= ActionSuggester.new(action_list.names + action_list.aliases + builtin_names).check(@action_name)
37
+ end
38
+
39
+ private
40
+
41
+ def do_before_all
42
+ AppConfig.load
43
+ Secrets.load if action&.load_secrets?
44
+ environment.set_variables
45
+ end
46
+
47
+ def do_before_action
48
+ return if ENV["OPS_RUNNING"] || action.skip_hooks?("before")
49
+
50
+ # this prevents before hooks from running in ops executed by ops
51
+ ENV["OPS_RUNNING"] = "1"
52
+ hook_handler.do_hooks("before")
53
+ end
54
+
55
+ def hook_handler
56
+ @hook_handler ||= HookHandler.new(@config)
57
+ end
58
+
59
+ def builtin
60
+ @builtin ||= Builtin.class_for(name: @action_name).new(@args, @config)
61
+ rescue NameError
62
+ # this means there isn't a builtin with that name in that module
63
+ nil
64
+ end
65
+
66
+ def builtin_names
67
+ Builtins.constants.select { |c| Builtins.const_get(c).is_a? Class }.map(&:downcase)
68
+ end
69
+
70
+ def forward
71
+ @forward ||= Forwards.new(@config, @args).get(@action_name)
72
+ end
73
+
74
+ def action
75
+ return action_list.get(@action_name) if action_list.get(@action_name)
76
+ return action_list.get_by_alias(@action_name) if action_list.get_by_alias(@action_name)
77
+ end
78
+
79
+ def action_list
80
+ @action_list ||= begin
81
+ Output.warn("'ops.yml' has no 'actions' defined.") if @config.any? && @config["actions"].nil?
82
+
83
+ ActionList.new(@config["actions"], @args)
84
+ end
85
+ end
86
+
87
+ def env_vars
88
+ @config.dig("options", "environment") || {}
89
+ end
90
+
91
+ def environment
92
+ @environment ||= Environment.new(env_vars)
93
+ end
94
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'ops_team'
5
- s.version = '1.0.0'
5
+ s.version = '1.0.1'
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: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - nickthecook@gmail.com
@@ -181,6 +181,7 @@ files:
181
181
  - lib/ops.rb
182
182
  - lib/options.rb
183
183
  - lib/output.rb
184
+ - lib/runner.rb
184
185
  - lib/secrets.rb
185
186
  - lib/version.rb
186
187
  - loader.rb