Plain is headed towards 1.0! Subscribe for development updates →

 1from plain.models import OperationalError, ProgrammingError
 2from plain.preflight import PreflightCheck, PreflightResult, register_check
 3from plain.runtime import settings
 4
 5from .bridge import get_flag_class
 6from .exceptions import FlagImportError
 7
 8
 9@register_check(name="flags.unused_flags")
10class CheckUnusedFlags(PreflightCheck):
11    """
12    Check for flags that are in the database, but no longer defined in code.
13
14    Only returns Info errors because it is valid to leave them if you're worried about
15    putting the flag back, but they should probably be deleted eventually.
16    """
17
18    def run(self) -> list[PreflightResult]:
19        # Import here to avoid circular import
20        from .models import Flag
21
22        errors = []
23
24        flag_names = Flag.query.all().values_list("name", flat=True)
25
26        try:
27            flag_names = set(flag_names)
28        except (ProgrammingError, OperationalError):
29            # The table doesn't exist yet
30            # (migrations probably haven't run yet),
31            # so we can't check it.
32            return errors
33
34        for flag_name in flag_names:
35            try:
36                get_flag_class(flag_name)
37            except FlagImportError:
38                errors.append(
39                    PreflightResult(
40                        fix=f"Flag {flag_name} is not used. Remove the flag from the database or define it in the {settings.FLAGS_MODULE} module.",
41                        warning=True,
42                        id="flags.unused_flags",
43                    )
44                )
45
46        return errors