From 2e8a18d181a685d40a67f81d50f9c9f0f48f28dd Mon Sep 17 00:00:00 2001 From: Deven Jahnke <10586846+devenjahnke@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:19:15 -0400 Subject: [PATCH 1/8] fix: Patch schema parsing logic for compatability with Streamz --- lib/avro/schema.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/avro/schema.php b/lib/avro/schema.php index f002f99..d305c22 100644 --- a/lib/avro/schema.php +++ b/lib/avro/schema.php @@ -334,7 +334,7 @@ static function real_parse($avro, $default_namespace=null, &$schemata=null) $extra_attributes = array_diff_key($avro, array_flip(self::$reserved_attrs)); if (self::is_primitive_type($type)) - return new AvroPrimitiveSchema($type, $logical_type, $extra_attributes, true); + return new AvroPrimitiveSchema($type, $logical_type, $extra_attributes, false); elseif (self::is_named_type($type)) { @@ -393,7 +393,7 @@ static function real_parse($avro, $default_namespace=null, &$schemata=null) $type)); } elseif (self::is_primitive_type($avro)) - return new AvroPrimitiveSchema($avro, null, [], true); + return new AvroPrimitiveSchema($avro, null, [], false); else throw new AvroSchemaParseException( sprintf('%s is not a schema we know about.', @@ -859,6 +859,11 @@ class AvroNamedSchema extends AvroSchema */ private $doc; + /** + * @var string + */ + const DEFAULT_ATTR = 'default'; + /** * @param string $type * @param AvroName $name @@ -893,6 +898,8 @@ public function to_avro() $avro[AvroSchema::NAMESPACE_ATTR] = $namespace; if (!is_null($this->doc)) $avro[AvroSchema::DOC_ATTR] = $this->doc; + if (array_key_exists(AvroNamedSchema::DEFAULT_ATTR, $this->extra_attributes)) + $avro[AvroNamedSchema::DEFAULT_ATTR] = $this->extra_attributes[AvroNamedSchema::DEFAULT_ATTR]; if (null !== $this->logical_type) { return array_merge($avro, array( self::LOGICAL_TYPE_ATTR => $this->logical_type From 835bda844b914784790a6546d67c5bd2f40c0a3e Mon Sep 17 00:00:00 2001 From: Deven Jahnke <10586846+devenjahnke@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:26:03 -0400 Subject: [PATCH 2/8] chore: replace flix-tech/avro-php with this fork --- composer.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/composer.json b/composer.json index 6e2f5be..647de45 100644 --- a/composer.json +++ b/composer.json @@ -8,6 +8,9 @@ "require-dev": { "phpunit/phpunit": "~8.5" }, + "replace": { + "flix-tech/avro-php": "5.0.2" + }, "suggest": { "ext-gmp": "Large integer support for 32-bit platforms.", "ext-zlib": "Zlib support for Deflate codec.", From 99bf354bd3114a5fc5c19d67a2251770ecf3ac92 Mon Sep 17 00:00:00 2001 From: Deven Jahnke <10586846+devenjahnke@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:37:04 -0400 Subject: [PATCH 3/8] fix: rename package --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 647de45..258f25b 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { - "name": "flix-tech/avro-php", - "description": "Avro schema encoder/decoder. Fork of rg/avro-php", + "name": "aryeo/avro-php", + "description": "Fork of flix-tech/avro-php to patch schema object functionality for compatability with Streamz ", "license": "Apache-2.0", "require": { "php": ">=7.4|>=8.0" From 75d83e167838d1959289913e7d16044eb244c17d Mon Sep 17 00:00:00 2001 From: Deven Jahnke <10586846+devenjahnke@users.noreply.github.com> Date: Tue, 25 Feb 2025 09:27:51 -0500 Subject: [PATCH 4/8] Remove enum default patch --- lib/avro/schema.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/avro/schema.php b/lib/avro/schema.php index d305c22..696a8b8 100644 --- a/lib/avro/schema.php +++ b/lib/avro/schema.php @@ -859,11 +859,6 @@ class AvroNamedSchema extends AvroSchema */ private $doc; - /** - * @var string - */ - const DEFAULT_ATTR = 'default'; - /** * @param string $type * @param AvroName $name @@ -898,8 +893,6 @@ public function to_avro() $avro[AvroSchema::NAMESPACE_ATTR] = $namespace; if (!is_null($this->doc)) $avro[AvroSchema::DOC_ATTR] = $this->doc; - if (array_key_exists(AvroNamedSchema::DEFAULT_ATTR, $this->extra_attributes)) - $avro[AvroNamedSchema::DEFAULT_ATTR] = $this->extra_attributes[AvroNamedSchema::DEFAULT_ATTR]; if (null !== $this->logical_type) { return array_merge($avro, array( self::LOGICAL_TYPE_ATTR => $this->logical_type From c3df70393282df5a627ea57452fe47e46843e9ae Mon Sep 17 00:00:00 2001 From: Deven Jahnke <10586846+devenjahnke@users.noreply.github.com> Date: Tue, 25 Feb 2025 09:30:47 -0500 Subject: [PATCH 5/8] Update composer replace version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 6bd5809..ef3b667 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ "phpunit/phpunit": "^10.5" }, "replace": { - "flix-tech/avro-php": "5.0.2" + "flix-tech/avro-php": "5.1.1" }, "suggest": { "ext-gmp": "Large integer support for 32-bit platforms.", From 7de482ee5b93f58d3c12911ef4267d60d3cda41f Mon Sep 17 00:00:00 2001 From: Deven Jahnke <10586846+devenjahnke@users.noreply.github.com> Date: Tue, 25 Feb 2025 09:58:03 -0500 Subject: [PATCH 6/8] feat: Add support for schema and field level tags --- lib/avro/schema.php | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/avro/schema.php b/lib/avro/schema.php index 2bc49a7..aceb2b7 100644 --- a/lib/avro/schema.php +++ b/lib/avro/schema.php @@ -183,6 +183,11 @@ class AvroSchema */ const TYPE_ATTR = 'type'; + /** + * @var string schema tags attribute name + */ + const TAGS_ATTR = 'tags'; + /** * @var string named schema name attribute name */ @@ -893,6 +898,8 @@ public function to_avro() $avro[AvroSchema::NAMESPACE_ATTR] = $namespace; if (!is_null($this->doc)) $avro[AvroSchema::DOC_ATTR] = $this->doc; + if (array_key_exists(AvroSchema::TAGS_ATTR, $this->extra_attributes)) + $avro[AvroSchema::TAGS_ATTR] = $this->extra_attributes[AvroSchema::TAGS_ATTR]; if (null !== $this->logical_type) { return array_merge($avro, array( self::LOGICAL_TYPE_ATTR => $this->logical_type @@ -1332,6 +1339,14 @@ static function parse_fields($field_data, $default_namespace, &$schemata) $has_default = true; } + $tags = null; + $has_tags = false; + if (array_key_exists(AvroField::TAGS_ATTR, $field)) + { + $tags = $field[AvroField::TAGS_ATTR]; + $has_tags = true; + } + if (in_array($name, $field_names)) throw new AvroSchemaParseException( sprintf("Field name %s is already in use", $name)); @@ -1346,7 +1361,7 @@ static function parse_fields($field_data, $default_namespace, &$schemata) $field_schema = self::subparse($type, $default_namespace, $schemata); $new_field = new AvroField($name, $field_schema, $is_schema_from_schemata, - $has_default, $default, $order, $doc, + $has_default, $default, $has_tags, $tags, $order, $doc, $logical_type, $precision, $scale); $field_names []= $name; $fields []= $new_field; @@ -1467,6 +1482,11 @@ class AvroField extends AvroSchema */ const SCALE_ATTR = 'scale'; + /** + * @var string + */ + const TAGS_ATTR = 'tags'; + /** * @var string */ @@ -1526,6 +1546,16 @@ private static function check_order_value($order) */ private $default; + /** + * @var boolean whether or no there is a tags value + */ + private $has_tags; + + /** + * @var string field tags value + */ + private $tags; + /** * @var string sort order of this field */ @@ -1569,7 +1599,7 @@ private static function check_order_value($order) * @todo Check validity of $order value */ public function __construct($name, $schema, $is_type_from_schemata, - $has_default, $default, $order=null, $doc=null, + $has_default, $default, $has_tags, $tags, $order=null, $doc=null, $logical_type=null, $precision=null, $scale=null) { if (!AvroName::is_well_formed_name($name)) @@ -1581,6 +1611,9 @@ public function __construct($name, $schema, $is_type_from_schemata, $this->has_default = $has_default; if ($this->has_default) $this->default = $default; + $this-has_tags = $has_tags; + if ($this->has_tags) + $this->tags = $tags; $this->check_order_value($order); $this->order = $order; $this->doc = $doc; @@ -1602,6 +1635,9 @@ public function to_avro() if ($this->has_default) $avro[AvroField::DEFAULT_ATTR] = $this->default; + if ($this->has_tags) + $avro[AvroField::TAGS_ATTR] = $this->tags; + if ($this->order) $avro[AvroField::ORDER_ATTR] = $this->order; From 605f338c2618ee1c9fdcb7c912ffff058ad91d12 Mon Sep 17 00:00:00 2001 From: Deven Jahnke <10586846+devenjahnke@users.noreply.github.com> Date: Tue, 25 Feb 2025 09:59:08 -0500 Subject: [PATCH 7/8] fix: typo --- lib/avro/schema.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/avro/schema.php b/lib/avro/schema.php index aceb2b7..2b8fcae 100644 --- a/lib/avro/schema.php +++ b/lib/avro/schema.php @@ -1611,7 +1611,7 @@ public function __construct($name, $schema, $is_type_from_schemata, $this->has_default = $has_default; if ($this->has_default) $this->default = $default; - $this-has_tags = $has_tags; + $this->has_tags = $has_tags; if ($this->has_tags) $this->tags = $tags; $this->check_order_value($order); From 1696ddc04bcdfdfecb10ac98c3192e7d45ea1826 Mon Sep 17 00:00:00 2001 From: Brian Sullivan Date: Mon, 19 Oct 2026 15:12:42 -0400 Subject: [PATCH 8/8] chore: gitlab migration --- .gitlab-ci.yml | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..957e5f3 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,76 @@ +# Tests aryeo/avro-php and publishes it to the Artifactory Composer repository. +# +# Branches run validation and the tests. A semver tag push (e.g. 1.1.1) runs the same +# checks, then packages the tagged source and publishes it. +# +# The job scripts come from the shared template. +include: + - project: vendor-platform/ci_cd/gitlab-ci-templates + ref: main + file: php-composer-package.yml + +stages: + - test + - package + - publish + +default: + tags: + - build + interruptible: true + +workflow: + rules: + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS + when: never + - if: $CI_COMMIT_BRANCH + - if: $CI_COMMIT_TAG + +validate: + stage: test + extends: .php-composer + script: + - composer validate --strict + +# GitHub runs these tests in an image that also builds the gmp and snappy extensions. The CI +# image has neither: LongEncodingTest skips its GMP tests (the library uses gmp only on 32-bit +# PHP), and the snappy codec cases in DataFileTest error until a PHP CI image includes snappy. +tests: + stage: test + extends: .php-tests + script: + # The tests write to these directories, as in the GitHub workflow. + - mkdir -p build/tmp build/share/test/schemas build/build/interop/data + - composer show -D + - vendor/bin/phpunit + +package: + stage: package + extends: .package + needs: [validate, tests] + rules: + - if: $CI_COMMIT_TAG =~ /^v?\d+\.\d+\.\d+$/ + +publish: + stage: publish + extends: .publish + needs: [package] + rules: + - if: $CI_COMMIT_TAG =~ /^v?\d+\.\d+\.\d+$/ + +# Publishes existing tags that predate the GitLab pipeline. Run a pipeline on master with +# BACKFILL_TAGS set, e.g. "1.0.0 1.1.0". Versions already in Artifactory are skipped. +backfill:package: + stage: package + extends: .backfill-package + needs: [] + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $BACKFILL_TAGS + +backfill:publish: + stage: publish + extends: .backfill-publish + needs: ["backfill:package"] + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $BACKFILL_TAGS