bashly 1.0.7 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -1
- data/lib/bashly/cli.rb +1 -0
- data/lib/bashly/commands/completions.rb +1 -1
- data/lib/bashly/commands/render.rb +103 -0
- data/lib/bashly/concerns/validation_helpers.rb +1 -1
- data/lib/bashly/config.rb +0 -2
- data/lib/bashly/extensions/string.rb +17 -1
- data/lib/bashly/extensions/yaml.rb +4 -1
- data/lib/bashly/libraries/config/config.sh +74 -94
- data/lib/bashly/libraries/ini/ini.sh +110 -0
- data/lib/bashly/libraries/libraries.yml +40 -1
- data/lib/bashly/libraries/render/mandoc/README.md +45 -0
- data/lib/bashly/libraries/render/mandoc/mandoc.gtx +196 -0
- data/lib/bashly/libraries/render/mandoc/render.rb +34 -0
- data/lib/bashly/libraries/render/mandoc/summary.txt +1 -0
- data/lib/bashly/libraries/render/markdown/README.md +42 -0
- data/lib/bashly/libraries/render/markdown/markdown.gtx +186 -0
- data/lib/bashly/libraries/render/markdown/render.rb +23 -0
- data/lib/bashly/libraries/render/markdown/summary.txt +1 -0
- data/lib/bashly/refinements/compose_refinements.rb +0 -2
- data/lib/bashly/render_context.rb +30 -0
- data/lib/bashly/render_source.rb +71 -0
- data/lib/bashly/script/base.rb +2 -1
- data/lib/bashly/script/command.rb +17 -0
- data/lib/bashly/version.rb +1 -1
- data/lib/bashly/views/command/dependencies_filter.gtx +1 -1
- data/lib/bashly/views/command/footer.gtx +1 -1
- data/lib/bashly/views/command/parse_requirements_while.gtx +1 -1
- data/lib/bashly/views/command/usage.gtx +2 -2
- data/lib/bashly/views/command/usage_commands.gtx +2 -2
- data/lib/bashly.rb +56 -11
- metadata +41 -9
@@ -0,0 +1,196 @@
|
|
1
|
+
# Reference: https://linux.die.net/man/5/pandoc_markdown
|
2
|
+
|
3
|
+
if version
|
4
|
+
> % {{ full_name.to_hyphen }}(1) Version {{ version }} | {{ summary }}
|
5
|
+
else
|
6
|
+
> % {{ full_name.to_hyphen }}(1) | {{ summary }}
|
7
|
+
end
|
8
|
+
|
9
|
+
> % {{ x_mandoc_authors&.for_manpage }}
|
10
|
+
> % {{ Date.today.strftime "%B %Y" }}
|
11
|
+
>
|
12
|
+
|
13
|
+
> NAME
|
14
|
+
> ==================================================
|
15
|
+
>
|
16
|
+
> **{{ full_name }}** - {{ summary }}
|
17
|
+
>
|
18
|
+
|
19
|
+
> SYNOPSIS
|
20
|
+
> ==================================================
|
21
|
+
>
|
22
|
+
> {{ usage_string.gsub(/^#{full_name}/, "**#{full_name}**") }}
|
23
|
+
>
|
24
|
+
|
25
|
+
> DESCRIPTION
|
26
|
+
> ==================================================
|
27
|
+
>
|
28
|
+
> {{ help.for_manpage }}
|
29
|
+
>
|
30
|
+
|
31
|
+
if default
|
32
|
+
> - *Default Command*
|
33
|
+
end
|
34
|
+
if alt.any?
|
35
|
+
> - Alias: **{{ alt.join ', ' }}**
|
36
|
+
end
|
37
|
+
if extensible
|
38
|
+
if extensible.is_a? String
|
39
|
+
> - Extensible: **{{ extensible }}**
|
40
|
+
else
|
41
|
+
> - *Extensible*
|
42
|
+
end
|
43
|
+
end
|
44
|
+
>
|
45
|
+
|
46
|
+
if public_commands.any?
|
47
|
+
grouped_commands.each do |group, commands|
|
48
|
+
> {{ group.gsub(/:$/, '').upcase }}
|
49
|
+
> ==================================================
|
50
|
+
>
|
51
|
+
commands.each do |subcommand|
|
52
|
+
> {{ subcommand.full_name }}
|
53
|
+
> --------------------------------------------------
|
54
|
+
>
|
55
|
+
> {{ subcommand.summary.for_manpage }}
|
56
|
+
>
|
57
|
+
end
|
58
|
+
>
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
if args.any?
|
63
|
+
> ARGUMENTS
|
64
|
+
> ==================================================
|
65
|
+
>
|
66
|
+
args.each do |arg|
|
67
|
+
> {{ arg.name.upcase }}
|
68
|
+
> --------------------------------------------------
|
69
|
+
>
|
70
|
+
> {{ arg.help.for_manpage }}
|
71
|
+
>
|
72
|
+
if arg.required
|
73
|
+
> - *Required*
|
74
|
+
end
|
75
|
+
if arg.repeatable
|
76
|
+
> - *Repeatable*
|
77
|
+
end
|
78
|
+
if arg.default
|
79
|
+
> - Default Value: **{{ arg.default }}**
|
80
|
+
end
|
81
|
+
if arg.allowed
|
82
|
+
> - Allowed Values: **{{ arg.allowed.join(', ') }}**
|
83
|
+
end
|
84
|
+
>
|
85
|
+
end
|
86
|
+
|
87
|
+
if catch_all.label && catch_all.help
|
88
|
+
> {{ catch_all.label }}
|
89
|
+
> --------------------------------------------------
|
90
|
+
>
|
91
|
+
if catch_all.help
|
92
|
+
> {{ catch_all.help.for_manpage }}
|
93
|
+
>
|
94
|
+
end
|
95
|
+
>
|
96
|
+
|
97
|
+
if catch_all.required?
|
98
|
+
> - *Required*
|
99
|
+
>
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
if flags.any?
|
105
|
+
> OPTIONS
|
106
|
+
> ==================================================
|
107
|
+
>
|
108
|
+
flags.each do |flag|
|
109
|
+
> {{ flag.usage_string }}
|
110
|
+
> --------------------------------------------------
|
111
|
+
>
|
112
|
+
> {{ flag.help.for_manpage }}
|
113
|
+
>
|
114
|
+
|
115
|
+
if flag.required
|
116
|
+
> - *Required*
|
117
|
+
end
|
118
|
+
if flag.repeatable
|
119
|
+
> - *Repeatable*
|
120
|
+
end
|
121
|
+
if flag.default
|
122
|
+
> - Default Value: **{{ flag.default }}**
|
123
|
+
end
|
124
|
+
if flag.allowed
|
125
|
+
> - Allowed Values: **{{ flag.allowed.join(', ') }}**
|
126
|
+
end
|
127
|
+
if flag.conflicts
|
128
|
+
> - Conflicts With: **{{ flag.conflicts.join(', ') }}**
|
129
|
+
end
|
130
|
+
>
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
if dependencies.any?
|
135
|
+
> DEPENDENCIES
|
136
|
+
> ==================================================
|
137
|
+
>
|
138
|
+
dependencies.each do |dependency|
|
139
|
+
> {{ dependency.commands.join ', ' }}
|
140
|
+
> --------------------------------------------------
|
141
|
+
>
|
142
|
+
if dependency.help
|
143
|
+
> {{ dependency.help.for_manpage }}
|
144
|
+
>
|
145
|
+
end
|
146
|
+
>
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
if public_environment_variables.any?
|
151
|
+
> ENVIRONMENT VARIABLES
|
152
|
+
> ==================================================
|
153
|
+
>
|
154
|
+
public_environment_variables.each do |environment_variable|
|
155
|
+
> {{ environment_variable.name.upcase }}
|
156
|
+
> --------------------------------------------------
|
157
|
+
>
|
158
|
+
> {{ environment_variable.help.for_manpage }}
|
159
|
+
>
|
160
|
+
|
161
|
+
if environment_variable.required
|
162
|
+
> - *Required*
|
163
|
+
end
|
164
|
+
if environment_variable.default
|
165
|
+
> - Default Value: **{{ environment_variable.default }}**
|
166
|
+
end
|
167
|
+
>
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
if examples
|
172
|
+
> EXAMPLES
|
173
|
+
> ==================================================
|
174
|
+
>
|
175
|
+
> ~~~
|
176
|
+
examples.each do |example|
|
177
|
+
> {{ example.for_manpage }}
|
178
|
+
>
|
179
|
+
end
|
180
|
+
> ~~~
|
181
|
+
>
|
182
|
+
end
|
183
|
+
|
184
|
+
if public_commands.any? || parents.any?
|
185
|
+
> SEE ALSO
|
186
|
+
> ==================================================
|
187
|
+
>
|
188
|
+
if parents.any?
|
189
|
+
> **{{ parents.first }}**(1)
|
190
|
+
end
|
191
|
+
= public_commands.map { |x| "**#{x.full_name.to_hyphen}**(1)" }.join ', '
|
192
|
+
>
|
193
|
+
end
|
194
|
+
|
195
|
+
= x_mandoc_footer&.for_manpage
|
196
|
+
>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# render script - mandoc
|
2
|
+
require 'gtx'
|
3
|
+
|
4
|
+
# Load the GTX template
|
5
|
+
template = "#{source}/mandoc.gtx"
|
6
|
+
gtx = GTX.load_file template
|
7
|
+
|
8
|
+
# Define a reusable code block for rendering a man page for a command
|
9
|
+
save_manpage = lambda { |command|
|
10
|
+
mdfile = "#{target}/#{command.full_name.tr(' ', '-')}.md"
|
11
|
+
manfile = "#{target}/#{command.full_name.tr(' ', '-')}.1"
|
12
|
+
save mdfile, gtx.parse(command)
|
13
|
+
|
14
|
+
# The pandoc command that creates a manpage from markdown
|
15
|
+
cmd = %[pandoc -f markdown-smart -s --to man "#{mdfile}" > "#{manfile}"]
|
16
|
+
success = system cmd
|
17
|
+
raise "Failed running pandoc\nMake sure the following command succeeds and try again:\n\n #{cmd}" unless success
|
18
|
+
|
19
|
+
say "g`saved` #{manfile}"
|
20
|
+
}
|
21
|
+
|
22
|
+
# Render the main command
|
23
|
+
save_manpage.call command
|
24
|
+
|
25
|
+
# Render all subcommands
|
26
|
+
command.deep_commands.reject(&:private).each do |subcommand|
|
27
|
+
save_manpage.call subcommand
|
28
|
+
end
|
29
|
+
|
30
|
+
# Show one of the files if requested
|
31
|
+
if show
|
32
|
+
file = "#{target}/#{show}"
|
33
|
+
system "man #{file}" if File.exist?(file)
|
34
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Render man pages for your script
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Render markdown
|
2
|
+
|
3
|
+
Render markdown documents for your script.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
```bash
|
8
|
+
# Generate all documents to the ./docs directory
|
9
|
+
$ bashly render :markdown docs
|
10
|
+
|
11
|
+
# Generate on change, and show one of the files
|
12
|
+
$ bashly render :markdown docs --watch --show index.md
|
13
|
+
```
|
14
|
+
|
15
|
+
## Supported custom definitions
|
16
|
+
|
17
|
+
Add these definitions to your `bashly.yml` to render them in your
|
18
|
+
markdown:
|
19
|
+
|
20
|
+
### Footer: `x_markdown_footer`
|
21
|
+
|
22
|
+
Add additional sections to your man pages. This field is expected
|
23
|
+
to be in markdown format.
|
24
|
+
|
25
|
+
#### Example
|
26
|
+
|
27
|
+
```yaml
|
28
|
+
x_markdown_footer: |-
|
29
|
+
# ISSUE TRACKER
|
30
|
+
|
31
|
+
Report issues at <https://github.com/lanalang/smallville>
|
32
|
+
```
|
33
|
+
|
34
|
+
## Markdown server
|
35
|
+
|
36
|
+
In order to view your markdown files in a browser, you can use the
|
37
|
+
[Madness markdown server](https://madness.dannyb.co/):
|
38
|
+
|
39
|
+
```bash
|
40
|
+
$ gem install madness
|
41
|
+
$ madness server docs
|
42
|
+
```
|
@@ -0,0 +1,186 @@
|
|
1
|
+
# === Header
|
2
|
+
|
3
|
+
> # {{ full_name }}
|
4
|
+
>
|
5
|
+
> {{ help.for_markdown }}
|
6
|
+
>
|
7
|
+
|
8
|
+
attributes = version || alt.any? || default || extensible
|
9
|
+
|
10
|
+
if attributes
|
11
|
+
> | Attributes |
|
12
|
+
> |------------------|-------------
|
13
|
+
if version
|
14
|
+
> | Version: | {{ version }}
|
15
|
+
end
|
16
|
+
if alt.any?
|
17
|
+
> | Alias: | {{ alt.join ', ' }}
|
18
|
+
end
|
19
|
+
if default
|
20
|
+
> | Default Command: | ✓ Yes
|
21
|
+
end
|
22
|
+
if extensible
|
23
|
+
> | Extensible: | {{ extensible.is_a?(String) ? extensible : "✓ Yes" }}
|
24
|
+
end
|
25
|
+
>
|
26
|
+
end
|
27
|
+
|
28
|
+
# === Usage
|
29
|
+
|
30
|
+
> ## Usage
|
31
|
+
>
|
32
|
+
> ```bash
|
33
|
+
> {{ usage_string.for_markdown }}
|
34
|
+
> ```
|
35
|
+
>
|
36
|
+
|
37
|
+
# === Examples
|
38
|
+
|
39
|
+
if examples
|
40
|
+
> ## Examples
|
41
|
+
>
|
42
|
+
examples.each do |example|
|
43
|
+
> ```bash
|
44
|
+
> {{ example }}
|
45
|
+
> ```
|
46
|
+
>
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# === Dependencies
|
51
|
+
|
52
|
+
if dependencies.any?
|
53
|
+
> ## Dependencies
|
54
|
+
>
|
55
|
+
dependencies.each do |dependency|
|
56
|
+
> #### *{{ dependency.commands.join ', ' }}*
|
57
|
+
>
|
58
|
+
> {{ dependency.help&.for_markdown }}
|
59
|
+
>
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# === Environment Variables
|
64
|
+
|
65
|
+
if public_environment_variables.any?
|
66
|
+
> ## Environment Variables
|
67
|
+
>
|
68
|
+
public_environment_variables.each do |environment_variable|
|
69
|
+
attributes = environment_variable.required || environment_variable.default
|
70
|
+
|
71
|
+
> #### *{{ environment_variable.name.upcase }}*
|
72
|
+
>
|
73
|
+
> {{ environment_variable.help.for_markdown }}
|
74
|
+
>
|
75
|
+
|
76
|
+
if attributes
|
77
|
+
> | Attributes |
|
78
|
+
> |-----------------|-------------
|
79
|
+
if environment_variable.required
|
80
|
+
> | Required: | ✓ Yes
|
81
|
+
end
|
82
|
+
if environment_variable.default
|
83
|
+
> | Default Value: | {{ environment_variable.default }}
|
84
|
+
end
|
85
|
+
>
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# === Commands
|
91
|
+
|
92
|
+
if commands.any?
|
93
|
+
grouped_commands.each do |group, commands|
|
94
|
+
> ## {{ group.gsub(/:$/, '') }}
|
95
|
+
>
|
96
|
+
commands.each do |subcommand|
|
97
|
+
> - [{{ subcommand.name }}]({{ subcommand.full_name.gsub(' ', '%20') }}) - {{ subcommand.summary.for_markdown }}
|
98
|
+
end
|
99
|
+
>
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# === Arguments
|
104
|
+
|
105
|
+
if args.any?
|
106
|
+
> ## Arguments
|
107
|
+
>
|
108
|
+
args.each do |arg|
|
109
|
+
attributes = arg.required || arg.repeatable || arg.default || arg.allowed
|
110
|
+
|
111
|
+
> #### *{{ arg.name.upcase }}*
|
112
|
+
>
|
113
|
+
> {{ arg.help.for_markdown }}
|
114
|
+
>
|
115
|
+
|
116
|
+
if attributes
|
117
|
+
> | Attributes |
|
118
|
+
> |-----------------|-------------
|
119
|
+
if arg.required
|
120
|
+
> | Required: | ✓ Yes
|
121
|
+
end
|
122
|
+
if arg.repeatable
|
123
|
+
> | Repeatable: | ✓ Yes
|
124
|
+
end
|
125
|
+
if arg.default
|
126
|
+
> | Default Value: | {{ arg.default }}
|
127
|
+
end
|
128
|
+
if arg.allowed
|
129
|
+
> | Allowed Values: | {{ arg.allowed.join(', ') }}
|
130
|
+
end
|
131
|
+
>
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
if catch_all.label && catch_all.help
|
136
|
+
> #### *{{ catch_all.label }}*
|
137
|
+
>
|
138
|
+
> {{ catch_all.help&.for_markdown }}
|
139
|
+
>
|
140
|
+
if catch_all.required?
|
141
|
+
> | Attributes |
|
142
|
+
> |------------|-------------
|
143
|
+
> | Required: | ✓ Yes
|
144
|
+
>
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# === Flags
|
150
|
+
|
151
|
+
if flags.any?
|
152
|
+
> ## Options
|
153
|
+
>
|
154
|
+
flags.each do |flag|
|
155
|
+
attributes = flag.required || flag.repeatable || flag.default || flag.allowed || flag.conflicts
|
156
|
+
|
157
|
+
> #### *{{ flag.usage_string }}*
|
158
|
+
>
|
159
|
+
> {{ flag.help.for_markdown }}
|
160
|
+
>
|
161
|
+
|
162
|
+
if attributes
|
163
|
+
> | Attributes |
|
164
|
+
> |-----------------|-------------
|
165
|
+
if flag.required
|
166
|
+
> | Required: | ✓ Yes
|
167
|
+
end
|
168
|
+
if flag.repeatable
|
169
|
+
> | Repeatable: | ✓ Yes
|
170
|
+
end
|
171
|
+
if flag.default
|
172
|
+
> | Default Value: | {{ flag.default }}
|
173
|
+
end
|
174
|
+
if flag.allowed
|
175
|
+
> | Allowed Values: | {{ flag.allowed.join(', ') }}
|
176
|
+
end
|
177
|
+
if flag.conflicts
|
178
|
+
> | Conflicts With: | *{{ flag.conflicts.join(', ') }}*
|
179
|
+
end
|
180
|
+
>
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
= x_markdown_footer&.for_manpage
|
186
|
+
>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# render script - markdown
|
2
|
+
require 'gtx'
|
3
|
+
|
4
|
+
# for previewing only (not needed for rendering)
|
5
|
+
require 'tty-markdown'
|
6
|
+
|
7
|
+
# Load the GTX template
|
8
|
+
template = "#{source}/markdown.gtx"
|
9
|
+
gtx = GTX.load_file template
|
10
|
+
|
11
|
+
# Render the file for the main command
|
12
|
+
save "#{target}/index.md", gtx.parse(command)
|
13
|
+
|
14
|
+
# Render a file for each subcommand
|
15
|
+
command.deep_commands.reject(&:private).each do |subcommand|
|
16
|
+
save "#{target}/#{subcommand.full_name}.md", gtx.parse(subcommand)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Show one of the files if requested
|
20
|
+
if show
|
21
|
+
file = "#{target}/#{show}"
|
22
|
+
puts TTY::Markdown.parse_file(file) if File.exist?(file)
|
23
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Render markdown documents for your script
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'date' # for use by template render scripts
|
2
|
+
require 'colsole'
|
3
|
+
|
4
|
+
module Bashly
|
5
|
+
class RenderContext
|
6
|
+
include Colsole
|
7
|
+
|
8
|
+
attr_reader :source, :target, :show
|
9
|
+
attr_writer :config
|
10
|
+
|
11
|
+
def initialize(source:, target:, show: nil)
|
12
|
+
@source = source
|
13
|
+
@target = target
|
14
|
+
@show = show
|
15
|
+
end
|
16
|
+
|
17
|
+
def config
|
18
|
+
@config ||= Config.new Settings.config_path
|
19
|
+
end
|
20
|
+
|
21
|
+
def command
|
22
|
+
@command ||= Script::Command.new config
|
23
|
+
end
|
24
|
+
|
25
|
+
def save(filename, content)
|
26
|
+
File.deep_write filename, content
|
27
|
+
say "g`saved` #{filename}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Bashly
|
2
|
+
class RenderSource
|
3
|
+
attr_reader :selector
|
4
|
+
|
5
|
+
class << self
|
6
|
+
include AssetHelper
|
7
|
+
|
8
|
+
def internal
|
9
|
+
@internal ||= internal_dirs.to_h do |dir|
|
10
|
+
selector = File.basename(dir).to_sym
|
11
|
+
[selector, new(selector)]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def internal_dirs
|
16
|
+
@internal_dirs ||= Dir["#{internal_root}/*"].select { |x| File.directory? x }
|
17
|
+
end
|
18
|
+
|
19
|
+
def internal_root
|
20
|
+
asset('libraries/render')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(selector)
|
25
|
+
@selector = selector
|
26
|
+
end
|
27
|
+
|
28
|
+
def render(target, show: nil)
|
29
|
+
context = RenderContext.new source: path, target: target, show: show
|
30
|
+
context.instance_eval render_script
|
31
|
+
end
|
32
|
+
|
33
|
+
def internal?
|
34
|
+
selector.is_a? Symbol
|
35
|
+
end
|
36
|
+
|
37
|
+
def path
|
38
|
+
internal? ? "#{internal_root}/#{selector}" : selector
|
39
|
+
end
|
40
|
+
|
41
|
+
def exist?
|
42
|
+
Dir.exist? path
|
43
|
+
end
|
44
|
+
|
45
|
+
def summary
|
46
|
+
File.readlines(summary_file)[0].chomp
|
47
|
+
end
|
48
|
+
|
49
|
+
def readme
|
50
|
+
File.read readme_file if File.exist? readme_file
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def render_script
|
56
|
+
@render_script ||= File.read "#{path}/render.rb"
|
57
|
+
end
|
58
|
+
|
59
|
+
def internal_root
|
60
|
+
self.class.internal_root
|
61
|
+
end
|
62
|
+
|
63
|
+
def summary_file
|
64
|
+
"#{path}/summary.txt"
|
65
|
+
end
|
66
|
+
|
67
|
+
def readme_file
|
68
|
+
"#{path}/README.md"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/bashly/script/base.rb
CHANGED
@@ -35,7 +35,8 @@ module Bashly
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def respond_to_missing?(method_name, include_private = false)
|
38
|
-
self.class.option_keys.include?(method_name) ||
|
38
|
+
self.class.option_keys.include?(method_name) ||
|
39
|
+
method_name.to_s.start_with?('x_') || super
|
39
40
|
end
|
40
41
|
end
|
41
42
|
end
|
@@ -200,6 +200,23 @@ module Bashly
|
|
200
200
|
end
|
201
201
|
end
|
202
202
|
|
203
|
+
# Returns subcommands by group
|
204
|
+
def grouped_commands
|
205
|
+
result = {}
|
206
|
+
|
207
|
+
public_commands.each do |command|
|
208
|
+
result[command.group_string] ||= []
|
209
|
+
result[command.group_string] << command
|
210
|
+
next unless command.expose
|
211
|
+
|
212
|
+
command.public_commands.each do |subcommand|
|
213
|
+
result[command.group_string] << subcommand
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
result
|
218
|
+
end
|
219
|
+
|
203
220
|
# Returns a mode identifier
|
204
221
|
def mode
|
205
222
|
@mode ||= if global_flags? then :global_flags
|
data/lib/bashly/version.rb
CHANGED
@@ -7,7 +7,7 @@ if dependencies.any?
|
|
7
7
|
> else
|
8
8
|
> printf "{{ strings[:missing_dependency] % { dependency: dependency.name } }}\n" >&2
|
9
9
|
if dependency.help
|
10
|
-
> printf "%s\n" "{{ dependency.help }}" >&2
|
10
|
+
> printf "%s\n" "{{ dependency.help.sanitize_for_print }}" >&2
|
11
11
|
end
|
12
12
|
> exit 1
|
13
13
|
> fi
|
@@ -4,7 +4,7 @@
|
|
4
4
|
> if [[ -n $long_usage ]]; then
|
5
5
|
|
6
6
|
if summary == help
|
7
|
-
> printf "{{ caption_string }}\n"
|
7
|
+
> printf "{{ caption_string.sanitize_for_print }}\n"
|
8
8
|
> echo
|
9
9
|
else
|
10
10
|
> printf "{{ full_name }}\n"
|
@@ -14,7 +14,7 @@ else
|
|
14
14
|
end
|
15
15
|
|
16
16
|
> else
|
17
|
-
> printf "{{ caption_string }}\n"
|
17
|
+
> printf "{{ caption_string.sanitize_for_print }}\n"
|
18
18
|
> echo
|
19
19
|
> fi
|
20
20
|
>
|
@@ -7,9 +7,9 @@ command_help_data.each do |group, commands|
|
|
7
7
|
|
8
8
|
commands.each do |command, info|
|
9
9
|
if info[:help_only]
|
10
|
-
> [[ -n $long_usage ]] && printf " %s {{ info[:summary] }}\n" "{{ command.ljust(maxlen).color(:command) }}"
|
10
|
+
> [[ -n $long_usage ]] && printf " %s {{ info[:summary].sanitize_for_print }}\n" "{{ command.ljust(maxlen).color(:command) }}"
|
11
11
|
else
|
12
|
-
> printf " %s {{ info[:summary] }}\n" "{{ command.ljust(maxlen).color(:command) }}"
|
12
|
+
> printf " %s {{ info[:summary].sanitize_for_print }}\n" "{{ command.ljust(maxlen).color(:command) }}"
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|