AOEpeople/StackFormation

View on GitHub
src/StackFormation/Command/Stack/TreeCommand.php

Summary

Maintainability
A
1 hr
Test Coverage
<?php

namespace StackFormation\Command\Stack;

use StackFormation\Helper\Decorator;
use StackFormation\Stack;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class TreeCommand extends \StackFormation\Command\AbstractCommand
{

    protected function configure()
    {
        $this
            ->setName('stack:tree')
            ->setDescription('List all stacks as tree')
            ->addOption(
                'nameFilter',
                null,
                InputOption::VALUE_OPTIONAL,
                'Name Filter (regex). Example --nameFilter \'/^foo/\''
            )
            ->addOption(
                'statusFilter',
                null,
                InputOption::VALUE_OPTIONAL,
                'Name Filter (regex). Example --statusFilter \'/IN_PROGRESS/\''
            );
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $nameFilter = $input->getOption('nameFilter');
        $statusFilter = $input->getOption('statusFilter');

        $stacks = $this->getStackFactory()->getStacksFromApi(false, $nameFilter, $statusFilter);
        $dataTree = $this->prepareTree($stacks);
        $dataTree = $this->flatternTree($dataTree);
        $this->renderNode($dataTree);
    }

    /**
     * prepare stack list
     *
     * @param StackFormation\Stack[]
     * @return array
     */
    protected function prepareTree(array $arr) {
        $tree = [];
        foreach ($arr as $a) {
            $name = $a->getName();
            $cur = &$tree;
            foreach (explode("-", $name) as $e) {
                if (empty($cur[$e])) $cur[$e] = [];
                $cur = &$cur[$e];
            }
        }
        return $tree;
    }

    /**
     * flattern tree to gain a better overview
     *
     * @param array $treeIn
     * @return array
     */
    protected function flatternTree(array $treeIn)
    {
        $treeOut = [];
        foreach ($treeIn as $name => $children) {
            if (count($children) === 0) {
                $treeOut[$name] = [];
            } elseif (count($children) === 1) {
                $name = sprintf('%s-%s', $name, key($children));
                if (count($children[key($children)]) > 0) {
                    $treeOut[$name] = $this->flatternTree($children[key($children)]);
                }else{
                    $treeOut[$name] = [];
                }
            } else {
                $treeOut[$name] = $this->flatternTree($children);
            }

        }
        return $treeOut;
    }

    /**
     * render tree node
     *
     * @param string $tree
     * @param int $depth
     * @param int $cap
     */
    protected function renderNode($tree, $depth = 0, $cap = 0) {

        $n = count($tree);
        foreach ($tree as $k => $next) {
            for ($pre = "", $i = $depth - 1; $i >= 0; $i--){
                $pre.= $cap >> $i & 1 ? "│  " : "   ";
            }
            echo $pre, --$n > 0 ? '├──' : '└──', $k, PHP_EOL;
            if (false === empty($next)){
                $this->renderNode($next, $depth + 1, ($cap << 1) | ($n > 0));
            }
        }
    }
}