ops_team 0.12.2 → 0.13.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 684c6b13e7c5440f067ed372f28f592fc24616aaeb42284ec30465166bd1ce79
4
- data.tar.gz: 67ba1850a8f28e7025bc3d179bdb33d6506dffa0c5a94b2aa50fce20e0c20dce
3
+ metadata.gz: ea3bc79f136cc22e2710bba983cb23d14ed332d7f9a4e14e1bf94b53f17e5a1b
4
+ data.tar.gz: 404cc0d081d9d1bbe4082fd4e24532322f5a1324d8063a6e6eaaea615a7a0321
5
5
  SHA512:
6
- metadata.gz: 747a3dfac949e43f25f3ee19b31bb60d9824b25265b5c8d09c0af9f298a514b2fec0fd48cace35c4ebc553847ebd9bf9b6ea246433a5efb51b7c4918bbc39628
7
- data.tar.gz: 32d665f336d2d31d7189b5bc9569155c00c4d27ba8b2260d282295c3e2664d0ead0729454996275a2d189f446a2afebc9ae6f9f66303d38245e511978ee58b88
6
+ metadata.gz: 1df25521312cd853043220089fed8b33b0bd3bbaa192ac3720e17528a14615ecd74ac3a17d69d3c87209f571149ef8d6d9adc4ce877cad9ef8fd0bf0b36fe0ef
7
+ data.tar.gz: 261a40eac02451b42d6c331bb2281647f687c04e2aafba7523d42a70bcc37e486904cf58993869452641f50d1ce07c2ea417054013c726b28cc75c6b6f6ee7f6
data/Gemfile CHANGED
@@ -6,8 +6,12 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
6
 
7
7
  gem "bcrypt_pbkdf"
8
8
  gem "colorize"
9
+ gem "e2mmap"
9
10
  gem "ed25519"
10
11
  gem "ejson"
12
+ gem "etc"
13
+ gem "io-console"
14
+ gem "json", ">= 2.3.0"
11
15
  gem "net-ssh"
12
16
  gem "require_all"
13
17
 
@@ -17,6 +21,7 @@ group :test do
17
21
  end
18
22
 
19
23
  group :development do
24
+ gem "irb"
20
25
  gem "pry"
21
26
  gem "pry-byebug"
22
27
  gem "rerun"
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ActionList
4
+ class UnknownActionError < StandardError; end
5
+
6
+ def initialize(actions_list, args)
7
+ @actions_list = actions_list
8
+ @args = args
9
+
10
+ process_action_list
11
+ end
12
+
13
+ def get(name)
14
+ @actions[name]
15
+ end
16
+
17
+ def get_by_alias(name)
18
+ @aliases[name]
19
+ end
20
+
21
+ def names
22
+ @actions.keys
23
+ end
24
+
25
+ def aliases
26
+ @aliases.keys
27
+ end
28
+
29
+ private
30
+
31
+ def process_action_list
32
+ @actions = {}
33
+ @aliases = {}
34
+
35
+ @actions_list.each do |name, config|
36
+ action = Action.new(config, @args)
37
+
38
+ @actions[name] = action
39
+ @aliases[action.alias] = action
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ActionSuggester
4
+ def initialize(dictionary)
5
+ @dictionary = dictionary
6
+ end
7
+
8
+ def check(word)
9
+ spellchecker.correct(word)
10
+ end
11
+
12
+ private
13
+
14
+ def spellchecker
15
+ @spellchecker ||= DidYouMean::SpellChecker.new(dictionary: @dictionary)
16
+ end
17
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'version'
4
+
3
5
  class Environment
4
6
  def initialize(env_hash)
5
7
  @env_hash = env_hash
@@ -21,6 +23,7 @@ class Environment
21
23
 
22
24
  def set_ops_variables
23
25
  ENV["OPS_YML_DIR"] = Dir.pwd
26
+ ENV["OPS_VERSION"] = Version.version.to_s
24
27
  end
25
28
 
26
29
  def set_environment_aliases
data/lib/ops.rb CHANGED
@@ -11,6 +11,9 @@ require 'output'
11
11
  require 'options'
12
12
  require 'environment'
13
13
  require 'version'
14
+ require 'action_list'
15
+ require 'action_suggester'
16
+
14
17
  require_rel "builtins"
15
18
 
16
19
  # executes commands based on local `ops.yml`
@@ -24,6 +27,8 @@ class Ops
24
27
  ERROR_LOADING_APP_CONFIG_EXIT_CODE = 66
25
28
  MIN_VERSION_NOT_MET_EXIT_CODE = 67
26
29
 
30
+ RECOMMEND_HELP_TEXT = "Run 'ops help' for a list of builtins and actions."
31
+
27
32
  class << self
28
33
  def project_name
29
34
  File.basename(::Dir.pwd)
@@ -38,13 +43,14 @@ class Ops
38
43
  end
39
44
 
40
45
  def run
41
- # "return" is here to allow specs to stub "exit"
46
+ # "return" is here to allow specs to stub "exit" without executing everything after it
42
47
  return exit(INVALID_SYNTAX_EXIT_CODE) unless syntax_valid?
43
48
  return exit(MIN_VERSION_NOT_MET_EXIT_CODE) unless min_version_met?
44
49
 
45
50
  run_action
46
51
  rescue UnknownActionError => e
47
- Output.error("Error: #{e}")
52
+ Output.error(e.to_s)
53
+ Output.out(RECOMMEND_HELP_TEXT) unless print_did_you_mean
48
54
  exit(UNKNOWN_ACTION_EXIT_CODE)
49
55
  end
50
56
 
@@ -53,12 +59,25 @@ class Ops
53
59
  def syntax_valid?
54
60
  if @action_name.nil?
55
61
  Output.error("Usage: ops <action>")
62
+ Output.out(RECOMMEND_HELP_TEXT)
56
63
  false
57
64
  else
58
65
  true
59
66
  end
60
67
  end
61
68
 
69
+ def print_did_you_mean
70
+ suggestions = did_you_mean.check(@action_name)
71
+
72
+ Output.out("Did you mean '#{suggestions.join(", ")}'?") if suggestions.any?
73
+
74
+ suggestions.any?
75
+ end
76
+
77
+ def did_you_mean
78
+ ActionSuggester.new(action_list.names + action_list.aliases + builtin_names)
79
+ end
80
+
62
81
  def min_version_met?
63
82
  return true unless min_version
64
83
 
@@ -80,7 +99,6 @@ class Ops
80
99
  return builtin.run if builtin
81
100
 
82
101
  do_before_action
83
-
84
102
  Output.notice("Running '#{action}' from #{CONFIG_FILE} in environment '#{ENV['environment']}'...")
85
103
  action.run
86
104
  rescue AppConfig::ParsingError => e
@@ -111,24 +129,22 @@ class Ops
111
129
  nil
112
130
  end
113
131
 
132
+ def builtin_names
133
+ Builtins.constants.select { |c| Builtins.const_get(c).is_a? Class }.map(&:downcase)
134
+ end
135
+
114
136
  def action
115
- return actions[@action_name] if actions[@action_name]
116
- return aliases[@action_name] if aliases[@action_name]
137
+ return action_list.get(@action_name) if action_list.get(@action_name)
138
+ return action_list.get_by_alias(@action_name) if action_list.get_by_alias(@action_name)
117
139
 
118
140
  raise UnknownActionError, "Unknown action: #{@action_name}"
119
141
  end
120
142
 
121
- def actions
122
- @actions ||= begin
123
- if config["actions"]
124
- config["actions"]&.transform_values do |config|
125
- Action.new(config, @args)
126
- end
127
- else
128
- # only print this error if ops.yml had something in it
129
- Output.warn("'ops.yml' has no 'actions' defined.") if config.any?
130
- {}
131
- end
143
+ def action_list
144
+ @action_list ||= begin
145
+ Output.warn("'ops.yml' has no 'actions' defined.") if config.any? && config["actions"].nil?
146
+
147
+ ActionList.new(config["actions"], @args)
132
148
  end
133
149
  end
134
150
 
@@ -142,14 +158,6 @@ class Ops
142
158
  end
143
159
  end
144
160
 
145
- def aliases
146
- @aliases ||= begin
147
- actions.each_with_object({}) do |(_name, action), alias_hash|
148
- alias_hash[action.alias] = action if action.alias
149
- end
150
- end
151
- end
152
-
153
161
  def env_vars
154
162
  @config.dig("options", "environment") || {}
155
163
  end
@@ -157,10 +165,6 @@ class Ops
157
165
  def environment
158
166
  @environment ||= Environment.new(env_vars)
159
167
  end
160
-
161
- def app_config
162
- @app_config ||= AppConfig.new
163
- end
164
168
  end
165
169
 
166
170
  Ops.new(ARGV).run if $PROGRAM_NAME == __FILE__
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'ops_team'
5
- s.version = '0.12.2'
5
+ s.version = '0.13.3'
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.12.2
4
+ version: 0.13.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - nickthecook@gmail.com
@@ -146,6 +146,8 @@ files:
146
146
  - etc/ruby.template.yml
147
147
  - etc/terraform.template.yml
148
148
  - lib/action.rb
149
+ - lib/action_list.rb
150
+ - lib/action_suggester.rb
149
151
  - lib/app_config.rb
150
152
  - lib/builtin.rb
151
153
  - lib/builtins/background.rb