|
Pierre-Yves Chibon |
33b534 |
# -*- coding: utf-8 -*-
|
|
Pierre-Yves Chibon |
fac0b1 |
|
|
Pierre-Yves Chibon |
fac0b1 |
"""
|
|
Pierre-Yves Chibon |
fac0b1 |
(c) 2014 - Copyright Red Hat Inc
|
|
Pierre-Yves Chibon |
fac0b1 |
|
|
Pierre-Yves Chibon |
fac0b1 |
Authors:
|
|
Pierre-Yves Chibon |
fac0b1 |
Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
|
|
Pierre-Yves Chibon |
fac0b1 |
|
|
Pierre-Yves Chibon |
fac0b1 |
"""
|
|
Pierre-Yves Chibon |
fac0b1 |
|
|
Pierre-Yves Chibon |
fac0b1 |
import flask
|
|
Pierre-Yves Chibon |
fac0b1 |
import os
|
|
Pierre-Yves Chibon |
be7090 |
import shutil
|
|
Pierre-Yves Chibon |
41558c |
import tempfile
|
|
Pierre-Yves Chibon |
fac0b1 |
from math import ceil
|
|
Pierre-Yves Chibon |
fac0b1 |
|
|
Pierre-Yves Chibon |
fac0b1 |
import pygit2
|
|
Pierre-Yves Chibon |
fac0b1 |
from sqlalchemy.exc import SQLAlchemyError
|
|
Pierre-Yves Chibon |
fac0b1 |
from pygments import highlight
|
|
Pierre-Yves Chibon |
fac0b1 |
from pygments.lexers import guess_lexer
|
|
Pierre-Yves Chibon |
fac0b1 |
from pygments.lexers.text import DiffLexer
|
|
Pierre-Yves Chibon |
fac0b1 |
from pygments.formatters import HtmlFormatter
|
|
Pierre-Yves Chibon |
fac0b1 |
|
|
Pierre-Yves Chibon |
fac0b1 |
|
|
Pierre-Yves Chibon |
6bf4e3 |
import progit.doc_utils
|
|
Pierre-Yves Chibon |
80bba3 |
import progit.lib
|
|
Pierre-Yves Chibon |
118968 |
import progit.lib.git
|
|
Pierre-Yves Chibon |
ac8023 |
import progit.forms
|
|
Pierre-Yves Chibon |
1e5fe9 |
from progit import (APP, SESSION, LOG, __get_file_in_tree, cla_required,
|
|
Pierre-Yves Chibon |
59be40 |
is_repo_admin, generate_gitolite_acls)
|
|
Pierre-Yves Chibon |
fac0b1 |
|
|
Pierre-Yves Chibon |
fac0b1 |
|
|
Pierre-Yves Chibon |
8df273 |
def _get_repo_path(repo):
|
|
Pierre-Yves Chibon |
8df273 |
""" Return the pat of the git repository corresponding to the provided
|
|
Pierre-Yves Chibon |
8df273 |
Repository object from the DB.
|
|
Pierre-Yves Chibon |
8df273 |
"""
|
|
Pierre-Yves Chibon |
8df273 |
if repo.is_fork:
|
|
Pierre-Yves Chibon |
8df273 |
repopath = os.path.join(APP.config['FORK_FOLDER'], repo.path)
|
|
Pierre-Yves Chibon |
8df273 |
else:
|
|
Pierre-Yves Chibon |
8df273 |
repopath = os.path.join(APP.config['GIT_FOLDER'], repo.path)
|
|
Pierre-Yves Chibon |
8df273 |
return repopath
|
|
Pierre-Yves Chibon |
8df273 |
|
|
Pierre-Yves Chibon |
8df273 |
|
|
Pierre-Yves Chibon |
8df273 |
def _get_parent_repo_path(repo):
|
|
Pierre-Yves Chibon |
8df273 |
""" Return the path of the parent git repository corresponding to the
|
|
Pierre-Yves Chibon |
8df273 |
provided Repository object from the DB.
|
|
Pierre-Yves Chibon |
8df273 |
"""
|
|
Pierre-Yves Chibon |
8df273 |
if repo.parent:
|
|
Pierre-Yves Chibon |
8df273 |
parentpath = os.path.join(APP.config['GIT_FOLDER'], repo.parent.path)
|
|
Pierre-Yves Chibon |
8df273 |
else:
|
|
Pierre-Yves Chibon |
8df273 |
parentpath = os.path.join(APP.config['GIT_FOLDER'], repo.path)
|
|
Pierre-Yves Chibon |
8df273 |
return parentpath
|
|
Pierre-Yves Chibon |
8df273 |
|
|
Pierre-Yves Chibon |
8df273 |
|
|
Pierre-Yves Chibon |
b31474 |
@APP.route('/<repo>/request-pulls')</repo>
|
|
Pierre-Yves Chibon |
b31474 |
@APP.route('/fork/<username>/<repo>/request-pulls')</repo></username>
|
|
Pierre-Yves Chibon |
b31474 |
def request_pulls(repo, username=None):
|
|
Pierre-Yves Chibon |
b31474 |
""" Request pulling the changes from the fork into the project.
|
|
Pierre-Yves Chibon |
47950c |
"""
|
|
Pierre-Yves Chibon |
b31474 |
status = flask.request.args.get('status', True)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
repo = progit.lib.get_project(SESSION, repo, user=username)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
if not repo:
|
|
Pierre-Yves Chibon |
47950c |
flask.abort(404, 'Project not found')
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
b31474 |
if status is False or str(status).lower() == 'closed':
|
|
Pierre-Yves Chibon |
ff8c27 |
requests = progit.lib.search_pull_requests(
|
|
Pierre-Yves Chibon |
b31474 |
SESSION, project_id=repo.id, status=False)
|
|
Pierre-Yves Chibon |
47950c |
else:
|
|
Pierre-Yves Chibon |
ff8c27 |
requests = progit.lib.search_pull_requests(
|
|
Pierre-Yves Chibon |
b31474 |
SESSION, project_id=repo.id, status=status)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
b31474 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
b31474 |
'requests.html',
|
|
Pierre-Yves Chibon |
b31474 |
select='requests',
|
|
Pierre-Yves Chibon |
b31474 |
repo=repo,
|
|
Pierre-Yves Chibon |
b31474 |
username=username,
|
|
Pierre-Yves Chibon |
b31474 |
requests=requests,
|
|
Pierre-Yves Chibon |
b31474 |
status=status,
|
|
Pierre-Yves Chibon |
b31474 |
)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
c33710 |
@APP.route('/<repo>/request-pull/<int:requestid>')</int:requestid></repo>
|
|
Pierre-Yves Chibon |
c33710 |
@APP.route('/fork/<username>/<repo>/request-pull/<int:requestid>')</int:requestid></repo></username>
|
|
Pierre-Yves Chibon |
b31474 |
def request_pull(repo, requestid, username=None):
|
|
Pierre-Yves Chibon |
47950c |
""" Request pulling the changes from the fork into the project.
|
|
Pierre-Yves Chibon |
47950c |
"""
|
|
Pierre-Yves Chibon |
b31474 |
|
|
Pierre-Yves Chibon |
47950c |
repo = progit.lib.get_project(SESSION, repo, user=username)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
if not repo:
|
|
Pierre-Yves Chibon |
47950c |
flask.abort(404, 'Project not found')
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
ff8c27 |
request = progit.lib.search_pull_requests(
|
|
Pierre-Yves Chibon |
47950c |
SESSION, project_id=repo.id, requestid=requestid)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
if not request:
|
|
Pierre-Yves Chibon |
47950c |
flask.abort(404, 'Pull-request not found')
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
0784c9 |
repo_from = request.repo_from
|
|
Pierre-Yves Chibon |
8df273 |
repopath = _get_repo_path(repo_from)
|
|
Pierre-Yves Chibon |
47950c |
repo_obj = pygit2.Repository(repopath)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
8df273 |
parentpath = _get_parent_repo_path(repo_from)
|
|
Pierre-Yves Chibon |
8df273 |
orig_repo = pygit2.Repository(parentpath)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
e31131 |
branch = repo_obj.lookup_branch(request.branch_from)
|
|
Pierre-Yves Chibon |
e31131 |
commitid = branch.get_object().hex
|
|
Pierre-Yves Chibon |
e31131 |
|
|
Pierre-Yves Chibon |
47950c |
diff_commits = []
|
|
Pierre-Yves Chibon |
e31131 |
diff = None
|
|
Pierre-Yves Chibon |
47950c |
if not repo_obj.is_empty and not orig_repo.is_empty:
|
|
Pierre-Yves Chibon |
2c9e9f |
orig_commit = orig_repo[
|
|
Pierre-Yves Chibon |
e31131 |
orig_repo.lookup_branch(request.branch).get_object().hex]
|
|
Pierre-Yves Chibon |
2c9e9f |
|
|
Pierre-Yves Chibon |
afd10d |
# Closed pull-request
|
|
Pierre-Yves Chibon |
f986ce |
if request.status is False:
|
|
Pierre-Yves Chibon |
f986ce |
commitid = request.commit_stop
|
|
Pierre-Yves Chibon |
afd10d |
for commit in repo_obj.walk(commitid, pygit2.GIT_SORT_TIME):
|
|
Pierre-Yves Chibon |
afd10d |
diff_commits.append(commit)
|
|
Pierre-Yves Chibon |
afd10d |
if commit.oid.hex == request.commit_start:
|
|
Pierre-Yves Chibon |
afd10d |
break
|
|
Pierre-Yves Chibon |
afd10d |
# Pull-request open
|
|
Pierre-Yves Chibon |
afd10d |
else:
|
|
Pierre-Yves Chibon |
afd10d |
master_commits = [
|
|
Pierre-Yves Chibon |
afd10d |
commit.oid.hex
|
|
Pierre-Yves Chibon |
afd10d |
for commit in orig_repo.walk(
|
|
Pierre-Yves Chibon |
afd10d |
orig_repo.lookup_branch(request.branch).get_object().hex,
|
|
Pierre-Yves Chibon |
afd10d |
pygit2.GIT_SORT_TIME)
|
|
Pierre-Yves Chibon |
afd10d |
]
|
|
Pierre-Yves Chibon |
afd10d |
for commit in repo_obj.walk(commitid, pygit2.GIT_SORT_TIME):
|
|
Pierre-Yves Chibon |
afd10d |
if request.status and commit.oid.hex in master_commits:
|
|
Pierre-Yves Chibon |
afd10d |
break
|
|
Pierre-Yves Chibon |
afd10d |
diff_commits.append(commit)
|
|
Pierre-Yves Chibon |
afd10d |
|
|
Pierre-Yves Chibon |
afd10d |
if request.status:
|
|
Pierre-Yves Chibon |
afd10d |
first_commit = repo_obj[diff_commits[-1].oid.hex]
|
|
Pierre-Yves Chibon |
afd10d |
request.commit_start = first_commit.oid.hex
|
|
Pierre-Yves Chibon |
afd10d |
request.commit_stop = diff_commits[0].oid.hex
|
|
Pierre-Yves Chibon |
afd10d |
SESSION.add(request)
|
|
Pierre-Yves Chibon |
1a6537 |
try:
|
|
Pierre-Yves Chibon |
1a6537 |
SESSION.commit()
|
|
Pierre-Yves Chibon |
1a6537 |
except SQLAlchemyError as err:
|
|
Pierre-Yves Chibon |
1a6537 |
SESSION.rollback()
|
|
Pierre-Yves Chibon |
1a6537 |
APP.logger.exception(err)
|
|
Pierre-Yves Chibon |
1a6537 |
flask.flash(
|
|
Pierre-Yves Chibon |
1a6537 |
'Could not update this pull-request in the database',
|
|
Pierre-Yves Chibon |
1a6537 |
'error')
|
|
Pierre-Yves Chibon |
e31131 |
|
|
Pierre-Yves Chibon |
e31131 |
if diff_commits:
|
|
Pierre-Yves Chibon |
e31131 |
first_commit = repo_obj[diff_commits[-1].oid.hex]
|
|
Pierre-Yves Chibon |
e31131 |
diff = repo_obj.diff(
|
|
Pierre-Yves Chibon |
e31131 |
repo_obj.revparse_single(first_commit.parents[0].oid.hex),
|
|
Pierre-Yves Chibon |
e31131 |
repo_obj.revparse_single(diff_commits[0].oid.hex)
|
|
Pierre-Yves Chibon |
e31131 |
)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
elif orig_repo.is_empty:
|
|
Pierre-Yves Chibon |
47950c |
orig_commit = None
|
|
Pierre-Yves Chibon |
60052e |
repo_commit = repo_obj[request.stop_id]
|
|
Pierre-Yves Chibon |
47950c |
diff = repo_commit.tree.diff_to_tree(swap=True)
|
|
Pierre-Yves Chibon |
47950c |
else:
|
|
Pierre-Yves Chibon |
47950c |
flask.flash(
|
|
Pierre-Yves Chibon |
47950c |
'Fork is empty, there are no commits to request pulling',
|
|
Pierre-Yves Chibon |
47950c |
'error')
|
|
Pierre-Yves Chibon |
47950c |
return flask.redirect(flask.url_for(
|
|
Pierre-Yves Chibon |
ea8735 |
'view_repo', username=username, repo=repo.name))
|
|
Pierre-Yves Chibon |
47950c |
|
|
Johan Cwiklinski |
fd18bd |
form = progit.forms.ConfirmationForm()
|
|
Johan Cwiklinski |
fd18bd |
|
|
Pierre-Yves Chibon |
47950c |
return flask.render_template(
|
|
Pierre-Yves Chibon |
47950c |
'pull_request.html',
|
|
Pierre-Yves Chibon |
47950c |
select='requests',
|
|
Pierre-Yves Chibon |
04ed02 |
requestid=requestid,
|
|
Pierre-Yves Chibon |
47950c |
repo=repo,
|
|
Pierre-Yves Chibon |
41558c |
username=username,
|
|
Pierre-Yves Chibon |
87ba70 |
pull_request=request,
|
|
Pierre-Yves Chibon |
2e8ea2 |
repo_admin=is_repo_admin(request.repo),
|
|
Pierre-Yves Chibon |
47950c |
diff_commits=diff_commits,
|
|
Pierre-Yves Chibon |
e31131 |
diff=diff,
|
|
Johan Cwiklinski |
fd18bd |
mergeform=form,
|
|
Pierre-Yves Chibon |
47950c |
)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
e31131 |
|
|
Pierre-Yves Chibon |
c33710 |
@APP.route('/<repo>/request-pull/<int:requestid>.patch')</int:requestid></repo>
|
|
Pierre-Yves Chibon |
c33710 |
@APP.route('/fork/<username>/<repo>/request-pull/<int:requestid>.patch')</int:requestid></repo></username>
|
|
Pierre-Yves Chibon |
e7de33 |
def request_pull_patch(repo, requestid, username=None):
|
|
Pierre-Yves Chibon |
e7de33 |
""" Returns the commits from the specified pull-request as patches.
|
|
Pierre-Yves Chibon |
e7de33 |
"""
|
|
Pierre-Yves Chibon |
e7de33 |
|
|
Pierre-Yves Chibon |
e7de33 |
repo = progit.lib.get_project(SESSION, repo, user=username)
|
|
Pierre-Yves Chibon |
e7de33 |
|
|
Pierre-Yves Chibon |
e7de33 |
if not repo:
|
|
Pierre-Yves Chibon |
e7de33 |
flask.abort(404, 'Project not found')
|
|
Pierre-Yves Chibon |
e7de33 |
|
|
Pierre-Yves Chibon |
ff8c27 |
request = progit.lib.search_pull_requests(
|
|
Pierre-Yves Chibon |
e7de33 |
SESSION, project_id=repo.id, requestid=requestid)
|
|
Pierre-Yves Chibon |
e7de33 |
|
|
Pierre-Yves Chibon |
e7de33 |
if not request:
|
|
Pierre-Yves Chibon |
e7de33 |
flask.abort(404, 'Pull-request not found')
|
|
Pierre-Yves Chibon |
e7de33 |
|
|
Pierre-Yves Chibon |
8df273 |
repo_from = request.repo_from
|
|
Pierre-Yves Chibon |
8df273 |
repopath = _get_repo_path(repo_from)
|
|
Pierre-Yves Chibon |
e7de33 |
repo_obj = pygit2.Repository(repopath)
|
|
Pierre-Yves Chibon |
e7de33 |
|
|
Pierre-Yves Chibon |
8df273 |
parentpath = _get_parent_repo_path(repo_from)
|
|
Pierre-Yves Chibon |
8df273 |
orig_repo = pygit2.Repository(parentpath)
|
|
Pierre-Yves Chibon |
e7de33 |
|
|
Pierre-Yves Chibon |
18e007 |
branch = repo_obj.lookup_branch(request.branch_from)
|
|
Pierre-Yves Chibon |
18e007 |
commitid = branch.get_object().hex
|
|
Pierre-Yves Chibon |
18e007 |
|
|
Pierre-Yves Chibon |
e7de33 |
diff_commits = []
|
|
Pierre-Yves Chibon |
e7de33 |
if not repo_obj.is_empty and not orig_repo.is_empty:
|
|
Pierre-Yves Chibon |
e7de33 |
orig_commit = orig_repo[
|
|
Pierre-Yves Chibon |
18e007 |
orig_repo.lookup_branch(request.branch).get_object().hex]
|
|
Pierre-Yves Chibon |
e7de33 |
|
|
Pierre-Yves Chibon |
a8ed59 |
# Closed pull-request
|
|
Pierre-Yves Chibon |
a8ed59 |
if request.status is False:
|
|
Pierre-Yves Chibon |
a8ed59 |
commitid = request.commit_stop
|
|
Pierre-Yves Chibon |
a8ed59 |
for commit in repo_obj.walk(commitid, pygit2.GIT_SORT_TIME):
|
|
Pierre-Yves Chibon |
a8ed59 |
diff_commits.append(commit)
|
|
Pierre-Yves Chibon |
a8ed59 |
if commit.oid.hex == request.commit_start:
|
|
Pierre-Yves Chibon |
a8ed59 |
break
|
|
Pierre-Yves Chibon |
a8ed59 |
# Pull-request open
|
|
Pierre-Yves Chibon |
a8ed59 |
else:
|
|
Pierre-Yves Chibon |
a8ed59 |
master_commits = [
|
|
Pierre-Yves Chibon |
a8ed59 |
commit.oid.hex
|
|
Pierre-Yves Chibon |
a8ed59 |
for commit in orig_repo.walk(
|
|
Pierre-Yves Chibon |
a8ed59 |
orig_repo.lookup_branch(request.branch).get_object().hex,
|
|
Pierre-Yves Chibon |
a8ed59 |
pygit2.GIT_SORT_TIME)
|
|
Pierre-Yves Chibon |
a8ed59 |
]
|
|
Pierre-Yves Chibon |
a8ed59 |
for commit in repo_obj.walk(commitid, pygit2.GIT_SORT_TIME):
|
|
Pierre-Yves Chibon |
a8ed59 |
if request.status and commit.oid.hex in master_commits:
|
|
Pierre-Yves Chibon |
a8ed59 |
break
|
|
Pierre-Yves Chibon |
a8ed59 |
diff_commits.append(commit)
|
|
Pierre-Yves Chibon |
e7de33 |
|
|
Pierre-Yves Chibon |
e7de33 |
elif orig_repo.is_empty:
|
|
Pierre-Yves Chibon |
e7de33 |
orig_commit = None
|
|
Pierre-Yves Chibon |
60052e |
repo_commit = repo_obj[request.stop_id]
|
|
Pierre-Yves Chibon |
e7de33 |
diff = repo_commit.tree.diff_to_tree(swap=True)
|
|
Pierre-Yves Chibon |
e7de33 |
else:
|
|
Pierre-Yves Chibon |
e7de33 |
flask.flash(
|
|
Pierre-Yves Chibon |
e7de33 |
'Fork is empty, there are no commits to request pulling',
|
|
Pierre-Yves Chibon |
e7de33 |
'error')
|
|
Pierre-Yves Chibon |
e7de33 |
return flask.redirect(flask.url_for(
|
|
Pierre-Yves Chibon |
e7de33 |
'view_repo', username=username, repo=repo.name))
|
|
Pierre-Yves Chibon |
e7de33 |
|
|
Pierre-Yves Chibon |
e7de33 |
diff_commits.reverse()
|
|
Pierre-Yves Chibon |
118968 |
patch = progit.lib.git.commit_to_patch(repo_obj, diff_commits)
|
|
Pierre-Yves Chibon |
e7de33 |
|
|
Pierre-Yves Chibon |
e7de33 |
return flask.Response(patch, content_type="text/plain;charset=UTF-8")
|
|
Pierre-Yves Chibon |
e7de33 |
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
abdb8f |
@APP.route('/<repo>/request-pull/<int:requestid>/comment/<commit>/'</commit></int:requestid></repo>
|
|
Pierre-Yves Chibon |
abdb8f |
'<filename>/<row>', methods=('GET', 'POST'))</row></filename>
|
|
Pierre-Yves Chibon |
c33710 |
@APP.route('/fork/<username>/<repo>/request-pull/<int:requestid>/comment/'</int:requestid></repo></username>
|
|
Pierre-Yves Chibon |
abdb8f |
'<commit>/<filename>/<row>', methods=('GET', 'POST'))</row></filename></commit>
|
|
Pierre-Yves Chibon |
abdb8f |
def pull_request_add_comment(repo, requestid, commit, filename, row,
|
|
Pierre-Yves Chibon |
abdb8f |
username=None):
|
|
Pierre-Yves Chibon |
cb10a1 |
""" Add a comment to a commit in a pull-request.
|
|
Pierre-Yves Chibon |
cb10a1 |
"""
|
|
Pierre-Yves Chibon |
cb10a1 |
repo = progit.lib.get_project(SESSION, repo, user=username)
|
|
Pierre-Yves Chibon |
cb10a1 |
|
|
Pierre-Yves Chibon |
cb10a1 |
if not repo:
|
|
Pierre-Yves Chibon |
cb10a1 |
flask.abort(404, 'Project not found')
|
|
Pierre-Yves Chibon |
cb10a1 |
|
|
Pierre-Yves Chibon |
ff8c27 |
request = progit.lib.search_pull_requests(
|
|
Pierre-Yves Chibon |
cb10a1 |
SESSION, project_id=repo.id, requestid=requestid)
|
|
Pierre-Yves Chibon |
cb10a1 |
repo = request.repo_from
|
|
Pierre-Yves Chibon |
cb10a1 |
|
|
Pierre-Yves Chibon |
cb10a1 |
if not request:
|
|
Pierre-Yves Chibon |
cb10a1 |
flask.abort(404, 'Pull-request not found')
|
|
Pierre-Yves Chibon |
cb10a1 |
|
|
Pierre-Yves Chibon |
cb10a1 |
form = progit.forms.AddPullRequestCommentForm()
|
|
Pierre-Yves Chibon |
cb10a1 |
form.commit.data = commit
|
|
Pierre-Yves Chibon |
abdb8f |
form.filename.data = filename
|
|
Pierre-Yves Chibon |
cb10a1 |
form.requestid.data = requestid
|
|
Pierre-Yves Chibon |
cb10a1 |
form.row.data = row
|
|
Pierre-Yves Chibon |
cb10a1 |
|
|
Pierre-Yves Chibon |
248f5e |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
248f5e |
comment = form.comment.data
|
|
Pierre-Yves Chibon |
248f5e |
|
|
Pierre-Yves Chibon |
248f5e |
try:
|
|
Pierre-Yves Chibon |
248f5e |
message = progit.lib.add_pull_request_comment(
|
|
Pierre-Yves Chibon |
248f5e |
SESSION,
|
|
Pierre-Yves Chibon |
248f5e |
request=request,
|
|
Pierre-Yves Chibon |
248f5e |
commit=commit,
|
|
Pierre-Yves Chibon |
abdb8f |
filename=filename,
|
|
Pierre-Yves Chibon |
248f5e |
row=row,
|
|
Pierre-Yves Chibon |
248f5e |
comment=comment,
|
|
Pierre-Yves Chibon |
248f5e |
user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
248f5e |
)
|
|
Pierre-Yves Chibon |
248f5e |
SESSION.commit()
|
|
Pierre-Yves Chibon |
248f5e |
flask.flash(message)
|
|
Pierre-Yves Chibon |
248f5e |
except SQLAlchemyError, err: # pragma: no cover
|
|
Pierre-Yves Chibon |
248f5e |
SESSION.rollback()
|
|
Pierre-Yves Chibon |
1a6537 |
APP.logger.exception(err)
|
|
Pierre-Yves Chibon |
248f5e |
flask.flash(str(err), 'error')
|
|
Pierre-Yves Chibon |
248f5e |
|
|
Pierre-Yves Chibon |
248f5e |
return flask.redirect(flask.url_for(
|
|
Pierre-Yves Chibon |
248f5e |
'request_pull', username=username,
|
|
Pierre-Yves Chibon |
248f5e |
repo=repo.name, requestid=requestid))
|
|
Pierre-Yves Chibon |
cb10a1 |
|
|
Pierre-Yves Chibon |
cb10a1 |
return flask.render_template(
|
|
Pierre-Yves Chibon |
cb10a1 |
'pull_request_comment.html',
|
|
Pierre-Yves Chibon |
cb10a1 |
select='requests',
|
|
Pierre-Yves Chibon |
cb10a1 |
requestid=requestid,
|
|
Pierre-Yves Chibon |
cb10a1 |
repo=repo,
|
|
Pierre-Yves Chibon |
cb10a1 |
username=username,
|
|
Pierre-Yves Chibon |
cb10a1 |
commit=commit,
|
|
Pierre-Yves Chibon |
abdb8f |
filename=filename,
|
|
Pierre-Yves Chibon |
cb10a1 |
row=row,
|
|
Pierre-Yves Chibon |
cb10a1 |
form=form,
|
|
Pierre-Yves Chibon |
cb10a1 |
)
|
|
Pierre-Yves Chibon |
cb10a1 |
|
|
Pierre-Yves Chibon |
cb10a1 |
|
|
Pierre-Yves Chibon |
57116a |
@APP.route('/<repo>/request-pull/<int:requestid>/merge', methods=['POST'])</int:requestid></repo>
|
|
Pierre-Yves Chibon |
57116a |
@APP.route('/fork/<username>/<repo>/request-pull/<int:requestid>/merge',</int:requestid></repo></username>
|
|
Pierre-Yves Chibon |
0a1731 |
methods=['POST'])
|
|
Pierre-Yves Chibon |
b31474 |
def merge_request_pull(repo, requestid, username=None):
|
|
Pierre-Yves Chibon |
b31474 |
""" Request pulling the changes from the fork into the project.
|
|
Pierre-Yves Chibon |
47950c |
"""
|
|
Johan Cwiklinski |
fd18bd |
|
|
Johan Cwiklinski |
fd18bd |
form = progit.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
15e950 |
if not form.validate_on_submit():
|
|
Pierre-Yves Chibon |
15e950 |
flask.flash('Invalid input submitted', 'error')
|
|
Pierre-Yves Chibon |
15e950 |
return flask.redirect(flask.url_for('view_repo', repo=repo.name))
|
|
Johan Cwiklinski |
fd18bd |
|
|
Pierre-Yves Chibon |
47950c |
repo = progit.lib.get_project(SESSION, repo, user=username)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
if not repo:
|
|
Pierre-Yves Chibon |
47950c |
flask.abort(404, 'Project not found')
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
ff8c27 |
request = progit.lib.search_pull_requests(
|
|
Pierre-Yves Chibon |
b31474 |
SESSION, project_id=repo.id, requestid=requestid)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
b31474 |
if not request:
|
|
Pierre-Yves Chibon |
b31474 |
flask.abort(404, 'Pull-request not found')
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
4f2df5 |
if not is_repo_admin(repo):
|
|
Pierre-Yves Chibon |
4f2df5 |
flask.abort(
|
|
Pierre-Yves Chibon |
4f2df5 |
403,
|
|
Pierre-Yves Chibon |
4f2df5 |
'You are not allowed to merge pull-request for this project')
|
|
Pierre-Yves Chibon |
4f2df5 |
|
|
Pierre-Yves Chibon |
b31474 |
error_output = flask.url_for(
|
|
Pierre-Yves Chibon |
b31474 |
'request_pull', repo=repo.name, requestid=requestid)
|
|
Pierre-Yves Chibon |
b31474 |
if username:
|
|
Pierre-Yves Chibon |
b31474 |
error_output = flask.url_for(
|
|
Pierre-Yves Chibon |
b31474 |
'fork_request_pull',
|
|
Pierre-Yves Chibon |
b31474 |
repo=repo.name,
|
|
Pierre-Yves Chibon |
b31474 |
requestid=requestid,
|
|
Pierre-Yves Chibon |
b31474 |
username=username)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
b31474 |
# Get the fork
|
|
Pierre-Yves Chibon |
2c9e9f |
if request.repo_from.is_fork:
|
|
Pierre-Yves Chibon |
2c9e9f |
repopath = os.path.join(
|
|
Pierre-Yves Chibon |
2c9e9f |
APP.config['FORK_FOLDER'], request.repo_from.path)
|
|
Pierre-Yves Chibon |
2c9e9f |
else:
|
|
Pierre-Yves Chibon |
2c9e9f |
repopath = os.path.join(
|
|
Pierre-Yves Chibon |
2c9e9f |
APP.config['GIT_FOLDER'], request.repo_from.path)
|
|
Pierre-Yves Chibon |
b31474 |
fork_obj = pygit2.Repository(repopath)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
b31474 |
# Get the original repo
|
|
Pierre-Yves Chibon |
b31474 |
parentpath = os.path.join(APP.config['GIT_FOLDER'], request.repo.path)
|
|
Pierre-Yves Chibon |
b31474 |
orig_repo = pygit2.Repository(parentpath)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
b31474 |
# Clone the original repo into a temp folder
|
|
Pierre-Yves Chibon |
b31474 |
newpath = tempfile.mkdtemp()
|
|
Pierre-Yves Chibon |
b31474 |
new_repo = pygit2.clone_repository(parentpath, newpath)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
a2dd31 |
repo_commit = fork_obj[
|
|
Pierre-Yves Chibon |
a2dd31 |
fork_obj.lookup_branch(request.branch_from).get_object().hex]
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
b31474 |
ori_remote = new_repo.remotes[0]
|
|
Pierre-Yves Chibon |
b31474 |
# Add the fork as remote repo
|
|
Pierre-Yves Chibon |
e5d251 |
reponame = '%s_%s' % (request.user.user, repo.name)
|
|
Pierre-Yves Chibon |
b31474 |
remote = new_repo.create_remote(reponame, repopath)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
b31474 |
# Fetch the commits
|
|
Pierre-Yves Chibon |
b31474 |
remote.fetch()
|
|
Pierre-Yves Chibon |
b31474 |
|
|
Pierre-Yves Chibon |
b31474 |
merge = new_repo.merge(repo_commit.oid)
|
|
Pierre-Yves Chibon |
a2dd31 |
if merge is None:
|
|
Pierre-Yves Chibon |
a2dd31 |
mergecode, prefcode = new_repo.merge_analysis(repo_commit.oid)
|
|
Pierre-Yves Chibon |
a2dd31 |
|
|
Pierre-Yves Chibon |
a2dd31 |
try:
|
|
Pierre-Yves Chibon |
a2dd31 |
branch_ref = new_repo.lookup_reference(
|
|
Pierre-Yves Chibon |
a2dd31 |
request.branch).resolve()
|
|
Pierre-Yves Chibon |
a2dd31 |
except ValueError:
|
|
Pierre-Yves Chibon |
a2dd31 |
branch_ref = new_repo.lookup_reference(
|
|
Pierre-Yves Chibon |
a2dd31 |
'refs/heads/%s' % request.branch).resolve()
|
|
Pierre-Yves Chibon |
a2dd31 |
|
|
Pierre-Yves Chibon |
a2dd31 |
refname = '%s:%s' % (branch_ref.name, branch_ref.name)
|
|
Pierre-Yves Chibon |
e04c77 |
if (
|
|
Pierre-Yves Chibon |
e04c77 |
(merge is not None and merge.is_uptodate)
|
|
Pierre-Yves Chibon |
a2dd31 |
or
|
|
Pierre-Yves Chibon |
e04c77 |
(merge is None and
|
|
Pierre-Yves Chibon |
e04c77 |
mergecode & pygit2.GIT_MERGE_ANALYSIS_UP_TO_DATE
|
|
Pierre-Yves Chibon |
e04c77 |
)):
|
|
Pierre-Yves Chibon |
d5c14e |
flask.flash('Nothing to do, changes were already merged', 'error')
|
|
Pierre-Yves Chibon |
cf13ff |
progit.lib.close_pull_request(SESSION, request, flask.g.fas_user)
|
|
Pierre-Yves Chibon |
1a6537 |
try:
|
|
Pierre-Yves Chibon |
1a6537 |
SESSION.commit()
|
|
Pierre-Yves Chibon |
1a6537 |
except SQLAlchemyError as err:
|
|
Pierre-Yves Chibon |
1a6537 |
SESSION.rollback()
|
|
Pierre-Yves Chibon |
1a6537 |
APP.logger.exception(err)
|
|
Pierre-Yves Chibon |
1a6537 |
flask.flash('Could not close this pull-request', 'error')
|
|
Pierre-Yves Chibon |
d5c14e |
return flask.redirect(error_output)
|
|
Pierre-Yves Chibon |
e04c77 |
elif (
|
|
Pierre-Yves Chibon |
e04c77 |
(merge is not None and merge.is_fastforward)
|
|
Pierre-Yves Chibon |
e04c77 |
or
|
|
Pierre-Yves Chibon |
e04c77 |
(merge is None and
|
|
Pierre-Yves Chibon |
e04c77 |
mergecode & pygit2.GIT_MERGE_ANALYSIS_FASTFORWARD
|
|
Pierre-Yves Chibon |
e04c77 |
)):
|
|
Pierre-Yves Chibon |
a2dd31 |
if merge is not None:
|
|
Pierre-Yves Chibon |
a2dd31 |
branch_ref.target = merge.fastforward_oid
|
|
Pierre-Yves Chibon |
a2dd31 |
sha = merge.fastforward_oid
|
|
Pierre-Yves Chibon |
a2dd31 |
elif merge is None and mergecode is not None:
|
|
Pierre-Yves Chibon |
a2dd31 |
print repo_commit.oid
|
|
Pierre-Yves Chibon |
a2dd31 |
branch_ref.set_target(repo_commit.oid.hex)
|
|
Pierre-Yves Chibon |
a2dd31 |
sha = branch_ref.target
|
|
Pierre-Yves Chibon |
b31474 |
ori_remote.push(refname)
|
|
Pierre-Yves Chibon |
b31474 |
flask.flash('Changes merged!')
|
|
Pierre-Yves Chibon |
a2dd31 |
|
|
Pierre-Yves Chibon |
b31474 |
else:
|
|
Pierre-Yves Chibon |
59b3a3 |
new_repo.index.write()
|
|
Pierre-Yves Chibon |
2c9e9f |
try:
|
|
Pierre-Yves Chibon |
2c9e9f |
tree = new_repo.index.write_tree()
|
|
Pierre-Yves Chibon |
2c9e9f |
except pygit2.GitError:
|
|
Pierre-Yves Chibon |
be7090 |
shutil.rmtree(newpath)
|
|
Pierre-Yves Chibon |
2c9e9f |
flask.flash('Merge conflicts!', 'error')
|
|
Pierre-Yves Chibon |
2c9e9f |
return flask.redirect(flask.url_for(
|
|
Pierre-Yves Chibon |
2c9e9f |
'request_pull',
|
|
Pierre-Yves Chibon |
2c9e9f |
repo=repo.name,
|
|
Pierre-Yves Chibon |
2c9e9f |
username=username,
|
|
Pierre-Yves Chibon |
2c9e9f |
requestid=requestid))
|
|
Pierre-Yves Chibon |
59b3a3 |
head = new_repo.lookup_reference('HEAD').get_object()
|
|
Pierre-Yves Chibon |
59b3a3 |
commit = new_repo[head.oid]
|
|
Pierre-Yves Chibon |
59b3a3 |
sha = new_repo.create_commit(
|
|
Pierre-Yves Chibon |
59b3a3 |
'refs/heads/master',
|
|
Pierre-Yves Chibon |
59b3a3 |
repo_commit.author,
|
|
Pierre-Yves Chibon |
59b3a3 |
repo_commit.committer,
|
|
Pierre-Yves Chibon |
59b3a3 |
'Merge #%s `%s`' % (request.id, request.title),
|
|
Pierre-Yves Chibon |
59b3a3 |
tree,
|
|
Pierre-Yves Chibon |
59b3a3 |
[head.hex, repo_commit.oid.hex])
|
|
Pierre-Yves Chibon |
59b3a3 |
ori_remote.push(refname)
|
|
Pierre-Yves Chibon |
59b3a3 |
flask.flash('Changes merged!')
|
|
Pierre-Yves Chibon |
b31474 |
|
|
Pierre-Yves Chibon |
b31474 |
# Update status
|
|
Pierre-Yves Chibon |
f7606b |
progit.lib.close_pull_request(SESSION, request, flask.g.fas_user)
|
|
Pierre-Yves Chibon |
1a6537 |
try:
|
|
Pierre-Yves Chibon |
1a6537 |
SESSION.commit()
|
|
Pierre-Yves Chibon |
1a6537 |
except SQLAlchemyError as err:
|
|
Pierre-Yves Chibon |
1a6537 |
SESSION.rollback()
|
|
Pierre-Yves Chibon |
1a6537 |
APP.logger.exception(err)
|
|
Pierre-Yves Chibon |
1a6537 |
flask.flash(
|
|
Pierre-Yves Chibon |
1a6537 |
'Could not update this pull-request in the database',
|
|
Pierre-Yves Chibon |
1a6537 |
'error')
|
|
Pierre-Yves Chibon |
be7090 |
shutil.rmtree(newpath)
|
|
Pierre-Yves Chibon |
b31474 |
|
|
Pierre-Yves Chibon |
b31474 |
return flask.redirect(flask.url_for('view_repo', repo=repo.name))
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
c33710 |
@APP.route('/<repo>/request-pull/cancel/<int:requestid>',</int:requestid></repo>
|
|
Pierre-Yves Chibon |
e04c77 |
methods=['POST'])
|
|
Pierre-Yves Chibon |
c33710 |
@APP.route('/fork/<username>/<repo>/request-pull/cancel/<int:requestid>',</int:requestid></repo></username>
|
|
Pierre-Yves Chibon |
e04c77 |
methods=['POST'])
|
|
Johan Cwiklinski |
86d9c4 |
def cancel_request_pull(repo, requestid, username=None):
|
|
Johan Cwiklinski |
86d9c4 |
""" Cancel request pulling request.
|
|
Johan Cwiklinski |
86d9c4 |
"""
|
|
Johan Cwiklinski |
fd18bd |
|
|
Johan Cwiklinski |
fd18bd |
form = progit.forms.ConfirmationForm()
|
|
Pierre-Yves Chibon |
15e950 |
if form.validate_on_submit():
|
|
Johan Cwiklinski |
fd18bd |
|
|
Pierre-Yves Chibon |
15e950 |
repo = progit.lib.get_project(SESSION, repo, user=username)
|
|
Johan Cwiklinski |
86d9c4 |
|
|
Pierre-Yves Chibon |
15e950 |
if not repo:
|
|
Pierre-Yves Chibon |
15e950 |
flask.abort(404, 'Project not found')
|
|
Johan Cwiklinski |
86d9c4 |
|
|
Pierre-Yves Chibon |
ff8c27 |
request = progit.lib.search_pull_requests(
|
|
Pierre-Yves Chibon |
15e950 |
SESSION, project_id=repo.id, requestid=requestid)
|
|
Johan Cwiklinski |
86d9c4 |
|
|
Pierre-Yves Chibon |
15e950 |
if not request:
|
|
Pierre-Yves Chibon |
15e950 |
flask.abort(404, 'Pull-request not found')
|
|
Johan Cwiklinski |
86d9c4 |
|
|
Pierre-Yves Chibon |
15e950 |
if not is_repo_admin(repo):
|
|
Pierre-Yves Chibon |
15e950 |
flask.abort(
|
|
Pierre-Yves Chibon |
15e950 |
403,
|
|
Pierre-Yves Chibon |
15e950 |
'You are not allowed to cancel pull-request for this project')
|
|
Johan Cwiklinski |
86d9c4 |
|
|
Pierre-Yves Chibon |
f7606b |
progit.lib.close_pull_request(
|
|
Pierre-Yves Chibon |
f7606b |
SESSION, request, flask.g.fas_user, merged=False)
|
|
Pierre-Yves Chibon |
d8fde8 |
try:
|
|
Pierre-Yves Chibon |
d8fde8 |
SESSION.commit()
|
|
Pierre-Yves Chibon |
d8fde8 |
flask.flash('Request pull canceled!')
|
|
Pierre-Yves Chibon |
d8fde8 |
except SQLAlchemyError as err:
|
|
Pierre-Yves Chibon |
d8fde8 |
SESSION.rollback()
|
|
Pierre-Yves Chibon |
d8fde8 |
APP.logger.exception(err)
|
|
Pierre-Yves Chibon |
d8fde8 |
flask.flash(
|
|
Pierre-Yves Chibon |
d8fde8 |
'Could not update this pull-request in the database',
|
|
Pierre-Yves Chibon |
d8fde8 |
'error')
|
|
Pierre-Yves Chibon |
15e950 |
else:
|
|
Pierre-Yves Chibon |
15e950 |
flask.flash('Invalid input submitted', 'error')
|
|
Johan Cwiklinski |
86d9c4 |
|
|
Johan Cwiklinski |
86d9c4 |
return flask.redirect(flask.url_for('view_repo', repo=repo.name))
|
|
Johan Cwiklinski |
86d9c4 |
|
|
Johan Cwiklinski |
86d9c4 |
|
|
Pierre-Yves Chibon |
e04c77 |
# Specific actions
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
e03e84 |
@APP.route('/do_fork/<repo>')</repo>
|
|
Pierre-Yves Chibon |
e03e84 |
@APP.route('/do_fork/<username>/<repo>')</repo></username>
|
|
Pierre-Yves Chibon |
d5e3d0 |
@cla_required
|
|
Pierre-Yves Chibon |
20ccbb |
def fork_project(repo, username=None):
|
|
Pierre-Yves Chibon |
fac0b1 |
""" Fork the project specified into the user's namespace
|
|
Pierre-Yves Chibon |
fac0b1 |
"""
|
|
Pierre-Yves Chibon |
20ccbb |
repo = progit.lib.get_project(SESSION, repo, user=username)
|
|
Pierre-Yves Chibon |
80bba3 |
|
|
Pierre-Yves Chibon |
80bba3 |
if repo is None:
|
|
Pierre-Yves Chibon |
fac0b1 |
flask.abort(404)
|
|
Pierre-Yves Chibon |
fac0b1 |
|
|
Pierre-Yves Chibon |
80bba3 |
try:
|
|
Pierre-Yves Chibon |
80bba3 |
message = progit.lib.fork_project(
|
|
Pierre-Yves Chibon |
80bba3 |
session=SESSION,
|
|
Pierre-Yves Chibon |
80bba3 |
repo=repo,
|
|
Pierre-Yves Chibon |
e54062 |
gitfolder=APP.config['GIT_FOLDER'],
|
|
Pierre-Yves Chibon |
6160b6 |
forkfolder=APP.config['FORK_FOLDER'],
|
|
Pierre-Yves Chibon |
4b7a7d |
docfolder=APP.config['DOCS_FOLDER'],
|
|
Pierre-Yves Chibon |
a33978 |
ticketfolder=APP.config['TICKETS_FOLDER'],
|
|
Pierre-Yves Chibon |
80bba3 |
user=flask.g.fas_user.username)
|
|
Pierre-Yves Chibon |
80bba3 |
|
|
Pierre-Yves Chibon |
80bba3 |
SESSION.commit()
|
|
Pierre-Yves Chibon |
59be40 |
generate_gitolite_acls()
|
|
Pierre-Yves Chibon |
80bba3 |
flask.flash(message)
|
|
Pierre-Yves Chibon |
80bba3 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
792a86 |
flask.url_for(
|
|
Pierre-Yves Chibon |
ea8735 |
'view_repo',
|
|
Pierre-Yves Chibon |
792a86 |
username=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
792a86 |
repo=repo.name)
|
|
Pierre-Yves Chibon |
80bba3 |
)
|
|
Pierre-Yves Chibon |
80bba3 |
except progit.exceptions.ProgitException, err:
|
|
Pierre-Yves Chibon |
80bba3 |
flask.flash(str(err), 'error')
|
|
Pierre-Yves Chibon |
80bba3 |
except SQLAlchemyError, err: # pragma: no cover
|
|
Pierre-Yves Chibon |
80bba3 |
SESSION.rollback()
|
|
Pierre-Yves Chibon |
80bba3 |
flask.flash(str(err), 'error')
|
|
Pierre-Yves Chibon |
80bba3 |
|
|
Pierre-Yves Chibon |
792a86 |
return flask.redirect(flask.url_for('view_repo', repo=repo.name))
|
|
Pierre-Yves Chibon |
fac0b1 |
|
|
Pierre-Yves Chibon |
fac0b1 |
|
|
Pierre-Yves Chibon |
6d60d2 |
@APP.route('/<repo>/diff/<branch_to>..<branch_from>',</branch_from></branch_to></repo>
|
|
Pierre-Yves Chibon |
2c9e9f |
methods=('GET', 'POST'))
|
|
Pierre-Yves Chibon |
6d60d2 |
@APP.route('/fork/<username>/<repo>/diff/<branch_to>..<branch_from>',</branch_from></branch_to></repo></username>
|
|
Pierre-Yves Chibon |
ac8023 |
methods=('GET', 'POST'))
|
|
Pierre-Yves Chibon |
d5e3d0 |
@cla_required
|
|
Pierre-Yves Chibon |
6d60d2 |
def new_request_pull(repo, branch_to, branch_from, username=None):
|
|
Pierre-Yves Chibon |
82055c |
""" Request pulling the changes from the fork into the project.
|
|
Pierre-Yves Chibon |
82055c |
"""
|
|
Pierre-Yves Chibon |
82055c |
repo = progit.lib.get_project(SESSION, repo, user=username)
|
|
Pierre-Yves Chibon |
82055c |
|
|
Pierre-Yves Chibon |
82055c |
if not repo:
|
|
Pierre-Yves Chibon |
82055c |
flask.abort(404)
|
|
Pierre-Yves Chibon |
82055c |
|
|
Pierre-Yves Chibon |
1e5fe9 |
if not is_repo_admin(repo):
|
|
Pierre-Yves Chibon |
1e5fe9 |
flask.abort(
|
|
Pierre-Yves Chibon |
1e5fe9 |
403,
|
|
Pierre-Yves Chibon |
1e5fe9 |
'You are not allowed to create pull-requests for this project')
|
|
Pierre-Yves Chibon |
1e5fe9 |
|
|
Pierre-Yves Chibon |
8df273 |
repopath = _get_repo_path(repo)
|
|
Pierre-Yves Chibon |
85755c |
repo_obj = pygit2.Repository(repopath)
|
|
Pierre-Yves Chibon |
82055c |
|
|
Pierre-Yves Chibon |
8df273 |
parentpath = _get_parent_repo_path(repo)
|
|
Pierre-Yves Chibon |
8df273 |
orig_repo = pygit2.Repository(parentpath)
|
|
Pierre-Yves Chibon |
82055c |
|
|
Pierre-Yves Chibon |
6d60d2 |
frombranch = repo_obj.lookup_branch(branch_from)
|
|
Pierre-Yves Chibon |
24542f |
if not frombranch:
|
|
Pierre-Yves Chibon |
6d60d2 |
flask.abort(
|
|
Pierre-Yves Chibon |
6d60d2 |
400,
|
|
Pierre-Yves Chibon |
6d60d2 |
'Branch %s does not exist' % branch_from)
|
|
Pierre-Yves Chibon |
24542f |
|
|
Pierre-Yves Chibon |
6d60d2 |
branch = orig_repo.lookup_branch(branch_to)
|
|
Pierre-Yves Chibon |
efda13 |
if not branch:
|
|
Pierre-Yves Chibon |
6d60d2 |
flask.abort(
|
|
Pierre-Yves Chibon |
6d60d2 |
400,
|
|
Pierre-Yves Chibon |
6d60d2 |
'Branch %s could not be found in the target repo' % branch_to)
|
|
Pierre-Yves Chibon |
efda13 |
|
|
Pierre-Yves Chibon |
6d60d2 |
branch = repo_obj.lookup_branch(branch_from)
|
|
Pierre-Yves Chibon |
6d60d2 |
commitid = branch.get_object().hex
|
|
Pierre-Yves Chibon |
82055c |
|
|
Pierre-Yves Chibon |
82055c |
diff_commits = []
|
|
Pierre-Yves Chibon |
82055c |
if not repo_obj.is_empty and not orig_repo.is_empty:
|
|
Pierre-Yves Chibon |
2c9e9f |
orig_commit = orig_repo[
|
|
Pierre-Yves Chibon |
6d60d2 |
orig_repo.lookup_branch(branch_to).get_object().hex]
|
|
Pierre-Yves Chibon |
2c9e9f |
|
|
Pierre-Yves Chibon |
2c9e9f |
master_commits = [
|
|
Pierre-Yves Chibon |
2c9e9f |
commit.oid.hex
|
|
Pierre-Yves Chibon |
2c9e9f |
for commit in orig_repo.walk(
|
|
Pierre-Yves Chibon |
6d60d2 |
orig_commit.oid.hex, pygit2.GIT_SORT_TIME)
|
|
Pierre-Yves Chibon |
2c9e9f |
]
|
|
Pierre-Yves Chibon |
2c9e9f |
|
|
Pierre-Yves Chibon |
82055c |
repo_commit = repo_obj[commitid]
|
|
Pierre-Yves Chibon |
82055c |
|
|
Pierre-Yves Chibon |
2c9e9f |
for commit in repo_obj.walk(
|
|
Pierre-Yves Chibon |
2c9e9f |
repo_commit.oid.hex, pygit2.GIT_SORT_TIME):
|
|
Pierre-Yves Chibon |
2c9e9f |
if commit.oid.hex in master_commits:
|
|
Pierre-Yves Chibon |
82055c |
break
|
|
Pierre-Yves Chibon |
82055c |
diff_commits.append(commit)
|
|
Pierre-Yves Chibon |
6d60d2 |
|
|
Pierre-Yves Chibon |
6d60d2 |
first_commit = repo_obj[diff_commits[-1].oid.hex]
|
|
Pierre-Yves Chibon |
6d60d2 |
diff = repo_obj.diff(
|
|
Pierre-Yves Chibon |
6d60d2 |
repo_obj.revparse_single(first_commit.parents[0].oid.hex),
|
|
Pierre-Yves Chibon |
6d60d2 |
repo_obj.revparse_single(diff_commits[0].oid.hex)
|
|
Pierre-Yves Chibon |
6d60d2 |
)
|
|
Pierre-Yves Chibon |
82055c |
|
|
Pierre-Yves Chibon |
82055c |
elif orig_repo.is_empty:
|
|
Pierre-Yves Chibon |
ac8023 |
orig_commit = None
|
|
Pierre-Yves Chibon |
85755c |
repo_commit = repo_obj[repo_obj.head.target]
|
|
Pierre-Yves Chibon |
85755c |
diff = repo_commit.tree.diff_to_tree(swap=True)
|
|
Pierre-Yves Chibon |
82055c |
else:
|
|
Pierre-Yves Chibon |
82055c |
flask.flash(
|
|
Pierre-Yves Chibon |
82055c |
'Fork is empty, there are no commits to request pulling',
|
|
Pierre-Yves Chibon |
82055c |
'error')
|
|
Pierre-Yves Chibon |
82055c |
return flask.redirect(flask.url_for(
|
|
Pierre-Yves Chibon |
ea8735 |
'view_repo', username=username, repo=repo.name))
|
|
Pierre-Yves Chibon |
82055c |
|
|
Pierre-Yves Chibon |
ac8023 |
form = progit.forms.RequestPullForm()
|
|
Pierre-Yves Chibon |
ac8023 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
ac8023 |
try:
|
|
Pierre-Yves Chibon |
ac8023 |
if orig_commit:
|
|
Pierre-Yves Chibon |
ac8023 |
orig_commit = orig_commit.oid.hex
|
|
Pierre-Yves Chibon |
2c9e9f |
|
|
Pierre-Yves Chibon |
2c9e9f |
parent = repo
|
|
Pierre-Yves Chibon |
2c9e9f |
if repo.parent:
|
|
Pierre-Yves Chibon |
2c9e9f |
parent = repo.parent
|
|
Pierre-Yves Chibon |
2c9e9f |
|
|
Pierre-Yves Chibon |
ac8023 |
message = progit.lib.new_pull_request(
|
|
Pierre-Yves Chibon |
ac8023 |
SESSION,
|
|
Pierre-Yves Chibon |
6d60d2 |
repo_to=parent,
|
|
Pierre-Yves Chibon |
6d60d2 |
branch_to=branch_to,
|
|
Pierre-Yves Chibon |
6d60d2 |
branch_from=branch_from,
|
|
Pierre-Yves Chibon |
ac8023 |
repo_from=repo,
|
|
Pierre-Yves Chibon |
ac8023 |
title=form.title.data,
|
|
Pierre-Yves Chibon |
ac8023 |
user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
ac8023 |
)
|
|
Pierre-Yves Chibon |
d8fde8 |
try:
|
|
Pierre-Yves Chibon |
d8fde8 |
SESSION.commit()
|
|
Pierre-Yves Chibon |
d8fde8 |
flask.flash(message)
|
|
Pierre-Yves Chibon |
d8fde8 |
except SQLAlchemyError as err:
|
|
Pierre-Yves Chibon |
d8fde8 |
SESSION.rollback()
|
|
Pierre-Yves Chibon |
d8fde8 |
APP.logger.exception(err)
|
|
Pierre-Yves Chibon |
d8fde8 |
flask.flash(
|
|
Pierre-Yves Chibon |
d8fde8 |
'Could not register this pull-request in the database',
|
|
Pierre-Yves Chibon |
d8fde8 |
'error')
|
|
Pierre-Yves Chibon |
8399d1 |
|
|
Pierre-Yves Chibon |
2c9e9f |
if not parent.is_fork:
|
|
Pierre-Yves Chibon |
8399d1 |
url = flask.url_for(
|
|
Pierre-Yves Chibon |
2c9e9f |
'request_pulls', username=None, repo=parent.name)
|
|
Pierre-Yves Chibon |
8399d1 |
else:
|
|
Pierre-Yves Chibon |
8399d1 |
url = flask.url_for(
|
|
Pierre-Yves Chibon |
2c9e9f |
'request_pulls', username=parent.user, repo=parent.name)
|
|
Pierre-Yves Chibon |
8399d1 |
|
|
Pierre-Yves Chibon |
8399d1 |
return flask.redirect(url)
|
|
Pierre-Yves Chibon |
ac8023 |
except progit.exceptions.ProgitException, err:
|
|
Pierre-Yves Chibon |
ac8023 |
flask.flash(str(err), 'error')
|
|
Pierre-Yves Chibon |
ac8023 |
except SQLAlchemyError, err: # pragma: no cover
|
|
Pierre-Yves Chibon |
ac8023 |
SESSION.rollback()
|
|
Pierre-Yves Chibon |
ac8023 |
flask.flash(str(err), 'error')
|
|
Pierre-Yves Chibon |
ac8023 |
|
|
Pierre-Yves Chibon |
82055c |
return flask.render_template(
|
|
Pierre-Yves Chibon |
82055c |
'pull_request.html',
|
|
Pierre-Yves Chibon |
0c4c0b |
select='requests',
|
|
Pierre-Yves Chibon |
82055c |
repo=repo,
|
|
Pierre-Yves Chibon |
82055c |
username=username,
|
|
Pierre-Yves Chibon |
82055c |
repo_obj=repo_obj,
|
|
Pierre-Yves Chibon |
82055c |
orig_repo=orig_repo,
|
|
Pierre-Yves Chibon |
82055c |
diff_commits=diff_commits,
|
|
Pierre-Yves Chibon |
6d60d2 |
diff=diff,
|
|
Pierre-Yves Chibon |
ac8023 |
form=form,
|
|
Pierre-Yves Chibon |
658f7c |
branches=[
|
|
Pierre-Yves Chibon |
658f7c |
branch.replace('refs/heads/', '')
|
|
Pierre-Yves Chibon |
658f7c |
for branch in sorted(orig_repo.listall_references())
|
|
Pierre-Yves Chibon |
658f7c |
],
|
|
Pierre-Yves Chibon |
6d60d2 |
branch_to=branch_to,
|
|
Pierre-Yves Chibon |
6d60d2 |
branch_from=branch_from,
|
|
Pierre-Yves Chibon |
82055c |
)
|