ops_team 0.12.2 → 0.13.3

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: 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