-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Update Clone dialog's handling of clipboard text #9116
Update Clone dialog's handling of clipboard text #9116
Conversation
ebb57e6
to
477a0bf
Compare
GitCommands/PathUtil.cs
Outdated
|| path.StartsWith("git:", StringComparison.CurrentCultureIgnoreCase) | ||
|| path.StartsWith("ssh:", StringComparison.CurrentCultureIgnoreCase) | ||
|| path.StartsWith("file:", StringComparison.CurrentCultureIgnoreCase)); | ||
&& UrlRegex.IsMatch(path); |
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.
RegEx parsing of this kind of thing makes me a bit uneasy, as the format is generally quite involved. Why not use Url.TryParse
instead?
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'm not sure if there is a Url.TryParse method (unless I'm looking in the wrong place?), but is this what you're referring to?
System.UriParser.IsWellFormedOriginalString
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.
Ah, yes, Uri.TryCreate
seems like a better match: https://docs.microsoft.com/en-us/dotnet/api/system.uri.trycreate?view=net-5.0#System_Uri_TryCreate_System_String_System_UriKind_System_Uri__
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've tried using Uri.TryCreate and it returns false if the string has any characters before or after the URL, which was the original problem - someone had a string in clipboard that of the form "git clone https://...." that wasn't getting detected as a valid potential URL because of the "git clone" text before the URL. I feel that using the regex to detect if the string contains a valid URL allows the user to manually remove non-URL text without having GE guess and potentially get it wrong.
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.
Given a URL cannot contain spaces, you could take the input string, split it by spaces and check each value.
My concern is that the full URL format is complex, and this regex will not cover all valid cases. The Uri class is far more likely to be correct.
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.
Thanks for the feedback, I've switched to using Uri.IsWellFormedUriString
as that allows file paths to not be treated as URIs (Uri.TryCreate
would consider them as URIs resulting in LocalRepositoryManager methods throwing an exception)
ef30e74
to
c687e82
Compare
#9018 was merged into the master only
|
c687e82
to
fcbb7d1
Compare
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.
Thank you, but the API needs a little more work.
[TestCase("git clone https://github.com/gitextensions/gitextensions", true)] | ||
[TestCase("HTTPS://MYPRIVATEGITHUB.COM:8080/LOUDREPO.GIT", true)] | ||
[TestCase("git://myurl/myrepo.git", true)] | ||
[TestCase("git clone https://github.com/gitextensions/gitextensions && cd gitextensions", true)] | ||
[TestCase("github.com/gitextensions", false)] | ||
[TestCase("github.com/gitextensions/gitextensions/pull/9018", false)] | ||
[TestCase("git clone ssh://username@gerrit-server:/PROJECT", true)] |
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.
Neither of these are correct inputs for CanBeGitURL
method - because the answer to the question "Can either of those be a git URL?" is "no".
[TestCase("git clone https://github.com/gitextensions/gitextensions", true)]
[TestCase("git clone https://github.com/gitextensions/gitextensions && cd gitextensions", true)]
[TestCase("github.com/gitextensions", false)]
[TestCase("github.com/gitextensions/gitextensions/pull/9018", false)]
[TestCase("git clone ssh://username@gerrit-server:/PROJECT", true)]
We can consider renaming the method to ContainsGitUrl
, because then the answer becomes "yes". But then the signature must be changed as well to return the valid git URL... So we'll have to make it something like:
public static bool TryExtractGitUrl(string url, out string gitUrl)
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 believe the comments are addressed
GitCommands/PathUtil.cs
Outdated
string[] pathElements = path.Split(' '); | ||
bool validUrl = false; | ||
foreach (string str in pathElements) | ||
{ | ||
validUrl |= Uri.IsWellFormedUriString(str, UriKind.Absolute); | ||
} |
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.
Likewise this method's purpose is to validate the input string, and not break it apart and check each part. The proposal makes the behaviour surprising - as now the question "Is 'git clone https://github.com/gitextensions/gitextensions' a URL?" results in "Yes", which is unexpected to anyone looking at the signature.
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.
Agree. If the caller wants to check individual words, they can split the string and call this on each.
|
@nyankoframe Any update? 3.5.1 is hopefully released quite soon |
Sorry for the delay; I was a bit buried at work, but should have some time in the next few days to make the proposed changes. |
fcbb7d1
to
a6c767b
Compare
a6c767b
to
0d3845e
Compare
GitCommands/PathUtil.cs
Outdated
return Uri.IsWellFormedUriString(path, UriKind.Absolute); | ||
} | ||
|
||
public static bool ExtractURLsFromString(string contents, List<string> urls) |
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.
A small change to the API here seems more idiomatic, somehow.
public static bool ExtractURLsFromString(string contents, List<string> urls) | |
public static bool TryExtractURLsFromString(string contents, out List<string> urls) |
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.
Thanks for the feedback; will update in the next iteration.
GitCommands/PathUtil.cs
Outdated
return false; | ||
} | ||
|
||
string[] parts = contents.Split(' '); |
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.
Could use LazyStringSplit
here (I think the PR where I added that was merged) to avoid allocating a string[]
.
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 don't see LazyStringSplit in the 3.5 branch, but will use it when I replace the original implementation in the main branch.
GitCommands/PathUtil.cs
Outdated
/// <param name="path">A path to check.</param> | ||
/// <returns><see langword="true"/> if the given path starts with 'http', 'ssh' or 'git'; otherwise <see langword="false"/>.</returns> | ||
/// <returns><see langword="true"/> if the given path contains a URL; otherwise <see langword="false"/>.</returns> | ||
[Pure] | ||
public static bool IsUrl(string path) |
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.
This method doesn't add much value any more. It's basically just Uri.IsWellFormedUriString
. Do we still need it?
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've removed this method and replaced references to it by calling Uri.IsWellFormedUriString
.
0d3845e
to
7b3852b
Compare
I don't understand why the submodule tests are failing in AppVeyor, but pass when I run them locally. :( |
7b3852b
to
efb5c6b
Compare
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 would like to see the test being updated, but otherwise OK for me
[TestCase("file:", false)] | ||
[TestCase("SSH:", true)] | ||
[TestCase("SSH", false)] | ||
[TestCase("https://myhost:12368/", true)] | ||
public void CanBeGitURL(string url, bool expected) |
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.
There are no tests for the second tests
|| url.EndsWith(".git", StringComparison.CurrentCultureIgnoreCase)
|| GitModule.IsValidGitWorkingDir(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.
There are some tests for paths/URLs that end with .git but I guess there are no tests for IsValidGitWorkingDir since it needs a specific directory structure.
Tests require the as much effort as the code... I cannot see what goes wrong, it seems a little like tests run in parallel (which is not possible for these tests). |
GitCommands/PathUtil.cs
Outdated
/// <param name="contents">A string to attempt to extract URLs from.</param> | ||
/// <param name="urls">A <see cref="List{T}"/> that contains any URLs extracted from <paramref name="contents"/>.</param> | ||
/// <returns><see langword="true"/> if the given string contains one or more URLs; otherwise <see langword="false"/>.</returns> | ||
public static bool TryExtractURLsFromString(string contents, out List<string> urls) |
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.
public static bool TryExtractURLsFromString(string contents, out List<string> urls) | |
public static bool TryExtractUrls(string contents, out IReadOnlyList<string> urls) |
GitCommands/PathUtil.cs
Outdated
/// <param name="contents">A string to attempt to extract URLs from.</param> | ||
/// <param name="urls">A <see cref="List{T}"/> that contains any URLs extracted from <paramref name="contents"/>.</param> | ||
/// <returns><see langword="true"/> if the given string contains one or more URLs; otherwise <see langword="false"/>.</returns> | ||
public static bool TryExtractURLsFromString(string contents, out List<string> urls) |
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.
💭 To clarify - we now have a single callsite for this method in FormClone
, right? If this is so, I'd turn this method into a private in FormClone
, and test it through a test accessor. And since the only use case for this method is to use the first detected URL, there are questions why we need to allocate a list, etc.
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.
Thank you for the feedback; I've changed this method to a private in FormClone
and have added a test for it.
Note: 3.5.1 is hopefully shipped soon... |
efb5c6b
to
212674b
Compare
|
||
accessor.TryExtractUrl(text, out var url).Should().Equals(expected); | ||
|
||
url.Should().Equals(expectedUrl); |
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.
Should expected URL be tested if expected
is false?
This change adds a new FormClone.TryExtractUrl method to split a string by spaces and extract the first string for which Uri.IsWellFormedUriString returns true. A new integration test is added for FormClone to validate the behavior of the new method. This change updates the Clone dialog to use the new method for extracting URLs from clipboard contents. Calls to PathUtil.IsUrl are replaced by direct calls to Uri.IsWellFormedUriString.
212674b
to
d462673
Compare
Thank you! |
@nyankoframe can you please send a matching PR to the master branch? |
This was changed in gitextensions#9116 to only check for a valid URL as part of the rework to break down a string of text to find a valid URL.
Fixes #6260
Proposed changes
Test methodology
Test environment(s)
✒️ I contribute this code under The Developer Certificate of Origin.