Skip to content

Commit

Permalink
upload: Add topological_topics as a generator
Browse files Browse the repository at this point in the history
Add recursive helper generator functions to iterate
topologically through topics, and use it in some key
places. Also detect cycles in the topic graph.
  • Loading branch information
jerry-skydio committed Mar 12, 2024
1 parent 8b3358d commit 30b1499
Showing 1 changed file with 31 additions and 2 deletions.
33 changes: 31 additions & 2 deletions revup/topic_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,21 @@ class Topic:
# Reviews for this topic, keyed by base branch
reviews: Dict[str, Review] = field(default_factory=dict)

def depth_first_iter(self) -> Iterator[Topic]:
for t in self.depth_first_iter_helper(set()):
yield t

def depth_first_iter_helper(self, seen: Set[str]) -> Iterator[Topic]:
if self.name in seen:
raise RevupUsageException(
f'Unexpected relative topic cycle at "{self.name}" chain includes {seen}'
)
seen.add(self.name)
if self.relative_topic:
for t in self.relative_topic.depth_first_iter_helper(seen):
yield t
yield self


@dataclass
class TopicStack:
Expand Down Expand Up @@ -234,10 +249,24 @@ def all_reviews_iter(self) -> Iterator[Tuple[str, Topic, str, Review]]:
"""
One liner for common iteration pattern to reduce indentation a bit.
"""
for name, topic in self.topics.items():
for name, topic in self.topological_topics():
for base_branch, review in topic.reviews.items():
yield name, topic, base_branch, review

def topological_topics(self) -> Iterator[Tuple[str, Topic]]:
"""
Iterate through all topics one at a time with the requirement that any topic must always
come after a topic it is relative to.
"""
seen: Set[str] = set()
for _, topic in self.topics.items():
for t in topic.depth_first_iter():
if t.name in seen:
# If this topic has been seen, then all in the chain must have been seen
break
seen.add(t.name)
yield t.name, t

def parse_commit_tags(self, commit_msg: str) -> Tuple[Dict[str, Set[str]], str]:
"""
Parse all commit tags in the commit message and return them in a dict, as well as
Expand Down Expand Up @@ -548,7 +577,7 @@ async def populate_reviews(
await self.populate_relative_reviews(uploader)

async def populate_relative_reviews(self, uploader: str) -> None:
for name, topic in list(self.topics.items()):
for name, topic in self.topological_topics():
if topic.relative_topic:
if len(topic.tags[TAG_BRANCH]) == 0:
topic.tags[TAG_BRANCH].update(topic.relative_topic.tags[TAG_BRANCH])
Expand Down

0 comments on commit 30b1499

Please sign in to comment.