Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4694134405 | |||
| 8c1e874b03 | |||
| 593546e3ff | |||
| c6963e0574 | |||
| 83794a7464 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,8 +1,5 @@
|
|||||||
/.idea
|
/.idea
|
||||||
/.vscode
|
/.vscode
|
||||||
/vendor
|
/vendor
|
||||||
/nbproject
|
|
||||||
/tmp
|
|
||||||
|
|
||||||
.phpunit.result.cache
|
.phpunit.result.cache
|
||||||
.phpunit.cache
|
.phpunit.cache
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ Possible ARGUMENTS:
|
|||||||
-p, --preserve - do not delete OUTPUT_PATH (if exists)
|
-p, --preserve - do not delete OUTPUT_PATH (if exists)
|
||||||
--dump - convert provided arguments into settings file in `pwd`
|
--dump - convert provided arguments into settings file in `pwd`
|
||||||
-h, --help - show this help message and exit
|
-h, --help - show this help message and exit
|
||||||
--version - show version info and exit
|
-v, --version - show version info and exit
|
||||||
|
|
||||||
If no ARGUMENTS passed then --help implied.
|
If no ARGUMENTS passed then --help implied.
|
||||||
If both -f and -d are specified then only unique set of files from both arguments will be converted.
|
If both -f and -d are specified then only unique set of files from both arguments will be converted.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
],
|
],
|
||||||
"keywords": ["postman", "collection", "converter", "http", "wget", "curl", "api", "convert"],
|
"keywords": ["postman", "collection", "converter", "http", "wget", "curl", "api", "convert"],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.4",
|
"php": "^8.1",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-mbstring": "*",
|
"ext-mbstring": "*",
|
||||||
"ext-readline": "*"
|
"ext-readline": "*"
|
||||||
@@ -32,6 +32,6 @@
|
|||||||
"sort-packages": true
|
"sort-packages": true
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^12.5"
|
"phpunit/phpunit": "^10.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
885
composer.lock
generated
885
composer.lock
generated
File diff suppressed because it is too large
Load Diff
17
pm-convert
17
pm-convert
@@ -2,12 +2,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
use PmConverter\Handler;
|
|
||||||
const EOL = PHP_EOL;
|
const EOL = PHP_EOL;
|
||||||
const DS = DIRECTORY_SEPARATOR;
|
const DS = DIRECTORY_SEPARATOR;
|
||||||
|
|
||||||
const PM_VERSION = '1.8';
|
use PmConverter\Processor;
|
||||||
|
|
||||||
$paths = [
|
$paths = [
|
||||||
__DIR__ . '/../../autoload.php',
|
__DIR__ . '/../../autoload.php',
|
||||||
@@ -24,13 +22,14 @@ foreach ($paths as $path) {
|
|||||||
|
|
||||||
is_null($file) && throw new RuntimeException('Unable to locate autoload.php file.');
|
is_null($file) && throw new RuntimeException('Unable to locate autoload.php file.');
|
||||||
|
|
||||||
$handler = new Handler();
|
$processor = new Processor($argv);
|
||||||
$handler::printVersion();
|
|
||||||
$handler::printCopyright();
|
|
||||||
try {
|
try {
|
||||||
$handler->init($argv);
|
$processor->handle();
|
||||||
$handler->start();
|
} catch (InvalidArgumentException $e) {
|
||||||
|
fwrite(STDERR, sprintf('ERROR: %s%s', $e->getMessage(), EOL));
|
||||||
|
print(implode(EOL, Processor::usage()));
|
||||||
|
die(1);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
fwrite(STDERR, sprintf('ERROR: %s%s', $e->getMessage(), EOL));
|
fwrite(STDERR, sprintf('ERROR: %s%s', $e->getMessage(), EOL));
|
||||||
exit(1);
|
die(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"directories": [
|
|
||||||
"tmp"
|
|
||||||
],
|
|
||||||
"output": "tmp/output",
|
|
||||||
"preserveOutput": false,
|
|
||||||
"formats": [
|
|
||||||
"opencollection"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace PmConverter;
|
|
||||||
|
|
||||||
use InvalidArgumentException;
|
|
||||||
use PmConverter\Converters\ConvertFormat;
|
|
||||||
use PmConverter\Enums\ArgumentNames as AN;
|
|
||||||
|
|
||||||
class ArgumentParser
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var array Raw arguments passed from cli ($argv)
|
|
||||||
*/
|
|
||||||
protected readonly array $raw;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array Parsed and ready to use
|
|
||||||
*/
|
|
||||||
protected ?array $parsed = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @param array $argv Raw arguments passed from cli ($argv)
|
|
||||||
*/
|
|
||||||
public function __construct(array $argv)
|
|
||||||
{
|
|
||||||
$this->raw = array_slice($argv, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses raw arguments
|
|
||||||
*
|
|
||||||
* @return array Settings according to settings file format
|
|
||||||
*/
|
|
||||||
public function parse(): array
|
|
||||||
{
|
|
||||||
foreach ($this->raw as $idx => $arg) {
|
|
||||||
switch ($arg) {
|
|
||||||
case '-c':
|
|
||||||
case '--config':
|
|
||||||
if (empty($this->raw[$idx + 1])) {
|
|
||||||
throw new InvalidArgumentException('a configuration file path is expected for -c (--config)');
|
|
||||||
}
|
|
||||||
if (isset($this->parsed[AN::Config])) {
|
|
||||||
printf(
|
|
||||||
"INFO: Config file is already set to '%s' and will be overwritten to '%s'",
|
|
||||||
$this->parsed[AN::Config],
|
|
||||||
$this->raw[$idx + 1],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$this->parsed[AN::Config] = $this->raw[$idx + 1];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '-d':
|
|
||||||
case '--dir':
|
|
||||||
if (empty($this->raw[$idx + 1])) {
|
|
||||||
throw new InvalidArgumentException('a directory path is expected for -d (--dir)');
|
|
||||||
}
|
|
||||||
$this->parsed[AN::Directories][] = $this->raw[$idx + 1];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '-f':
|
|
||||||
case '--file':
|
|
||||||
if (empty($this->raw[$idx + 1])) {
|
|
||||||
throw new InvalidArgumentException('a directory path is expected for -f (--file)');
|
|
||||||
}
|
|
||||||
$this->parsed[AN::Files][] = $this->raw[$idx + 1];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '-e':
|
|
||||||
case '--env':
|
|
||||||
if (empty($this->raw[$idx + 1])) {
|
|
||||||
throw new InvalidArgumentException('an environment file path is expected for -e (--env)');
|
|
||||||
}
|
|
||||||
$this->parsed[AN::Environment][] = $this->raw[$idx + 1];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '-o':
|
|
||||||
case '--output':
|
|
||||||
if (empty($this->raw[$idx + 1])) {
|
|
||||||
throw new InvalidArgumentException('an output path is expected for -o (--output)');
|
|
||||||
}
|
|
||||||
$this->parsed[AN::Output][] = $this->raw[$idx + 1];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '-p':
|
|
||||||
case '--preserve':
|
|
||||||
$this->parsed[AN::PreserveOutput] = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '--http':
|
|
||||||
$this->parsed[AN::Formats][] = ConvertFormat::Http;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '--curl':
|
|
||||||
$this->parsed[AN::Formats][] = ConvertFormat::Curl;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '--wget':
|
|
||||||
$this->parsed[AN::Formats][] = ConvertFormat::Wget;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '--openc':
|
|
||||||
case '--opencollection':
|
|
||||||
$this->parsed[AN::Formats][] = ConvertFormat::OpenCollection;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '--v2.0':
|
|
||||||
$this->parsed[AN::Formats][] = ConvertFormat::Postman20;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '--v2.1':
|
|
||||||
$this->parsed[AN::Formats][] = ConvertFormat::Postman21;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '-a':
|
|
||||||
case '--all':
|
|
||||||
foreach (ConvertFormat::cases() as $format) {
|
|
||||||
$this->parsed[AN::Formats][] = $format;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '--var':
|
|
||||||
$definition = trim($this->raw[$idx + 1]);
|
|
||||||
$name = strtok($definition, '='); // take first part before equal sign as var name
|
|
||||||
$value = strtok(''); // take the rest of argument as var value
|
|
||||||
if (isset($this->parsed[AN::Vars][$name])) {
|
|
||||||
printf(
|
|
||||||
"INFO: Variable '%s' is already set to '%s' and will be overwritten to '%s'",
|
|
||||||
$name,
|
|
||||||
$this->parsed[AN::Vars][$name],
|
|
||||||
$value,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$this->parsed[AN::Vars][$name] = $value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '--dev':
|
|
||||||
$this->parsed[AN::DevMode] = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '-v':
|
|
||||||
case '--verbose':
|
|
||||||
$this->parsed[AN::Verbose] = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '--dump':
|
|
||||||
$this->parsed[AN::Dump] = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '--version':
|
|
||||||
$this->parsed[AN::Version] = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '-h':
|
|
||||||
case '--help':
|
|
||||||
$this->parsed[AN::Help] = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ([AN::Directories, AN::Files, AN::Formats] as $field) {
|
|
||||||
if (!empty($this->parsed[$field])) {
|
|
||||||
$this->parsed[$field] = array_unique($this->parsed[$field] ?? []);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->parsed ?? [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns parsed arguments (if set) or parses raw ones
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function parsed(): array
|
|
||||||
{
|
|
||||||
return $this->parsed ??= $this->parse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,6 @@ namespace PmConverter;
|
|||||||
use Exception;
|
use Exception;
|
||||||
use Generator;
|
use Generator;
|
||||||
use JsonException;
|
use JsonException;
|
||||||
use PmConverter\Enums\CollectionVersion;
|
|
||||||
use Stringable;
|
use Stringable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,23 +111,26 @@ class Collection implements Stringable
|
|||||||
*/
|
*/
|
||||||
public static function detectFileVersion(string $filepath): CollectionVersion
|
public static function detectFileVersion(string $filepath): CollectionVersion
|
||||||
{
|
{
|
||||||
$content = file_get_contents($filepath);
|
$handle = fopen($filepath, 'r');
|
||||||
|
if ($handle === false) {
|
||||||
if ($content === false) {
|
throw new Exception("Cannot open file for reading: $filepath");
|
||||||
throw new Exception("cannot read file: $filepath");
|
|
||||||
}
|
}
|
||||||
|
$content = '';
|
||||||
$json = json_decode($content, true, flags: JSON_THROW_ON_ERROR);
|
// Postman collection files may be HUGE and I don't need to parse
|
||||||
$schema = $json['info']['schema'] ?? '';
|
// them here to find value .info.schema field because normally it
|
||||||
|
// is stored at the beginning of a file, so if it's not then this
|
||||||
if (str_ends_with($schema, 'v2.0.0/collection.json')) {
|
// is a user problem, not mine.
|
||||||
|
while (\mb_strlen($content) <= 2048) {
|
||||||
|
$content .= fgets($handle, 50);
|
||||||
|
if (str_contains($content, 'https://schema.getpostman.com/json/collection')) {
|
||||||
|
if (str_contains($content, '/v2.0.')) {
|
||||||
return CollectionVersion::Version20;
|
return CollectionVersion::Version20;
|
||||||
}
|
}
|
||||||
|
if (str_contains($content, '/v2.1.')) {
|
||||||
if (str_ends_with($schema, 'v2.1.0/collection.json')) {
|
|
||||||
return CollectionVersion::Version21;
|
return CollectionVersion::Version21;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return CollectionVersion::Unknown;
|
return CollectionVersion::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace PmConverter\Enums;
|
namespace PmConverter;
|
||||||
|
|
||||||
enum CollectionVersion: string
|
enum CollectionVersion: string
|
||||||
{
|
{
|
||||||
@@ -62,8 +62,7 @@ abstract class AbstractConverter
|
|||||||
$this->setCollectionVars();
|
$this->setCollectionVars();
|
||||||
foreach ($collection->iterate() as $path => $item) {
|
foreach ($collection->iterate() as $path => $item) {
|
||||||
// $this->requests[$path][] = $this->makeRequest($item);
|
// $this->requests[$path][] = $this->makeRequest($item);
|
||||||
$request = $this->makeRequest($item);
|
$this->writeRequest($this->makeRequest($item), $path);
|
||||||
$this->writeRequest($request, $path);
|
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -104,7 +103,6 @@ abstract class AbstractConverter
|
|||||||
foreach ($this->collection?->variable ?? [] as $var) {
|
foreach ($this->collection?->variable ?? [] as $var) {
|
||||||
Environment::instance()->setCustomVar($var->key, $var->value);
|
Environment::instance()->setCustomVar($var->key, $var->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace PmConverter\Converters\Abstract;
|
namespace PmConverter\Converters\Abstract;
|
||||||
|
|
||||||
|
use PmConverter\CollectionVersion;
|
||||||
use PmConverter\Converters\RequestContract;
|
use PmConverter\Converters\RequestContract;
|
||||||
use PmConverter\Enums\CollectionVersion;
|
|
||||||
use PmConverter\Enums\HttpVersion;
|
|
||||||
use PmConverter\Exceptions\EmptyHttpVerbException;
|
use PmConverter\Exceptions\EmptyHttpVerbException;
|
||||||
use PmConverter\Exceptions\InvalidHttpVersionException;
|
use PmConverter\Exceptions\InvalidHttpVersionException;
|
||||||
|
use PmConverter\HttpVersion;
|
||||||
use Stringable;
|
use Stringable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ namespace PmConverter\Converters;
|
|||||||
|
|
||||||
use PmConverter\Converters\Curl\CurlConverter;
|
use PmConverter\Converters\Curl\CurlConverter;
|
||||||
use PmConverter\Converters\Http\HttpConverter;
|
use PmConverter\Converters\Http\HttpConverter;
|
||||||
use PmConverter\Converters\OpenCollection\OpenCollectionConverter;
|
|
||||||
use PmConverter\Converters\Postman20\Postman20Converter;
|
use PmConverter\Converters\Postman20\Postman20Converter;
|
||||||
use PmConverter\Converters\Postman21\Postman21Converter;
|
use PmConverter\Converters\Postman21\Postman21Converter;
|
||||||
use PmConverter\Converters\Wget\WgetConverter;
|
use PmConverter\Converters\Wget\WgetConverter;
|
||||||
@@ -17,7 +16,6 @@ enum ConvertFormat: string
|
|||||||
case Http = HttpConverter::class;
|
case Http = HttpConverter::class;
|
||||||
case Curl = CurlConverter::class;
|
case Curl = CurlConverter::class;
|
||||||
case Wget = WgetConverter::class;
|
case Wget = WgetConverter::class;
|
||||||
case OpenCollection = OpenCollectionConverter::class;
|
|
||||||
case Postman20 = Postman20Converter::class;
|
case Postman20 = Postman20Converter::class;
|
||||||
case Postman21 = Postman21Converter::class;
|
case Postman21 = Postman21Converter::class;
|
||||||
|
|
||||||
@@ -27,7 +25,6 @@ enum ConvertFormat: string
|
|||||||
'http' => ConvertFormat::Http,
|
'http' => ConvertFormat::Http,
|
||||||
'curl' => ConvertFormat::Curl,
|
'curl' => ConvertFormat::Curl,
|
||||||
'wget' => ConvertFormat::Wget,
|
'wget' => ConvertFormat::Wget,
|
||||||
'opencollection' => ConvertFormat::OpenCollection,
|
|
||||||
'v2.0' => ConvertFormat::Postman20,
|
'v2.0' => ConvertFormat::Postman20,
|
||||||
'v2.1' => ConvertFormat::Postman21,
|
'v2.1' => ConvertFormat::Postman21,
|
||||||
};
|
};
|
||||||
@@ -39,7 +36,6 @@ enum ConvertFormat: string
|
|||||||
ConvertFormat::Http => 'http',
|
ConvertFormat::Http => 'http',
|
||||||
ConvertFormat::Curl => 'curl',
|
ConvertFormat::Curl => 'curl',
|
||||||
ConvertFormat::Wget => 'wget',
|
ConvertFormat::Wget => 'wget',
|
||||||
ConvertFormat::OpenCollection => 'opencollection',
|
|
||||||
ConvertFormat::Postman20 => 'v2.0',
|
ConvertFormat::Postman20 => 'v2.0',
|
||||||
ConvertFormat::Postman21 => 'v2.1',
|
ConvertFormat::Postman21 => 'v2.1',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace PmConverter\Converters\OpenCollection;
|
|
||||||
|
|
||||||
use PmConverter\Collection;
|
|
||||||
use PmConverter\Converters\Abstract\AbstractConverter;
|
|
||||||
use PmConverter\FileSystem;
|
|
||||||
|
|
||||||
class OpenCollectionConverter extends AbstractConverter
|
|
||||||
{
|
|
||||||
protected const FILE_EXT = 'yml';
|
|
||||||
|
|
||||||
protected const OUTPUT_DIR = 'opencollection';
|
|
||||||
|
|
||||||
protected const REQUEST_CLASS = OpenCollectionRequest::class;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function convert(Collection $collection): static
|
|
||||||
{
|
|
||||||
$this->collection = $collection;
|
|
||||||
$this->outputPath = FileSystem::makeDir($this->outputPath);
|
|
||||||
$this->setCollectionVars();
|
|
||||||
|
|
||||||
// Write main collection file
|
|
||||||
$this->writeCollectionFile($collection);
|
|
||||||
|
|
||||||
foreach ($collection->iterate() as $path => $item) {
|
|
||||||
$request = $this->makeRequest($item);
|
|
||||||
$this->writeRequest($request, $path);
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes main OpenCollection collection file
|
|
||||||
*
|
|
||||||
* @param Collection $collection
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function writeCollectionFile(Collection $collection): void
|
|
||||||
{
|
|
||||||
$filepath = sprintf('%s%scollection.%s', $this->outputPath, DS, static::FILE_EXT);
|
|
||||||
$content = $this->generateCollectionContent($collection);
|
|
||||||
file_put_contents($filepath, $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates collection YAML content
|
|
||||||
*
|
|
||||||
* @param Collection $collection
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function generateCollectionContent(Collection $collection): string
|
|
||||||
{
|
|
||||||
$output = [
|
|
||||||
'name: ' . ($collection->name ?? 'Untitled Collection'),
|
|
||||||
'type: collection',
|
|
||||||
'',
|
|
||||||
];
|
|
||||||
|
|
||||||
if (!empty($collection->info?->description)) {
|
|
||||||
$output[] = 'description: |';
|
|
||||||
$output[] = ' ' . str_replace("\n", "\n ", $collection->info->description);
|
|
||||||
$output[] = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
$output[] = 'version: 1';
|
|
||||||
$output[] = '';
|
|
||||||
$output[] = 'baseVars: []';
|
|
||||||
$output[] = '';
|
|
||||||
$output[] = 'environments: []';
|
|
||||||
$output[] = '';
|
|
||||||
$output[] = 'requests:';
|
|
||||||
|
|
||||||
foreach ($collection->iterate() as $path => $item) {
|
|
||||||
$requestRef = str_replace(DS, '/', $path . '/' . $item->name);
|
|
||||||
$output[] = ' - $ref: ./' . $requestRef . '.yml';
|
|
||||||
}
|
|
||||||
|
|
||||||
return implode("\n", $output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace PmConverter\Converters\OpenCollection;
|
|
||||||
|
|
||||||
use PmConverter\Converters\Abstract\AbstractRequest;
|
|
||||||
use PmConverter\Exceptions\EmptyHttpVerbException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class to determine file content with OpenCollection format
|
|
||||||
*/
|
|
||||||
class OpenCollectionRequest extends AbstractRequest
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
protected function prepareDescription(): array
|
|
||||||
{
|
|
||||||
return empty($this->description)
|
|
||||||
? []
|
|
||||||
: ['description: |', ' ' . str_replace("\n", "\n ", $this->description), ''];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
* @throws EmptyHttpVerbException
|
|
||||||
*/
|
|
||||||
protected function prepareHeaders(): array
|
|
||||||
{
|
|
||||||
$output = ['headers:'];
|
|
||||||
foreach ($this->headers as $name => $data) {
|
|
||||||
$prefix = $data['disabled'] ? '# ' : '';
|
|
||||||
$output[] = sprintf('%s %s: %s', $prefix, $name, $data['value']);
|
|
||||||
}
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
protected function prepareBody(): array
|
|
||||||
{
|
|
||||||
$output = ['body:'];
|
|
||||||
|
|
||||||
switch ($this->getBodymode()) {
|
|
||||||
case 'formdata':
|
|
||||||
$output[] = ' type: formdata';
|
|
||||||
$output[] = ' files:';
|
|
||||||
foreach ($this->body as $key => $data) {
|
|
||||||
$disabled = $data['disabled'] ?? false;
|
|
||||||
$prefix = $disabled ? '# ' : ' ';
|
|
||||||
if ($data['type'] === 'file') {
|
|
||||||
$output[] = sprintf('%s- name: %s', $prefix, $key);
|
|
||||||
$output[] = sprintf('%s type: file', $prefix);
|
|
||||||
$output[] = sprintf('%s value: %s', $prefix, $data['value']);
|
|
||||||
} else {
|
|
||||||
$output[] = sprintf('%s- name: %s', $prefix, $key);
|
|
||||||
$output[] = sprintf('%s type: text', $prefix);
|
|
||||||
$output[] = sprintf('%s value: %s', $prefix, $data['value']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$output[] = ' type: raw';
|
|
||||||
if (!empty($this->body)) {
|
|
||||||
$output[] = ' content: |';
|
|
||||||
$bodyContent = is_string($this->body) ? $this->body : json_encode($this->body, JSON_PRETTY_PRINT);
|
|
||||||
foreach (explode("\n", $bodyContent) as $line) {
|
|
||||||
$output[] = ' ' . $line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
* @throws EmptyHttpVerbException
|
|
||||||
*/
|
|
||||||
public function __toString(): string
|
|
||||||
{
|
|
||||||
$output = [
|
|
||||||
'name: ' . $this->getName(),
|
|
||||||
'type: request',
|
|
||||||
'',
|
|
||||||
];
|
|
||||||
|
|
||||||
$output[] = 'method: ' . strtolower($this->getVerb());
|
|
||||||
$output[] = '';
|
|
||||||
|
|
||||||
$url = $this->getRawUrl();
|
|
||||||
$output[] = 'url: ' . $url;
|
|
||||||
$output[] = '';
|
|
||||||
|
|
||||||
$output = array_merge($output, $this->prepareDescription());
|
|
||||||
|
|
||||||
if (!empty($this->headers)) {
|
|
||||||
$output = array_merge($output, $this->prepareHeaders());
|
|
||||||
$output[] = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->verb !== 'GET' && !empty($this->body)) {
|
|
||||||
$output = array_merge($output, $this->prepareBody());
|
|
||||||
$output[] = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return implode("\n", $output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,8 +5,8 @@ declare(strict_types=1);
|
|||||||
namespace PmConverter\Converters\Postman20;
|
namespace PmConverter\Converters\Postman20;
|
||||||
|
|
||||||
use PmConverter\Collection;
|
use PmConverter\Collection;
|
||||||
|
use PmConverter\CollectionVersion;
|
||||||
use PmConverter\Converters\Abstract\AbstractConverter;
|
use PmConverter\Converters\Abstract\AbstractConverter;
|
||||||
use PmConverter\Enums\CollectionVersion;
|
|
||||||
use PmConverter\Exceptions\CannotCreateDirectoryException;
|
use PmConverter\Exceptions\CannotCreateDirectoryException;
|
||||||
use PmConverter\Exceptions\DirectoryIsNotWriteableException;
|
use PmConverter\Exceptions\DirectoryIsNotWriteableException;
|
||||||
use PmConverter\FileSystem;
|
use PmConverter\FileSystem;
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ declare(strict_types=1);
|
|||||||
namespace PmConverter\Converters\Postman21;
|
namespace PmConverter\Converters\Postman21;
|
||||||
|
|
||||||
use PmConverter\Collection;
|
use PmConverter\Collection;
|
||||||
|
use PmConverter\CollectionVersion;
|
||||||
use PmConverter\Converters\Abstract\AbstractConverter;
|
use PmConverter\Converters\Abstract\AbstractConverter;
|
||||||
use PmConverter\Enums\CollectionVersion;
|
|
||||||
use PmConverter\Exceptions\CannotCreateDirectoryException;
|
use PmConverter\Exceptions\CannotCreateDirectoryException;
|
||||||
use PmConverter\Exceptions\DirectoryIsNotWriteableException;
|
use PmConverter\Exceptions\DirectoryIsNotWriteableException;
|
||||||
use PmConverter\FileSystem;
|
use PmConverter\FileSystem;
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace PmConverter\Enums;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Argument names
|
|
||||||
*/
|
|
||||||
class ArgumentNames
|
|
||||||
{
|
|
||||||
public const Config = 'config';
|
|
||||||
public const Directories = 'directories';
|
|
||||||
public const Files = 'files';
|
|
||||||
public const Environment = 'environment';
|
|
||||||
public const Output = 'output';
|
|
||||||
public const PreserveOutput = 'preserveOutput';
|
|
||||||
public const Formats = 'formats';
|
|
||||||
public const Vars = 'vars';
|
|
||||||
public const DevMode = 'devMode';
|
|
||||||
public const Verbose = 'verbose';
|
|
||||||
public const Dump = 'dump';
|
|
||||||
public const Version = 'version';
|
|
||||||
public const Help = 'help';
|
|
||||||
}
|
|
||||||
@@ -38,11 +38,11 @@ class Environment implements ArrayAccess
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|null $filepath
|
* @param string $filepath
|
||||||
* @return $this
|
* @return $this
|
||||||
* @throws JsonException
|
* @throws JsonException
|
||||||
*/
|
*/
|
||||||
public function readFromFile(?string $filepath): static
|
public function readFromFile(string $filepath): static
|
||||||
{
|
{
|
||||||
if (empty($filepath)) {
|
if (empty($filepath)) {
|
||||||
return $this;
|
return $this;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ namespace PmConverter;
|
|||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use JsonException;
|
use JsonException;
|
||||||
use PmConverter\Enums\CollectionVersion;
|
|
||||||
use PmConverter\Exceptions\CannotCreateDirectoryException;
|
use PmConverter\Exceptions\CannotCreateDirectoryException;
|
||||||
use PmConverter\Exceptions\DirectoryIsNotReadableException;
|
use PmConverter\Exceptions\DirectoryIsNotReadableException;
|
||||||
use PmConverter\Exceptions\DirectoryIsNotWriteableException;
|
use PmConverter\Exceptions\DirectoryIsNotWriteableException;
|
||||||
@@ -25,16 +24,7 @@ class FileSystem
|
|||||||
*/
|
*/
|
||||||
public static function normalizePath(string $path): string
|
public static function normalizePath(string $path): string
|
||||||
{
|
{
|
||||||
$path = trim($path);
|
$path = str_replace('~/', "{$_SERVER['HOME']}/", $path);
|
||||||
|
|
||||||
if (str_starts_with($path, '~' . DS)) {
|
|
||||||
$path = str_replace('~' . DS, $_SERVER['HOME'] . DS, $path);
|
|
||||||
} elseif (str_starts_with($path, '.' . DS)) {
|
|
||||||
$path = str_replace('.' . DS, $_SERVER['PWD'] . DS, $path);
|
|
||||||
} elseif (!str_starts_with($path, DS)) {
|
|
||||||
$path = $_SERVER['PWD'] . DS . $path;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rtrim($path, DS);
|
return rtrim($path, DS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,11 +116,9 @@ class FileSystem
|
|||||||
*/
|
*/
|
||||||
public static function isCollectionFile(string $path): bool
|
public static function isCollectionFile(string $path): bool
|
||||||
{
|
{
|
||||||
$path = static::normalizePath($path);
|
return (!empty($path = static::normalizePath($path)))
|
||||||
return !empty($path)
|
|
||||||
&& str_ends_with($path, '.postman_collection.json')
|
&& str_ends_with($path, '.postman_collection.json')
|
||||||
&& file_exists($path)
|
&& file_exists($path)
|
||||||
&& is_file($path)
|
|
||||||
&& is_readable($path)
|
&& is_readable($path)
|
||||||
&& Collection::detectFileVersion($path) !== CollectionVersion::Unknown;
|
&& Collection::detectFileVersion($path) !== CollectionVersion::Unknown;
|
||||||
}
|
}
|
||||||
|
|||||||
239
src/Handler.php
239
src/Handler.php
@@ -1,239 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace PmConverter;
|
|
||||||
|
|
||||||
use JsonException;
|
|
||||||
use PmConverter\Enums\ArgumentNames as AN;
|
|
||||||
|
|
||||||
class Handler
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var array Ready to use arguments
|
|
||||||
*/
|
|
||||||
protected array $arguments;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Settings Settings read from file and merged with provided in cli
|
|
||||||
*/
|
|
||||||
protected Settings $settings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Environment Environment laoded from file with custom vars provided
|
|
||||||
*/
|
|
||||||
protected Environment $env;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Processor Object that do convertions according to settings
|
|
||||||
*/
|
|
||||||
protected Processor $processor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes main flow
|
|
||||||
*
|
|
||||||
* @param array $argv Raw arguments passed from cli
|
|
||||||
* @return void
|
|
||||||
* @throws JsonException
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function init(array $argv): void
|
|
||||||
{
|
|
||||||
$this->arguments = (new ArgumentParser($argv))->parsed();
|
|
||||||
|
|
||||||
if (!empty($this->arguments[AN::Help])) {
|
|
||||||
self::printHelp();
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($this->arguments[AN::Version])) {
|
|
||||||
self::printVersion();
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->settings = new Settings();
|
|
||||||
$this->settings->loadFromFile($this->arguments[AN::Config] ?? null);
|
|
||||||
$this->settings->override($this->arguments);
|
|
||||||
|
|
||||||
if (empty($this->settings->collectionPaths())) {
|
|
||||||
throw new \Exception('at least 1 collection file must be defined');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($arguments[AN::Dump])) {
|
|
||||||
$this->handleSettingsDump();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->env = Environment::instance()
|
|
||||||
->readFromFile($this->settings->envFilepath())
|
|
||||||
->setCustomVars($this->settings->vars());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts convertions
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
* @throws Exceptions\CannotCreateDirectoryException
|
|
||||||
* @throws Exceptions\DirectoryIsNotReadableException
|
|
||||||
* @throws Exceptions\DirectoryIsNotWriteableException
|
|
||||||
* @throws Exceptions\DirectoryNotExistsException
|
|
||||||
* @throws Exceptions\IncorrectSettingsFileException
|
|
||||||
* @throws JsonException
|
|
||||||
*/
|
|
||||||
public function start(): void
|
|
||||||
{
|
|
||||||
$this->processor = new Processor($this->settings, $this->env);
|
|
||||||
$this->processor->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles settings file saving when requested by --dump
|
|
||||||
*
|
|
||||||
* @return never
|
|
||||||
*/
|
|
||||||
protected function handleSettingsDump(): never
|
|
||||||
{
|
|
||||||
$answer = 'o';
|
|
||||||
|
|
||||||
if ($this->settings->fileExists()) {
|
|
||||||
echo 'Settings file already exists: ' . $this->settings->filePath() . EOL;
|
|
||||||
echo 'Do you want to (o)verwrite it, (b)ackup it and create new one or (c)ancel (default)?' . EOL;
|
|
||||||
$answer = strtolower(trim(readline('> ')));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!in_array($answer, ['o', 'b'])) {
|
|
||||||
die('Current settings file has not been changed' . EOL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($answer === 'b') {
|
|
||||||
$filepath = $this->settings->backup();
|
|
||||||
printf("Settings file has been backed up to file:%s\t%s%s", EOL, $filepath, EOL);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->settings->dump();
|
|
||||||
printf("Arguments has been converted into settings file:%s\t%s%s", EOL, $this->settings->filePath(), EOL);
|
|
||||||
die('Review and edit it if needed.' . EOL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns usage help strings
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected static function help(): array
|
|
||||||
{
|
|
||||||
return array_merge(self::version(), [
|
|
||||||
'Usage:',
|
|
||||||
"\t./pm-convert -f|-d PATH -o OUTPUT_PATH [ARGUMENTS] [FORMATS]",
|
|
||||||
"\tphp pm-convert -f|-d PATH -o OUTPUT_PATH [ARGUMENTS] [FORMATS]",
|
|
||||||
"\tcomposer pm-convert -f|-d PATH -o OUTPUT_PATH [ARGUMENTS] [FORMATS]",
|
|
||||||
"\t./vendor/bin/pm-convert -f|-d PATH -o OUTPUT_PATH [ARGUMENTS] [FORMATS]",
|
|
||||||
'',
|
|
||||||
'Possible ARGUMENTS:',
|
|
||||||
"\t-f, --file - a PATH to a single collection file to convert from",
|
|
||||||
"\t-d, --dir - a PATH to a directory with collections to convert from",
|
|
||||||
"\t-o, --output - a directory OUTPUT_PATH to put results in",
|
|
||||||
"\t-e, --env - use environment file with variables to replace in requests",
|
|
||||||
"\t--var \"NAME=VALUE\" - force replace specified env variable called NAME with custom VALUE",
|
|
||||||
"\t-p, --preserve - do not delete OUTPUT_PATH (if exists)",
|
|
||||||
"\t --dump - convert provided arguments into settings file in `pwd",
|
|
||||||
"\t-h, --help - show this help message and exit",
|
|
||||||
"\t-v, --version - show version info and exit",
|
|
||||||
'',
|
|
||||||
'If no ARGUMENTS passed then --help implied.',
|
|
||||||
'If both -f and -d are specified then only unique set of files from both arguments will be converted.',
|
|
||||||
'-f or -d are required to be specified at least once, but each may be specified multiple times.',
|
|
||||||
'PATH must be a valid path to readable json-file or directory.',
|
|
||||||
'OUTPUT_PATH must be a valid path to writeable directory.',
|
|
||||||
'If -o or -e was specified several times then only last one will be used.',
|
|
||||||
'',
|
|
||||||
'Possible FORMATS:',
|
|
||||||
"\t--http - generate raw *.http files (default)",
|
|
||||||
"\t--curl - generate shell scripts with curl command",
|
|
||||||
"\t--wget - generate shell scripts with wget command",
|
|
||||||
"\t--opencollection - generate OpenCollection YAML files",
|
|
||||||
"\t--v2.0 - convert from Postman Collection Schema v2.1 into v2.0",
|
|
||||||
"\t--v2.1 - convert from Postman Collection Schema v2.0 into v2.1",
|
|
||||||
"\t-a, --all - convert to all of formats listed above",
|
|
||||||
'',
|
|
||||||
'If no FORMATS specified then --http implied.',
|
|
||||||
'Any of FORMATS can be specified at the same time or replaced by --all.',
|
|
||||||
'',
|
|
||||||
'Example:',
|
|
||||||
" ./pm-convert \ ",
|
|
||||||
" -f ~/dir1/first.postman_collection.json \ ",
|
|
||||||
" --directory ~/team \ ",
|
|
||||||
" --file ~/dir2/second.postman_collection.json \ ",
|
|
||||||
" --env ~/localhost.postman_environment.json \ ",
|
|
||||||
" -d ~/personal \ ",
|
|
||||||
" --var \"myvar=some value\" \ ",
|
|
||||||
" -o ~/postman_export \ ",
|
|
||||||
" --all",
|
|
||||||
"",
|
|
||||||
], self::copyright());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints usage help message in stdout
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function printHelp(): void
|
|
||||||
{
|
|
||||||
self::printArray(self::help());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns version strings
|
|
||||||
*
|
|
||||||
* @return string[]
|
|
||||||
*/
|
|
||||||
protected static function version(): array
|
|
||||||
{
|
|
||||||
return ['Postman collection converter v' . PM_VERSION, ''];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints version message in stdout
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function printVersion(): void
|
|
||||||
{
|
|
||||||
self::printArray(self::version());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns copyright strings
|
|
||||||
*
|
|
||||||
* @return string[]
|
|
||||||
*/
|
|
||||||
protected static function copyright(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'Anthony Axenov (c) 2023 - ' . (int)date('Y') . ', MIT license',
|
|
||||||
'https://git.axenov.dev/anthony/pm-convert',
|
|
||||||
'',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints copyright message in stdout
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function printCopyright(): void
|
|
||||||
{
|
|
||||||
self::printArray(self::copyright());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints an arrays of string to stdout
|
|
||||||
*
|
|
||||||
* @param ...$strings
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected static function printArray(...$strings): void
|
|
||||||
{
|
|
||||||
fwrite(STDOUT, implode("\n", array_merge(...$strings)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace PmConverter\Enums;
|
namespace PmConverter;
|
||||||
|
|
||||||
enum HttpVersion: string
|
enum HttpVersion: string
|
||||||
{
|
{
|
||||||
@@ -6,9 +6,12 @@ namespace PmConverter;
|
|||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Generator;
|
use Generator;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use JetBrains\PhpStorm\NoReturn;
|
||||||
use JsonException;
|
use JsonException;
|
||||||
use PmConverter\Converters\Abstract\AbstractConverter;
|
use PmConverter\Converters\Abstract\AbstractConverter;
|
||||||
use PmConverter\Converters\ConverterContract;
|
use PmConverter\Converters\ConverterContract;
|
||||||
|
use PmConverter\Converters\ConvertFormat;
|
||||||
use PmConverter\Exceptions\CannotCreateDirectoryException;
|
use PmConverter\Exceptions\CannotCreateDirectoryException;
|
||||||
use PmConverter\Exceptions\DirectoryIsNotReadableException;
|
use PmConverter\Exceptions\DirectoryIsNotReadableException;
|
||||||
use PmConverter\Exceptions\DirectoryIsNotWriteableException;
|
use PmConverter\Exceptions\DirectoryIsNotWriteableException;
|
||||||
@@ -16,10 +19,15 @@ use PmConverter\Exceptions\DirectoryNotExistsException;
|
|||||||
use PmConverter\Exceptions\IncorrectSettingsFileException;
|
use PmConverter\Exceptions\IncorrectSettingsFileException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processor class
|
* Main class
|
||||||
*/
|
*/
|
||||||
class Processor
|
class Processor
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Converter version
|
||||||
|
*/
|
||||||
|
public const VERSION = '1.6.1';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int Initial timestamp
|
* @var int Initial timestamp
|
||||||
*/
|
*/
|
||||||
@@ -30,23 +38,150 @@ class Processor
|
|||||||
*/
|
*/
|
||||||
protected readonly int $initRam;
|
protected readonly int $initRam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Settings Settings (lol)
|
||||||
|
*/
|
||||||
|
protected Settings $settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var ConverterContract[] Converters will be used for conversion according to chosen formats
|
* @var ConverterContract[] Converters will be used for conversion according to chosen formats
|
||||||
*/
|
*/
|
||||||
protected array $converters = [];
|
protected array $converters = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool Do we need to save settings file and exit or not?
|
||||||
|
*/
|
||||||
|
protected bool $needDumpSettings = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Environment
|
||||||
|
*/
|
||||||
|
public Environment $env;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param Settings $settings Settings (lol)
|
* @param array $argv Arguments came from cli
|
||||||
* @param Environment $env Environment
|
* @throws IncorrectSettingsFileException
|
||||||
|
* @throws JsonException
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(protected readonly array $argv)
|
||||||
protected Settings $settings,
|
{
|
||||||
protected Environment $env,
|
|
||||||
) {
|
|
||||||
$this->initTime = hrtime(true);
|
$this->initTime = hrtime(true);
|
||||||
$this->initRam = memory_get_usage(true);
|
$this->initRam = memory_get_usage(true);
|
||||||
|
$this->settings = Settings::init();
|
||||||
|
$this->env = Environment::instance()
|
||||||
|
->readFromFile($this->settings->envFilepath())
|
||||||
|
->setCustomVars($this->settings->vars());
|
||||||
|
$this->parseArgs();
|
||||||
|
$this->needDumpSettings && $this->dumpSettingsFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses an array of arguments came from cli
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws JsonException
|
||||||
|
*/
|
||||||
|
protected function parseArgs(): void
|
||||||
|
{
|
||||||
|
$arguments = array_slice($this->argv, 1);
|
||||||
|
$needHelp = count($arguments) === 0 && !$this->settings::fileExists();
|
||||||
|
foreach ($arguments as $idx => $arg) {
|
||||||
|
switch ($arg) {
|
||||||
|
case '-f':
|
||||||
|
case '--file':
|
||||||
|
$this->settings->addFilePath($this->argv[$idx + 1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-o':
|
||||||
|
case '--output':
|
||||||
|
if (empty($this->argv[$idx + 1])) {
|
||||||
|
throw new InvalidArgumentException('-o is required');
|
||||||
|
}
|
||||||
|
$this->settings->setOutputPath($this->argv[$idx + 1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-d':
|
||||||
|
case '--dir':
|
||||||
|
if (empty($this->argv[$idx + 1])) {
|
||||||
|
throw new InvalidArgumentException('a directory path is expected for -d (--dir)');
|
||||||
|
}
|
||||||
|
$this->settings->addDirPath($this->argv[$idx + 1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-e':
|
||||||
|
case '--env':
|
||||||
|
$this->settings->setEnvFilepath($this->argv[$idx + 1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-p':
|
||||||
|
case '--preserve':
|
||||||
|
$this->settings->setPreserveOutput(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '--http':
|
||||||
|
$this->settings->addFormat(ConvertFormat::Http);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '--curl':
|
||||||
|
$this->settings->addFormat(ConvertFormat::Curl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '--wget':
|
||||||
|
$this->settings->addFormat(ConvertFormat::Wget);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '--v2.0':
|
||||||
|
$this->settings->addFormat(ConvertFormat::Postman20);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '--v2.1':
|
||||||
|
$this->settings->addFormat(ConvertFormat::Postman21);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-a':
|
||||||
|
case '--all':
|
||||||
|
foreach (ConvertFormat::cases() as $format) {
|
||||||
|
$this->settings->addFormat($format);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '--var':
|
||||||
|
//TODO split by first equal sign
|
||||||
|
$this->env->setCustomVar(...explode('=', trim($this->argv[$idx + 1])));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '--dev':
|
||||||
|
$this->settings->setDevMode(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '--dump':
|
||||||
|
$this->needDumpSettings = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-v':
|
||||||
|
case '--version':
|
||||||
|
die(implode(EOL, $this->version()) . EOL);
|
||||||
|
|
||||||
|
case '-h':
|
||||||
|
case '--help':
|
||||||
|
$needHelp = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($needHelp) {
|
||||||
|
die(implode(EOL, $this->usage()) . EOL);
|
||||||
|
}
|
||||||
|
if (empty($this->settings->collectionPaths())) {
|
||||||
|
throw new InvalidArgumentException('there are no collections to convert');
|
||||||
|
}
|
||||||
|
if (empty($this->settings->outputPath())) {
|
||||||
|
throw new InvalidArgumentException('-o is required');
|
||||||
|
}
|
||||||
|
if (empty($this->settings->formats())) {
|
||||||
|
$this->settings->addFormat(ConvertFormat::Http);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,14 +193,41 @@ class Processor
|
|||||||
* @throws DirectoryIsNotWriteableException
|
* @throws DirectoryIsNotWriteableException
|
||||||
* @throws DirectoryNotExistsException
|
* @throws DirectoryNotExistsException
|
||||||
* @throws JsonException
|
* @throws JsonException
|
||||||
|
* @throws IncorrectSettingsFileException
|
||||||
*/
|
*/
|
||||||
public function start(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
$this->prepareOutputDirectory();
|
$this->prepareOutputDirectory();
|
||||||
$this->initConverters();
|
$this->initConverters();
|
||||||
$this->convert();
|
$this->convert();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes all settings into file if --dump provided
|
||||||
|
*
|
||||||
|
* @return never
|
||||||
|
*/
|
||||||
|
#[NoReturn]
|
||||||
|
protected function dumpSettingsFile(): never
|
||||||
|
{
|
||||||
|
$answer = 'o';
|
||||||
|
if ($this->settings::fileExists()) {
|
||||||
|
echo 'Settings file already exists: ' . $this->settings::filepath() . EOL;
|
||||||
|
echo 'Do you want to (o)verwrite it, (b)ackup it and create new one or (c)ancel (default)?' . EOL;
|
||||||
|
$answer = strtolower(trim(readline('> ')));
|
||||||
|
}
|
||||||
|
if (!in_array($answer, ['o', 'b'])) {
|
||||||
|
die('Current settings file has not been changed' . EOL);
|
||||||
|
}
|
||||||
|
if ($answer === 'b') {
|
||||||
|
$filepath = $this->settings->backup();
|
||||||
|
printf("Settings file has been backed up to file:%s\t%s%s", EOL, $filepath, EOL);
|
||||||
|
}
|
||||||
|
$this->settings->dump($this->env->customVars());
|
||||||
|
printf("Arguments has been converted into settings file:%s\t%s%s", EOL, $this->settings::filepath(), EOL);
|
||||||
|
die('Review and edit it if needed.' . EOL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes output directory
|
* Initializes output directory
|
||||||
*
|
*
|
||||||
@@ -102,7 +264,7 @@ class Processor
|
|||||||
* @return Generator<Collection>
|
* @return Generator<Collection>
|
||||||
* @throws JsonException
|
* @throws JsonException
|
||||||
*/
|
*/
|
||||||
protected function nextCollection(): Generator
|
protected function newCollection(): Generator
|
||||||
{
|
{
|
||||||
foreach ($this->settings->collectionPaths() as $collectionPath) {
|
foreach ($this->settings->collectionPaths() as $collectionPath) {
|
||||||
yield Collection::fromFile($collectionPath);
|
yield Collection::fromFile($collectionPath);
|
||||||
@@ -118,7 +280,9 @@ class Processor
|
|||||||
{
|
{
|
||||||
$count = count($this->settings->collectionPaths());
|
$count = count($this->settings->collectionPaths());
|
||||||
$current = $success = 0;
|
$current = $success = 0;
|
||||||
foreach ($this->nextCollection() as $collection) {
|
$collection = null;
|
||||||
|
print(implode(EOL, array_merge($this->version(), $this->copyright())) . EOL . EOL);
|
||||||
|
foreach ($this->newCollection() as $collection) {
|
||||||
++$current;
|
++$current;
|
||||||
printf("Converting '%s' (%d/%d):%s", $collection->name(), $current, $count, EOL);
|
printf("Converting '%s' (%d/%d):%s", $collection->name(), $current, $count, EOL);
|
||||||
foreach ($this->converters as $type => $converter) {
|
foreach ($this->converters as $type => $converter) {
|
||||||
@@ -133,7 +297,7 @@ class Processor
|
|||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
printf(' ERROR %s: %s%s', $e->getCode(), $e->getMessage(), EOL);
|
printf(' ERROR %s: %s%s', $e->getCode(), $e->getMessage(), EOL);
|
||||||
if ($this->settings->isDevMode()) {
|
if ($this->settings->isDevMode()) {
|
||||||
array_map(static fn (string $line) => printf(' %s%s', $line, EOL), $e->getTrace());
|
array_map(static fn ($line) => printf(' %s%s', $line, EOL), $e->getTrace());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,4 +326,79 @@ class Processor
|
|||||||
$ram = (memory_get_peak_usage(true) - $this->initRam) / 1024 / 1024;
|
$ram = (memory_get_peak_usage(true) - $this->initRam) / 1024 / 1024;
|
||||||
printf("Converted %d/%d in %.2f $timeFmt using up to %.2f MiB RAM%s", $success, $count, $time, $ram, EOL);
|
printf("Converted %d/%d in %.2f $timeFmt using up to %.2f MiB RAM%s", $success, $count, $time, $ram, EOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public static function version(): array
|
||||||
|
{
|
||||||
|
return ['Postman collection converter v' . self::VERSION];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public static function copyright(): array
|
||||||
|
{
|
||||||
|
$years = ($year = (int)date('Y')) > 2023 ? "2023 - $year" : $year;
|
||||||
|
return [
|
||||||
|
"Anthony Axenov (c) $years, MIT license",
|
||||||
|
'https://git.axenov.dev/anthony/pm-convert'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function usage(): array
|
||||||
|
{
|
||||||
|
return array_merge(static::version(), [
|
||||||
|
'Usage:',
|
||||||
|
"\t./pm-convert -f|-d PATH -o OUTPUT_PATH [ARGUMENTS] [FORMATS]",
|
||||||
|
"\tphp pm-convert -f|-d PATH -o OUTPUT_PATH [ARGUMENTS] [FORMATS]",
|
||||||
|
"\tcomposer pm-convert -f|-d PATH -o OUTPUT_PATH [ARGUMENTS] [FORMATS]",
|
||||||
|
"\t./vendor/bin/pm-convert -f|-d PATH -o OUTPUT_PATH [ARGUMENTS] [FORMATS]",
|
||||||
|
'',
|
||||||
|
'Possible ARGUMENTS:',
|
||||||
|
"\t-f, --file - a PATH to a single collection file to convert from",
|
||||||
|
"\t-d, --dir - a PATH to a directory with collections to convert from",
|
||||||
|
"\t-o, --output - a directory OUTPUT_PATH to put results in",
|
||||||
|
"\t-e, --env - use environment file with variables to replace in requests",
|
||||||
|
"\t--var \"NAME=VALUE\" - force replace specified env variable called NAME with custom VALUE",
|
||||||
|
"\t-p, --preserve - do not delete OUTPUT_PATH (if exists)",
|
||||||
|
"\t --dump - convert provided arguments into settings file in `pwd",
|
||||||
|
"\t-h, --help - show this help message and exit",
|
||||||
|
"\t-v, --version - show version info and exit",
|
||||||
|
'',
|
||||||
|
'If no ARGUMENTS passed then --help implied.',
|
||||||
|
'If both -f and -d are specified then only unique set of files from both arguments will be converted.',
|
||||||
|
'-f or -d are required to be specified at least once, but each may be specified multiple times.',
|
||||||
|
'PATH must be a valid path to readable json-file or directory.',
|
||||||
|
'OUTPUT_PATH must be a valid path to writeable directory.',
|
||||||
|
'If -o or -e was specified several times then only last one will be used.',
|
||||||
|
'',
|
||||||
|
'Possible FORMATS:',
|
||||||
|
"\t--http - generate raw *.http files (default)",
|
||||||
|
"\t--curl - generate shell scripts with curl command",
|
||||||
|
"\t--wget - generate shell scripts with wget command",
|
||||||
|
"\t--v2.0 - convert from Postman Collection Schema v2.1 into v2.0",
|
||||||
|
"\t--v2.1 - convert from Postman Collection Schema v2.0 into v2.1",
|
||||||
|
"\t-a, --all - convert to all of formats listed above",
|
||||||
|
'',
|
||||||
|
'If no FORMATS specified then --http implied.',
|
||||||
|
'Any of FORMATS can be specified at the same time or replaced by --all.',
|
||||||
|
'',
|
||||||
|
'Example:',
|
||||||
|
" ./pm-convert \ ",
|
||||||
|
" -f ~/dir1/first.postman_collection.json \ ",
|
||||||
|
" --directory ~/team \ ",
|
||||||
|
" --file ~/dir2/second.postman_collection.json \ ",
|
||||||
|
" --env ~/localhost.postman_environment.json \ ",
|
||||||
|
" -d ~/personal \ ",
|
||||||
|
" --var \"myvar=some value\" \ ",
|
||||||
|
" -o ~/postman_export \ ",
|
||||||
|
" --all",
|
||||||
|
"",
|
||||||
|
], static::copyright());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
267
src/Settings.php
267
src/Settings.php
@@ -4,11 +4,10 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace PmConverter;
|
namespace PmConverter;
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use JsonException;
|
use JsonException;
|
||||||
use PmConverter\Converters\ConvertFormat;
|
use PmConverter\Converters\ConvertFormat;
|
||||||
use PmConverter\Enums\ArgumentNames as AN;
|
use PmConverter\Exceptions\IncorrectSettingsFileException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class responsible for settings storage and dumping
|
* Class responsible for settings storage and dumping
|
||||||
@@ -16,9 +15,9 @@ use PmConverter\Enums\ArgumentNames as AN;
|
|||||||
class Settings
|
class Settings
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string|null Full path to settings file
|
* @var string Full path to settings file
|
||||||
*/
|
*/
|
||||||
protected ?string $filePath = null;
|
protected static string $filepath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool Flag to output some debug-specific messages
|
* @var bool Flag to output some debug-specific messages
|
||||||
@@ -28,7 +27,7 @@ class Settings
|
|||||||
/**
|
/**
|
||||||
* @var string[] Paths to collection directories
|
* @var string[] Paths to collection directories
|
||||||
*/
|
*/
|
||||||
protected array $dirPaths = [];
|
protected array $directories = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string[] Paths to collection files
|
* @var string[] Paths to collection files
|
||||||
@@ -36,14 +35,14 @@ class Settings
|
|||||||
protected array $collectionPaths = [];
|
protected array $collectionPaths = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string|null Output path where to put results in
|
* @var string Output path where to put results in
|
||||||
*/
|
*/
|
||||||
protected ?string $outputPath;
|
protected string $outputPath = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool Flag to remove output directories or not before conversion started
|
* @var bool Flag to remove output directories or not before conversion started
|
||||||
*/
|
*/
|
||||||
protected bool $preserveOutput;
|
protected bool $preserveOutput = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string[] Additional variables
|
* @var string[] Additional variables
|
||||||
@@ -56,129 +55,36 @@ class Settings
|
|||||||
protected array $formats = [];
|
protected array $formats = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string|null Path to environment file
|
* @var string Path to environment file
|
||||||
*/
|
*/
|
||||||
protected ?string $envFilePath = null;
|
protected string $envFilepath = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws JsonException
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->loadFromDefaults();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads settings from file
|
|
||||||
*
|
|
||||||
* @param string|null $filePath
|
|
||||||
* @return void
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public function loadFromFile(?string $filePath = null): void
|
|
||||||
{
|
|
||||||
if (is_null($filePath)) {
|
|
||||||
$filePath = sprintf('%s%spm-convert-settings.json', $_SERVER['PWD'], DS);
|
|
||||||
}
|
|
||||||
|
|
||||||
$filePath = trim($filePath);
|
|
||||||
file_exists($filePath) || throw new Exception("file does not exist: $filePath");
|
|
||||||
is_file($filePath) || throw new Exception("not a file: $filePath");
|
|
||||||
is_readable($filePath) || throw new Exception("file is not readable: $filePath");
|
|
||||||
|
|
||||||
$content = file_get_contents($filePath);
|
|
||||||
$settings = json_decode($content ?: '{}', true, JSON_THROW_ON_ERROR);
|
|
||||||
|
|
||||||
$this->setFromArray($settings);
|
|
||||||
$this->filePath = $filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rewrites some defined settings with new values
|
|
||||||
*
|
|
||||||
* @param array $settings
|
|
||||||
* @return void
|
|
||||||
* @throws JsonException
|
|
||||||
*/
|
|
||||||
public function override(array $settings): void
|
|
||||||
{
|
|
||||||
$settings = array_replace_recursive($this->__serialize(), $settings);
|
|
||||||
$this->setFromArray($settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads settings with default values
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
* @throws JsonException
|
|
||||||
*/
|
|
||||||
public function loadFromDefaults(): void
|
|
||||||
{
|
|
||||||
$this->setFromArray(self::defaults());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns default settings values
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function defaults(?string $key = null): mixed
|
|
||||||
{
|
|
||||||
$values = [
|
|
||||||
AN::Config => null,
|
|
||||||
AN::Directories => [],
|
|
||||||
AN::Files => [],
|
|
||||||
AN::Environment => null,
|
|
||||||
AN::Output => null,
|
|
||||||
AN::PreserveOutput => false,
|
|
||||||
AN::Formats => ['http'],
|
|
||||||
AN::Vars => [],
|
|
||||||
AN::DevMode => false,
|
|
||||||
AN::Verbose => false,
|
|
||||||
];
|
|
||||||
|
|
||||||
return $key ? $values[$key] : $values;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set settings from array
|
|
||||||
*
|
|
||||||
* @param array $settings
|
|
||||||
* @return void
|
|
||||||
* @throws JsonException
|
|
||||||
*/
|
|
||||||
protected function setFromArray(array $settings): void
|
|
||||||
{
|
|
||||||
foreach ($settings[AN::Directories] ?? self::defaults(AN::Directories) as $path) {
|
|
||||||
$this->addDirPath($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($settings[AN::Files] ?? self::defaults(AN::Files) ?? [] as $path) {
|
|
||||||
$this->addFilePath($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->setEnvFilePath($settings[AN::Environment] ?? self::defaults(AN::Environment));
|
|
||||||
$this->setOutputPath($settings[AN::Output] ?? self::defaults(AN::Output));
|
|
||||||
$this->setPreserveOutput($settings[AN::PreserveOutput] ?? self::defaults(AN::PreserveOutput));
|
|
||||||
|
|
||||||
foreach ($settings[AN::Formats] ?? self::defaults(AN::Formats) as $format) {
|
|
||||||
$this->addFormat(ConvertFormat::fromArg($format));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->vars = $settings[AN::Vars] ?? self::defaults(AN::Vars);
|
|
||||||
$this->setDevMode($settings[AN::DevMode] ?? self::defaults(AN::DevMode));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks wether settings file exists or not
|
|
||||||
*
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function fileExists(): bool
|
public static function fileExists(): bool
|
||||||
{
|
{
|
||||||
return is_file($this->filePath)
|
return file_exists(self::$filepath);
|
||||||
&& is_readable($this->filePath)
|
}
|
||||||
&& is_writable($this->filePath);
|
|
||||||
|
/**
|
||||||
|
* @return self
|
||||||
|
* @throws IncorrectSettingsFileException
|
||||||
|
* @throws JsonException
|
||||||
|
*/
|
||||||
|
public static function init(): self
|
||||||
|
{
|
||||||
|
$content = '{}';
|
||||||
|
self::$filepath = sprintf('%s%spm-convert-settings.json', $_SERVER['PWD'], DS);
|
||||||
|
if (self::fileExists()) {
|
||||||
|
$content = trim(file_get_contents(self::$filepath));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$settings = json_decode($content ?: '{}', flags: JSON_THROW_ON_ERROR);
|
||||||
|
} catch (JsonException $e) {
|
||||||
|
throw new IncorrectSettingsFileException('Incorrect settings file: ' . $e->getMessage(), $e->getCode());
|
||||||
|
}
|
||||||
|
return new self($settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -186,65 +92,77 @@ class Settings
|
|||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function filePath(): string
|
public static function filepath(): string
|
||||||
{
|
{
|
||||||
return $this->filePath;
|
return self::$filepath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param object $settings
|
||||||
|
* @throws JsonException
|
||||||
|
*/
|
||||||
|
protected function __construct(object $settings)
|
||||||
|
{
|
||||||
|
foreach ($settings->directories ?? [] as $path) {
|
||||||
|
$this->addDirPath($path);
|
||||||
|
}
|
||||||
|
foreach ($settings->files ?? [] as $path) {
|
||||||
|
$this->addFilePath($path);
|
||||||
|
}
|
||||||
|
$this->setDevMode(!empty($settings->devMode));
|
||||||
|
$this->setPreserveOutput(!empty($settings->preserveOutput));
|
||||||
|
isset($settings->environment) && $this->setEnvFilepath($settings->environment);
|
||||||
|
isset($settings->output) && $this->setOutputPath($settings->output);
|
||||||
|
foreach ($settings->formats ?? [] as $format) {
|
||||||
|
$this->addFormat(ConvertFormat::fromArg($format));
|
||||||
|
}
|
||||||
|
foreach ($settings->vars ?? [] as $name => $value) {
|
||||||
|
$this->vars[$name] = $value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds directory path into current settings array and fills files array with its content
|
|
||||||
*
|
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return void
|
* @return void
|
||||||
* @throws JsonException
|
* @throws JsonException
|
||||||
*/
|
*/
|
||||||
public function addDirPath(string $path): void
|
public function addDirPath(string $path): void
|
||||||
{
|
{
|
||||||
$this->dirPaths = array_unique(array_merge(
|
$this->directories = array_unique(array_merge(
|
||||||
$this->dirPaths ?? [],
|
$this->directories ?? [],
|
||||||
[FileSystem::normalizePath($path)]
|
[FileSystem::normalizePath($path)]
|
||||||
));
|
));
|
||||||
|
|
||||||
$files = array_filter(
|
$files = array_filter(
|
||||||
FileSystem::dirContents($path),
|
FileSystem::dirContents($path),
|
||||||
static fn ($filename) => FileSystem::isCollectionFile($filename)
|
static fn ($filename) => FileSystem::isCollectionFile($filename)
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->collectionPaths = array_unique(array_merge($this->collectionPaths ?? [], $files));
|
$this->collectionPaths = array_unique(array_merge($this->collectionPaths ?? [], $files));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds collection file into current settings array
|
|
||||||
*
|
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return void
|
* @return void
|
||||||
* @throws JsonException
|
* @throws JsonException
|
||||||
*/
|
*/
|
||||||
public function addFilePath(string $path): void
|
public function addFilePath(string $path): void
|
||||||
{
|
{
|
||||||
if (!FileSystem::isCollectionFile($path)) {
|
$normpath = FileSystem::normalizePath($path);
|
||||||
|
if (!FileSystem::isCollectionFile($normpath)) {
|
||||||
throw new InvalidArgumentException("not a valid collection: $path");
|
throw new InvalidArgumentException("not a valid collection: $path");
|
||||||
}
|
}
|
||||||
|
in_array($path, $this->collectionPaths) || $this->collectionPaths[] = $path;
|
||||||
if (!in_array($path, $this->collectionPaths)) {
|
|
||||||
$this->collectionPaths[] = FileSystem::normalizePath($path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets output directory path
|
* @param string $outputPath
|
||||||
*
|
|
||||||
* @param string|null $outputPath
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setOutputPath(?string $outputPath): void
|
public function setOutputPath(string $outputPath): void
|
||||||
{
|
{
|
||||||
$this->outputPath = $outputPath;
|
$this->outputPath = $outputPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets developer mode setting
|
|
||||||
*
|
|
||||||
* @param bool $devMode
|
* @param bool $devMode
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
@@ -254,8 +172,6 @@ class Settings
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a format to convert to into current settings array
|
|
||||||
*
|
|
||||||
* @param ConvertFormat $format
|
* @param ConvertFormat $format
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
@@ -275,8 +191,6 @@ class Settings
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a setting responsible for saving old convertion results
|
|
||||||
*
|
|
||||||
* @param bool $preserveOutput
|
* @param bool $preserveOutput
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
@@ -286,21 +200,15 @@ class Settings
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets environment filepath setting
|
* @param string $filepath
|
||||||
*
|
|
||||||
* @param string|null $filepath
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setEnvFilePath(?string $filepath): void
|
public function setEnvFilepath(string $filepath): void
|
||||||
{
|
{
|
||||||
$this->envFilePath = is_string($filepath)
|
$this->envFilepath = FileSystem::normalizePath($filepath);
|
||||||
? FileSystem::normalizePath($filepath)
|
|
||||||
: $filepath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns current value of developer mode setting
|
|
||||||
*
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isDevMode(): bool
|
public function isDevMode(): bool
|
||||||
@@ -309,8 +217,6 @@ class Settings
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns current value of collection files setting
|
|
||||||
*
|
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public function collectionPaths(): array
|
public function collectionPaths(): array
|
||||||
@@ -319,18 +225,14 @@ class Settings
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns current value of output directory path setting
|
* @return string
|
||||||
*
|
|
||||||
* @return string|null
|
|
||||||
*/
|
*/
|
||||||
public function outputPath(): ?string
|
public function outputPath(): string
|
||||||
{
|
{
|
||||||
return $this->outputPath;
|
return $this->outputPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns current value of preserve output setting
|
|
||||||
*
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isPreserveOutput(): bool
|
public function isPreserveOutput(): bool
|
||||||
@@ -339,8 +241,6 @@ class Settings
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns current convert formats
|
|
||||||
*
|
|
||||||
* @return ConvertFormat[]
|
* @return ConvertFormat[]
|
||||||
*/
|
*/
|
||||||
public function formats(): array
|
public function formats(): array
|
||||||
@@ -349,13 +249,11 @@ class Settings
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns current value of environment filepath setting
|
* @return string
|
||||||
*
|
|
||||||
* @return string|null
|
|
||||||
*/
|
*/
|
||||||
public function envFilepath(): ?string
|
public function envFilepath(): string
|
||||||
{
|
{
|
||||||
return $this->envFilePath;
|
return $this->envFilepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -366,17 +264,17 @@ class Settings
|
|||||||
public function __serialize(): array
|
public function __serialize(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
AN::DevMode => $this->isDevMode(),
|
'dev' => $this->isDevMode(),
|
||||||
AN::Directories => $this->dirPaths,
|
'directories' => $this->directories,
|
||||||
AN::Files => $this->collectionPaths(),
|
'files' => $this->collectionPaths(),
|
||||||
AN::Environment => $this->envFilepath(),
|
'environment' => $this->envFilepath(),
|
||||||
AN::Output => $this->outputPath(),
|
'output' => $this->outputPath(),
|
||||||
AN::PreserveOutput => $this->isPreserveOutput(),
|
'preserve-output' => $this->isPreserveOutput(),
|
||||||
AN::Formats => array_values(array_map(
|
'formats' => array_values(array_map(
|
||||||
static fn (ConvertFormat $format) => $format->toArg(),
|
static fn (ConvertFormat $format) => $format->toArg(),
|
||||||
$this->formats(),
|
$this->formats(),
|
||||||
)),
|
)),
|
||||||
AN::Vars => $this->vars,
|
'vars' => $this->vars,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,8 +307,7 @@ class Settings
|
|||||||
*/
|
*/
|
||||||
public function backup(): string
|
public function backup(): string
|
||||||
{
|
{
|
||||||
$newFilePath = $this->filePath() . '.bak.' . time();
|
copy(self::$filepath, $newfilepath = self::$filepath . '.bak.' . time());
|
||||||
copy($this->filePath(), $newFilePath);
|
return $newfilepath;
|
||||||
return $newFilePath;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class AbstractRequestTest extends TestCase
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||||
* @covers \PmConverter\Enums\HttpVersion
|
* @covers PmConverter\HttpVersion
|
||||||
* @return void
|
* @return void
|
||||||
* @throws InvalidHttpVersionException
|
* @throws InvalidHttpVersionException
|
||||||
*/
|
*/
|
||||||
@@ -25,7 +25,7 @@ class AbstractRequestTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::getVerb()
|
* @covers PmConverter\Converters\Abstract\AbstractRequest::getVerb()
|
||||||
* @covers \PmConverter\Enums\HttpVersion
|
* @covers PmConverter\HttpVersion
|
||||||
* @return void
|
* @return void
|
||||||
* @throws InvalidHttpVersionException
|
* @throws InvalidHttpVersionException
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"files": [
|
|
||||||
"collections/20-API Lifecycle.postman_collection.json"
|
|
||||||
],
|
|
||||||
"output": "converted",
|
|
||||||
"preserveOutput": false,
|
|
||||||
"formats": [
|
|
||||||
"http"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user