Completed
Push — master ( d2e043...09ed12 )
by Changwan
12:25
created

InstallCommand::install()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 2
dl 0
loc 22
ccs 0
cts 18
cp 0
crap 2
rs 9.2
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
    /**
22
     * {@inheritdoc}
23
     */
24
    public function withIO(InputInterface $input, OutputInterface $output)
25
    {
26
        $this->io = new SymfonyStyle($input, $output);
27
        return parent::withIO($input, $output);
28
    }
29
30
    public function execute()
31
    {
32
        if (file_exists('.wandu.php')) {
33
            throw new \RuntimeException('already installed. if you want to re-install, remove the ".wandu.php" file!');
34
        }
35
36
        $this->output->writeln('Hello, <info>Welcome to Wandu Framework!</info>');
37
38
        $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...
39
        $appNamespace = $this->askAppNamespace('app namespace?', 'Wandu\\App');
40
        
41
        $this->install($appBasePath, $appNamespace);
42
43
        // set composer
44
        $this->saveAutoloadToComposer($appNamespace);
45
46
        // run composer
47
        $this->runDumpAutoload();
48
49
        $this->output->writeln("<info>Install Complete!</info>");
50
    }
51
52
    protected function install($appBasePath, $appNamespace)
53
    {
54
        $installer = new SkeletonBuilder($appBasePath, __DIR__ . '/../skeleton');
55
        $replacers = [
56
            'YourOwnApp' => $appNamespace,
57
        ];
58
        $installer->build($replacers);
59
60
        file_put_contents($appBasePath . '/.wandu.php', <<<PHP
61
<?php
62
63
define('WANDU_DB_HOST', 'localhost');
64
define('WANDU_DB_DBNAME', 'wandu');
65
define('WANDU_DB_USERNAME', 'root');
66
define('WANDU_DB_PASSWORD', 'root');
67
define('WANDU_DB_PREFIX', 'local_');
68
69
return new {$appNamespace}\ApplicationDefinition();
70
71
PHP
72
        );
73
    }
74
    
75
    protected function runDumpAutoload()
76
    {
77
        if (file_exists('composer.phar')) {
78
            $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...
79
            $composer = "{$binary} composer.phar";
80
        } else {
81
            $composer = 'composer';
82
        }
83
        (new Process("{$composer} dump-autoload", getcwd()))->run();
84
    }
85
86
    protected function saveAutoloadToComposer($appNamespace)
87
    {
88
        $this->output->write("save autoload setting to composer... ");
89
90
        $composerJson = [];
91
        if (file_exists('composer.json')) {
92
            $composerJson = json_decode(file_get_contents('composer.json'), true);
93
            if (json_last_error()) {
94
                $composerJson = [];
95
            }
96
        }
97
98
        if (!isset($composerJson['autoload'])) {
99
            $composerJson['autoload'] = [];
100
        }
101
        if (!isset($composerJson['autoload']['psr-4'])) {
102
            $composerJson['autoload']['psr-4'] = [];
103
        }
104
        $composerJson['autoload']['psr-4'][$appNamespace . '\\'] = 'src/';
105
        file_put_contents(
106
            'composer.json',
107
            json_encode($composerJson, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT) . "\n"
108
        );
109
        $this->output->writeln("<info>ok</info>");
110
    }
111
112
    protected function askAppNamespace($message, $default)
113
    {
114
        return $this->io->ask($message, $default, function ($namespace) {
115
            return rtrim($namespace, '\\');
116
        });
117
    }
118
119
    /**
120
     * @param string $message
121
     * @param string $default
122
     * @return string
123
     */
124
    protected function askAppBasePath($message, $default)
125
    {
126
        if (function_exists('posix_getuid')) {
127
            $info = posix_getpwuid(posix_getuid());
128
            $default = str_replace($info['dir'], '~', $default);
129
        }
130
        return $this->io->ask($message, $default);
131
    }
132
133
    /**
134
     * @param string $path
135
     * @return string
136
     */
137
    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...
138
    {
139
        if ($path[0] === '~') {
140
            if (!function_exists('posix_getuid')) {
141
                throw new \InvalidArgumentException('cannot use tilde(~) character in your php environment.');
142
            }
143
            $info = posix_getpwuid(posix_getuid());
144
            $path = str_replace('~', $info['dir'], $path);
145
        }
146
147
        $basePath = getcwd();
148
        if ($path === $basePath) {
149
            $path = '.';
150
        } elseif (strpos($path, $basePath) === 0) {
151
            $path = str_replace("{$basePath}/", './', $path);
152
        } 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...
153
        } elseif (strpos($path, '..') === 0) {
154
            $path = realpath($basePath . '/' . $path);
155
        } else {
156
            $path = './' . $path;
157
        }
158
        return rtrim($path, '/');
159
    }
160
}
161