From 15a709b7ce6e766538bb918836e58f7911718ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20B=C3=B6sing?= <2189546+boesing@users.noreply.github.com> Date: Tue, 20 Aug 2024 15:42:50 +0200 Subject: [PATCH 1/2] feature: replace dependabot with renovate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com> --- .github/dependabot.yml | 16 ---------------- .github/workflows/auto-merge-dependabot.yml | 21 --------------------- renovate.json | 6 ++++++ 3 files changed, 6 insertions(+), 37 deletions(-) delete mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/auto-merge-dependabot.yml create mode 100644 renovate.json diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 26b5fe0..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,16 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - labels: - - "dependency update" - - - package-ecosystem: "composer" - directory: "/" - schedule: - interval: "weekly" - versioning-strategy: increase-if-necessary - labels: - - "dependency update" diff --git a/.github/workflows/auto-merge-dependabot.yml b/.github/workflows/auto-merge-dependabot.yml deleted file mode 100644 index 873a7fe..0000000 --- a/.github/workflows/auto-merge-dependabot.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: "Auto merge dependabot bumps" - -on: - workflow_run: - types: - - completed - workflows: - - "Continuous Integration" - -jobs: - merge-me: - name: Merge me! - runs-on: ubuntu-latest - - steps: - - name: Merge me! - if: ${{ github.event.workflow_run.conclusion == 'success' }} - uses: ridedott/merge-me-action@v2.10.83 - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PRESET: DEPENDABOT_MINOR diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..3a1050f --- /dev/null +++ b/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "local>boesing/.github:renovate-config" + ] +} \ No newline at end of file From 62d7ffa6809306568c9987f3d99392a54f7d116d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20B=C3=B6sing?= <2189546+boesing@users.noreply.github.com> Date: Tue, 22 Oct 2024 23:59:58 +0200 Subject: [PATCH 2/2] feature: allow items to be in multiple groups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com> --- src/Map.php | 29 +++++++++++++++-------------- src/MapInterface.php | 4 ++-- src/OrderedList.php | 29 +++++++++++++++-------------- src/OrderedListInterface.php | 4 ++-- tests/GenericMapTest.php | 13 +++++++++++++ tests/GenericOrderedListTest.php | 13 +++++++++++++ 6 files changed, 60 insertions(+), 32 deletions(-) diff --git a/src/Map.php b/src/Map.php index d824b59..d42c9ea 100644 --- a/src/Map.php +++ b/src/Map.php @@ -20,6 +20,7 @@ use function array_values; use function asort; use function implode; +use function is_array; use function sprintf; use function strcmp; use function uasort; @@ -375,16 +376,10 @@ public function partition(callable $callback): array return [$instance1, $instance2]; } - /** - * @template TGroup of non-empty-string - * @psalm-param callable(TValue):TGroup $callback - * - * @psalm-return MapInterface> - */ public function group(callable $callback): MapInterface { /** - * @psalm-var MapInterface> $groups + * @psalm-var MapInterface> $groups */ $groups = new GenericMap([]); @@ -393,15 +388,21 @@ public function group(callable $callback): MapInterface * @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the * value here. */ - $groupIdentifier = $callback($value); - try { - $group = $groups->get($groupIdentifier); - } catch (OutOfBoundsException) { - $group = clone $this; - $group->data = []; + $groupIdentifiers = $callback($value); + if (! is_array($groupIdentifiers)) { + $groupIdentifiers = [$groupIdentifiers]; } - $groups = $groups->put($groupIdentifier, $group->put($key, $value)); + foreach ($groupIdentifiers as $groupIdentifier) { + try { + $group = $groups->get($groupIdentifier); + } catch (OutOfBoundsException) { + $group = clone $this; + $group->data = []; + } + + $groups = $groups->put($groupIdentifier, $group->put($key, $value)); + } } return $groups; diff --git a/src/MapInterface.php b/src/MapInterface.php index 7661bb2..98a7553 100644 --- a/src/MapInterface.php +++ b/src/MapInterface.php @@ -215,10 +215,10 @@ public function partition(callable $callback): array; /** * Groups the items of this object by using the callback. * - * @template TGroup of non-empty-string + * @template TGroup of non-empty-string|non-empty-list * @psalm-param callable(TValue):TGroup $callback * - * @psalm-return MapInterface> + * @psalm-return MapInterface> */ public function group(callable $callback): MapInterface; diff --git a/src/OrderedList.php b/src/OrderedList.php index 3fe4ba3..c4a5868 100644 --- a/src/OrderedList.php +++ b/src/OrderedList.php @@ -22,6 +22,7 @@ use function assert; use function hash; use function implode; +use function is_array; use function is_callable; use function serialize; use function sort; @@ -367,30 +368,30 @@ public function partition(callable $callback): array return [$instance1, $instance2]; } - /** - * @template TGroup of non-empty-string - * @psalm-param callable(TValue):TGroup $callback - * - * @psalm-return MapInterface> - */ public function group(callable $callback): MapInterface { - /** @var MapInterface> $groups */ + /** @var MapInterface> $groups */ $groups = new GenericMap([]); foreach ($this as $value) { /** * @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the * value here. */ - $groupName = $callback($value); - if (! $groups->has($groupName)) { - $groups = $groups->put($groupName, new GenericOrderedList([$value])); - continue; + $groupNames = $callback($value); + if (! is_array($groupNames)) { + $groupNames = [$groupNames]; } - $existingGroup = $groups->get($groupName); - $existingGroup = $existingGroup->add($value); - $groups = $groups->put($groupName, $existingGroup); + foreach ($groupNames as $groupName) { + if (! $groups->has($groupName)) { + $groups = $groups->put($groupName, new GenericOrderedList([$value])); + continue; + } + + $existingGroup = $groups->get($groupName); + $existingGroup = $existingGroup->add($value); + $groups = $groups->put($groupName, $existingGroup); + } } return $groups; diff --git a/src/OrderedListInterface.php b/src/OrderedListInterface.php index 53558ff..b5349f4 100644 --- a/src/OrderedListInterface.php +++ b/src/OrderedListInterface.php @@ -182,10 +182,10 @@ public function partition(callable $callback): array; /** * Groups the items by using the callback. * - * @template TGroup of non-empty-string + * @template TGroup of non-empty-string|non-empty-list * @psalm-param callable(TValue):TGroup $callback * - * @psalm-return MapInterface> + * @psalm-return MapInterface> */ public function group(callable $callback): MapInterface; diff --git a/tests/GenericMapTest.php b/tests/GenericMapTest.php index a595e55..9678180 100644 --- a/tests/GenericMapTest.php +++ b/tests/GenericMapTest.php @@ -736,6 +736,19 @@ public function testWillGroupValuesToNewInstancesOfInitialInstance(): void self::assertEquals($object2, $b->get('bar')); } + public function testWillGroupValueIntoMultipleGroups(): void + { + $map = new GenericMap([ + 'foo' => $object1 = new GenericObject(1), + ]); + + $grouped = $map->group(fn () => ['a', 'b']); + self::assertTrue($grouped->has('a')); + self::assertTrue($grouped->has('b')); + self::assertTrue($grouped->get('a')->contains($object1)); + self::assertTrue($grouped->get('b')->contains($object1)); + } + /** * @template T * @psalm-param array $elements diff --git a/tests/GenericOrderedListTest.php b/tests/GenericOrderedListTest.php index 09ab77f..a2357c3 100644 --- a/tests/GenericOrderedListTest.php +++ b/tests/GenericOrderedListTest.php @@ -1048,6 +1048,19 @@ public function testWillGroupValuesToNewInstancesOfInitialInstance(): void self::assertEquals($object2, $b->at(0)); } + public function testWillGroupValueIntoMultipleGroups(): void + { + $list = new GenericOrderedList([ + $object1 = new GenericObject(1), + ]); + + $grouped = $list->group(fn () => ['a', 'b']); + self::assertTrue($grouped->has('a')); + self::assertTrue($grouped->has('b')); + self::assertTrue($grouped->get('a')->contains($object1)); + self::assertTrue($grouped->get('b')->contains($object1)); + } + /** * @template T * @psalm-param list $data