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("Checking manifest file") # 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("Done") 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("The following lines appear to define the same plugin") 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(" • Cannot determine which is the correct plugin") 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" - {p.line}") self.line(f" - {p2.line}") specs.remove(p2) elif select_p2: self.line(f" - {p.line}") self.line(f" - {p2.line}") specs.remove(p) else: self.line(" • Logic error in correct spec determination") 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