Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions atlassian/bitbucket/cloud/repositories/diffstat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
from ..base import BitbucketCloudBase


class DiffStat(BitbucketCloudBase):
"""
Bitbucket Cloud repository diffstat entry.

This represents the changes for one specific file in a diff.

See https://developer.atlassian.com/cloud/bitbucket/rest/api-group-commits/#api-repositories-workspace-repo-slug-diffstat-spec-get
"""

MODIFIED = "modified"
ADDED = "added"
REMOVED = "removed"
MERGE_CONFLICT = "merge conflict"
SUBREPO_CONFLICT = "subrepo conflict"

def __init__(self, data, *args, **kwargs):
"""See BitbucketCloudBase."""
super(DiffStat, self).__init__(None, None, *args, data=data, expected_type="diffstat", **kwargs)

@property
def lines_removed(self):
"""Lines removed."""
return self.get_data("lines_removed")

@property
def lines_added(self):
"""Lines added."""
return self.get_data("lines_added")

@property
def old(self):
"""A CommitFile object, representing a file at a commit in a repository."""
return CommitFile(self.get_data("old"), **self._new_session_args)

@property
def new(self):
"""A CommitFile object, representing a file at a commit in a repository."""
return CommitFile(self.get_data("new"), **self._new_session_args)

@property
def has_conflict(self):
"""True if the change causes a conflict."""
return str(self.get_data("status")) in (self.MERGE_CONFLICT, self.SUBREPO_CONFLICT)


class CommitFile(BitbucketCloudBase):
"""
Bitbucket Cloud repository diffstat file.

File reference from a diffstat entry.

See https://developer.atlassian.com/cloud/bitbucket/rest/api-group-commits/#api-repositories-workspace-repo-slug-diffstat-spec-get
"""

def __init__(self, data, *args, **kwargs):
"""See BitbucketCloudBase."""
if data is None: # handles add/remove
data = {"path": None, "escaped_path": None, "links": {}, "type": "commit_file"}
super(CommitFile, self).__init__(None, None, *args, data=data, expected_type="commit_file", **kwargs)

@property
def path(self):
"""The path in the repository."""
return self.get_data("path")

@property
def escaped_path(self):
"""
The escaped version of the path as it appears in a diff.

If the path does not require escaping this will be the same as path.
"""
return self.get_data("escaped_path")
48 changes: 47 additions & 1 deletion atlassian/bitbucket/cloud/repositories/pullRequests.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# coding=utf-8

from ..base import BitbucketCloudBase
from .diffstat import DiffStat
from ..common.users import User


Expand Down Expand Up @@ -177,6 +178,16 @@ def destination_branch(self):
"""destination branch"""
return self.get_data("destination")["branch"]["name"]

@property
def source_commit(self):
"""Source commit."""
return self.get_data("source")["commit"]["hash"]

@property
def destination_commit(self):
"""Destination commit."""
return self.get_data("destination")["commit"]["hash"]

@property
def comment_count(self):
"""number of comments"""
Expand All @@ -197,6 +208,41 @@ def author(self):
"""User object of the author"""
return User(None, self.get_data("author"))

@property
def has_conflict(self):
"""Returns True if any of the changes in the PR cause conflicts."""
for diffstat in self.diffstat():
if diffstat.has_conflict:
return True
return False

def diffstat(self):
"""
Returns a generator object of diffstats

API docs: https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Bworkspace%7D/%7Brepo_slug%7D/pullrequests/%7Bpull_request_id%7D/diffstat
"""
for diffstat in self._get_paged("diffstat"):
yield DiffStat(diffstat, **self._new_session_args)

return

def diff(self, encoding="utf-8"):
"""
Returns PR diff

API docs: https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Bworkspace%7D/%7Brepo_slug%7D/pullrequests/%7Bpull_request_id%7D/diff
"""
return str(self.get("diff", not_json_response=True), encoding=encoding)

def patch(self, encoding="utf-8"):
"""
Returns PR patch

API docs: https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Bworkspace%7D/%7Brepo_slug%7D/pullrequests/%7Bpull_request_id%7D/patch
"""
return str(self.get("patch", not_json_response=True), encoding=encoding)

def statuses(self):
"""
Returns generator object of the statuses endpoint
Expand Down Expand Up @@ -573,7 +619,7 @@ def update(self, raw_message):

def delete(self):
"""
Delete the pullrequest tasl.
Delete the pullrequest task.

This is feature currently undocumented.
"""
Expand Down