--- a/contrib/windows/update_tortoisehg_libs.py Fri Aug 19 18:21:28 2016 +0200
+++ b/contrib/windows/update_tortoisehg_libs.py Fri Dec 12 11:17:43 2014 +0100
@@ -1,23 +1,23 @@
# this script will update tortoisehgs python libs to include the missing libs that hg-review needs
-# (tested with Python 2.6 and Tortoisehg 1.1)
+# (tested with Python 2.7.3 and Tortoisehg 2.6.2)
#
# Daniel Newton <djpnewton@gmail.com>
#
-# Version 1.0 (2010/07/28)
+# Version 1.1 (2013/01/18)
import sys
import os
# check python version
-if sys.version[:3] != '2.6':
- sys.exit('Need Python 2.6')
+if sys.version[:3] != '2.7':
+ sys.exit('Need Python 2.7')
# check for windows
if sys.platform != 'win32':
sys.exit('Script only works on win32')
# list of libs to add
-libs = ('Cookie.py', 'decimal.py', 'htmlentitydefs.py', 'code.py', 'codeop.py', 'compiler', 'numbers.py', 'symbol.py', 'uuid.py')
+libs = ('Cookie.py', 'htmlentitydefs.py', 'code.py', 'codeop.py', 'compiler', 'symbol.py', 'uuid.py')
# find python lib path
pylib_path = os.path.join(os.path.dirname(sys.executable), 'lib')
--- a/docs/overview.rst Fri Aug 19 18:21:28 2016 +0200
+++ b/docs/overview.rst Fri Dec 12 11:17:43 2014 +0100
@@ -27,6 +27,18 @@
[extensions]
review = [path to]/hg-review/review/
+TortoiseHG
+~~~~~~~~~~
+
+People using TortoiseHG on Windows platforms need to update the tortoisehg
+`library.zip`. This is easily done by running the
+`contrib\\windows\\update_tortoisehg_libs.py` script.
+
+Do to that, you need to have python 2.7 installed::
+
+ python contrib\windows\update_tortoisehg_libs.py
+
+
Usage
-----
--- a/review/static/styles/style.less Fri Aug 19 18:21:28 2016 +0200
+++ b/review/static/styles/style.less Fri Dec 12 11:17:43 2014 +0100
@@ -269,6 +269,10 @@
overflow: hidden;
text-overflow: ellipsis;
}
+ &.user {
+ text-align: center;
+ white-space: nowrap;
+ }
&.desc {
a {
display: inline-block;
--- a/review/templates/changeset.html Fri Aug 19 18:21:28 2016 +0200
+++ b/review/templates/changeset.html Fri Dec 12 11:17:43 2014 +0100
@@ -29,12 +29,12 @@
<h2>
{{ rev.rev() }}:
- <span class="desc">{{ rev.description().splitlines()[0] }}</span>
+ <span class="desc">{{ utils['decode'](rev.description().splitlines()[0]) }}</span>
<span class="by">by</span>
<a href="mailto:{{ utils['email'](rev.user()) }}">{{ utils['person'](rev.user()) }}</a>
</h2>
- <div class="fulldesc">{{ rev.description() }}</div>
+ <div class="fulldesc">{{ utils['decode'](rev.description()) }}</div>
</div>
{% with %}
--- a/review/templates/index.html Fri Aug 19 18:21:28 2016 +0200
+++ b/review/templates/index.html Fri Dec 12 11:17:43 2014 +0100
@@ -14,8 +14,14 @@
<tr class="{{ phase }}">
<td class="node"><span class="rev">{{ rev.rev() }}</span><span class="sep">:</span><span class="hash">{{ node_short }}</span></td>
+ <td class="user">{{ utils['person'](rev.user()) }}</td>
<td class="desc">
- <a class="changeset-link" href="{{ link }}">{{ rev.description().splitlines()[0] }}</a>
+ <a class="changeset-link" href="{{ link }}">
+ {% if rev.branch() != 'default' %}
+ [{{ rev.branch() }}]
+ {%endif%}
+ {{ utils['decode'](rev.description().splitlines()[0]) }}
+ </a>
</td>
<td class="stats">
{% with %}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/review/tests/test_web.py Fri Dec 12 11:17:43 2014 +0100
@@ -0,0 +1,38 @@
+import unittest
+
+from nose.tools import eq_
+
+import util
+
+from .. import web
+
+NON_EXISTENT_REV = 999999
+
+class WebTestCase(unittest.TestCase):
+ """Simple web tests. Currently only checks for correct status codes."""
+
+ def setUp(self):
+ util.setup_reviewed_sandbox()()
+ ui = util.get_ui()
+ repo = util.get_sandbox_repo()
+ web._configure_app(ui, repo)
+ web.app.config['TESTING'] = True
+ self.app = web.app.test_client()
+
+ def tearDown(self):
+ util.teardown_sandbox()
+
+ def test_index_no_rev(self):
+ rv = self.app.get('/')
+ eq_(rv.status_code, 200)
+
+ def test_index_high_rev(self):
+ rv = self.app.get('/%s/' % NON_EXISTENT_REV)
+ eq_(rv.status_code, 200)
+
+ def test_index_known_rev(self):
+ rv = self.app.get('/0/')
+ eq_(rv.status_code, 200)
+
+if __name__ == '__main__':
+ unittest.main()
--- a/review/web.py Fri Aug 19 18:21:28 2016 +0200
+++ b/review/web.py Fri Dec 12 11:17:43 2014 +0100
@@ -188,6 +188,7 @@
@app.route('/changeset/<revhash>/', methods=['GET', 'POST'])
def changeset(revhash):
+ revhash = revhash.encode('ascii')
if request.method == 'POST':
signoff = request.form.get('signoff', None)
if signoff and not app.read_only:
@@ -216,6 +217,7 @@
def patch(revhash):
result = StringIO.StringIO()
try:
+ revhash = revhash.encode('ascii')
diff_opts = _patch.diffopts(app.ui, {'git': True})
cmdutil.export(g.datastore.target, [revhash], fp=result, opts=diff_opts)
except error.RepoLookupError:
@@ -250,23 +252,29 @@
return _render('500.html'), 500
+def _configure_app(ui, repo, read_only=False, allow_anon=False):
+ """Configure the web app.
+
+ This happens in a distinct function to reuse these steps in tests.
+
+ """
+ app.read_only = read_only
+ app.debug = ui.debugflag
+ app.allow_anon = allow_anon
+ app.site_root = ''
+ if app.allow_anon:
+ ui.setconfig('ui', 'username', 'Anonymous <anonymous@example.com>')
+ app.ui = ui
+ app.repo = repo
+ app.title = os.path.basename(repo.root)
+ app.project_url = None
+
def load_interface(ui, repo, read_only=False, allow_anon=False,
open=False, address='127.0.0.1', port=8080):
if open:
import webbrowser
webbrowser.open('http://localhost:%d/' % port)
- app.read_only = read_only
- app.debug = ui.debugflag
- app.allow_anon = allow_anon
- app.site_root = ''
-
- if app.allow_anon:
- ui.setconfig('ui', 'username', 'Anonymous <anonymous@example.com>')
-
- app.ui = ui
- app.repo = repo
- app.title = os.path.basename(repo.root)
- app.project_url = None
+ _configure_app(ui, repo, read_only, allow_anon)
app.run(host=address, port=port)