Completed
Push — master ( 751190...396778 )
by Changwan
07:49
created

InstallCommand::execute()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 23
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 11
nc 3
nop 0
dl 0
loc 23
ccs 0
cts 14
cp 0
crap 12
rs 9.0856
c 0
b 0
f 0
1
<?php
2
namespace Wandu\Installation\Commands;
3
4
use Symfony\Component\Console\Input\InputInterface;
5
use Symfony\Component\Console\Output\OutputInterface;
6
use Symfony\Component\Console\Style\SymfonyStyle;
7
use Symfony\Component\Process\PhpExecutableFinder;
8
use Symfony\Component\Process\Process;
9
use Symfony\Component\Process\ProcessUtils;
10
use Wandu\Console\Command;
11
use Wandu\Installation\SkeletonBuilder;
12
13
class InstallCommand extends Command
14
{
15
    /** @var string */
16
    protected $description = "Install <comment>Wandu Framework</comment> to your project directory.";
17
18
    /** @var \Symfony\Component\Console\Style\SymfonyStyle */
19
    protected $io;
20
    
21
    /** @var array */
22
    protected $options = [
23
        'namespace?' => 'default wandu app namespace',
24
    ];
25
    
26
    /**
27
     * {@inheritdoc}
28
     */
29
    public function withIO(InputInterface $input, OutputInterface $output)
30
    {
31
        $this->io = new SymfonyStyle($input, $output);
32
        return parent::withIO($input, $output);
33
    }
34
35
    public function execute()
36
    {
37
        if (file_exists('.wandu.php')) {
38
            throw new \RuntimeException('already installed. if you want to re-install, remove the ".wandu.php" file!');
39
        }
40
41
        $this->output->writeln('Hello, <info>Welcome to Wandu Framework!</info>');
42
43
        $appBasePath = getcwd(); //static::filterPath($this->askAppBasePath('install path?', $basePath));
0 ignored issues
show
Unused Code Comprehensibility introduced by
80% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
44
45
        $appNamespace = $this->input->getOption('namespace') ?:
46
            $this->askAppNamespace('app namespace?', 'Wandu\\App');
47
        
48
        $this->install($appBasePath, $appNamespace);
49
50
        // set composer
51
        $this->saveAutoloadToComposer($appNamespace);
52
53
        // run composer
54
        $this->runDumpAutoload();
55
56
        $this->output->writeln("<info>Install Complete!</info>");
57
    }
58
59
    protected function install($appBasePath, $appNamespace)
60
    {
61
        $installer = new SkeletonBuilder($appBasePath, __DIR__ . '/../skeleton');
62
        $replacers = [
63
            'WanduSkeleton' => $appNamespace,
64
        ];
65
        $installer->build($replacers);
66
67
        file_put_contents($appBasePath . '/.wandu.php', <<<PHP
68
<?php
69
70
define('WANDU_DB_HOST', 'localhost');
71
define('WANDU_DB_DBNAME', 'wandu');
72
define('WANDU_DB_USERNAME', 'root');
73
define('WANDU_DB_PASSWORD', 'root');
74
define('WANDU_DB_PREFIX', 'local_');
75
76
return new {$appNamespace}\ApplicationDefinition();
77
78
PHP
79
        );
80
    }
81
    
82
    protected function runDumpAutoload()
83
    {
84
        if (file_exists('composer.phar')) {
85
            $binary = ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false));
0 ignored issues
show
Security Bug introduced by
It seems like (new \Symfony\Component\...eFinder())->find(false) targeting Symfony\Component\Proces...xecutableFinder::find() can also be of type false; however, Symfony\Component\Proces...Utils::escapeArgument() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
86
            $composer = "{$binary} composer.phar";
87
        } else {
88
            $composer = 'composer';
89
        }
90
        (new Process("{$composer} dump-autoload", getcwd()))->run();
91
    }
92
93
    protected function saveAutoloadToComposer($appNamespace)
94
    {
95
        $this->output->write("save autoload setting to composer... ");
96
97
        $composerJson = [];
98
        if (file_exists('composer.json')) {
99
            $composerJson = json_decode(file_get_contents('composer.json'), true);
100
            if (json_last_error()) {
101
                $composerJson = [];
102
            }
103
        }
104
105
        if (!isset($composerJson['autoload'])) {
106
            $composerJson['autoload'] = [];
107
        }
108
        if (!isset($composerJson['autoload']['psr-4'])) {
109
            $composerJson['autoload']['psr-4'] = [];
110
        }
111
        $composerJson['autoload']['psr-4'][$appNamespace . '\\'] = 'src/';
112
        file_put_contents(
113
            'composer.json',
114
            json_encode($composerJson, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT) . "\n"
115
        );
116
        $this->output->writeln("<info>ok</info>");
117
    }
118
119
    protected function askAppNamespace($message, $default)
120
    {
121
        return $this->io->ask($message, $default, function ($namespace) {
122
            return rtrim($namespace, '\\');
123
        });
124
    }
125
126
    /**
127
     * @param string $message
128
     * @param string $default
129
     * @return string
130
     */
131
    protected function askAppBasePath($message, $default)
132
    {
133
        if (function_exists('posix_getuid')) {
134
            $info = posix_getpwuid(posix_getuid());
135
            $default = str_replace($info['dir'], '~', $default);
136
        }
137
        return $this->io->ask($message, $default);
138
    }
139
140
    /**
141
     * @param string $path
142
     * @return string
143
     */
144
    static protected function filterPath($path)
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
145
    {
146
        if ($path[0] === '~') {
147
            if (!function_exists('posix_getuid')) {
148
                throw new \InvalidArgumentException('cannot use tilde(~) character in your php environment.');
149
            }
150
            $info = posix_getpwuid(posix_getuid());
151
            $path = str_replace('~', $info['dir'], $path);
152
        }
153
154
        $basePath = getcwd();
155
        if ($path === $basePath) {
156
            $path = '.';
157
        } elseif (strpos($path, $basePath) === 0) {
158
            $path = str_replace("{$basePath}/", './', $path);
159
        } elseif ($path[0] === '/' || strpos($path, './') === 0) {
0 ignored issues
show
Unused Code introduced by
This elseif statement is empty, and could be removed.

This check looks for the bodies of elseif statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These elseif bodies can be removed. If you have an empty elseif but statements in the else branch, consider inverting the condition.

Loading history...
160
        } elseif (strpos($path, '..') === 0) {
161
            $path = realpath($basePath . '/' . $path);
162
        } else {
163
            $path = './' . $path;
164
        }
165
        return rtrim($path, '/');
166
    }
167
}
168