power_stencil 0.6.3 → 0.7.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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +2 -0
  3. data/README.md +3 -7
  4. data/doc/entities.md +8 -8
  5. data/doc/images/power-stencil-entity-creation.svg +247 -114
  6. data/doc/templates.md +22 -18
  7. data/etc/base_commands_definition.yml +14 -0
  8. data/etc/power_stencil.yaml +7 -1
  9. data/etc/templates/project/.zzzgitignore.erb +8 -3
  10. data/lib/power_stencil.rb +1 -0
  11. data/lib/power_stencil/command_processors/create.rb +6 -5
  12. data/lib/power_stencil/command_processors/delete.rb +23 -15
  13. data/lib/power_stencil/command_processors/edit.rb +4 -2
  14. data/lib/power_stencil/command_processors/plugin.rb +6 -2
  15. data/lib/power_stencil/command_processors/shell.rb +10 -3
  16. data/lib/power_stencil/dsl/entities.rb +0 -16
  17. data/lib/power_stencil/engine/entities_handling.rb +1 -1
  18. data/lib/power_stencil/engine/project_engine.rb +5 -9
  19. data/lib/power_stencil/plugins/templates.rb +2 -2
  20. data/lib/power_stencil/project/base.rb +15 -12
  21. data/lib/power_stencil/project/create.rb +23 -2
  22. data/lib/power_stencil/project/git.rb +75 -0
  23. data/lib/power_stencil/project/info.rb +1 -1
  24. data/lib/power_stencil/project/paths.rb +22 -6
  25. data/lib/power_stencil/project/plugins.rb +1 -1
  26. data/lib/power_stencil/project/templates.rb +15 -22
  27. data/lib/power_stencil/system_entity_definitions/all.rb +1 -1
  28. data/lib/power_stencil/system_entity_definitions/buildable.rb +1 -1
  29. data/lib/power_stencil/system_entity_definitions/entity_override.rb +5 -0
  30. data/lib/power_stencil/system_entity_definitions/entity_project_common.rb +12 -4
  31. data/lib/power_stencil/system_entity_definitions/{has_associated_files.rb → entity_templates.rb} +2 -2
  32. data/lib/power_stencil/system_entity_definitions/project_config.rb +1 -1
  33. data/lib/power_stencil/system_entity_definitions/project_entity.rb +6 -0
  34. data/lib/power_stencil/system_entity_definitions/simple_exec.rb +2 -2
  35. data/lib/power_stencil/version.rb +1 -1
  36. data/power_stencil.gemspec +1 -0
  37. metadata +19 -4
@@ -5,6 +5,8 @@ module PowerStencil
5
5
 
6
6
  module Create
7
7
 
8
+ INITIAL_REPOSITORY_COMMIT_MESSAGE = 'Initial commit for project "%s".'
9
+
8
10
  include Climatic::Proxy
9
11
 
10
12
  def create_project_tree(path, config_directory_name = PowerStencil.config[:default_config_directory_name])
@@ -14,14 +16,33 @@ module PowerStencil
14
16
  raise PowerStencil::Error, "The directory '#{path}' already contains a PowerStencil project !" unless config[:force]
15
17
  end
16
18
  logger.info "Creating project in '#{path}'..."
17
- render_project_template_in(path)
19
+ render_project_template_in path
20
+ initialize_git_repository path
18
21
  end
19
22
 
20
23
  private
21
24
 
25
+ def initialize_git_repository(repo_path)
26
+ if config[:'no-git']
27
+ puts_and_logs 'Do not initialize project git repository as per config request.', logs_as: :debug
28
+ return
29
+ end
30
+ if Dir.exists? File.join(repo_path, '.git')
31
+ puts_and_logs 'Git repository already exists. Skipping.', logs_as: :debug, check_verbose: false
32
+ return
33
+ end
34
+ puts_and_logs 'Initializing git repository...', logs_as: :debug
35
+ git = ::Git.init repo_path
36
+ logger.debug 'Adding all files.'
37
+ git.add repo_path
38
+ logger.debug 'Committing initial status'
39
+ commit_msg = INITIAL_REPOSITORY_COMMIT_MESSAGE % [File.basename(repo_path)]
40
+ git.commit_all commit_msg
41
+ end
42
+
22
43
  def render_project_template_in(new_project_config_path)
23
44
  engine = PowerStencil::Engine::InitEngine.new
24
- engine.render_source PowerStencil::Project::Paths.project_system_template_path, new_project_config_path
45
+ engine.render_source PowerStencil::Project::Paths.project_system_template_template_path, new_project_config_path
25
46
  end
26
47
 
27
48
  end
@@ -0,0 +1,75 @@
1
+ module PowerStencil
2
+ module Project
3
+
4
+ module Git
5
+
6
+ include Climatic::Utils::Input
7
+
8
+ def track_action_with_git(action_message,
9
+ user_validation_required: false,
10
+ validation_message: 'Commit changes ?',
11
+ show_files_to_commit: false,
12
+ &block)
13
+ return yield if git.nil?
14
+
15
+ status_before_action = git.status
16
+ yield
17
+ status_after_action = git.status
18
+
19
+ files_introduced_by_action = status_after_action.untracked.reject { |f| status_before_action.untracked.keys.include? f}
20
+ files_deleted_by_action = status_after_action.deleted.reject { |f| status_before_action.deleted.keys.include? f}
21
+ files_modified_by_action = status_after_action.changed.reject { |f| status_before_action.changed.keys.include? f}
22
+ files_to_commit = [files_introduced_by_action, files_deleted_by_action, files_modified_by_action].map(&:keys).flatten.sort.uniq
23
+
24
+ if files_to_commit.empty?
25
+ puts_and_logs 'Nothing to commit.'
26
+ return
27
+ end
28
+
29
+ if show_files_to_commit
30
+ header = 'Following file'
31
+ header << 's' if files_to_commit.count > 1
32
+ header << ' will be committed:'
33
+ puts header
34
+ puts files_to_commit.map { |filename| " - '#{filename}'" }
35
+ end
36
+
37
+ if user_validation_required
38
+ unless get_user_confirmation(default_choice: 'Yes', prompt: validation_message)
39
+ puts_and_logs 'Commit cancelled by user.', check_verbose: false
40
+ return
41
+ end
42
+ end
43
+
44
+ files_to_commit.each { |filename| git.add filename }
45
+
46
+ # Verify files to be committed really are
47
+ files_really_to_be_committed = git.diff.stats[:files].keys.select { |filename| files_to_commit.include? filename }
48
+ return if files_really_to_be_committed.empty?
49
+ files_really_to_be_committed.each { |filename| logger.info "File '#{filename}' will be committed" }
50
+
51
+ git.commit action_message
52
+ puts_and_logs 'All changes introduced have been committed.'
53
+ end
54
+
55
+ private
56
+
57
+ attr_reader :git
58
+
59
+ def setup_git_tracking
60
+ @git = nil
61
+ if config[:'no-git']
62
+ logger.debug "Won't track any changes with git as per config request!"
63
+ return
64
+ end
65
+ @git = ::Git.open(self.project_root, :log => PowerStencil.logger)
66
+ logger.debug 'Following project changes with git'
67
+ rescue => e
68
+ logger.debug PowerStencil::Error.report_error(e)
69
+ logger.warn 'This project is not managed by git'
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+ end
@@ -73,7 +73,7 @@ module PowerStencil
73
73
  end
74
74
 
75
75
  msg << " (provided by #{source_provider_display})"
76
- msg << " template-template path: '#{entity_type_templates[type]}'" unless entity_type_templates[type].nil?
76
+ msg << " template-template path: '#{entity_type_templates_templates[type]}'" unless entity_type_templates_templates[type].nil?
77
77
  report << msg
78
78
  end
79
79
  report
@@ -7,12 +7,12 @@ module PowerStencil
7
7
 
8
8
  attr_reader :project_config_root, :started_from
9
9
 
10
- def self.system_templates_path
10
+ def self.system_templates_templates_path
11
11
  File.expand_path File.join('..', '..', '..', '..', 'etc', 'templates'), __FILE__
12
12
  end
13
13
 
14
- def self.project_system_template_path
15
- File.join system_templates_path, 'project'
14
+ def self.project_system_template_template_path
15
+ File.join system_templates_templates_path, 'project'
16
16
  end
17
17
 
18
18
  def build_run_path(seed)
@@ -31,8 +31,8 @@ module PowerStencil
31
31
  File.join project_root, PowerStencil.config[:project_build_root_directory_name]
32
32
  end
33
33
 
34
- def template_path(entity_type)
35
- File.join PowerStencil::Project::Paths.system_templates_path, entity_type.to_s
34
+ def system_template_template_path(entity_type)
35
+ File.join PowerStencil::Project::Paths.system_templates_templates_path, entity_type.to_s
36
36
  end
37
37
 
38
38
  def project_local_plugins_path
@@ -43,10 +43,26 @@ module PowerStencil
43
43
  File.join project_local_plugins_path, plugin_name
44
44
  end
45
45
 
46
- def project_templates_path
46
+ def project_templates_templates_path
47
47
  File.join project_config_root, PowerStencil.config[:project_templates_directory_name]
48
48
  end
49
49
 
50
+ def entities_template_path
51
+ File.join project_root, PowerStencil.config[:versioned_entities_templates_directory_name]
52
+ end
53
+
54
+ def user_entities_template_path
55
+ File.join project_root, PowerStencil.config[:unversioned_user_entities_templates_directory_name]
56
+ end
57
+
58
+ def entity_template_path(entity)
59
+ if entity.is_versioned_entity?
60
+ File.join entities_template_path, entity.type.to_s, entity.name
61
+ else
62
+ File.join user_entities_template_path, entity.type.to_s, entity.name
63
+ end
64
+ end
65
+
50
66
  def project_entity_definitions_path
51
67
  File.join project_config_root, PowerStencil.config[:project_entity_definitions_directory_name]
52
68
  end
@@ -11,7 +11,7 @@ module PowerStencil
11
11
  raise PowerStencil::Error, "Plugin '#{plugin_name}' already exists !" if plugins.keys.include? plugin_name
12
12
  raise PowerStencil::Error, "Invalid plugin name '#{plugin_name}'" if (plugin_name.underscore =~ /^[_[:lower:]][_[:alnum:]]*$/).nil?
13
13
  entity_engine.dsl = PowerStencil::Dsl::PluginGeneration
14
- entity_engine.render_source entity_type_templates[:plugin_definition],
14
+ entity_engine.render_source entity_type_templates_templates[:plugin_definition],
15
15
  new_plugin_path,
16
16
  overwrite_files: overwrite_files,
17
17
  main_entry_point: plugin_name
@@ -3,48 +3,41 @@ module PowerStencil
3
3
 
4
4
  module Templates
5
5
 
6
- def setup_templates_for_entities
7
- plugins.each do |plugin_name, plugin|
8
- logger.debug "Checking if plugin '#{plugin_name}' declares some templates..."
9
- plugin.register_plugin_templates
10
- end
11
- end
12
-
13
- def entity_type_templates
14
- @entity_type_templates ||= {}
6
+ def entity_type_templates_templates
7
+ @entity_type_templates_templates ||= {}
15
8
  end
16
9
 
17
- def register_template_path_for_type(entity_type, path)
18
- if entity_type_templates.include? entity_type
19
- logger.warn "There is already a template-template path registered for entity type '#{entity_type}': '#{entity_type_templates[entity_type]}'."
10
+ def register_template_template_path_for_type(entity_type, path)
11
+ if entity_type_templates_templates.include? entity_type
12
+ logger.warn "There is already a template-template path registered for entity type '#{entity_type}': '#{entity_type_templates_templates[entity_type]}'."
20
13
  end
21
14
  raise PowerStencil::Error, "There is no template in path: '#{path}'" unless Dir.exist? path and File.readable? path
22
15
  raise PowerStencil::Error, "Trying to register a template for non existing type '#{entity_type}'" unless engine.available_entity_types.include? entity_type
23
16
  logger.debug "Registering '#{path}' as template for type '#{entity_type}'."
24
- entity_type_templates[entity_type] = path
17
+ entity_type_templates_templates[entity_type] = path
25
18
  end
26
19
 
27
- def generate_entity_dir_for_entity(entity, force: false)
28
- unless entity_type_templates[entity.type].nil?
20
+ def generate_template_dir_for_entity(entity, force: false)
21
+ unless entity_type_templates_templates[entity.type].nil?
29
22
  logger.debug "Generating entity dir for entity '#{entity.as_path}'"
30
- target_path = File.join project_root, entity.type.to_s, entity.name.to_s
31
- render_entity_template_in entity, target_path, force: force
23
+ target_path = entity.templates_path
24
+ render_entity_template_template_in entity, target_path, force: force
32
25
  end
33
26
  end
34
27
 
35
- def delete_entity_dir_for_entity(entity, force: false)
28
+ def delete_template_dir_for_entity(entity, force: false)
36
29
  return unless force
37
- unless entity_type_templates[entity.type].nil?
30
+ unless entity_type_templates_templates[entity.type].nil?
38
31
  logger.debug "Deleting entity files for entity '#{entity.as_path}'"
39
- target_path = File.join project_root, entity.type.to_s, entity.name.to_s
32
+ target_path = entity.templates_path
40
33
  FileUtils.rmtree target_path unless target_path.nil? or target_path.empty?
41
34
  end
42
35
  end
43
36
 
44
37
  private
45
38
 
46
- def render_entity_template_in(entity, entity_dir_path, force: false)
47
- entity_engine.render_source entity_type_templates[entity.type],
39
+ def render_entity_template_template_in(entity, entity_dir_path, force: false)
40
+ entity_engine.render_source entity_type_templates_templates[entity.type],
48
41
  entity_dir_path,
49
42
  overwrite_files: force,
50
43
  main_entry_point: entity.name
@@ -2,7 +2,7 @@
2
2
  # So it is safe to declare files in the order you need.
3
3
 
4
4
  require 'power_stencil/system_entity_definitions/non_persistent'
5
- require 'power_stencil/system_entity_definitions/has_associated_files'
5
+ require 'power_stencil/system_entity_definitions/entity_templates'
6
6
  require 'power_stencil/system_entity_definitions/source_provider'
7
7
  require 'power_stencil/system_entity_definitions/buildable'
8
8
  require 'power_stencil/system_entity_definitions/entity_project_common'
@@ -10,7 +10,7 @@ module PowerStencil
10
10
  def buildable_by(plugin_name = nil)
11
11
  return @build_plugin_name if plugin_name.nil?
12
12
  @build_plugin_name = plugin_name
13
- self.include PowerStencil::SystemEntityDefinitions::HasAssociatedFiles
13
+ self.include PowerStencil::SystemEntityDefinitions::EntityTemplates
14
14
  end
15
15
 
16
16
  def buildable?
@@ -6,4 +6,9 @@ class UniverseCompiler::Entity::Override
6
6
 
7
7
  field :description
8
8
 
9
+ def initialize(fields: {}, universe: nil, user: false)
10
+ @is_versioned_entity = not(user)
11
+ super(fields: fields, universe: universe)
12
+ end
13
+
9
14
  end
@@ -3,17 +3,25 @@ module PowerStencil
3
3
 
4
4
  module EntityProjectCommon
5
5
 
6
+ def is_versioned_entity?
7
+ @is_versioned_entity
8
+ end
9
+
10
+ def is_user_entity?
11
+ not(@is_versioned_entity)
12
+ end
13
+
6
14
  def save(uri = source_uri, raise_error: true, force_save: false, force_files_generation: false )
7
15
  super(source_uri, raise_error: raise_error, force_save: force_save)
8
- unless PowerStencil.project.entity_type_templates[type].nil?
9
- PowerStencil.project.generate_entity_dir_for_entity self, force: force_files_generation
16
+ unless PowerStencil.project.entity_type_templates_templates[type].nil?
17
+ PowerStencil.project.generate_template_dir_for_entity self, force: force_files_generation
10
18
  end
11
19
  self
12
20
  end
13
21
 
14
22
  def delete(force_files_deletion: false)
15
- unless PowerStencil.project.entity_type_templates[type].nil?
16
- PowerStencil.project.delete_entity_dir_for_entity self, force: force_files_deletion
23
+ unless PowerStencil.project.entity_type_templates_templates[type].nil?
24
+ PowerStencil.project.delete_template_dir_for_entity self, force: force_files_deletion
17
25
  end
18
26
  super()
19
27
  self
@@ -1,10 +1,10 @@
1
1
  module PowerStencil
2
2
  module SystemEntityDefinitions
3
3
 
4
- module HasAssociatedFiles
4
+ module EntityTemplates
5
5
 
6
6
  def templates_path
7
- File.join PowerStencil.project.project_root, type.to_s, name
7
+ PowerStencil.project.entity_template_path self
8
8
  end
9
9
 
10
10
  end
@@ -11,7 +11,7 @@ module PowerStencil
11
11
 
12
12
  field_reader :simulate, :debug
13
13
 
14
- def initialize(fields: {}, universe: nil)
14
+ def initialize(fields: {}, universe: nil, user: false)
15
15
  super
16
16
  self.name = 'Project Config'
17
17
  end
@@ -11,6 +11,12 @@ module PowerStencil
11
11
 
12
12
  field :description
13
13
 
14
+ def initialize(fields: {}, universe: nil, user: false)
15
+ @is_versioned_entity = not(user)
16
+ super(fields: fields, universe: universe)
17
+ end
18
+
19
+
14
20
  end
15
21
 
16
22
  end
@@ -3,7 +3,7 @@ module PowerStencil
3
3
 
4
4
  class SimpleExec < PowerStencil::SystemEntityDefinitions::ProjectEntity
5
5
 
6
- include PowerStencil::SystemEntityDefinitions::HasAssociatedFiles
6
+ include PowerStencil::SystemEntityDefinitions::EntityTemplates
7
7
 
8
8
  DOC = 'Describes a simple process to be called after source files have been rendered'.freeze
9
9
 
@@ -20,7 +20,7 @@ module PowerStencil
20
20
  self.post_process = PowerStencil.project.engine.new_entity universe, :process_descriptor, fields: {
21
21
  name: "simple_exec_#{name}.process",
22
22
  process: './main.sh'
23
- }
23
+ }, user: is_user_entity?
24
24
  end
25
25
  end
26
26
  super(raise_error: raise_error)
@@ -1,3 +1,3 @@
1
1
  module PowerStencil
2
- VERSION = '0.6.3'.freeze
2
+ VERSION = '0.7.0'.freeze
3
3
  end
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
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'
32
+ spec.add_dependency 'git'
32
33
 
33
34
  source_code_uri = 'https://gitlab.com/tools4devops/power_stencil'
34
35
 
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.6.3
4
+ version: 0.7.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-10-29 00:00:00.000000000 Z
11
+ date: 2019-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: git
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description: PowerStencil is the Swiss-army knife templating workflow for developers
112
126
  and ops.
113
127
  email:
@@ -240,6 +254,7 @@ files:
240
254
  - lib/power_stencil/project/base.rb
241
255
  - lib/power_stencil/project/config.rb
242
256
  - lib/power_stencil/project/create.rb
257
+ - lib/power_stencil/project/git.rb
243
258
  - lib/power_stencil/project/info.rb
244
259
  - lib/power_stencil/project/paths.rb
245
260
  - lib/power_stencil/project/plugins.rb
@@ -250,7 +265,7 @@ files:
250
265
  - lib/power_stencil/system_entity_definitions/buildable.rb
251
266
  - lib/power_stencil/system_entity_definitions/entity_override.rb
252
267
  - lib/power_stencil/system_entity_definitions/entity_project_common.rb
253
- - lib/power_stencil/system_entity_definitions/has_associated_files.rb
268
+ - lib/power_stencil/system_entity_definitions/entity_templates.rb
254
269
  - lib/power_stencil/system_entity_definitions/non_persistent.rb
255
270
  - lib/power_stencil/system_entity_definitions/plugin.rb
256
271
  - lib/power_stencil/system_entity_definitions/process_descriptor.rb
@@ -276,7 +291,7 @@ metadata:
276
291
  documentation_uri: https://gitlab.com/tools4devops/power_stencil/blob/master/README.md
277
292
  source_code_uri: https://gitlab.com/tools4devops/power_stencil
278
293
  homepage_uri: https://powerstencil.brizone.org/
279
- post_install_message: "\nThank you for installing PowerStencil 0.6.3 !\nFrom the command
294
+ post_install_message: "\nThank you for installing PowerStencil 0.7.0 !\nFrom the command
280
295
  line you can run `power_stencil --help`\nIf your shell is not completing the command:\n
281
296
  \ If you use rbenv: `rbenv rehash`\n If you use zsh : `rehash`\n\nOfficial Website
282
297
  \ : https://powerstencil.brizone.org/\nFull documentation here : https://gitlab.com/tools4devops/power_stencil/blob/master/README.md\nFeel