diff --git a/resources/schema.json b/resources/schema.json
index f8780306d..51f6153bd 100644
--- a/resources/schema.json
+++ b/resources/schema.json
@@ -98,7 +98,7 @@
},
"gitlab": {
"type": "string",
- "definition": "GitLab(Code Climate) code quality json file."
+ "definition": "GitLab (Code Climate) code quality json file."
},
"summaryJson": {
"type": "string",
diff --git a/src/Command/RunCommand.php b/src/Command/RunCommand.php
index f0a8b008b..e16d10c2d 100644
--- a/src/Command/RunCommand.php
+++ b/src/Command/RunCommand.php
@@ -125,6 +125,9 @@ final class RunCommand extends BaseCommand
/** @var string */
private const OPTION_LOGGER_GITHUB = 'logger-github';
+ /** @var string */
+ private const OPTION_LOGGER_GITLAB = 'logger-gitlab';
+
private const OPTION_LOGGER_HTML = 'logger-html';
private const OPTION_USE_NOOP_MUTATORS = 'noop';
@@ -274,6 +277,12 @@ protected function configure(): void
'Log escaped Mutants as GitHub Annotations (automatically detected on Github Actions itself, use true to force-enable or false to force-disable it).',
false
)
+ ->addOption(
+ self::OPTION_LOGGER_GITLAB,
+ null,
+ InputOption::VALUE_OPTIONAL,
+ 'Path to log escaped Mutants in the GitLab (Code Climate) JSON format.',
+ )
->addOption(
self::OPTION_LOGGER_HTML,
null,
@@ -404,6 +413,7 @@ private function createContainer(IO $io, LoggerInterface $logger): Container
$testFramework = trim((string) $input->getOption(self::OPTION_TEST_FRAMEWORK));
$testFrameworkExtraOptions = trim((string) $input->getOption(self::OPTION_TEST_FRAMEWORK_OPTIONS));
$initialTestsPhpOptions = trim((string) $input->getOption(self::OPTION_INITIAL_TESTS_PHP_OPTIONS));
+ $gitlabFileLogPath = trim((string) $input->getOption(self::OPTION_LOGGER_GITLAB));
$htmlFileLogPath = trim((string) $input->getOption(self::OPTION_LOGGER_HTML));
/** @var string|null $minMsi */
@@ -489,6 +499,7 @@ private function createContainer(IO $io, LoggerInterface $logger): Container
$isForGitDiffLines,
$gitDiffBase,
$this->getUseGitHubLogger($input),
+ $gitlabFileLogPath === '' ? Container::DEFAULT_GITLAB_LOGGER_PATH : $gitlabFileLogPath,
$htmlFileLogPath === '' ? Container::DEFAULT_HTML_LOGGER_PATH : $htmlFileLogPath,
(bool) $input->getOption(self::OPTION_USE_NOOP_MUTATORS),
(bool) $input->getOption(self::OPTION_EXECUTE_ONLY_COVERING_TEST_CASES)
diff --git a/src/Configuration/ConfigurationFactory.php b/src/Configuration/ConfigurationFactory.php
index a1646af4d..2fbaa7e81 100644
--- a/src/Configuration/ConfigurationFactory.php
+++ b/src/Configuration/ConfigurationFactory.php
@@ -108,6 +108,7 @@ public function create(
bool $isForGitDiffLines,
?string $gitDiffBase,
?bool $useGitHubLogger,
+ ?string $gitlabLogFilePath,
?string $htmlLogFilePath,
bool $useNoopMutators,
bool $executeOnlyCoveringTestCases
@@ -140,7 +141,7 @@ public function create(
),
$this->retrieveFilter($filter, $gitDiffFilter, $isForGitDiffLines, $gitDiffBase, $schema->getSource()->getDirectories()),
$schema->getSource()->getExcludes(),
- $this->retrieveLogs($schema->getLogs(), $configDir, $useGitHubLogger, $htmlLogFilePath),
+ $this->retrieveLogs($schema->getLogs(), $configDir, $useGitHubLogger, $gitlabLogFilePath, $htmlLogFilePath),
$logVerbosity,
$namespacedTmpDir,
$this->retrievePhpUnit($schema, $configDir),
@@ -308,7 +309,7 @@ private function retrieveFilter(string $filter, ?string $gitDiffFilter, bool $is
return $this->gitDiffFileProvider->provide($gitDiffFilter, $baseBranch, $sourceDirectories);
}
- private function retrieveLogs(Logs $logs, string $configDir, ?bool $useGitHubLogger, ?string $htmlLogFilePath): Logs
+ private function retrieveLogs(Logs $logs, string $configDir, ?bool $useGitHubLogger, ?string $gitlabLogFilePath, ?string $htmlLogFilePath): Logs
{
if ($useGitHubLogger === null) {
$useGitHubLogger = $this->detectCiGithubActions();
@@ -318,6 +319,10 @@ private function retrieveLogs(Logs $logs, string $configDir, ?bool $useGitHubLog
$logs->setUseGitHubAnnotationsLogger($useGitHubLogger);
}
+ if ($gitlabLogFilePath !== null) {
+ $logs->setGitlabLogFilePath($gitlabLogFilePath);
+ }
+
if ($htmlLogFilePath !== null) {
$logs->setHtmlLogFilePath($htmlLogFilePath);
}
diff --git a/src/Configuration/Entry/Logs.php b/src/Configuration/Entry/Logs.php
index eb883ea05..a3e017275 100644
--- a/src/Configuration/Entry/Logs.php
+++ b/src/Configuration/Entry/Logs.php
@@ -46,7 +46,7 @@ public function __construct(
private ?string $htmlLogFilePath,
private readonly ?string $summaryLogFilePath,
private readonly ?string $jsonLogFilePath,
- private readonly ?string $gitlabLogFilePath,
+ private ?string $gitlabLogFilePath,
private readonly ?string $debugLogFilePath,
private readonly ?string $perMutatorFilePath,
private bool $useGitHubAnnotationsLogger,
@@ -81,6 +81,11 @@ public function getHtmlLogFilePath(): ?string
return $this->htmlLogFilePath;
}
+ public function setGitlabLogFilePath(string $gitlabLogFilePath): void
+ {
+ $this->gitlabLogFilePath = $gitlabLogFilePath;
+ }
+
public function setHtmlLogFilePath(string $htmlLogFilePath): void
{
$this->htmlLogFilePath = $htmlLogFilePath;
diff --git a/src/Container.php b/src/Container.php
index ad9439e07..35afc14b0 100644
--- a/src/Container.php
+++ b/src/Container.php
@@ -173,6 +173,7 @@ final class Container
public const DEFAULT_GIT_DIFF_LINES = false;
public const DEFAULT_GIT_DIFF_BASE = null;
public const DEFAULT_USE_GITHUB_LOGGER = null;
+ public const DEFAULT_GITLAB_LOGGER_PATH = null;
public const DEFAULT_HTML_LOGGER_PATH = null;
public const DEFAULT_USE_NOOP_MUTATORS = false;
public const DEFAULT_EXECUTE_ONLY_COVERING_TEST_CASES = false;
@@ -588,6 +589,7 @@ public static function create(): self
self::DEFAULT_GIT_DIFF_LINES,
self::DEFAULT_GIT_DIFF_BASE,
self::DEFAULT_USE_GITHUB_LOGGER,
+ self::DEFAULT_GITLAB_LOGGER_PATH,
self::DEFAULT_HTML_LOGGER_PATH,
self::DEFAULT_USE_NOOP_MUTATORS,
self::DEFAULT_EXECUTE_ONLY_COVERING_TEST_CASES
@@ -622,6 +624,7 @@ public function withValues(
bool $isForGitDiffLines,
?string $gitDiffBase,
?bool $useGitHubLogger,
+ ?string $gitlabLogFilePath,
?string $htmlLogFilePath,
bool $useNoopMutators,
bool $executeOnlyCoveringTestCases
@@ -690,6 +693,7 @@ public function withValues(
$isForGitDiffLines,
$gitDiffBase,
$useGitHubLogger,
+ $gitlabLogFilePath,
$htmlLogFilePath,
$useNoopMutators,
$executeOnlyCoveringTestCases
diff --git a/tests/benchmark/Tracing/provide-traces-closure.php b/tests/benchmark/Tracing/provide-traces-closure.php
index b022223a0..77bbade0d 100644
--- a/tests/benchmark/Tracing/provide-traces-closure.php
+++ b/tests/benchmark/Tracing/provide-traces-closure.php
@@ -71,6 +71,7 @@
Container::DEFAULT_GIT_DIFF_LINES,
Container::DEFAULT_GIT_DIFF_BASE,
Container::DEFAULT_USE_GITHUB_LOGGER,
+ Container::DEFAULT_GITLAB_LOGGER_PATH,
Container::DEFAULT_HTML_LOGGER_PATH,
true,
Container::DEFAULT_EXECUTE_ONLY_COVERING_TEST_CASES
diff --git a/tests/phpunit/Configuration/ConfigurationFactoryTest.php b/tests/phpunit/Configuration/ConfigurationFactoryTest.php
index 5e61fdab3..5790cbfe3 100644
--- a/tests/phpunit/Configuration/ConfigurationFactoryTest.php
+++ b/tests/phpunit/Configuration/ConfigurationFactoryTest.php
@@ -114,6 +114,7 @@ public function test_it_can_create_a_configuration(
bool $inputIsForGitDiffLines,
string $inputGitDiffBase,
?bool $inputUseGitHubAnnotationsLogger,
+ ?string $inputGitlabLogFilePath,
?string $inputHtmlLogFilePath,
bool $inputUseNoopMutators,
int $inputMsiPrecision,
@@ -170,6 +171,7 @@ public function test_it_can_create_a_configuration(
$inputIsForGitDiffLines,
$inputGitDiffBase,
$inputUseGitHubAnnotationsLogger,
+ $inputGitlabLogFilePath,
$inputHtmlLogFilePath,
$inputUseNoopMutators,
$inputExecuteOnlyCoveringTestCases
@@ -258,6 +260,7 @@ public function valueProvider(): iterable
'master',
true,
null,
+ null,
false,
2,
10,
@@ -447,6 +450,42 @@ public function valueProvider(): iterable
true
);
+ yield 'null GitLab file log path with existing path from config file' => self::createValueForGitlabLogger(
+ '/from-config.json',
+ null,
+ '/from-config.json'
+ );
+
+ yield 'absolute GitLab file log path' => self::createValueForGitlabLogger(
+ '/path/to/from-config.json',
+ null,
+ '/path/to/from-config.json',
+ );
+
+ yield 'relative GitLab file log path' => self::createValueForGitlabLogger(
+ 'relative/path/to/from-config.json',
+ null,
+ '/path/to/relative/path/to/from-config.json'
+ );
+
+ yield 'override GitLab file log path from CLI option with existing path from config file' => self::createValueForGitlabLogger(
+ '/from-config.json',
+ '/from-cli.json',
+ '/from-cli.json'
+ );
+
+ yield 'set GitLab file log path from CLI option when config file has no setting' => self::createValueForGitlabLogger(
+ null,
+ '/from-cli.json',
+ '/from-cli.json'
+ );
+
+ yield 'null GitLab file log path in config and CLI' => self::createValueForGitlabLogger(
+ null,
+ null,
+ null
+ );
+
yield 'ignoreMsiWithNoMutations not specified in schema and true in input' => self::createValueForIgnoreMsiWithNoMutations(
null,
true,
@@ -770,6 +809,7 @@ public function valueProvider(): iterable
'master',
false,
null,
+ null,
false,
2,
10,
@@ -858,6 +898,7 @@ public function valueProvider(): iterable
'master',
false,
null,
+ null,
false,
2,
10,
@@ -955,6 +996,7 @@ private static function createValueForTimeout(
'master',
false,
null,
+ null,
false,
2,
$expectedTimeOut,
@@ -1031,6 +1073,7 @@ private static function createValueForTmpDir(
'master',
false,
null,
+ null,
false,
2,
10,
@@ -1108,6 +1151,7 @@ private static function createValueForCoveragePath(
'master',
false,
null,
+ null,
false,
2,
10,
@@ -1184,6 +1228,7 @@ private static function createValueForPhpUnitConfigDir(
'master',
false,
null,
+ null,
false,
2,
10,
@@ -1261,6 +1306,7 @@ private static function createValueForNoProgress(
'master',
false,
null,
+ null,
false,
2,
10,
@@ -1351,6 +1397,7 @@ private static function createValueForGithubActionsDetected(
'master',
$inputUseGitHubAnnotationsLogger,
null,
+ null,
false,
2,
10,
@@ -1382,6 +1429,108 @@ private static function createValueForGithubActionsDetected(
];
}
+ private static function createValueForGitlabLogger(
+ ?string $gitlabFileLogPathInConfig,
+ ?string $gitlabFileLogPathFromCliOption,
+ ?string $expectedGitlabFileLogPath
+ ): array {
+ $expectedLogs = new Logs(
+ null,
+ null,
+ null,
+ null,
+ $expectedGitlabFileLogPath,
+ null,
+ null,
+ false,
+ null,
+ null,
+ );
+
+ return [
+ false,
+ false,
+ new SchemaConfiguration(
+ '/path/to/infection.json',
+ null,
+ new Source([], []),
+ new Logs(
+ null,
+ null,
+ null,
+ null,
+ $gitlabFileLogPathInConfig,
+ null,
+ null,
+ false,
+ null,
+ null,
+ ),
+ '',
+ new PhpUnit(null, null),
+ null,
+ null,
+ null,
+ [],
+ null,
+ null,
+ null,
+ null
+ ),
+ null,
+ null,
+ false,
+ 'none',
+ false,
+ false,
+ false,
+ false,
+ null,
+ false,
+ null,
+ '',
+ null,
+ null,
+ '',
+ 0,
+ false,
+ 'AM',
+ false,
+ 'master',
+ false,
+ $gitlabFileLogPathFromCliOption,
+ null,
+ false,
+ 2,
+ 10,
+ [],
+ [],
+ 'src/a.php,src/b.php',
+ [],
+ $expectedLogs,
+ 'none',
+ sys_get_temp_dir() . '/infection',
+ new PhpUnit('/path/to', null),
+ self::getDefaultMutators(),
+ 'phpunit',
+ null,
+ null,
+ false,
+ '',
+ sys_get_temp_dir() . '/infection',
+ false,
+ false,
+ false,
+ false,
+ false,
+ null,
+ false,
+ null,
+ [],
+ true,
+ ];
+ }
+
private static function createValueForIgnoreMsiWithNoMutations(
?bool $ignoreMsiWithNoMutationsFromSchemaConfiguration,
?bool $ignoreMsiWithNoMutationsFromInput,
@@ -1428,6 +1577,7 @@ private static function createValueForIgnoreMsiWithNoMutations(
'master',
false,
null,
+ null,
false,
2,
10,
@@ -1505,6 +1655,7 @@ private static function createValueForMinMsi(
'master',
false,
null,
+ null,
false,
2,
10,
@@ -1582,6 +1733,7 @@ private static function createValueForMinCoveredMsi(
'master',
false,
null,
+ null,
false,
2,
10,
@@ -1660,6 +1812,7 @@ private static function createValueForTestFramework(
'master',
false,
null,
+ null,
false,
2,
10,
@@ -1737,6 +1890,7 @@ private static function createValueForInitialTestsPhpOptions(
'master',
false,
null,
+ null,
false,
2,
10,
@@ -1815,6 +1969,7 @@ private static function createValueForTestFrameworkExtraOptions(
'master',
false,
null,
+ null,
false,
2,
10,
@@ -1892,6 +2047,7 @@ private static function createValueForTestFrameworkKey(
'master',
false,
null,
+ null,
false,
2,
10,
@@ -1973,6 +2129,7 @@ private static function createValueForMutators(
'master',
false,
null,
+ null,
$useNoopMutatos,
2,
10,
@@ -2053,6 +2210,7 @@ private static function createValueForIgnoreSourceCodeByRegex(
'master',
false,
null,
+ null,
false,
2,
10,
@@ -2152,6 +2310,7 @@ private static function createValueForHtmlLogFilePath(?string $htmlFileLogPathIn
false,
'master',
true,
+ null,
$htmlFileLogPathFromCliOption,
false,
2,
diff --git a/tests/phpunit/ContainerTest.php b/tests/phpunit/ContainerTest.php
index 7e3049553..a9966ea3c 100644
--- a/tests/phpunit/ContainerTest.php
+++ b/tests/phpunit/ContainerTest.php
@@ -96,6 +96,7 @@ public function test_it_can_build_lazy_source_file_data_factory_that_fails_on_us
Container::DEFAULT_GIT_DIFF_LINES,
Container::DEFAULT_GIT_DIFF_BASE,
Container::DEFAULT_USE_GITHUB_LOGGER,
+ Container::DEFAULT_GITLAB_LOGGER_PATH,
Container::DEFAULT_HTML_LOGGER_PATH,
Container::DEFAULT_USE_NOOP_MUTATORS,
Container::DEFAULT_EXECUTE_ONLY_COVERING_TEST_CASES
@@ -146,6 +147,7 @@ public function test_it_provides_a_friendly_error_when_attempting_to_configure_i
Container::DEFAULT_GIT_DIFF_LINES,
Container::DEFAULT_GIT_DIFF_BASE,
Container::DEFAULT_USE_GITHUB_LOGGER,
+ Container::DEFAULT_GITLAB_LOGGER_PATH,
Container::DEFAULT_HTML_LOGGER_PATH,
Container::DEFAULT_USE_NOOP_MUTATORS,
Container::DEFAULT_EXECUTE_ONLY_COVERING_TEST_CASES,