Skip to content
Open
Show file tree
Hide file tree
Changes from 9 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
4 changes: 3 additions & 1 deletion inlineplz/interfaces/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
from __future__ import absolute_import

from inlineplz.interfaces.github import GitHubInterface
from inlineplz.interfaces.stash import StashInterface

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prospector: pylint: Import "from inlineplz.interfaces.stash import StashInterface" should be placed at the top of the module (wrong-import-position)

INTERFACES = {
'github': GitHubInterface
'github': GitHubInterface,
'stash': StashInterface
}
3 changes: 2 additions & 1 deletion inlineplz/interfaces/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@


class GitHubInterface(InterfaceBase):
def __init__(self, owner, repo, pr, token, url=None):
def __init__(self, owner, repo, pr, auth, url=None):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prospector: pylint: Too many arguments (6/5) (too-many-arguments)

self.github = None
token = auth.get('token')
# TODO: support non-PR runs
try:
pr = int(pr)
Expand Down
93 changes: 93 additions & 0 deletions inlineplz/interfaces/stash.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import

import stashy
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prospector: pylint: Unable to import 'stashy' (import-error)

import unidiff

from inlineplz.interfaces.base import InterfaceBase
from inlineplz.util import git


class StashInterface(InterfaceBase):
def __init__(self, project, repo, pr, auth, url=None):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prospector: pylint: Too many arguments (6/5) (too-many-arguments)

self.stash = None
username = auth.get('username')
password = auth.get('password')
# TODO: support non-PR runs
try:
pr = int(pr)
except ValueError:
return
if not url:
return
else:
self.stash = stashy.connect(url, username=username, password=password, verify=False)
self.pull_request = self.stash.projects[project].repos[repo].pull_requests[pr]
self.commits = [c for c in self.pull_request.commits()]
self.last_sha = self.commits[0]['id']
self.first_sha = self.commits[-1]['id']
self.parent_sha = self.commits[-1]['parents'][0]['id']
self.diff = git.diff(self.parent_sha, self.last_sha)

def post_messages(self, messages, max_comments):
# TODO: support non-PR runs
if not self.stash:
return
messages_to_post = 0
messages_posted = 0
for msg in messages:
if not msg.comments:
continue
msg_position = self.position(msg)
if msg_position:
messages_to_post += 1
if not self.is_duplicate(msg, msg_position):
self.pull_request.comment(
self.format_message(msg),
srcPath=msg.path,
fileLine=msg_position,
lineType='ADDED',
fileType='TO'
)
messages_posted += 1
if max_comments >= 0 and messages_posted > max_comments:
break
return messages_to_post

def is_duplicate(self, message, position):
for comment in self.pull_request.comments(message.path):
if ('anchor' in comment and
'line' in comment['anchor'] and
comment['anchor']['line'] == position and
comment['text'].strip() == self.format_message(message).strip()):
return True
return False

@staticmethod
def format_message(message):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder if this should be moved to the parent class or to a utility module. thoughts?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the implementation here is slightly different from github.py because the structure of comments in the stash API is different. I couldn't think of a good way to extract the shared logic from what is unique to each interface. Any suggestions?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah i didn't notice the difference, nevermind

if not message.comments:
return ''
if len(message.comments) > 1:
return (
'```\n' +
'\n'.join(sorted(list(message.comments))) +
'\n```'
)
return '`{0}`'.format(list(message.comments)[0].strip())

def position(self, message):
"""
Determine where the comment should go
Skips messages outside of the scope of changes we're looking at
"""
patch = unidiff.PatchSet(self.diff.split('\n'))
for patched_file in patch:
target = patched_file.target_file.lstrip('b/')
if target == message.path:
for hunk_no, hunk in enumerate(patched_file):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prospector: pylint: Unused variable 'hunk_no' (unused-variable)

for position, hunk_line in enumerate(hunk):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prospector: pylint: Unused variable 'position' (unused-variable)

if '+' not in hunk_line.line_type:
continue
if hunk_line.target_line_no == message.line_number:
return hunk_line.target_line_no
6 changes: 5 additions & 1 deletion inlineplz/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ def main():
parser.add_argument('--repo', type=str)
parser.add_argument('--repo-slug', type=str)
parser.add_argument('--token', type=str)
parser.add_argument('--user', type=str)
parser.add_argument('--password', type=str)
parser.add_argument('--interface', type=str, choices=interfaces.INTERFACES)
parser.add_argument('--url', type=str)
parser.add_argument('--dryrun', action='store_true')
Expand Down Expand Up @@ -77,6 +79,8 @@ def inline(args):
repo: Repository name
pr: Pull request ID
token: Authentication for repository
user: (If not using token) username for repository
password: (If not using token) password for repository
url: Root URL of repository (not your project) Default: https://github.com
dryrun: Prints instead of posting comments.
zero_exit: If true: always return a 0 exit code.
Expand Down Expand Up @@ -107,7 +111,7 @@ def inline(args):
owner,
repo,
args.pull_request,
args.token,
dict(token=args.token, username=args.user, password=args.password),
args.url
)
if my_interface.post_messages(messages, args.max_comments) and not args.zero_exit:
Expand Down
4 changes: 4 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
requirements = [
'unidiff',
'github3.py',
'stashy>=0.3.0',
'xmltodict',
'pyyaml',
'scandir'
Expand All @@ -34,6 +35,9 @@
packages=find_packages('.', exclude=('tests*', 'testing*')),
include_package_data=True,
install_requires=requirements,
dependency_links=[ # TODO: Remove dependency_links once stashy is updated on PyPI
'git+https://github.com/RisingOak/stashy.git#egg=stashy-0.3.0'
],
license="ISCL",
zip_safe=False,
keywords='inlineplz',
Expand Down