# HG changeset patch # User Mads Kiilerich # Date 1592774412 -7200 # Node ID 35af0bd45bf356e71232d9fddc63534c760f4f67 # Parent 5463f4b13fc3bb8507e25e8f1266a3f368b44668 diff: drop per file ignore-whitespace and context - it didn't work and had conceptual issue (Issue #344) Diffs are currently generated at the low level as one big diff between two vcs resisions, provided global values for diff context size and flag for ignoring whitespace. All files use the same flags. There is no way to actually compute the full diff using these use per file flags, and no simple and efficient way to add it. The best option is thus to drop the failed attempt at making it per file, and just rely on the simple global flags in the URL. The links for changing whitespace and context is sometimes shown for the whole "page", and sometimes next to the diff for one file. For now, keep showing the link in these places, but make sure it navigates back to the FID of the section where the link was clicked. The implementation is completely rewritten and moved to a more appropriate location in helpers. With a more clean implementation, we also consistently use the simple getters to extract values from the URL. diff -r 5463f4b13fc3 -r 35af0bd45bf3 kallithea/controllers/changeset.py --- a/kallithea/controllers/changeset.py Thu Jun 18 14:53:28 2020 +0200 +++ b/kallithea/controllers/changeset.py Sun Jun 21 23:20:12 2020 +0200 @@ -28,7 +28,7 @@ import binascii import logging import traceback -from collections import OrderedDict, defaultdict +from collections import OrderedDict from tg import request, response from tg import tmpl_context as c @@ -54,113 +54,6 @@ log = logging.getLogger(__name__) -def _update_with_GET(params, GET): - for k in ['diff1', 'diff2', 'diff']: - params[k] += GET.getall(k) - - -def get_ignore_ws(fid, GET): - ig_ws_global = GET.get('ignorews') - ig_ws = [k for k in GET.getall(fid) if k.startswith('WS')] - if ig_ws: - try: - return int(ig_ws[0].split(':')[-1]) - except ValueError: - raise HTTPBadRequest() - return ig_ws_global - - -def _ignorews_url(GET, fileid=None, anchor=None): - fileid = str(fileid) if fileid else None - params = defaultdict(list) - _update_with_GET(params, GET) - lbl = _('Show whitespace') - ig_ws = get_ignore_ws(fileid, GET) - ln_ctx = get_line_ctx(fileid, GET) - # global option - if fileid is None: - if ig_ws is None: - params['ignorews'] += [1] - lbl = _('Ignore whitespace') - ctx_key = 'context' - ctx_val = ln_ctx - # per file options - else: - if ig_ws is None: - params[fileid] += ['WS:1'] - lbl = _('Ignore whitespace') - - ctx_key = fileid - ctx_val = 'C:%s' % ln_ctx - # if we have passed in ln_ctx pass it along to our params - if ln_ctx: - params[ctx_key] += [ctx_val] - - params['anchor'] = anchor - icon = h.literal('') - return h.link_to(icon, h.url.current(**params), title=lbl, **{'data-toggle': 'tooltip'}) - - -def get_line_ctx(fid, GET): - ln_ctx_global = GET.get('context') - if fid: - ln_ctx = [k for k in GET.getall(fid) if k.startswith('C')] - else: - _ln_ctx = [k for k in GET if k.startswith('C')] - ln_ctx = GET.get(_ln_ctx[0]) if _ln_ctx else ln_ctx_global - if ln_ctx: - ln_ctx = [ln_ctx] - - if ln_ctx: - retval = ln_ctx[0].split(':')[-1] - else: - retval = ln_ctx_global - - try: - return int(retval) - except Exception: - return 3 - - -def _context_url(GET, fileid=None, anchor=None): - """ - Generates url for context lines - - :param fileid: - """ - - fileid = str(fileid) if fileid else None - ig_ws = get_ignore_ws(fileid, GET) - ln_ctx = (get_line_ctx(fileid, GET) or 3) * 2 - - params = defaultdict(list) - _update_with_GET(params, GET) - - # global option - if fileid is None: - if ln_ctx > 0: - params['context'] += [ln_ctx] - - if ig_ws: - ig_ws_key = 'ignorews' - ig_ws_val = 1 - - # per file option - else: - params[fileid] += ['C:%s' % ln_ctx] - ig_ws_key = fileid - ig_ws_val = 'WS:%s' % 1 - - if ig_ws: - params[ig_ws_key] += [ig_ws_val] - - lbl = _('Increase diff context to %(num)s lines') % {'num': ln_ctx} - - params['anchor'] = anchor - icon = h.literal('') - return h.link_to(icon, h.url.current(**params), title=lbl, **{'data-toggle': 'tooltip'}) - - def create_cs_pr_comment(repo_name, revision=None, pull_request=None, allowed_to_change_status=True): """ Add a comment to the specified changeset or pull request, using POST values @@ -287,8 +180,6 @@ def _index(self, revision, method): c.pull_request = None - c.ignorews_url = _ignorews_url - c.context_url = _context_url c.fulldiff = request.GET.get('fulldiff') # for reporting number of changed files # get ranges of revisions if preset rev_range = revision.split('...')[:2] @@ -351,9 +242,8 @@ cs2 = changeset.raw_id cs1 = changeset.parents[0].raw_id if changeset.parents else EmptyChangeset().raw_id - diff_context_size = get_line_ctx('', request.GET) - ignore_whitespace_diff = get_ignore_ws('', request.GET) - + ignore_whitespace_diff = h.get_ignore_whitespace_diff(request.GET) + diff_context_size = h.get_diff_context_size(request.GET) raw_diff = diffs.get_diff(c.db_repo_scm_instance, cs1, cs2, ignore_whitespace=ignore_whitespace_diff, context=diff_context_size) diff_limit = None if c.fulldiff else self.cut_off_limit diff -r 5463f4b13fc3 -r 35af0bd45bf3 kallithea/controllers/compare.py --- a/kallithea/controllers/compare.py Thu Jun 18 14:53:28 2020 +0200 +++ b/kallithea/controllers/compare.py Sun Jun 21 23:20:12 2020 +0200 @@ -37,13 +37,12 @@ from webob.exc import HTTPBadRequest, HTTPFound, HTTPNotFound from kallithea.config.routing import url -from kallithea.controllers.changeset import _context_url, _ignorews_url from kallithea.lib import diffs from kallithea.lib import helpers as h from kallithea.lib.auth import HasRepoPermissionLevelDecorator, LoginRequired from kallithea.lib.base import BaseRepoController, render from kallithea.lib.graphmod import graph_data -from kallithea.lib.utils2 import ascii_bytes, ascii_str, safe_bytes, safe_int +from kallithea.lib.utils2 import ascii_bytes, ascii_str, safe_bytes from kallithea.model.db import Repository @@ -208,12 +207,8 @@ other_repo=c.a_repo.repo_name, other_ref_type=org_ref_type, other_ref_name=org_ref_name, merge=merge or '') - - # set callbacks for generating markup for icons - c.ignorews_url = _ignorews_url - c.context_url = _context_url - ignore_whitespace_diff = request.GET.get('ignorews') == '1' - diff_context_size = safe_int(request.GET.get('context'), 3) + ignore_whitespace_diff = h.get_ignore_whitespace_diff(request.GET) + diff_context_size = h.get_diff_context_size(request.GET) c.a_rev = self._get_ref_rev(c.a_repo, org_ref_type, org_ref_name, returnempty=True) diff -r 5463f4b13fc3 -r 35af0bd45bf3 kallithea/controllers/files.py --- a/kallithea/controllers/files.py Thu Jun 18 14:53:28 2020 +0200 +++ b/kallithea/controllers/files.py Sun Jun 21 23:20:12 2020 +0200 @@ -39,14 +39,13 @@ from webob.exc import HTTPFound, HTTPNotFound from kallithea.config.routing import url -from kallithea.controllers.changeset import _context_url, _ignorews_url, get_ignore_ws, get_line_ctx from kallithea.lib import diffs from kallithea.lib import helpers as h from kallithea.lib.auth import HasRepoPermissionLevelDecorator, LoginRequired from kallithea.lib.base import BaseRepoController, jsonify, render from kallithea.lib.exceptions import NonRelativePathError from kallithea.lib.utils import action_logger -from kallithea.lib.utils2 import asbool, convert_line_endings, detect_mode, safe_int, safe_str +from kallithea.lib.utils2 import asbool, convert_line_endings, detect_mode, safe_str from kallithea.lib.vcs.backends.base import EmptyChangeset from kallithea.lib.vcs.conf import settings from kallithea.lib.vcs.exceptions import (ChangesetDoesNotExistError, ChangesetError, EmptyRepositoryError, ImproperArchiveTypeError, NodeAlreadyExistsError, @@ -558,8 +557,8 @@ @LoginRequired(allow_default_user=True) @HasRepoPermissionLevelDecorator('read') def diff(self, repo_name, f_path): - ignore_whitespace_diff = request.GET.get('ignorews') == '1' - diff_context_size = safe_int(request.GET.get('context'), 3) + ignore_whitespace_diff = h.get_ignore_whitespace_diff(request.GET) + diff_context_size = h.get_diff_context_size(request.GET) diff2 = request.GET.get('diff2', '') diff1 = request.GET.get('diff1', '') or diff2 c.action = request.GET.get('diff') @@ -567,8 +566,6 @@ c.f_path = f_path c.big_diff = False fulldiff = request.GET.get('fulldiff') - c.ignorews_url = _ignorews_url - c.context_url = _context_url c.changes = OrderedDict() c.changes[diff2] = [] @@ -641,8 +638,6 @@ else: fid = h.FID(diff2, node2.path) - diff_context_size = get_line_ctx(fid, request.GET) - ignore_whitespace_diff = get_ignore_ws(fid, request.GET) diff_limit = None if fulldiff else self.cut_off_limit c.a_rev, c.cs_rev, a_path, diff, st, op = diffs.wrapped_diff(filenode_old=node1, filenode_new=node2, @@ -651,7 +646,6 @@ line_context=diff_context_size, enable_comments=False) c.file_diff_data = [(fid, fid, op, a_path, node2.path, diff, st)] - return render('files/file_diff.html') @LoginRequired(allow_default_user=True) diff -r 5463f4b13fc3 -r 35af0bd45bf3 kallithea/controllers/pullrequests.py --- a/kallithea/controllers/pullrequests.py Thu Jun 18 14:53:28 2020 +0200 +++ b/kallithea/controllers/pullrequests.py Sun Jun 21 23:20:12 2020 +0200 @@ -36,7 +36,7 @@ from webob.exc import HTTPBadRequest, HTTPForbidden, HTTPFound, HTTPNotFound from kallithea.config.routing import url -from kallithea.controllers.changeset import _context_url, _ignorews_url, create_cs_pr_comment, delete_cs_pr_comment +from kallithea.controllers.changeset import create_cs_pr_comment, delete_cs_pr_comment from kallithea.lib import diffs from kallithea.lib import helpers as h from kallithea.lib.auth import HasRepoPermissionLevelDecorator, LoginRequired @@ -569,10 +569,8 @@ c.cs_comments = c.cs_repo.get_comments(raw_ids) c.cs_statuses = c.cs_repo.statuses(raw_ids) - ignore_whitespace_diff = request.GET.get('ignorews') == '1' - diff_context_size = safe_int(request.GET.get('context'), 3) - c.ignorews_url = _ignorews_url - c.context_url = _context_url + ignore_whitespace_diff = h.get_ignore_whitespace_diff(request.GET) + diff_context_size = h.get_diff_context_size(request.GET) fulldiff = request.GET.get('fulldiff') diff_limit = None if fulldiff else self.cut_off_limit diff -r 5463f4b13fc3 -r 35af0bd45bf3 kallithea/lib/helpers.py --- a/kallithea/lib/helpers.py Thu Jun 18 14:53:28 2020 +0200 +++ b/kallithea/lib/helpers.py Sun Jun 21 23:20:12 2020 +0200 @@ -213,12 +213,48 @@ """ Creates a unique ID for filenode based on it's hash of path and revision it's safe to use in urls + """ + return 'C-%s-%s' % (short_id(raw_id), hashlib.md5(safe_bytes(path)).hexdigest()[:12]) - :param raw_id: - :param path: - """ + +def get_ignore_whitespace_diff(GET): + """Return true if URL requested whitespace to be ignored""" + return bool(GET.get('ignorews')) + - return 'C-%s-%s' % (short_id(raw_id), hashlib.md5(safe_bytes(path)).hexdigest()[:12]) +def ignore_whitespace_link(GET, anchor=None): + """Return snippet with link to current URL with whitespace ignoring toggled""" + params = dict(GET) # ignoring duplicates + if get_ignore_whitespace_diff(GET): + params.pop('ignorews') + title = _("Show whitespace changes") + else: + params['ignorews'] = '1' + title = _("Ignore whitespace changes") + params['anchor'] = anchor + return link_to( + literal(''), + url.current(**params), + title=title, + **{'data-toggle': 'tooltip'}) + + +def get_diff_context_size(GET): + """Return effective context size requested in URL""" + return safe_int(GET.get('context'), default=3) + + +def increase_context_link(GET, anchor=None): + """Return snippet with link to current URL with double context size""" + context = get_diff_context_size(GET) * 2 + params = dict(GET) # ignoring duplicates + params['context'] = str(context) + params['anchor'] = anchor + return link_to( + literal(''), + url.current(**params), + title=_('Increase diff context to %(num)s lines') % {'num': context}, + **{'data-toggle': 'tooltip'}) class _FilesBreadCrumbs(object): diff -r 5463f4b13fc3 -r 35af0bd45bf3 kallithea/templates/changeset/changeset.html --- a/kallithea/templates/changeset/changeset.html Thu Jun 18 14:53:28 2020 +0200 +++ b/kallithea/templates/changeset/changeset.html Sun Jun 21 23:20:12 2020 +0200 @@ -47,8 +47,8 @@ - ${c.ignorews_url(request.GET)} - ${c.context_url(request.GET)} + ${h.ignore_whitespace_link(request.GET)} + ${h.increase_context_link(request.GET)}
diff -r 5463f4b13fc3 -r 35af0bd45bf3 kallithea/templates/changeset/diff_block.html --- a/kallithea/templates/changeset/diff_block.html Thu Jun 18 14:53:28 2020 +0200 +++ b/kallithea/templates/changeset/diff_block.html Sun Jun 21 23:20:12 2020 +0200 @@ -65,8 +65,8 @@ - ${c.ignorews_url(request.GET, url_fid, id_fid)} - ${c.context_url(request.GET, url_fid, id_fid)} + ${h.ignore_whitespace_link(request.GET, id_fid)} + ${h.increase_context_link(request.GET, id_fid)}
${_('Show inline comments')} diff -r 5463f4b13fc3 -r 35af0bd45bf3 kallithea/templates/compare/compare_diff.html --- a/kallithea/templates/compare/compare_diff.html Thu Jun 18 14:53:28 2020 +0200 +++ b/kallithea/templates/compare/compare_diff.html Sun Jun 21 23:20:12 2020 +0200 @@ -60,9 +60,8 @@ % else: ${ungettext('%s file changed with %s insertions and %s deletions','%s files changed with %s insertions and %s deletions', len(c.file_diff_data)) % (len(c.file_diff_data),c.lines_added,c.lines_deleted)}: %endif - - ${c.ignorews_url(request.GET)} - ${c.context_url(request.GET)} + ${h.ignore_whitespace_link(request.GET)} + ${h.increase_context_link(request.GET)}
%if not c.file_diff_data: