thor_enhance 0.4.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +36 -8
- data/README.md +4 -2
- data/bin/thor_enhance +22 -0
- data/docs/autogenerate/Readme.md +166 -0
- data/generated_readme/commands/Readme.md +34 -0
- data/generated_readme/commands/autobots.md +69 -0
- data/generated_readme/commands/sample.md +84 -0
- data/generated_readme/commands/sub/Readme.md +37 -0
- data/generated_readme/commands/sub/innard.md +46 -0
- data/lib/thor_enhance/autogenerate/command.rb +334 -0
- data/lib/thor_enhance/autogenerate/configuration.rb +72 -0
- data/lib/thor_enhance/autogenerate/option.rb +44 -0
- data/lib/thor_enhance/autogenerate/templates/aggregate_options.rb.erb +11 -0
- data/lib/thor_enhance/autogenerate/templates/class_options.rb.erb +7 -0
- data/lib/thor_enhance/autogenerate/templates/command.rb.erb +54 -0
- data/lib/thor_enhance/autogenerate/templates/footer.rb.erb +2 -0
- data/lib/thor_enhance/autogenerate/templates/option.rb.erb +14 -0
- data/lib/thor_enhance/autogenerate/templates/root.rb.erb +9 -0
- data/lib/thor_enhance/autogenerate/validate.rb +95 -0
- data/lib/thor_enhance/autogenerate.rb +87 -0
- data/lib/thor_enhance/command_method.rb +42 -6
- data/lib/thor_enhance/configuration.rb +47 -4
- data/lib/thor_enhance/option.rb +0 -2
- data/lib/thor_enhance/sample.rb +58 -0
- data/lib/thor_enhance/thor_auto_generate_inject.rb +64 -0
- data/lib/thor_enhance/tree.rb +4 -2
- data/lib/thor_enhance/version.rb +1 -1
- data/lib/thor_enhance.rb +12 -4
- data/thor_enhance.gemspec +1 -0
- metadata +36 -2
@@ -0,0 +1,87 @@
|
|
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
|
+
Command.new(name: name, leaf: leaf, basename: basename, root: options.generated_root)
|
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
|
+
children_result = save_generated_readmes!(commands: youthful_kids, generated_root: options.generated_root, apply: options.apply)
|
39
|
+
return children_result if children_result[:status] != :pass
|
40
|
+
|
41
|
+
root_result = save_generated_readmes!(commands: command_structure, generated_root: options.generated_root, apply: options.apply)
|
42
|
+
return root_result if root_result[:status] != :pass
|
43
|
+
|
44
|
+
self_for_roots = root_result[:saved_status].collect { _1[:self_for_root] }
|
45
|
+
# Add saved results from the children
|
46
|
+
root_result[:saved_status] += children_result[:saved_status]
|
47
|
+
# Add root savior saved results
|
48
|
+
root_result[:saved_status] << root_savior!(basename: basename, apply: options.apply, full_root: root_result[:full_root], self_for_roots: self_for_roots)
|
49
|
+
|
50
|
+
root_result
|
51
|
+
end
|
52
|
+
|
53
|
+
def save_generated_readmes!(commands:, generated_root:, apply:)
|
54
|
+
parent = generated_root || ENV["THOR_ENHANCE_GENERATED_ROOT_PATH"]
|
55
|
+
full_root = "#{parent}/commands"
|
56
|
+
saved_status = commands.map do |command|
|
57
|
+
command.save_self!(root: full_root, apply: apply)
|
58
|
+
end
|
59
|
+
|
60
|
+
{ status: :pass, full_root: full_root, saved_status: saved_status }
|
61
|
+
end
|
62
|
+
|
63
|
+
def root_savior!(basename:, full_root:, self_for_roots:, apply:)
|
64
|
+
full_path = "#{full_root}/Readme.md"
|
65
|
+
regenerate_thor_command = "#{basename} thor_enhance_autogenerate --apply"
|
66
|
+
footer = ThorEnhance::Autogenerate::Command::FOOTER_TEMPLATE.result_with_hash({ regenerate_thor_command: regenerate_thor_command })
|
67
|
+
|
68
|
+
root_erb_result = (self_for_roots.map do |root_child|
|
69
|
+
ROOT_TEMPLATE.result_with_hash({ root_child: root_child })
|
70
|
+
end + [footer]).join("\n")
|
71
|
+
|
72
|
+
FileUtils.mkdir_p(full_root)
|
73
|
+
if File.exist?(full_path)
|
74
|
+
content = File.read(full_path)
|
75
|
+
diff = root_erb_result == content ? :same : :overwite
|
76
|
+
else
|
77
|
+
diff = :new
|
78
|
+
end
|
79
|
+
|
80
|
+
if apply
|
81
|
+
File.write(full_path, root_erb_result)
|
82
|
+
end
|
83
|
+
|
84
|
+
{ path: full_path, diff: diff, apply: apply }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
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)
|
@@ -98,7 +100,10 @@ module ThorEnhance
|
|
98
100
|
# The value is nil/unset
|
99
101
|
|
100
102
|
# If we have disabled required operations, go ahead and skip this
|
101
|
-
|
103
|
+
if ::Thor.__thor_enhance_definition == ThorEnhance::CommandMethod::ClassMethods::THOR_ENHANCE_DISABLE
|
104
|
+
::Thor.__thor_enhance_definition_ignored << meth.to_sym
|
105
|
+
next
|
106
|
+
end
|
102
107
|
|
103
108
|
# Skip if the expected command method was not required
|
104
109
|
next unless object[:required]
|
@@ -106,6 +111,10 @@ module ThorEnhance
|
|
106
111
|
# Skip if the method is part of the ignore list
|
107
112
|
next if ThorEnhance::Tree.ignore_commands.include?(meth.to_s)
|
108
113
|
|
114
|
+
# subcommands/subtasks need not require things that regular commands need
|
115
|
+
# If user wants them on the sucommand, thats cool, but we will never enforce it
|
116
|
+
next if subcommands.map(&:to_s).include?(meth.to_s)
|
117
|
+
|
109
118
|
# At this point, the command method is missing, we are not in disable mode, and the command method was required
|
110
119
|
# raise all hell
|
111
120
|
raise ThorEnhance::RequiredOption, "`#{meth}` does not have required command method #{name} invoked. " \
|
@@ -129,8 +138,35 @@ module ThorEnhance
|
|
129
138
|
@__thor_enhance_definition_stack ||= []
|
130
139
|
end
|
131
140
|
|
141
|
+
def __thor_enhance_definition_ignored
|
142
|
+
@__thor_enhance_definition_ignored ||= []
|
143
|
+
end
|
144
|
+
|
132
145
|
private
|
133
146
|
|
147
|
+
def __thor_enhance_validate_arguments!(object, input, args, kwargs)
|
148
|
+
expected_arity = object.dig(:arity)
|
149
|
+
if args.length != expected_arity
|
150
|
+
raise ArgumentError, "Excluding #{input}, the expected arity command method `#{name}` for #{@usage} is #{expected_arity}. Provided #{args.length}"
|
151
|
+
end
|
152
|
+
|
153
|
+
# checks if there are extra kwargs present that are not expected
|
154
|
+
available_kwargs = object.dig(:kwargs).keys
|
155
|
+
extra_keys = kwargs.keys - available_kwargs
|
156
|
+
unless extra_keys.empty?
|
157
|
+
raise ArgumentError, "#{@usage} received command method `#{name}` with unknown KWargs #{extra_keys}"
|
158
|
+
end
|
159
|
+
|
160
|
+
# Checks if all the required kwargs are present
|
161
|
+
req_kwargs = object.dig(:kwargs).select { _2 }.keys
|
162
|
+
missing_required_kwargs = req_kwargs - kwargs.keys
|
163
|
+
|
164
|
+
# binding.pry if expected_arity > 0 || available_kwargs.length > 0
|
165
|
+
return if missing_required_kwargs.empty?
|
166
|
+
|
167
|
+
raise ArgumentError, "#{@usage} received command method `#{name}` with missing KWargs #{missing_required_kwargs}"
|
168
|
+
end
|
169
|
+
|
134
170
|
def __thor_enhance_access(type:, &block)
|
135
171
|
raise ArgumentError, "Expected to receive block. No block given" unless block_given?
|
136
172
|
|
@@ -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
|
-
|
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
|
-
|
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
|
data/lib/thor_enhance/option.rb
CHANGED
@@ -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,58 @@
|
|
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
|
+
title "Innard command for Subtask Subcommand"
|
14
|
+
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!"
|
15
|
+
example "innard --count 5", desc: "Innard sub command with a count of 5"
|
16
|
+
example "innard --count 35", desc: "Innard sub command with a count of 35"
|
17
|
+
header name: "Deprecation warning", desc: "This command will get deprecated in the next major version"
|
18
|
+
when_should_i_use_this "Use sub command task to validate that subocommands work as expected"
|
19
|
+
method_option :count, type: :numeric, readme: :skip
|
20
|
+
def innard;end;
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "sub", "Thor sub command validation for thor enhance"
|
24
|
+
title "Subcommand for sample class"
|
25
|
+
subcommand "sub", SubCommand
|
26
|
+
|
27
|
+
desc "sample", "This Sample command does a lot of nothing"
|
28
|
+
when_should_i_use_this <<~README
|
29
|
+
Have you ever wanted your code to be useless?
|
30
|
+
Well, this command does absolutely nothing.
|
31
|
+
This output is to say that this command does absolutely nothing
|
32
|
+
README
|
33
|
+
how_does_this_help "Honestly, this does not help at all", tag: "h4"
|
34
|
+
how_does_this_help "But its cool because it is a repatable command", tag: "h1"
|
35
|
+
example "sample", desc: "yo yo ma"
|
36
|
+
example "sample --boolean", desc: "yo yo ma"
|
37
|
+
method_option :boolean, aliases: "-b", type: :boolean, desc: "Just a normal boolean", readme: :important
|
38
|
+
method_option :count, type: :numeric, enum: [1,2,3,4,5], default: 1, desc: "How many times to output text", readme: :important
|
39
|
+
def sample
|
40
|
+
options[:count].times { Kernel.puts "Executed Sample method" }
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "autobots", "Command outputs what Optimus prime is thniking"
|
44
|
+
when_should_i_use_this <<~README
|
45
|
+
Do you ever feel angry about how powerful the Decepticons are compared to the Autobots? It seems unfair.
|
46
|
+
Trust...The autobots agree.
|
47
|
+
README
|
48
|
+
example "sample", desc: "yo yo ma"
|
49
|
+
example "sample --boolean", desc: "yo yo ma"
|
50
|
+
method_option :bumble, aliases: "-b", type: :boolean, desc: "Enable bumblee bee flag", readme: :important
|
51
|
+
def autobots
|
52
|
+
Kernel.puts "Optimus prime requires megatron must be eliminated"
|
53
|
+
if options.bumble
|
54
|
+
Kernel.puts "Bumble bee agrees"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
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
|
data/lib/thor_enhance/tree.rb
CHANGED
@@ -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])
|
data/lib/thor_enhance/version.rb
CHANGED
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 <
|
14
|
-
class ValidationFailed <
|
15
|
-
class RequiredOption <
|
16
|
-
class OptionDeprecated <
|
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
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thor_enhance
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Taylor
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '6'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '6'
|
27
41
|
description: Have you ever wanted your thor commands to tell a story of what they
|
28
42
|
are? Or have you ever wanted to deprecate an option over time easily? ThorEnhance
|
29
43
|
allows to to annote methods and commands in a human readable way
|
@@ -45,7 +59,9 @@ files:
|
|
45
59
|
- README.md
|
46
60
|
- bin/console
|
47
61
|
- bin/setup
|
62
|
+
- bin/thor_enhance
|
48
63
|
- docker-compose.yml
|
64
|
+
- docs/autogenerate/Readme.md
|
49
65
|
- docs/command.md
|
50
66
|
- docs/hooks.md
|
51
67
|
- docs/initialization.md
|
@@ -54,13 +70,31 @@ files:
|
|
54
70
|
- examples/basic_example.md
|
55
71
|
- examples/example_with_subcommand.md
|
56
72
|
- examples/hooks.md
|
73
|
+
- generated_readme/commands/Readme.md
|
74
|
+
- generated_readme/commands/autobots.md
|
75
|
+
- generated_readme/commands/sample.md
|
76
|
+
- generated_readme/commands/sub/Readme.md
|
77
|
+
- generated_readme/commands/sub/innard.md
|
57
78
|
- lib/thor_enhance.rb
|
79
|
+
- lib/thor_enhance/autogenerate.rb
|
80
|
+
- lib/thor_enhance/autogenerate/command.rb
|
81
|
+
- lib/thor_enhance/autogenerate/configuration.rb
|
82
|
+
- lib/thor_enhance/autogenerate/option.rb
|
83
|
+
- lib/thor_enhance/autogenerate/templates/aggregate_options.rb.erb
|
84
|
+
- lib/thor_enhance/autogenerate/templates/class_options.rb.erb
|
85
|
+
- lib/thor_enhance/autogenerate/templates/command.rb.erb
|
86
|
+
- lib/thor_enhance/autogenerate/templates/footer.rb.erb
|
87
|
+
- lib/thor_enhance/autogenerate/templates/option.rb.erb
|
88
|
+
- lib/thor_enhance/autogenerate/templates/root.rb.erb
|
89
|
+
- lib/thor_enhance/autogenerate/validate.rb
|
58
90
|
- lib/thor_enhance/base.rb
|
59
91
|
- lib/thor_enhance/command.rb
|
60
92
|
- lib/thor_enhance/command_hook.rb
|
61
93
|
- lib/thor_enhance/command_method.rb
|
62
94
|
- lib/thor_enhance/configuration.rb
|
63
95
|
- lib/thor_enhance/option.rb
|
96
|
+
- lib/thor_enhance/sample.rb
|
97
|
+
- lib/thor_enhance/thor_auto_generate_inject.rb
|
64
98
|
- lib/thor_enhance/tree.rb
|
65
99
|
- lib/thor_enhance/version.rb
|
66
100
|
- thor_enhance.gemspec
|