def _get_github_diff_lines(token, owner, repo, path, sha1, sha2):
    diff = github.get_file_diff(token, owner, repo, path, sha1, sha2)
    if not diff:
        return False

    # The first four lines are headers which github ignores in indexing.
    return diff.split('\n')[4:]
Example #2
0
def file_diff(owner, repo, number):
    token = session['token']
    login = session['login']
    path = request.args.get('path', '')
    sha1 = request.args.get('sha1', '')
    sha2 = request.args.get('sha2', '')
    if not (path and sha1 and sha2):
        return "Incomplete request (need path, sha1, sha2)"

    pr = gitcritic.PullRequest.from_github(db, token, login, owner, repo, number)

    unified_diff = github.get_file_diff(token, owner, repo, path, sha1, sha2)
    if not unified_diff:
        return "Unable to get diff for %s..%s" % (sha1, sha2)

    # github excludes the first four header lines of "git diff"
    github_diff = '\n'.join(unified_diff.split('\n')[4:])

    # before = github.get_file_at_ref(token, owner, repo, path, sha1) or ''
    # after = github.get_file_at_ref(token, owner, repo, path, sha2) or ''

    for commit in pr.commits:
        if commit['sha'] == sha1: commit['selected_left'] = True
        if commit['sha'] == sha2: commit['selected_right'] = True

    pr.add_file_diff_links(sha1, sha2)

    idxs = [i for (i, f) in enumerate(pr.files) if f['filename'] == path]

    if idxs:
        file_idx = idxs[0]
        prev_file = pr.files[file_idx - 1] if file_idx > 0 else None
        next_file = pr.files[file_idx + 1] if file_idx < len(pr.files) - 1 else None
        app.logger.info("next_file: %s", next_file)
    else:
        # The current file is not part of this diff.
        # Just do something sensible.
        prev_file = None
        next_file = pr.files[0] if len(pr.files) > 0 else None

    pull_request_url = url_for('pull', owner=owner, repo=repo, number=number) + '?sha1=%s&sha2=%s' % (sha1, sha2)

    github_file_urls = map(lambda sha: 'http://github.com/%s/%s/blob/%s/%s' % (owner, repo, sha, path), [sha1, sha2])

    return render_template('file_diff.html',
                           logged_in_user=login,
                           owner=owner, repo=repo,
                           pull_request=pr.pull_request,
                           commits=pr.commits,
                           comments=pr.comments,
                           files=pr.files,
                           path=path, sha1=sha1, sha2=sha2,
                           # before_contents=before, after_contents=after,
                           prev_file=prev_file, next_file=next_file,
                           github_diff=github_diff,
                           pull_request_url=pull_request_url,
                           github_file_urls=github_file_urls)
def _get_github_diff_lines(token, owner, repo, path, sha1, sha2):
    diff = github.get_file_diff(token, owner, repo, path, sha1, sha2)
    if not diff:
        return False

    # The first several lines are headers which github ignores in indexing.
    diff_lines = diff.split('\n')
    while diff_lines and not DIFF_HUNK_HEADER_RE.match(diff_lines[0]):
        del diff_lines[0]
    return diff_lines
Example #4
0
def file_diff(user, repo, number):
    path = request.args.get('path', '')
    sha1 = request.args.get('sha1', '')
    sha2 = request.args.get('sha2', '')
    if not (path and sha1 and sha2):
        return "Incomplete request (need path, sha1, sha2)"

    # TODO(danvk): consolidate this code with the pull route
    token = session['token']
    commits = github.get_pull_request_commits(token, user, repo, number)
    pr = github.get_pull_request(token, user, repo, number)
    comments = github.get_pull_request_comments(token, user, repo, number)

    open('/tmp/commits.txt', 'wb').write(json.dumps(commits, indent=2))

    commit_to_comments = defaultdict(int)
    for comment in comments['diff_level']:
        commit_to_comments[comment['original_commit_id']] += 1

    commits.reverse()
    # Add an entry for the base commit.
    commits.append({
        'sha': pr['base']['sha'],
        'commit': {
            'message': '(%s)' % pr['base']['ref'],
            'author': {'date': ''}
        },
        'author': {'login': ''}
    })


    # github excludes the first four header lines of "git diff"
    diff_info = github.get_diff_info(token, user, repo, sha1, sha2)
    unified_diff = github.get_file_diff(token, user, repo, path, sha1, sha2)
    if not unified_diff or not diff_info:
        return "Unable to get diff for %s..%s" % (sha1, sha2)

    github_diff = '\n'.join(unified_diff.split('\n')[4:])

    # TODO(danvk): only annotate comments on this file.
    github_comments.add_line_numbers_to_comments(token, user, repo, pr['base']['sha'], comments['diff_level'])

    differing_files = [f['filename'] for f in diff_info['files']]
    before = github.get_file_at_ref(token, user, repo, path, sha1)
    after = github.get_file_at_ref(token, user, repo, path, sha2)

    def diff_url(path):
        return (url_for('file_diff', user=user, repo=repo, number=number) +
                '?path=' + urllib.quote(path) +
                '&sha1=' + urllib.quote(sha1) + '&sha2=' + urllib.quote(sha2))

    linked_files = [{'path':p, 'link': diff_url(p)} for p in differing_files]

    if path in differing_files:
        file_idx = differing_files.index(path)
        prev_file = linked_files[file_idx - 1] if file_idx > 0 else None
        next_file = linked_files[file_idx + 1] if file_idx < len(linked_files) - 1 else None
    else:
        # The current file is not part of this diff.
        # Just do something sensible.
        prev_file = None
        next_file = linked_files[0] if len(linked_files) > 0 else None
    
    pull_request_url = url_for('pull', user=user, repo=repo, number=number)

    return render_template('file_diff.html', commits=commits, user=user, repo=repo, pull_request=pr, comments=comments, path=path, sha1=sha1, sha2=sha2, before_contents=before, after_contents=after, differing_files=linked_files, prev_file=prev_file, next_file=next_file, github_diff=github_diff, pull_request_url=pull_request_url)