One of the nice features of Tomtit is that users can create scripts using Sparrowdo DSL and then package those one as regular Perl6 modules.
Let me show how to do this.
Tomtit profile
Tomtit profile is set of predefined scripts, say, I want to automate some routine operations that come from one my project to another. Instead of copy/paste git/clone them why not define those ones as Perl6 module and reuse it?!
Well, let me introduce Tomtit profiles.
Profile is Perl6 module
Say we have 3 simple operations we repeat again and again over all our projects:
- Dog - to say something as dogs do
- Cat - to say something as cats do
- Fish - to ( not ) to say something as fishes do
Consider creating Tomtit profile containing all 3 scripts representing our operations:
Tomtit::Profile::Pets
:
#!perl6
use v6;
unit module Tomtit::Profile::Pets:ver<0.0.1>;
our sub profile-data () {
my %a is Map = (
cat => (slurp %?RESOURCES<cat.pl6>.Str),
dog => (slurp %?RESOURCES<dog.pl6>.Str),
fish => (slurp %?RESOURCES<fish.pl6>.Str)
);
}
Every animal's scripts is just a Perl6 module resource:
resources/
cat.pl6
dog.pl6
fish.pl6
Sparrowdo DSL and Extensions
We are free Sparrowdo DSL when writing Tomtit scripts, for example:
cat.pl6
:
#!perl6
group "cats";
user "cat", %( group => 'cats' );
package-install "cats";
bash "echo 'cats say miu miu'";
Usually Sparrowdo DSL is enough to write your scripts, it has a lot of battery included definitions. But you can always extend DSL by writing specific sparrow plugin and call it through task-run
method:
cat.pl6
:
#!perl6
task-run "feed my cat", "cat-feed", %(
food => "Friskies",
drink => "Water"
);
Placeholders and Configurations
As I said those scripts are meant for use across various projects. However there are might be parts of a script which are common for all the projects and vise versa are specific to every project. The easiest way to handle this commonality/uniqueness problem is to add placeholders instead of actual values which are project specific:
cat.pl6
:
#!perl6
# This should be cat's group and it's specific to every project
# Change it appropriately
# Once you install the script
my $group = "ChangeMe";
group $group;
user "cat", %( group => $group );
Or you can even use Tomtit environments data to populate project specific data inside your scripts, this is even more maintainable:
cat.pl6
:
#!perl6
# This should be cat's group and it's specific to every project
# Change it appropriately
# Once you install the script
my $group = config<cats><group>;
group $group;
user "cat", %( group => $group );
To create Tomtit environment configuration say this:
tom --env-edit default
#!perl6
{
cats => %(
group => "bobtail"
)
}
Anyway once the script is installed you either modify it in place filling placeholders or set environment data, so everything works properly.
Let's go ahead and see how we distribute our scripts through Tomtit profiles.
Using profile by Tomtit
Once our Tomtit::Profile::Pets
profile is ready we can start using it through Tomtit:
zef install Tomtit::Profile::Pets
We add profile to configuration file so it could be seen through Bash completion:
~/tom.yaml
profiles:
- Tomtit-Profile-Pets
Now let's install profile:
tom --profile <TAB><TAB>
ado hello perl6 Tomtit-Profile-Pets
git perl ruby
tom --profile Tomtit-Profile-Pets
install Tomtit::Profile::Pets@cat ...
install Tomtit::Profile::Pets@dog ...
install Tomtit::Profile::Pets@fish ...
The cool thing about profiles is the way I can share my scripts with others. They single point of knowledge is just tomtit cli configuration files including all the necessary profile references with underneath are just Per6l modules. So having this configuration file in repository and installing related Perl6 modules is all is required to bring my scripts to others:
~/tom.yaml
:
profiles:
Tomtit-Profile-Pets
Tomtit-Profile-Birds
Tomtit-Profile-Humans
Install profile modules:
zef install Tomtit::Profile::Pets Tomtit::Birds Tomtit-Humans
Install profile scripts:
tom --profile Tomtit-Profile-Birds # so on
The installed scripts are useful on project initialization stage when you need to copy existed harness logic into your new project. However those scripts are not considered "static", one day I can update existed profile to add more scripts or fix bug in old ones, the end users will only have to updated related Perl6 module and reinstall script from profile:
zef upgrade Tomtit::Profile::Pets
tom --profile Tomtit-Profile-Pets
You can even take it more granular way, updating/installing only specific script:
tom --profile Tomtit-Profile-Pets@fish
To list available scripts within profile just say:
tom --list --profile $profile
:
tom --list --profile Tomtit-Profile-Pets
load portable profile Tomtit::Profile::Pets as Perl6 module ...
[profile scenarios]
Tomtit::Profile::Pets@cat installed: False
Tomtit::Profile::Pets@dog installed: False
Tomtit::Profile::Pets@fish installed: False
Conclusion
Tomtit profile is good way to distribute scripts across projects, they are easy to maintainable, easy to write and rely on powerful and simle Sparrowdo DSL and could be extended by plugin written on other languages.
Why not give it a try?
Thank you for reading.