Mercurial > hgsubversion
changeset 1352:30193fdd5da4
Addressed using relative URLs to actually divert to another server & added DocTest strings.
Code has been tested on real-world repositories that use relative references
but adding tests which do the round trip testing as a standalone has been beyond
me.
author | Gadget Steve <gadgetsteve@hotmail.com> |
---|---|
date | Sat, 19 Sep 2015 07:27:31 +0100 |
parents | 9d58ca6253a3 |
children | 63a29df4f661 |
files | hgsubversion/svnexternals.py |
diffstat | 1 files changed, 60 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/hgsubversion/svnexternals.py +++ b/hgsubversion/svnexternals.py @@ -125,19 +125,73 @@ def resolvedots(url): Fix references that include .. entries. Scans a URL for .. type entries and resolves them but will not allow any number of ..s to take us out of domain so http://.. will raise an exception. + + Tests, (Don't know how to construct a round trip for this so doctest): + >>> # Relative URL within servers svn area + >>> resolvedots( + ... "http://some.svn.server/svn/some_repo/../other_repo") + 'http://some.svn.server/svn/other_repo' + >>> # Complex One + >>> resolvedots( + ... "http://some.svn.server/svn/repo/../other/repo/../../other_repo") + 'http://some.svn.server/svn/other_repo' + >>> # Another Complex One + >>> resolvedots( + ... "http://some.svn.server/svn/repo/dir/subdir/../../../other_repo/dir") + 'http://some.svn.server/svn/other_repo/dir' + >>> # Last Complex One - SVN Allows this & seen it used even if it is BAD! + >>> resolvedots( + ... "http://svn.server/svn/my_repo/dir/subdir/../../other_dir") + 'http://svn.server/svn/my_repo/other_dir' + >>> # Outside the SVN Area might be OK + >>> resolvedots( + ... "http://svn.server/svn/some_repo/../../other_svn_repo") + 'http://svn.server/other_svn_repo' + >>> # Complex One + >>> resolvedots( + ... "http://some.svn.server/svn/repo/../other/repo/../../other_repo") + 'http://some.svn.server/svn/other_repo' + >>> # On another server is not a relative URL should give an exception + >>> resolvedots( + ... "http://some.svn.server/svn/some_repo/../../../other_server") + Traceback (most recent call last): + ... + RelativeSourceError: Relative URL cannot be to another server """ orig = url.split('/') fixed = [] for item in orig: if item != '..': fixed.append(item) - elif len(fixed) > 2: # Don't allow things to go out of domain + elif len(fixed) > 3: # Don't allow things to go out of domain fixed.pop() else: - raise RelativeSourceError() + raise RelativeSourceError( + 'Relative URL cannot be to another server') return '/'.join(fixed) + + def resolvesource(ui, svnroot, source): + """ Resolve the source as either matching the scheme re or by resolving + relative URLs which start with ^ and my include relative .. references. + + >>> root = 'http://some.svn.server/svn/some_repo' + >>> resolvesource(None, root, 'http://other.svn.server') + 'http://other.svn.server' + >>> resolvesource(None, root, 'ssh://other.svn.server') + 'ssh://other.svn.server' + >>> resolvesource(None, root, '^/other_repo') + 'http://some.svn.server/svn/some_repo/other_repo' + >>> resolvesource(None, root, '^/sub_repo') + 'http://some.svn.server/svn/some_repo/sub_repo' + >>> resolvesource(None, root, '^/../other_repo') + 'http://some.svn.server/svn/other_repo' + >>> resolvesource(None, root, '^/../../../server/other_repo') + Traceback (most recent call last): + ... + RelativeSourceError: Relative URL cannot be to another server + """ if re_scheme.search(source): return source if source.startswith('^/'): @@ -457,3 +511,7 @@ class svnsubrepo(subrepo.svnsubrepo): if self._state[1] == 'HEAD': return 'HEAD' return super(svnsubrepo, self).basestate() + +if __name__ == "__main__": + import doctest + doctest.testmod()