Git integration
===============
- [Overview](#overview)
- [`PowerStencil` "_write_" actions](#powerstencil-_write_-actions)
- [Activating / De-activating integration](#activating--de-activating-integration)
- [Generic config flag](#generic-config-flag)
- [How things are tracked](#how-things-are-tracked)
- [Project creation](#project-creation)
- [Entity creation](#entity-creation)
- [Modifying an entity](#modifying-an-entity)
- [Deleting an entity](#deleting-an-entity)
- [`PowerStencil` shell session](#powerstencil-shell-session)
- [Plugin creation](#plugin-creation)
- [(Re)Generating `zsh` command line completion for the project](#regenerating-zsh-command-line-completion-for-the-project)
- [Manual actions](#manual-actions)
[:back:][Documentation root]
# Overview
The git integration within `PowerStencil` provides tons of useful default behaviors. Let's browse what it brings out of the box.
:hand: You should have already read the whole [Getting Started] part before reading this.
# `PowerStencil` "_write_" actions
When interacting with `PowerStencil`, only some of the commands actually trigger write actions on your disk.
Here is a summary:
| `PowerStencil` sub-command | Status |
|----------------------------|:------:|
|`init` | creates a project
|`info` | read-only
|`plugin` | creates a plugin
|`get` | read-only
|`shell` | do anything
|`adm --zsh-completion` | generates zsh command-line completion
|`check` | read-only
|`create` | creates entities
|`edit` | modifies entities
|`delete` | deletes entities
|`describe` | read-only
|`build` | read-only
On top this we could add some other actions, you can obviously perform manually within the repository, like:
* Create/update/delete entity types
* Create/update/delete entity type templates-templates
* Code within local plugins
* Create/update/delete templates for buildable entities
* Modify `.ps_project/versioned-config.yaml` config file (the file `.ps_project/personal-config.yaml` is unversioned)
* ... and of course anything else, not `PowerStencil` related, you would like add to your project.
**:+1: The git integration will not interfere with any of your manually done actions and will keep anything you are doing manually out of scope of automatically generated git commits.**
# Activating / De-activating integration
## Generic config flag
You can specify in the `.ps_project/versioned-config.yaml` config file that you don't want to activate the git integration by adding:
```yaml
:no-git: true
```
And then nothing will be automatically tracked by git. It could be also activated in your personal config file (`.ps_project/personal-config.yaml`) if you you temporarily want to manage commits manually for whatever strange reason.
Still if you do that, when you initially created the project a git repository has been created. But if you want to completely stay out of git and for example use another versioning tool (does it still exist ??), you can create your project without git integration by doing:
$ power_stencil init my_project --no-git
In this case the setting inside your config file is not even necessary.
Or course you could _a posteriori_ delete the `.git` directory, but why would you want to do that...
:warning: Be careful that the `.gitignore` file is there to normally ensure that only things that really need to be committed are actually. So it means that if you use a different versionning tool, you have to somehow translate this `.gitignore` file in the paradigm of the tool you actually use !
:information_source: One legitimate reason to temporarily avoid automatic git commit may be for plugin creation, but we'll see that in the next paragraph.
# How things are tracked
Each command not stated as "read-only" in the [table above](#subcommands-impact), actually generate a git commit. Let's see that in detail.
## Project creation
When a project is created with:
$ power_stencil init test
A git repository is automatically created, initial project files are added to git staging and a first commit is done. So from the project directory we can see:
```
$ git log --full-history --summary
commit a5cc500277d8a58d78111e1accdeff7f72fc3027
Author: Joe
Date: Sun Nov 3 18:31:20 2019 +0100
Initial commit for project "test".
create mode 100644 .gitignore
create mode 100644 .ps_project/entities/README.md
create mode 100644 .ps_project/entity_definitions/README.md
create mode 100644 .ps_project/plugins/README.md
create mode 100644 .ps_project/templates-templates/README.md
create mode 100644 .ps_project/versioned-config.yaml
```
So you see by default all the files which have been committed.
## Entity creation
To make the things a bit more fun, let's do it with an entity that generates templates like a `simple_exec`:
$ power_stencil create simple_exec/foo
```
$ git log -1 --summary
commit 00a09a274377c0797061b342b61ebab028189163
Author: Joe
Date: Sun Nov 3 18:55:12 2019 +0100
Created 'simple_exec/foo' (and potential dependencies).
create mode 100644 .ps_project/entities/process_descriptor/simple_exec_foo.process.yaml
create mode 100644 .ps_project/entities/simple_exec/foo.yaml
create mode 100755 templates/simple_exec/foo/main.sh
```
:+1: Yeah, all files generated are committed at once, including the `process_descriptor` it automatically creates as well as the templates generated. Pretty cool...
In the end it gives a pretty understandable history:
```
$ git log --oneline
00a09a2 Created 'simple_exec/foo' (and potential dependencies).
a5cc500 Initial commit for project "test".
```
And of course the working directory remains clean:
```
$ git status
On branch master
nothing to commit, working tree clean
```
## Modifying an entity
Of course you probably guessed it now, if you edit the `simple_exec/foo` entity using, the:
$ power_stencil edit simple_exec/foo
```
$ git log -1 --summary
commit 7de417f51f7ca37a4e81b7dee968affaa437f383
Author: Joe
Date: Sun Nov 3 19:10:44 2019 +0100
Edited entity 'simple_exec/foo'.
```
And of course you can track the changes.
```
$ git diff 00a09a2
diff --git a/.ps_project/entities/simple_exec/foo.yaml b/.ps_project/entities/simple_exec/foo.yaml
index 710b97f..1d9cc26 100644
--- a/.ps_project/entities/simple_exec/foo.yaml
+++ b/.ps_project/entities/simple_exec/foo.yaml
@@ -1,3 +1,4 @@
--- !ruby/object:PowerStencil::SystemEntityDefinitions::SimpleExec
:name: foo
:post_process: !entity process_descriptor/simple_exec_foo.process
+:description: A useless entity
```
**:hand: But of course, if I modify the templates by editing manually the `templates/simple_exec/foo/main.sh` file, or by adding new files in the template directory of this entity, I will have to manage them manually like I would normally do with any file tracked by git.**
## Deleting an entity
When deleting an entity, `PowerStencil` offers to delete the entity only with:
$ power_stencil delete simple_exec/foo
Or to delete it, including its associated templates with:
$ power_stencil delete simple_exec/foo --delete-files
In both cases, the git integration will track things correctly. Let's say we choose the second option:
```
$ power_stencil delete simple_exec/foo --delete-files --auto
Deleting entity 'simple_exec/foo'
Deleted 'simple_exec/foo' and template files.
$ git log -1 --summary
commit 1193c1c961fc2eecc50dea93b5f76411797f415b
Author: Joe
Date: Sun Nov 3 19:27:44 2019 +0100
Deleted entity 'simple_exec/foo' (and potential dependencies) including templates..
delete mode 100644 .ps_project/entities/process_descriptor/simple_exec_foo.process.yaml
delete mode 100644 .ps_project/entities/simple_exec/foo.yaml
delete mode 100755 templates/simple_exec/foo/main.sh
```
## `PowerStencil` shell session
You can do a lot of things within a shell session, and sometimes even destructive actions you may not want to commit. This is why `PowerStencil` will ask you if you want to commit your changes and present you with the list of changes. Here under a sample session:
```
$ power_stencil shell
Please report a bug if this causes problems.
-------------------------------------------------------------------------------
Welcome to the PowerStencil shell session
In this shell you have access to anything the templating engine has access to.
On top of this, you can view, edit, save and delete entities.
- Retrieve and manipulate entities using the `entities` hash.
- Persist your changes using the `save` method on each entity.
- Create new project or user entities using `new_` and
`user_new_` methods (see `available_entity_types` for a list of
possible types).
- And of course, it is a fully fledged Ruby Pry REPL, so you can do anything
you want...
Type `exit` to end your session.
-------------------------------------------------------------------------------
PowerStencil DSL> e = new_simple_exec name: :test2
=> #
PowerStencil DSL> e.save
=> #
PowerStencil DSL> exit
Following files will be committed:
- '.ps_project/entities/process_descriptor/simple_exec_test2.process.yaml'
- '.ps_project/entities/simple_exec/test2.yaml'
- 'templates/simple_exec/test2/main.sh'
Would you like to commit your changes ? ([Yes]/y/No/n): y
$ git log -1 --summary
commit 8c8554b297a05466147208ca657323300e952981
Author: Joe
Date: Sun Nov 3 19:33:25 2019 +0100
Changes done in PowerStencil shell session.
create mode 100644 .ps_project/entities/process_descriptor/simple_exec_test2.process.yaml
create mode 100644 .ps_project/entities/simple_exec/test2.yaml
create mode 100755 templates/simple_exec/test2/main.sh
```
You see the commit is labelled `Changes done in PowerStencil shell session`.
:information_source: If you have not introduced any change, the question will not even be asked when you exit the shell...
## Plugin creation
As expected if you create a plugin using the command:
$ power_stencil plugin --create bar
It tracks this as well:
```
$ git log -1 --summary
commit 591df0951a04476ebe29284fda8fd548c638dcea
Author: Joe
Date: Sun Nov 3 19:42:11 2019 +0100
Generated new local plugin 'bar'.
create mode 100644 .ps_project/plugins/bar/.gitignore
create mode 100644 .ps_project/plugins/bar/.rspec
create mode 100644 .ps_project/plugins/bar/.travis.yml
create mode 100644 .ps_project/plugins/bar/CODE_OF_CONDUCT.md
create mode 100644 .ps_project/plugins/bar/Gemfile
create mode 100644 .ps_project/plugins/bar/LICENSE.txt
create mode 100644 .ps_project/plugins/bar/README.md
create mode 100644 .ps_project/plugins/bar/Rakefile
create mode 100644 .ps_project/plugins/bar/bin/console
create mode 100644 .ps_project/plugins/bar/bin/setup
create mode 100644 .ps_project/plugins/bar/etc/command_line.yaml
create mode 100644 .ps_project/plugins/bar/etc/plugin_capabilities.yaml
create mode 100644 .ps_project/plugins/bar/etc/plugin_config.yaml
create mode 100644 .ps_project/plugins/bar/etc/templates/.git_keep
create mode 100644 .ps_project/plugins/bar/etc/templates/bar_entity/.copy_ignore
create mode 100644 .ps_project/plugins/bar/etc/templates/bar_entity/.subst_ignore
create mode 100644 .ps_project/plugins/bar/etc/templates/bar_entity/message.txt
create mode 100644 .ps_project/plugins/bar/lib/bar.rb
create mode 100644 .ps_project/plugins/bar/lib/bar/bar_processor.rb
create mode 100644 .ps_project/plugins/bar/lib/bar/dsl/bar_dsl.rb
create mode 100644 .ps_project/plugins/bar/lib/bar/entity_definitions/bar_entity.rb
create mode 100644 .ps_project/plugins/bar/lib/bar/plugin_helper.rb
create mode 100644 .ps_project/plugins/bar/lib/bar/version.rb
create mode 100644 .ps_project/plugins/bar/psplugin_bar.gemspec
create mode 100644 .ps_project/plugins/bar/spec/bar_spec.rb
create mode 100644 .ps_project/plugins/bar/spec/spec_helper.rb
```
Cool ! Nevertheless, plugins may be one of the things you may want to track a bit differently. For example as git sub-modules, to keep a separated git history, and ease future re-useability of the plugin you are developing.
So it's up to you and `PowerStencil` provides an easy way to keep your plugin out of your project repo. Same as for `power_stencil init`, `power_stencil plugin --create` supports the `--no-git` option...
## (Re)Generating `zsh` command line completion for the project
If you generate the zsh command line completion file for the project by doing, from within the project:
$ power_stencil adm --zsh-completion
You will then generate a file that contains project-specific zsh completion directives: `.ps_project/.zsh_project_completion`.
That file is versioned too, because its content depends on the plugins (local or as gems) that you actually use in this project. **If you add a new plugin or modify the way local ones handle the command-line, you should then regenerate it**, by re-running that command if you want the completion to fully take in account your changes.
It is tracked like that:
```
$ git log -1 --summary
commit 0c7bedb7249654873882c56bb15172c528511cff
Author: Joe
Date: Sun Nov 10 11:21:10 2019 +0100
Adding project specific zsh completion file: '.ps_project/.zsh_project_completion'.
create mode 100644 .ps_project/.zsh_project_completion
```
# Manual actions
Ok, so far we have a pretty nice git history:
```
$ git log --oneline
591df09 Generated new local plugin 'bar'.
8c8554b Changes done in PowerStencil shell session.
1193c1c Deleted entity 'simple_exec/foo' (and potential dependencies) including templates..
7de417f Edited entity 'simple_exec/foo'.
00a09a2 Created 'simple_exec/foo' (and potential dependencies).
a5cc500 Initial commit for project "test".
```
And our working directory is still clean.
```
$ git status
On branch master
nothing to commit, working tree clean
```
But what happens if we modify things manually ? How does it interfere with everything we saw before.
:wink: Actually, before any action, `PowerStencil` gets a snapshot of the working directory in terms of git modifications (added, removed, modified, moved files...) and **will not include any of this pre-existing changes in its own commits**.
It's actually, a good separation of responsibilities. If you modified something by yourself, you are responsible to commit the changes (or not)...
In the end, it means you have to completely manage by yourself any changes you would apply to:
* the main config file (`.ps_project/versioned-config.yaml`)
* entity types creation, modification, deletion (under `.ps_project/entity_definitions/`).
* template-templates creation, modification, deletion for your own entity types (under `.ps_project/templates-templates/`).
* entity templates added and any modification (under `templates`).
* code changes in your local plugins (`.ps_project/plugins/`)
[:back:][Documentation root]
[Documentation root]: ../README.md "Back to documentation root"
[entities]: entities.md "Entities in PowerStencil"
[plugins]: plugins.md "Plugins in PowerStencil"
[overrides]: builds.md#overriding-entities-and-build-scenarii "Overriding data locally"
[example use cases]: example_use_cases.md "Example uses cases using PowerStencil"
[Getting Started]: ../README.md#getting-started "Getting Started with PowerStencil"