Passed
Pull Request — master (#2226)
by Arnaud
09:02 queued 03:18
created

NewSite::execute()   C

Complexity

Conditions 12
Paths 186

Size

Total Lines 85
Code Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 55
c 1
b 0
f 0
nc 186
nop 2
dl 0
loc 85
rs 6.25

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * This file is part of Cecil.
5
 *
6
 * (c) Arnaud Ligny <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Cecil\Command;
15
16
use Cecil\Exception\RuntimeException;
17
use Cecil\Util;
18
use Symfony\Component\Console\Input\InputArgument;
19
use Symfony\Component\Console\Input\InputInterface;
20
use Symfony\Component\Console\Input\InputOption;
21
use Symfony\Component\Console\Output\OutputInterface;
22
use Symfony\Component\Yaml\Yaml;
23
24
/**
25
 * NewSite command.
26
 *
27
 * This command creates a new website in the specified directory or the current directory if no path is provided.
28
 * It prompts the user for various details about the website, such as title, baseline, base URL, description, and author information.
29
 * It can also add demo content if the `--demo` option is provided.
30
 * If the `--force` option is used, it will override an existing website in the specified directory.
31
 */
32
class NewSite extends AbstractCommand
33
{
34
    /**
35
     * {@inheritdoc}
36
     */
37
    protected function configure()
38
    {
39
        $this
40
            ->setName('new:site')
41
            ->setDescription('Creates a new website')
42
            ->setDefinition([
43
                new InputArgument('path', InputArgument::OPTIONAL, 'Use the given path as working directory'),
44
                new InputOption('force', 'f', InputOption::VALUE_NONE, 'Override directory if it already exists'),
45
                new InputOption('demo', null, InputOption::VALUE_NONE, 'Add demo content (pages, templates and assets)'),
46
            ])
47
            ->setHelp(
48
                <<<'EOF'
49
The <info>%command.name%</> command creates a new website in the current directory, or in <comment><path></> if provided.
50
If you run this command without any options, it will ask you for the website title, baseline, base URL, description, etc.
51
52
  <info>%command.full_name%</>
53
  <info>%command.full_name% path/to/the/working/directory</>
54
55
To create a new website with <comment>demo content</comment>, run:
56
57
  <info>%command.full_name% --demo</>
58
59
To <comment>override</comment> an existing website, run:
60
61
  <info>%command.full_name% --force</>
62
EOF
63
            );
64
    }
65
66
    /**
67
     * {@inheritdoc}
68
     *
69
     * @throws RuntimeException
70
     */
71
    protected function execute(InputInterface $input, OutputInterface $output): int
72
    {
73
        $force = $input->getOption('force');
74
        $demo = $input->getOption('demo');
75
76
        try {
77
            // ask to override existing site?
78
            if (Util\File::getFS()->exists(Util::joinFile($this->getPath(false), $this->locateConfigFile($this->getPath())['name'] ?: self::CONFIG_FILE[0])) && !$force) {
79
                $output->writeln('<comment>Website already exists.</comment>');
80
                if (!$this->io->confirm('Do you want to override it?', false)) {
81
                    return 0;
82
                }
83
            }
84
            // setup questions
85
            $title = $this->io->ask('Give a title to your website', 'New website');
86
            $baseline = $this->io->ask('Give a baseline to your website', '');
87
            $baseurl = $this->io->ask('Base URL?', '/', [$this, 'validateUrl']);
88
            $description = $this->io->ask('Write a full description of your site', 'Website created with Cecil.');
89
            $demo = ($demo !== false) ?: $this->io->confirm('Add demo content?', false);
90
            // override skeleton default config
91
            $config = Yaml::parseFile(Util::joinPath($this->rootPath, 'resources/skeleton', self::CONFIG_FILE[0]), Yaml::PARSE_DATETIME);
92
            $config = array_replace_recursive($config, [
93
                'title'       => $title,
94
                'baseline'    => $baseline,
95
                'baseurl'     => $baseurl,
96
                'description' => $description
97
            ]);
98
            $configYaml = Yaml::dump($config, 2, 2);
99
            Util\File::getFS()->dumpFile(Util::joinPath($this->getPath(), $this->locateConfigFile($this->getPath())['name'] ?: self::CONFIG_FILE[0]), $configYaml);
100
            // create path dir
101
            Util\File::getFS()->mkdir($this->getPath(false));
102
            // creates sub dir
103
            foreach (
104
                [
105
                    (string) $this->getBuilder()->getConfig()->get('assets.dir'),
106
                    (string) $this->getBuilder()->getConfig()->get('layouts.dir'),
107
                    (string) $this->getBuilder()->getConfig()->get('pages.dir'),
108
                    (string) $this->getBuilder()->getConfig()->get('static.dir'),
109
                ] as $value
110
            ) {
111
                Util\File::getFS()->mkdir(Util::joinPath($this->getPath(), $value));
112
            }
113
            // copy files
114
            foreach (
115
                [
116
                    'assets/favicon.png',
117
                    'assets/icon.png',
118
                    'pages/index.md',
119
                ] as $value
120
            ) {
121
                Util\File::getFS()->copy(
122
                    Util::joinPath($this->rootPath, 'resources/skeleton', $value),
123
                    Util::joinPath($this->getPath(), $value)
124
                );
125
            }
126
            // demo: copy all files
127
            if ($demo) {
128
                foreach (
129
                    [
130
                        (string) $this->getBuilder()->getConfig()->get('assets.dir'),
131
                        (string) $this->getBuilder()->getConfig()->get('layouts.dir'),
132
                        (string) $this->getBuilder()->getConfig()->get('pages.dir'),
133
                        (string) $this->getBuilder()->getConfig()->get('static.dir'),
134
                    ] as $value
135
                ) {
136
                    Util\File::getFS()->mirror(
137
                        Util::joinPath($this->rootPath, 'resources/skeleton', $value),
138
                        Util::joinPath($this->getPath(), $value)
139
                    );
140
                }
141
            }
142
            // done
143
            $output->writeln(\sprintf('<info>Your new website is created in %s.</info>', realpath($this->getPath())));
144
            $this->io->newLine();
145
            $this->io->listing([
146
                'Start the built-in preview server with <info>' . $this->binName() . ' serve</info>',
147
                'You can create a new page with <info>' . $this->binName() . ' new:page</info>',
148
            ]);
149
150
            $this->io->text('Visit <href=https://cecil.app>https://cecil.app</> for documentation and more.');
151
        } catch (\Exception $e) {
152
            throw new RuntimeException(\sprintf($e->getMessage()));
153
        }
154
155
        return 0;
156
    }
157
}
158