Skip to content

Commit

Permalink
Add support for json5 configuration file format (#1727)
Browse files Browse the repository at this point in the history
* Add support for `json5` configuration file format

* Keep support for `json` to be backward-compatible with previous versions
* Generate `json5` by default for new projects

Closes #1724

* Revert changes in `infection.json5`

* Set constants to private where possible

* Fix e2e test `Initial_Configuration`
  • Loading branch information
maks-rafalko committed Sep 15, 2022
1 parent bd5525c commit b66257a
Show file tree
Hide file tree
Showing 13 changed files with 123 additions and 108 deletions.
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -48,6 +48,7 @@
"ext-libxml": "*",
"ext-mbstring": "*",
"composer-runtime-api": "^2.0",
"colinodell/json5": "^2.2",
"composer/xdebug-handler": "^2.0 || ^3.0",
"infection/abstract-testframework-adapter": "^0.5.0",
"infection/extension-installer": "^0.1.0",
Expand All @@ -58,7 +59,6 @@
"sanmai/later": "^0.1.1",
"sanmai/pipeline": "^5.1 || ^6",
"sebastian/diff": "^3.0.2 || ^4.0",
"seld/jsonlint": "^1.7",
"symfony/console": "^5.4 || ^6.0",
"symfony/filesystem": "^5.4 || ^6.0",
"symfony/finder": "^5.4 || ^6.0",
Expand Down
156 changes: 92 additions & 64 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

File renamed without changes.
4 changes: 2 additions & 2 deletions src/Command/ConfigureCommand.php
Expand Up @@ -163,7 +163,7 @@ protected function executeCommand(IO $io): bool
$io->newLine();
$io->writeln(sprintf(
'Configuration file "<comment>%s</comment>" was created.',
SchemaConfigurationLoader::DEFAULT_CONFIG_FILE
SchemaConfigurationLoader::DEFAULT_JSON5_CONFIG_FILE
));
$io->newLine();

Expand Down Expand Up @@ -223,7 +223,7 @@ private function saveConfig(
];

file_put_contents(
SchemaConfigurationLoader::DEFAULT_CONFIG_FILE,
SchemaConfigurationLoader::DEFAULT_JSON5_CONFIG_FILE,
json_encode($configObject, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
);
}
Expand Down
5 changes: 1 addition & 4 deletions src/Command/RunCommand.php
Expand Up @@ -568,10 +568,7 @@ private function startUp(
private function runConfigurationCommand(Locator $locator, IO $io): void
{
try {
$locator->locateOneOf([
SchemaConfigurationLoader::DEFAULT_CONFIG_FILE,
SchemaConfigurationLoader::DEFAULT_DIST_CONFIG_FILE,
]);
$locator->locateOneOf(SchemaConfigurationLoader::POSSIBLE_DEFAULT_CONFIG_FILES);
} catch (FileNotFound|FileOrDirectoryNotFound $exception) {
$configureCommand = $this->getApplication()->find('configure');

Expand Down
11 changes: 4 additions & 7 deletions src/Configuration/Schema/SchemaConfigurationFile.php
Expand Up @@ -35,11 +35,11 @@

namespace Infection\Configuration\Schema;

use ColinODell\Json5\SyntaxError;
use function is_file;
use function is_readable;
use function json5_decode;
use function Safe\file_get_contents;
use Seld\JsonLint\JsonParser;
use Seld\JsonLint\ParsingException;
use stdClass;

/**
Expand Down Expand Up @@ -81,11 +81,8 @@ public function getDecodedContents(): stdClass
$contents = file_get_contents($this->path);

try {
return $this->decodedContents = (new JsonParser())->parse(
$contents,
JsonParser::DETECT_KEY_CONFLICTS
);
} catch (ParsingException $exception) {
return $this->decodedContents = json5_decode($contents);
} catch (SyntaxError $exception) {
throw InvalidFile::createForInvalidJson($this, $exception->getMessage(), $exception);
}
}
Expand Down
13 changes: 11 additions & 2 deletions src/Configuration/Schema/SchemaConfigurationLoader.php
Expand Up @@ -42,8 +42,17 @@
*/
final class SchemaConfigurationLoader
{
public const DEFAULT_DIST_CONFIG_FILE = 'infection.json.dist';
public const DEFAULT_CONFIG_FILE = 'infection.json';
public const POSSIBLE_DEFAULT_CONFIG_FILES = [
self::DEFAULT_JSON5_CONFIG_FILE,
self::DEFAULT_JSON_CONFIG_FILE,
self::DEFAULT_DIST_JSON5_CONFIG_FILE,
self::DEFAULT_DIST_JSON_CONFIG_FILE,
];
public const DEFAULT_JSON5_CONFIG_FILE = 'infection.json5';

private const DEFAULT_DIST_JSON5_CONFIG_FILE = 'infection.json5.dist';
private const DEFAULT_DIST_JSON_CONFIG_FILE = 'infection.json.dist';
private const DEFAULT_JSON_CONFIG_FILE = 'infection.json';

private Locator $locator;
private SchemaConfigurationFileLoader $fileLoader;
Expand Down
5 changes: 2 additions & 3 deletions src/Container.php
Expand Up @@ -640,9 +640,8 @@ public function withValues(
array_filter(
[
$configFile,
SchemaConfigurationLoader::DEFAULT_CONFIG_FILE,
SchemaConfigurationLoader::DEFAULT_DIST_CONFIG_FILE,
]
...SchemaConfigurationLoader::POSSIBLE_DEFAULT_CONFIG_FILES,
],
)
)
);
Expand Down
File renamed without changes.
6 changes: 3 additions & 3 deletions tests/e2e/Configure/run_tests.bash
Expand Up @@ -7,7 +7,7 @@ if test ! -f "$(which expect)"; then
fi

cd $(dirname $0)
rm -f infection.json
rm -f infection.json5

set -e

Expand All @@ -25,5 +25,5 @@ unset GITHUB_ACTIONS

./do_configure.expect

test -f infection.json
diff -u infection.json.test infection.json
test -f infection.json5
diff -u infection.json5.test infection.json5
4 changes: 2 additions & 2 deletions tests/e2e/Initial_Configuration/run_tests.bash
Expand Up @@ -7,7 +7,7 @@ if test ! -f "$(which expect)"; then
fi

cd $(dirname $0)
rm -v -f infection.json infection.log
rm -v -f infection.json5 infection.log

set -e

Expand All @@ -27,4 +27,4 @@ unset GITHUB_ACTIONS

trap 'echo Final check failed: $(tail -n+$LINENO $0 | head -n1)' ERR

test -f infection.json
test -f infection.json5
2 changes: 1 addition & 1 deletion tests/e2e/Unconfigured/run_tests.bash
Expand Up @@ -21,6 +21,6 @@ fi

test -x $(which tput) && tput setaf 1 # red
echo "Infection configuration master did not start."
rm -f infection.json.dist
rm -f infection.json5
exit 1;

23 changes: 4 additions & 19 deletions tests/phpunit/Configuration/Schema/SchemaConfigurationFileTest.php
Expand Up @@ -35,14 +35,14 @@

namespace Infection\Tests\Configuration\Schema;

use ColinODell\Json5\SyntaxError;
use Exception;
use function get_class;
use Infection\Configuration\Schema\InvalidFile;
use Infection\Configuration\Schema\SchemaConfigurationFile;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
use function Safe\sprintf;
use Seld\JsonLint\ParsingException;
use function sprintf;

/**
* @group integration
Expand Down Expand Up @@ -156,26 +156,11 @@ public function invalidConfigContentsProvider(): iterable
self::FIXTURES_DIR . '/invalid-json',
new InvalidFile(
sprintf(
<<<'ERROR'
Could not parse the JSON file "%s": Parse error on line 1:
^
Expected one of: 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['
ERROR
,
'Could not parse the JSON file "%s": Unexpected EOF at line 1 column 1 of the JSON5 data',
self::FIXTURES_DIR . '/invalid-json'
),
0,
new ParsingException(
<<<'ERROR'
Parse error on line 1:
^
Expected one of: 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['
ERROR
,
[]
)
new SyntaxError('Unexpected EOF', 1, 1),
),
];
}
Expand Down

0 comments on commit b66257a

Please sign in to comment.