|
17 | 17 | # limitations under the License. |
18 | 18 | """Checks needed to determine integrity of workflows.""" |
19 | 19 |
|
20 | | -from typing import Optional, Tuple |
| 20 | +from typing import List, Optional, Tuple, cast |
21 | 21 |
|
| 22 | +from renku.command.command_builder import inject |
22 | 23 | from renku.command.util import WARNING |
| 24 | +from renku.core.interface.plan_gateway import IPlanGateway |
23 | 25 | from renku.core.util import communication |
24 | 26 | from renku.domain_model.project_context import project_context |
| 27 | +from renku.domain_model.workflow.plan import AbstractPlan |
25 | 28 | from renku.infrastructure.gateway.activity_gateway import reindex_catalog |
26 | 29 |
|
27 | 30 |
|
@@ -58,3 +61,67 @@ def check_activity_catalog(fix, force, **_) -> Tuple[bool, Optional[str]]: |
58 | 61 | communication.info("Workflow metadata was rebuilt") |
59 | 62 |
|
60 | 63 | return True, None |
| 64 | + |
| 65 | + |
| 66 | +@inject.autoparams("plan_gateway") |
| 67 | +def check_modification_date(fix, plan_gateway: IPlanGateway, **_) -> Tuple[bool, Optional[str]]: |
| 68 | + """Check if all plans have modification date set for them. |
| 69 | +
|
| 70 | + Args: |
| 71 | + fix(bool): Whether to fix found issues. |
| 72 | + plan_gateway(IPlanGateway): Injected PlanGateway. |
| 73 | + _: keyword arguments. |
| 74 | +
|
| 75 | + Returns: |
| 76 | + Tuple[bool, Optional[str]]: Tuple of whether there are plans without modification date and a string of their IDs |
| 77 | + """ |
| 78 | + plans: List[AbstractPlan] = plan_gateway.get_all_plans() |
| 79 | + |
| 80 | + to_be_processed = [] |
| 81 | + for plan in plans: |
| 82 | + if not hasattr(plan, "date_modified") or plan.date_modified is None: |
| 83 | + to_be_processed.append(plan) |
| 84 | + |
| 85 | + if not to_be_processed: |
| 86 | + return True, None |
| 87 | + if not fix: |
| 88 | + ids = [plan.id for plan in to_be_processed] |
| 89 | + message = ( |
| 90 | + WARNING |
| 91 | + + "The following workflows have incorrect modification date (use 'renku doctor --fix' to fix them).:\n\t" |
| 92 | + + "\n\t".join(ids) |
| 93 | + ) |
| 94 | + return False, message |
| 95 | + |
| 96 | + fix_plan_dates(plans=to_be_processed, plan_gateway=plan_gateway) |
| 97 | + project_context.database.commit() |
| 98 | + communication.info("Workflow modification dates were fixed") |
| 99 | + |
| 100 | + return True, None |
| 101 | + |
| 102 | + |
| 103 | +def fix_plan_dates(plans: List[AbstractPlan], plan_gateway): |
| 104 | + """Set modification date on a list of plans and fix their creation date.""" |
| 105 | + processed = set() |
| 106 | + # NOTE: switch creation date for modification date |
| 107 | + for tail in plans: |
| 108 | + to_be_processed: List[AbstractPlan] = [] |
| 109 | + if tail not in processed: |
| 110 | + processed.add(tail) |
| 111 | + to_be_processed.append(tail) |
| 112 | + creation_date = tail.date_created |
| 113 | + plan = tail |
| 114 | + |
| 115 | + while plan.is_derivation(): |
| 116 | + plan = cast(AbstractPlan, plan_gateway.get_by_id(plan.derived_from)) |
| 117 | + creation_date = plan.date_created |
| 118 | + if plan not in processed: |
| 119 | + processed.add(plan) |
| 120 | + to_be_processed.append(plan) |
| 121 | + |
| 122 | + while to_be_processed: |
| 123 | + plan = to_be_processed.pop() |
| 124 | + plan.unfreeze() |
| 125 | + plan.date_modified = plan.date_created |
| 126 | + plan.date_created = creation_date |
| 127 | + plan.freeze() |
0 commit comments