Skip to content

VicDeo/Multiplicator

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Multiplicator by M4x0nus

This application allows to replicate a file structure using a reference file structure (so-called skeleton) and a list of predefined variables.

The classic usecase is to build a dozen of Dockerfiles for the different versions of environment.

TL;DR - a working sample

File structure:

┌skeletons/php/Dockerfile.template
├main.py
└config.yaml

config.yaml:

skeletons:
  - php

var:
  COMMON_HEADER: "# This is an autogenerated file"

out:
  - php-8.0:
    skeleton: php
    var:
      VERSION: 8.0
      WITH_XDEBUG: ""

  - php-8.0-with-xdebug:
    skeleton: php
    var:
      VERSION: 8.0
      WITH_XDEBUG: "1"
      XDEBUG_VERSION: "3.1.4"

  - php-8.1:
    skeleton: php
    var:
      VERSION: 8.1
      WITH_XDEBUG: ""

  - php-8.1-with-xdebug:
    skeleton: php
    var:
      VERSION: 8.1
      WITH_XDEBUG: "1"
      XDEBUG_VERSION: "3.1.5"

skeletons/my-skeleton/Dockerfile.template:

{{COMMON_HEADER}}
ARG PHP_VERSION={{VERSION}}
FROM php:${VERSION}-fpm-alpine
{% if WITH_XDEBUG -%}
RUN pecl install xdebug-{{XDEBUG_VERSION}} && docker-php-ext-enable xdebug
{% endif -%}
# The rest of the file is cut for the sake of brevity

Now you are ready to run python3 main.py update to get 4 different Dockerfiles:

out
├ php-8.0/Dockerfile
├ php-8.0-with-xdebug/Dockerfile
├ php-8.1/Dockerfile
└ php-8.1-with-xdebug/Dockerfile

Need more variations? Just replicate the entries in the out section of the config.yaml and change the variable values accordingly!

Basics

A reference file structure(s) is/are located in the skeletons directory.

All generated sets of files are put into the out directory.

The application takes a config file in the YAML format.

To start generation one need to use update command:

python3 main.py update

It takes no arguments as by default it uses config.yaml from the current directory as a config file.

But the update command still has some aux options that are listed below:

Short Long Parameter Description
-c --config PATH Config yaml file path
-d --directory PATH Working directory path
--dry-run Just check the validity of the config

Config file

Config file has 3 basic sections:

  • skeletons - all available skeletons are listed here.
  • var - global (common) variables are listed here
  • out - all target structures are listed here

All names are using 1 to 1 mapping to the filesystem which means that

skeletons:
  - node

is searched in ./skeletons/node directory while the generated item

out:
  - node-16

will be placed into the ./out/node-16 directory

"skeletons" config section

There is no much to say. Basically this is a list:

skeletons:
  - skeleton_1
  - skeleton_2
  - skeleton_3

All the declared in the config file skeletons should be existing subdirectories of the skeletons directory. The application validates that.

"var" config section

Just another list of variables that is common for all parsed templates:

var:
    # This variable could be used as a common header that is available in any template
    HEADER: |
      #
      # 'Twas brillig, and the slithy toves
      # Did gyre and gimble in the wabe;
      # All mimsy were the borogoves,
      # And the mome raths outgrabe.
      #

Don't be scared or confused with pipes and hashes - this is how multiline value is written in YAML. Check out YAML reference or config.yaml.sample for more details.

"out" config section

Pretty easy:

out:
  - generated_item_1:
    skeleton: skeleton_1
    var:
      some_var_1: value
      some_var_2: another_value

  - generated_item_2:
    skeleton: skeleton_1
    var:
      some_var_1: some_value
      some_var_2: yet_another_value

Basically all items in the out section should have a title and a reference to the skeleton that is declared in the skeletons section.

Templates

All files of the skeleton with .template extension are considered to be Jinja2 templates. Such files are parsed with Jinja2 engine and have .template extension stripped afterwards. Yes, that's what variables are intended for, but Jinja2 significantly more powerful, just check it out.

Tips and Tricks

  • Inactive config file items. It is possible to have inactive items this way:
out:
  - generated_item_1:
    skeleton: skeleton_1
    var:
      some_var_1: value
      some_var_2: another_value   

inactive:
  - generated_item_2: # this one will be ignored
    skeleton: skeleton_1
    var:
      some_var_1: some_value
      some_var_2: yet_another_value

Above we created a non-standard config section with the name inactive which will be ignored by the script.

  • Please note that out directory content is completely regenerated every time you run update command. In case you need to save the generated directory after the respective section was removed from the config file you need to copy it somewhere before running update command

  • In addition to the update command there is a print command that is used to list the current out directory content. In case out directory is empty or missing the output of the print command will be the following:

> python3 main.py
No tags available
>

print command has the following aux options:

Short Long Parameter Description
-d --directory PATH Working directory path

License

This work is provided under the MIT License. See the included LICENSE file.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Python 94.0%
  • Dockerfile 4.7%
  • Shell 1.3%