Completed
Push — master ( a64d37...bc15d8 )
by Viacheslav
06:34
created

GenGo::setUpDefinition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 17
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 26
rs 9.7
1
<?php
2
3
namespace Swaggest\JsonCli;
4
5
use Swaggest\GoCodeBuilder\JsonSchema\GoBuilder;
6
use Swaggest\GoCodeBuilder\JsonSchema\StripPrefixPathToNameHook;
7
use Swaggest\GoCodeBuilder\JsonSchema\StructHookCallback;
8
use Swaggest\GoCodeBuilder\Templates\GoFile;
9
use Swaggest\GoCodeBuilder\Templates\Struct\StructDef;
10
use Swaggest\JsonSchema\Context;
11
use Swaggest\JsonSchema\JsonSchema;
12
use Swaggest\JsonSchema\RemoteRef\Preloaded;
13
use Swaggest\JsonSchema\Schema;
14
use Yaoi\Command;
15
16
class GenGo extends Command
17
{
18
    /** @var string */
19
    public $schema;
20
    /** @var string */
21
    public $packageName = 'entities';
22
    /** @var string */
23
    public $rootName = 'Structure';
24
    /** @var bool */
25
    public $showConstProperties = false;
26
    /** @var bool */
27
    public $keepParentInPropertyNames = false;
28
    /** @var string[] */
29
    public $defPtr = ['#/definitions'];
30
    /** @var string[] */
31
    public $ptrInSchema;
32
33
    public $output;
34
35
36
    /**
37
     * @param Command\Definition $definition
38
     * @param \stdClass|static $options
39
     */
40
    public static function setUpDefinition(Command\Definition $definition, $options)
41
    {
42
        $definition->description = 'Generate Go code from JSON schema';
43
        $options->schema = Command\Option::create()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...amed()->setIsRequired() of type Yaoi\Command\Option is incompatible with the declared type string of property $schema.

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...
44
            ->setDescription('Path to JSON schema file')->setIsUnnamed()->setIsRequired();
45
46
        $options->output = Command\Option::create()
47
            ->setDescription('Path to output .go file, STDOUT is used by default')->setType();
48
49
        $options->ptrInSchema = Command\Option::create()->setType()->setIsVariadic()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...oot schema, default #') of type Yaoi\Command\Option is incompatible with the declared type string[] of property $ptrInSchema.

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('JSON pointers to structure in in root schema, default #');
51
52
        $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...
53
            ->setDescription('Go package name, default "entities"');
54
55
        $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...
56
            ->setDescription('Go root struct name, default "Structure", only used for # pointer');
57
58
        $options->defPtr = Command\Option::create()->setType()->setIsVariadic()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...default #/definitions') of type Yaoi\Command\Option is incompatible with the declared type string[] of property $defPtr.

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...
59
            ->setDescription('Definitions pointers to strip from symbol names, default #/definitions');
60
61
        $options->showConstProperties = Command\Option::create()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...es, hidden by default') of type Yaoi\Command\Option is incompatible with the declared type boolean of property $showConstProperties.

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...
62
            ->setDescription('Show properties with constant values, hidden by default');
63
64
        $options->keepParentInPropertyNames = Command\Option::create()
0 ignored issues
show
Documentation Bug introduced by
It seems like Yaoi\Command\Option::cre...e, removed by default') of type Yaoi\Command\Option is incompatible with the declared type boolean of property $keepParentInPropertyNames.

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...
65
            ->setDescription('Keep parent prefix in property name, removed by default');
66
67
    }
68
69
70
    public function performAction()
71
    {
72
        $dataValue = Base::readJsonOrYaml($this->schema, $this->response);
73
        if (!$dataValue) {
74
            $this->response->error('Unable to find schema in ' . $this->schema);
75
            die(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
76
        }
77
78
        $skipRoot = false;
79
        if (empty($this->ptrInSchema)) {
80
            $schema = Schema::import($dataValue);
81
        } else {
82
            $baseName = basename($this->schema);
83
            $skipRoot = true;
84
            $preloaded = new Preloaded();
85
            $preloaded->setSchemaData($baseName, $dataValue);
86
            $data = new \stdClass();
87
            foreach ($this->ptrInSchema as $i => $ptr) {
88
                $data->oneOf[$i] = (object)[Schema::PROP_REF => $baseName . $ptr];
89
            }
90
            $schema = Schema::import($data, new Context($preloaded));
91
        }
92
93
94
        $builder = new GoBuilder();
95
        $builder->options->hideConstProperties = !$this->showConstProperties;
96
        $builder->options->trimParentFromPropertyNames = !$this->keepParentInPropertyNames;
97
        $pathToNameHook = new StripPrefixPathToNameHook();
98
99
        if (!empty($this->defPtr)) {
100
            $pathToNameHook->prefixes = [];
101
            foreach ($this->defPtr as $defPtr) {
102
                if (isset($baseName)) {
103
                    $pathToNameHook->prefixes[] = $baseName . $defPtr;
104
                }
105
                $pathToNameHook->prefixes[] = $defPtr;
106
            }
107
        }
108
109
        if (isset($baseName)) {
110
            $pathToNameHook->prefixes[] = $baseName;
111
        }
112
113
        $builder->pathToNameHook = $pathToNameHook;
114
115
        $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

115
        $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...
116
            if ('#' === $path) {
117
                $structDef->setName($this->rootName);
118
            }
119
        });
120
        if ($schema instanceof JsonSchema) {
121
            $builder->getType($schema);
122
        }
123
124
        $goFile = new GoFile($this->packageName);
125
        $goFile->fileComment = 'Code generated by github.com/swaggest/json-cli, DO NOT EDIT.';
126
        $goFile->setComment('Package ' . $this->packageName . ' contains JSON mapping structures.');
127
        foreach ($builder->getGeneratedStructs() as $generatedStruct) {
128
            if ($skipRoot && $generatedStruct->path === '#') {
129
                continue;
130
            }
131
            $goFile->getCode()->addSnippet($generatedStruct->structDef);
132
        }
133
        $goFile->getCode()->addSnippet($builder->getCode());
134
135
        if ($this->output) {
136
            file_put_contents($this->output, $goFile->render());
137
        } else {
138
            echo $goFile->render();
139
        }
140
    }
141
}