|
@@ -138,6 +138,7 @@ def convert_stacktrace_frame_path_to_source_path(
|
|
|
# XXX: Look at sentry.interfaces.stacktrace and maybe use that
|
|
|
class FrameFilename:
|
|
|
def __init__(self, frame_file_path: str) -> None:
|
|
|
+ self.raw_path = frame_file_path
|
|
|
if frame_file_path[0] == "/":
|
|
|
frame_file_path = frame_file_path.replace("/", "", 1)
|
|
|
|
|
@@ -187,9 +188,9 @@ class FrameFilename:
|
|
|
# - app:///../some/path/foo.js
|
|
|
|
|
|
start_at_index = get_straight_path_prefix_end_index(frame_file_path)
|
|
|
- backslash_index = frame_file_path.find("/", start_at_index)
|
|
|
+ slash_index = frame_file_path.find("/", start_at_index)
|
|
|
dir_path, self.file_name = frame_file_path.rsplit("/", 1) # foo.tsx (both)
|
|
|
- self.root = frame_file_path[0:backslash_index] # some or .some
|
|
|
+ self.root = frame_file_path[0:slash_index] # some or .some
|
|
|
self.dir_path = dir_path.replace(self.root, "") # some/path/ (both)
|
|
|
self.file_and_dir_path = remove_straight_path_prefix(
|
|
|
frame_file_path
|
|
@@ -299,36 +300,18 @@ class CodeMappingTreesHelper:
|
|
|
]
|
|
|
|
|
|
for file in matches:
|
|
|
+ stacktrace_root, source_path = find_roots(frame_filename.raw_path, file)
|
|
|
file_matches.append(
|
|
|
{
|
|
|
"filename": file,
|
|
|
"repo_name": repo_tree.repo.name,
|
|
|
"repo_branch": repo_tree.repo.branch,
|
|
|
- "stacktrace_root": f"{frame_filename.root}/",
|
|
|
- "source_path": _get_code_mapping_source_path(file, frame_filename),
|
|
|
+ "stacktrace_root": stacktrace_root,
|
|
|
+ "source_path": source_path,
|
|
|
}
|
|
|
)
|
|
|
return file_matches
|
|
|
|
|
|
- def _normalized_stack_and_source_roots(
|
|
|
- self, stacktrace_root: str, source_path: str
|
|
|
- ) -> tuple[str, str]:
|
|
|
- # We have a one to one code mapping (e.g. "app/" & "app/")
|
|
|
- if source_path == stacktrace_root:
|
|
|
- stacktrace_root = ""
|
|
|
- source_path = ""
|
|
|
- # stacktrace_root starts with a FILE_PATH_PREFIX_REGEX
|
|
|
- elif (without := remove_straight_path_prefix(stacktrace_root)) != stacktrace_root:
|
|
|
- start_index = get_straight_path_prefix_end_index(stacktrace_root)
|
|
|
- starts_with = stacktrace_root[:start_index]
|
|
|
- if source_path == without:
|
|
|
- stacktrace_root = starts_with
|
|
|
- source_path = ""
|
|
|
- elif source_path.rfind(f"/{without}"):
|
|
|
- stacktrace_root = starts_with
|
|
|
- source_path = source_path.replace(f"/{without}", "/")
|
|
|
- return (stacktrace_root, source_path)
|
|
|
-
|
|
|
def _generate_code_mapping_from_tree(
|
|
|
self,
|
|
|
repo_tree: RepoTree,
|
|
@@ -342,12 +325,7 @@ class CodeMappingTreesHelper:
|
|
|
if len(matched_files) != 1:
|
|
|
return []
|
|
|
|
|
|
- stacktrace_root = f"{frame_filename.root}/"
|
|
|
- source_path = _get_code_mapping_source_path(matched_files[0], frame_filename)
|
|
|
- if frame_filename.frame_type() != "packaged":
|
|
|
- stacktrace_root, source_path = self._normalized_stack_and_source_roots(
|
|
|
- stacktrace_root, source_path
|
|
|
- )
|
|
|
+ stacktrace_root, source_path = find_roots(frame_filename.raw_path, matched_files[0])
|
|
|
# It is too risky generating code mappings when there's more
|
|
|
# than one file potentially matching
|
|
|
return [
|
|
@@ -516,29 +494,6 @@ def get_sorted_code_mapping_configs(project: Project) -> list[RepositoryProjectP
|
|
|
return sorted_configs
|
|
|
|
|
|
|
|
|
-def _get_code_mapping_source_path(src_file: str, frame_filename: FrameFilename) -> str:
|
|
|
- """Generate the source code root for a code mapping. It always includes a last backslash"""
|
|
|
- source_code_root = None
|
|
|
- if frame_filename.frame_type() == "packaged":
|
|
|
- if frame_filename.dir_path != "":
|
|
|
- # src/sentry/identity/oauth2.py (sentry/identity/oauth2.py) -> src/sentry/
|
|
|
- source_path = src_file.rsplit(frame_filename.dir_path)[0].rstrip("/")
|
|
|
- source_code_root = f"{source_path}/"
|
|
|
- elif frame_filename.root != "":
|
|
|
- # src/sentry/wsgi.py (sentry/wsgi.py) -> src/sentry/
|
|
|
- source_code_root = src_file.rsplit(frame_filename.file_name)[0]
|
|
|
- else:
|
|
|
- # ssl.py -> raise NotImplementedError
|
|
|
- raise NotImplementedError("We do not support top level files.")
|
|
|
- else:
|
|
|
- # static/app/foo.tsx (./app/foo.tsx) -> static/app/
|
|
|
- # static/app/foo.tsx (app/foo.tsx) -> static/app/
|
|
|
- source_code_root = f"{src_file.replace(frame_filename.file_and_dir_path, remove_straight_path_prefix(frame_filename.root))}/"
|
|
|
- if source_code_root:
|
|
|
- assert source_code_root.endswith("/")
|
|
|
- return source_code_root
|
|
|
-
|
|
|
-
|
|
|
def find_roots(stack_path: str, source_path: str) -> tuple[str, str]:
|
|
|
"""
|
|
|
Returns a tuple containing the stack_root, and the source_root.
|
|
@@ -554,6 +509,12 @@ def find_roots(stack_path: str, source_path: str) -> tuple[str, str]:
|
|
|
|
|
|
if stack_root: # append trailing slash
|
|
|
stack_root = f"{stack_root}{stack_path_delim}"
|
|
|
+ if source_root and source_root[-1] != SLASH:
|
|
|
+ source_root = f"{source_root}{SLASH}"
|
|
|
+ if stack_path.endswith(".py") and len(overlap_to_check) > 1:
|
|
|
+ next_dir = overlap_to_check[0]
|
|
|
+ stack_root = f"{stack_root}{next_dir}{stack_path_delim}"
|
|
|
+ source_root = f"{source_root}{next_dir}{SLASH}"
|
|
|
|
|
|
return (stack_root, source_root)
|
|
|
|