Completed
Push — master ( 9226b3...e0bc2b )
by Mike
08:41
created

GenerateSpecCommand::execute()   C

Complexity

Conditions 7
Paths 5

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 7
eloc 19
c 2
b 0
f 0
nc 5
nop 2
dl 0
loc 32
rs 6.7272
1
<?php
2
3
namespace Sugarcrm\UpgradeSpec\Command;
4
5
use Sugarcrm\UpgradeSpec\Data\Manager;
6
use Sugarcrm\UpgradeSpec\Helper\File;
7
use Sugarcrm\UpgradeSpec\Helper\Sugarcrm;
8
use Sugarcrm\UpgradeSpec\Spec\Context;
9
use Sugarcrm\UpgradeSpec\Spec\Generator;
10
use Symfony\Component\Console\Input\InputArgument;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Input\InputOption;
13
use Symfony\Component\Console\Output\OutputInterface;
14
15
class GenerateSpecCommand extends Command
16
{
17
    /**
18
     * @var Generator
19
     */
20
    private $generator;
21
22
    /**
23
     * @var Sugarcrm
24
     */
25
    private $sugarcrm;
26
27
    /**
28
     * @var File
29
     */
30
    private $file;
31
32
    /**
33
     * @var Manager
34
     */
35
    private $dataManager;
36
37
    /**
38
     * GenerateSpecCommand constructor.
39
     *
40
     * @param null      $name
41
     * @param Generator $generator
42
     * @param Manager   $dataManager
43
     * @param Sugarcrm  $sugarcrmHelper
44
     * @param File      $fileHelper
45
     */
46
    public function __construct($name, Generator $generator, Manager $dataManager, Sugarcrm $sugarcrmHelper, File $fileHelper)
47
    {
48
        parent::__construct($name);
49
50
        $this->generator = $generator;
51
        $this->dataManager = $dataManager;
52
        $this->sugarcrm = $sugarcrmHelper;
53
        $this->file = $fileHelper;
54
    }
55
56
    /**
57
     *  Configure the command.
58
     */
59
    protected function configure()
60
    {
61
        $this->setName('generate:spec')
62
            ->setDescription('Generate a new upgrade spec')
63
            ->addArgument('path', InputArgument::REQUIRED, 'Path to SugarCRM build we are going to upgrade')
64
            ->addArgument('version', InputArgument::OPTIONAL, 'Version to upgrade to')
65
            ->addOption('dump', 'D', InputOption::VALUE_NONE, 'Save generated spec to file')
66
            ->addOption('packagesPath', 'P', InputOption::VALUE_OPTIONAL, 'Path to a folder with SugarCRM upgrade packages');
67
    }
68
69
    /**
70
     * Execute the command.
71
     *
72
     * @param InputInterface  $input
73
     * @param OutputInterface $output
74
     *
75
     * @return int
76
     */
77
    protected function execute(InputInterface $input, OutputInterface $output)
78
    {
79
        $path = $input->getArgument('path');
80
81
        $version = $this->sugarcrm->getBuildVersion($path);
82
        $flav = $this->sugarcrm->getBuildFlav($path);
83
        $upgradeTo = $this->dataManager->getLatestVersion($flav, $input->getArgument('version'));
84
85
        $packagesPath = null;
86
        if ($input->hasParameterOption('--packagesPath') || $input->hasParameterOption('-P')) {
87
            $packagesPath = $input->getOption('packagesPath');
88
            if (!file_exists($packagesPath) || !is_readable($packagesPath)) {
89
                throw new \InvalidArgumentException('Invalid "upgradePackages" argument value');
90
            }
91
        }
92
93
        $upgradeContext = new Context($version, $upgradeTo, $flav, $packagesPath);
94
95
        $output->writeln(sprintf('<comment>Generating upgrade spec: %s ...</comment>', $upgradeContext));
96
97
        $spec = $this->generator->generate($upgradeContext);
98
99
        if ($input->hasParameterOption('--dump') || $input->hasParameterOption('-D')) {
100
            $this->file->saveToFile(sprintf('%s.md', $upgradeContext->asFilename()), $spec);
101
        } else {
102
            $output->writeln(sprintf('<info>%s</info>', $spec));
103
        }
104
105
        $output->writeln('<comment>Done</comment>');
106
107
        return 0;
108
    }
109
110
    /**
111
     * @param InputInterface $input
112
     */
113
    protected function validateInput(InputInterface $input)
114
    {
115
        $path = $input->getArgument('path');
116
        $version = $input->getArgument('version');
117
118
        $this->validatePath($path);
119
        $this->validateVersion(
120
            $this->sugarcrm->getBuildVersion($path),
121
            $this->dataManager->getLatestVersion($this->sugarcrm->getBuildFlav($path), $version)
122
        );
123
    }
124
125
    /**
126
     * @param $path
127
     */
128
    private function validatePath($path)
129
    {
130
        if (!$this->sugarcrm->isSugarcrmBuild($path)) {
131
            throw new \InvalidArgumentException('Invalid "path" argument value');
132
        }
133
    }
134
135
    /**
136
     * @param $buildVersion
137
     * @param $upgradeTo
138
     */
139
    private function validateVersion($buildVersion, $upgradeTo)
140
    {
141
        $buildVersionParts = explode('.', $buildVersion);
142
143
        $fullVersion = $buildVersion;
144
145
        // v1.v2 -> v1.v2.0.0, v1.v2.v3 -> v1.v2.v3.0
146
        if (($versionLength = count($buildVersionParts)) < 4) {
147
            $fullVersion = implode('.', array_merge($buildVersionParts, array_fill(0, 4 - $versionLength, '0')));
148
        }
149
150
        if (!preg_match('/\d+(\.\d+){1,3}/', $upgradeTo)) {
151
            throw new \InvalidArgumentException('Invalid version format');
152
        }
153
154
        if (version_compare($fullVersion, $upgradeTo, '>=')) {
155
            throw new \InvalidArgumentException(sprintf('Given version ("%s") is lower or equal to the build version ("%s")', $upgradeTo, $buildVersion));
156
        }
157
    }
158
}
159