Skip to content

Commit 53da2d4

Browse files
authored
Chore/init (#1)
* add converter * Create LICENSE * update readme
1 parent b5132cf commit 53da2d4

13 files changed

+463
-1
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea
2+
composer.lock
3+
vendor
4+
output

LICENSE

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2021, php-kafka
4+
Copyright (c) 2021, Nick Chiu
5+
6+
All rights reserved.
7+
8+
Redistribution and use in source and binary forms, with or without
9+
modification, are permitted provided that the following conditions are met:
10+
11+
1. Redistributions of source code must retain the above copyright notice, this
12+
list of conditions and the following disclaimer.
13+
14+
2. Redistributions in binary form must reproduce the above copyright notice,
15+
this list of conditions and the following disclaimer in the documentation
16+
and/or other materials provided with the distribution.
17+
18+
3. Neither the name of the copyright holder nor the names of its
19+
contributors may be used to endorse or promote products derived from
20+
this software without specific prior written permission.
21+
22+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,19 @@
1-
# avsc-json-converter
1+
# Avsc Json Schema converter
2+
Converts an Avsc schema into a JSON schema
3+
4+
## Installation
5+
```bash
6+
composer require php-kafka/avsc-json-converter
7+
```
8+
9+
## Usage
10+
Convert a folder with avsc files into json schema:
11+
```bash
12+
./bin/console convert:avsc-to-json avscFolder jsonOutputFolder
13+
```
14+
### Options
15+
- `--convertOnlyValueSchema` only convert avsc files that end with `value.avsc`
16+
- `--noDefaultAsRequired` only mark fields with no defaults as required instead of all
17+
18+
## Known issues
19+
This library is very experimental and has the following open [issues / tasks](https://github.com/php-kafka/avsc-json-converter/issues)

bin/avsc-to-json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../src/console.php

composer.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"name": "php-kafka/avsc-json-converter",
3+
"description": "Library that converts Avsc to JSON schema",
4+
"license": [
5+
"BSD-3-Clause"
6+
],
7+
"authors": [
8+
{
9+
"name": "php-kafka",
10+
"homepage": "https://php-kafka.com"
11+
},
12+
{
13+
"name": "Nick",
14+
"email": "coding.nikazu@gmail.com",
15+
"homepage": "https://github.com/nick-zh"
16+
}
17+
],
18+
"keywords": [
19+
"avsc",
20+
"json",
21+
"schema",
22+
"converter"
23+
],
24+
"config": {
25+
"sort-packages": true
26+
},
27+
"require": {
28+
"php": "^7.4|^8.0",
29+
"ext-json": "*",
30+
"symfony/console": "^5.3",
31+
"pimple/pimple": "^3.5"
32+
},
33+
"bin": [
34+
"bin/avsc-to-json"
35+
],
36+
"autoload": {
37+
"psr-4": {
38+
"PhpKafka\\AvscJsonConverter\\": "src/"
39+
}
40+
},
41+
"extra": {
42+
"branch-alias": {
43+
"dev-main": "1.0-dev"
44+
}
45+
},
46+
"support": {
47+
"issues": "https://github.com/php-kafka/avsc-json-converter/issues"
48+
}
49+
}

src/AppContainer.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpKafka\AvscJsonConverter;
6+
7+
use PhpKafka\AvscJsonConverter\ServiceProvider\CommandServiceProvider;
8+
use PhpKafka\AvscJsonConverter\ServiceProvider\ConverterServiceProvider;
9+
use Pimple\Container;
10+
11+
class AppContainer
12+
{
13+
/**
14+
* @param string $env
15+
* @return Container
16+
*/
17+
public static function init(): Container
18+
{
19+
$container = new Container();
20+
21+
$container
22+
->register(new ConverterServiceProvider())
23+
->register(new CommandServiceProvider())
24+
;
25+
26+
27+
return $container;
28+
}
29+
}

src/Avro/Avro.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace PhpKafka\AvscJsonConverter\Avro;
4+
5+
class Avro
6+
{
7+
public const FILE_EXTENSION = 'avsc';
8+
public const LONELIEST_NUMBER = 1;
9+
public const BASIC_TYPES = [
10+
'null' => self::LONELIEST_NUMBER,
11+
'boolean' => self::LONELIEST_NUMBER,
12+
'int' => self::LONELIEST_NUMBER,
13+
'long' => self::LONELIEST_NUMBER,
14+
'float' => self::LONELIEST_NUMBER,
15+
'double' => self::LONELIEST_NUMBER,
16+
'bytes' => self::LONELIEST_NUMBER,
17+
'string' => self::LONELIEST_NUMBER,
18+
'enum' => self::LONELIEST_NUMBER,
19+
'array' => self::LONELIEST_NUMBER,
20+
'map' => self::LONELIEST_NUMBER,
21+
'fixed' => self::LONELIEST_NUMBER,
22+
];
23+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpKafka\AvscJsonConverter\Command;
6+
7+
use PhpKafka\AvscJsonConverter\Avro\Avro;
8+
use PhpKafka\AvscJsonConverter\Converter\ConverterInterface;
9+
use Symfony\Component\Console\Command\Command;
10+
use Symfony\Component\Console\Input\InputArgument;
11+
use Symfony\Component\Console\Input\InputInterface;
12+
use Symfony\Component\Console\Input\InputOption;
13+
use Symfony\Component\Console\Output\OutputInterface;
14+
15+
class ConvertAvscToJsonCommand extends Command
16+
{
17+
private ConverterInterface $converter;
18+
19+
public function __construct(ConverterInterface $converter, string $name = null)
20+
{
21+
$this->converter = $converter;
22+
parent::__construct($name);
23+
}
24+
25+
protected function configure(): void
26+
{
27+
$this
28+
->setName('convert:avsc-to-json')
29+
->setDescription('Convert avsc schema to json schema')
30+
->addArgument('schemaDirectory', InputArgument::REQUIRED, 'Schema directory')
31+
->addArgument('outputDirectory', InputArgument::REQUIRED, 'Output directory')
32+
->addOption('convertOnlyValueSchema', null, InputOption::VALUE_NONE, 'Only convert value schema')
33+
->addOption('noDefaultAsRequired', null, InputOption::VALUE_NONE, 'Instead of all fields, only fields with no default are required')
34+
;
35+
}
36+
37+
public function execute(InputInterface $input, OutputInterface $output): ?int
38+
{
39+
$count = 0;
40+
41+
/** @var string $schemaDirectory */
42+
$schemaDirectory = $input->getArgument('schemaDirectory');
43+
44+
/** @var string $outputDirectory */
45+
$outputDirectory = $input->getArgument('outputDirectory');
46+
47+
$onlyValueSchema = (bool) $input->getOption('convertOnlyValueSchema');
48+
$noDefaultAsRequired = (bool) $input->getOption('noDefaultAsRequired');
49+
50+
$iterator = new \RecursiveIteratorIterator(
51+
new \RecursiveDirectoryIterator(
52+
$schemaDirectory,
53+
\FilesystemIterator::SKIP_DOTS
54+
)
55+
);
56+
57+
/** @var \SplFileInfo $file */
58+
foreach ($iterator as $file) {
59+
if (Avro::FILE_EXTENSION !== $file->getExtension()) {
60+
continue;
61+
}
62+
63+
if (true === $onlyValueSchema && false === str_ends_with($file->getFilename(), 'value.avsc')) {
64+
continue;
65+
}
66+
67+
++$count;
68+
$avsc = file_get_contents($file->getRealPath());
69+
$json = $this->converter->convert($avsc, ['markNoDefaultAsRequired' => $noDefaultAsRequired]);
70+
71+
if (false === file_exists($outputDirectory)) {
72+
mkdir($outputDirectory);
73+
}
74+
75+
$fname = $outputDirectory . DIRECTORY_SEPARATOR . str_replace('.avsc', '.json', $file->getFilename());
76+
file_put_contents($fname, $json);
77+
}
78+
79+
$output->writeln(sprintf('Successfully converted %d schemas', $count));
80+
81+
return 0;
82+
}
83+
}

0 commit comments

Comments
 (0)