You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2015/04/21 16:46:59 UTC
[2/8] allura git commit: [#7866] ticket:754 Refactor code to support
can_merge backgroud task (WIP)
[#7866] ticket:754 Refactor code to support can_merge backgroud task (WIP)
Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/76f05fab
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/76f05fab
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/76f05fab
Branch: refs/heads/master
Commit: 76f05fabc43acab1f15416b3dd2423daf34a954b
Parents: fb7f2cf
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Apr 17 13:04:14 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Tue Apr 21 08:15:31 2015 +0000
----------------------------------------------------------------------
Allura/allura/controllers/repository.py | 8 +-
Allura/allura/model/repository.py | 34 ++++--
Allura/allura/tasks/repo_tasks.py | 9 +-
Allura/allura/templates/repo/merge_request.html | 113 +++++++++++++------
4 files changed, 118 insertions(+), 46 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/allura/blob/76f05fab/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index b36449c..07a522b 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -366,7 +366,9 @@ class MergeRequestController(object):
return dict(
downstream_app=downstream_app,
req=self.req,
- status=self.req.merge_task_status(),
+ can_merge=self.req.can_merge(),
+ can_merge_status=self.req.can_merge_task_status(),
+ merge_status=self.req.merge_task_status(),
page=page,
limit=limit,
count=self.req.discussion_thread.post_count)
@@ -454,6 +456,10 @@ class MergeRequestController(object):
def merge_task_status(self):
return {'status': self.req.merge_task_status()}
+ @expose('json:')
+ def can_merge_task_status(self):
+ return {'status': self.req.can_merge_task_status()}
+
class RefsController(object):
http://git-wip-us.apache.org/repos/asf/allura/blob/76f05fab/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 8083e17..35d2870 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -838,20 +838,23 @@ class MergeRequest(VersionedArtifact, ActivityObject):
return False
return True
+ def can_merge_cache(self, source_hash, target_hash):
+ """
+ Returns True/False or None in case of cache miss.
+ """
+ return None
+
def can_merge(self):
"""
Returns true if you can merge cleanly (no conflicts)
"""
- if not self.app.forkable:
- return False
- try:
- result = self.app.repo.can_merge(self)
- except:
- log.exception(
- "Can't determine if merge request %s can be merged",
- self.url())
- return False
- return result
+ cached = self.can_merge_cache(None, None)
+ if cached is not None:
+ return cached
+ in_progress = self.can_merge_task_status() in ['ready', 'busy']
+ if self.app.forkable and not in_progress:
+ from allura.tasks import repo_tasks
+ repo_tasks.can_merge.post(self._id)
def merge(self):
in_progress = self.merge_task_status() in ['ready', 'busy']
@@ -870,6 +873,17 @@ class MergeRequest(VersionedArtifact, ActivityObject):
return task.state
return None
+ def can_merge_task_status(self):
+ task = MonQTask.query.find({
+ 'state': {'$in': ['busy', 'complete', 'error', 'ready']}, # needed to use index
+ 'task_name': 'allura.tasks.repo_tasks.can_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
# One of these for each commit in the physical repo on disk. The _id is the
http://git-wip-us.apache.org/repos/asf/allura/blob/76f05fab/Allura/allura/tasks/repo_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/repo_tasks.py b/Allura/allura/tasks/repo_tasks.py
index e873694..d16755c 100644
--- a/Allura/allura/tasks/repo_tasks.py
+++ b/Allura/allura/tasks/repo_tasks.py
@@ -158,8 +158,15 @@ def tarball(revision, path):
@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)
mr.app.repo.merge(mr)
mr.status = 'merged'
session(mr).flush(mr)
+
+
+@task
+def can_merge(merge_request_id):
+ from allura import model as M
+ mr = M.MergeRequest.query.get(_id=merge_request_id)
+ result = self.app.repo.can_merge(self)
+ # TODO: set cache
http://git-wip-us.apache.org/repos/asf/allura/blob/76f05fab/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 928a0db..99bcdec 100644
--- a/Allura/allura/templates/repo/merge_request.html
+++ b/Allura/allura/templates/repo/merge_request.html
@@ -34,8 +34,8 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
{% block content %}
<div class="grid-19">
- <div id="task_status">
- {% if status == 'complete' %}
+ <div id="merge_task_status" class="task_status">
+ {% if merge_status == 'complete' %}
<h2 class="complete">Merged</h2>
{% else %}
<img src="{{g.forge_static('images/spinner.gif')}}" class="spinner" style="display:none"/>
@@ -44,6 +44,13 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
<h2 class="fail">Something went wrong. Please, merge manually</h2>
{% endif %}
</div>
+ <div id="can_merge_task_status" class="task_status">
+ {% if can_merge_status != 'complete' %}
+ <img src="{{g.forge_static('images/spinner.gif')}}" class="spinner" style="display:none"/>
+ <h2 class="busy ready">Checking if merge is possible...</h2>
+ <h2 class="fail">Something went wrong. Please, merge manually</h2>
+ {% endif %}
+ </div>
</div>
{% if req.downstream_repo %}
@@ -58,20 +65,19 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
<div>{{g.markdown.convert(req.description)}}</div>
{% if req.merge_allowed(c.user) %}
- {% set can_merge = req.can_merge() %}
<div class="grid-19">
<form action="merge" method="POST">
{{ lib.csrf_token() }}
- <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.
- </div>
- {% else %}
- <div class="merge-conflicts">
- Merge request has conflicts. Follow manual instructions below to merge.
- </div>
- {% endif %}
+ <input id="merge-btn" type="submit" value="Merge"{% if not can_merge or merge_status in ('ready', 'busy') %}disabled="disabled"{% endif %}>
+ <div class="merge-help-text can-merge-in-progress" {% if can_merge == None %}style="display: block;"{% endif %}>
+ Checking if merge is possible...
+ </div>
+ <div class="merge-help-text merge-ok" {% if can_merge == True %}style="display: block;"{% endif %}>
+ Merge request has no conflicts. You can merge automatically.
+ </div>
+ <div class="merge-help-text merge-conflicts" {% if can_merge == False %}style="display: block;"{% endif %}>
+ Merge request has conflicts. Follow manual instructions below to merge.
+ </div>
</form>
</div>
{% endif %}
@@ -87,7 +93,7 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
<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') %}
+ {% if merge_status not in ('ready', 'busy') %}
{{ c.mr_dispose_form.display(action="save", value=dict(status=req.status)) }}
<br style="clear:both">
{% endif %}
@@ -122,15 +128,17 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
{% block extra_css %}
<style type="text/css">
+ .merge-help-text { display: none; }
.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; }
+ .can-merge-in-progress { color: grey; }
+
+ .task_status { margin: 0 10px; }
+ .task_status h2 { display: none; }
+ .task_status .{{ merge_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 %}
@@ -138,35 +146,72 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
{{ super() }}
<script type="text/javascript">
$(function() {
- {% if status in ('ready', 'busy') %}
- $('.spinner').show();
+ {% if merge_status in ('ready', 'busy') %}
+ $('#merge_task_status > .spinner').show();
var delay = 500;
- function check_status() {
+ function check_merge_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();
+ $('#merge_task_status > .spinner').hide();
+ $('#merge_task_status h2').hide();
+ $('#merge_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();
+ $('#merge_task_status h2').hide();
+ $('#merge_task_status h2.busy').show();
+ } else {
+ // something went wrong
+ $('#merge_task_status > .spinner').hide();
+ $('#merge_task_status h2').hide();
+ $('#merge_task_status h2.fail').show();
+ }
+ if (delay < 60000){
+ delay = delay * 2;
+ }
+ window.setTimeout(check_merge_status, delay);
+ }
+ });
+ }
+ window.setTimeout(check_merge_status, delay);
+ {% endif %}
+
+ {% if can_merge_status in ('ready', 'busy') %}
+ $('#can_merge_task_status > .spinner').show();
+ var delay = 500;
+ function check_can_merge_status() {
+ $.get("{{request.path.rstrip('/') + '/can_merge_task_status'}}", function(data) {
+ if (data.status === 'complete') {
+ $('#can_merge_task_status > .spinner').hide();
+ $('#can_merge_task_status h2').hide();
+ // TODO: check if actually can merge and show appropriate message
+ $('.merge-help-text').hide();
+ $('.merge-ok').show();
+ $('.merge-btn').prop('disabled', false);
+ } else {
+ if (data.status === 'ready' || data.status === 'busy') {
+ // keep waiting
+ $('#can_merge_task_status h2').hide();
+ $('#can_merge_task_status h2.busy').show();
+ $('.merge-help-text').hide();
+ $('.can-merge-in-progress').show();
} else {
// something went wrong
- $('.spinner').hide();
- $('#task_status h2').hide();
- $('#task_status h2.fail').show();
+ $('#can_merge_task_status > .spinner').hide();
+ $('#can_merge_task_status h2').hide();
+ $('#merge_task_status h2.fail').show();
+ $('.merge-help-text').hide();
+ $('.merge-conflicts').show();
}
if (delay < 60000){
delay = delay * 2;
}
- window.setTimeout(check_status, delay);
+ window.setTimeout(check_can_merge_status, delay);
}
});
}
- window.setTimeout(check_status, delay);
+ window.setTimeout(check_can_merge_status, delay);
{% endif %}
});
</script>