Skip to content

[REFACTOR] Deduplicate scan_X methods in scanner.py into generic _scan_by_plugin #30

Description

@KbWen

Problem Description

scanner.py contains approximately 15 nearly identical scan_X() methods (scan_dependencies, scan_secrets, scan_rules, scan_docker, scan_iac, scan_ci, scan_firebase, scan_mcp, scan_agency, scan_vulnerabilities, scan_mobile, scan_api, scan_entropy, scan_ai_supply_chain).

Each method follows the exact same pattern:

def scan_X(self, limit_files=None):
    findings = []
    plugin = next((p for p in self.scanners if "X" in getattr(p, 'name', '').lower()), None)
    if not plugin: return []
    for root, files in self._iter_files(limit_files):
        for file in files:
            file_path = os.path.join(root, file)
            if not self._is_safe_path(file_path):
                continue
            findings.extend(plugin.scan([file_path], self.config))
    return findings

This creates ~200 lines of duplicated code that must be maintained in parallel.

Proposed Refactor

Replace all scan_X methods with a single generic method:

def _scan_by_plugin(self, plugin_name_match: str, limit_files=None, file_filter=None):
    """Generic scan method that delegates to a specific plugin by name match."""
    findings = []
    plugin = next((p for p in self.scanners if plugin_name_match in getattr(p, 'name', '').lower()), None)
    if not plugin:
        return []
    for root, files in self._iter_files(limit_files):
        for file in files:
            if file_filter and not file_filter(file):
                continue
            file_path = os.path.join(root, file)
            if not self._is_safe_path(file_path):
                continue
            findings.extend(plugin.scan([file_path], self.config))
    return findings

Then each public method becomes a one-liner:

def scan_docker(self, limit_files=None):
    return self._scan_by_plugin("docker", limit_files)

def scan_dependencies(self, limit_files=None):
    return self._scan_by_plugin("hallucination", limit_files, 
        file_filter=lambda f: f in ['requirements.txt', 'package.json'])

Impact

  • Reduces ~200 lines to ~30 lines
  • Easier to add new scan commands in the future
  • Single place to fix bugs in the iteration/safety logic

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions