thor_enhance 0.4.0 → 0.5.0

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.
@@ -0,0 +1,49 @@
1
+ # <%= title.to_s.titlecase %>
2
+
3
+ ## Description
4
+ <%= command.long_description || command.description %>
5
+
6
+ ```bash
7
+ # Base command for `<%= command.usage %>`
8
+ <%= basename_string %>
9
+ ```
10
+
11
+ <%= custom_headers %>
12
+
13
+ <% headers.each do |header| %>
14
+ ## <%= header[:name] %>
15
+ <%= header[:desc]%>
16
+ <% end %>
17
+ <% if drawn_out_examples %>
18
+ ---
19
+
20
+ ## Examples
21
+ <% drawn_out_examples.each do |ex|%>
22
+ ```bash
23
+ <%= ex %>
24
+ ```
25
+ <% end %>
26
+ <% end %>
27
+ <% if !method_options_erb.strip.empty? %>
28
+ ---
29
+
30
+ <% if children_descriptors.empty? %>
31
+ ## Method Options
32
+
33
+ <%= method_options_erb %>
34
+ <% end %>
35
+ <% else %>
36
+ <% children_descriptors.each do |child| %>
37
+ ### [<%= child[:title]%>](<%= child[:link] %>)
38
+
39
+ <%= child[:description] %>
40
+
41
+ ```bash
42
+ <%= child[:basename_string]%> <options>
43
+ <%= child[:examples].map { _1 }.join("\n") %>
44
+ ```
45
+ <% end %>
46
+ <% end %>
47
+ ---
48
+
49
+ <%= footer_erb %>
@@ -0,0 +1,3 @@
1
+ > AutoGenerateted by [ThorEnhance](https://github.com/matt-taylor/thor_enhance) <br>
2
+ > Regenerate file with: <%= regenerate_single_command %> <br>
3
+ > Regenerate all files with: <%= regenerate_thor_command %>
@@ -0,0 +1,14 @@
1
+ # What: <%= option.description %>
2
+ # Type: <%= option.type %>
3
+ # Required: <%= option.required %>
4
+ # <%= "**Allowed inputs:** #{option.enum}" if option.enum %>
5
+ # <%= name.to_s.titlecase %>
6
+ <%= invocations.map { "`#{_1}`"}.join(" | ") %>
7
+
8
+ **What:** <%= option.description %><br>
9
+ **Invocation:** <br>
10
+ **Type:** <%= option.type %><br>
11
+ **Default:** <%= option.default || "none" %><br>
12
+ **Required:** <%= option.required %><br>
13
+ <%= "**Allowed inputs:** #{option.enum}" if option.enum %>
14
+
@@ -0,0 +1,9 @@
1
+ ## [<%= root_child[:title]%>](<%= root_child[:link] %>)
2
+ <%= root_child[:description] %>
3
+
4
+ ```bash
5
+ # Help Command
6
+ <%= root_child[:basename_string]%> <options>
7
+
8
+ <%= root_child[:examples].map { _1 }.join("\n") %>
9
+ ```
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThorEnhance
4
+ module Autogenerate
5
+ module Validate
6
+ module_function
7
+
8
+ def validate(options:, root: nil)
9
+ root_result = validate_root(options: options, root: root)
10
+ return root_result if root_result[:status] != :pass
11
+
12
+ trunk = root_result[:trunk]
13
+ constant = root_result[:constant]
14
+
15
+ subcommand_result = validate_subcommand(options: options, trunk: trunk)
16
+ return subcommand_result if subcommand_result[:status] != :pass
17
+
18
+ trunk = subcommand_result[:trunk]
19
+ command_result = validate_command(options: options, trunk: trunk, constant: constant)
20
+ return command_result if command_result[:status] != :pass
21
+ command = command_result[:command]
22
+ { command: command, trunk: trunk, constant: constant, status: :pass }
23
+ end
24
+
25
+ def validate_root(options:, root:)
26
+ begin
27
+ constant = root || Object.const_get(options.root.to_s)
28
+ rescue NameError => e
29
+ msg_array = [
30
+ "Unable to load provided --root|-r option `#{options.root}`",
31
+ "Please check the spelling and ensure the klass has loaded"
32
+ ]
33
+ return { error: e, msg_array: msg_array, status: :fail }
34
+ end
35
+
36
+ begin
37
+ trunk = ThorEnhance::Tree.tree(base: constant)
38
+ rescue TreeFailure => e
39
+ msg_array = [
40
+ "--root|-r option is not a Thor klass.",
41
+ "Please ensure that the provided klass is a child of Thor"
42
+ ]
43
+ return { error: e, msg_array: msg_array, status: :fail }
44
+ end
45
+
46
+ { trunk: trunk, constant: constant, status: :pass }
47
+ end
48
+
49
+ def validate_command(options:, trunk:, constant:)
50
+ # Return early when command is not present in the options object
51
+ command = options.command
52
+ return { status: :pass, trunk: trunk, command: nil } if command.nil?
53
+
54
+ # Return early when command is found in the tree trunk
55
+ command = trunk.children[options.command] rescue trunk[options.command]
56
+ return { status: :pass, trunk: trunk, command: command } if command
57
+
58
+ # Command option was available but command was not found in the trunk
59
+ msg_array = ["Failed to find --command|-c `#{options.command}`"]
60
+ msg_array << "Provided root command `#{constant}`"
61
+ msg_array << "With Provided subcommand `#{options.subcommand}`" if options.subcommand
62
+ msg_array << "does not have command `#{options.command}` as a child" if options.subcommand
63
+
64
+ { msg_array: msg_array, status: :fail }
65
+ end
66
+
67
+ def validate_subcommand(options:, trunk:)
68
+ subcommands = options.subcommand
69
+ return { trunk: trunk, status: :pass } if subcommands.nil?
70
+
71
+ subcommands = subcommands.dup
72
+ subcommand = subcommands.shift
73
+ temp_trunk = trunk[subcommand]
74
+ while subcommand != nil
75
+ if temp_trunk.nil? || !temp_trunk.children?
76
+ msg_array = [
77
+ "Order is important with --subcommands|-s options",
78
+ "Provided with: #{options.subcommand}",
79
+ "Subcommand `#{subcommand}` does not have any child commands",
80
+ "Every provided subcommand must have children",
81
+ "If the subcommand `#{subcommand}` is meant to be a command",
82
+ "Pass `#{subcommand}` in as `--command|-c #{subcommand}` instead",
83
+ ]
84
+ return { msg_array: msg_array, status: :fail }
85
+ end
86
+ subcommand = subcommands.shift
87
+ # Will always be in the child hash at this point if subcommand exists
88
+ temp_trunk = temp_trunk.children[subcommand] if subcommand
89
+ end
90
+
91
+ { trunk: temp_trunk, subcommands: options.subcommand, status: :pass }
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor_enhance/autogenerate/configuration"
4
+ require "thor_enhance/autogenerate/validate"
5
+ require "thor_enhance/autogenerate/option"
6
+ require "thor_enhance/autogenerate/command"
7
+
8
+ module ThorEnhance
9
+ module Autogenerate
10
+ module_function
11
+
12
+ ROOT_ERB = "#{File.dirname(__FILE__)}/autogenerate/templates/root.rb.erb"
13
+ ROOT_TEMPLATE = ERB.new(File.read(ROOT_ERB))
14
+
15
+ def execute!(options:, basename: File.basename($0), root: nil)
16
+ validate_result = Validate.validate(options: options, root: root)
17
+ return validate_result if validate_result[:status] != :pass
18
+
19
+ command = validate_result[:command]
20
+ trunk = validate_result[:trunk]
21
+ leaves =
22
+ if command
23
+ { options.command => command }
24
+ elsif Hash === trunk
25
+ # Parent trunk is a hash -- structure needs to change
26
+ trunk
27
+ else
28
+ # if not parent, grab the children
29
+ trunk.children
30
+ end
31
+
32
+ command_structure = leaves.map do |name, leaf|
33
+ parent = Command.new(name: name, leaf: leaf, basename: basename)
34
+ end
35
+
36
+ # flatten_children returns all kids, grandkids, great grandkids etc of the commands returned from the above mapping
37
+ youthful_kids = command_structure.map(&:flatten_children).flatten
38
+
39
+ # this is a flat map of the entire family tree. Each node knows where it is so we can flatten it
40
+ family_tree = command_structure + youthful_kids
41
+
42
+ save_generated_readmes!(commands: family_tree, generated_root: options.generated_root, apply: options.apply)
43
+ end
44
+
45
+ def save_generated_readmes!(commands:, generated_root:, apply:)
46
+ parent = generated_root || ENV["THOR_ENHANCE_GENERATED_ROOT_PATH"]
47
+ full_root = "#{parent}/commands"
48
+ saved_status = commands.map do |command|
49
+ command.save_self!(root: full_root, apply: apply)
50
+ end
51
+ self_for_roots = saved_status.collect { _1[:self_for_root] }
52
+ saved_status << root_savior!(apply: apply, full_root: full_root, self_for_roots: self_for_roots)
53
+
54
+ { status: :pass, saved_status: saved_status }
55
+ end
56
+
57
+ def root_savior!(full_root:, self_for_roots:, apply:)
58
+ full_path = "#{full_root}/Readme.md"
59
+ root_erb_result = self_for_roots.map do |root_child|
60
+ ROOT_TEMPLATE.result_with_hash({ root_child: root_child })
61
+ end.join("\n")
62
+
63
+ FileUtils.mkdir_p(full_root)
64
+ if File.exist?(full_path)
65
+ content = File.read(full_path)
66
+ diff = root_erb_result == content ? :same : :overwite
67
+ else
68
+ diff = :new
69
+ end
70
+
71
+ if apply
72
+ File.write(full_path, root_erb_result)
73
+ end
74
+
75
+ { path: full_path, diff: diff, apply: apply }
76
+ end
77
+ end
78
+ end
@@ -14,16 +14,18 @@ module ThorEnhance
14
14
  ThorEnhance.configuration.command_method_enhance.each do |name, object|
15
15
  # Define a new method based on the name of each enhanced command method
16
16
  # Method takes care all validation except requirment -- Requirement is done during command initialization
17
- ClassMethods.define_method("#{name}") do |input|
17
+ ClassMethods.define_method("#{name}") do |input = nil, *args, **kwargs|
18
18
  return nil unless ThorEnhance.configuration.allowed?(self)
19
19
 
20
- value = instance_variable_get("@#{name}")
21
- value ||= {}
22
20
  # Usage is nil when the `desc` has not been defined yet -- Under normal circumstance this will never happen
23
21
  if @usage.nil?
24
22
  raise ArgumentError, "Usage is not set. Please ensure `#{name}` is defined after usage is set"
25
23
  end
26
24
 
25
+ __thor_enhance_validate_arguments!(object, input, args, kwargs)
26
+ value = instance_variable_get("@#{name}")
27
+ value ||= {}
28
+
27
29
  # Required check gets done on command initialization (defined below in ClassMethods)
28
30
  if input.nil?
29
31
  # no op when it is nil
@@ -39,14 +41,14 @@ module ThorEnhance
39
41
 
40
42
  if object[:repeatable]
41
43
  value[@usage] ||= []
42
- value[@usage] << input
44
+ value[@usage] << { input: input, arguments: { kwargs: kwargs, positional: args } }
43
45
  else
44
46
  if value[@usage]
45
47
  raise ValidationFailed, "#{@usage} recieved command method `#{name}` with repeated invocations of " \
46
48
  "`#{name}`. Please remove the secondary invocation. Or set `#{name}` as a repeatable command method"
47
49
  end
48
50
 
49
- value[@usage] = input
51
+ value[@usage] = { input: input, arguments: { kwargs: kwargs, positional: args } }
50
52
  end
51
53
 
52
54
  instance_variable_set("@#{name}", value)
@@ -106,6 +108,10 @@ module ThorEnhance
106
108
  # Skip if the method is part of the ignore list
107
109
  next if ThorEnhance::Tree.ignore_commands.include?(meth.to_s)
108
110
 
111
+ # subcommands/subtasks need not require things that regular commands need
112
+ # If user wants them on the sucommand, thats cool, but we will never enforce it
113
+ next if subcommands.map(&:to_s).include?(meth.to_s)
114
+
109
115
  # At this point, the command method is missing, we are not in disable mode, and the command method was required
110
116
  # raise all hell
111
117
  raise ThorEnhance::RequiredOption, "`#{meth}` does not have required command method #{name} invoked. " \
@@ -131,6 +137,30 @@ module ThorEnhance
131
137
 
132
138
  private
133
139
 
140
+
141
+ def __thor_enhance_validate_arguments!(object, input, args, kwargs)
142
+ expected_arity = object.dig(:arity)
143
+ if args.length != expected_arity
144
+ raise ArgumentError, "Excluding #{input}, the expected arity command method `#{name}` for #{@usage} is #{expected_arity}. Provided #{args.length}"
145
+ end
146
+
147
+ # checks if there are extra kwargs present that are not expected
148
+ available_kwargs = object.dig(:kwargs).keys
149
+ extra_keys = kwargs.keys - available_kwargs
150
+ unless extra_keys.empty?
151
+ raise ArgumentError, "#{@usage} received command method `#{name}` with unknown KWargs #{extra_keys}"
152
+ end
153
+
154
+ # Checks if all the required kwargs are present
155
+ req_kwargs = object.dig(:kwargs).select { _2 }.keys
156
+ missing_required_kwargs = req_kwargs - kwargs.keys
157
+
158
+ # binding.pry if expected_arity > 0 || available_kwargs.length > 0
159
+ return if missing_required_kwargs.empty?
160
+
161
+ raise ArgumentError, "#{@usage} received command method `#{name}` with missing KWargs #{missing_required_kwargs}"
162
+ end
163
+
134
164
  def __thor_enhance_access(type:, &block)
135
165
  raise ArgumentError, "Expected to receive block. No block given" unless block_given?
136
166
 
@@ -58,6 +58,30 @@ module ThorEnhance
58
58
  self.class.disallow_changes!
59
59
  end
60
60
 
61
+ def readme_enhance!(required: false, &block)
62
+ # only inject readme things if it is required client side
63
+ require "thor_enhance/thor_auto_generate_inject"
64
+ require "thor_enhance/autogenerate"
65
+
66
+ if defined?(@autogenerated_config)
67
+ raise ValidationFailed, "ReadMe Enhance has already been initialized."
68
+ end
69
+
70
+ autogenerated_config.set_default_required(required)
71
+ autogenerated_config.default
72
+ yield(autogenerated_config) if block_given?
73
+
74
+ autogenerated_config.configuration.each do |meth, object|
75
+ object.each do |name, args|
76
+ public_send(meth, name, **args)
77
+ end
78
+ end
79
+ end
80
+
81
+ def autogenerated_config
82
+ @autogenerated_config ||= Autogenerate::Configuration.new
83
+ end
84
+
61
85
  def command_method_enhance
62
86
  @command_method_enhance ||= {}
63
87
  end
@@ -66,6 +90,14 @@ module ThorEnhance
66
90
  @klass_procs ||= []
67
91
  end
68
92
 
93
+ def basename
94
+ @basename
95
+ end
96
+
97
+ def basename=(name)
98
+ @basename = name
99
+ end
100
+
69
101
  def allowed
70
102
  @allowed ||= DEFAULT_ALLOWED
71
103
  end
@@ -92,14 +124,21 @@ module ThorEnhance
92
124
  end
93
125
 
94
126
  # Adding a new method to enhance the overall command
95
- def add_command_method_enhance(name, allowed_klasses: nil, enums: nil, required: false, repeatable: false)
127
+ def add_command_method_enhance(name, allowed_klasses: nil, enums: nil, required: false, repeatable: false, arity: 0, required_kwargs: [], optional_kwargs: [])
128
+ return if ENV["SKIP_TESTING_METHOD"]
129
+
96
130
  self.class.allow_changes?
97
131
 
98
- add_to_variable(command_method_enhance, ::Thor::Command.instance_methods, name, allowed_klasses, enums, required, repeatable)
132
+ kwargs = {}
133
+ required_kwargs.each { kwargs[_1.to_sym] = true }
134
+ optional_kwargs.each { kwargs[_1.to_sym] = false }
135
+ add_to_variable(command_method_enhance, ::Thor::Command.instance_methods, name, allowed_klasses, enums, required, repeatable, arity, kwargs)
99
136
  end
100
137
 
101
138
  # add a new flag on the command option
102
139
  def add_option_enhance(name, allowed_klasses: nil, enums: nil, required: false)
140
+ return if ENV["SKIP_TESTING_METHOD"]
141
+
103
142
  self.class.allow_changes?
104
143
 
105
144
  add_to_variable(option_enhance, ::Thor::Option.instance_methods, name, allowed_klasses, enums, required)
@@ -107,7 +146,7 @@ module ThorEnhance
107
146
 
108
147
  private
109
148
 
110
- def add_to_variable(storage, methods, name, allowed_klasses, enums, required, repeatable = false)
149
+ def add_to_variable(storage, methods, name, allowed_klasses, enums, required, repeatable = false, arity = 0, kwargs = false)
111
150
  # Reject if the name is not a Symbol or a string
112
151
  if [String, Symbol].none? { _1 === name }
113
152
  raise ArgumentError, "Invalid name type received. Received [#{name}] of type [#{name.class}]. Expected to be of type String or Symbol"
@@ -136,7 +175,11 @@ module ThorEnhance
136
175
  raise ArgumentError, "Recieved allowed_klasses with #{allowed_klasses}. When present, it is expected to be an Array"
137
176
  end
138
177
 
139
- storage[name.to_sym] = { allowed_klasses: allowed_klasses, enums: enums, required: required, repeatable: repeatable }
178
+ if arity < 0
179
+ raise ArgumentError, "Recieved arity with #{arity}. When present, it is expected to be greater than 0"
180
+ end
181
+
182
+ storage[name.to_sym] = { allowed_klasses: allowed_klasses, enums: enums, required: required, repeatable: repeatable, kwargs: kwargs, arity: arity }
140
183
  end
141
184
  end
142
185
  end
@@ -5,8 +5,6 @@ require "thor"
5
5
  module ThorEnhance
6
6
  module Option
7
7
  def self.thor_enhance_injection!
8
- return false unless ThorEnhance::Configuration.allow_changes?
9
-
10
8
  # Create getter method for the enhance instance variable
11
9
  ThorEnhance.configuration.option_enhance.each do |name, object|
12
10
  define_method(name) { instance_variable_get("@#{name}") }
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor_enhance"
4
+
5
+ module ThorEnhance
6
+ class Sample < Thor
7
+ thor_enhance_allow!
8
+
9
+ class SubCommand < Thor
10
+ thor_enhance_allow!
11
+
12
+ desc "innard", "Validate that a subcommand works. This description can be as long as you want it to be."
13
+ long_desc "Wow, This longer description will take precedence over the desc above. This is what will be shown in the readme autogenerated page. Try me out!"
14
+ example "innard --count 5", desc: "Innard sub command with a count of 5"
15
+ example "innard --count 35", desc: "Innard sub command with a count of 35"
16
+ header name: "Deprecation warning", desc: "This command will get deprecated in the next major version"
17
+ when_should_i_use_this "Use sub command task to validate that subocommands work as expected"
18
+ method_option :count, type: :numeric, readme: :skip
19
+ def innard;end;
20
+ end
21
+
22
+ desc "sub", "Thor sub command validation for thor enhance"
23
+ subcommand "sub", SubCommand
24
+
25
+ desc "sample", "This Sample command does a lot of nothing"
26
+ when_should_i_use_this <<~README
27
+ Have you ever wanted your code to be useless?
28
+ Well, this command does absolutely nothing.
29
+ This output is to say that this command does absolutely nothing
30
+ README
31
+ how_does_this_help "Honestly, this does not help at all", tag: "h4"
32
+ how_does_this_help "But its cool because it is a repatable command", tag: "h1"
33
+ example "sample", desc: "yo yo ma"
34
+ example "sample --boolean", desc: "yo yo ma"
35
+ method_option :boolean, aliases: "-b", type: :boolean, desc: "Just a normal boolean", readme: :important
36
+ def sample
37
+ Kernel.puts "Executed Sample method"
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ ####################
4
+ #
5
+ # Injects a method directly into the thor base class
6
+ # This allows the developer to have this convenience method
7
+ # Just by utilizing ThorEnhance
8
+ #
9
+ ####################
10
+ require "thor"
11
+
12
+ class Thor
13
+ desc "thor_enhance_autogenerate", "Auto Generate ReadMe material for your Thor commands"
14
+ method_option :subcommand, aliases: "-s", type: :string, repeatable: true, desc: "When provided, autogeneration will execute on the subcommand"
15
+ method_option :command, aliases: "-c", type: :string, desc: "When provided, autogeneration will occur only on this method. Note: When used with subcommand, method must exist on subcommand"
16
+ method_option :basename, aliases: "-b", type: :string, desc: "The name of the file that executes the Thor script"
17
+ method_option :generated_root, aliases: "-r", type: :string, default: File.expand_path("generated_readme"), desc: "The root location to store autogenerated files"
18
+ method_option :apply, aliases: "-a", type: :boolean, desc: "When comfortable with the changes made, enabling apply will save changes to generated files"
19
+
20
+ def thor_enhance_autogenerate
21
+ require "thor_enhance/autogenerate"
22
+ basename = options.basename || ThorEnhance.basename || File.basename($0)
23
+
24
+ result = ThorEnhance::Autogenerate.execute!(options: options, root: self.class, basename: basename)
25
+
26
+ if result[:status] == :pass
27
+ __auto_generate_success!(result[:saved_status])
28
+ else
29
+ __auto_generate_fail!(result[:msg_array])
30
+ end
31
+ end
32
+
33
+ no_tasks do
34
+ def __auto_generate_success!(statuses)
35
+ if statuses.all? { _1[:apply] == true }
36
+ say "Readme changes are enabled", [:green, :bold], true
37
+ else
38
+ say "Readme changes are not enabled. To apply changes, add `--apply` to the command", [:on_white, :black], true
39
+ end
40
+ statuses.each do |status|
41
+ case status[:diff]
42
+ when :new
43
+ say " Added : #{status[:path]}", [:green, :bold], true
44
+ when :same
45
+ say " No Change: #{status[:path]}", [:yellow, :bold], true
46
+ when :overwite
47
+ say " Changes : #{status[:path]}", [:cyan, :bold], true
48
+ else
49
+ say " : #{status[:path]}", [:bold], true
50
+ end
51
+ end
52
+ end
53
+
54
+ def __auto_generate_fail!(msg_array)
55
+ say_error set_color("*********************** FAILED OPERATION ***********************", :red, :bold)
56
+ say_error set_color("FAIL: Unable to continue", :red, :bold)
57
+ msg_array.each do |line|
58
+ say_error set_color("FAIL: #{line}", :red, :bold)
59
+ end
60
+ say_error set_color("*********************** FAILED OPERATION ***********************", :red, :bold)
61
+ exit 1
62
+ end
63
+ end
64
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ThorEnhance
4
4
  class Tree
5
- DEFAULT_IGNORE_COMMANDS = ["help"]
5
+ DEFAULT_IGNORE_COMMANDS = ["help", "thor_enhance_autogenerate"]
6
6
 
7
7
  def self.add_ignore_commands(command)
8
8
  return false if ignore_commands.include?(command)
@@ -20,6 +20,8 @@ module ThorEnhance
20
20
  end
21
21
 
22
22
  def self.tree(base:, parent: nil)
23
+ raise TreeFailure, "#{base} does not respond to all_commands. Unable to continue" unless base.respond_to?(:all_commands)
24
+
23
25
  base.all_commands.map do |k, command|
24
26
  next if ignore_commands.include?(k)
25
27
 
@@ -36,7 +38,7 @@ module ThorEnhance
36
38
  @parent = parent
37
39
  @base = base
38
40
  @command = command
39
- @children = []
41
+ @children = {}
40
42
 
41
43
  if !base.subcommand_classes.nil? && base.subcommand_classes[command.name]
42
44
  @children = self.class.tree(parent: self, base: base.subcommand_classes[command.name])
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ThorEnhance
4
- VERSION = "0.4.0"
4
+ VERSION = "0.5.0"
5
5
  end
data/lib/thor_enhance.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support"
4
+
3
5
  require "thor_enhance/base"
4
6
  require "thor_enhance/command"
5
7
  require "thor_enhance/command_hook"
@@ -10,10 +12,16 @@ require "thor_enhance/tree"
10
12
 
11
13
  module ThorEnhance
12
14
  class BaseError < StandardError; end
13
- class OptionNotAllowed < StandardError; end
14
- class ValidationFailed < StandardError; end
15
- class RequiredOption < StandardError; end
16
- class OptionDeprecated < StandardError; end
15
+ class OptionNotAllowed < BaseError; end
16
+ class ValidationFailed < BaseError; end
17
+ class RequiredOption < BaseError; end
18
+ class OptionDeprecated < BaseError; end
19
+ class TreeFailure < BaseError; end
20
+ class AutoGenerateFailure < BaseError; end
21
+
22
+ def self.basename
23
+ configuration.basename
24
+ end
17
25
 
18
26
  def self.configure
19
27
  yield configuration if block_given?
data/thor_enhance.gemspec CHANGED
@@ -30,4 +30,5 @@ Gem::Specification.new do |spec|
30
30
  spec.require_paths = ["lib"]
31
31
 
32
32
  spec.add_dependency "thor", "~> 1.3"
33
+ spec.add_dependency "activesupport", ">=6"
33
34
  end