|
Pierre-Yves Chibon |
fac0b1 |
#-*- 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 |
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 |
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 |
b31474 |
requests = progit.lib.get_pull_requests(
|
|
Pierre-Yves Chibon |
b31474 |
SESSION, project_id=repo.id, status=False)
|
|
Pierre-Yves Chibon |
47950c |
else:
|
|
Pierre-Yves Chibon |
b31474 |
requests = progit.lib.get_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 |
b31474 |
@APP.route('/<repo>/request-pull/<requestid>')</requestid></repo>
|
|
Pierre-Yves Chibon |
b31474 |
@APP.route('/fork/<username>/<repo>/request-pull/<requestid>')</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 |
47950c |
request = progit.lib.get_pull_request(
|
|
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 |
2c9e9f |
if repo.is_fork:
|
|
Pierre-Yves Chibon |
2c9e9f |
repopath = os.path.join(APP.config['FORK_FOLDER'], repo.path)
|
|
Pierre-Yves Chibon |
2c9e9f |
else:
|
|
Pierre-Yves Chibon |
2c9e9f |
repopath = os.path.join(APP.config['GIT_FOLDER'], repo.path)
|
|
Pierre-Yves Chibon |
47950c |
repo_obj = pygit2.Repository(repopath)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
2c9e9f |
if repo.parent:
|
|
Pierre-Yves Chibon |
2c9e9f |
parentname = os.path.join(APP.config['GIT_FOLDER'], repo.parent.path)
|
|
Pierre-Yves Chibon |
2c9e9f |
else:
|
|
Pierre-Yves Chibon |
2c9e9f |
parentname = os.path.join(APP.config['GIT_FOLDER'], repo.path)
|
|
Pierre-Yves Chibon |
47950c |
orig_repo = pygit2.Repository(parentname)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
diff_commits = []
|
|
Pierre-Yves Chibon |
47950c |
diffs = []
|
|
Pierre-Yves Chibon |
47950c |
repo_commit = repo_obj[request.stop_id]
|
|
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 |
2c9e9f |
orig_repo.lookup_branch('master').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 |
2c9e9f |
orig_repo.lookup_branch('master').get_object().hex,
|
|
Pierre-Yves Chibon |
2c9e9f |
pygit2.GIT_SORT_TIME)
|
|
Pierre-Yves Chibon |
2c9e9f |
]
|
|
Pierre-Yves Chibon |
2c9e9f |
|
|
Pierre-Yves Chibon |
2c9e9f |
repo_commit = repo_obj[request.start_id]
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
2c9e9f |
for commit in repo_obj.walk(
|
|
Pierre-Yves Chibon |
2c9e9f |
request.stop_id, pygit2.GIT_SORT_TIME):
|
|
Pierre-Yves Chibon |
2c9e9f |
if commit.oid.hex in master_commits:
|
|
Pierre-Yves Chibon |
47950c |
break
|
|
Pierre-Yves Chibon |
47950c |
diff_commits.append(commit)
|
|
Pierre-Yves Chibon |
47950c |
diffs.append(
|
|
Pierre-Yves Chibon |
47950c |
repo_obj.diff(
|
|
Pierre-Yves Chibon |
47950c |
repo_obj.revparse_single(commit.parents[0].oid.hex),
|
|
Pierre-Yves Chibon |
47950c |
repo_obj.revparse_single(commit.oid.hex)
|
|
Pierre-Yves Chibon |
47950c |
)
|
|
Pierre-Yves Chibon |
47950c |
)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
elif orig_repo.is_empty:
|
|
Pierre-Yves Chibon |
47950c |
orig_commit = None
|
|
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 |
|
|
Pierre-Yves Chibon |
47950c |
html_diffs = []
|
|
Pierre-Yves Chibon |
47950c |
for diff in diffs:
|
|
Pierre-Yves Chibon |
47950c |
html_diffs.append(
|
|
Pierre-Yves Chibon |
47950c |
highlight(
|
|
Pierre-Yves Chibon |
47950c |
diff.patch,
|
|
Pierre-Yves Chibon |
47950c |
DiffLexer(),
|
|
Pierre-Yves Chibon |
47950c |
HtmlFormatter(
|
|
Pierre-Yves Chibon |
47950c |
noclasses=True,
|
|
Pierre-Yves Chibon |
47950c |
style="tango",)
|
|
Pierre-Yves Chibon |
47950c |
)
|
|
Pierre-Yves Chibon |
47950c |
)
|
|
Pierre-Yves Chibon |
47950c |
|
|
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 |
47950c |
request=request,
|
|
Pierre-Yves Chibon |
2e8ea2 |
repo_admin=is_repo_admin(request.repo),
|
|
Pierre-Yves Chibon |
47950c |
repo_obj=repo_obj,
|
|
Pierre-Yves Chibon |
47950c |
orig_repo=orig_repo,
|
|
Pierre-Yves Chibon |
47950c |
diff_commits=diff_commits,
|
|
Pierre-Yves Chibon |
47950c |
diffs=diffs,
|
|
Pierre-Yves Chibon |
47950c |
html_diffs=html_diffs,
|
|
Pierre-Yves Chibon |
47950c |
)
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
47950c |
|
|
Pierre-Yves Chibon |
b31474 |
@APP.route('/<repo>/request-pull/merge/<requestid>')</requestid></repo>
|
|
Pierre-Yves Chibon |
b31474 |
@APP.route('/fork/<username>/<repo>/request-pull/merge/<requestid>')</requestid></repo></username>
|
|
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 |
"""
|
|
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 |
request = progit.lib.get_pull_request(
|
|
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 |
b31474 |
repo_commit = fork_obj[request.stop_id]
|
|
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 |
b31474 |
master_ref = new_repo.lookup_reference('HEAD').resolve()
|
|
Pierre-Yves Chibon |
b31474 |
|
|
Pierre-Yves Chibon |
59b3a3 |
refname = '%s:%s' % (master_ref.name, master_ref.name)
|
|
Pierre-Yves Chibon |
d5c14e |
if merge.is_uptodate:
|
|
Pierre-Yves Chibon |
d5c14e |
flask.flash('Nothing to do, changes were already merged', 'error')
|
|
Pierre-Yves Chibon |
d5c14e |
progit.lib.close_pull_request(SESSION, request)
|
|
Pierre-Yves Chibon |
d5c14e |
SESSION.commit()
|
|
Pierre-Yves Chibon |
d5c14e |
return flask.redirect(error_output)
|
|
Pierre-Yves Chibon |
d5c14e |
elif merge.is_fastforward:
|
|
Pierre-Yves Chibon |
b31474 |
master_ref.target = merge.fastforward_oid
|
|
Pierre-Yves Chibon |
b31474 |
ori_remote.push(refname)
|
|
Pierre-Yves Chibon |
b31474 |
flask.flash('Changes merged!')
|
|
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 |
b31474 |
progit.lib.close_pull_request(SESSION, request)
|
|
Pierre-Yves Chibon |
b31474 |
SESSION.commit()
|
|
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 |
47950c |
## 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 |
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 |
2c9e9f |
@APP.route('/<repo>/request-pull/new',</repo>
|
|
Pierre-Yves Chibon |
2c9e9f |
methods=('GET', 'POST'))
|
|
Pierre-Yves Chibon |
2c9e9f |
@APP.route('/<repo>/request-pull/new/<commitid>',</commitid></repo>
|
|
Pierre-Yves Chibon |
2c9e9f |
methods=('GET', 'POST'))
|
|
Pierre-Yves Chibon |
ac8023 |
@APP.route('/fork/<username>/<repo>/request-pull/new',</repo></username>
|
|
Pierre-Yves Chibon |
3bb858 |
methods=('GET', 'POST'))
|
|
Pierre-Yves Chibon |
ac8023 |
@APP.route('/fork/<username>/<repo>/request-pull/new/<commitid>',</commitid></repo></username>
|
|
Pierre-Yves Chibon |
ac8023 |
methods=('GET', 'POST'))
|
|
Pierre-Yves Chibon |
d5e3d0 |
@cla_required
|
|
Pierre-Yves Chibon |
2c9e9f |
def new_request_pull(repo, username=None, commitid=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 |
2c9e9f |
if repo.is_fork:
|
|
Pierre-Yves Chibon |
2c9e9f |
repopath = os.path.join(APP.config['FORK_FOLDER'], repo.path)
|
|
Pierre-Yves Chibon |
2c9e9f |
else:
|
|
Pierre-Yves Chibon |
2c9e9f |
repopath = os.path.join(APP.config['GIT_FOLDER'], repo.path)
|
|
Pierre-Yves Chibon |
85755c |
repo_obj = pygit2.Repository(repopath)
|
|
Pierre-Yves Chibon |
82055c |
|
|
Pierre-Yves Chibon |
2c9e9f |
if repo.parent:
|
|
Pierre-Yves Chibon |
2c9e9f |
parentname = os.path.join(APP.config['GIT_FOLDER'], repo.parent.path)
|
|
Pierre-Yves Chibon |
2c9e9f |
else:
|
|
Pierre-Yves Chibon |
2c9e9f |
parentname = os.path.join(APP.config['GIT_FOLDER'], repo.path)
|
|
Pierre-Yves Chibon |
82055c |
orig_repo = pygit2.Repository(parentname)
|
|
Pierre-Yves Chibon |
82055c |
|
|
Pierre-Yves Chibon |
82055c |
if commitid is None:
|
|
Pierre-Yves Chibon |
82055c |
commitid = repo_obj.head.target
|
|
Pierre-Yves Chibon |
e990b6 |
branchname = flask.request.args.get('branch', None)
|
|
Pierre-Yves Chibon |
e990b6 |
if branchname:
|
|
Pierre-Yves Chibon |
e990b6 |
branch = repo_obj.lookup_branch(branchname)
|
|
Pierre-Yves Chibon |
e990b6 |
commitid = branch.get_object().hex
|
|
Pierre-Yves Chibon |
82055c |
|
|
Pierre-Yves Chibon |
82055c |
diff_commits = []
|
|
Pierre-Yves Chibon |
82055c |
diffs = []
|
|
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 |
2c9e9f |
orig_repo.lookup_branch('master').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 |
2c9e9f |
orig_repo.lookup_branch('master').get_object().hex,
|
|
Pierre-Yves Chibon |
2c9e9f |
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 |
82055c |
diffs.append(
|
|
Pierre-Yves Chibon |
82055c |
repo_obj.diff(
|
|
Pierre-Yves Chibon |
82055c |
repo_obj.revparse_single(commit.parents[0].oid.hex),
|
|
Pierre-Yves Chibon |
82055c |
repo_obj.revparse_single(commit.oid.hex)
|
|
Pierre-Yves Chibon |
82055c |
)
|
|
Pierre-Yves Chibon |
82055c |
)
|
|
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 |
82055c |
html_diffs = []
|
|
Pierre-Yves Chibon |
82055c |
for diff in diffs:
|
|
Pierre-Yves Chibon |
82055c |
html_diffs.append(
|
|
Pierre-Yves Chibon |
82055c |
highlight(
|
|
Pierre-Yves Chibon |
82055c |
diff.patch,
|
|
Pierre-Yves Chibon |
82055c |
DiffLexer(),
|
|
Pierre-Yves Chibon |
82055c |
HtmlFormatter(
|
|
Pierre-Yves Chibon |
82055c |
noclasses=True,
|
|
Pierre-Yves Chibon |
82055c |
style="tango",)
|
|
Pierre-Yves Chibon |
82055c |
)
|
|
Pierre-Yves Chibon |
82055c |
)
|
|
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 |
2c9e9f |
repo=parent,
|
|
Pierre-Yves Chibon |
ac8023 |
repo_from=repo,
|
|
Pierre-Yves Chibon |
ac8023 |
title=form.title.data,
|
|
Pierre-Yves Chibon |
ac8023 |
start_id=orig_commit,
|
|
Pierre-Yves Chibon |
ac8023 |
stop_id=repo_commit.oid.hex,
|
|
Pierre-Yves Chibon |
ac8023 |
user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
ac8023 |
)
|
|
Pierre-Yves Chibon |
ac8023 |
SESSION.commit()
|
|
Pierre-Yves Chibon |
ac8023 |
flask.flash(message)
|
|
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 |
ac8023 |
commitid=commitid,
|
|
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 |
82055c |
diffs=diffs,
|
|
Pierre-Yves Chibon |
82055c |
html_diffs=html_diffs,
|
|
Pierre-Yves Chibon |
ac8023 |
form=form,
|
|
Pierre-Yves Chibon |
82055c |
)
|