You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by je...@apache.org on 2015/03/06 13:35:28 UTC
[21/26] allura git commit: [#7830] ticket:729 Move actual merge to
background task
[#7830] ticket:729 Move actual merge to background task
Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/46767d9f
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/46767d9f
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/46767d9f
Branch: refs/heads/ib/7830
Commit: 46767d9ff92ca6c205dcf0d7fadffaca2094cf9e
Parents: 0a9980e
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Feb 19 12:14:52 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Fri Mar 6 09:43:07 2015 +0000
----------------------------------------------------------------------
Allura/allura/controllers/repository.py | 11 +--
Allura/allura/model/repository.py | 27 ++++---
Allura/allura/tasks/repo_tasks.py | 15 ++++
Allura/allura/templates/repo/merge_request.html | 82 +++++++++++++++++---
4 files changed, 107 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/allura/blob/46767d9f/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 0869982..2d1295c 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -365,6 +365,7 @@ class MergeRequestController(object):
return dict(
downstream_app=downstream_app,
req=self.req,
+ status=self.req.merge_task_status(),
page=page,
limit=limit,
count=self.req.discussion_thread.post_count)
@@ -446,13 +447,13 @@ class MergeRequestController(object):
require_access(c.app, 'write')
if self.req.status != 'open' or not self.req.can_merge():
raise exc.HTTPNotFound
- ok = self.req.merge()
- if ok:
- flash('Merged successfully', 'ok')
- else:
- flash('Merge failed. Please, merge manually', 'error')
+ self.req.merge()
redirect(self.req.url())
+ @expose('json:')
+ def merge_task_status(self):
+ return {'status': self.req.merge_task_status()}
+
class RefsController(object):
http://git-wip-us.apache.org/repos/asf/allura/blob/46767d9f/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 5e4a171..d866598 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -23,7 +23,7 @@ import string
import re
from subprocess import Popen, PIPE
from hashlib import sha1
-from datetime import datetime
+from datetime import datetime, timedelta
from time import time
from collections import defaultdict, OrderedDict
from urlparse import urljoin
@@ -818,16 +818,21 @@ class MergeRequest(VersionedArtifact, ActivityObject):
return result
def merge(self):
- if not self.app.forkable:
- return False
- try:
- self.app.repo.merge(self)
- except:
- log.exception("Can't merge merge request %s", self.url())
- return False
- self.status = 'merged'
- session(self).flush(self)
- return True
+ in_progress = self.merge_task_status() in ['ready', 'busy']
+ if self.app.forkable and not in_progress:
+ from allura.tasks import repo_tasks
+ repo_tasks.merge.post(self._id)
+
+ def merge_task_status(self):
+ task = MonQTask.query.find({
+ 'state': {'$in': ['busy', 'complete', 'error', 'ready']}, # needed to use index
+ 'task_name': 'allura.tasks.repo_tasks.merge',
+ 'args': [self._id],
+ 'time_queue': {'$gt': datetime.utcnow() - timedelta(days=1)}, # constrain on index further
+ }).sort('_id', -1).limit(1).first()
+ if task:
+ return task.state
+ return None
# Basic commit information
http://git-wip-us.apache.org/repos/asf/allura/blob/46767d9f/Allura/allura/tasks/repo_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/repo_tasks.py b/Allura/allura/tasks/repo_tasks.py
index 61cac83..e50f9d2 100644
--- a/Allura/allura/tasks/repo_tasks.py
+++ b/Allura/allura/tasks/repo_tasks.py
@@ -20,6 +20,7 @@ import logging
import traceback
from pylons import tmpl_context as c, app_globals as g
+from ming.odm import session
from allura.lib.decorators import task
from allura.lib.repository import RepositoryApp
@@ -152,3 +153,17 @@ def tarball(revision, path):
log.warn(
'Skipped creation of snapshot: %s:%s because revision is not specified' %
(c.project.shortname, c.app.config.options.mount_point))
+
+
+@task
+def merge(merge_request_id):
+ from allura import model as M
+ log = logging.getLogger(__name__)
+ mr = M.MergeRequest.query.get(_id=merge_request_id)
+ try:
+ mr.app.repo.merge(mr)
+ except:
+ log.exception("Can't merge merge request %s", mr.url())
+ return
+ mr.status = 'merged'
+ session(mr).flush(mr)
http://git-wip-us.apache.org/repos/asf/allura/blob/46767d9f/Allura/allura/templates/repo/merge_request.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/merge_request.html b/Allura/allura/templates/repo/merge_request.html
index 060b5b9..1520270 100644
--- a/Allura/allura/templates/repo/merge_request.html
+++ b/Allura/allura/templates/repo/merge_request.html
@@ -33,6 +33,19 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
{% endblock %}
{% block content %}
+ <div class="grid-19">
+ <div id="task_status">
+ {% if status == 'complete' %}
+ <h2 class="complete">Merged</h2>
+ {% else %}
+ <img src="{{g.forge_static('images/spinner.gif')}}" class="spinner" style="display:none"/>
+ <h2 class="busy ready">Merging...</h2>
+ <h2 class="complete">Merged</h2>
+ <h2 class="fail">Something went wrong. Please, merge manually</h2>
+ {% endif %}
+ </div>
+ </div>
+
{% if req.downstream_repo %}
<p>
<a href="{{req.creator_url}}">{{req.creator_name}}</a>
@@ -49,7 +62,7 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
<div class="grid-19">
<form action="merge" method="POST">
{{ lib.csrf_token() }}
- <input type="submit" value="Merge"{% if not can_merge %}disabled="disabled"{% endif %}>
+ <input type="submit" value="Merge"{% if not can_merge or status in ('ready', 'busy') %}disabled="disabled"{% endif %}>
{% if can_merge %}
<div class="merge-ok">
Merge request has no conflicts. You can merge automatically.
@@ -68,14 +81,16 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
<div class="grid-19"><a href="#discussion_holder">Discuss</a></div>
{% if h.has_access(c.app, 'write')() %}
- <div class="grid-19">To merge the commits, please execute the following commands in your working
- copy: </div>
- <div class="grid-19"><textarea
- style="width:80%; height:60px;"
- readonly
- >{{ c.app.repo.merge_command(req) | safe }}</textarea></div>
- {{ c.mr_dispose_form.display(action="save", value=dict(status=req.status)) }}
- <br style="clear:both">
+ <div class="grid-19">
+ To merge the commits, please execute the following commands in your working copy:
+ </div>
+ <div class="grid-19">
+ <textarea style="width:80%; height:60px;" readonly>{{ c.app.repo.merge_command(req) | safe }}</textarea>
+ </div>
+ {% if status not in ('ready', 'busy') %}
+ {{ c.mr_dispose_form.display(action="save", value=dict(status=req.status)) }}
+ <br style="clear:both">
+ {% endif %}
{% endif %}
{% else %}
<p>
@@ -83,12 +98,10 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
<a href="{{req.creator_url}}">{{req.creator_name}}</a>
is deleted
</p>
-
<div>{{g.markdown.convert(req.description)}}</div>
-
{% if h.has_access(c.app, 'write')() %}
{{ c.mr_dispose_form.display(action="save", value=dict(status=req.status)) }}
- <br style="clear:both">
+ <br style="clear:both">
{% endif %}
{% endif %}
@@ -111,5 +124,50 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
<style type="text/css">
.merge-ok { color: green; }
.merge-conflicts { color: red; }
+
+ #task_status { margin: 0 10px; }
+ #task_status h2 { display: none; }
+ #task_status .{{ status }} { display: inline-block; }
+ #task_status h2.complete { color: #C6D880; }
+ #task_status h2.busy, #task_status h2.busy { color: #003565; }
+ #task_status h2.fail { color: #f33; }
</style>
{% endblock %}
+
+{% block extra_js %}
+{{ super() }}
+<script type="text/javascript">
+$(function() {
+ {% if status in ('ready', 'busy') %}
+ $('.spinner').show();
+ var delay = 500;
+ function check_status() {
+ $.get("{{request.path.rstrip('/') + '/merge_task_status'}}", function(data) {
+ if (data.status === 'complete') {
+ $('.spinner').hide();
+ $('#task_status h2').hide();
+ $('#task_status h2.complete').show();
+ location.reload();
+ } else {
+ if (data.status === 'ready' || data.status === 'busy') {
+ // keep waiting
+ $('#task_status h2').hide();
+ $('#task_status h2.busy').show();
+ } else {
+ // something went wrong
+ $('.spinner').hide();
+ $('#task_status h2').hide();
+ $('#task_status h2.fail').show();
+ }
+ if (delay < 60000){
+ delay = delay * 2;
+ }
+ window.setTimeout(check_status, delay);
+ }
+ });
+ }
+ window.setTimeout(check_status, delay);
+ {% endif %}
+});
+</script>
+{% endblock %}