-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathGenGo.php
136 lines (109 loc) · 4.84 KB
/
GenGo.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<?php
namespace Swaggest\JsonCli;
use Swaggest\GoCodeBuilder\JsonSchema\GoBuilder;
use Swaggest\GoCodeBuilder\JsonSchema\MarshalingTestFunc;
use Swaggest\GoCodeBuilder\JsonSchema\StripPrefixPathToNameHook;
use Swaggest\GoCodeBuilder\JsonSchema\StructHookCallback;
use Swaggest\GoCodeBuilder\Templates\GoFile;
use Swaggest\GoCodeBuilder\Templates\Struct\StructDef;
use Swaggest\JsonCli\GenGo\BuilderOptions;
use Swaggest\JsonCli\JsonSchema\ResolverMux;
use Swaggest\JsonSchema\Context;
use Swaggest\JsonSchema\RemoteRef\BasicFetcher;
use Swaggest\JsonSchema\RemoteRef\Preloaded;
use Swaggest\JsonSchema\Schema;
use Yaoi\Command;
class GenGo extends Base
{
use BuilderOptions;
/** @var string */
public $packageName = 'entities';
/** @var string */
public $rootName = 'Structure';
/** @var bool */
public $withTests = false;
public $output;
/**
* @param Command\Definition $definition
* @param \stdClass|static $options
*/
public static function setUpDefinition(Command\Definition $definition, $options)
{
$definition->description = 'Generate Go code from JSON schema';
Base::setupGenOptions($definition, $options);
$options->output = Command\Option::create()
->setDescription('Path to output .go file, STDOUT is used by default')->setType();
$options->packageName = Command\Option::create()->setType()
->setDescription('Go package name, default "entities"');
$options->rootName = Command\Option::create()->setType()
->setDescription('Go root struct name, default "Structure", only used for # pointer');
$options->withTests = Command\Option::create()
->setDescription('Generate (un)marshaling tests for entities (experimental feature)');
static::setUpBuilderOptions($options);
}
public function performAction()
{
try {
$skipRoot = false;
$baseName = null;
$schema = $this->loadSchema($skipRoot, $baseName);
$builderOptions = $this->makeGoBuilderOptions();
$builder = new GoBuilder();
$builder->options = $builderOptions;
$pathToNameHook = new StripPrefixPathToNameHook();
if (!empty($this->defPtr)) {
$pathToNameHook->prefixes = [];
foreach ($this->defPtr as $defPtr) {
if (isset($baseName)) {
$pathToNameHook->prefixes[] = $baseName . $defPtr;
}
$pathToNameHook->prefixes[] = $defPtr;
}
}
if (isset($baseName)) {
$pathToNameHook->prefixes[] = $baseName;
}
$builder->pathToNameHook = $pathToNameHook;
$builder->structCreatedHook = new StructHookCallback(function (StructDef $structDef, $path, $schema) {
if ('#' === $path) {
$structDef->setName($this->rootName);
}
});
if ($schema instanceof Schema) {
$builder->getType($schema);
}
$goFile = new GoFile($this->packageName);
$goFile->fileComment = 'Code generated by github.com/swaggest/json-cli ' . App::$ver . ', DO NOT EDIT.';
$goFile->setComment('Package ' . $this->packageName . ' contains JSON mapping structures.');
$goTestFile = new GoFile($this->packageName . '_test');
$goTestFile->setPackage($this->packageName);
$goTestFile->fileComment = 'Code generated by github.com/swaggest/json-cli ' . App::$ver . ', DO NOT EDIT.';
mt_srand(1);
foreach ($builder->getGeneratedStructs() as $generatedStruct) {
if ($skipRoot && $generatedStruct->path === '#') {
continue;
}
$goFile->getCode()->addSnippet($generatedStruct->structDef);
if ($this->withTests) {
$goTestFile->getCode()->addSnippet(MarshalingTestFunc::make($generatedStruct, $builder->options));
}
}
$goFile->getCode()->addSnippet($builder->getCode());
if ($this->output) {
if (!file_exists(dirname($this->output))) {
$this->response->error('Destination directory does not exist, please create: ' . dirname($this->output));
throw new ExitCode('', 1);
}
file_put_contents($this->output, $goFile->render());
if ($this->withTests) {
file_put_contents(str_replace('.go', '_test.go', $this->output), $goTestFile->render());
}
} else {
echo $goFile->render();
}
} catch (\Exception $e) {
$this->response->error($e->getMessage());
throw new ExitCode('', 1);
}
}
}