Passed
Pull Request — master (#9)
by ANTHONIUS
03:11
created

InitCommand::doBackupRepoDir()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 24
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.5125
c 0
b 0
f 0
cc 5
eloc 15
nc 2
nop 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A InitCommand::doAskInstallDir() 0 9 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the dotfiles project.
7
 *
8
 *     (c) Anthonius Munthi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Dotfiles\Core\Command;
15
16
use Dotfiles\Core\DI\Parameters;
17
use Dotfiles\Core\Exceptions\InvalidOperationException;
18
use Dotfiles\Core\Processor\ProcessRunner;
19
use Dotfiles\Core\Util\Toolkit;
20
use Symfony\Component\Console\Input\InputArgument;
21
use Symfony\Component\Console\Input\InputInterface;
22
use Symfony\Component\Console\Input\InputOption;
23
use Symfony\Component\Console\Output\OutputInterface;
24
use Symfony\Component\Console\Question\Question;
25
26
class InitCommand extends Command
27
{
28
    /**
29
     * @var string
30
     */
31
    private $defaultBackupDir;
32
33
    /**
34
     * @var string
35
     */
36
    private $defaultHomeDir;
37
38
    /**
39
     * @var InputInterface
40
     */
41
    private $input;
42
43
    /**
44
     * @var OutputInterface
45
     */
46
    private $output;
47
48
    /**
49
     * @var Parameters
50
     */
51
    private $parameters;
52
53
    /**
54
     * @var ProcessRunner
55
     */
56
    private $runner;
57
58
    public function __construct(?string $name = null, ProcessRunner $processor, Parameters $parameters)
59
    {
60
        parent::__construct($name);
61
        $this->runner = $processor;
62
        $this->parameters = $parameters;
63
        $this->defaultHomeDir = $parameters->get('dotfiles.home_dir');
64
        $this->defaultBackupDir = $parameters->get('dotfiles.backup_dir');
65
    }
66
67
    protected function configure(): void
68
    {
69
        $this
70
            ->setName('init')
71
            ->setDescription('Initialize new Dotfiles project.')
72
            ->addArgument('backup-dir', InputArgument::OPTIONAL, 'Local repository directory')
73
            ->addOption('machine', 'm', InputOption::VALUE_OPTIONAL, 'Machine name')
74
            ->addOption('install-dir', 'i', InputOption::VALUE_OPTIONAL, 'Dotfiles instalaltion directory installation')
75
        ;
76
    }
77
78
    /**
79
     * @param InputInterface  $input
80
     * @param OutputInterface $output
81
     *
82
     * @return int|null|void
83
     */
84
    protected function execute(InputInterface $input, OutputInterface $output)
85
    {
86
        $this->input = $input;
87
        $this->output = $output;
88
89
        if (null === ($backupDir = $input->getArgument('backup-dir'))) {
90
            $backupDir = $this->doAskBackupDir();
91
        }
92
93
        if (null === ($machine = $input->getOption('machine'))) {
94
            $machine = $this->doAskMachineName();
95
        }
96
97
        if (null === ($installDir = $input->getOption('install-dir'))) {
98
            $installDir = $this->doAskInstallDir();
99
        }
100
101
        $this->initDotfilesProfile($backupDir, $machine, $installDir);
102
    }
103
104
    private function doAskBackupDir()
105
    {
106
        $input = $this->input;
107
        $output = $this->output;
108
        $helper = $this->getHelper('question');
109
        $default = getenv('DOTFILES_BACKUP_DIR');
110
        $question = new Question("Please enter local backup dir (<comment>$default</comment>): ", $default);
111
        $question->setValidator(function ($answer) {
112
            $parent = dirname($answer);
113
            if (!is_dir($parent) || !is_writable($parent)) {
114
                throw new InvalidOperationException(
115
                    "Can not find parent directory, please ensure that $parent is exists and writable"
116
                );
117
            }
118
119
            return $answer;
120
        });
121
122
        $question->setMaxAttempts(3);
123
124
        return $helper->ask($input, $output, $question);
125
    }
126
127
    private function doAskInstallDir()
128
    {
129
        $input = $this->input;
130
        $output = $this->output;
131
        $helper = $this->getHelper('question');
132
        $default = getenv('DOTFILES_HOME_DIR').'/.dotfiles';
133
        $question = new Question(sprintf('Your installation directory (<comment>%s</comment>):', $default), $default);
134
135
        return $helper->ask($input, $output, $question);
136
    }
137
138
    private function doAskMachineName()
139
    {
140
        $input = $this->input;
141
        $output = $this->output;
142
        $helper = $this->getHelper('question');
143
        $default = getenv('DOTFILES_MACHINE_NAME');
144
        $question = new Question(sprintf('Please enter your machine name (<comment>%s</comment>):', $default), $default);
145
146
        return $helper->ask($input, $output, $question);
147
    }
148
149
    private function initDotfilesProfile(string $backupDir, string $machine, $installDir): void
150
    {
151
        $time = (new \DateTime())->format('Y-m-d H:i:s');
152
        $envFile = getenv('DOTFILES_HOME_DIR').'/.dotfiles_profile';
153
        Toolkit::ensureFileDir($envFile);
154
        $contents = <<<EOF
155
# generated at $time
156
DOTFILES_MACHINE_NAME=$machine
157
DOTFILES_BACKUP_DIR=$backupDir
158
DOTFILES_INSTALL_DIR=$installDir
159
EOF;
160
161
        file_put_contents($envFile, $contents, LOCK_EX);
162
    }
163
}
164