|
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 |
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 |
f39cd3 |
from progit import APP, SESSION, LOG, __get_file_in_tree
|
|
Pierre-Yves Chibon |
fac0b1 |
|
|
Pierre-Yves Chibon |
fac0b1 |
|
|
Pierre-Yves Chibon |
fac0b1 |
### Application
|
|
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 |
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 |
80bba3 |
repo_folder=APP.config['GIT_FOLDER'],
|
|
Pierre-Yves Chibon |
80bba3 |
fork_folder=APP.config['FORK_FOLDER'],
|
|
Pierre-Yves Chibon |
80bba3 |
user=flask.g.fas_user.username)
|
|
Pierre-Yves Chibon |
80bba3 |
|
|
Pierre-Yves Chibon |
80bba3 |
SESSION.commit()
|
|
Pierre-Yves Chibon |
80bba3 |
flask.flash(message)
|
|
Pierre-Yves Chibon |
80bba3 |
return flask.redirect(
|
|
Pierre-Yves Chibon |
792a86 |
flask.url_for(
|
|
Pierre-Yves Chibon |
792a86 |
'view_fork_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 |
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 |
ac8023 |
def new_request_pull(username, repo, 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 |
ebf29e |
repopath = os.path.join(APP.config['FORK_FOLDER'], repo.path)
|
|
Pierre-Yves Chibon |
85755c |
repo_obj = pygit2.Repository(repopath)
|
|
Pierre-Yves Chibon |
82055c |
|
|
Pierre-Yves Chibon |
82055c |
parentname = os.path.join(APP.config['GIT_FOLDER'], repo.parent.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 |
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 |
82055c |
orig_commit = orig_repo[orig_repo.head.target]
|
|
Pierre-Yves Chibon |
82055c |
repo_commit = repo_obj[commitid]
|
|
Pierre-Yves Chibon |
82055c |
|
|
Pierre-Yves Chibon |
82055c |
for commit in repo_obj.walk(commitid, pygit2.GIT_SORT_TIME):
|
|
Pierre-Yves Chibon |
82055c |
if commit.oid.hex == orig_commit.oid.hex:
|
|
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 |
82055c |
'view_fork_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 |
ac8023 |
message = progit.lib.new_pull_request(
|
|
Pierre-Yves Chibon |
ac8023 |
SESSION,
|
|
Pierre-Yves Chibon |
ac8023 |
repo=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 |
ac8023 |
return flask.redirect(flask.url_for(
|
|
Pierre-Yves Chibon |
ac8023 |
'view_fork_issues', username=username, repo=repo.name))
|
|
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 |
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 |
)
|