power_stencil 0.8.13 → 0.9.3
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 +27 -15
- data/doc/faq.md +4 -7
- data/doc/git_integration.md +38 -12
- data/etc/meta_templates/plugin_seed/.gitignore +12 -0
- data/etc/meta_templates/plugin_seed/.gitlab-ci.yml +11 -0
- data/etc/meta_templates/plugin_seed/README.md +20 -5
- data/etc/meta_templates/plugin_seed/etc/plugin_capabilities.yaml +3 -0
- data/etc/meta_templates/plugin_seed/psplugin_{entity}.gemspec +2 -0
- data/etc/meta_templates/plugin_seed/spec/project_helper.rb +50 -0
- data/etc/meta_templates/plugin_seed/spec/spec_helper.rb +2 -1
- data/etc/meta_templates/plugin_seed/spec/{entity}_spec.rb +21 -1
- data/etc/power_stencil.yaml +6 -1
- data/etc/templates/plugin_definition/.gitignore +2 -1
- data/etc/templates/plugin_definition/.gitlab-ci.yml +11 -0
- data/etc/templates/plugin_definition/README.md +20 -5
- data/etc/templates/plugin_definition/etc/plugin_capabilities.yaml +3 -0
- data/etc/templates/plugin_definition/psplugin_{entity}.gemspec +2 -0
- data/etc/templates/plugin_definition/spec/project_helper.rb +50 -0
- data/etc/templates/plugin_definition/spec/spec_helper.rb +2 -1
- data/etc/templates/plugin_definition/spec/{entity}_spec.rb +21 -1
- data/etc/templates/project/.ps_project/versioned-config.yaml +1 -0
- data/etc/templates/zsh_command_line_completion/_power_stencil.sh.erb +18 -8
- data/lib/power_stencil.rb +4 -0
- data/lib/power_stencil/command_processors/adm.rb +29 -1
- data/lib/power_stencil/command_processors/create.rb +14 -4
- data/lib/power_stencil/dsl/completion.rb +37 -0
- data/lib/power_stencil/engine/base.rb +2 -0
- data/lib/power_stencil/engine/directory_processor.rb +20 -1
- data/lib/power_stencil/engine/project_engine.rb +1 -1
- data/lib/power_stencil/engine/renderers/haml.rb +21 -0
- data/lib/power_stencil/initializer.rb +6 -1
- data/lib/power_stencil/plugins/base.rb +0 -1
- data/lib/power_stencil/plugins/capabilities.rb +4 -0
- data/lib/power_stencil/plugins/command_line.rb +3 -1
- data/lib/power_stencil/plugins/require.rb +6 -6
- data/lib/power_stencil/project/base.rb +2 -0
- data/lib/power_stencil/project/plugins.rb +35 -2
- data/lib/power_stencil/ultra_command_line/command_line_manager.rb +35 -0
- data/lib/power_stencil/ultra_command_line/option_definition.rb +5 -0
- data/lib/power_stencil/ultra_command_line/providers_manager.rb +21 -0
- data/lib/power_stencil/ultra_command_line/sub_command.rb +12 -0
- data/lib/power_stencil/utils/completion.rb +19 -9
- data/lib/power_stencil/utils/dependency_solver.rb +19 -0
- data/lib/power_stencil/version.rb +1 -1
- data/power_stencil.gemspec +2 -1
- metadata +35 -11
@@ -11,6 +11,8 @@ Gem::Specification.new do |spec|
|
|
11
11
|
|
12
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
|
+
# For official plugins
|
15
|
+
# spec.homepage = "https://powerstencil.brizone.org/#plugins"
|
14
16
|
spec.homepage = "TODO: Put your gem's website or public repo URL here."
|
15
17
|
spec.license = 'MIT'
|
16
18
|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module PowerStencilTests
|
2
|
+
|
3
|
+
module Project
|
4
|
+
|
5
|
+
TEMP_DIR_PREFIX = 'PS_TESTS_'
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
|
10
|
+
def temporary_project(project_name, with_git_support: false, scope: :all)
|
11
|
+
self.instance_eval do
|
12
|
+
puts scope
|
13
|
+
around(scope) do |execution|
|
14
|
+
Dir.mktmpdir(TEMP_DIR_PREFIX) do |tests_root_dir|
|
15
|
+
tmp_project_path = File.join tests_root_dir, project_name
|
16
|
+
create_project_including_this_plugin tmp_project_path, with_git_support: with_git_support
|
17
|
+
execution.run
|
18
|
+
@tmp_project_path = nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def plugin_path
|
25
|
+
File.expand_path File.join('..', '..'), __FILE__
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :tmp_project_path
|
31
|
+
|
32
|
+
def self.included(base)
|
33
|
+
base.extend(ClassMethods)
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_project_including_this_plugin(project_path, with_git_support: false)
|
37
|
+
cmd = "power_stencil init --project-path '#{project_path}'"
|
38
|
+
cmd << ' --no-git' unless with_git_support
|
39
|
+
`#{cmd}`
|
40
|
+
project_plugin_path = File.join project_path, '.ps_project', 'plugins'
|
41
|
+
`ln -s '#{self.class.plugin_path}' '#{project_plugin_path}'`
|
42
|
+
@tmp_project_path = project_path
|
43
|
+
end
|
44
|
+
|
45
|
+
def temporary_project_cmd(params)
|
46
|
+
"power_stencil #{params} --project-path '#{tmp_project_path}'"
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -1,10 +1,30 @@
|
|
1
1
|
RSpec.describe <%= plugin_module_name %> do
|
2
|
+
|
3
|
+
include PowerStencilTests::Project
|
4
|
+
temporary_project 'test_project', scope: :all
|
5
|
+
|
6
|
+
let(:plugin_list) { 'plugin --list' }
|
7
|
+
let(:test_entity) { '<%= plugin_name %>_entity/test_<%= plugin_name %>' }
|
8
|
+
let(:create_<%= plugin_name %>) { "create #{test_entity}" }
|
9
|
+
let(:get_<%= plugin_name %>) { "get #{test_entity}" }
|
10
|
+
|
2
11
|
it 'has a version number' do
|
3
12
|
expect(<%= plugin_module_name %>::VERSION).not_to be nil
|
4
13
|
end
|
5
14
|
|
6
|
-
it '
|
15
|
+
it 'should add a "<%= plugin_name %>" sub-command' do
|
16
|
+
expect(`#{temporary_project_cmd plugin_list}`).to match '- <%= plugin_name %>'
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should be possible to create a "<%= plugin_name %>_entity"' do
|
20
|
+
`#{temporary_project_cmd create_<%= plugin_name %>}`
|
21
|
+
expect($?.success?).to be_truthy
|
22
|
+
expect(`#{temporary_project_cmd get_<%= plugin_name %>}`).not_to be_empty
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should do something useful' do
|
7
26
|
pending 'Tests implementation'
|
8
27
|
RSpec.fail
|
9
28
|
end
|
29
|
+
|
10
30
|
end
|
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
# zsh shell completion script for <%= script_name %>
|
4
4
|
# To regenerate this file: '<%= script_name %> adm --zsh-completion'
|
5
|
-
# Generated
|
5
|
+
# Generated<%= timestamp %> by <%= script_name %> v<%= PowerStencil::VERSION %>
|
6
6
|
|
7
|
-
<% commands =
|
8
|
-
_<%= script_name %>() {
|
7
|
+
<% commands = context_commands -%>
|
8
|
+
_<%= script_name %>_first_level() {
|
9
9
|
local cmd
|
10
10
|
local <%= script_name %>_sub_commands
|
11
11
|
<%= script_name %>_sub_commands=(<%= commands.reject { |c| c.name.empty? }.sort { |a,b| a.name <=> b.name }.map(&:name).join ' ' %>)
|
@@ -21,7 +21,7 @@ _<%= script_name %>() {
|
|
21
21
|
(( $+functions[_<%= script_name %>_cmd_$cmd] )) && _<%= script_name %>_cmd_$cmd
|
22
22
|
else
|
23
23
|
_values : \
|
24
|
-
<%= continued_multilines(root_command
|
24
|
+
<%= continued_multilines(context_options(root_command commands).sort { |a,b| a.name <=> b.name }.map {|o| option_representation o}, number_spaces: 10) %>
|
25
25
|
fi
|
26
26
|
else
|
27
27
|
_values : \
|
@@ -33,7 +33,7 @@ _<%= script_name %>() {
|
|
33
33
|
<% end -%>
|
34
34
|
<%= command_representation command %> \
|
35
35
|
<% end -%>
|
36
|
-
<%= continued_multilines(root_command.
|
36
|
+
<%= continued_multilines(context_options(root_command).sort { |a,b| a.name <=> b.name }.map {|o| option_representation o}, number_spaces: 8) %>
|
37
37
|
fi
|
38
38
|
}
|
39
39
|
|
@@ -46,7 +46,7 @@ _<%= script_name %>_cmd_<%= command.name %>() {
|
|
46
46
|
_arguments -s : \
|
47
47
|
<%
|
48
48
|
command_param = default_command_param_type command
|
49
|
-
options_lines = command.
|
49
|
+
options_lines = context_options(command).sort { |a,b| a.name <=> b.name }.map {|o| option_representation o}
|
50
50
|
options_lines << command_param unless command_param.empty?
|
51
51
|
-%>
|
52
52
|
<%= continued_multilines(options_lines) %>
|
@@ -124,5 +124,15 @@ _power_stencil_do_nothing() {
|
|
124
124
|
return 1
|
125
125
|
}
|
126
126
|
|
127
|
-
|
128
|
-
_<%= script_name %>
|
127
|
+
|
128
|
+
_<%= script_name %>() {
|
129
|
+
if $( _within_power_stencil_project ); then
|
130
|
+
local project_root=$( _power_stencil_project_root )
|
131
|
+
if [ -f "${project_root}/.ps_project/<%= PowerStencil.config[:completion_target][:zsh][:project_completion_filename] %>" ]; then
|
132
|
+
. "${project_root}/.ps_project/<%= PowerStencil.config[:completion_target][:zsh][:project_completion_filename] %>"
|
133
|
+
fi
|
134
|
+
else
|
135
|
+
. "<%= File.expand_path(File.join PowerStencil.config[:completion_target][:zsh][:completion_dir], "_#{script_name}") %>"
|
136
|
+
fi
|
137
|
+
_<%= script_name %>_first_level "$@"
|
138
|
+
}
|
data/lib/power_stencil.rb
CHANGED
@@ -5,6 +5,10 @@ require 'dir_glob_ignore'
|
|
5
5
|
|
6
6
|
$DO_NOT_AUTOSTART_CLIMATIC=true
|
7
7
|
require 'climatic'
|
8
|
+
require 'power_stencil/ultra_command_line/command_line_manager'
|
9
|
+
require 'power_stencil/ultra_command_line/providers_manager'
|
10
|
+
require 'power_stencil/ultra_command_line/option_definition'
|
11
|
+
require 'power_stencil/ultra_command_line/sub_command'
|
8
12
|
|
9
13
|
require 'power_stencil/error'
|
10
14
|
require 'power_stencil/utils/os'
|
@@ -12,7 +12,35 @@ module PowerStencil
|
|
12
12
|
def execute
|
13
13
|
|
14
14
|
if config[:'zsh-completion']
|
15
|
-
|
15
|
+
target_dir = File.expand_path config[:completion_target][:zsh][:completion_dir]
|
16
|
+
script_name = 'power_stencil'
|
17
|
+
user_completion_script = File.join target_dir, "_#{script_name}"
|
18
|
+
begin
|
19
|
+
current_dir = Dir.pwd
|
20
|
+
Dir.mktmpdir 'completion_generation' do |tmpdir|
|
21
|
+
Dir.chdir tmpdir
|
22
|
+
generate_zsh_completion script_name, user_completion_script, false
|
23
|
+
end
|
24
|
+
ensure
|
25
|
+
Dir.chdir current_dir
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
project
|
30
|
+
shortname_project_completion_script = File.join config[:default_config_directory_name], config[:completion_target][:zsh][:project_completion_filename]
|
31
|
+
project.track_action_with_git("Adding project specific zsh completion file: '#{ shortname_project_completion_script }'.") do
|
32
|
+
project_completion_script = File.join project.project_config_root, config[:completion_target][:zsh][:project_completion_filename]
|
33
|
+
generate_zsh_completion script_name, project_completion_script, true
|
34
|
+
puts_and_logs "A specific completion has been generated for this project in '#{project_completion_script}'.", check_verbose: false
|
35
|
+
end
|
36
|
+
rescue
|
37
|
+
# Do not check errors. This is just to load project config...
|
38
|
+
logger.debug "Outside of a PowerStencil project... Not generating zsh project completion."
|
39
|
+
end
|
40
|
+
puts_and_logs "zsh global auto_completion has been installed in '#{user_completion_script}'.", check_verbose: false
|
41
|
+
puts
|
42
|
+
puts "You should ensure you have something like 'fpath=(#{target_dir} $fpath)' in your ~/.zshrc file..."
|
43
|
+
puts 'You may have to relog for changes to be applied.'
|
16
44
|
return
|
17
45
|
end
|
18
46
|
|
@@ -17,8 +17,17 @@ module PowerStencil
|
|
17
17
|
unless config[:property].nil?
|
18
18
|
config[:property].each do |property_def|
|
19
19
|
if md = property_def.match(/^\s*(?<prop_name>[^:=]+)\s*[:=]\s*(?<prop_val>.*)\s*$/)
|
20
|
-
|
21
|
-
|
20
|
+
property_value = md['prop_val']
|
21
|
+
logger.debug "Using extra properties from command line '#{md['prop_name']}' = '#{property_value}'"
|
22
|
+
if pmd = property_value.match(/^\s*!entity\s+(?<entity_type>[^\/]+)\/(?<entity_name>.*)\s*$/)
|
23
|
+
type = pmd['entity_type'].to_sym
|
24
|
+
name = pmd['entity_name']
|
25
|
+
referenced_entity = project.engine.entity(type, name)
|
26
|
+
property_value = referenced_entity.to_reference unless referenced_entity.nil?
|
27
|
+
puts_and_logs "Could not find entity '#{type.to_s}/#{name}' !", logs_as: :error, check_verbose: false if referenced_entity.nil?
|
28
|
+
end
|
29
|
+
|
30
|
+
entity_as_hash[md['prop_name'].to_sym] = property_value
|
22
31
|
else
|
23
32
|
raise PowerStencil::Error, "Invalid command line property definition: '#{property_def}'"
|
24
33
|
end
|
@@ -35,14 +44,16 @@ module PowerStencil
|
|
35
44
|
new_entity = edit_before_save new_entity
|
36
45
|
end
|
37
46
|
|
47
|
+
new_entity.resolve_fields_references!
|
48
|
+
|
38
49
|
new_entity.valid? raise_error: true
|
39
50
|
project.track_action_with_git("Created '#{new_entity.as_path}' (and potential dependencies).") do
|
40
51
|
new_entity.save
|
41
52
|
end
|
42
53
|
puts_and_logs "Generated templates in '#{new_entity.templates_path}'.", check_verbose: false if new_entity.buildable?
|
43
54
|
rescue => e
|
44
|
-
puts_and_logs "Failed to create '#{search_criterion.as_path}' with message '#{e.message}'.", logs_as: :error, check_verbose: false
|
45
55
|
logger.debug PowerStencil::Error.report_error(e)
|
56
|
+
raise PowerStencil::Error, "Failed to create '#{search_criterion.as_path}' with message '#{e.message}'."
|
46
57
|
end
|
47
58
|
end
|
48
59
|
end
|
@@ -63,7 +74,6 @@ module PowerStencil
|
|
63
74
|
modifications_valid? modified_path, entity
|
64
75
|
end
|
65
76
|
project.engine.root_universe.replace entity, modified_entity
|
66
|
-
modified_entity.resolve_fields_references!
|
67
77
|
modified_entity
|
68
78
|
end
|
69
79
|
|
@@ -5,15 +5,52 @@ module PowerStencil
|
|
5
5
|
|
6
6
|
class << self
|
7
7
|
attr_accessor :script_name
|
8
|
+
attr_accessor :generating_project_completion
|
8
9
|
end
|
9
10
|
|
10
11
|
attr_reader :encountered_types
|
11
12
|
|
13
|
+
def timestamp
|
14
|
+
if generating_user_completion?
|
15
|
+
" on the #{Time.now}"
|
16
|
+
else
|
17
|
+
''
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
12
21
|
def initialize(universe)
|
13
22
|
super
|
14
23
|
@encountered_types = {}
|
15
24
|
end
|
16
25
|
|
26
|
+
def generating_project_completion?
|
27
|
+
self.class.generating_project_completion
|
28
|
+
end
|
29
|
+
|
30
|
+
def generating_user_completion?
|
31
|
+
!self.class.generating_project_completion
|
32
|
+
end
|
33
|
+
|
34
|
+
def context_commands
|
35
|
+
if generating_user_completion?
|
36
|
+
PowerStencil.command_line_manager.commands.select do |command|
|
37
|
+
command.providers.include? PowerStencil
|
38
|
+
end
|
39
|
+
else
|
40
|
+
PowerStencil.command_line_manager.commands
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def context_options(command)
|
45
|
+
if generating_user_completion?
|
46
|
+
command.options.select do |option|
|
47
|
+
option.providers.include? PowerStencil
|
48
|
+
end
|
49
|
+
else
|
50
|
+
command.options
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
17
54
|
def script_name
|
18
55
|
self.class.script_name
|
19
56
|
end
|
@@ -2,6 +2,7 @@ require 'power_stencil/engine/entities_definitions'
|
|
2
2
|
require 'power_stencil/engine/directory_processor'
|
3
3
|
|
4
4
|
require 'power_stencil/engine/renderers/erb'
|
5
|
+
require 'power_stencil/engine/renderers/haml'
|
5
6
|
require 'power_stencil/dsl/base'
|
6
7
|
require 'power_stencil/dsl/plugin_generation'
|
7
8
|
require 'power_stencil/dsl/completion'
|
@@ -18,6 +19,7 @@ module PowerStencil
|
|
18
19
|
include PowerStencil::Engine::DirectoryProcessor
|
19
20
|
|
20
21
|
include PowerStencil::Engine::Renderers::Erb
|
22
|
+
include PowerStencil::Engine::Renderers::Haml
|
21
23
|
|
22
24
|
attr_accessor :dsl
|
23
25
|
attr_reader :root_universe
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'erb'
|
3
|
+
require 'haml'
|
4
|
+
|
3
5
|
|
4
6
|
module PowerStencil
|
5
7
|
module Engine
|
@@ -30,10 +32,27 @@ module PowerStencil
|
|
30
32
|
end
|
31
33
|
end
|
32
34
|
ensure
|
33
|
-
@
|
35
|
+
@files_not_to_rename = nil
|
34
36
|
@files_not_to_render = nil
|
35
37
|
end
|
36
38
|
|
39
|
+
|
40
|
+
def render_single_template_file(source_template, destination_file, main_entry_point: nil)
|
41
|
+
compiled_universe = root_universe.compile scenario: config[:scenario]
|
42
|
+
puts_and_logs 'Entities analysis completed.'
|
43
|
+
|
44
|
+
logger.info 'Generating target file...'
|
45
|
+
|
46
|
+
process_file source_template, destination_file,
|
47
|
+
compiled_universe,
|
48
|
+
overwrite_files: true,
|
49
|
+
main_entry_point: main_entry_point
|
50
|
+
ensure
|
51
|
+
@files_not_to_rename = nil
|
52
|
+
@files_not_to_render = nil
|
53
|
+
end
|
54
|
+
|
55
|
+
|
37
56
|
private
|
38
57
|
|
39
58
|
def detemplatized_file_name(filename, replacement_text)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module PowerStencil
|
2
|
+
module Engine
|
3
|
+
module Renderers
|
4
|
+
|
5
|
+
module Haml
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def render_haml_template(source, context)
|
10
|
+
logger.debug "Using HAML to render file '#{source}'"
|
11
|
+
::Haml::Engine.new(File.read source).render(context)
|
12
|
+
rescue => e
|
13
|
+
logger.debug PowerStencil::Error.report_error(e)
|
14
|
+
raise PowerStencil::Error, "Error rendering '#{source}': '#{e.message}'"
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -55,14 +55,19 @@ module PowerStencil
|
|
55
55
|
describe: PowerStencil::CommandProcessors::Describe,
|
56
56
|
adm: PowerStencil::CommandProcessors::Adm
|
57
57
|
}.each do |command_name, processor|
|
58
|
-
|
58
|
+
command = command_line_manager.command_by_alias(command_name)
|
59
|
+
command_line_manager.register_processor command,
|
59
60
|
processor.new
|
61
|
+
command.add_provider self
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
63
65
|
def setup_climatic(cmd_line_args)
|
64
66
|
mngr = Climatic::ConfigLayers::CommandLineLayer.build_command_line_manager base_commands_definition_file
|
65
67
|
Climatic.bootstrap cmd_line_args: cmd_line_args, command_manager: mngr
|
68
|
+
mngr.commands.each do |command|
|
69
|
+
command.add_provider PowerStencil
|
70
|
+
end
|
66
71
|
begin
|
67
72
|
# Fix command line layer priority to allow a bigger number of plugins
|
68
73
|
config.command_line_layer.priority = 999
|