PowerStencil ============ [![Gem Version](https://badge.fury.io/rb/power_stencil.svg)](https://rubygems.org/gems/power_stencil) [![Pipeline status](https://gitlab.com/tools4devops/power_stencil/badges/master/pipeline.svg)](https://gitlab.com/tools4devops/power_stencil/commits/master) `Power Stencil` is the Swiss-army knife templating workflow for developers and ops. See [official website][PowerStencil site]. - [Overview](#overview) - [Pfff, yet another templating engine...?](#pfff-yet-another-templating-engine) - [Installation](#installation) - [Usage](#usage) - [Help](#help) - [Creating a `PowerStencil` project](#creating-a-powerstencil-project) - [`PowerStencil` project structure](#powerstencil-project-structure) - [Getting started](#getting-started) - [Entities](#entities) - [Templates](#templates) - [Builds](#builds) - [Plugins](#plugins) - [Project status](#project-status) - [Contributing](#contributing) - [License](#license) - [Code of Conduct](#code-of-conduct) # Overview `PowerStencil` proposes a radical approach on how to manage your shared configuration. **Configuration** is one of the most complex things to maintain, and anyone who participated in a large scale piece of software, be it for code, tools configuration or even documentation, knows how complex it is to maintain, **keep consistent and avoid duplication** on the long run, across the various projects that may share this configuration. From a very high level point of view, the workfow `PowerStencil` proposes looks like: ![simple-flow-image] `PowerStencil` provides **development and operations friendly workflows to fully manage the maintenance of a complex shared config** in order to generate anything you may want like _documentation_, _static sites_, _code_, _configuration_ for multiple tools..., while **avoiding duplication, and manage it like code** ! It is a common pattern to introduce a database to manage shared configuration for CI/CD processes, and it is a very bad idea (see [F.A.Q.][DB in F.A.Q.]) because it implies extra tooling, and specific developments that de-facto become single point of failure at the heart of your development process. Why would you do that when something as versatile and ubiquitous as Git exists that will integrate smoothly within your existing development and operations workflows, builds, CI/CD processes, while benefiting from all the goodness provided by Git, like branches, decentralization, versioning, tags, code reviews, traceability, simplified fallbacks etc... ? A `PowerStencil` project is composed of a data repository and a pretty standard templating flow to generate whatever is needed by your project or organization and **with `PowerStencil` everything is maintained in a git repository**: data, templates, specific code **without sacrificing on data integrity and relational features**. No more config loss, no more change applied without a full lineage. **:information_source: With `PowerStencil` data can either be managed as documents to edit (Yaml) or fully as code within a powerful shell !!**. Choose the method that fits the most to what you are doing. The `PowerStencil` gem provides the `power_stencil` executable which is a pluggable CLI to: - Manage your project **relational-integrity-checked data** in a versioned, git diff friendly yet flexible format. - Visualize your **data relations with graphviz**. Customize generated graphs easily. - Easily **manage templates** to generate whatever your project/organization requires. - Define builds that you can easily **embed in your CI/CD process** or use them standalone. - Propose mechanism to temporarily override some data to test changes impact without polluting the official repository data. - Ensure **re-usability** with a versatile extension mechanism, including plugins. # Pfff, yet another templating engine...? **Actually `PowerStencil` is _not_ a templating engine**. It uses already existing and proven templating engines. Currently it uses [ERB], which is a pretty standard and very well known engine in the [Ruby] world and especially for people who already used the [Rails] framework. Virtually any templating engine existing in the Ruby ecosystem could be integrated in the `PowerStencil` framework next to [ERB] (as `PowerStencil` already comes with a mechanism to select a templating engine regarding some criteria like file extension, path etc...). This will probably be the case in a future release, at least to integrate the [Haml] templating engine in order to ease the generation of XML-like files, still you obviously already can do it with [ERB]. So `PowerStencil` is definitely not a templating it is actually much more than that. # Installation You need a working install of the [Ruby] language (>= 2.3). Then you can install the `PowerStencil` gem by issuing the usual: $ gem install power_stencil :hand: It is **strongly** advised to have `git` installed on your system, as `PowerStencil` is integrated with `git` to provide a better user experience. If you want to create [Graphviz] graphs, you probably may want to install it for your system. If you are using an _apt-based_ system like Ubuntu or Debian it may probably be as simple as: $ sudo apt install graphviz If you use Windows, install [Graphviz] using the stable version for Windows and add the `bin` directory to the `%PATH%`. # Usage ## Help The `power_stencil` CLI provides a contextual help. You can begin with: $ power_stencil --help That will display a basic help: ```shell PowerStencil is the Swiss-army knife templating workflow for developers and ops. -- Options --------------------------------------------------------------------- -v, --verbose Displays extra runtime information. -h, --help Displays this help. --program-version, -V, --version Displays program version. --simulate Will not perform actual actions --debug Debug mode --debug-on-err, --debug-on-stderr Sends debugging to SDTERR --log-level Defines the level of logging (0 to 5) --log-file Specifies a file to log into --truncate-log-file Truncates the log file (appends by default) --project-path Specifies a startup path to use instead of '.' --auto Bypasses command-line confirmations to the user -------------------------------------------------------------------------------- Following subcommands exist too: For more information you can always issue sub_command_name --help... -------------------------------------------------------------------------------- * init: Initializes a PowerStencil repository ... * info: Generic information about the repository ... * plugin: Manipulates plugins ... * get: Query entities from repository ... * shell: Opens a shell to interact with entities ... * check: Check repository entities consistency ... * create: Creates entities in the repository ... * edit: Edit entities from repository ... * delete: Delete entities from repository ... * describe: Detailed information about entity types ... * build: Builds entities ... ``` The program uses the standard paradigm of sub-commands (à-la-git), and each can have its own options that you can check using: $ power_stencil --help [Plugins] may bring extra subcommands and/or options, so depending on the project you are working in, the output of `--help` may differ... ## Creating a `PowerStencil` project To create a new project, use the `init` sub-command. It works as you would expect. If you run it in an existing directory it will create the project here but you can specify the directory where you want the project to be created (the path will be created provided you have enough rights on the filesystem): $ power_stencil init /where/you/want/your/project Once the project created, if you are anywhere within the project tree, you don't need to specify the project path anymore (if needed, any `power_stencil` sub-command supports a `--project-path` option). If you're used to the Git command line, it works the same way, and you should not feel in uncharted territory... **:information_source: The rest of this documentation will assume you are at the root of this created project.** **:information_source: If you have `git` installed on your system, **the repository of the newly created project has been automatically turned into a git repository. And any action done through the `power_stencil` command-line will be automatically tracked by `git`**. Only things you will do outside of the `power_stencil` command-line (adding or modifying templates, creating or modifying entity types... any manual action) will require a user action to make `git` take it in account. You can completely de-activate this behaviour if you want to fully manage things by yourself by adding `:no-git: true` in the `.ps_project/versioned-config.yaml`, yet there is no good reason for that... Unless you know what you are doing, you should keep the default settings. ## `PowerStencil` project structure The structure of a brand new `PowerStencil` project is the following: ``` ├── .gitignore └── .ps_project ├── entities │   └── README.md ├── entity_definitions │   └── README.md ├── personal-config.yaml ├── plugins ├── templates-templates │   └── README.md ├── user_entities │   └── README.md └── versioned-config.yaml ``` Other directories will appear once you start working with the project, perform some [builds] or when you will define [templates], but this is the initial state. Not all the files in this directory should be versioned, and this the reason why there is a preconfigured `.gitignore` at the root of the project. It is prefilled so that unless you want to specifically avoid a file to be versioned, you don't need to worry regarding `PowerStencil` project files. **By default everything that must be versioned actually is and everything that shouldn't isn't**. The project has two distinct config files. - Keep the official project config in the `.ps_project/versioned-config.yaml` which, as its name suggest, will be git versioned. - But any developer who wants to temporarily override some configuration should do it in the `.ps_project/personal-config.yaml`, which is not to be versioned. The content defined in the latter will override the content of the versioned one. **This is a clean way for anyone who wants to test something to safely do it locally without the risk to pollute the central repo.** There is the same mechanism between `.ps_project/entities` (where the project data is stored and which is versioned) and `.ps_project/user_entities` (where local data is stored and not versioned), but as opposed to the two aforementioned config files, you should not edit anything directly there, but instead use the CLI or the shell. More information on how to manage entities [here][entities]. The `plugins` directory can optionally contain project specific plugins. Plugins are a great way to extend `PowerStencil` for the needs of a project or organization. ## Getting started See the four following topics as a kind of tutorial on `PowerStencil`. You should read them in order, as each of them assumes you already read the previous one. ### Entities The **core of the system** is the **[entity][entities]**, so you should start by having a look at what entities are, how they are easily managed using the `PowerStencil` CLI and shell. ### Templates Then it is important to understand how to use entities within **[templates]**. Templates are the way to **generate whatever you need** (doc, code, descriptors, sites, whatever...) from the data that the entities represent. ### Builds The mechanism that **combines entities and templates** is called a **[build][builds]**. A build is always attached to an entity (you build something). The result of a build is a set of files. Optionally an action can be triggered after the files are generated (could be as simple as calling a script that has been generated). ### Plugins `PowerStencil` could stop there, and you would be able to do whatever you want, but there is a whole world beyond. **[Plugins]** provide a way to completely **extend `PowerStencil` and ease cross-projects share and re-usability**, further control relations between entities, implement complex post-build actions, add CLI sub-commands and options. Plugins can be local to the project or coming in the form of standard Ruby Gems ! The icing on the cake...

And course, you may want to **read the [F.A.Q.]** # Project status Check `PowerStencil` [status in the F.A.Q.]. # Contributing Bug reports and pull requests are welcome on Gitlab at https://gitlab.com/tools4devops/power_stencil. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. ## License The gem is available as open source under the terms of the [MIT License]. ## Code of Conduct Everyone interacting in the PowerStencil project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct]. [templates]: doc/templates.md "Templates in PowerStencil" [entities]: doc/entities.md "Entities in PowerStencil" [builds]: doc/builds.md "Builds in PowerStencil" [plugins]: doc/plugins.md "Plugins in PowerStencil" [example use cases]: doc/example_use_cases.md "Example uses cases using PowerStencil" [F.A.Q.]: doc/faq.md "PowerStencil F.A.Q." [status in the F.A.Q.]: doc/faq.md#what-is-the-status-of-powerstencil- "PowerStencil project status" [DB in F.A.Q.]: doc/faq.md#why-is-a-real-database-a-bad-idea-as-configuration-store-for-cicd- "Databases in build processes" [code of conduct]: CODE_OF_CONDUCT.md [ERB implementation]: lib/power_stencil/engine/renderers/erb.rb "Mostly the only module you need to clone to implement another templating engine" [simple-flow-image]: doc/images/power-stencil-simple-flow.svg [MIT License]: http://opensource.org/licenses/MIT "The MIT license" [ERB]: https://ruby-doc.org/stdlib-2.6.3/libdoc/erb/rdoc/ERB.html "Quick ERB description" [Haml]: http://haml.info/ "The templating engine for XML-like documents" [Ruby]: https://www.ruby-lang.org "The powerful Ruby language" [Rails]: https://rubyonrails.org/ "The Ruby on Rails framework" [PowerStencil site]: https://powerstencil.brizone.org "Official PowerStencil website" [Graphviz]: https://www.graphviz.org/ "Graph Visualization Software"