<commit_before># tempo

[![Build Status](https://travis-ci.org/assimtech/tempo.svg?branch=master)](https://travis-ci.org/assimtech/tempo)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/assimtech/tempo/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/assimtech/tempo/?branch=master)
[![Code Coverage](https://scrutinizer-ci.com/g/assimtech/tempo/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/assimtech/tempo/?branch=master)


Tempo is a scripting tool for running commands on local or remote nodes. It was originally developed to script complex
`php` project deployments however can be used for all kinds of tasks (e.g. unix user management, package updates etc).


## Quick start

Download [tempo.phar](https://github.com/assimtech/tempo/releases/download/0.1.0/tempo.phar).
If you place it in `~/bin/tempo` and make it executable you will be able to run `tempo` from any of your projects.


Create a `tempo.php` file in the root of your project containing the following:

```php
<?php

// If you have installed tempo with composer into your project, omit the autoloader
require_once __DIR__ . '/vendor/autoload.php';
// If you aren't using composer you are responsible for loading MyProject\Tempo\Command\* etc
// This can be done with require's or your own autoloader

use Assimtech\Tempo;
use MyProject\Tempo\Command;

// Infrastructure
$infrastructureLoader = Tempo\Factory\InfrastructureLoaderFactory::create();
$infrastructure = $infrastructureLoader->load(__DIR__ . '/tempo/infrastructure.yml');

// Commands
$definition = new Tempo\Definition();
foreach ($infrastructure->getEnvironments() as $env) {
    $definition->addCommand(new Command\WhereAmI($env));
}

return $definition;
```

Then create a `tempo/infrastructure.yml` file containing the following:
```yaml
nodes:
    server1:
        ssh:
            host: server1.example.com

environments:
    -
        name: test
        nodes: [ server1, server2 ]
```

Change "server1.example.com" to a server you have ssh access to.
If you need to change username / port etc, please see the documentation on how to setup a [Node](docs/04-Nodes.md)


Then create a `MyProject\Tempo\Command\WhereAmI` class containing the following:
```php
<?php

namespace MyProject\Tempo\Command;

use Assimtech\Tempo\Command\AbstractCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class WhereAmI extends AbstractCommand
{
    /**
     * {@inheritdoc}
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        foreach ($this->env->getNodes() as $node) {
            $output->write("I'm on: ");
            $hostname = $node->run('hostname --fqdn');
            $output->writeln($hostname);

            $ips = $node->run('/sbin/ifconfig');
            $output->writeln($ips);
        }
    }
}
```

Run tempo from within the root of your project:

```shell<commit_msg>Added return code to command execute<commit_after># tempo

[![Build Status](https://travis-ci.org/assimtech/tempo.svg?branch=master)](https://travis-ci.org/assimtech/tempo)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/assimtech/tempo/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/assimtech/tempo/?branch=master)
[![Code Coverage](https://scrutinizer-ci.com/g/assimtech/tempo/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/assimtech/tempo/?branch=master)


Tempo is a scripting tool for running commands on local or remote nodes. It was originally developed to script complex
`php` project deployments however can be used for all kinds of tasks (e.g. unix user management, package updates etc).


## Quick start

Download [tempo.phar](https://github.com/assimtech/tempo/releases/download/0.1.0/tempo.phar).
If you place it in `~/bin/tempo` and make it executable you will be able to run `tempo` from any of your projects.


Create a `tempo.php` file in the root of your project containing the following:

```php
<?php

// If you have installed tempo with composer into your project, omit the autoloader
require_once __DIR__ . '/vendor/autoload.php';
// If you aren't using composer you are responsible for loading MyProject\Tempo\Command\* etc
// This can be done with require's or your own autoloader

use Assimtech\Tempo;
use MyProject\Tempo\Command;

// Infrastructure
$infrastructureLoader = Tempo\Factory\InfrastructureLoaderFactory::create();
$infrastructure = $infrastructureLoader->load(__DIR__ . '/tempo/infrastructure.yml');

// Commands
$definition = new Tempo\Definition();
foreach ($infrastructure->getEnvironments() as $env) {
    $definition->addCommand(new Command\WhereAmI($env));
}

return $definition;
```

Then create a `tempo/infrastructure.yml` file containing the following:
```yaml
nodes:
    server1:
        ssh:
            host: server1.example.com

environments:
    -
        name: test
        nodes: [ server1, server2 ]
```

Change "server1.example.com" to a server you have ssh access to.
If you need to change username / port etc, please see the documentation on how to setup a [Node](docs/04-Nodes.md)


Then create a `MyProject\Tempo\Command\WhereAmI` class containing the following:
```php
<?php

namespace MyProject\Tempo\Command;

use Assimtech\Tempo\Command\AbstractCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class WhereAmI extends AbstractCommand
{
    /**
     * {@inheritdoc}
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        foreach ($this->env->getNodes() as $node) {
            $output->write("I'm on: ");
            $hostname = $node->run('hostname --fqdn');
            $output->writeln($hostname);

            $ips = $node->run('/sbin/ifconfig');
            $output->writeln($ips);
        }
        return 0;
    }
}
```

Run tempo from within the root of your project:

```shell
{'fraction_non_alphanumeric': 0.12694952205265805, 'fraction_numerical': 0.0035217172564145564, 'mean_word_length': 3.912685337726524, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 23, 'https://': 14, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1287697', 'n_tokens_mistral': 1886, 'n_tokens_neox': 1812, 'n_words': 504}