Failed Conditions
Push — master ( b9670c...4ba57f )
by Zac
16:20 queued 37s
created

src/ResultBundle/Command/ResultCleanupCommand.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Overwatch\ResultBundle\Command;
4
5
use Overwatch\ResultBundle\Entity\TestResult;
6
use Overwatch\ResultBundle\Enum\ResultStatus;
7
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Input\InputOption;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use Symfony\Component\DependencyInjection\ContainerInterface;
12
13
/**
14
 * ResultCleanupCommand
15
 * The overwatch:result:cleanup command, that archives old results
16
 */
17
class ResultCleanupCommand extends ContainerAwareCommand
18
{
19
    /**
20
     * @var \Doctrine\ORM\EntityManager
21
     */
22
    private $em;
23
24
    /**
25
     * @var \Overwatch\ResultBundle\Entity\TestResultRepository
26
     */
27
    private $resultRepo;
28
29
    /**
30
     * @var \Symfony\Component\Console\Output\OutputInterface
31
     */
32
    private $output;
33
34
    private $archiveFile = null;
35
36 6
    protected function configure()
37
    {
38 6
        $this
39 6
            ->setName('overwatch:results:cleanup')
40 6
            ->setDescription('Deletes and optionally archives older test results')
41 6
            ->addOption('delete', null, InputOption::VALUE_REQUIRED, 'Delete test results older than this value')
42 6
            ->addOption('compress', null, InputOption::VALUE_REQUIRED, 'Compress test results older than this value')
43 6
            ->addOption('archive', null, InputOption::VALUE_NONE, 'Archive items to a file')
44 6
            ->setHelp(<<<EOF
45
The <info>%command.name%</info> deletes and optionally archives older test results.
46
47
  <info>php %command.full_name%</info>
48
49
By default, the command will perform no operation. You should pass the <info>--delete</info> and/or <info>--compress</info>
50
options to configure what operations the command will apply.
51
52
See https://github.com/zsturgess/overwatch/blob/master/app/Resources/docs/installing.md#cleaning-up-results
53
54
EOF
55 6
            )
56
        ;
57 6
    }
58
59 6
    public function setContainer(ContainerInterface $container = null)
60
    {
61 6
        parent::setContainer($container);
62
63
        //Set up some shortcuts to services
64 6
        if ($container !== null) {
65 6
            $this->em = $container->get('doctrine.orm.entity_manager');
66 6
        }
67 6
    }
68
69 6
    protected function execute(InputInterface $input, OutputInterface $output)
70
    {
71 6
        $this->output = $output;
72 6
        $this->resultRepo = $this->em->getRepository('OverwatchResultBundle:TestResult');
73
74 6
        $delete = $this->convertOption($input->getOption('delete'));
75 6
        $compress = $this->convertOption($input->getOption('compress'));
76
77 6
        $this->output->writeln($this->getApplication()->getLongVersion() . ', running a cleanup');
78
79 6
        if ($delete === null && $compress === null) {
80 1
            throw new \InvalidArgumentException('Neither the --delete or --compress options were passed. No operation will be completed.');
81
        }
82
83 5
        if ($input->getOption('archive')) {
84 3
            $this->prepareArchive();
85 2
        }
86
87 4
        $this->deleteResults($delete);
88 4
        $this->compressResults($compress);
89
90 4
        $output->writeln(' > Applying <info>' . count($this->em->getUnitOfWork()->getScheduledEntityDeletions()) . '</info> cleanup operations');
91 4
        $this->em->flush();
92 4
        $output->writeln('<info>Cleanup finished</info>');
93 4
    }
94
95 6
    private function convertOption($option)
96
    {
97 6
        if ($option === null) {
98 6
            return null;
99
        }
100
101 5
        return new \DateTime($option);
102
    }
103
104 3
    private function prepareArchive()
105
    {
106 3
        $archiveDir = $this->getContainer()->get('kernel')->getRootDir() . '/logs/';
107 3
        $header = $this->getApplication()->getName() . ' ' . $this->getApplication()->getVersion() . ', running a cleanup';
108
109 3
        $this->archiveFile = $archiveDir . 'overwatch_archive_' . date('YmdHis') . '.log';
110 3
        $this->output->writeln(' > Preparing archive file <info>' . $this->archiveFile . '</info>');
111
112 3 View Code Duplication
        if (!file_put_contents($this->archiveFile, $header . PHP_EOL, FILE_APPEND)) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
113 1
            throw new \InvalidArgumentException('Could not write to the archive file.');
114
        }
115 2
    }
116
117
    /**
118
     * @param null|\DateTime $delete
119
     */
120 4
    private function deleteResults($delete)
121
    {
122 4
        if ($delete === null) {
123 2
            return;
124
        }
125
126 2
        $this->output->writeln(' > Finding results older than <info>' . $delete->format('Y-m-d H:i:s') . '</info> to delete');
127 2
        $resultsToCleanup = $this->resultRepo->getResultsOlderThan($delete);
128
129 2
        foreach ($resultsToCleanup as $row) {
130 2
            $result = $row[0];
131
132 2
            $this->archiveResult($result);
133 2
        }
134 2
    }
135
136
    /**
137
     * @param null|\DateTime $compress
138
     */
139 4
    private function compressResults($compress)
140
    {
141 4
        if ($compress === null) {
142 2
            return;
143
        }
144
145 2
        $lastResult = ResultStatus::PASSED;
146 2
        $this->output->writeln(' > Finding results older than <info>' . $compress->format('Y-m-d H:i:s') . '</info> to compress');
147 2
        $resultsToCleanup = $this->resultRepo->getResultsOlderThan($compress);
148
149 2
        foreach ($resultsToCleanup as $row) {
150 2
            $result = $row[0];
151
152 2
            if ($result->getStatus() === $lastResult) {
153 2
                $this->archiveResult($result);
154 2
            }
155
156 2
            $lastResult = $result->getStatus();
157 2
        }
158 2
    }
159
160 4
    private function archiveResult(TestResult $result)
161
    {
162 4 View Code Duplication
        if ($this->archiveFile !== null) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
163 2
            file_put_contents($this->archiveFile, (string) $result . PHP_EOL, FILE_APPEND);
164 2
        }
165
166 4
        $this->em->remove($result);
167 4
    }
168
}
169