From adaa0b60bbf9d4307936dbb8f2284705c82fdc76 Mon Sep 17 00:00:00 2001 From: Petr Chromec Date: Tue, 4 Aug 2026 08:36:41 +0200 Subject: [PATCH] Fix generated GPBMetadata for php --- CHANGELOG.md | 5 +++++ README.md | 9 +++++++++ buf.gen.yaml | 9 +++++++++ composer.json | 3 ++- gen/csharp/Core.cs | 2 +- gen/php/Feather/Contracts/Core/V1/Box.php | 2 +- gen/php/Feather/Contracts/Core/V1/CorrelationId.php | 2 +- gen/php/Feather/Contracts/Core/V1/Error.php | 2 +- gen/php/Feather/Contracts/Core/V1/Instance.php | 2 +- .../Feather/Contracts/Core/V1/SerializedForChunking.php | 2 +- gen/php/Feather/Contracts/Core/V1/Spot.php | 2 +- gen/php/Feather/Contracts/Core/V1/Timestamp.php | 2 +- .../Feather/Contracts/Core/V1}/Core.php | 4 ++-- 13 files changed, 35 insertions(+), 11 deletions(-) rename gen/php/{Feather/Contracts/Core/V1/GPBMetadata => GPBMetadata/Feather/Contracts/Core/V1}/Core.php (89%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a622bb..ffc43ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +### Fixed +- Pinned the PHP `php_metadata_namespace` to the standard protoc convention `GPBMetadata\Feather\Contracts\Core\V1` (instead of managed mode's `Feather\Contracts\Core\V1\GPBMetadata` default), so downstream contracts generated without managed mode can load the metadata class. + +### Changed +- Added a `GPBMetadata\` PSR-4 autoload entry in `composer.json` for the relocated PHP metadata class. ## 1.2.0 - 2026-07-31 ### Changed diff --git a/README.md b/README.md index a64505c..cff8486 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,15 @@ Common flags: `no-lint`, `no-clean` to skip the respective steps. buf push # publishes buf.build/feathertools/contracts ``` +### Managed mode + +Buf can decide the generated namespaces two ways, controlled in [`buf.gen.yaml`](buf.gen.yaml): + +- **Managed mode ON** (used here) — namespaces are **derived from the Protobuf package** and injected at generation time, so the `.proto` stays free of language-specific options. This is Buf's idiomatic default and the right choice when the package (`feather.contracts.core.v1`) already maps cleanly onto the desired namespaces (`Feather.Contracts.Core.V1`, `Feather\Contracts\Core\V1`). +- **Managed mode OFF** — namespaces come from `option` lines written **inside the `.proto`** (or plain package-derived protoc defaults). Choose this only when you need a namespace scheme the package can't produce (e.g. a `Context.Contracts.System` layout that intentionally differs from the package path). + +This repository uses **managed mode ON** with a single override: `php_metadata_namespace` is pinned to the standard protoc convention `GPBMetadata\` (rather than managed mode's `\GPBMetadata` default). This keeps the PHP metadata class name compatible with downstream contracts that import `core.proto` and are generated **without** managed mode. **Any project reusing these contracts should follow the same idea**: prefer managed mode on, and only add overrides when a name must interoperate with an external convention. + ### Proto conventions - File name: `lower_snake_case`; messages: `UpperCamelCase`; fields: `lower_snake_case`; enum values: `UPPER_SNAKE_CASE`. diff --git a/buf.gen.yaml b/buf.gen.yaml index 74b55be..abb0644 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -2,6 +2,15 @@ version: v2 clean: true managed: enabled: true # derive csharp_namespace / php_namespace from the package + override: + # Emit the PHP metadata class in the standard protoc convention + # (GPBMetadata\) instead of managed mode's default + # (\GPBMetadata). Downstream contracts generated without + # managed mode import core.proto and reference + # \GPBMetadata\Feather\Contracts\Core\V1\Core::initOnce(), so the emitted + # class name must match that convention. + - file_option: php_metadata_namespace + value: GPBMetadata\Feather\Contracts\Core\V1 plugins: # C# messages + gRPC - remote: buf.build/protocolbuffers/csharp diff --git a/composer.json b/composer.json index 85f9983..7418dc5 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,8 @@ }, "autoload": { "psr-4": { - "Feather\\Contracts\\Core\\V1\\": "gen/php/Feather/Contracts/Core/V1/" + "Feather\\Contracts\\Core\\V1\\": "gen/php/Feather/Contracts/Core/V1/", + "GPBMetadata\\": "gen/php/GPBMetadata/" } }, "archive": { diff --git a/gen/csharp/Core.cs b/gen/csharp/Core.cs index 5de1abd..6016d2a 100644 --- a/gen/csharp/Core.cs +++ b/gen/csharp/Core.cs @@ -37,7 +37,7 @@ static CoreReflection() { "B2NvbnRlbnQYASABKAxSB2NvbnRlbnRCsQEKHWNvbS5mZWF0aGVyLmNvbnRy", "YWN0cy5jb3JlLnYxQglDb3JlUHJvdG9QAaICA0ZDQ6oCGUZlYXRoZXIuQ29u", "dHJhY3RzLkNvcmUuVjHKAhlGZWF0aGVyXENvbnRyYWN0c1xDb3JlXFYx4gIl", - "RmVhdGhlclxDb250cmFjdHNcQ29yZVxWMVxHUEJNZXRhZGF0YeoCHEZlYXRo", + "R1BCTWV0YWRhdGFcRmVhdGhlclxDb250cmFjdHNcQ29yZVxWMeoCHEZlYXRo", "ZXI6OkNvbnRyYWN0czo6Q29yZTo6VjFiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, diff --git a/gen/php/Feather/Contracts/Core/V1/Box.php b/gen/php/Feather/Contracts/Core/V1/Box.php index 7f610dc..4dc9fec 100644 --- a/gen/php/Feather/Contracts/Core/V1/Box.php +++ b/gen/php/Feather/Contracts/Core/V1/Box.php @@ -34,7 +34,7 @@ class Box extends \Google\Protobuf\Internal\Message * } */ public function __construct($data = NULL) { - \Feather\Contracts\Core\V1\GPBMetadata\Core::initOnce(); + \GPBMetadata\Feather\Contracts\Core\V1\Core::initOnce(); parent::__construct($data); } diff --git a/gen/php/Feather/Contracts/Core/V1/CorrelationId.php b/gen/php/Feather/Contracts/Core/V1/CorrelationId.php index 4071ff8..8f034fc 100644 --- a/gen/php/Feather/Contracts/Core/V1/CorrelationId.php +++ b/gen/php/Feather/Contracts/Core/V1/CorrelationId.php @@ -29,7 +29,7 @@ class CorrelationId extends \Google\Protobuf\Internal\Message * } */ public function __construct($data = NULL) { - \Feather\Contracts\Core\V1\GPBMetadata\Core::initOnce(); + \GPBMetadata\Feather\Contracts\Core\V1\Core::initOnce(); parent::__construct($data); } diff --git a/gen/php/Feather/Contracts/Core/V1/Error.php b/gen/php/Feather/Contracts/Core/V1/Error.php index 6ebb3e2..0a2844c 100644 --- a/gen/php/Feather/Contracts/Core/V1/Error.php +++ b/gen/php/Feather/Contracts/Core/V1/Error.php @@ -34,7 +34,7 @@ class Error extends \Google\Protobuf\Internal\Message * } */ public function __construct($data = NULL) { - \Feather\Contracts\Core\V1\GPBMetadata\Core::initOnce(); + \GPBMetadata\Feather\Contracts\Core\V1\Core::initOnce(); parent::__construct($data); } diff --git a/gen/php/Feather/Contracts/Core/V1/Instance.php b/gen/php/Feather/Contracts/Core/V1/Instance.php index eb2e763..c4e78ff 100644 --- a/gen/php/Feather/Contracts/Core/V1/Instance.php +++ b/gen/php/Feather/Contracts/Core/V1/Instance.php @@ -29,7 +29,7 @@ class Instance extends \Google\Protobuf\Internal\Message * } */ public function __construct($data = NULL) { - \Feather\Contracts\Core\V1\GPBMetadata\Core::initOnce(); + \GPBMetadata\Feather\Contracts\Core\V1\Core::initOnce(); parent::__construct($data); } diff --git a/gen/php/Feather/Contracts/Core/V1/SerializedForChunking.php b/gen/php/Feather/Contracts/Core/V1/SerializedForChunking.php index 4e47e61..23ae65e 100644 --- a/gen/php/Feather/Contracts/Core/V1/SerializedForChunking.php +++ b/gen/php/Feather/Contracts/Core/V1/SerializedForChunking.php @@ -31,7 +31,7 @@ class SerializedForChunking extends \Google\Protobuf\Internal\Message * } */ public function __construct($data = NULL) { - \Feather\Contracts\Core\V1\GPBMetadata\Core::initOnce(); + \GPBMetadata\Feather\Contracts\Core\V1\Core::initOnce(); parent::__construct($data); } diff --git a/gen/php/Feather/Contracts/Core/V1/Spot.php b/gen/php/Feather/Contracts/Core/V1/Spot.php index d68c4dc..d1e8c77 100644 --- a/gen/php/Feather/Contracts/Core/V1/Spot.php +++ b/gen/php/Feather/Contracts/Core/V1/Spot.php @@ -34,7 +34,7 @@ class Spot extends \Google\Protobuf\Internal\Message * } */ public function __construct($data = NULL) { - \Feather\Contracts\Core\V1\GPBMetadata\Core::initOnce(); + \GPBMetadata\Feather\Contracts\Core\V1\Core::initOnce(); parent::__construct($data); } diff --git a/gen/php/Feather/Contracts/Core/V1/Timestamp.php b/gen/php/Feather/Contracts/Core/V1/Timestamp.php index 078be35..413ccb3 100644 --- a/gen/php/Feather/Contracts/Core/V1/Timestamp.php +++ b/gen/php/Feather/Contracts/Core/V1/Timestamp.php @@ -32,7 +32,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message * } */ public function __construct($data = NULL) { - \Feather\Contracts\Core\V1\GPBMetadata\Core::initOnce(); + \GPBMetadata\Feather\Contracts\Core\V1\Core::initOnce(); parent::__construct($data); } diff --git a/gen/php/Feather/Contracts/Core/V1/GPBMetadata/Core.php b/gen/php/GPBMetadata/Feather/Contracts/Core/V1/Core.php similarity index 89% rename from gen/php/Feather/Contracts/Core/V1/GPBMetadata/Core.php rename to gen/php/GPBMetadata/Feather/Contracts/Core/V1/Core.php index 1ab87c8..09d6210 100644 --- a/gen/php/Feather/Contracts/Core/V1/GPBMetadata/Core.php +++ b/gen/php/GPBMetadata/Feather/Contracts/Core/V1/Core.php @@ -3,7 +3,7 @@ # NO CHECKED-IN PROTOBUF GENCODE # source: feather/contracts/core/v1/core.proto -namespace Feather\Contracts\Core\V1\GPBMetadata; +namespace GPBMetadata\Feather\Contracts\Core\V1; class Core { @@ -16,7 +16,7 @@ public static function initOnce() { return; } $pool->internalAddGeneratedFile( - "\x0A\x95\x05\x0A\$feather/contracts/core/v1/core.proto\x12\x19feather.contracts.core.v1\"5\x0A\x05Error\x12\x12\x0A\x04name\x18\x01 \x01(\x09R\x04name\x12\x18\x0A\x07message\x18\x02 \x01(\x09R\x07message\"\x1F\x0A\x0DCorrelationId\x12\x0E\x0A\x02id\x18\x01 \x01(\x09R\x02id\"2\x0A\x09Timestamp\x12%\x0A\x0Eunix_timestamp\x18\x01 \x01(\x03R\x0DunixTimestamp\"2\x0A\x04Spot\x12\x12\x0A\x04zone\x18\x01 \x01(\x09R\x04zone\x12\x16\x0A\x06bucket\x18\x02 \x01(\x09R\x06bucket\"&\x0A\x08Instance\x12\x1A\x0A\x08instance\x18\x01 \x01(\x09R\x08instance\"{\x0A\x03Box\x12?\x0A\x08instance\x18\x01 \x01(\x0B2#.feather.contracts.core.v1.InstanceR\x08instance\x123\x0A\x04spot\x18\x02 \x01(\x0B2\x1F.feather.contracts.core.v1.SpotR\x04spot\"1\x0A\x15SerializedForChunking\x12\x18\x0A\x07content\x18\x01 \x01(\x0CR\x07contentB\xB1\x01\x0A\x1Dcom.feather.contracts.core.v1B\x09CoreProtoP\x01\xA2\x02\x03FCC\xAA\x02\x19Feather.Contracts.Core.V1\xCA\x02\x19Feather\\Contracts\\Core\\V1\xE2\x02%Feather\\Contracts\\Core\\V1\\GPBMetadata\xEA\x02\x1CFeather::Contracts::Core::V1b\x06proto3" + "\x0A\x95\x05\x0A\$feather/contracts/core/v1/core.proto\x12\x19feather.contracts.core.v1\"5\x0A\x05Error\x12\x12\x0A\x04name\x18\x01 \x01(\x09R\x04name\x12\x18\x0A\x07message\x18\x02 \x01(\x09R\x07message\"\x1F\x0A\x0DCorrelationId\x12\x0E\x0A\x02id\x18\x01 \x01(\x09R\x02id\"2\x0A\x09Timestamp\x12%\x0A\x0Eunix_timestamp\x18\x01 \x01(\x03R\x0DunixTimestamp\"2\x0A\x04Spot\x12\x12\x0A\x04zone\x18\x01 \x01(\x09R\x04zone\x12\x16\x0A\x06bucket\x18\x02 \x01(\x09R\x06bucket\"&\x0A\x08Instance\x12\x1A\x0A\x08instance\x18\x01 \x01(\x09R\x08instance\"{\x0A\x03Box\x12?\x0A\x08instance\x18\x01 \x01(\x0B2#.feather.contracts.core.v1.InstanceR\x08instance\x123\x0A\x04spot\x18\x02 \x01(\x0B2\x1F.feather.contracts.core.v1.SpotR\x04spot\"1\x0A\x15SerializedForChunking\x12\x18\x0A\x07content\x18\x01 \x01(\x0CR\x07contentB\xB1\x01\x0A\x1Dcom.feather.contracts.core.v1B\x09CoreProtoP\x01\xA2\x02\x03FCC\xAA\x02\x19Feather.Contracts.Core.V1\xCA\x02\x19Feather\\Contracts\\Core\\V1\xE2\x02%GPBMetadata\\Feather\\Contracts\\Core\\V1\xEA\x02\x1CFeather::Contracts::Core::V1b\x06proto3" , true); static::$is_initialized = true;