Completed
Push — master ( 85f4f7...c06f74 )
by James
03:18
created

DetectCommand::execute()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 4

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 17
ccs 15
cts 15
cp 1
rs 9.2
cc 4
eloc 11
nc 6
nop 2
crap 4
1
<?php
2
3
/**
4
 * This file is, guess what, part of WebHelper.
5
 *
6
 * (c) James <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace JamesRezo\WebHelper\Command;
13
14
use Symfony\Component\Console\Input\InputInterface;
15
use Symfony\Component\Console\Output\OutputInterface;
16
use Symfony\Component\Console\Input\InputArgument;
17
use JamesRezo\WebHelper\Factory;
18
use JamesRezo\WebHelper\WebServer\WebServerInterface;
19
20
/**
21
 * Detects webservers.
22
 */
23
class DetectCommand extends BaseCommand
24
{
25
    /**
26
     * {@inheritdoc}
27
     */
28 3
    protected function configure()
29
    {
30 3
        $this
31 3
            ->setName('detect')
32 3
            ->setDescription('Detect webservers on this platform.')
33 3
            ->setHelp('The <info>detect</info> command finds webserver binaries in the PATH'.
34 3
                ' or in the path passed in argument.')
35 3
            ->addArgument('path', InputArgument::IS_ARRAY, 'path list to look into for a binary instead of PATH.')
36
        ;
37 3
    }
38
39
    /**
40
     * Execute the command.
41
     *
42
     * {@inheritdoc}
43
     *
44
     * @param InputInterface  $input  the input interface
45
     * @param OutputInterface $output the output interface
46
     */
47 2
    protected function execute(InputInterface $input, OutputInterface $output)
48
    {
49 2
        $path = $this->getPath($input);
50 2
51 1
        $factory = new Factory();
52 1
        $files = false;
53
        foreach ($factory->getKnownWebServers() as $webservername) {
54 2
            $webserver = $factory->createWebServer($webservername);
55 2
            $file = $this->searchBinary($path, $webserver, $output);
56 2
            $files = $files || (strlen($file) > 0);
57 2
        }
58 2
        if (!$files) {
59 2
            $output->writeln('<error>No Web Server Found.</error>');
60 1
61 1
            return 1;
62 1
        }
63 1
    }
64 1
65 1
    /**
66 1
     * Finds the first binary available to manage a webserver.
67 1
     *
68 1
     * Validity of a binary is to retrieve a version and and default config file
69 1
     *
70 1
     * @param  array              $path      a list of directories to scan
71
     * @param  WebServerInterface $webserver the webserver to detect
72 1
     * @param  OutputInterface    $output    the output interface
73 1
     *
74 1
     * @return string the absolute path of the binary if found and valid, empty string elsewhere
75 1
     */
76
    private function searchBinary(array $path, WebServerInterface $webserver, OutputInterface $output)
77 2
    {
78 2
        $file = '';
79 2
80
        foreach ($webserver->getBinaries() as $binary) {
81 2
            $file = $this->which($binary, $path);
82
            if ($file) {
83 2
                $output->writeln('<comment>'.$file.' detected for '.$webserver->getName().'.</comment>');
84
                $settings = $webserver->getSettings($file);
85 2
86 2
                $version = $webserver->extractVersion($settings);
87 2
                if (!$version) {
88 1
                    $output->writeln('<error>No version found for "'.$file.'".</error>');
89 1
                    $file = '';
90 2
                    continue;
91
                }
92 2
93
                $configFile = $webserver->extractRootConfigurationFile($settings);
94
                if (!$configFile) {
95
                    $output->writeln('<error>No conf. file found for "'.$file.'".</error>');
96
                    $file = '';
97
                    continue;
98
                }
99
100
                if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE) {
101
                    $output->writeln('<comment>That says:</comment>');
102
                    $output->write($settings);
103
                }
104
105
                $output->writeln('<info>Detected version:</info>'.$version);
106
                $output->writeln('<info>Detected conf. file:</info>'.$configFile);
107
108
                if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
109
                    $output->writeln(
110
                        '<comment>You should analyze this with </comment>'.
111
                        'wh analyze '.$webserver->getName().':'.$version.' '.$configFile
112
                    );
113
                }
114
                break;
115
            }
116
        }
117
118
        return $file;
119
    }
120
121
    /**
122
     * A `which`-like function.
123
     *
124
     * Finds the absolute path of a binary in a list of directories
125
     *
126
     * @param string $binary the binary to find in a list of directories
127
     * @param array  $paths  a list of directories to scan
128
     *
129
     * @return string the absolute path of the binary if found, empty string elsewhere
130
     */
131
    private function which($binary, array $paths = array())
132
    {
133
        $file = '';
134
135
        foreach ($paths as $path) {
136
            $path = preg_replace('#('.preg_quote(DIRECTORY_SEPARATOR).')*$#', '', $path).DIRECTORY_SEPARATOR;
137
            if (is_executable($path.$binary) && !is_dir($path.$binary)) {
138
                $file = $path.$binary;
139
            }
140
        }
141
142
        return $file;
143
    }
144
}
145