ops_team 1.0.0 → 1.0.1
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 +4 -4
- data/lib/ops.rb +34 -104
- data/lib/runner.rb +94 -0
- data/ops_team.gemspec +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf2a309a88bc396994795bca23a308043e8e8ec6c16a5e7b85baf0b66e15ed83
|
4
|
+
data.tar.gz: 526857c4d776fddf9d20d96c81cf4ab6905a364601d32fb5989467439f366aea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 '
|
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
|
-
|
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
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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
|
-
|
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
|
105
|
-
|
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
|
177
|
-
|
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
|
189
|
-
|
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
|
193
|
-
|
122
|
+
def config_file_exists?
|
123
|
+
File.exist?(CONFIG_FILE)
|
194
124
|
end
|
195
125
|
end
|
196
126
|
|
data/lib/runner.rb
ADDED
@@ -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
|
data/ops_team.gemspec
CHANGED
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.
|
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
|