stempl is a simple tool to create the same files and folder structure (skeleton) from a template directory. Each .erb file in the template is parsed using the ERB template engine, which allows customization of the skeleton if neccessary. This is useful if you need to repeatedly create similar skeletons with minor differences in content.
Add this line to your application's Gemfile:
gem 'stempl', :git => 'git://github.com/sginzel/stempl.git'
And then execute:
$ bundle
Or build and install it yourself as:
$ git clone https://github.com/sginzel/stempl.git && cd stempl && bundle install && gem build stempl && gem install stempl
stempl was developed and tested with ruby 2.3.3, but anything >2.0 should work without guarantees.
stempl [options] --varname \'var value\' names
-r, --repository Template location (local or remote git, default: ~/.stempl)
-t, --target Target directory for skeletons, default: .
-f, --force force overwrite (default: false)
-v, --verbose enable verbose mode
-q, --quiet suppress output (quiet mode)
-d, --dry-run dry-run - do not create any files or directories, just print the actions
--names Name of skeleton
--version print the version
-h, --help
Please not that names of stempl templates must not contain spaces.
# Clone a simple demultiplex workflow to a new subfolder in the current directory
stempl -d -t demultiplex_today \
-r https://github.com/sginzel/stempl-examples.git \
demultiplex
This will download the repository using git clone
to a temporary directory and use the demultiplex template.
Please make sure that git
is available on your system.
To create a new stempl template you can either create one at ~/.stempl or have stempl
create one for you
# For production remove -d and -v option (verbosive dry-run)
stempl -d -v -t target new_stempl
[INFO] ~/.stempl/ew_stempl does not exist.
[INFO] Do you want to create a new stempl at ~/.stempl/ew_stempl?(Y/n)
Y
Create stempl ~/.stempl/new_stempl
[MKDIR-stempl] ~/.stempl/new_stempl
[DEFAULT_CONF] ~/.stempl/new_stempl/.config.yaml
---
name: new_stempl
version: 0.01
collate: []
variables: []
dialog: []
[END OF DEFAULT_CONF]
Each file or folder that is created in the new_stempl directory will now be copied to the target location when stempl -t target new_stempl
is called.
The configuration of a stempl will be copied to the target location with the name .stempl_config.yaml. If the target is used again predefined dynamic values can be used from the that config.
Every file and folder is simply copied from the template to the target directory. The only exception are .erb files, which are parsed with the ERB template engine to customize the templates.
If user input is required use cli_read
and cli_select_file
to read values from the command prompt.
While parsing the template undefined variables are detected and a cli_read
command prompt will query a values from the user.
This is repeated until no undefinded variables are found.
- <% ... %> - execute code that is inside <% %> brackets.
- <%= ... %> - execute code and add the last return value to the skeleton. Nesting is not possible.
- cli_read (varname, prompt) - query a value through the command line (alias:
read
). - cli_select_file (varname, prompt) - select a file through the command line (alias:
select_file
). - dialog ({varname: "default value", ...}) - Opens a GUI dialog to prompt for user input.
- dialog (["varname1", "varname2", ...]}) -
dialog()
can also handle arrays and defaults to text input. - repository - the template repository location.
- target_dir - the location of the skeleton to generate.
- source - template file location.
- target - skeleton file location. Is
nil
when the file is included innocopy
section of the config file.
Add a YAML file named .config.yaml
to the template directory to configure the parsing process.
--- # .config.yaml
name: 'Some Name'
version: 0.1
collate:
- file_zzz
- file_aaa
- file_cca
exclude:
- bbb.*
nocopy:
- file_cca
variables:
name: John Smith
age: 33
dialog:
- # Dialog #1
name: Johny doe
age: 123
- # Dialog #2
favorite_file: select_file
favorite_directory: select_dir
favorite_food:
- Pizza
- Salad
---
- name - name of the stempl.
- version - version (for future use)
- collate - Order in which files should be processed. This can be important when defining one which is used in multiple files. Any file not present in the collate field is appended to the collation and sorted alphabetically.
- exclude - Files to be excluded from the template
- nocopy - These files are only passed through the template engine, but the result is not copied to the skeleton. These files require the .erb extension and can be used to execute code while processing a template.
- variables - A lookup for predefined variables. Can also be given on the command line
stempl some_stempl --name \'John Doe\' --age 33
. Of course you will run into trouble if your variable names correspond to an option recognized by stempl. Please use \' to quote strings with spaces from a command line. - dialog - An array of hashes that are used to build the dialogs.
The template engine can also be used for the config file. Although obviously, the variables section is ignored while parsing the config file at this stage.
--- # .config.yaml
name: 'Some Name'
version: 0.1
collate:
- file_zzz
- file_aaa
- file_cca
exclude:
- bbb.*
nocopy:
- file_cca
variables:
name: <%= cli_read('person_name', 'give a default name')%>
age: 33
dialog:
- # Dialog #1
name: <%= person_name %>
age: 123
- # Dialog #2
favorite_file: select_file
favorite_directory: select_dir
favorite_food:
- Pizza
- Salad
---
If you want to use a more familiar syntax you can also parse a Has into a yaml when parsing the .config.yaml.erb template.
<%=
{
'name' => 'Some Name'
'version' => 0.1,
'collate' => %w( file_zzz file_aaa file_cca ),
'collate' => %w( file_zzz file_aaa file_cca ),
'exclude' => 'bbb.*',
'nocopy' => 'file_cca',
'variables' => {
'name' => cli_read('person_name', 'give a default name')
'age' => 33
},
'dialog' => [
{ 'name' => person_name, 'age' => 123 },
{ 'favorite_file' => select_file, 'favorite_folder' => select_dir, 'favorite_food' => %w(Pizza Salad)}
]
}.to_yaml %>
Dialogs are displayed using GTK3 and the input types are determined by the default values provided in the .config.yaml. Each entry in the dialog-field is opened as a new dialog window.
dialog:
- # First dialog window
name: John Doe
age: 32
- # Second dialog window
favorite_file: select_file
favorite_folder: select_dir
favorite_food:
- Pizza
- Salad
Strings and numbers will result in text boxes, select_file and select_dir will provide file and folder selections, if the default value is an array a combobox will be displayed.
When using dialogs the GUI is not always destroyed properly and only closes after the application terminates.
This simple skeleton reads the standard .bashrc and appends a customized history size. The welcome message is customized if the user is an admin.
# .bashrc.erb
<%= File.open('/etc/skel/.bashrc', 'r').read %>
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=<%= cli_read 'histsize', 'How many records should be in the history? ' %>
HISTFILESIZE=<%= cli_read 'histfilesize', 'How big should the history file be? ' %>
echo '###########################################'
echo 'Welcome <%= username %> to your new account'
echo '<%= (is_admin == "true")?("YOU ARE ADMIN"):("") %> '
echo '###########################################'
---- # .config.yaml.erb
name: homeskeleton
version: 0.1
collate:
- .bashrc
exclude: []
nocopy: []
variables:
dialog:
-
username:
histsize: <%= cli_read 'histsize', 'Tell me the histsize on the console please' %>
histfilesize: <%= (histsize).to_i*2 %>
is_admin:
- Yes
- No
---
YAML was designed as a readable format and does this job well.
Unfortunately this means that 'yes' and 'no' are converted into true/fals when the .yaml file is parsed.
That is why line #10 in .bashrc.erb does not check is_admin == 'Yes'
.
All values which are read over the console or dialog are stored as strings/text. Keep this in mind if you want to work with numbers (e.g. line #11 of .config.yaml.erb)
Bug reports and pull requests are welcome on GitHub at https://github.com/sginzel/stempl. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
The gem is available as open source under the terms of the MIT License.
Everyone interacting in the Stempl project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.