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)