thor_enhance 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile +5 -5
- data/Gemfile.lock +6 -14
- data/README.md +28 -0
- data/docs/initialization.md +62 -0
- data/docs/method_option.md +0 -1
- data/examples/basic_example.md +1 -0
- data/examples/example_with_subcommand.md +3 -0
- data/examples/hooks.md +2 -1
- data/lib/thor_enhance/base.rb +35 -0
- data/lib/thor_enhance/command.rb +0 -5
- data/lib/thor_enhance/command_method.rb +104 -12
- data/lib/thor_enhance/configuration.rb +57 -7
- data/lib/thor_enhance/option.rb +15 -9
- data/lib/thor_enhance/version.rb +1 -1
- data/lib/thor_enhance.rb +1 -0
- data/thor_enhance.gemspec +0 -5
- metadata +4 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6298d393beb8a380215c08bc6fa78c97cfd29b3d804159f97b361628b5dd4707
|
4
|
+
data.tar.gz: 15533218c1806a98998f3b66781a9543a22c231f60126c7b98b6a58bc5cf9cd6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a85cdd00c9939a3f0165fdb41950c9578b56d806cd42cfff90a7058e384fcf33d46ca9f2f79eea35524f305a791a57ee1167e38818d7587fe0b5115112945c84
|
7
|
+
data.tar.gz: 38e8c731b8696c6abb82df29fdaabe2468e742ac69b222ac06796b989d0b6de119dfd56af82c6d2cf833522d06c2fdd0802cbb1f2fffce28b6c37c2ce62cb5d3
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
8
|
|
9
|
+
## [0.4.0]
|
10
|
+
- Enable Enhancements on a klass basis
|
11
|
+
- Add Enable/disable blocks for enhancements to allow for onboarding new tasks
|
12
|
+
- Fix required command options
|
13
|
+
|
9
14
|
## [0.3.0]
|
10
15
|
- remove `warn` hook in favor of enriched `deprecate` hook
|
11
16
|
- method name validation on entry
|
data/Gemfile
CHANGED
@@ -5,8 +5,8 @@ source "https://rubygems.org"
|
|
5
5
|
# Specify your gem's dependencies in GEMNAME.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
gem
|
9
|
-
gem
|
10
|
-
gem
|
11
|
-
gem
|
12
|
-
gem
|
8
|
+
gem "pry"
|
9
|
+
gem "pry-byebug"
|
10
|
+
gem "rspec", "~> 3.0"
|
11
|
+
gem "rspec_junit_formatter"
|
12
|
+
gem "simplecov", "~> 0.17.0", require: false
|
data/Gemfile.lock
CHANGED
@@ -9,13 +9,9 @@ GEM
|
|
9
9
|
specs:
|
10
10
|
byebug (11.1.3)
|
11
11
|
coderay (1.1.3)
|
12
|
-
concurrent-ruby (1.2.2)
|
13
12
|
diff-lcs (1.5.0)
|
14
13
|
docile (1.4.0)
|
15
|
-
|
16
|
-
i18n (>= 1.8.11, < 2)
|
17
|
-
i18n (1.14.1)
|
18
|
-
concurrent-ruby (~> 1.0)
|
14
|
+
json (2.6.3)
|
19
15
|
method_source (1.0.0)
|
20
16
|
pry (0.14.2)
|
21
17
|
coderay (~> 1.1)
|
@@ -23,7 +19,6 @@ GEM
|
|
23
19
|
pry-byebug (3.10.1)
|
24
20
|
byebug (~> 11.0)
|
25
21
|
pry (>= 0.13, < 0.15)
|
26
|
-
rake (12.3.3)
|
27
22
|
rspec (3.12.0)
|
28
23
|
rspec-core (~> 3.12.0)
|
29
24
|
rspec-expectations (~> 3.12.0)
|
@@ -39,25 +34,22 @@ GEM
|
|
39
34
|
rspec-support (3.12.1)
|
40
35
|
rspec_junit_formatter (0.6.0)
|
41
36
|
rspec-core (>= 2, < 4, != 2.12.0)
|
42
|
-
simplecov (0.
|
37
|
+
simplecov (0.17.1)
|
43
38
|
docile (~> 1.1)
|
44
|
-
|
45
|
-
|
46
|
-
simplecov-html (0.
|
47
|
-
simplecov_json_formatter (0.1.4)
|
39
|
+
json (>= 1.8, < 3)
|
40
|
+
simplecov-html (~> 0.10.0)
|
41
|
+
simplecov-html (0.10.2)
|
48
42
|
thor (1.3.0)
|
49
43
|
|
50
44
|
PLATFORMS
|
51
45
|
aarch64-linux
|
52
46
|
|
53
47
|
DEPENDENCIES
|
54
|
-
faker
|
55
48
|
pry
|
56
49
|
pry-byebug
|
57
|
-
rake (~> 12.0)
|
58
50
|
rspec (~> 3.0)
|
59
51
|
rspec_junit_formatter
|
60
|
-
simplecov
|
52
|
+
simplecov (~> 0.17.0)
|
61
53
|
thor_enhance!
|
62
54
|
|
63
55
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# ThorEnhance
|
2
2
|
|
3
|
+
`ThorEnhance` enhances thor's capabiltiies. It allows customizable method options and task options.
|
4
|
+
|
5
|
+
Additionally it provides hooks into each method option that allows deprecation dynamically.
|
3
6
|
|
4
7
|
## Installation
|
5
8
|
|
@@ -11,8 +14,33 @@ gem 'thor_enhance'
|
|
11
14
|
|
12
15
|
## Usage
|
13
16
|
|
17
|
+
### Hooks
|
18
|
+
Hooks allow you to deprecate, warn, or do some other custimizable action when a user calls thor with the specific option
|
19
|
+
|
20
|
+
[Hook documentation](docs/hooks.md)
|
21
|
+
[Hook examples](examples/hooks.md)
|
22
|
+
|
23
|
+
### Method option Injection
|
24
|
+
Method option injection allows you to enhance specific commands. When used inconjunction with [ThorEnhance::Tree](docs/tree.md), the added fields to the method options are avaialable in your code with ease.
|
25
|
+
|
26
|
+
[Method option documentation](docs/method_option.md)
|
27
|
+
|
28
|
+
|
29
|
+
### Command option Injection
|
30
|
+
Command option injection is very powerful. This allows add low level documentation in line with the actual code.
|
31
|
+
|
32
|
+
[Command option documentation](docs/command.md)
|
33
|
+
|
34
|
+
### [Future Plans] Automatic ReadMe Generation
|
35
|
+
The beauty of ThorEnhance is that it forces all your documentation to live with the code. As your code changes, the documentation naturally changes with it.
|
36
|
+
|
37
|
+
In the near future, we plan to allow for automatic readme generation based on the enhanced commands provided.
|
38
|
+
|
39
|
+
|
14
40
|
### Initialization
|
15
41
|
|
42
|
+
[Refere to documentation](docs/initialization.md)
|
43
|
+
|
16
44
|
## Contributing
|
17
45
|
|
18
46
|
Bug reports and pull requests are welcome on GitHub at
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Initialize ThorEnhance
|
2
|
+
|
3
|
+
ThorEnhance requires initialization prior to your custom Thor classes loading.
|
4
|
+
|
5
|
+
## How to initialize
|
6
|
+
|
7
|
+
ThorEnhance provides several ways to enforce options on downstream classes.
|
8
|
+
|
9
|
+
### Preferred route
|
10
|
+
When creating the Thor Class, set `thor_enhance_allow!` at the top of the class. This will allow `ThorEnhance` to know that what class to allow and enforce enhancments for
|
11
|
+
```ruby
|
12
|
+
class Enhance < Thor
|
13
|
+
thor_enhance_allow!
|
14
|
+
...
|
15
|
+
end
|
16
|
+
```
|
17
|
+
|
18
|
+
If you have methods are are not ready to abide by the enformence, No worries. Simple use the enable/disable wrappers.
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
class Enhance < Thor
|
22
|
+
thor_enhance_allow!
|
23
|
+
|
24
|
+
disable_thor_enhance! do
|
25
|
+
desc task1 # No enhancements are required
|
26
|
+
def task1;end;
|
27
|
+
|
28
|
+
enable_thor_enhance! do
|
29
|
+
desc task2 # All enhancements are required
|
30
|
+
def task2;end;
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
desc task3 # All enhancements are required
|
35
|
+
def task3;end;
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
|
40
|
+
### Alternate route
|
41
|
+
When initializing the `ThorEnhance` gem in the configuration, add the following code:
|
42
|
+
```ruby
|
43
|
+
ThorEnhance.configure do |c|
|
44
|
+
...
|
45
|
+
c.allowed = :all
|
46
|
+
...
|
47
|
+
end
|
48
|
+
```
|
49
|
+
|
50
|
+
The above code will enforce all Thor classes have required ThorEnhanced enhancements.
|
51
|
+
|
52
|
+
**Caution**: Other gems that utilize thor like `Rake` `RSpec` `Rails` may fail on boot when utilizing the `:all` option. Use with caution
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
[Method Options](method_option.md)
|
57
|
+
[Command Options](command.md)
|
58
|
+
|
59
|
+
## Example
|
60
|
+
|
61
|
+
[Basic Example](../examples/basic_example.md)
|
62
|
+
[Basic Example with Subcommand](../examples/basic_example_with_subcommand.md)
|
data/docs/method_option.md
CHANGED
data/examples/basic_example.md
CHANGED
@@ -28,6 +28,7 @@ require "bundler/setup"
|
|
28
28
|
require "thor_enhance_config"
|
29
29
|
|
30
30
|
class ThorEnhancement < Thor
|
31
|
+
thor_enhance_allow!
|
31
32
|
|
32
33
|
dec "test", "Testing method"
|
33
34
|
example "thor_cli.rb test --value 'This is rad'"
|
@@ -43,6 +44,8 @@ class ThorEnhancement < Thor
|
|
43
44
|
end
|
44
45
|
|
45
46
|
class SubCommand < Thor
|
47
|
+
thor_enhance_allow!
|
48
|
+
|
46
49
|
desc "sub_command", "Command for SubCommand"
|
47
50
|
example "bin/thor sub_command innard -t something -s better"
|
48
51
|
example "bin/thor sub_command innard -s better"
|
data/examples/hooks.md
CHANGED
@@ -33,8 +33,9 @@ require "thor_enhance_config"
|
|
33
33
|
|
34
34
|
VERSION = Gem::Version.new("1.2.3")
|
35
35
|
MAX_VERSION = Gem::Version.new("2.0.0")
|
36
|
-
class ThorEnhancement < Thor
|
37
36
|
|
37
|
+
class ThorEnhancement < Thor
|
38
|
+
thor_enhance_allow!
|
38
39
|
dec "test", "Testing method"
|
39
40
|
example "thor_cli.rb test --value 'This is rad'"
|
40
41
|
example "thor_cli.rb test"
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "thor"
|
4
|
+
|
5
|
+
module ThorEnhance
|
6
|
+
module Base
|
7
|
+
module BuildOption
|
8
|
+
def self.included(base)
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def build_option(name, options, scope)
|
14
|
+
# Method is monkey patched in order to make options aware of the klass that creates it if available
|
15
|
+
# This allows us to enable and disable required options based on the class
|
16
|
+
scope[name] = Thor::Option.new(name, {check_default_type: check_default_type}.merge!(options), self)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module AllowedKlass
|
22
|
+
def self.included(base)
|
23
|
+
base.extend(ClassMethods)
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
def thor_enhance_allow!
|
28
|
+
ThorEnhance.configuration.allowed_klasses << self
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
data/lib/thor_enhance/command.rb
CHANGED
@@ -12,11 +12,6 @@ module ThorEnhance
|
|
12
12
|
define_method(name) { instance_variable_get("@#{name}") }
|
13
13
|
define_method("#{name}=") { instance_variable_set("@#{name}", _1) }
|
14
14
|
end
|
15
|
-
|
16
|
-
# Prepend it so we can call this run method first
|
17
|
-
::Thor::Command.prepend ThorEnhance::CommandHook
|
18
|
-
|
19
|
-
::Thor::Command.include ThorEnhance::Command
|
20
15
|
end
|
21
16
|
end
|
22
17
|
end
|
@@ -8,29 +8,50 @@ module ThorEnhance
|
|
8
8
|
def self.thor_enhance_injection!
|
9
9
|
return false unless ThorEnhance::Configuration.allow_changes?
|
10
10
|
|
11
|
-
# This will dynamically define
|
11
|
+
# This will dynamically define class metohds on the Thor Base class
|
12
12
|
# This allows us to add convenience helpers per method
|
13
|
+
# Allows us to add inline helper class functions for each desc task
|
13
14
|
ThorEnhance.configuration.command_method_enhance.each do |name, object|
|
14
|
-
#
|
15
|
-
#
|
15
|
+
# Define a new method based on the name of each enhanced command method
|
16
|
+
# Method takes care all validation except requirment -- Requirement is done during command initialization
|
16
17
|
ClassMethods.define_method("#{name}") do |input|
|
18
|
+
return nil unless ThorEnhance.configuration.allowed?(self)
|
19
|
+
|
17
20
|
value = instance_variable_get("@#{name}")
|
18
21
|
value ||= {}
|
22
|
+
# Usage is nil when the `desc` has not been defined yet -- Under normal circumstance this will never happen
|
19
23
|
if @usage.nil?
|
20
24
|
raise ArgumentError, "Usage is not set. Please ensure `#{name}` is defined after usage is set"
|
21
25
|
end
|
26
|
+
|
27
|
+
# Required check gets done on command initialization (defined below in ClassMethods)
|
28
|
+
if input.nil?
|
29
|
+
# no op when it is nil
|
30
|
+
elsif !object[:enums].nil?
|
31
|
+
unless object[:enums].include?(input)
|
32
|
+
raise ValidationFailed, "#{@usage} recieved command method `#{name}` with incorrect enum. Received: [#{input}]. Expected: [#{object[:enums]}]"
|
33
|
+
end
|
34
|
+
elsif !object[:allowed_klasses].nil?
|
35
|
+
unless object[:allowed_klasses].include?(value.class)
|
36
|
+
raise ValidationFailed, "#{@usage} recieved command method `#{name}` with incorrect class type. Received: [#{input.class}]. Expected: #{object[:allowed_klasses]}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
22
40
|
if object[:repeatable]
|
23
41
|
value[@usage] ||= []
|
24
42
|
value[@usage] << input
|
25
43
|
else
|
44
|
+
if value[@usage]
|
45
|
+
raise ValidationFailed, "#{@usage} recieved command method `#{name}` with repeated invocations of " \
|
46
|
+
"`#{name}`. Please remove the secondary invocation. Or set `#{name}` as a repeatable command method"
|
47
|
+
end
|
48
|
+
|
26
49
|
value[@usage] = input
|
27
50
|
end
|
28
51
|
|
29
52
|
instance_variable_set("@#{name}", value)
|
30
53
|
end
|
31
54
|
end
|
32
|
-
|
33
|
-
::Thor.include ThorEnhance::CommandMethod
|
34
55
|
end
|
35
56
|
|
36
57
|
def self.included(base)
|
@@ -38,20 +59,91 @@ module ThorEnhance
|
|
38
59
|
end
|
39
60
|
|
40
61
|
module ClassMethods
|
62
|
+
THOR_ENHANCE_ENABLE = :enable
|
63
|
+
THOR_ENHANCE_DISABLE = :disable
|
64
|
+
|
65
|
+
def disable_thor_enhance!(&block)
|
66
|
+
__thor_enhance_access(type: THOR_ENHANCE_DISABLE, &block)
|
67
|
+
end
|
68
|
+
|
69
|
+
def enable_thor_enhance!(&block)
|
70
|
+
__thor_enhance_access(type: THOR_ENHANCE_ENABLE, &block)
|
71
|
+
end
|
41
72
|
|
42
73
|
# Call all things super for it (super in thor also calls super as well)
|
43
|
-
# If the command exists, then
|
74
|
+
# If the command exists, then set the instance variable
|
44
75
|
def method_added(meth)
|
45
|
-
super(meth)
|
76
|
+
value = super(meth)
|
46
77
|
|
47
|
-
# Skip if the
|
78
|
+
# Skip if the command does not exist -- Super creates the command
|
48
79
|
if command = all_commands[meth.to_s]
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
80
|
+
|
81
|
+
if ThorEnhance.configuration.allowed?(self)
|
82
|
+
ThorEnhance.configuration.command_method_enhance.each do |name, object|
|
83
|
+
|
84
|
+
instance_variable = instance_variable_get("@#{name}")
|
85
|
+
# instance variable was correctly assigned and exists as a hash
|
86
|
+
if Hash === instance_variable
|
87
|
+
# Expected key exists in the hash
|
88
|
+
# This key already passed validation for type and enum
|
89
|
+
# Set it and move on
|
90
|
+
if instance_variable.key?(meth.to_s)
|
91
|
+
value = instance_variable[meth.to_s]
|
92
|
+
command.send("#{name}=", value)
|
93
|
+
next
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# At this point, the key command method was never invoked on for the `name` thor task
|
98
|
+
# The value is nil/unset
|
99
|
+
|
100
|
+
# If we have disabled required operations, go ahead and skip this
|
101
|
+
next if ::Thor.__thor_enhance_definition == ThorEnhance::CommandMethod::ClassMethods::THOR_ENHANCE_DISABLE
|
102
|
+
|
103
|
+
# Skip if the expected command method was not required
|
104
|
+
next unless object[:required]
|
105
|
+
|
106
|
+
# Skip if the method is part of the ignore list
|
107
|
+
next if ThorEnhance::Tree.ignore_commands.include?(meth.to_s)
|
108
|
+
|
109
|
+
# At this point, the command method is missing, we are not in disable mode, and the command method was required
|
110
|
+
# raise all hell
|
111
|
+
raise ThorEnhance::RequiredOption, "`#{meth}` does not have required command method #{name} invoked. " \
|
112
|
+
"Ensure it is added after the `desc` task is invoked"
|
113
|
+
end
|
53
114
|
end
|
54
115
|
end
|
116
|
+
|
117
|
+
value
|
118
|
+
end
|
119
|
+
|
120
|
+
def __thor_enhance_definition
|
121
|
+
@__thor_enhance_definition
|
122
|
+
end
|
123
|
+
|
124
|
+
def __thor_enhance_definition=(value)
|
125
|
+
@__thor_enhance_definition = value
|
126
|
+
end
|
127
|
+
|
128
|
+
def __thor_enhance_definition_stack
|
129
|
+
@__thor_enhance_definition_stack ||= []
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def __thor_enhance_access(type:, &block)
|
135
|
+
raise ArgumentError, "Expected to receive block. No block given" unless block_given?
|
136
|
+
|
137
|
+
# capture original value. This allows us to do nested enable/disables
|
138
|
+
::Thor.__thor_enhance_definition_stack << ::Thor.__thor_enhance_definition.dup
|
139
|
+
::Thor.__thor_enhance_definition = type
|
140
|
+
|
141
|
+
yield
|
142
|
+
|
143
|
+
nil
|
144
|
+
ensure
|
145
|
+
# Return the state to the most recently set stack
|
146
|
+
::Thor.__thor_enhance_definition = ::Thor.__thor_enhance_definition_stack.pop
|
55
147
|
end
|
56
148
|
end
|
57
149
|
end
|
@@ -4,15 +4,13 @@ require "thor"
|
|
4
4
|
|
5
5
|
module ThorEnhance
|
6
6
|
class Configuration
|
7
|
-
|
8
|
-
# Order is important -- Ensure deoreacte is first
|
9
7
|
HOOKERS = [DEPRECATE = :deprecate, HOOK = :hook]
|
8
|
+
ALLOWED_VALUES = [DEFAULT_ALLOWED = nil, ALLOW_ALL = :all]
|
10
9
|
|
11
10
|
class << self
|
12
|
-
attr_accessor :allow_changes
|
13
|
-
|
14
11
|
def allow_changes?(raise_error: true)
|
15
|
-
return true
|
12
|
+
return true unless defined?(@@allow_changes)
|
13
|
+
return true if @@allow_changes.nil?
|
16
14
|
|
17
15
|
if raise_error
|
18
16
|
raise BaseError, "Configuration changes are halted. Unable to change ThorEnhancements"
|
@@ -22,7 +20,7 @@ module ThorEnhance
|
|
22
20
|
end
|
23
21
|
|
24
22
|
def disallow_changes!
|
25
|
-
allow_changes =
|
23
|
+
@@allow_changes = :prevent
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
@@ -32,6 +30,31 @@ module ThorEnhance
|
|
32
30
|
ThorEnhance::Option.thor_enhance_injection!
|
33
31
|
ThorEnhance::Command.thor_enhance_injection!
|
34
32
|
ThorEnhance::CommandMethod.thor_enhance_injection!
|
33
|
+
|
34
|
+
############
|
35
|
+
# Commands #
|
36
|
+
############
|
37
|
+
# Prepend it so we can call our run method first
|
38
|
+
::Thor::Command.prepend ThorEnhance::CommandHook
|
39
|
+
::Thor::Command.include ThorEnhance::Command
|
40
|
+
|
41
|
+
##################
|
42
|
+
# Command Method #
|
43
|
+
##################
|
44
|
+
::Thor.include ThorEnhance::CommandMethod
|
45
|
+
|
46
|
+
###########
|
47
|
+
# Options #
|
48
|
+
###########
|
49
|
+
# Must be prepended because we change the arity of the initializer here
|
50
|
+
::Thor::Option.prepend ThorEnhance::Option
|
51
|
+
::Thor.include ThorEnhance::Base::BuildOption
|
52
|
+
|
53
|
+
####################
|
54
|
+
# Other Injections #
|
55
|
+
####################
|
56
|
+
::Thor.include ThorEnhance::Base::AllowedKlass
|
57
|
+
|
35
58
|
self.class.disallow_changes!
|
36
59
|
end
|
37
60
|
|
@@ -39,6 +62,28 @@ module ThorEnhance
|
|
39
62
|
@command_method_enhance ||= {}
|
40
63
|
end
|
41
64
|
|
65
|
+
def allowed_klasses
|
66
|
+
@klass_procs ||= []
|
67
|
+
end
|
68
|
+
|
69
|
+
def allowed
|
70
|
+
@allowed ||= DEFAULT_ALLOWED
|
71
|
+
end
|
72
|
+
|
73
|
+
def allowed=(value)
|
74
|
+
raise ArgumentError, "Unexpected value for `allowed =`. Given: #{value}. Expected one of #{ALLOWED_VALUES}" unless ALLOWED_VALUES.include?(value)
|
75
|
+
|
76
|
+
@allowed = value
|
77
|
+
end
|
78
|
+
|
79
|
+
def allowed?(klass)
|
80
|
+
return true if allowed == ALLOW_ALL
|
81
|
+
return true if allowed_klasses.include?(klass)
|
82
|
+
|
83
|
+
# At this point, allowed is false and not an includable klass -- dont allow
|
84
|
+
false
|
85
|
+
end
|
86
|
+
|
42
87
|
def option_enhance
|
43
88
|
@option_enhance ||= {
|
44
89
|
DEPRECATE => { allowed_klasses: [Proc], behavior: :request, required: false },
|
@@ -83,7 +128,12 @@ module ThorEnhance
|
|
83
128
|
|
84
129
|
# if enums is present and not an array
|
85
130
|
if !enums.nil? && !enums.is_a?(Array)
|
86
|
-
raise ArgumentError, "Recieved
|
131
|
+
raise ArgumentError, "Recieved enums with #{enums}. When present, it is expected to be an Array"
|
132
|
+
end
|
133
|
+
|
134
|
+
# if allowed_klasses is present and not an array
|
135
|
+
if !allowed_klasses.nil? && !allowed_klasses.is_a?(Array)
|
136
|
+
raise ArgumentError, "Recieved allowed_klasses with #{allowed_klasses}. When present, it is expected to be an Array"
|
87
137
|
end
|
88
138
|
|
89
139
|
storage[name.to_sym] = { allowed_klasses: allowed_klasses, enums: enums, required: required, repeatable: repeatable }
|
data/lib/thor_enhance/option.rb
CHANGED
@@ -11,24 +11,30 @@ module ThorEnhance
|
|
11
11
|
ThorEnhance.configuration.option_enhance.each do |name, object|
|
12
12
|
define_method(name) { instance_variable_get("@#{name}") }
|
13
13
|
end
|
14
|
-
|
15
|
-
::Thor::Option.include ThorEnhance::Option
|
16
14
|
end
|
17
15
|
|
18
|
-
|
19
|
-
|
16
|
+
# Monkey patched initializer
|
17
|
+
# Thor Option initializer only takes (name, options) as arguments
|
18
|
+
# Thor::Option.new is only called from `build_option` which gets monkey patched in thor_enhance/base
|
19
|
+
def initialize(name, options = {}, klass = nil)
|
20
|
+
super(name, options)
|
20
21
|
|
21
|
-
thor_enhance_definitions(options)
|
22
|
+
thor_enhance_definitions(options, klass)
|
22
23
|
end
|
23
24
|
|
24
|
-
def thor_enhance_definitions(options)
|
25
|
+
def thor_enhance_definitions(options, klass)
|
26
|
+
return nil unless ThorEnhance.configuration.allowed?(klass)
|
27
|
+
|
25
28
|
ThorEnhance.configuration.option_enhance.each do |name, object|
|
26
|
-
if
|
27
|
-
|
29
|
+
# When disabled, we do not do the required check, if present, it is still required to be a valid option otherwise
|
30
|
+
unless ::Thor.__thor_enhance_definition == ThorEnhance::CommandMethod::ClassMethods::THOR_ENHANCE_DISABLE
|
31
|
+
if options[name.to_sym].nil? && object[:required]
|
32
|
+
raise RequiredOption, "#{@name} does not have required option #{name}. Please add it to the option"
|
33
|
+
end
|
28
34
|
end
|
29
35
|
|
30
36
|
value = options[name.to_sym]
|
31
|
-
if value.nil?
|
37
|
+
if value.nil? # This can be nil here because we have already done a required check
|
32
38
|
# no op when it is nil and not required
|
33
39
|
elsif !object[:enums].nil?
|
34
40
|
unless object[:enums].include?(value)
|
data/lib/thor_enhance/version.rb
CHANGED
data/lib/thor_enhance.rb
CHANGED
data/thor_enhance.gemspec
CHANGED
@@ -30,9 +30,4 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.require_paths = ["lib"]
|
31
31
|
|
32
32
|
spec.add_dependency "thor", "~> 1.3"
|
33
|
-
|
34
|
-
spec.add_development_dependency "pry-byebug"
|
35
|
-
spec.add_development_dependency "rake", "~> 12.0"
|
36
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
37
|
-
spec.add_development_dependency "simplecov", "~> 0.17.0"
|
38
33
|
end
|
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.4.0
|
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-
|
11
|
+
date: 2023-11-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -24,62 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: pry-byebug
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rake
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '12.0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '12.0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rspec
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '3.0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '3.0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: simplecov
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: 0.17.0
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 0.17.0
|
83
27
|
description: Have you ever wanted your thor commands to tell a story of what they
|
84
28
|
are? Or have you ever wanted to deprecate an option over time easily? ThorEnhance
|
85
29
|
allows to to annote methods and commands in a human readable way
|
@@ -104,12 +48,14 @@ files:
|
|
104
48
|
- docker-compose.yml
|
105
49
|
- docs/command.md
|
106
50
|
- docs/hooks.md
|
51
|
+
- docs/initialization.md
|
107
52
|
- docs/method_option.md
|
108
53
|
- docs/tree.md
|
109
54
|
- examples/basic_example.md
|
110
55
|
- examples/example_with_subcommand.md
|
111
56
|
- examples/hooks.md
|
112
57
|
- lib/thor_enhance.rb
|
58
|
+
- lib/thor_enhance/base.rb
|
113
59
|
- lib/thor_enhance/command.rb
|
114
60
|
- lib/thor_enhance/command_hook.rb
|
115
61
|
- lib/thor_enhance/command_method.rb
|