Completed
Push — master ( 01982b...3c7394 )
by ANTHONIUS
11s
created

AddCommand   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 114
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 10
dl 0
loc 114
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A configure() 0 8 1
A doAddDir() 0 17 2
A doAddFile() 0 9 1
B execute() 0 25 5
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\Config\Config;
17
use Dotfiles\Core\Exceptions\InvalidOperationException;
18
use Dotfiles\Core\Util\Filesystem;
19
use Dotfiles\Core\Util\Toolkit;
20
use Psr\Log\LoggerInterface;
21
use Symfony\Component\Console\Input\InputArgument;
22
use Symfony\Component\Console\Input\InputInterface;
23
use Symfony\Component\Console\Input\InputOption;
24
use Symfony\Component\Console\Output\OutputInterface;
25
use Symfony\Component\Finder\Finder;
26
27
class AddCommand extends Command implements CommandInterface
28
{
29
    /**
30
     * @var Config
31
     */
32
    private $config;
33
34
    /**
35
     * @var LoggerInterface
36
     */
37
    private $logger;
38
39
    /**
40
     * @var OutputInterface
41
     */
42
    private $output;
43
44
    public function __construct(
45
        ?string $name = null,
46
        Config $config,
47
        LoggerInterface $logger
48
    ) {
49
        parent::__construct($name);
50
        $this->config = $config;
51
        $this->logger = $logger;
52
    }
53
54
    protected function configure(): void
55
    {
56
        $this
57
            ->setName('add')
58
            ->setDescription('Add new file into dotfiles manager')
59
            ->addArgument('path', InputArgument::REQUIRED, 'A file or directory name to add. This file must be exists in $HOME directory')
60
            ->addOption('machine', '-m', InputOption::VALUE_OPTIONAL, 'Add this file/directory into machine registry', 'default')
61
            ->addOption('recursive', '-r', InputOption::VALUE_NONE, 'Import all directory contents recursively')
62
        ;
63
    }
64
65
    /**
66
     * @param InputInterface  $input
67
     * @param OutputInterface $output
68
     *
69
     * @return int|null|void
70
     *
71
     * @throws InvalidOperationException when path not exists
72
     */
73
    protected function execute(InputInterface $input, OutputInterface $output)
74
    {
75
        $this->output = $output;
76
        $config = $this->config;
77
        $recursive = $input->getOption('recursive');
78
        $machine = $input->getOption('machine');
79
        $repoDir = $config->get('dotfiles.repo_dir')."/src/$machine/home";
80
        $sourcePath = $input->getArgument('path');
81
        $originPath = $config->get('dotfiles.home_dir').DIRECTORY_SEPARATOR.$sourcePath;
82
        $targetPath = $repoDir.'/'.str_replace('.', '', $sourcePath);
83
84
        if (!is_file($originPath) && !is_dir($originPath)) {
85
            throw new InvalidOperationException("Path <comment>$sourcePath</comment> not exists");
86
        }
87
        Toolkit::ensureDir($repoDir);
88
89
        $basename = basename($sourcePath);
90
        if (0 === strpos($basename, '.')) {
91
            $targetPath = str_replace('.'.$sourcePath, $basename, $targetPath);
92
        }
93
94
        if (is_dir($originPath)) {
95
            $this->doAddDir($originPath, $targetPath, $recursive);
96
        } else {
97
            $this->doAddFile($originPath, $targetPath);
98
        }
99
    }
100
101
    /**
102
     * @param string $origin
103
     * @param string $target
104
     * @param bool   $recursive
105
     *
106
     * @throws InvalidOperationException
107
     */
108
    private function doAddDir(string $origin, string $target, $recursive): void
109
    {
110
        if (!$recursive) {
111
            throw new InvalidOperationException('Add dir without recursive');
112
        }
113
114
        $finder = Finder::create()
115
            ->in($origin)
116
            ->ignoreVCS(true)
117
            ->ignoreDotFiles(false)
118
        ;
119
        $fs = new Filesystem();
120
        $fs->mirror($origin, $target, $finder);
121
        $this->output->writeln(sprintf(
122
            'copy files from <comment>%s</comment> to <comment>%s</comment>',
123
            $origin,
124
            $target
125
        ));
126
    }
127
128
    /**
129
     * @param string $origin
130
     * @param string $target
131
     */
132
    private function doAddFile(string $origin, string $target): void
133
    {
134
        $fs = new Filesystem();
135
        $fs->copy($origin, $target);
136
        $this->output->writeln(
137
            sprintf(
138
                'copy from <comment>%s</comment> to <comment>%s</comment>',
139
                $origin,
140
                $target
141
            )
142
        );
143
    }
144
}
145