diff --git a/go-tests/go.mod b/go-tests/go.mod index 3671698b4..ea786454a 100644 --- a/go-tests/go.mod +++ b/go-tests/go.mod @@ -6,7 +6,7 @@ toolchain go1.24.4 require ( github.com/go-chi/chi/v5 v5.2.2 - github.com/platformsh/cli v0.0.0-20250512110214-68e4962f0990 + github.com/platformsh/cli v0.0.0-20250703103124-87b7ab372c7b github.com/stretchr/testify v1.10.0 golang.org/x/crypto v0.39.0 ) diff --git a/go-tests/go.sum b/go-tests/go.sum index c3a92c206..ac25c7eac 100644 --- a/go-tests/go.sum +++ b/go-tests/go.sum @@ -5,8 +5,8 @@ github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hH github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s= github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= -github.com/platformsh/cli v0.0.0-20250512110214-68e4962f0990 h1:0xJ3ftKO/9qB3KCMnGzEzKZizOEJgCGBfOQk1ts9szk= -github.com/platformsh/cli v0.0.0-20250512110214-68e4962f0990/go.mod h1:1OFXJCFPlXT4zSc1U/U3xSNh1UmuqOm9rz+FldYe8z8= +github.com/platformsh/cli v0.0.0-20250703103124-87b7ab372c7b h1:o0ykauvwRrRUKszPVLjaI2MaB9y276vlwYEaxzUfwXE= +github.com/platformsh/cli v0.0.0-20250703103124-87b7ab372c7b/go.mod h1:1OFXJCFPlXT4zSc1U/U3xSNh1UmuqOm9rz+FldYe8z8= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= diff --git a/go-tests/project_info_test.go b/go-tests/project_info_test.go index 9ab3417eb..f4caf17f7 100644 --- a/go-tests/project_info_test.go +++ b/go-tests/project_info_test.go @@ -81,4 +81,9 @@ git git@git.region-1.example.com:mock-project.git` // TODO --refresh should not be needed here assert.Equal(t, "New Title\n", f.Run("pro:info", "-p", projectID, "title", "--refresh")) + + // Test setting an attribute using dot notation + f.Run("pro:info", "-v", "-p", projectID, "attributes.foo", "bar") + // TODO --refresh should not be needed here + assert.Equal(t, "bar\n", f.Run("pro:info", "-p", projectID, "attributes.foo", "--refresh")) } diff --git a/src/Command/Project/ProjectInfoCommand.php b/src/Command/Project/ProjectInfoCommand.php index 9470bfa23..46ca02cde 100644 --- a/src/Command/Project/ProjectInfoCommand.php +++ b/src/Command/Project/ProjectInfoCommand.php @@ -113,7 +113,19 @@ protected function listProperties(array $properties): int protected function setProperty(string $property, string $value, Project $project, bool $noWait): int { - $type = $this->getType($property); + $isMap = str_contains($property, '.'); + if ($isMap) { + [$mapName, $mapKey] = explode('.', $property, 2); + $type = $this->getType($mapName . '.*'); + $currentMap = $project->getProperty($mapName) ?? []; + $currentValue = $currentMap[$mapKey] ?? null; + $update = [$mapName => [$mapKey => $value]]; + } else { + $type = $this->getType($property); + $currentValue = $project->getProperty($property); + $update = [$property => $value]; + } + if (!$type) { $this->stdErr->writeln("Property not writable: $property"); return 1; @@ -122,17 +134,18 @@ protected function setProperty(string $property, string $value, Project $project $value = false; } settype($value, $type); - $currentValue = $project->getProperty($property); + if ($currentValue === $value) { $this->stdErr->writeln( "Property $property already set as: " . $this->propertyFormatter->format($value, $property), ); return 0; + } $project->ensureFull(); - $result = $project->update([$property => $value]); + $result = $project->update($update); $this->stdErr->writeln(sprintf( 'Property %s set to: %s', $property, @@ -160,6 +173,7 @@ protected function getType(string $property): string|false 'description' => 'string', 'default_domain' => 'string', 'default_branch' => 'string', + 'attributes.*' => 'string', ]; return $writableProperties[$property] ?? false;