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