Skip to content

Commit 4b0d35a

Browse files
authored
Merge pull request #86 from RoussKS/main
Allow JSON Format Ansible --extra-vars
2 parents 8d03a84 + 0b4a7a1 commit 4b0d35a

5 files changed

Lines changed: 97 additions & 2 deletions

File tree

Asm/Ansible/Ansible.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
use Asm\Ansible\Process\ProcessBuilder;
1313
use Asm\Ansible\Process\ProcessBuilderInterface;
1414
use Asm\Ansible\Utils\Env;
15-
use JetBrains\PhpStorm\Pure;
1615
use Psr\Log\LoggerAwareInterface;
1716
use Psr\Log\LoggerAwareTrait;
1817
use Psr\Log\NullLogger;

Asm/Ansible/Command/AnsiblePlaybook.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
namespace Asm\Ansible\Command;
66

7+
use Asm\Ansible\Utils\Str;
78
use InvalidArgumentException;
9+
use JsonException;
810

911
/**
1012
* Class AnsiblePlaybook
@@ -210,6 +212,21 @@ public function extraVars(string|array $extraVars = ''): AnsiblePlaybookInterfac
210212
throw new InvalidArgumentException(sprintf('Expected string|array, got "%s"', gettype($extraVars)));
211213
}
212214

215+
// Trim the string & check if empty before moving on.
216+
$extraVars = trim($extraVars);
217+
218+
if ($extraVars === '') {
219+
return $this;
220+
}
221+
222+
// JSON formatted string can be used for extra vars as is.
223+
// The value is automatically escaped & wrapped around single quotes from the Library's process.
224+
if (Str::isJsonFormatted($extraVars)) {
225+
$this->addOption('--extra-vars', $extraVars);
226+
227+
return $this;
228+
}
229+
213230
if (!str_contains($extraVars, '=')) {
214231
throw new InvalidArgumentException('The extra vars raw string should be in the "key=value" form.');
215232
}

Asm/Ansible/Utils/Str.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Asm\Ansible\Utils;
6+
7+
use JsonException;
8+
9+
class Str
10+
{
11+
/**
12+
* Validate the provided string is JSON formatted.
13+
*
14+
* Not JSON if result is not an object (stdClass).
15+
* Silent return false on exceptions e.g. Invalid/Incorrect encoding, Array depth more than 512 etc.
16+
*
17+
* @param string $value
18+
* @return bool
19+
*/
20+
public static function isJsonFormatted(string $value): bool
21+
{
22+
try {
23+
return is_object(json_decode($value, false, 512, JSON_THROW_ON_ERROR));
24+
} catch (JsonException) {
25+
return false;
26+
}
27+
}
28+
}

Tests/Asm/Ansible/Command/AnsiblePlaybookTest.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,14 +801,21 @@ public function testExtraVars(): void
801801
//$playbookFile = $this->getSamplesPathFor(AnsiblePlaybook::class) . '/playbook1.yml';
802802

803803
$tests = [
804+
// Test empty strings (with & without spaces).
804805
[
805806
'input' => '',
806807
'expect' => false,
807808
],
809+
[
810+
'input' => ' ',
811+
'expect' => false,
812+
],
813+
// Test empty array.
808814
[
809815
'input' => [],
810816
'expect' => false,
811817
],
818+
// Test Arrays
812819
[
813820
'input' => ['key' => 'value'],
814821
'expect' => '--extra-vars=key=value',
@@ -817,6 +824,12 @@ public function testExtraVars(): void
817824
'input' => ['key1' => 'value1', 'key2' => 'value2'],
818825
'expect' => '--extra-vars=key1=value1 key2=value2',
819826
],
827+
// Test valid JSON.
828+
[
829+
'input' => '{ "key1": "value1", "key2": "value2" }',
830+
'expect' => '--extra-vars={ "key1": "value1", "key2": "value2" }',
831+
],
832+
// Test key value string.
820833
[
821834
'input' => 'key=value',
822835
'expect' => '--extra-vars=key=value',
@@ -854,7 +867,8 @@ public function testExtraVars(): void
854867

855868
$tests = [
856869
'string without equals',
857-
new DateTime()
870+
'{ key1: "value1" }', // Invalid JSON syntax (missing " from key1) which would trigger string without `=`.
871+
new DateTime() // Invalid type
858872
];
859873

860874
foreach ($tests as $input) {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Asm\Ansible\Utils;
6+
7+
use PHPUnit\Framework\TestCase;
8+
9+
/**
10+
* @group utils
11+
*/
12+
class StrTest extends TestCase
13+
{
14+
/**
15+
* Assert valid JSON string is correctly checked.
16+
*
17+
* @return void
18+
*/
19+
public function testJsonWithValidFormat(): void
20+
{
21+
$value = '{ "key1": "value1" }';
22+
23+
$this->assertTrue(Str::isJsonFormatted($value));
24+
}
25+
26+
/**
27+
* Assert string is not valid JSON.
28+
*
29+
* @return void
30+
*/
31+
public function testStringIsNotJson(): void
32+
{
33+
$value = 'something';
34+
35+
$this->assertFalse(Str::isJsonFormatted($value));
36+
}
37+
}

0 commit comments

Comments
 (0)