about summary refs log tree commit diff stats
path: root/pkgs/by-name/up/update-vim-plugins/update_vim_plugins/cleanup.py
blob: fd313ed00b872cd7f4840b23431eef159eccc40d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
from cleo.commands.command import Command
from cleo.helpers import argument

from .helpers import read_manifest_to_spec, read_blacklist_to_spec, write_manifest_from_spec


class CleanUpCommand(Command):
    name = "cleanup"
    description = "Clean up manifest"
    arguments = [argument("plug_dir", description="Path to the plugin directory", optional=False)]

    def handle(self):
        """Main command function"""

        plug_dir = self.argument("plug_dir")
        self.line("<comment>Checking manifest file</comment>")
        # all cleaning up will be done during reading and writing automatically
        manifest = read_manifest_to_spec(plug_dir)
        blacklist = read_blacklist_to_spec(plug_dir)

        new_manifest = [spec for spec in manifest if spec not in blacklist]

        new_manifest_filterd = self.filter_renamed(new_manifest)

        write_manifest_from_spec(new_manifest_filterd, plug_dir)

        self.line("<comment>Done</comment>")

    def filter_renamed(self, specs):
        """Filter specs that define the same plugin (same owner and same repo) but with different properties.
        This could be a different name, source, or branch
        """

        error = False
        for i, p in enumerate(specs):
            for p2 in specs:
                same_owner = p.owner.lower() == p2.owner.lower()
                same_repo = p.repo.lower() == p2.repo.lower()
                different_specs = p != p2
                marked_duplicate = p.marked_duplicate or p2.marked_duplicate

                if same_owner and same_repo and different_specs and not marked_duplicate:
                    self.line("<info>The following lines appear to define the same plugin</info>")

                    p_props_defined = p.branch is not None or p.custom_name is not None
                    p2_props_defined = p2.branch is not None or p2.custom_name is not None
                    p_is_lower_case = p.owner == p.owner.lower() and p.name == p.name.lower()
                    p2_is_lower_case = p2.owner == p2.owner.lower() and p2.name == p2.name.lower()

                    # list of conditions for selecting p
                    select_p = p_props_defined and not p2_props_defined or p2_is_lower_case and not p_is_lower_case
                    # list of conditions for selecting p2
                    select_p2 = p2_props_defined and not p_props_defined or p_is_lower_case and not p2_is_lower_case

                    # one is more defined and is all lower, but the other is not all lower
                    # (we assume the not all lower case is the correct naming)
                    error_props_lower = (
                        p_props_defined and p_is_lower_case and not p2_props_defined and not p2_is_lower_case
                    )
                    error_props_lower2 = (
                        p2_props_defined and p2_is_lower_case and not p_props_defined and not p_is_lower_case
                    )

                    # both props are defined
                    error_props = p_props_defined and p2_props_defined

                    # the sources are different
                    error_source = p.repository_host != p2.repository_host

                    if error_props_lower or error_props_lower2 or error_props or error_source:
                        self.line(" • <error>Cannot determine which is the correct plugin</error>")
                        self.line(f" - {p.line}")
                        self.line(f" - {p2.line}")
                        error = True
                        # remove second spec to not encounter the error twice
                        # this will not be written to the manifest.txt because we set
                        # the error flag and will exit after the loop
                        specs.remove(p2)
                    elif select_p:
                        self.line(f" - <comment>{p.line}</comment>")
                        self.line(f" - {p2.line}")
                        specs.remove(p2)
                    elif select_p2:
                        self.line(f" - {p.line}")
                        self.line(f" - <comment>{p2.line}</comment>")
                        specs.remove(p)
                    else:
                        self.line(" • <error>Logic error in correct spec determination</error>")
                        self.line(f" - {p.line}")
                        self.line(f" - {p2.line}")
                        error = True
                        # remove second spec to not encounter the error twice
                        # this will not be written to the manifest.txt because we set
                        # the error flag and will exit after the loop
                        specs.remove(p)
        if error:
            # exit after all errors have been found
            exit(1)

        return specs