power_stencil 0.7.4 → 0.8.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 +12 -0
- data/doc/plugins.md +27 -11
- data/etc/base_commands_definition.yml +33 -10
- data/etc/meta_templates/plugin_seed/psplugin_{entity}.gemspec +1 -1
- data/etc/power_stencil.yaml +7 -0
- data/etc/templates/plugin_definition/psplugin_{entity}.gemspec +1 -1
- data/etc/templates/project/.ps_project/versioned-config.yaml +4 -0
- data/etc/templates/zsh_command_line_completion/.copy_ignore +2 -0
- data/etc/templates/zsh_command_line_completion/_power_stencil.sh.erb +117 -0
- data/lib/power_stencil.rb +4 -0
- data/lib/power_stencil/command_processors/adm.rb +29 -0
- data/lib/power_stencil/command_processors/plugin.rb +14 -19
- data/lib/power_stencil/dsl/completion.rb +94 -0
- data/lib/power_stencil/engine/base.rb +1 -0
- data/lib/power_stencil/initializer.rb +2 -1
- data/lib/power_stencil/plugins/command_line.rb +1 -1
- data/lib/power_stencil/project/base.rb +2 -0
- data/lib/power_stencil/project/completion.rb +25 -0
- data/lib/power_stencil/utils/completion.rb +29 -0
- data/lib/power_stencil/utils/slop_extra_option_types.rb +40 -0
- data/lib/power_stencil/version.rb +1 -1
- data/power_stencil.gemspec +4 -1
- metadata +14 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1eacfe087b69afd2c0255a513247426d5698b6e3
|
4
|
+
data.tar.gz: 037422841a5061473c73166e299dd643fa8e46af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 09a9753d65ad28ce0bd068dceed0da1a9351c7680f81de4d02180577ebbc08373297819fa471870531a6402de115c524d576fc355248e0a045d867b5586fab3e
|
7
|
+
data.tar.gz: fc3831ccc82144c7a4a80efd05ec8b78dc03c82a5bb4380ec1e290e2d59b441740ae8b298b28ba4c04148893719d8f63b95f55060554bfaf781f6d8828504b18
|
data/README.md
CHANGED
@@ -15,6 +15,7 @@ See [official website][PowerStencil site].
|
|
15
15
|
- [Installation](#installation)
|
16
16
|
- [Usage](#usage)
|
17
17
|
- [Help](#help)
|
18
|
+
- [Command line auto-completion](#command-line-auto-completion)
|
18
19
|
- [Creating a `PowerStencil` project](#creating-a-powerstencil-project)
|
19
20
|
- [`PowerStencil` project structure](#powerstencil-project-structure)
|
20
21
|
- [Getting started](#getting-started)
|
@@ -117,6 +118,7 @@ PowerStencil is the Swiss-army knife templating workflow for developers and ops.
|
|
117
118
|
* plugin: Manipulates plugins ...
|
118
119
|
* get: Query entities from repository ...
|
119
120
|
* shell: Opens a shell to interact with entities ...
|
121
|
+
* adm: Administrative commands ...
|
120
122
|
* check: Check repository entities consistency ...
|
121
123
|
* create: Creates entities in the repository ...
|
122
124
|
* edit: Edit entities from repository ...
|
@@ -131,6 +133,16 @@ The program uses the standard paradigm of sub-commands (à-la-git), and each can
|
|
131
133
|
|
132
134
|
[Plugins] may bring extra subcommands and/or options, so depending on the project you are working in, the output of `--help` may differ...
|
133
135
|
|
136
|
+
## Command line auto-completion
|
137
|
+
|
138
|
+
`PowerStencil` comes with a command-line auto-completion feature for `zsh`. It is not yet available for `bash`.
|
139
|
+
|
140
|
+
You can install it by running:
|
141
|
+
|
142
|
+
$ power_stencil adm --zsh-completion
|
143
|
+
|
144
|
+
It provides a very useful auto-completion for sub-commands, options as well as parameters...
|
145
|
+
|
134
146
|
## Creating a `PowerStencil` project
|
135
147
|
|
136
148
|
To create a new project, use the `init` sub-command. It works as you would expect. If you run it in an existing directory it will create the project here but you can specify the directory where you want the project to be created (the path will be created provided you have enough rights on the filesystem):
|
data/doc/plugins.md
CHANGED
@@ -15,6 +15,8 @@ Plugins
|
|
15
15
|
- [Providing entity types and templates](#providing-entity-types-and-templates)
|
16
16
|
- [Providing custom build process](#providing-custom-build-process)
|
17
17
|
- [Plugin capabilities and structure](#plugin-capabilities-and-structure)
|
18
|
+
- [Proposed default plugin structure and life-cycle](#proposed-default-plugin-structure-and-life-cycle)
|
19
|
+
- [Fully manually created plugin](#fully-manually-created-plugin)
|
18
20
|
- [Using plugins available as gems](#using-plugins-available-as-gems)
|
19
21
|
- [Conclusion](#conclusion)
|
20
22
|
|
@@ -46,12 +48,12 @@ If you want to have new custom sub-commands or options available.
|
|
46
48
|
|
47
49
|
Plugins are actually Ruby Gems with a specific structure. Plugins can be part of the project or provided as a separated stand-alone Gem.
|
48
50
|
|
49
|
-
The normal process would be to begin with a plugin within the project and once you're ok with its features you may release it as a standalone Ruby Gem.
|
51
|
+
The normal process would be to begin with a plugin within the project (under `.ps_project/plugins` directory) and once you're ok with its features you may release it as a standalone Ruby Gem.
|
50
52
|
|
51
53
|
- Plugins local to the project are automatically taken in account.
|
52
|
-
- To use plugins provided as Gems you have to set the `:
|
54
|
+
- To use plugins provided as Gems you have to set the `:project_plugins:` array property in the `.ps_project/versioned-config.yaml`
|
53
55
|
|
54
|
-
|
56
|
+
See [using plugins gems](#using-plugins-available-as-gems) for more information.
|
55
57
|
|
56
58
|
|
57
59
|
# Creating plugin local to the project
|
@@ -160,10 +162,12 @@ PowerStencil is the Swiss-army knife templating workflow for developers and ops.
|
|
160
162
|
* plugin: Manipulates plugins ...
|
161
163
|
* get: Query entities from repository ...
|
162
164
|
* shell: Opens a shell to interact with entities ...
|
165
|
+
* adm: Administrative commands ...
|
163
166
|
* check: Check repository entities consistency ...
|
164
167
|
* create: Creates entities in the repository ...
|
165
168
|
* edit: Edit entities from repository ...
|
166
169
|
* delete: Delete entities from repository ...
|
170
|
+
* describe: Detailed information about entity types ...
|
167
171
|
* build: Builds entities ...
|
168
172
|
* myplugin: Does nothing useful Added by plugin myplugin
|
169
173
|
```
|
@@ -310,11 +314,23 @@ Here the code simply reads the generated `message.txt` file and displays it...
|
|
310
314
|
|
311
315
|
# Plugin capabilities and structure
|
312
316
|
|
313
|
-
|
317
|
+
## Proposed default plugin structure and life-cycle
|
314
318
|
|
315
|
-
|
319
|
+
So the `power_stencil plugin --create` generated a fully working plugin, implementing all the features you could define in a plugin.
|
316
320
|
|
317
|
-
|
321
|
+
The generated plugin has the structure of a legit ruby gem, and this is not by chance, this is to prepare the fact that you may want to create a _stand-alone plugin gem_ that you you may want to re-use accross different projects.
|
322
|
+
|
323
|
+
So, the default structure of a generated plugin is a very good starting point to develop your own plugins. You may remove manually some of the features, add some... and then eventually decide to separate it from your project repository, give it its own life and release it as a `PowerStencil` gem plugin. :champagne: :stars:
|
324
|
+
|
325
|
+
**:information_source:This is by far the easiest and safest way to create and make evolve plugins of your own and the recommended way.**
|
326
|
+
|
327
|
+
|
328
|
+
## Fully manually created plugin
|
329
|
+
|
330
|
+
|
331
|
+
Nevertheless and in order to further understand the concepts behind `PowerStencil` plugins, here under you will find a way to do everything manually.
|
332
|
+
|
333
|
+
Using the provided plugin template is not mandatory. Actually the only mandatory file for a plugin to be valid is the file `etc/plugin_capabilities.yaml` in the plugin directory. This file declares what the plugin is able to do. For the `myplugin` we just created it contains:
|
318
334
|
|
319
335
|
```yaml
|
320
336
|
---
|
@@ -362,7 +378,7 @@ Let's create a plugin fully manually instead of using the `power_stencil plugin
|
|
362
378
|
|
363
379
|
$ mkdir -p .ps_project/plugins/minimal/etc
|
364
380
|
|
365
|
-
(of course the command to create the directory may be different on your system). Then here let's create a `plugin_capabilities.yaml` file with the following content:
|
381
|
+
(of course the command to create the directory may be different on your system). Then here let's create a `plugin_capabilities.yaml` file in this `etc` subdirectory of the plugin directory with the following content:
|
366
382
|
|
367
383
|
```yaml
|
368
384
|
---
|
@@ -426,13 +442,13 @@ MinimalPlugin::Minimal:
|
|
426
442
|
:name: test
|
427
443
|
```
|
428
444
|
|
429
|
-
All of this to demonstrate that a plugin can be almost anything, even something very minimalistic, but nevertheless you should keep on using the `power_stencil plugin --create` command and benefit from the structure it brings, as well as the possibility to become a stand-alone plugin gem
|
445
|
+
All of this to demonstrate that a plugin can be almost anything, even something very minimalistic, but nevertheless **you should keep on using the `power_stencil plugin --create` command and benefit from the structure it brings, as well as the possibility to become so easily a stand-alone plugin gem**...
|
430
446
|
|
431
447
|
# Using plugins available as gems
|
432
448
|
|
433
|
-
Any plugin you have created using the `power_stencil plugin --create` command is directly eligible to become a gem.
|
449
|
+
Any plugin you have created using the `power_stencil plugin --create` command is directly eligible to become a plugin gem.
|
434
450
|
|
435
|
-
**If you release a plugin you created within a project as a gem (by doing `bundle exec rake release` from within the plugin directory, like for any standard gem :+1:), you can then re-use your plugin
|
451
|
+
**If you release a plugin you created within a project as a gem (by doing `bundle exec rake release` from within the plugin directory, like for any standard gem :+1:), you can then re-use your plugin accross any other `PowerStencil` project !**
|
436
452
|
|
437
453
|
All you have to do for that is to declare it in the `.ps_project/versioned-config.yaml` config file by adding an array `:project_plugins`:
|
438
454
|
|
@@ -473,7 +489,7 @@ Installed plugin 'my_awesome_plugin2' (version: 0.1.1)
|
|
473
489
|
Installed plugin 'my_awesome_plugin3' (version: 1.2.3)
|
474
490
|
```
|
475
491
|
|
476
|
-
**:star2: ::+1: You can now verify using `power_stencil info` or `power_stencil plugin --list`, that the plugins have been installed and that any feature they provide is now available to your project.**
|
492
|
+
**:star2: ::+1: You can now verify using `power_stencil info` or `power_stencil plugin --list -v`, that the plugins have been installed and that any feature they provide is now available to your project.**
|
477
493
|
|
478
494
|
# Conclusion
|
479
495
|
|
@@ -40,7 +40,7 @@
|
|
40
40
|
:global: true
|
41
41
|
:dependencies:
|
42
42
|
- debug
|
43
|
-
:type:
|
43
|
+
:type: log_level
|
44
44
|
:summary: Defines the level of logging (0 to 5)
|
45
45
|
log-file:
|
46
46
|
:global: true
|
@@ -48,7 +48,7 @@
|
|
48
48
|
- debug
|
49
49
|
:incompatibilities:
|
50
50
|
- debug-on-stderr
|
51
|
-
:type:
|
51
|
+
:type: file
|
52
52
|
:summary: Specifies a file to log into
|
53
53
|
truncate-log-file:
|
54
54
|
:global: true
|
@@ -58,7 +58,7 @@
|
|
58
58
|
:summary: Truncates the log file (appends by default)
|
59
59
|
project-path:
|
60
60
|
:global: true
|
61
|
-
:type:
|
61
|
+
:type: path
|
62
62
|
:summary: Specifies a startup path to use instead of '.'
|
63
63
|
auto:
|
64
64
|
:global: true
|
@@ -79,6 +79,7 @@
|
|
79
79
|
Default is initializing the PowerStencil repository in current directory. If
|
80
80
|
specified, will initialize a repository in project_path (global option
|
81
81
|
project_path can be used too).
|
82
|
+
:type: path
|
82
83
|
:options:
|
83
84
|
force:
|
84
85
|
:type: bool
|
@@ -107,9 +108,10 @@
|
|
107
108
|
plugin [options]
|
108
109
|
|
109
110
|
Manipulates plugins.
|
111
|
+
:type: bool
|
110
112
|
:options:
|
111
113
|
create:
|
112
|
-
:type:
|
114
|
+
:type: string
|
113
115
|
:summary: Scaffolds a fully working plugin skeleton.
|
114
116
|
:long_aliases:
|
115
117
|
- new
|
@@ -151,6 +153,7 @@
|
|
151
153
|
"type/name" or two consecutive parameters "type name". If in
|
152
154
|
"regexp" mode then each criterion is considered as a regular
|
153
155
|
expression (be careful, not a file pattern alike)
|
156
|
+
:type: entity
|
154
157
|
:options:
|
155
158
|
regexp: ®EXPOPT
|
156
159
|
:type: bool
|
@@ -173,7 +176,7 @@
|
|
173
176
|
:type: bool
|
174
177
|
:summary: Entities as used by susbstitution engine.
|
175
178
|
scenario: &SCENARIOOPT
|
176
|
-
:type:
|
179
|
+
:type: scenario
|
177
180
|
:summary: Applies overrides defined for this scenario.
|
178
181
|
:dependencies:
|
179
182
|
- compiled
|
@@ -186,7 +189,7 @@
|
|
186
189
|
:short_aliases:
|
187
190
|
- g
|
188
191
|
graph-file:
|
189
|
-
:type:
|
192
|
+
:type: file
|
190
193
|
:summary: Displays the query result as a graph in the specified file.
|
191
194
|
:long_aliases:
|
192
195
|
- gf
|
@@ -204,6 +207,20 @@
|
|
204
207
|
<<: *COMPILEDOPT
|
205
208
|
scenario:
|
206
209
|
<<: *SCENARIOOPT
|
210
|
+
adm:
|
211
|
+
:banner: |
|
212
|
+
Administrative commands.
|
213
|
+
|
214
|
+
Usage:
|
215
|
+
|
216
|
+
adm [options]
|
217
|
+
:options:
|
218
|
+
zsh-completion:
|
219
|
+
:type: bool
|
220
|
+
:summary: Generates power_stencil completion script for zsh shell.
|
221
|
+
query-for-completion:
|
222
|
+
:type: completion_query_type
|
223
|
+
:summary: Internal. Used by the auto-completion system.
|
207
224
|
check:
|
208
225
|
:banner: |
|
209
226
|
Check repository entities consistency.
|
@@ -213,11 +230,12 @@
|
|
213
230
|
check [entity_type[[/ ]entity_name]] [options]
|
214
231
|
|
215
232
|
Check entities consistency. By default will check all entities.
|
233
|
+
:type: entity
|
216
234
|
:options:
|
217
235
|
regexp:
|
218
236
|
<<: *REGEXPOPT
|
219
237
|
invalid-only:
|
220
|
-
:type:
|
238
|
+
:type: bool
|
221
239
|
:summary: Show invalid entities only.
|
222
240
|
:long_aliases:
|
223
241
|
- invalid
|
@@ -232,6 +250,7 @@
|
|
232
250
|
create entity_type[/ ]entity_name [options]
|
233
251
|
|
234
252
|
Creates repository entities. Both type and name have to be provided
|
253
|
+
:type: entity_type
|
235
254
|
:options:
|
236
255
|
property:
|
237
256
|
:type: array
|
@@ -246,7 +265,7 @@
|
|
246
265
|
:long_aliases:
|
247
266
|
- edit-after-create
|
248
267
|
editor:
|
249
|
-
:type:
|
268
|
+
:type: file
|
250
269
|
:summary: Specifies an editor to use.
|
251
270
|
:dependencies:
|
252
271
|
- edit
|
@@ -267,10 +286,11 @@
|
|
267
286
|
edit [entity_type[[/ ]entity_name]] [options]
|
268
287
|
|
269
288
|
Edits repository entities. Parameters are used the same way as in 'get'.
|
289
|
+
:type: entity
|
270
290
|
:options:
|
271
291
|
regexp: *REGEXPOPT
|
272
292
|
editor:
|
273
|
-
:type:
|
293
|
+
:type: file
|
274
294
|
:summary: Specifies an editor to use.
|
275
295
|
:short_aliases:
|
276
296
|
- e
|
@@ -283,6 +303,7 @@
|
|
283
303
|
delete [entity_type[[/ ]entity_name]] [options]
|
284
304
|
|
285
305
|
Deletes repository entities. Parameters are used the same way as in 'get'.
|
306
|
+
:type: entity
|
286
307
|
:options:
|
287
308
|
regexp: *REGEXPOPT
|
288
309
|
delete-files:
|
@@ -298,6 +319,7 @@
|
|
298
319
|
|
299
320
|
Displays information about core properties of given entity types.
|
300
321
|
By default will describe all entity types.
|
322
|
+
:type: entity_type
|
301
323
|
build:
|
302
324
|
:banner: |
|
303
325
|
Builds entities.
|
@@ -307,6 +329,7 @@
|
|
307
329
|
build [entity_type[[/ ]entity_name]]+ [options]
|
308
330
|
|
309
331
|
Builds repository entities. Parameters are used the same way as in 'get'.
|
332
|
+
:type: entity
|
310
333
|
:options:
|
311
334
|
regexp: *REGEXPOPT
|
312
335
|
supported-builds:
|
@@ -330,7 +353,7 @@
|
|
330
353
|
:short_aliases:
|
331
354
|
- t
|
332
355
|
target-path:
|
333
|
-
:type:
|
356
|
+
:type: path
|
334
357
|
:summary: Build into specified directory
|
335
358
|
:long_aliases:
|
336
359
|
- path
|
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ['Your name']
|
10
10
|
spec.email = ['you@somewhere']
|
11
11
|
|
12
|
-
spec.summary = %q{
|
12
|
+
spec.summary = %q{<%= plugin_name %> is a plugin for the PowerStencil framework.}
|
13
13
|
spec.description = %q{TODO: Write a longer description or delete this line.}
|
14
14
|
spec.homepage = "TODO: Put your gem's website or public repo URL here."
|
15
15
|
spec.license = "MIT"
|
data/etc/power_stencil.yaml
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ['Your name']
|
10
10
|
spec.email = ['you@somewhere']
|
11
11
|
|
12
|
-
spec.summary = %q{
|
12
|
+
spec.summary = %q{<%= plugin_name %> is a plugin for the PowerStencil framework.}
|
13
13
|
spec.description = %q{TODO: Write a longer description or delete this line.}
|
14
14
|
spec.homepage = "TODO: Put your gem's website or public repo URL here."
|
15
15
|
spec.license = "MIT"
|
@@ -5,6 +5,10 @@
|
|
5
5
|
# If you want to ensure a minimal version number of PowerStencil
|
6
6
|
:min_power_stencil_version: <%= PowerStencil::VERSION %>
|
7
7
|
|
8
|
+
# Project plugins gems
|
9
|
+
# List of plugins, provided as real Ruby gems (outside of this project), that you want to use in this project.
|
10
|
+
# :project_plugins: []
|
11
|
+
|
8
12
|
# Graphviz configuration
|
9
13
|
#
|
10
14
|
# If you are under Gnome, chances are that you have 'eog' installed
|
@@ -0,0 +1,117 @@
|
|
1
|
+
#compdef <%= script_name %>
|
2
|
+
|
3
|
+
# zsh shell completion script for <%= script_name %>
|
4
|
+
# To regenerate this file: '<%= script_name %> adm --zsh-completion'
|
5
|
+
# Generated on the <%= Time.now %> by <%= script_name %> v<%= PowerStencil::VERSION %>
|
6
|
+
|
7
|
+
<% commands = PowerStencil.command_line_manager.commands -%>
|
8
|
+
_<%= script_name %>() {
|
9
|
+
local cmd
|
10
|
+
local <%= script_name %>_sub_commands
|
11
|
+
<%= script_name %>_sub_commands=(<%= commands.reject { |c| c.name.empty? }.sort { |a,b| a.name <=> b.name }.map(&:name).join ' ' %>)
|
12
|
+
if (( CURRENT > 2)); then
|
13
|
+
cmd=${words[2]}
|
14
|
+
# Set the context for the subcommand.
|
15
|
+
curcontext="${curcontext%:*:*}:power_stencil-$cmd"
|
16
|
+
# Narrow the range of words we are looking at to exclude `<%= script_name %>'
|
17
|
+
(( CURRENT-- ))
|
18
|
+
shift words
|
19
|
+
# Run the completion for the subcommand
|
20
|
+
if (($<%= script_name %>_sub_commands[(Ie)$cmd])); then
|
21
|
+
(( $+functions[_<%= script_name %>_cmd_$cmd] )) && _<%= script_name %>_cmd_$cmd
|
22
|
+
else
|
23
|
+
_values : \
|
24
|
+
<%= continued_multilines(root_command(commands).options.sort { |a,b| a.name <=> b.name }.map {|o| option_representation o}, number_spaces: 10) %>
|
25
|
+
fi
|
26
|
+
else
|
27
|
+
_values : \
|
28
|
+
<% root_command = nil -%>
|
29
|
+
<% commands.sort { |a,b| a.name <=> b.name }.each do |command| -%>
|
30
|
+
<% if command.root_command? -%>
|
31
|
+
<% root_command = command -%>
|
32
|
+
<% next -%>
|
33
|
+
<% end -%>
|
34
|
+
<%= command_representation command %> \
|
35
|
+
<% end -%>
|
36
|
+
<%= continued_multilines(root_command.options.sort { |a,b| a.name <=> b.name }.map {|o| option_representation o}, number_spaces: 8) %>
|
37
|
+
fi
|
38
|
+
}
|
39
|
+
|
40
|
+
###############################################################################
|
41
|
+
# Sub-commands
|
42
|
+
|
43
|
+
<% commands.reject { |c| c.name.empty? }.sort { |a,b| a.name <=> b.name }.each do |command| -%>
|
44
|
+
# <%= command.name %> sub-command
|
45
|
+
_<%= script_name %>_cmd_<%= command.name %>() {
|
46
|
+
_arguments -s : \
|
47
|
+
<%
|
48
|
+
command_param = default_command_param_type command
|
49
|
+
options_lines = command.options.sort { |a,b| a.name <=> b.name }.map {|o| option_representation o}
|
50
|
+
options_lines << command_param unless command_param.empty?
|
51
|
+
-%>
|
52
|
+
<%= continued_multilines(options_lines) %>
|
53
|
+
}
|
54
|
+
|
55
|
+
<% end %>
|
56
|
+
|
57
|
+
###############################################################################
|
58
|
+
# Type handlers
|
59
|
+
|
60
|
+
_get_completion_info() {
|
61
|
+
local cmd="$@"
|
62
|
+
res=$( eval ${cmd} 2>/dev/null )
|
63
|
+
echo ${res}
|
64
|
+
}
|
65
|
+
|
66
|
+
_power_stencil_project_root() {
|
67
|
+
cur_dir=`pwd`
|
68
|
+
psdir=".ps_project"
|
69
|
+
while [[ "${cur_dir}" != "" && ! -e "${cur_dir}/${psdir}" ]]; do
|
70
|
+
cur_dir=${cur_dir%/*}
|
71
|
+
done
|
72
|
+
echo "${cur_dir}"
|
73
|
+
}
|
74
|
+
|
75
|
+
_within_power_stencil_project() {
|
76
|
+
local res=$( _power_stencil_project_root )
|
77
|
+
if [ -z "${res#"${res%%[! ]*}"}" ]; then
|
78
|
+
return 1
|
79
|
+
fi
|
80
|
+
return 0
|
81
|
+
}
|
82
|
+
|
83
|
+
# Type entity
|
84
|
+
_power_stencil_entity() {
|
85
|
+
$( _within_power_stencil_project ) || return 'YOU_ARE_NOT_WITHIN_A_POWER_STENCIL_PROJECT'
|
86
|
+
_values : $( _get_completion_info power_stencil adm --query-for-completion entities )
|
87
|
+
}
|
88
|
+
|
89
|
+
# Type entity_type
|
90
|
+
_power_stencil_entity_type() {
|
91
|
+
$( _within_power_stencil_project ) || return 'YOU_ARE_NOT_WITHIN_A_POWER_STENCIL_PROJECT'
|
92
|
+
_values : $( _get_completion_info power_stencil adm --query-for-completion entity-types )
|
93
|
+
}
|
94
|
+
|
95
|
+
# Type scenario
|
96
|
+
_power_stencil_scenario() {
|
97
|
+
$( _within_power_stencil_project ) || return 'YOU_ARE_NOT_WITHIN_A_POWER_STENCIL_PROJECT'
|
98
|
+
_values : $( _get_completion_info power_stencil adm --query-for-completion scenario )
|
99
|
+
}
|
100
|
+
|
101
|
+
# Type log_level
|
102
|
+
_power_stencil_log_level() {
|
103
|
+
_values : $( echo 0 1 2 3 4 5 )
|
104
|
+
}
|
105
|
+
|
106
|
+
# Type completion_query_type
|
107
|
+
_power_stencil_completion_query_type() {
|
108
|
+
_values : $( echo entities entity-types scenario )
|
109
|
+
}
|
110
|
+
|
111
|
+
# Type array and string
|
112
|
+
_power_stencil_do_nothing() {
|
113
|
+
return 1
|
114
|
+
}
|
115
|
+
|
116
|
+
# Let's rock
|
117
|
+
_<%= script_name %> "$@"
|
data/lib/power_stencil.rb
CHANGED
@@ -9,6 +9,7 @@ require 'climatic'
|
|
9
9
|
|
10
10
|
require 'power_stencil/error'
|
11
11
|
require 'power_stencil/utils/os'
|
12
|
+
require 'power_stencil/utils/slop_extra_option_types'
|
12
13
|
require 'power_stencil/utils/semantic_version'
|
13
14
|
require 'power_stencil/utils/file_helper'
|
14
15
|
require 'power_stencil/utils/directory_processor'
|
@@ -16,6 +17,7 @@ require 'power_stencil/utils/secure_require'
|
|
16
17
|
require 'power_stencil/utils/gem_utils'
|
17
18
|
require 'power_stencil/utils/file_edit'
|
18
19
|
require 'power_stencil/utils/graphviz'
|
20
|
+
require 'power_stencil/utils/completion'
|
19
21
|
|
20
22
|
require 'climatic/script/unimplemented_processor'
|
21
23
|
require 'power_stencil/project/proxy'
|
@@ -34,6 +36,7 @@ require 'power_stencil/command_processors/shell'
|
|
34
36
|
require 'power_stencil/command_processors/plugin'
|
35
37
|
require 'power_stencil/command_processors/build'
|
36
38
|
require 'power_stencil/command_processors/describe'
|
39
|
+
require 'power_stencil/command_processors/adm'
|
37
40
|
|
38
41
|
|
39
42
|
module PowerStencil
|
@@ -55,3 +58,4 @@ module PowerStencil
|
|
55
58
|
extend PowerStencil::Initializer
|
56
59
|
|
57
60
|
end
|
61
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module PowerStencil
|
2
|
+
module CommandProcessors
|
3
|
+
|
4
|
+
class Adm
|
5
|
+
|
6
|
+
include Climatic::Script::UnimplementedProcessor
|
7
|
+
include Climatic::Proxy
|
8
|
+
include PowerStencil::Project::Proxy
|
9
|
+
include PowerStencil::Utils::Completion
|
10
|
+
|
11
|
+
|
12
|
+
def execute
|
13
|
+
|
14
|
+
if config[:'zsh-completion']
|
15
|
+
generate_zsh_completion 'power_stencil'
|
16
|
+
return
|
17
|
+
end
|
18
|
+
|
19
|
+
if config[:'query-for-completion']
|
20
|
+
puts project.query_for_completion config[:'query-for-completion'].to_sym
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -29,7 +29,7 @@ module PowerStencil
|
|
29
29
|
end
|
30
30
|
return
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
if config[:list]
|
34
34
|
if project.plugins.empty?
|
35
35
|
puts 'No plugin used in this project.'
|
@@ -46,28 +46,23 @@ module PowerStencil
|
|
46
46
|
end
|
47
47
|
return
|
48
48
|
end
|
49
|
-
|
50
49
|
|
51
50
|
if config[:create]
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
msg
|
59
|
-
project.track_action_with_git(msg) do
|
60
|
-
project.create_new_local_plugin_tree plugin_name, target_path
|
61
|
-
puts_and_logs msg, check_verbose: false
|
62
|
-
end
|
63
|
-
|
64
|
-
rescue => e
|
65
|
-
msg = "Could not create plugin '#{plugin_name}' because '#{e.message}'"
|
66
|
-
puts msg
|
67
|
-
logger.error "Could not create plugin '#{plugin_name}' because '#{e.message}'"
|
68
|
-
logger.debug PowerStencil::Error.report_error(e)
|
51
|
+
plugin_name = config[:create]
|
52
|
+
begin
|
53
|
+
target_path = File.join project.project_local_plugin_path(plugin_name)
|
54
|
+
msg = "Generated new local plugin '#{plugin_name}'."
|
55
|
+
project.track_action_with_git(msg) do
|
56
|
+
project.create_new_local_plugin_tree plugin_name, target_path
|
57
|
+
puts_and_logs msg, check_verbose: false
|
69
58
|
end
|
59
|
+
rescue => e
|
60
|
+
msg = "Could not create plugin '#{plugin_name}' because '#{e.message}'"
|
61
|
+
puts msg
|
62
|
+
logger.error "Could not create plugin '#{plugin_name}' because '#{e.message}'"
|
63
|
+
logger.debug PowerStencil::Error.report_error(e)
|
70
64
|
end
|
65
|
+
|
71
66
|
return
|
72
67
|
end
|
73
68
|
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module PowerStencil
|
2
|
+
module Dsl
|
3
|
+
|
4
|
+
class Completion < PowerStencil::Dsl::Base
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_accessor :script_name
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :encountered_types
|
11
|
+
|
12
|
+
def initialize(universe)
|
13
|
+
super
|
14
|
+
@encountered_types = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def script_name
|
18
|
+
self.class.script_name
|
19
|
+
end
|
20
|
+
|
21
|
+
def root_command(commands)
|
22
|
+
commands.select { |c| c.name.empty? }.first
|
23
|
+
end
|
24
|
+
|
25
|
+
def command_summary(command)
|
26
|
+
text = command.help[0][0,60].tr("\n", ' ')
|
27
|
+
text.match(/^\s*(?<sentence>[^\s][^\.]+)\./) do |md|
|
28
|
+
return "#{md['sentence']} ..."
|
29
|
+
end
|
30
|
+
text
|
31
|
+
end
|
32
|
+
|
33
|
+
def command_representation(command, enclosing_dquote: true)
|
34
|
+
cr = "#{command.name}[#{command_summary command}]"
|
35
|
+
enclosing_dquote ? "\"#{cr}\"" : cr
|
36
|
+
end
|
37
|
+
|
38
|
+
def default_command_param_type(command, enclosing_dquote: true)
|
39
|
+
return '' if %i(bool boolean).include? command.type
|
40
|
+
default_cpt = "*:#{command.type}:_#{script_name}_#{command.type} "
|
41
|
+
type = command.type
|
42
|
+
|
43
|
+
encountered_types[type] ||=[]
|
44
|
+
encountered_types[type] << command unless encountered_types[type].include? command
|
45
|
+
enclosing_dquote ? "\"#{default_cpt}\"" : default_cpt
|
46
|
+
end
|
47
|
+
|
48
|
+
def option_representation(option, enclosing_dquote: true)
|
49
|
+
opr = "--#{option.name}[#{option.summary}]"
|
50
|
+
opr = if option.type.nil? or option.type.empty?
|
51
|
+
opr
|
52
|
+
else
|
53
|
+
if %i(bool boolean).include? option.type
|
54
|
+
opr
|
55
|
+
else
|
56
|
+
encountered_types[option.type] ||=[]
|
57
|
+
encountered_types[option.type] << option unless encountered_types[option.type].include? option
|
58
|
+
"#{opr}:#{option.type}:_#{ zsh_completion_from_type option.type} "
|
59
|
+
end
|
60
|
+
end
|
61
|
+
enclosing_dquote ? "\"#{opr}\"" : opr
|
62
|
+
end
|
63
|
+
|
64
|
+
def continued_multilines(lines, number_spaces: 4, cr: "\n", spaces_in_first_line: true, str_cont: ' \\')
|
65
|
+
return '' if lines.empty?
|
66
|
+
spaces = ' ' * number_spaces
|
67
|
+
first_line = true
|
68
|
+
res = lines.map do |line|
|
69
|
+
if first_line
|
70
|
+
fline = if spaces_in_first_line
|
71
|
+
"#{spaces}#{line}"
|
72
|
+
else
|
73
|
+
line
|
74
|
+
end
|
75
|
+
first_line = false
|
76
|
+
fline
|
77
|
+
else
|
78
|
+
"#{spaces}#{line}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
eol = str_cont + cr
|
82
|
+
res.join eol
|
83
|
+
end
|
84
|
+
|
85
|
+
def zsh_completion_from_type(type)
|
86
|
+
slop_class = type.to_s.split('_').map(&:capitalize).join + 'Option'
|
87
|
+
klass = Slop.const_get slop_class
|
88
|
+
klass::ZSH_TYPE
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
@@ -46,7 +46,8 @@ module PowerStencil
|
|
46
46
|
shell: PowerStencil::CommandProcessors::Shell,
|
47
47
|
plugin: PowerStencil::CommandProcessors::Plugin,
|
48
48
|
build: PowerStencil::CommandProcessors::Build,
|
49
|
-
describe: PowerStencil::CommandProcessors::Describe
|
49
|
+
describe: PowerStencil::CommandProcessors::Describe,
|
50
|
+
adm: PowerStencil::CommandProcessors::Adm
|
50
51
|
}.each do |command_name, processor|
|
51
52
|
command_line_manager.register_processor command_line_manager.command_by_alias(command_name),
|
52
53
|
processor.new
|
@@ -7,8 +7,8 @@ module PowerStencil
|
|
7
7
|
|
8
8
|
|
9
9
|
def register_processors
|
10
|
+
clm = PowerStencil.command_line_manager
|
10
11
|
plugin_definition[:processors].each do |processors_name, processor|
|
11
|
-
clm = PowerStencil.command_line_manager
|
12
12
|
processor_class = Object.const_get processor
|
13
13
|
clm.register_processor clm.command_by_alias(processors_name), processor_class.new
|
14
14
|
end
|
@@ -6,6 +6,7 @@ require 'power_stencil/project/info'
|
|
6
6
|
require 'power_stencil/project/templates'
|
7
7
|
require 'power_stencil/project/plugins'
|
8
8
|
require 'power_stencil/project/git'
|
9
|
+
require 'power_stencil/project/completion'
|
9
10
|
|
10
11
|
require 'power_stencil/engine/project_engine'
|
11
12
|
require 'power_stencil/engine/entity_engine'
|
@@ -32,6 +33,7 @@ module PowerStencil
|
|
32
33
|
include PowerStencil::Project::Plugins
|
33
34
|
include PowerStencil::Project::Info
|
34
35
|
include PowerStencil::Project::Git
|
36
|
+
include PowerStencil::Project::Completion
|
35
37
|
extend PowerStencil::Project::Create
|
36
38
|
|
37
39
|
attr_reader :engine, :entity_engine
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module PowerStencil
|
2
|
+
module Project
|
3
|
+
|
4
|
+
module Completion
|
5
|
+
|
6
|
+
def query_for_completion(query_type)
|
7
|
+
case query_type
|
8
|
+
when :entities
|
9
|
+
engine.entities(engine.root_universe).map(&:as_path).sort
|
10
|
+
when :'entity-types'
|
11
|
+
engine.available_entity_types.sort
|
12
|
+
when :scenario
|
13
|
+
engine.entities(engine.root_universe, criterion: :by_type, value: :entity_override) do |entity|
|
14
|
+
!entity.scenario.nil? and !entity.scenario.empty?
|
15
|
+
end.map(&:scenario).sort.uniq
|
16
|
+
else
|
17
|
+
raise PowerStencil::Error, "'#{query_type}' is not a valid query type for completion !"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module PowerStencil
|
2
|
+
module Utils
|
3
|
+
|
4
|
+
module Completion
|
5
|
+
|
6
|
+
include PowerStencil::Utils::DirectoryProcessor
|
7
|
+
|
8
|
+
def generate_zsh_completion(script_name)
|
9
|
+
|
10
|
+
# Dirty hack
|
11
|
+
config.executable_gem_layer[:file_renaming_patterns] = {'(.+)_power_stencil.sh.erb' => '\1_power_stencil' }
|
12
|
+
|
13
|
+
target_dir = File.expand_path config[:completion_target][:zsh][:completion_dir]
|
14
|
+
source_dir = File.join PowerStencil::Project::Paths.system_templates_templates_path, 'zsh_command_line_completion'
|
15
|
+
|
16
|
+
engine = PowerStencil::Engine::InitEngine.new
|
17
|
+
engine.dsl = PowerStencil::Dsl::Completion
|
18
|
+
engine.dsl.script_name = script_name
|
19
|
+
engine.render_source source_dir, target_dir, overwrite_files: true
|
20
|
+
|
21
|
+
puts_and_logs "zsh auto_completion has been installed in '#{File.join target_dir, "_#{script_name}"}'.", check_verbose: false
|
22
|
+
puts "You should ensure you have something like 'fpath=(#{target_dir} $fpath)' in your ~/.zshrc file..."
|
23
|
+
puts 'You may have to relog for changes to be applied.'
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Slop
|
2
|
+
|
3
|
+
# :file, :path, :log_level, :string, :array, :entity_type, :scenario
|
4
|
+
|
5
|
+
class StringOption
|
6
|
+
ZSH_TYPE = :power_stencil_do_nothing
|
7
|
+
end
|
8
|
+
|
9
|
+
class ArrayOption
|
10
|
+
ZSH_TYPE = :power_stencil_do_nothing
|
11
|
+
end
|
12
|
+
|
13
|
+
class LogLevelOption < IntegerOption
|
14
|
+
ZSH_TYPE = :power_stencil_log_level
|
15
|
+
end
|
16
|
+
|
17
|
+
class PathOption < StringOption
|
18
|
+
ZSH_TYPE = :path_files
|
19
|
+
end
|
20
|
+
class FileOption < StringOption
|
21
|
+
ZSH_TYPE = :files
|
22
|
+
end
|
23
|
+
|
24
|
+
class EntityOption < StringOption
|
25
|
+
ZSH_TYPE = :power_stencil_entity
|
26
|
+
end
|
27
|
+
|
28
|
+
class EntityTYpeOption < StringOption
|
29
|
+
ZSH_TYPE = :power_stencil_entity_type
|
30
|
+
end
|
31
|
+
|
32
|
+
class ScenarioOption < StringOption
|
33
|
+
ZSH_TYPE = :power_stencil_scenario
|
34
|
+
end
|
35
|
+
|
36
|
+
class CompletionQueryTypeOption < StringOption
|
37
|
+
ZSH_TYPE = :power_stencil_completion_query_type
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
data/power_stencil.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency 'rake', '~> 10.0'
|
26
26
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
27
27
|
|
28
|
-
spec.add_dependency 'climatic', '~> 0.2.
|
28
|
+
spec.add_dependency 'climatic', '~> 0.2.32'
|
29
29
|
spec.add_dependency 'dir_glob_ignore', '~> 0.3'
|
30
30
|
spec.add_dependency 'universe_compiler', '~> 0.5.1'
|
31
31
|
spec.add_dependency 'pry'
|
@@ -50,5 +50,8 @@ If your shell is not completing the command:
|
|
50
50
|
Official Website : #{spec.homepage}
|
51
51
|
Full documentation here : #{spec.metadata['source_code_uri']}/blob/master/README.md
|
52
52
|
Feel free to report issues: #{spec.metadata['source_code_uri']}/issues
|
53
|
+
|
54
|
+
Type 'power_stencil adm --zsh-completion' to install auto-completion for zsh.
|
55
|
+
|
53
56
|
}
|
54
57
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: power_stencil
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Laurent Briais
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.2.
|
61
|
+
version: 0.2.32
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.2.
|
68
|
+
version: 0.2.32
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: dir_glob_ignore
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -209,8 +209,11 @@ files:
|
|
209
209
|
- etc/templates/project/.ps_project/versioned-config.yaml
|
210
210
|
- etc/templates/project/.zzzgitignore.erb
|
211
211
|
- etc/templates/simple_exec/main.sh
|
212
|
+
- etc/templates/zsh_command_line_completion/.copy_ignore
|
213
|
+
- etc/templates/zsh_command_line_completion/_power_stencil.sh.erb
|
212
214
|
- exe/power_stencil
|
213
215
|
- lib/power_stencil.rb
|
216
|
+
- lib/power_stencil/command_processors/adm.rb
|
214
217
|
- lib/power_stencil/command_processors/build.rb
|
215
218
|
- lib/power_stencil/command_processors/check.rb
|
216
219
|
- lib/power_stencil/command_processors/create.rb
|
@@ -226,6 +229,7 @@ files:
|
|
226
229
|
- lib/power_stencil/command_processors/shell.rb
|
227
230
|
- lib/power_stencil/command_processors/trace_helper.rb
|
228
231
|
- lib/power_stencil/dsl/base.rb
|
232
|
+
- lib/power_stencil/dsl/completion.rb
|
229
233
|
- lib/power_stencil/dsl/entities.rb
|
230
234
|
- lib/power_stencil/dsl/plugin_generation.rb
|
231
235
|
- lib/power_stencil/engine/base.rb
|
@@ -252,6 +256,7 @@ files:
|
|
252
256
|
- lib/power_stencil/plugins/templates.rb
|
253
257
|
- lib/power_stencil/plugins/type.rb
|
254
258
|
- lib/power_stencil/project/base.rb
|
259
|
+
- lib/power_stencil/project/completion.rb
|
255
260
|
- lib/power_stencil/project/config.rb
|
256
261
|
- lib/power_stencil/project/create.rb
|
257
262
|
- lib/power_stencil/project/git.rb
|
@@ -273,6 +278,7 @@ files:
|
|
273
278
|
- lib/power_stencil/system_entity_definitions/project_entity.rb
|
274
279
|
- lib/power_stencil/system_entity_definitions/simple_exec.rb
|
275
280
|
- lib/power_stencil/system_entity_definitions/source_provider.rb
|
281
|
+
- lib/power_stencil/utils/completion.rb
|
276
282
|
- lib/power_stencil/utils/directory_processor.rb
|
277
283
|
- lib/power_stencil/utils/file_edit.rb
|
278
284
|
- lib/power_stencil/utils/file_helper.rb
|
@@ -281,6 +287,7 @@ files:
|
|
281
287
|
- lib/power_stencil/utils/os.rb
|
282
288
|
- lib/power_stencil/utils/secure_require.rb
|
283
289
|
- lib/power_stencil/utils/semantic_version.rb
|
290
|
+
- lib/power_stencil/utils/slop_extra_option_types.rb
|
284
291
|
- lib/power_stencil/version.rb
|
285
292
|
- power_stencil.gemspec
|
286
293
|
homepage: https://powerstencil.brizone.org/
|
@@ -291,11 +298,12 @@ metadata:
|
|
291
298
|
documentation_uri: https://gitlab.com/tools4devops/power_stencil/blob/master/README.md
|
292
299
|
source_code_uri: https://gitlab.com/tools4devops/power_stencil
|
293
300
|
homepage_uri: https://powerstencil.brizone.org/
|
294
|
-
post_install_message: "\nThank you for installing PowerStencil 0.
|
301
|
+
post_install_message: "\nThank you for installing PowerStencil 0.8.0 !\nFrom the command
|
295
302
|
line you can run `power_stencil --help`\nIf your shell is not completing the command:\n
|
296
303
|
\ If you use rbenv: `rbenv rehash`\n If you use zsh : `rehash`\n\nOfficial Website
|
297
304
|
\ : https://powerstencil.brizone.org/\nFull documentation here : https://gitlab.com/tools4devops/power_stencil/blob/master/README.md\nFeel
|
298
|
-
free to report issues: https://gitlab.com/tools4devops/power_stencil/issues\n
|
305
|
+
free to report issues: https://gitlab.com/tools4devops/power_stencil/issues\n\nType
|
306
|
+
'power_stencil adm --zsh-completion' to install auto-completion for zsh.\n\n "
|
299
307
|
rdoc_options: []
|
300
308
|
require_paths:
|
301
309
|
- lib
|