def remove_obsolete()

in sync/bugcomponents.py [0:0]


def remove_obsolete(path: str, moves: Optional[Dict[str, str]] = None) -> str:
    from lib2to3 import (pygram,  # type: ignore
                         pytree,
                         patcomp)
    from lib2to3.pgen2 import driver

    files_pattern = ("with_stmt< 'with' power< 'Files' "
                     "trailer< '(' arg=any any* ')' > any* > any* >")
    base_dir = os.path.dirname(path) or "."
    d = driver.Driver(pygram.python_grammar,
                      convert=pytree.convert)
    tree = d.parse_file(path)
    pc = patcomp.PatternCompiler()
    pat = pc.compile_pattern(files_pattern)

    unmatched_patterns = set()
    node_patterns = {}

    for node in tree.children:
        match_values: Dict[Any, Any] = {}
        if pat.match(node, match_values):
            path_pat = literal_eval(match_values['arg'].value)
            unmatched_patterns.add(path_pat)
            node_patterns[path_pat] = (node, match_values)

    for base_path, _, files in os.walk(base_dir):
        for filename in files:
            full_path = os.path.join(base_path, filename)
            path = os.path.relpath(full_path, base_dir)
            try:
                assert ("../" not in path and
                        not path.endswith("/..")), "Path {} is outside {}".format(full_path,
                                                                                  base_dir)
            except AssertionError:
                newrelic.agent.record_exception(params={
                    "path": full_path
                })
                continue

            if path[:2] == "./":
                path = path[2:]
            for pattern in unmatched_patterns.copy():
                if match(path, pattern):
                    unmatched_patterns.remove(pattern)

    if moves:
        moved_patterns = compute_moves(moves, unmatched_patterns)
        unmatched_patterns -= set(moved_patterns.keys())
        for old_pattern, new_pattern in moved_patterns.items():
            node, match_values = node_patterns[old_pattern]
            arg = match_values["arg"]
            arg.replace(arg.__class__(arg.type, '"%s"' % new_pattern))

    for pattern in unmatched_patterns:
        logger.debug("Removing %s" % pattern)
        node_patterns[pattern][0].remove()

    return str(tree)