Completed
Push — master ( 7df85e...fc1c11 )
by recca
21:52 queued 20:42
created

Find   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 0
loc 151
ccs 0
cts 48
cp 0
rs 10
c 0
b 0
f 0
wmc 17
lcom 1
cbo 4

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A run() 0 12 1
D handle() 0 54 13
A getArguments() 0 6 1
A getOptions() 0 9 1
1
<?php
2
3
namespace Recca0120\Terminal\Console\Commands;
4
5
use Exception;
6
use Illuminate\Filesystem\Filesystem;
7
use Symfony\Component\Console\Input\InputArgument;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Input\InputOption;
10
use Symfony\Component\Console\Input\StringInput;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use Symfony\Component\Finder\Finder;
13
14
class Find extends Command
15
{
16
    /**
17
     * The console command name.
18
     *
19
     * @var string
20
     */
21
    protected $name = 'find';
22
23
    /**
24
     * The console command description.
25
     *
26
     * @var string
27
     */
28
    protected $description = 'search for files in a directory hierarchy';
29
30
    /**
31
     * $finder.
32
     *
33
     * @var \Symfony\Component\Finder\Finder
34
     */
35
    protected $finder;
36
37
    /**
38
     * $files.
39
     *
40
     * @var \Illuminate\Filesystem\Filesystem
41
     */
42
    protected $files;
43
44
    /**
45
     * __construct.
46
     *
47
     * @param \Symfony\Component\Finder\Finder  $finder
48
     * @param \Illuminate\Filesystem\Filesystem $files
49
     */
50
    public function __construct(Finder $finder, Filesystem $files)
51
    {
52
        parent::__construct();
53
54
        $this->finder = $finder;
55
        $this->files = $files;
56
    }
57
58
    /**
59
     * run.
60
     *
61
     * @param \Symfony\Component\Console\Input\InputInterface   $input
62
     * @param \Symfony\Component\Console\Output\OutputInterface $output
63
     * @return int
64
     */
65
    public function run(InputInterface $input, OutputInterface $output)
66
    {
67
        $command = (string) $input;
68
        $command = strtr($command, [
69
            ' -name' => ' -N',
70
            ' -type' => ' -T',
71
            ' -maxdepth' => ' -M',
72
            ' -delete' => ' -d true',
73
        ]);
74
75
        return parent::run(new StringInput($command), $output);
76
    }
77
78
    /**
79
     * Handle the command.
80
     *
81
     * @throws \InvalidArgumentException
82
     */
83
    public function handle()
84
    {
85
        $path = $this->argument('path');
86
        $name = $this->option('name');
87
        $type = $this->option('type');
88
        $maxDepth = $this->option('maxdepth');
89
        $delete = filter_var($this->option('delete'), FILTER_VALIDATE_BOOLEAN);
90
91
        $root = function_exists('base_path') === true ? base_path() : getcwd();
92
        $path = rtrim($root, '/').'/'.$path;
93
94
        $this->finder->in($path);
95
96
        if (is_null($name) === false) {
97
            $this->finder->name($name);
98
        }
99
100
        switch ($type) {
101
            case 'd':
102
                $this->finder->directories();
103
                break;
104
            case 'f':
105
                $this->finder->files();
106
                break;
107
        }
108
109
        if (is_null($maxDepth) === false) {
110
            if ($maxDepth == '0') {
111
                $this->line($path);
112
113
                return;
114
            }
115
            $this->finder->depth('<'.$maxDepth);
116
        }
117
118
        foreach ($this->finder->getIterator() as $file) {
119
            $realPath = $file->getRealpath();
120
            if ($delete === true && $this->files->exists($realPath) === true) {
121
                $removed = false;
122
                try {
123
                    if ($this->files->isDirectory($realPath) === true) {
124
                        $removed = $this->files->deleteDirectory($realPath);
125
                    } else {
126
                        $removed = $this->files->delete($realPath);
127
                    }
128
                } catch (Exception $e) {
129
                    $removed = false;
130
                }
131
                $removed === true ? $this->info('removed '.$realPath) : $this->error('removed '.$realPath.' fail');
132
            } else {
133
                $this->line($realPath);
134
            }
135
        }
136
    }
137
138
    /**
139
     * Get the console command arguments.
140
     *
141
     * @return array
142
     */
143
    protected function getArguments()
144
    {
145
        return [
146
            ['path', InputArgument::REQUIRED, 'path'],
147
        ];
148
    }
149
150
    /**
151
     * Get the console command options.
152
     *
153
     * @return array
154
     */
155
    protected function getOptions()
156
    {
157
        return [
158
            ['type', 'T', InputOption::VALUE_OPTIONAL, 'File is of type c: [f, d]'],
159
            ['name', 'N', InputOption::VALUE_OPTIONAL, 'Base of file name (the path with the leading directories removed) matches shell pattern pattern.  The metacharacters (`*\', `?\', and `[]\') match a `.\' at  the  start of  the  base name (this is a change in findutils-4.2.2; see section STANDARDS CONFORMANCE below).  To ignore a directory and the files under it, use -prune; see an example in the description of -path.  Braces are not recognised as being special, despite the fact that some shells including Bash imbue braces with a special meaning in shell patterns.  The filename matching is performed with the use of the fnmatch(3) library function.   Don\'t forget to enclose the pattern in quotes in order to protect it from expansion by the shell.'],
160
            ['maxdepth', 'M', InputOption::VALUE_OPTIONAL, '-maxdepth alias -M'],
161
            ['delete', 'd', InputOption::VALUE_OPTIONAL, 'Delete files; true if removal succeeded.  If the removal failed, an error message is issued.  If -delete fails, find\'s exit status will be nonzervagranto (when it  eventually exits).  Use of -delete automatically turns on the -depth option.'],
162
        ];
163
    }
164
}
165