thor_enhance 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile +6 -5
- data/Gemfile.lock +27 -7
- data/README.md +30 -0
- data/bin/thor_enhance +22 -0
- data/docs/autogenerate/Readme.md +152 -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/autogenerate/command.rb +240 -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 +12 -0
- data/lib/thor_enhance/autogenerate/templates/command.rb.erb +49 -0
- data/lib/thor_enhance/autogenerate/templates/footer.rb.erb +3 -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 +78 -0
- data/lib/thor_enhance/base.rb +35 -0
- data/lib/thor_enhance/command.rb +0 -5
- data/lib/thor_enhance/command_method.rb +139 -17
- data/lib/thor_enhance/configuration.rb +104 -11
- data/lib/thor_enhance/option.rb +15 -11
- data/lib/thor_enhance/sample.rb +40 -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 +13 -4
- data/thor_enhance.gemspec +1 -5
- metadata +22 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8bd2c2b70158e1ab7a387dddfefde9c88c27c1809278ee05608dfca0f7de6484
|
4
|
+
data.tar.gz: eb3ed82f1b26e2239130ff9383971c7167975ac685815e08d48de42cf7eea74c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52f31daa639f2db023690b1c5b67ae261f0de382a1e03c9ad0a4801162e2ddef4127a942d8b57ad9a2dd72392a17953e63ad9ebfa913bf3e6a70d753bc668617
|
7
|
+
data.tar.gz: b504a6e6087671967755adf851386e0ad499d568a9f66ae561b2aee44b77a2b84c882ace9656136a10f2ed91ce77101023ee8e1ee9b2136d79f02dc428c1e63b
|
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,9 @@ 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", require: false
|
13
|
+
gem "ice_age"
|
data/Gemfile.lock
CHANGED
@@ -1,29 +1,45 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
thor_enhance (0.
|
4
|
+
thor_enhance (0.5.0)
|
5
|
+
activesupport (>= 6)
|
5
6
|
thor (~> 1.3)
|
6
7
|
|
7
8
|
GEM
|
8
9
|
remote: https://rubygems.org/
|
9
10
|
specs:
|
11
|
+
activesupport (7.1.2)
|
12
|
+
base64
|
13
|
+
bigdecimal
|
14
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
15
|
+
connection_pool (>= 2.2.5)
|
16
|
+
drb
|
17
|
+
i18n (>= 1.6, < 2)
|
18
|
+
minitest (>= 5.1)
|
19
|
+
mutex_m
|
20
|
+
tzinfo (~> 2.0)
|
21
|
+
base64 (0.2.0)
|
22
|
+
bigdecimal (3.1.4)
|
10
23
|
byebug (11.1.3)
|
11
24
|
coderay (1.1.3)
|
12
25
|
concurrent-ruby (1.2.2)
|
26
|
+
connection_pool (2.4.1)
|
13
27
|
diff-lcs (1.5.0)
|
14
28
|
docile (1.4.0)
|
15
|
-
|
16
|
-
|
29
|
+
drb (2.2.0)
|
30
|
+
ruby2_keywords
|
17
31
|
i18n (1.14.1)
|
18
32
|
concurrent-ruby (~> 1.0)
|
33
|
+
ice_age (0.2.0)
|
19
34
|
method_source (1.0.0)
|
35
|
+
minitest (5.20.0)
|
36
|
+
mutex_m (0.2.0)
|
20
37
|
pry (0.14.2)
|
21
38
|
coderay (~> 1.1)
|
22
39
|
method_source (~> 1.0)
|
23
40
|
pry-byebug (3.10.1)
|
24
41
|
byebug (~> 11.0)
|
25
42
|
pry (>= 0.13, < 0.15)
|
26
|
-
rake (12.3.3)
|
27
43
|
rspec (3.12.0)
|
28
44
|
rspec-core (~> 3.12.0)
|
29
45
|
rspec-expectations (~> 3.12.0)
|
@@ -39,6 +55,7 @@ GEM
|
|
39
55
|
rspec-support (3.12.1)
|
40
56
|
rspec_junit_formatter (0.6.0)
|
41
57
|
rspec-core (>= 2, < 4, != 2.12.0)
|
58
|
+
ruby2_keywords (0.0.5)
|
42
59
|
simplecov (0.22.0)
|
43
60
|
docile (~> 1.1)
|
44
61
|
simplecov-html (~> 0.11)
|
@@ -46,19 +63,22 @@ GEM
|
|
46
63
|
simplecov-html (0.12.3)
|
47
64
|
simplecov_json_formatter (0.1.4)
|
48
65
|
thor (1.3.0)
|
66
|
+
tzinfo (2.0.6)
|
67
|
+
concurrent-ruby (~> 1.0)
|
49
68
|
|
50
69
|
PLATFORMS
|
51
70
|
aarch64-linux
|
71
|
+
arm64-darwin-22
|
72
|
+
arm64-darwin-23
|
52
73
|
|
53
74
|
DEPENDENCIES
|
54
|
-
|
75
|
+
ice_age
|
55
76
|
pry
|
56
77
|
pry-byebug
|
57
|
-
rake (~> 12.0)
|
58
78
|
rspec (~> 3.0)
|
59
79
|
rspec_junit_formatter
|
60
80
|
simplecov
|
61
81
|
thor_enhance!
|
62
82
|
|
63
83
|
BUNDLED WITH
|
64
|
-
2.
|
84
|
+
2.5.1
|
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,35 @@ 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
|
+
### 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
|
+
ThorEnhance can automatically generate your code bases Readme for you.
|
38
|
+
|
39
|
+
[Autogenerate Readme](docs/autogenerate/Readme.md)
|
40
|
+
|
41
|
+
|
14
42
|
### Initialization
|
15
43
|
|
44
|
+
[Refere to documentation](docs/initialization.md)
|
45
|
+
|
16
46
|
## Contributing
|
17
47
|
|
18
48
|
Bug reports and pull requests are welcome on GitHub at
|
data/bin/thor_enhance
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
require "bundler/setup"
|
5
|
+
require "pry"
|
6
|
+
|
7
|
+
require "thor_enhance"
|
8
|
+
|
9
|
+
ThorEnhance.configure do |c|
|
10
|
+
c.readme_enhance!(required: true) do |r|
|
11
|
+
r.custom_header(:how_does_this_help, repeatable: true)
|
12
|
+
r.custom_header(:when_should_i_use_this, required: true, question: true)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
require "thor_enhance/sample"
|
17
|
+
|
18
|
+
begin
|
19
|
+
ThorEnhance::Sample.start
|
20
|
+
rescue Interrupt => e
|
21
|
+
$stdout.puts "\nThanks for using Better Dependabot 👋\n"
|
22
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# Autogenerate Readme
|
2
|
+
|
3
|
+
A core component of `ThorEnhance` is the ability to autogenerate Readmes for your thor commands. This allows the code and the readme to be in lockstep without the worry of the Readme getting out of date.
|
4
|
+
|
5
|
+
## How does this work?
|
6
|
+
By building on top of [Command Method Injection](../command.md) and [Method Option Injection](../method_option.md), ThorEnhance allows Readme's to get autogenerated based on the description of the command and the methods.
|
7
|
+
|
8
|
+
## How to use
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
# thor_enhance_config.rb
|
12
|
+
ThorEnhance.configure do |c|
|
13
|
+
c.readme_enhance!
|
14
|
+
end
|
15
|
+
```
|
16
|
+
|
17
|
+
## Default capabilities
|
18
|
+
|
19
|
+
### Example Command Option
|
20
|
+
When `readme_enhance` is enabled, by default the `example`ew command option is available on for every command.
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
desc "sample", "This Sample command"
|
24
|
+
example "sample", desc: "Basic invocation of the useless command"
|
25
|
+
example "sample --boolean", desc: "Basic invocation of the useless command with a flag"
|
26
|
+
method_option :boolean, type: :boolean, desc: "Just a normal boolean"
|
27
|
+
def sample;end;
|
28
|
+
```
|
29
|
+
|
30
|
+
The example command takes signature expects:
|
31
|
+
```ruby
|
32
|
+
# remove basename and any submodules from command execution
|
33
|
+
example "command execution", desc: "Description of what the command does"
|
34
|
+
```
|
35
|
+
|
36
|
+
By default, `example` is not required for every command. To make example required for every command, modify the configuration to
|
37
|
+
```ruby
|
38
|
+
ThorEnhance.configure do |c|
|
39
|
+
c.readme_enhance! do |r|
|
40
|
+
r.example(required: true)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
### Header Command Option
|
46
|
+
When `readme_enhance` is enabled, by default a the `header` option is available on every command.
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
desc "sample", "This Sample command"
|
50
|
+
header name: "When should I use this?", desc: "To add additional commentary to your command"
|
51
|
+
header name: "I can have many headers", desc: "Headers can be different per command"
|
52
|
+
def sample;end;
|
53
|
+
```
|
54
|
+
|
55
|
+
By default, `header` is not required for every command. It is an additive command that is customizable per command
|
56
|
+
|
57
|
+
### Title Command Option
|
58
|
+
When `readme_enhance` is enabled, by default a the `title` option is available on every command.
|
59
|
+
|
60
|
+
This optional command option gets used for the Readme title. Otherwise, the method name gets used
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
desc "sample", "This Sample command"
|
64
|
+
title ""
|
65
|
+
def sample;end;
|
66
|
+
```
|
67
|
+
|
68
|
+
By default, `title` is not required for every command. To make example required for every command, modify the configuration to
|
69
|
+
```ruby
|
70
|
+
ThorEnhance.configure do |c|
|
71
|
+
c.readme_enhance! do |r|
|
72
|
+
r.title(required: true)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
### Readme Method Option
|
78
|
+
|
79
|
+
When `readme_enhance` is enabled, by default `readme` flag is available on every option.
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
desc "sample", "This Sample command"
|
83
|
+
method_option :boolean, type: :boolean, desc: "Just a normal boolean", readme: :important
|
84
|
+
def sample;end;
|
85
|
+
```
|
86
|
+
|
87
|
+
The Default options for the value of `:readme` are [`:important`, `:advanced`, `:skip`].
|
88
|
+
|
89
|
+
All methods flagged with `:important` will show up higher in the readme. Anything labled with `:skip`, will not show up on the readme.
|
90
|
+
|
91
|
+
|
92
|
+
By default, `readme` is not required for every method.
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
# This will require all method_options to have the `readme` flag
|
96
|
+
ThorEnhance.configure do |c|
|
97
|
+
c.readme_enhance! do |r|
|
98
|
+
r.readme(required: true)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
```
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
# This will options without the `readme` flag to a group of :empty on the readme
|
105
|
+
ThorEnhance.configure do |c|
|
106
|
+
c.readme_enhance! do |r|
|
107
|
+
r.readme(empty_group: :empty)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
# Setting enums will override the default readme groups
|
114
|
+
# Only these values will be allowed as readme values
|
115
|
+
# The order of the arry determines the order the group will be ouputted in the Readme
|
116
|
+
ThorEnhance.configure do |c|
|
117
|
+
c.readme_enhance! do |r|
|
118
|
+
r.readme(enums: ["cool", :features, "live", "here".to_sym])
|
119
|
+
end
|
120
|
+
end
|
121
|
+
```
|
122
|
+
|
123
|
+
### Custom Header Command Option
|
124
|
+
|
125
|
+
Custom Headers must get manually added to the configuration.
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
ThorEnhance.configure do |c|
|
129
|
+
c.readme_enhance! do |r|
|
130
|
+
# how_does_this_help will be required on every command
|
131
|
+
r.custom_header("how_does_this_help", required: true)
|
132
|
+
# when_should_i_use_this is a repeatable command
|
133
|
+
r.custom_header("when_should_i_use_this", repeatable: true)
|
134
|
+
# is_this_important is now a question. On the readme, `?` gets appened to the header
|
135
|
+
r.custom_header("is_this_important", question: true)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
```
|
139
|
+
|
140
|
+
The configuration enumerated above allows the ability to do the following:
|
141
|
+
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
desc "sample", "This Sample command"
|
145
|
+
how_does_this_help "This command will help enable additional configuration for each command. This will get appended to the Readme in the order it appears as originally configured", tag: "h4"
|
146
|
+
when_should_i_use_this "Use this whenever you like"
|
147
|
+
when_should_i_use_this "Or you dont ever have to use this", tag: "h2"
|
148
|
+
is_this_important "Yes this is imporant. It even has a custom tag", tag: 1
|
149
|
+
def sample;end;
|
150
|
+
```
|
151
|
+
|
152
|
+
Take special not of the `tag` option on the custom header. By default, header will output as an <h2> header tag. To change, this you can use numeric `1|2|3|4` or you can use string `h[1234]`
|
@@ -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,240 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/string/inflections"
|
4
|
+
require "thor_enhance/autogenerate/option"
|
5
|
+
require "erb"
|
6
|
+
|
7
|
+
module ThorEnhance
|
8
|
+
module Autogenerate
|
9
|
+
class Command
|
10
|
+
COMMAND_ERB = "#{File.dirname(__FILE__)}/templates/command.rb.erb"
|
11
|
+
COMMAND_TEMPLATE = ERB.new(File.read(COMMAND_ERB))
|
12
|
+
|
13
|
+
AGGREGATE_OPTIONS_ERB = "#{File.dirname(__FILE__)}/templates/aggregate_options.rb.erb"
|
14
|
+
AGGREGATE_OPTIONS_TEMPLATE = ERB.new(File.read(AGGREGATE_OPTIONS_ERB))
|
15
|
+
|
16
|
+
FOOTER_ERB = "#{File.dirname(__FILE__)}/templates/footer.rb.erb"
|
17
|
+
FOOTER_TEMPLATE = ERB.new(File.read(FOOTER_ERB))
|
18
|
+
|
19
|
+
attr_reader :leaf, :name, :basename, :child_commands, :parent
|
20
|
+
|
21
|
+
def initialize(leaf:, name:, basename:, parent: nil)
|
22
|
+
@leaf = leaf
|
23
|
+
@name = name
|
24
|
+
@basename = basename
|
25
|
+
@child_commands = []
|
26
|
+
@parent = parent
|
27
|
+
initialize_children!
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize_children!
|
31
|
+
return unless children?
|
32
|
+
|
33
|
+
@child_commands = leaf.children.map do |name, child_leaf|
|
34
|
+
self.class.new(leaf: child_leaf, name: name, basename: basename, parent: self)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def method_options
|
39
|
+
@method_options ||= begin
|
40
|
+
_options = options.map { |name, option| Option.new(name: name, option: option) }
|
41
|
+
|
42
|
+
_options.group_by { _1.readme_type }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def command_erb
|
47
|
+
@command_erb ||= begin
|
48
|
+
params = {
|
49
|
+
basename_string: basename_string,
|
50
|
+
children_descriptors: children_descriptors,
|
51
|
+
command: command,
|
52
|
+
custom_headers: custom_headers,
|
53
|
+
description: description,
|
54
|
+
drawn_out_examples: drawn_out_examples,
|
55
|
+
footer_erb: footer_erb,
|
56
|
+
headers: headers,
|
57
|
+
method_options_erb: method_options_erb,
|
58
|
+
parent_basename_string: parent_basename_string,
|
59
|
+
title: title,
|
60
|
+
}
|
61
|
+
COMMAND_TEMPLATE.result_with_hash(params)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def footer_erb
|
66
|
+
@footer_erb ||= begin
|
67
|
+
regenerate_single_command = "#{parent_basename_string} thor_enhance_autogenerate --command #{command.usage} --apply"
|
68
|
+
regenerate_thor_command = "#{basename} thor_enhance_autogenerate --apply"
|
69
|
+
FOOTER_TEMPLATE.result_with_hash({ regenerate_single_command: regenerate_single_command, regenerate_thor_command: regenerate_thor_command })
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def drawn_out_examples(with_desc: true)
|
74
|
+
case command.example
|
75
|
+
when nil
|
76
|
+
when Array
|
77
|
+
command.example.map do |example|
|
78
|
+
value = []
|
79
|
+
value << "# #{example[:arguments][:kwargs][:desc]}" if with_desc
|
80
|
+
value << "#{parent_basename_string} #{example[:input]}"
|
81
|
+
value.join("\n")
|
82
|
+
end
|
83
|
+
else
|
84
|
+
value = []
|
85
|
+
value << "# #{example[:arguments][:kwargs][:desc]}" if with_desc
|
86
|
+
value << "#{parent_basename_string} #{example[:input]}"
|
87
|
+
[value.join("\n")]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def method_options_erb
|
92
|
+
@method_options_erb ||= AGGREGATE_OPTIONS_TEMPLATE.result_with_hash({ method_options: method_options })
|
93
|
+
end
|
94
|
+
|
95
|
+
def basename_string
|
96
|
+
"#{parent_basename_string} #{command.usage}"
|
97
|
+
end
|
98
|
+
|
99
|
+
def parent_basename_string
|
100
|
+
parent_names = [basename]
|
101
|
+
temp_leaf = leaf
|
102
|
+
while parent = temp_leaf.parent
|
103
|
+
temp_leaf = parent
|
104
|
+
parent_names << parent.command.usage
|
105
|
+
end
|
106
|
+
parent_names.join(" ")
|
107
|
+
end
|
108
|
+
|
109
|
+
def parent_root
|
110
|
+
if parent
|
111
|
+
# Remove the last index of parent because that will be the Readme.md file
|
112
|
+
# We just want the directory of the parent file
|
113
|
+
parent.relative_readme_path[0..-2]
|
114
|
+
else
|
115
|
+
[]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def relative_readme_path
|
120
|
+
if children?
|
121
|
+
# If children exist, this is a subcommand and needs to be a root ReadMe
|
122
|
+
[*parent_root, name, "Readme.md"]
|
123
|
+
else
|
124
|
+
[*parent_root, "#{name}.md"]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# this only returns children and its children
|
129
|
+
# Call this on top most parent to retreive family tree for subcommands
|
130
|
+
def flatten_children
|
131
|
+
return [] if child_commands.empty?
|
132
|
+
|
133
|
+
child_commands.map do |child|
|
134
|
+
[child, child.flatten_children]
|
135
|
+
end.flatten
|
136
|
+
end
|
137
|
+
|
138
|
+
def save_self!(root:, apply:)
|
139
|
+
absolute_path = "#{root}/#{relative_readme_path.join("/")}"
|
140
|
+
pathname = Pathname.new(absolute_path)
|
141
|
+
FileUtils.mkdir_p(pathname.dirname)
|
142
|
+
if File.exist?(absolute_path)
|
143
|
+
content = File.read(absolute_path)
|
144
|
+
diff = command_erb == content ? :same : :overwite
|
145
|
+
else
|
146
|
+
diff = :new
|
147
|
+
end
|
148
|
+
|
149
|
+
if apply
|
150
|
+
File.write(absolute_path, command_erb)
|
151
|
+
end
|
152
|
+
|
153
|
+
{ path: absolute_path, diff: diff, apply: apply, self_for_root: self_for_root }
|
154
|
+
end
|
155
|
+
|
156
|
+
def description
|
157
|
+
command.long_description || command.description
|
158
|
+
end
|
159
|
+
|
160
|
+
def title
|
161
|
+
command.title || command.usage
|
162
|
+
end
|
163
|
+
|
164
|
+
def self_for_root
|
165
|
+
params_for_child(self)
|
166
|
+
end
|
167
|
+
|
168
|
+
private
|
169
|
+
|
170
|
+
def custom_headers
|
171
|
+
ThorEnhance.configuration.autogenerated_config.custom_headers.map do |header|
|
172
|
+
next unless command.respond_to?(header.to_sym)
|
173
|
+
|
174
|
+
header_value = command.public_send(header.to_sym)
|
175
|
+
next if header_value.nil?
|
176
|
+
case header_value
|
177
|
+
when Array
|
178
|
+
header_value.map { header_string(_1, header) }
|
179
|
+
else
|
180
|
+
header_string(header_value, header)
|
181
|
+
end
|
182
|
+
|
183
|
+
end.compact.flatten.join("\n\n")
|
184
|
+
end
|
185
|
+
|
186
|
+
def header_string(header_value, header)
|
187
|
+
header_name = header.to_s.gsub(/[_-]/, " ").titlecase
|
188
|
+
header_name += "?" if ThorEnhance.configuration.autogenerated_config.question_headers.include?(header)
|
189
|
+
header_tag = decipher_header_tag(header_value[:arguments][:kwargs][:tag])
|
190
|
+
header_input = header_value[:input]
|
191
|
+
"#{header_tag} #{header_name}\n\n#{header_input}"
|
192
|
+
end
|
193
|
+
|
194
|
+
def decipher_header_tag(input)
|
195
|
+
case input
|
196
|
+
when String
|
197
|
+
begin
|
198
|
+
input[0..1][-1].to_i.to_s == input[0..1][-1] ? "#" * input[0..1][-1].to_i : "##"
|
199
|
+
rescue
|
200
|
+
"##"
|
201
|
+
end
|
202
|
+
when Integer
|
203
|
+
"#" * input
|
204
|
+
else
|
205
|
+
"##"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def children_descriptors
|
210
|
+
child_commands.map { params_for_child(_1) }
|
211
|
+
end
|
212
|
+
|
213
|
+
def params_for_child(child)
|
214
|
+
{
|
215
|
+
title: child.title,
|
216
|
+
link: child.relative_readme_path[-1],
|
217
|
+
description: child.description,
|
218
|
+
basename_string: child.basename_string,
|
219
|
+
examples: child.drawn_out_examples(with_desc: false) || [],
|
220
|
+
}
|
221
|
+
end
|
222
|
+
|
223
|
+
def headers
|
224
|
+
(command.header || []).map { _1[:arguments][:kwargs] }
|
225
|
+
end
|
226
|
+
|
227
|
+
def children?
|
228
|
+
leaf.children?
|
229
|
+
end
|
230
|
+
|
231
|
+
def command
|
232
|
+
leaf.command
|
233
|
+
end
|
234
|
+
|
235
|
+
def options
|
236
|
+
command.options
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|