Skip to content

SEC-2816: Fix/avoid tracked dependencies - #25

Merged
JojoVes merged 11 commits into
mainfrom
fix/avoid-tracked-dependencies
May 4, 2026
Merged

JojoVes merged 11 commits into
mainfrom
fix/avoid-tracked-dependencies

Conversation

@adam-vessey

@adam-vessey adam-vessey commented Apr 30, 2026 •

Copy link
Copy Markdown

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced export operations with selective filtering capabilities based on UUID and entity type parameters in batch configurations
  • Performance Improvements

    • Optimized memory efficiency during batch export processing through lazy entity iteration instead of pre-loading all entities into memory
    • Improved dependency resolution and export performance through optimized storage instance caching
    • Enhanced context propagation for better control over export behavior

@adam-vessey adam-vessey added the patch Backwards compatible bug fixes. label Apr 30, 2026
@coderabbitai

coderabbitai Bot commented Apr 30, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

@adam-vessey has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 37 minutes and 21 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5a9d56b7-75c8-4218-9832-c1437a1187e8

📥 Commits

Reviewing files that changed from the base of the PR and between 3114b83 and 979e278.

📒 Files selected for processing (2)
  • src/DependencyResolver/ImportQueueResolver.php
  • src/Form/ContentExportTrait.php
📝 Walkthrough

Walkthrough

The PR extends method signatures across dependency resolvers, export managers, and forms to accept and propagate an optional serializer_context parameter. It adds batch metadata (uuids and entity_types) to export configuration and refactors entity export processing from array-based to iterator-based approach with lazy evaluation.

Changes

Cohort / File(s) Summary
Serializer Context Integration
src/ContentSyncManager.php, src/DependencyResolver/ContentSyncResolverInterface.php, src/DependencyResolver/ExportQueueResolver.php, src/DependencyResolver/ImportQueueResolver.php
Extended method signatures to accept optional serializer_context parameter and forward it through resolver chains. ExportQueueResolver adds depth-tracking and conditional entity-type pruning logic when batch_info is present. ImportQueueResolver accepts the parameter but does not yet forward it to depthFirstSearch.
Export Configuration and Batch Metadata
src/Drush/Commands/ContentSyncCommands.php, src/Form/ContentExportTrait.php
Added batch_info array (containing parsed uuids and entity_types) to export batch configuration. Refined batch logic validation to check serializer_context['batch_info'] shape and propagate context into generateExportQueue instead of calling without context.
Entity Export Processing Refactoring
src/Form/ContentExportForm.php
Replaced array-based $entities_list construction with a new private entityGenerator(bool $access_check) method that lazily yields entity pairs. Updated submitForm and snapshot to pass iterators instead of arrays to generateExportBatch.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • chrismacdonaldw

Poem

🐰 Through resolvers deep, the context flows so free,
Each UUID batched, each entity decree,
From arrays turned to streams of lazy grace,
The export dance finds its rightful pace! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main objective of the changeset, which focuses on fixing or avoiding tracked dependencies through modifications to the dependency resolver logic.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/avoid-tracked-dependencies

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 37 minutes and 21 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@adam-vessey adam-vessey changed the title Fix/avoid tracked dependencies SEC-2816: Fix/avoid tracked dependencies Apr 30, 2026
…e time.

Still requires all of any particular type in an array; however, such should
still be smaller than the combined array.
Should reduce the risk of malfunction should other module not be
updated to provide 'batch_info' accordingly.
Analogous to the previous `!empty($entities_list)` checks.
Had overlooked the different value being provided in the two locations.
Comment thread src/DependencyResolver/ImportQueueResolver.php
else {
$activeStorage = new ContentDatabaseStorage(\Drupal::database(), 'cs_db_snapshot');
$entity = $activeStorage->cs_read($identifier);
$this->activeStorage ??= new ContentDatabaseStorage(\Drupal::database(), 'cs_db_snapshot');

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor optimization; only instantiating once per instance.

... could possibly go further, to wrap in a service? But yeah, let's not get too crazy in terms of refactoring.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The snapshotting side, where it was building out the huge array, which was turned into a generator (and DRY'd up slightly).

@adam-vessey
adam-vessey marked this pull request as ready for review May 1, 2026 15:35

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/DependencyResolver/ImportQueueResolver.php (1)

117-120: ⚡ Quick win

Forward serializer_context from the import entry point.

resolve() now advertises array $serializer_context = [], but it still drops that value before the first DFS call. That leaves the new parameter as dead API and makes the import resolver diverge from ExportQueueResolver::resolve(), which already forwards its context.

♻️ Suggested change
  public function resolve(array $normalized_entities, $visited = [], array $serializer_context = []) {
    $visited = [];
    foreach ($normalized_entities as $identifier => $entity) {
-      $this->depthFirstSearch($visited, [$identifier], $normalized_entities);
+      $this->depthFirstSearch($visited, [$identifier], $normalized_entities, $serializer_context);
    }
    // Reverse the array to adjust it to an array_pop-driven iterator.
    return array_reverse($visited);
  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/DependencyResolver/ImportQueueResolver.php` around lines 117 - 120, The
resolve() method in ImportQueueResolver drops the passed $serializer_context and
resets $visited before calling depthFirstSearch, so the new parameter is unused;
update resolve() to stop discarding $serializer_context and forward it into
depthFirstSearch (and any downstream calls) similar to
ExportQueueResolver::resolve(), and avoid reinitializing $visited unnecessarily
so depthFirstSearch($visited, [$identifier], $normalized_entities,
$serializer_context) (or the appropriate parameter order used by
depthFirstSearch) receives the context.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Drush/Commands/ContentSyncCommands.php`:
- Around line 441-444: The current code always sets 'batch_info' to
['uuids'=>[], 'entity_types'=>[]] which makes
ContentExportTrait::processContentExportFiles() think exports are filtered;
update the assembly of the payload in ContentSyncCommands.php so that
'batch_info' is only included when at least one of $options['uuids'] or
$options['entity-types'] is provided (i.e., build $batch_info only if those
arrays are non-empty and otherwise omit the 'batch_info' key entirely);
reference the existing 'batch_info' array in this diff and ensure the change
preserves behavior for the filtered export path and lets --include-dependencies
run for unfiltered exports.

In `@src/Form/ContentExportTrait.php`:
- Around line 244-256: The code reads
$serializer_context['include_dependencies'] directly which can be undefined in
ContentExportForm::submitForm() and snapshot(), causing notices; update the
conditional in ContentExportTrait to guard that access (use
!empty($serializer_context['include_dependencies']) or isset+truthy check)
before evaluating the rest of the expression so the branch only runs when
include_dependencies is present and truthy, leaving the remaining checks
(batch_info, uuids, entity_types) unchanged.

---

Nitpick comments:
In `@src/DependencyResolver/ImportQueueResolver.php`:
- Around line 117-120: The resolve() method in ImportQueueResolver drops the
passed $serializer_context and resets $visited before calling depthFirstSearch,
so the new parameter is unused; update resolve() to stop discarding
$serializer_context and forward it into depthFirstSearch (and any downstream
calls) similar to ExportQueueResolver::resolve(), and avoid reinitializing
$visited unnecessarily so depthFirstSearch($visited, [$identifier],
$normalized_entities, $serializer_context) (or the appropriate parameter order
used by depthFirstSearch) receives the context.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 48c43212-bb8d-4f08-84cf-45f7c505fa11

📥 Commits

Reviewing files that changed from the base of the PR and between a3b7659 and 3114b83.

📒 Files selected for processing (7)
  • src/ContentSyncManager.php
  • src/DependencyResolver/ContentSyncResolverInterface.php
  • src/DependencyResolver/ExportQueueResolver.php
  • src/DependencyResolver/ImportQueueResolver.php
  • src/Drush/Commands/ContentSyncCommands.php
  • src/Form/ContentExportForm.php
  • src/Form/ContentExportTrait.php

Comment thread src/Drush/Commands/ContentSyncCommands.php
Comment thread src/Form/ContentExportTrait.php
Comment thread src/DependencyResolver/ExportQueueResolver.php
Comment thread src/DependencyResolver/ExportQueueResolver.php
Comment thread src/DependencyResolver/ImportQueueResolver.php
Comment thread src/ContentSyncManager.php
@JojoVes
JojoVes merged commit 58fea76 into main May 4, 2026
1 of 2 checks passed
@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown

Tag generated by PR: v3.1.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

patch Backwards compatible bug fixes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants