power_stencil 0.6.3 → 0.7.0

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