fix MoU-milestone-hunting to be automatic
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 5 Jul 2022 10:57:05 +0000 (11:57 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 5 Jul 2022 10:57:05 +0000 (11:57 +0100)
(no need at all to have a manual field)
the top-level root task represents the Grant itself and is *not* itself
a sub-task.

src/budget_sync/budget_graph.py
src/budget_sync/write_budget_markdown.py

index 3fa2d72bfce8af431377f490da949094aea9f457..cf4fbc07b9cc046307790e28cc1b6d62826b9001 100644 (file)
@@ -328,7 +328,6 @@ class Node:
         self.milestone_str = bug.cf_nlnet_milestone
         if self.milestone_str == "---":
             self.milestone_str = None
-        self.is_in_nlnet_mou = bug.cf_is_in_nlnet_mou2 == "Yes"
 
     @property
     def status(self) -> BugStatus:
@@ -453,6 +452,16 @@ class Node:
                 self._raise_loop_error()
         return retval
 
+    @cached_property
+    def is_in_nlnet_mou(self):
+        """returns true if this bugreport is a child of the top-level milestone.
+        it does *not* return true for the top-level bugreport itself because
+        only the immediate child-nodes comprise the MoU.
+        """
+        if self.parent is None:
+            return False
+        return self.parent == self.root
+
     @cached_property
     def closest_bug_in_mou(self) -> Optional["Node"]:
         """returns the closest bug that is in a NLNet MoU, searching only in
@@ -742,9 +751,10 @@ class BudgetGraph:
                             node.bug.id, node.milestone.identifier,
                             node.milestone.canonical_bug_id
                         ))
-                elif not node.is_in_nlnet_mou:
-                    errors.append(BudgetGraphRootWithMilestoneNotInMoU(
-                        node.bug.id, node.milestone_str))
+                # the root level bugs are not themselves "the child MoU list"
+                #elif not node.is_in_nlnet_mou:
+                #    errors.append(BudgetGraphRootWithMilestoneNotInMoU(
+                #        node.bug.id, node.milestone_str))
         except BudgetGraphBaseError as e:
             errors.append(e)
 
@@ -768,11 +778,12 @@ class BudgetGraph:
             if node.milestone_str is None:
                 errors.append(BudgetGraphInMoUWithoutMilestone(node.bug.id,
                                                                root.bug.id))
-            elif node.parent is not None and \
-                    not node.parent.is_in_nlnet_mou:
-                errors.append(BudgetGraphInMoUButParentNotInMoU(
-                    node.bug.id, node.parent.bug.id, root.bug.id,
-                    node.milestone_str))
+            # don't consider the top-level root to be part of the MoU
+            #elif node.parent is not None and \
+            #        not node.parent.is_in_nlnet_mou:
+            #    errors.append(BudgetGraphInMoUButParentNotInMoU(
+            #        node.bug.id, node.parent.bug.id, root.bug.id,
+            #        node.milestone_str))
 
         if node.budget_excluding_subtasks < 0 \
                 or node.budget_including_subtasks < 0:
index 8c1d096262c691f1701b2e3ae7e61e073ba947dd..757bdac222cd6f5639493f02755aa15e6153ed4e 100644 (file)
@@ -76,6 +76,18 @@ class MarkdownWriter:
         summary = markdown_escape(node.bug.summary)
         print(f"* [Bug #{node.bug.id}]({node.bug_url}):\n  {summary}",
               file=self.buffer)
+        closest = node.closest_bug_in_mou
+        if closest is node:
+            print(f"    * this task is an MoU Milestone",
+                  file=self.buffer)
+        elif closest is not None:
+            print(f"    * this task is part of MoU milestone\n"
+                  f"      [Bug #{closest.bug.id}]({closest.bug_url})",
+                  file=self.buffer)
+        elif payment is not None: # only report this if there's a payment
+            print(f"    * neither this task nor any parent tasks are in "
+                  f"the MoU",
+                  file=self.buffer)
         if payment is not None:
             if node.fixed_budget_excluding_subtasks \
                     != node.budget_excluding_subtasks:
@@ -97,18 +109,6 @@ class MarkdownWriter:
             else:
                 print(f"    * &euro;{payment.amount} which is the total amount",
                       file=self.buffer)
-            closest = node.closest_bug_in_mou
-            if closest is node:
-                print(f"    * this task is in the MoU",
-                      file=self.buffer)
-            elif closest is not None:
-                print(f"    * the closest parent task which is in the MoU is\n"
-                      f"      [Bug #{closest.bug.id}]({closest.bug_url})",
-                      file=self.buffer)
-            else:
-                print(f"    * neither this task nor any parent tasks are in "
-                      f"the MoU",
-                      file=self.buffer)
 
 
 def _markdown_for_person(person: Person,