GenGo::performAction()   F
last analyzed

Complexity

Conditions 15
Paths 667

Size

Total Lines 75
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 15
eloc 48
nc 667
nop 0
dl 0
loc 75
rs 2.2124
c 5
b 0
f 0

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
namespace Swaggest\JsonCli;
4
5
use Swaggest\GoCodeBuilder\JsonSchema\GoBuilder;
6
use Swaggest\GoCodeBuilder\JsonSchema\MarshalingTestFunc;
7
use Swaggest\GoCodeBuilder\JsonSchema\StripPrefixPathToNameHook;
8
use Swaggest\GoCodeBuilder\JsonSchema\StructHookCallback;
9
use Swaggest\GoCodeBuilder\Templates\GoFile;
10
use Swaggest\GoCodeBuilder\Templates\Struct\StructDef;
11
use Swaggest\JsonCli\GenGo\BuilderOptions;
12
use Swaggest\JsonCli\JsonSchema\ResolverMux;
13
use Swaggest\JsonSchema\Context;
14
use Swaggest\JsonSchema\RemoteRef\BasicFetcher;
15
use Swaggest\JsonSchema\RemoteRef\Preloaded;
16
use Swaggest\JsonSchema\Schema;
17
use Yaoi\Command;
18
19
class GenGo extends Base
20
{
21
    use BuilderOptions;
0 ignored issues
show
Bug introduced by
The trait Swaggest\JsonCli\GenGo\BuilderOptions requires the property $file which is not provided by Swaggest\JsonCli\GenGo.
Loading history...
22
23
    /** @var string */
24
    public $packageName = 'entities';
25
26
    /** @var string */
27
    public $rootName = 'Structure';
28
29
    /** @var bool */
30
    public $withTests = false;
31
32
    public $output;
33
34
    /**
35
     * @param Command\Definition $definition
36
     * @param \stdClass|static $options
37
     */
38
    public static function setUpDefinition(Command\Definition $definition, $options)
39
    {
40
        $definition->description = 'Generate Go code from JSON schema';
41
        Base::setupGenOptions($definition, $options);
42
43
        $options->output = Command\Option::create()
44
            ->setDescription('Path to output .go file, STDOUT is used by default')->setType();
45
46
        $options->packageName = Command\Option::create()->setType()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...e, default "entities"') of type Yaoi\Command\Option is incompatible with the declared type string of property $packageName.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
47
            ->setDescription('Go package name, default "entities"');
48
49
        $options->rootName = Command\Option::create()->setType()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...ly used for # pointer') of type Yaoi\Command\Option is incompatible with the declared type string of property $rootName.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
50
            ->setDescription('Go root struct name, default "Structure", only used for # pointer');
51
52
        $options->withTests = Command\Option::create()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...experimental feature)') of type Yaoi\Command\Option is incompatible with the declared type boolean of property $withTests.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
53
            ->setDescription('Generate (un)marshaling tests for entities (experimental feature)');
54
55
        static::setUpBuilderOptions($options);
56
    }
57
58
59
    public function performAction()
60
    {
61
        try {
62
            $skipRoot = false;
63
            $baseName = null;
64
            $schema = $this->loadSchema($skipRoot, $baseName);
65
66
            $builderOptions = $this->makeGoBuilderOptions();
67
            $builder = new GoBuilder();
68
            $builder->options = $builderOptions;
69
70
            $pathToNameHook = new StripPrefixPathToNameHook();
71
72
            if (!empty($this->defPtr)) {
73
                $pathToNameHook->prefixes = [];
74
                foreach ($this->defPtr as $defPtr) {
75
                    if (isset($baseName)) {
76
                        $pathToNameHook->prefixes[] = $baseName . $defPtr;
77
                    }
78
                    $pathToNameHook->prefixes[] = $defPtr;
79
                }
80
            }
81
82
            if (isset($baseName)) {
83
                $pathToNameHook->prefixes[] = $baseName;
84
            }
85
86
            $builder->pathToNameHook = $pathToNameHook;
87
88
            $builder->structCreatedHook = new StructHookCallback(function (StructDef $structDef, $path, $schema) {
0 ignored issues
show
Unused Code introduced by
The parameter $schema is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

88
            $builder->structCreatedHook = new StructHookCallback(function (StructDef $structDef, $path, /** @scrutinizer ignore-unused */ $schema) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
89
                if ('#' === $path) {
90
                    $structDef->setName($this->rootName);
91
                }
92
            });
93
            if ($schema instanceof Schema) {
94
                $builder->getType($schema);
95
            }
96
97
            $goFile = new GoFile($this->packageName);
98
            $goFile->fileComment = 'Code generated by github.com/swaggest/json-cli ' . App::$ver . ', DO NOT EDIT.';
99
            $goFile->setComment('Package ' . $this->packageName . ' contains JSON mapping structures.');
100
101
            $goTestFile = new GoFile($this->packageName . '_test');
102
            $goTestFile->setPackage($this->packageName);
103
            $goTestFile->fileComment = 'Code generated by github.com/swaggest/json-cli ' . App::$ver . ', DO NOT EDIT.';
104
105
            mt_srand(1);
106
107
            foreach ($builder->getGeneratedStructs() as $generatedStruct) {
108
                if ($skipRoot && $generatedStruct->path === '#') {
109
                    continue;
110
                }
111
                $goFile->getCode()->addSnippet($generatedStruct->structDef);
112
                if ($this->withTests) {
113
                    $goTestFile->getCode()->addSnippet(MarshalingTestFunc::make($generatedStruct, $builder->options));
114
                }
115
            }
116
            $goFile->getCode()->addSnippet($builder->getCode());
117
118
            if ($this->output) {
119
                if (!file_exists(dirname($this->output))) {
120
                    $this->response->error('Destination directory does not exist, please create: ' . dirname($this->output));
121
                    throw new ExitCode('', 1);
122
                }
123
                file_put_contents($this->output, $goFile->render());
124
125
                if ($this->withTests) {
126
                    file_put_contents(str_replace('.go', '_test.go', $this->output), $goTestFile->render());
127
                }
128
            } else {
129
                echo $goFile->render();
130
            }
131
        } catch (\Exception $e) {
132
            $this->response->error($e->getMessage());
133
            throw new ExitCode('', 1);
134
        }
135
    }
136
}