Development workflow management using Tomtit
Tags: productivity, terminal, git, raku
Published: 2020-10-05 19:03:01

---
title: Development workflow management using Tomtit
published: true
description: How to automate your development flows using Tomtit and Sparrow
tags: productivity, terminal, git, raku
cover_image: https://cdn1.vectorstock.com/i/1000x1000/23/80/tomtit-vector-25962380.jpg
---

Every developer deals with the same tasks on daily basis. For instance working with git, linting yaml files, build and releasing modules, calling http APIs and so on.

So, welcome [Tomtit](https://github.com/melezhik/Tomtit) - a task and workflow 
manager built on [Sparrow](https://github.com/melezhik/Sparrow6) engine that allows one to easily develop harness scripts and run them though a high-level [Raku](https://raku.org) scenarios.

If you're terminal and automation lover - welcome to this post, I'll show how the use of Tomtit could increase your productivity tremendously.   


# Install Tomtit

Tomtit is a Raku module - so it's installed through a Raku package manager:

```bash
$ zef install --/test Tomtit
```

# Setup

Once Tomtit is installed one can use `tom` - command line api to make an initial setup:

```bash
$ tom --completion
$ source  ~/.tom_completion.sh
$ s6 --repo-init ~/repo 
```

Once commands are executed you'll setup a local Sparrow repository (in case you want to use plugins, see further) and install bash completion for a tom client.

In our post we're going to use _an example_ Raku project to show typical Tomtit workflow:

```bash
$ git clone https://github.com/melezhik/rakudist-teddy-bear.git
```

Before we get started we need to initialize our project with some technical directory required by Tomtit:

```bash
$ cd rakudist-teddy-bear
$ tom --init
```

# Create some tasks

Now, let's give it a run and create some script that automate our work. 

Consider a simple example from Raku world of testing and building of Raku source code:

```
$ tom --edit build-app
/home/ubuntu/projects/rakudist-teddy-bear/.tom/build-app.pl6 does not exit, do you want to create it? (type Y to confirm): Y
```
Once we confirm a creation of new scenario tom will run editor defined at `$EDITOR` so we can create a raku script:

```perl
#!raku
task-run ".tom/tasks/build";
```  
So far it just a function `task-run` that is exported by Tomtit, and that run a script located at `.tom/tasks/build` folder, now we need to implement the underlying script:


```bash
$ mkdir -p .tom/tasks/build
$ nano .tom/tasks/build/task.bash
```

```bash
!#bash
prove6 --lib t/
zef install --force-install .
```

As we one can see we choose here Bash for an underlying script, as it fits best for this simple tasks. One could also choose between other **languages**, that are supported by [Sparrow](https://github.com/melezhik/Sparrow6) - underlying Tomtit engine.

 
Now we can run a build application task by using a tom command line:

```bash
$ tom build-app
17:05:12 10/04/2020 [repository] index updated from index updated from file:///home/ubuntu/repo/api/v1/index
17:05:13 10/04/2020 [.tom/tasks/build] t/00-load.t .. ok
17:05:13 10/04/2020 [.tom/tasks/build] All tests successful.
17:05:13 10/04/2020 [.tom/tasks/build] Files=1, Tests=1,  0 wallclock secs
17:05:13 10/04/2020 [.tom/tasks/build] Result: PASS
17:05:17 10/04/2020 [.tom/tasks/build] ===> Installing: Teddy Bear:ver<0.0.1>
```

To edit a task, run:

```bash
$ tom --edit build-app
```
And you'll get your `$EDITOR` opening task source code ... 

# More examples

Tomtit allow more then that. We've just seen a simple example. 
Let me bring some more ones.

## Creating a task that return a value back to Raku scenario

Say one have a http endpoint (it could be any internal API) that return some output in JSON format to be proceeded. These type of tasks are quite frequent in my daily $job. It's dead easy to create a Tomtit helper for that:


```bash
$ mkdir -p .tom/tasks/trigger-api/tasks/http-call
$ nano .tom/tasks/trigger-api/tasks/http-call/task.bash
```

```bash
#!bash
curl -f -o $cache_root_dir/out.json  $(config url)
```

```bash
$ nano .tom/tasks/trigger-api/hook.pl6
```

```perl
#!raku
run_task "http-call"; 
```

```bash
$ nano .tom/tasks/trigger-api/task.pl6
```

```perl
#!raku
use JSON::Tiny;
update_state from-json("{cache_root_dir()}/out.json".IO.slurp) 
```

```bash
$ tom --edit trigger-api
```

```perl
#!raku
my %state = task-run ".tom/tasks/trigger-api", %(
   url => "http://foo.bar.baz/API"
);

say "data received", %state.perl;
```

And run the task as:

```bash
$ tom trigger-api
```

# Sharing your tasks with others

Very soon, as I develop my scripts I see that some of them repeatable and solve the same tasks. To reduce code duplication and allow team members to use my scripts I can package them and distribute as Sparrow plugins. Remember that Tomtit built on the top of Sparrow?

So for the last example I can move a `trigger-api` script into separate git repository and convert in into a plugin:

```bash
$ mkdir ~/plugins/
$ mv .tom/tasks/trigger-api/ ~/plugins
$ cd ~/plugins/trigger-api
$ nano sparrow.json
```

```json
{
  "name" : "trigger-api",
  "description" : "call http API",
  "version" : "0.0.1"
}
```

And finally upload it to a repository:
 
```bash
$ s6 --upload
02:31:46 10/05/2020 [repository] upload plugin
02:31:46 10/05/2020 [repository] upload trigger-api@0.0.1
```

Once a plugin uploaded to repository you can make it public by just running a web server with document root at repository root:

```bash
$ cd ~/repo && python -m http.server 8000
```

So my team would pick it up as:

```bash
$ export SP6_REPO=http://$my_host:8000 
``` 

Now the last bit - let's refactor `trigger-api` Raku task so that it uses a plugin:


```perl
#!raku
my %state = task-run "http call", "trigger-api", %(
   url => "http://foo.bar.baz/API"
);

say "data received", %state.perl;
```

---

That is it. I hope you've enjoyed the post. As usual I'd appreciate any feedback and comments.