summaryrefslogtreecommitdiffstats
path: root/src/debputy/plugin/api/example_processing.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/debputy/plugin/api/example_processing.py')
-rw-r--r--src/debputy/plugin/api/example_processing.py99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/debputy/plugin/api/example_processing.py b/src/debputy/plugin/api/example_processing.py
new file mode 100644
index 0000000..3bde8c3
--- /dev/null
+++ b/src/debputy/plugin/api/example_processing.py
@@ -0,0 +1,99 @@
+import dataclasses
+from enum import Enum
+from typing import Set, Tuple, List, cast, Dict, Sequence
+
+from debputy.filesystem_scan import build_virtual_fs
+from debputy.plugin.api import VirtualPath
+from debputy.plugin.api.impl_types import (
+ AutomaticDiscardRuleExample,
+ PluginProvidedDiscardRule,
+)
+from debputy.util import _normalize_path
+
+
+class DiscardVerdict(Enum):
+ INCONSISTENT_CODE_KEPT = (
+ None,
+ "INCONSISTENT (code kept the path, but should have discarded)",
+ )
+ INCONSISTENT_CODE_DISCARDED = (
+ None,
+ "INCONSISTENT (code discarded the path, but should have kept it)",
+ )
+ KEPT = (False, "Kept")
+ DISCARDED_BY_CODE = (True, "Discarded (directly by the rule)")
+ DISCARDED_BY_DIRECTORY = (True, "Discarded (directory was discarded)")
+
+ @property
+ def message(self) -> str:
+ return cast("str", self.value[1])
+
+ @property
+ def is_consistent(self) -> bool:
+ return self.value[0] is not None
+
+ @property
+ def is_discarded(self) -> bool:
+ return self.value[0] is True
+
+ @property
+ def is_kept(self) -> bool:
+ return self.value[0] is False
+
+
+@dataclasses.dataclass(slots=True, frozen=True)
+class ProcessedDiscardRuleExample:
+ rendered_paths: Sequence[Tuple[VirtualPath, DiscardVerdict]]
+ inconsistent_paths: Set[VirtualPath]
+ # To avoid the parents being garbage collected
+ fs_root: VirtualPath
+
+
+def process_discard_rule_example(
+ discard_rule: PluginProvidedDiscardRule,
+ example: AutomaticDiscardRuleExample,
+) -> ProcessedDiscardRuleExample:
+ fs_root: VirtualPath = build_virtual_fs([p for p, _ in example.content])
+
+ actual_discarded: Dict[str, bool] = {}
+ expected_output = {
+ "/" + _normalize_path(p.path_name, with_prefix=False): v
+ for p, v in example.content
+ }
+ inconsistent_paths = set()
+ rendered_paths = []
+
+ for p in fs_root.all_paths():
+ parent = p.parent_dir
+ discard_carry_over = False
+ path_name = p.absolute
+ if parent and actual_discarded[parent.absolute]:
+ verdict = True
+ discard_carry_over = True
+ else:
+ verdict = discard_rule.should_discard(p)
+
+ actual_discarded[path_name] = verdict
+ expected = expected_output.get(path_name)
+ if expected is not None:
+ inconsistent = expected != verdict
+ if inconsistent:
+ inconsistent_paths.add(p)
+ else:
+ continue
+
+ if inconsistent:
+ if verdict:
+ verdict_code = DiscardVerdict.INCONSISTENT_CODE_DISCARDED
+ else:
+ verdict_code = DiscardVerdict.INCONSISTENT_CODE_KEPT
+ elif verdict:
+ if discard_carry_over:
+ verdict_code = DiscardVerdict.DISCARDED_BY_DIRECTORY
+ else:
+ verdict_code = DiscardVerdict.DISCARDED_BY_CODE
+ else:
+ verdict_code = DiscardVerdict.KEPT
+ rendered_paths.append((p, verdict_code))
+
+ return ProcessedDiscardRuleExample(rendered_paths, inconsistent_paths, fs_root)