NewSite::execute()   F
last analyzed

Complexity

Conditions 13
Paths 380

Size

Total Lines 93
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 13
eloc 61
c 1
b 1
f 0
nc 380
nop 2
dl 0
loc 93
rs 3.5333

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)
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
            // define root path
85
            $root = Util\Platform::isPhar() ? Util\Platform::getPharPath() . '/' : realpath(Util::joinFile(__DIR__, '/../../'));
86
            // setup questions
87
            $title = $this->io->ask('Give a title to your website', 'New website');
88
            $baseline = $this->io->ask('Give a baseline to your website', '');
89
            $baseurl = $this->io->ask('Base URL?', '/', [$this, 'validateUrl']);
90
            $description = $this->io->ask('Write a full description of your site', 'Website created with Cecil.');
91
            $authorName = $this->io->ask('What is the author name?', 'Cecil');
92
            $authorUrl = $this->io->ask('What is the author URL?', 'https://cecil.app', [$this, 'validateUrl']);
93
            $demo = ($demo !== false) ?: $this->io->confirm('Add demo content?', false);
94
            // override skeleton default config
95
            $config = Yaml::parseFile(Util::joinPath($root, 'resources/skeleton', self::CONFIG_FILE[0]), Yaml::PARSE_DATETIME);
96
            $config = array_replace_recursive($config, [
97
                'title'       => $title,
98
                'baseline'    => $baseline,
99
                'baseurl'     => $baseurl,
100
                'description' => $description,
101
                'author'      => [
102
                    'name' => $authorName,
103
                    'url'  => $authorUrl,
104
                ],
105
            ]);
106
            $configYaml = Yaml::dump($config, 2, 2);
107
            Util\File::getFS()->dumpFile(Util::joinPath($this->getPath(), $this->locateConfigFile($this->getPath())['name'] ?: self::CONFIG_FILE[0]), $configYaml);
108
            // create path dir
109
            Util\File::getFS()->mkdir($this->getPath(false));
110
            // creates sub dir
111
            foreach (
112
                [
113
                    (string) $this->getBuilder()->getConfig()->get('assets.dir'),
114
                    (string) $this->getBuilder()->getConfig()->get('layouts.dir'),
115
                    (string) $this->getBuilder()->getConfig()->get('pages.dir'),
116
                    (string) $this->getBuilder()->getConfig()->get('static.dir'),
117
                ] as $value
118
            ) {
119
                Util\File::getFS()->mkdir(Util::joinPath($this->getPath(), $value));
120
            }
121
            // copy files
122
            foreach (
123
                [
124
                    'assets/favicon.png',
125
                    'pages/index.md',
126
                    'static/cecil-card.png',
127
                ] as $value
128
            ) {
129
                Util\File::getFS()->copy(
130
                    Util::joinPath($root, 'resources/skeleton', $value),
131
                    Util::joinPath($this->getPath(), $value)
132
                );
133
            }
134
            // demo: copy all files
135
            if ($demo) {
136
                foreach (
137
                    [
138
                        (string) $this->getBuilder()->getConfig()->get('assets.dir'),
139
                        (string) $this->getBuilder()->getConfig()->get('layouts.dir'),
140
                        (string) $this->getBuilder()->getConfig()->get('pages.dir'),
141
                        (string) $this->getBuilder()->getConfig()->get('static.dir'),
142
                    ] as $value
143
                ) {
144
                    Util\File::getFS()->mirror(
145
                        Util::joinPath($root, 'resources/skeleton', $value),
146
                        Util::joinPath($this->getPath(), $value)
147
                    );
148
                }
149
            }
150
            // done
151
            $output->writeln(\sprintf('<info>Your new website is created in %s.</info>', realpath($this->getPath())));
152
            $this->io->newLine();
153
            $this->io->listing([
154
                'Start the built-in preview server with <info>' . $this->binName() . ' serve</info>',
155
                'You can create a new page with <info>' . $this->binName() . ' new:page</info>',
156
            ]);
157
158
            $this->io->text('Visit <href=https://cecil.app>https://cecil.app</> for documentation and more.');
159
        } catch (\Exception $e) {
160
            throw new RuntimeException(\sprintf($e->getMessage()));
161
        }
162
163
        return 0;
164
    }
165
}
166