Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix nested hierarchy in yaml #27

Merged
merged 7 commits into from
Jul 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@

## [Unreleased]

## [4.2.4] - 2019-07-26
### Fixed
- [#27] Yaml indent: fix nested hierarchy, where elements are nested in 2 arrays, e.g.:
```yaml
patchesJson6902:
- target:
group: extensions
version: v1beta1
kind: Ingress
name: shopsys
path: ./ingress-patch.yaml
```
to correct
```yaml
patchesJson6902:
- target:
group: extensions
version: v1beta1
kind: Ingress
name: shopsys
path: ./ingress-patch.yaml
```
, Thanks to [@PetrHeinz]

## [4.2.3] - 2019-07-14
### Fixed
- Yaml path service: first check whether path refer to real dir or file
Expand Down Expand Up @@ -103,7 +127,9 @@
[@ChrisDBrown]: https://github.com/ChrisDBrown
[@boris-brtan]: https://github.com/boris-brtan
[@DavidOstrozlik]: https://github.com/DavidOstrozlik
[@PetrHeinz]: https://github.com/PetrHeinz

[#27]: https://github.com/sspooky13/yaml-standards/pull/27
[#18]: https://github.com/sspooky13/yaml-standards/pull/18
[#14]: https://github.com/sspooky13/yaml-standards/issues/14
[#13]: https://github.com/sspooky13/yaml-standards/pull/13
Expand Down
41 changes: 41 additions & 0 deletions src/Model/Component/YamlService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace YamlStandards\Model\Component;

use Symfony\Component\Yaml\Inline;
use Symfony\Component\Yaml\Yaml;

class YamlService
Expand Down Expand Up @@ -98,4 +99,44 @@ public static function isLineStartOfArrayWithKeyAndValue($trimmedLine)
{
return $trimmedLine !== '-' && self::hasLineDashOnStartOfLine($trimmedLine);
}

/**
* value starting with key, e.g. 'foo: bar' or '"foo bar": baz'
*
* @param string $value
* @return bool
*/
public static function isKeyInStartOfString($value)
{
return (bool)preg_match('~^(' . Inline::REGEX_QUOTED_STRING . '|[^ \'"{\[].*?) *:~u', $value);
}

/**
* line possibly opening an array, e.g. 'foo:' or '- foo:'
*
* @param string $trimmedLine
* @return bool
*/
public static function isLineOpeningAnArray($trimmedLine)
{
return (bool)preg_match('~^(- +)*(' . Inline::REGEX_QUOTED_STRING . '|[^ \'"{\[].*?) *:$~u', $trimmedLine);
sspooky13 marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* @param string $line
* @return int
*/
public static function rowIndentsOf($line)
{
return strlen($line) - strlen(ltrim($line));
}

/**
* @param string $line
* @return int
*/
public static function keyIndentsOf($line)
{
return strlen($line) - strlen(ltrim($line, '- '));
}
}
71 changes: 28 additions & 43 deletions src/Model/YamlIndent/YamlIndentDataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function getRightFileLines(array $fileLines, $key, $countOfIndents, $file

$line = $fileLines[$key];
$trimmedLine = trim($line);
$countOfRowIndents = strlen($line) - strlen(ltrim($line));
$countOfRowIndents = YamlService::rowIndentsOf($line);
$explodedLine = explode(':', $line);

// empty line
Expand Down Expand Up @@ -112,8 +112,7 @@ public function getRightFileLines(array $fileLines, $key, $countOfIndents, $file
// parent, not comment line
if ($isCommentLine === false && ($trimmedLineValue === '' || YamlService::isValueReuseVariable($trimmedLineValue))) {
$nextLine = $fileLines[$key + 1];
$countOfNextRowIndents = strlen($nextLine) - strlen(ltrim($nextLine));
if ($countOfNextRowIndents > $countOfRowIndents) {
if (YamlService::rowIndentsOf($nextLine) > $countOfRowIndents) {
$countOfParents = $this->getCountOfParentsForLine($fileLines, $key);

$correctIndents = $this->getCorrectIndents($countOfParents * $countOfIndents);
Expand All @@ -136,15 +135,7 @@ public function getRightFileLines(array $fileLines, $key, $countOfIndents, $file
*/
private function getCorrectIndents($countOfIndents)
{
$currentNumberOfIndents = 1;
$indents = '';

while ($currentNumberOfIndents <= $countOfIndents) {
$indents .= ' ';
$currentNumberOfIndents++;
}

return $indents;
return str_repeat(' ', $countOfIndents);
}

/**
Expand All @@ -162,8 +153,6 @@ private function belongLineToArray(array $fileLines, $key)
{
while ($key >= 0) {
$line = $fileLines[$key];
$countOfRowIndents = strlen($line) - strlen(ltrim($line));

$key--;
$prevLine = $fileLines[$key];
$trimmedPrevLine = trim($prevLine);
Expand All @@ -172,9 +161,7 @@ private function belongLineToArray(array $fileLines, $key)
$prevLine = preg_replace('/-/', ' ', $prevLine, 1); // replace '-' for space
}

$countOfPrevRowIndents = strlen($prevLine) - strlen(ltrim($prevLine));

if ($countOfPrevRowIndents === $countOfRowIndents) {
if (YamlService::rowIndentsOf($prevLine) === YamlService::rowIndentsOf($line)) {
if (YamlService::isLineStartOfArrayWithKeyAndValue($trimmedPrevLine)) {
return true;
}
Expand Down Expand Up @@ -217,36 +204,23 @@ private function getCorrectLineForArrayWithKeyAndValue($line, array $fileLines,
return $correctIndentsOnStartOfLine . '-' . $correctIndentsBetweenDashAndBracket . $trimmedLineWithoutDash;
}

/**
* solution for more values in array
* "- foo: bar"
* " baz: qux:
*/
if (array_key_exists($key + 1, $fileLines) && $this->isNextLineKeyAndValueOfArray($lineWithReplacedDashToSpace, $fileLines[$key + 1])) {
$correctIndentsBetweenDashAndKey = $this->getCorrectIndents($countOfIndents - 1); // 1 space is dash, dash is as indent
// solution "- foo" (single value of an array)
if (YamlService::isKeyInStartOfString($trimmedLineWithoutDash) === false) {
$correctIndentsBetweenDashAndKey = $this->getCorrectIndents(1);

return $correctIndentsOnStartOfLine . '-' . $correctIndentsBetweenDashAndKey . $trimmedLineWithoutDash;
}

// solution for one value in array "- foo: bar" or "- foo"
$correctIndentsBetweenDashAndKey = $this->getCorrectIndents(1);
/**
* solution for one or more values in array
* "- foo: bar"
* " baz: qux"
*/
$correctIndentsBetweenDashAndKey = $this->getCorrectIndents($countOfIndents - 1); // 1 space is dash, dash is as indent

return $correctIndentsOnStartOfLine . '-' . $correctIndentsBetweenDashAndKey . $trimmedLineWithoutDash;
}

/**
* @param string $currentLine
* @param string $nextLine
* @return bool
*/
private function isNextLineKeyAndValueOfArray($currentLine, $nextLine)
{
$countOfCurrentRowIndents = strlen($currentLine) - strlen(ltrim($currentLine));
$countOfNextRowIndents = strlen($nextLine) - strlen(ltrim($nextLine));

return $countOfCurrentRowIndents === $countOfNextRowIndents;
}

/**
* Go back until deepest parent and count them
*
Expand All @@ -255,12 +229,14 @@ private function isNextLineKeyAndValueOfArray($currentLine, $nextLine)
* @return int
*
* @SuppressWarnings("CyclomaticComplexity")
* @SuppressWarnings("ExcessiveMethodLength")
*/
private function getCountOfParentsForLine(array $fileLines, $key)
{
$countOfParents = 0;
$line = $fileLines[$key];
$countOfRowIndents = strlen($line) - strlen(ltrim($line));
$originalLine = $line;
$countOfRowIndents = YamlService::rowIndentsOf($line);
$trimmedLine = trim($line);
$isArrayLine = YamlService::hasLineDashOnStartOfLine($trimmedLine);

Expand All @@ -269,7 +245,7 @@ private function getCountOfParentsForLine(array $fileLines, $key)
$prevLine = $fileLines[$key];
$trimmedPrevLine = trim($prevLine);
$isPrevLineArrayLine = YamlService::hasLineDashOnStartOfLine($trimmedPrevLine);
$countOfPrevRowIndents = strlen($prevLine) - strlen(ltrim($prevLine));
$countOfPrevRowIndents = YamlService::rowIndentsOf($prevLine);

// ignore comment line and empty line
if ($trimmedPrevLine === '' || YamlService::isLineComment($prevLine)) {
Expand All @@ -294,11 +270,20 @@ private function getCountOfParentsForLine(array $fileLines, $key)
($isArrayLine === false && $countOfPrevRowIndents < $countOfRowIndents)
) {
$line = $fileLines[$key];
$countOfRowIndents = strlen($line) - strlen(ltrim($line));
$countOfRowIndents = YamlService::rowIndentsOf($line);
$trimmedLine = trim($line);
$isArrayLine = YamlService::hasLineDashOnStartOfLine($trimmedLine);

$countOfParents++;

/* nested hierarchy in array fix, eg.
- foo:
nested: value
bar: baz
*/
if ($isArrayLine && YamlService::isLineOpeningAnArray($trimmedLine) && YamlService::keyIndentsOf($originalLine) > YamlService::keyIndentsOf($line)) {
$countOfParents++;
}
}

// if line has zero counts of indents then it's highest parent and should be ended
Expand All @@ -313,7 +298,7 @@ private function getCountOfParentsForLine(array $fileLines, $key)
continue;
}

$countOfRowIndents = strlen($prevLine) - strlen(ltrim($prevLine));
$countOfRowIndents = YamlService::rowIndentsOf($prevLine);
$explodedPrevLine = explode(':', $prevLine);
if ($countOfRowIndents === 0 && array_key_exists(1, $explodedPrevLine) && trim($explodedPrevLine[1]) === '') {
$countOfParents++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ private function getCorrectYamlContentWithSpacesBetweeenGroups(array $yamlLines,
continue;
}

$countOfRowIndents = strlen($yamlLine) - strlen(ltrim($yamlLine));
$lineLevel = $this->getLevelOfCurrentLine($key, $yamlLines, $countOfRowIndents);
$lineLevel = $this->getLevelOfCurrentLine($key, $yamlLines, YamlService::rowIndentsOf($yamlLine));
$correctYamlLines[$key] = $yamlLine;

if ($lineLevel <= $level) {
Expand All @@ -79,7 +78,7 @@ private function getCorrectYamlContentWithSpacesBetweeenGroups(array $yamlLines,
private function getLevelOfCurrentLine($key, array $yamlLines, $previousCountOfIndents, $currentLineLevel = 1)
{
$yamlLine = $yamlLines[$key];
$countOfRowIndents = strlen($yamlLine) - strlen(ltrim($yamlLine));
$countOfRowIndents = YamlService::rowIndentsOf($yamlLine);
$key--;

if (YamlService::isLineComment($yamlLine)) {
Expand Down Expand Up @@ -112,7 +111,6 @@ private function getLevelOfCurrentLine($key, array $yamlLines, $previousCountOfI
private function getCorrectYamlLinesWithSpace($correctYamlLines, $key)
{
$yamlLine = $correctYamlLines[$key];
$countOfRowIndents = strlen($yamlLine) - strlen(ltrim($yamlLine));
$key--;

if (reset($correctYamlLines) === $yamlLine) {
Expand All @@ -128,9 +126,7 @@ private function getCorrectYamlLinesWithSpace($correctYamlLines, $key)
}

$previousYamlLine = $correctYamlLines[$key];
$previousCountOfRowIndents = strlen($previousYamlLine) - strlen(ltrim($previousYamlLine));

if ($previousCountOfRowIndents < $countOfRowIndents) {
if (YamlService::rowIndentsOf($previousYamlLine) < YamlService::rowIndentsOf($yamlLine)) {
return $correctYamlLines;
}

Expand Down
4 changes: 3 additions & 1 deletion tests/Model/YamlIndent/YamlIndentCheckerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public function testCheckUnfixedFilesIsNotCorrect()
{
$inputSettingData = $this->getInputSettingDataMock();
$pathToFiles = [
__DIR__ . '/resource/unfixed/kustomization.yaml',
__DIR__ . '/resource/unfixed/shopsys-service.yml',
__DIR__ . '/resource/unfixed/symfony-config.yml',
__DIR__ . '/resource/unfixed/symfony-route.yml',
Expand Down Expand Up @@ -54,6 +55,7 @@ public function testCheckFixedFilesIsCorrect()
{
$inputSettingData = $this->getInputSettingDataMock();
$pathToFiles = [
__DIR__ . '/resource/fixed/kustomization.yaml',
__DIR__ . '/resource/fixed/shopsys-service.yml',
__DIR__ . '/resource/fixed/symfony-config.yml',
__DIR__ . '/resource/fixed/symfony-route.yml',
Expand All @@ -65,7 +67,7 @@ public function testCheckFixedFilesIsCorrect()

foreach ($pathToFiles as $pathToFile) {
$result = $yamlIndentChecker->check($pathToFile, $inputSettingData);
$this->assertSame(Result::RESULT_CODE_OK, $result->getResultCode());
$this->assertSame(Result::RESULT_CODE_OK, $result->getResultCode(), sprintf('YAML indent check of "%s" failed.', $pathToFile));
}
}

Expand Down
2 changes: 2 additions & 0 deletions tests/Model/YamlIndent/YamlIndentFixerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public function testFixUnfixedFiles()
{
$inputSettingData = $this->getInputSettingDataMock();
$pathToUnfixedFiles = [
__DIR__ . '/resource/unfixed/kustomization.yaml',
__DIR__ . '/resource/unfixed/shopsys-service.yml',
__DIR__ . '/resource/unfixed/symfony-config.yml',
__DIR__ . '/resource/unfixed/symfony-route.yml',
Expand All @@ -36,6 +37,7 @@ public function testFixUnfixedFiles()
__DIR__ . '/resource/unfixed/yaml-getting-started.yml',
];
$pathToFixedFiles = [
__DIR__ . '/resource/fixed/kustomization.yaml',
__DIR__ . '/resource/fixed/shopsys-service.yml',
__DIR__ . '/resource/fixed/symfony-config.yml',
__DIR__ . '/resource/fixed/symfony-route.yml',
Expand Down
20 changes: 20 additions & 0 deletions tests/Model/YamlIndent/resource/fixed/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
bases:
- ../../base
resources:
- ../../../deployments/adminer.yml
- ../../../deployments/redis-admin.yml
- ../../../deployments/selenium-server.yml
- ../../../services/adminer.yml
- ../../../services/redis-admin.yml
- ../../../services/selenium-server.yml
patchesJson6902:
- target:
group: extensions
version: v1beta1
kind: Ingress
name: shopsys
path: ./ingress-patch.yaml
configMapGenerator:
- name: nginx-configuration
files:
- ../../../../../docker/nginx/nginx.conf
20 changes: 20 additions & 0 deletions tests/Model/YamlIndent/resource/unfixed/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
bases:
- ../../base
resources:
- ../../../deployments/adminer.yml
- ../../../deployments/redis-admin.yml
- ../../../deployments/selenium-server.yml
- ../../../services/adminer.yml
- ../../../services/redis-admin.yml
- ../../../services/selenium-server.yml
patchesJson6902:
- target:
group: extensions
version: v1beta1
kind: Ingress
name: shopsys
path: ./ingress-patch.yaml
configMapGenerator:
- name: nginx-configuration
files:
- ../../../../../docker/nginx/nginx.conf