src/GenGo.php
<?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);
}
}
}