def test_simple(self): date = datetime.datetime.utcnow() org = self.create_organization() project = self.create_project(organization=org, name='foo') # this shouldn't be included release1 = Release.objects.create( organization=org, version='a' * 40, date_released=date - datetime.timedelta(days=2), ) release1.add_project(project) release2 = Release.objects.create( organization=org, version='b' * 40, date_released=date - datetime.timedelta(days=1), ) release2.add_project(project) release3 = Release.objects.create( organization=org, version='c' * 40, date_released=date, ) release3.add_project(project) releases = list(Release.get_closest_releases(project, release2.version)) assert len(releases) == 2 assert releases[0] == release2 assert releases[1] == release3
def get_event_file_committers(project, event, frame_limit=25): # populate event data Event.objects.bind_nodes([event], 'data') group = Group.objects.get(id=event.group_id) first_release_version = group.get_first_release() if not first_release_version: raise Release.DoesNotExist releases = Release.get_closest_releases(project, first_release_version) if not releases: raise Release.DoesNotExist commits = _get_commits(releases) if not commits: raise Commit.DoesNotExist frames = _get_frame_paths(event) app_frames = [frame for frame in frames if frame['in_app']][-frame_limit:] if not app_frames: app_frames = [frame for frame in frames][-frame_limit:] # TODO(maxbittker) return this set instead of annotated frames # XXX(dcramer): frames may not define a filepath. For example, in Java its common # to only have a module name/path path_set = { f for f in (frame.get('filename') or frame.get('abs_path') for frame in app_frames) if f } file_changes = [] if path_set: file_changes = _get_commit_file_changes(commits, path_set) commit_path_matches = { path: _match_commits_path(file_changes, path) for path in path_set } annotated_frames = [{ 'frame': frame, 'commits': commit_path_matches.get( frame.get('filename') or frame.get('abs_path')) or [] } for frame in app_frames] relevant_commits = list({ match for match in commit_path_matches for match in commit_path_matches[match] }) committers = _get_committers(annotated_frames, relevant_commits) metrics.incr('feature.owners.has-committers', instance='hit' if committers else 'miss') return committers
def get(self, _, project, event_id): """ Retrieve Committer information for an event ``````````````````````````````````````````` Return commiters on an individual event, plus a per-frame breakdown. :pparam string project_slug: the slug of the project the event belongs to. :pparam string event_id: the hexadecimal ID of the event to retrieve (as reported by the raven client). :auth: required """ try: event = Event.objects.get( id=event_id, project_id=project.id, ) except Event.DoesNotExist: return Response({'detail': 'Event not found'}, status=404) # populate event data Event.objects.bind_nodes([event], 'data') group = Group.objects.get(id=event.group_id) first_release_version = group.get_first_release() if not first_release_version: return Response({'detail': 'Release not found'}, status=404) releases = Release.get_closest_releases(project, first_release_version) if not releases: return Response({'detail': 'Release not found'}, status=404) commits = self._get_commits(releases) if not commits: return Response({'detail': 'No Commits found for Release'}, status=404) frames = self._get_frame_paths(event) frame_limit = 15 app_frames = [frame for frame in frames if frame['in_app']][:frame_limit] # TODO(maxbittker) return this set instead of annotated frames path_set = {frame['abs_path'] for frame in app_frames} file_changes = [] if path_set: file_changes = self._get_commit_file_changes(commits, path_set) commit_path_matches = { path: self._match_commits_path(file_changes, path) for path in path_set } annotated_frames = [ { 'frame': frame, 'commits': commit_path_matches[frame['abs_path']] } for frame in app_frames ] relevant_commits = list( {commit for match in commit_path_matches for commit in commit_path_matches[match]} ) committers = self._get_committers(annotated_frames, relevant_commits) # serialize the commit objects serialized_annotated_frames = [ { 'frame': frame['frame'], 'commits': serialize(frame['commits']) } for frame in annotated_frames ] data = { # map author ids to sentry user dicts 'committers': committers, 'annotatedFrames': serialized_annotated_frames } return Response(data)