Write mutations

Here are the basics to create new mutations.

Create directory structure

transmute command reads mutations in filesystem. By default in mutations/ directory relative to current working directory.

transmute collects executable files as follows:

  • mutations/recurrent/* are “recurrent” mutations. They will be executed for each release.
  • mutations/development/* are “in-development” mutations. The “development” release is a special one. It will always be executed last, and “in-development” mutations will always be executed backward then forward.
  • mutations/*/* are mutations within a “release”.
  • mutations/* are mutations without a “release”.

Here is a sample directory layout (from the Demo):

├── 0001_hello_world.sh
├── 0002_hello_world.py
├── 1.0
│   └── 0093_print_version.sh
├── 1.1
│   └── 0060_print_version.sh
├── development
│   └── 0077_refactoring.py
└── recurrent
    └── 0050_syncdb.sh

Mutations are executable files

transmute command collects only executables. It means you can run any program (provided your system is compatible).

It also means that you can attach data (images, json, ...) inside the mutations/ folder and use data within your mutations scripts.

bash

Here is a mutation script written in bash:

# Here is a minimal mutation using sh.
# It is just an executable script.
echo 'Hello world!'

Since this script doesn’t handle arguments, its content will be executed for both forward and backward operations.

Python

Here is a mutation script written in Python:

#!/usr/bin/env python
"""This mutation shows how ``transmutator`` can be used as a Python library."""
import transmutator


class HelloWorldMutation(transmutator.AtomicMutation):
    """`transmutator` provides base classes to implement mutations."""
    def forward(self):
        """Forward: say hello using Python."""
        print("Hello Python world!")

    def backward(self):
        """Backward: say goodbye using Python."""
        print("Goodbye Python world!")


if __name__ == '__main__':  # Python mutations are scripts, just like sh ones.
    mutation = HelloWorldMutation()  # Mutations may be initialized with conf.
    mutation()  # Mutation instances are callables.

As you can see, this script takes advantage of transmutator as a Python library. The AtomicMutation instances are callables that run either forward() or backward() method depending on command-line arguments.