New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NF: Helper to support Git-style URL rewriting #4064
Changes from 2 commits
a046652
5f7002c
9aa56c4
8e564e6
1dd19a0
c844b40
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -722,3 +722,49 @@ def unset(self, var, where='dataset', reload=True): | |
|
||
# use unset all as it is simpler for now | ||
self._run(['--unset-all', var], where=where, reload=reload) | ||
|
||
|
||
def rewrite_url(cfg, url): | ||
"""Any matching 'url.<base>.insteadOf' configuration is applied | ||
|
||
Any URL that starts with such a configuration will be rewritten | ||
to start, instead, with <base>. When more than one insteadOf | ||
strings match a given URL, the longest match is used. | ||
|
||
Parameters | ||
---------- | ||
cfg : ConfigManager or dict | ||
dict-like with configuration variable name/value-pairs. | ||
url : str | ||
URL to be rewritten, if matching configuration is found. | ||
|
||
Returns | ||
------- | ||
str | ||
Rewritten or unmodified URL. | ||
""" | ||
insteadof = { | ||
# only leave the base url | ||
k[4:-10]: v | ||
for k, v in cfg.items() | ||
if k.startswith('url.') and k.endswith('.insteadof') | ||
} | ||
prev_url = None | ||
while url != prev_url: | ||
prev_url = url | ||
# all config that applies | ||
matches = {k: len(v) for k, v in insteadof.items() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do see one problem here: You match all configs (well, the longest). However, what if I have a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is not how gitconfig works:
Local overwrites global, it does not append. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, my suggestion is wrong. The usual tuple considers the keys, not the values. So, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I don't get it yet. What is it that this function does or doesn't that git itself does when rewriting URLs. The point here is to be as clever (no more, no less) than Git. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I absolutely agree.
That's quite unexpected to me. Edit: Also note, that on same length of the real URL piece the same thing happens: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might also well be, that the two of user interpret differently what length is considered by git.
In my example I'd consider There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Last for now: Tried to somehow apply local config for that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The length of the match is relevant, not the length of the replacement (see There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like te discussion ended up being about unexpected behavior that is a consequence of git's decision to use the replacement as the key (discussed here). But I think Ben's point about the value potentially being a tuple still needs to be considered to be safe. Consider for example the unlikely event that the user has repeat values for the same key:
Here's what
That's because the value is a tuple and the length is calculated as 2:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
if url.startswith(v)} | ||
# find longest match, like Git does | ||
if matches: | ||
rewrite_base, match_len = sorted( | ||
matches.items(), | ||
key=lambda x: x[1], | ||
reverse=True, | ||
)[0] | ||
url = '{}{}'.format(rewrite_base, url[match_len:]) | ||
return url | ||
|
||
|
||
# for convenience, bind to class too | ||
ConfigManager.rewrite_url = rewrite_url |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, git itself doesn't recursively resolve the
insteadof
values. Is there a concrete use case for this?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found it to be an awesome thing to do, but now I cannot think of an actual need for it. Will remove (but keep the memory of having done it close to my heart).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.