Batch codemod call sites into reviewable pull requests

Agent buildMedium20 minGoogle and Meta style

Your task

Your company is removing a deprecated internal API used at about 4,000 call sites in a monorepo. A codemod agent (one that rewrites code by a fixed rule) migrates the mechanical sites in small pull requests per team and hands the rest to people.

Write plan_codemod_batches(call_sites, max_sites_per_pr): the rule your agent follows to turn the inventory into a migration plan.

  • call_sites (list of str): one entry per call site, written team:pattern, for example "payments:simple".
  • max_sites_per_pr (int): the most call sites one pull request may hold. A value of 0 or less means 1.
  • Return a list of plan entries, each written owner=<team>;rule=<rule>;sites=<count>.

Rules:

  1. Split each entry at its first : into team and pattern, exactly as written, with no trimming. An entry with no : is all team, with an empty pattern.
  2. The rule is the pattern itself if it is import, simple or wrapper. Any other pattern, the empty one included, gets the rule manual.
  3. Group the sites by team and rule, and count each group.
  4. Order the groups by the text team + "|" + rule, compared character by character. | sorts after every letter, digit, - and _, so team ab comes before team a.
  5. A manual group becomes one entry with its full count, whatever the cap: it is a review queue, not a pull request.
  6. Any other group is split into pull requests of max_sites_per_pr sites, full ones first, then the remainder.

Examples

plan_codemod_batches(call_sites: list[str], max_sites_per_pr: int) -> list[str]
Example 1
Inputplan_codemod_batches(["payments:simple", "payments:simple", "payments:simple", "search:dynamic"], 2)
Output["owner=payments;rule=simple;sites=2", "owner=payments;rule=simple;sites=1", "owner=search;rule=manual;sites=1"]
Example 2
Inputplan_codemod_batches(["core:generated", "core:reflection", "core:simple"], 10)
Output["owner=core;rule=manual;sites=2", "owner=core;rule=simple;sites=1"]
Example 3
Inputplan_codemod_batches(["search:simple", "payments:simple", "search:simple", "payments:wrapper", "search:dynamic"], 2)
Output["owner=payments;rule=simple;sites=1", "owner=payments;rule=wrapper;sites=1", "owner=search;rule=manual;sites=1", "owner=search;rule=simple;sites=2"]