power_stencil 0.8.13 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|