bashly 1.0.7 → 1.1.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/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
|
|