Skip to content

Refactor parseGitURL - #4983

Merged
k8s-ci-robot merged 1 commit into
kubernetes-sigs:masterfrom
KnVerey:repospec_separators
Jan 18, 2023
Merged

k8s-ci-robot merged 1 commit into
kubernetes-sigs:masterfrom
KnVerey:repospec_separators

Conversation

@KnVerey

@KnVerey KnVerey commented Jan 14, 2023 •

Copy link
Copy Markdown
Contributor

Part of #4866
Refactors the code that splits the RepoPath from the KustRootPath, and fixes inconsistencies and bugs in doing so:

  • Uses a common path splitting strategy for all URLs--no more completely separate parsing for .git, _git, local etc.
  • Eliminates the special case where URLs containing _git didn't even use extractHost
  • Makes the documented // delimiter work for all URLs (we had skipped tests showing this was broken in some cases)
  • Removes the pseudo-validation of the path segment using url.Parse (see this inline comment)

TIL while working on PR that the error messages NewRepoSpecFromURL never seem to make it to the user AFAICT. Instead, the return of an error is interpreted as "this is probably not a URL at all". For example,(fl *fileLoader) New then tries to load it as a local file, and (fl *fileLoader) httpClientGetContent returns an HTTP error instead of a "this was a remote repo" error. Stuff like this is (part of) why our error messages are so terrible. This PR does not attempt to change this, but the unusual implication of an error return value is good to keep in mind for review.

Remaining follow-ups:

  • (fairly simple) Stop messing with the conventional .git suffix entirely (originally included here but removed for clarity: see this comment)
  • (simple) Add arbitrary username support
  • (unlikely to make the release) Fix the overloading of the error return value? "This URL is invalid" (what we're giving) is not the same as "This doesn't look like a URL" (what the callers seem to need). Could the callers be using something that just validates the URL generically? I'd like to experiment with a dedicated function that does that, and compare it to the results of our error and smoke RepoSpec tests. I think this has a big potential for impact on Kustomize's most confusing error messages.

@k8s-ci-robot

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@k8s-ci-robot k8s-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jan 14, 2023
@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. approved Indicates a PR has been approved by an approver from all required OWNERS files. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jan 14, 2023

func parsePath(n string) string {
parsed, err := url.Parse(n)
// TODO(annasong): decide how to handle error, i.e. return error, empty string, etc.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is suggesting removing this parsing entirely. I noticed that no tests fail if we do so, and so I was wondering what this is intended to catch. I looked back in the history, and it was introduced by #3900. IIUC that PR intended it as a more reliable way (vs the former regex) to separate query parts from the path. We still use it for that today; since #4863 we just do it a bit earlier in the parsing flow. At that earlier point, we're passing the whole raw value to the parser, whereas originally (in valid cases anyway) we were passing just the kust root path + query. So the Path value we would get back at our new invocation is not usable.

The question is, do we then need to continue to put the path through the URL parser at the end of the parsing flow, now on its own (the query long since removed)? I don't think so, because IIUC the original intent was not to validate the path; it was just convenient to take the value returned when we separated a query from it. If you go back one more step in the history, peelQuery was just splitting a query chunk off of n when present.

This also relates to the stance I explained on my last PR re: passing things through to git if they're not interfering with our ability to parse out the repo root. In this case, we've necessarily already done that.

LMK if you agree.

}
var host, rest = n, ""
if sepIndex := findPathSeparator(n, acceptSCP); sepIndex > 0 {
host, rest = n[:sepIndex+1], n[sepIndex+1:]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before, when we didn't find a separator, the whole thing was considered a path. Now it's considered a host. I think this makes more sense, and it maintains the current error messages in some cases. Notably, ssh://git.example.com should complain about orgRepo, not host, missing. Previously all parsing would complete before any errors would return, and for whatever reason orgRepo was checked first, resulting in the correct message for that case despite host also being empty.

Comment thread api/internal/git/repospec.go Resolved
@k8s-ci-robot

Copy link
Copy Markdown
Contributor

@KnVerey: This PR has multiple commits, and the default merge method is: merge.
You can request commits to be squashed using the label: tide/merge-method-squash

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.


if strings.Contains(n, gitDelimiter) {
index := strings.Index(n, gitDelimiter)
// Adding _git/ to host

@KnVerey KnVerey Jan 16, 2023 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know why it was originally added to the host segment in #1271. It's part of the path to to the repo, not the host (our new variable names are nice here!). At the end of the day, correcting this doesn't affect the clone spec.

@KnVerey
KnVerey force-pushed the repospec_separators branch from 8e0e801 to 4d8aed0 Compare January 17, 2023 00:04
if pathElements := strings.Split(cleanedPath, string(filepath.Separator)); len(pathElements) > 0 &&
pathElements[0] == filesys.ParentDir {
return nil, fmt.Errorf("url path exits repo: %s", n)
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially only moved the RepoPath and Host validations into their respective parser methods, but then I noticed that this one is effectively just a KustRootPath validation, so I moved it too. Then all I had left here was the IsAbs check, so I deleted this and renamed parseGitURL to NewRepoSpecFromURL (FYI because that's not what it looks like on Github).

@KnVerey
KnVerey force-pushed the repospec_separators branch from 4d8aed0 to abbeb64 Compare January 17, 2023 00:08
@KnVerey
KnVerey force-pushed the repospec_separators branch from abbeb64 to 0020839 Compare January 17, 2023 01:36
// the parts.
// the different parts of URL, set into a RepoSpec object and return RepoSpec object.
// It MUST return an error if the input is not a git-like URL, as this is used by some code paths
// to distinguish between local and remote paths.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As of today, this seems to be the ONLY thing the errors are used for: to judge whether the string is a URL.

Host: "[email protected]:",
RepoPath: "company/project",
KustRootPath: "/path",
KustRootPath: "path",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it matters whether we end up with a leading slash here, but previously we were inconsistent. Github URLs (which generally are best tested/supported) did not have the prefix previously, so I took them all in that direction.

},
},
{
name: "unsupported protocol after username (invalid but currently passed through to git)",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a behaviour change vs before all our refactoring, though at the end of the day this URL could never work. This PR would require adding code to continue accepting this particular input, and since it isn't valid anyway, I didn't think it was worthwhile.

name: "triple slash absolute path",
kustomization: `
resources:
- file:///$ROOT/simple.git

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out $ROOT already contains a slash, so this test case used four slashes not three, and that's not valid.

@KnVerey KnVerey changed the title Refactor parseGitURL to consolidate code paths, improve error handling Refactor parseGitURL Jan 17, 2023
@KnVerey
KnVerey marked this pull request as ready for review January 17, 2023 02:18
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jan 17, 2023
{
name: "t8",
name: "_git host delimiter in non-github url",
input: "https://itfs.mycompany.com/collection/project/_git/somerepos",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good callout, and thank you for providing the references. TIL about that RFC! In this case, the test suite is just for the parsing step, so there's no chance of us actually trying to use these URLs--the names are for use case illustration purposes only. It uses a variety of invalid/irrelevant domains currently, and I think I'll leave them alone for the purposes of this PR.

name: "double-slash path delimiter https",
input: "https://fake-git-hosting.org/path/to/repo//examples/multibases/dev",
cloneSpec: "https://fake-git-hosting.org/path/to.git",
cloneSpec: "https://fake-git-hosting.org/path/to/repo.git",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think fake-git-hosting.org needs to change too.

@koba1t

koba1t commented Jan 17, 2023

Copy link
Copy Markdown
Member

I think this PR looks good!
I comment on a few nit points. If you don't think need to fix that, please ignore that comments

@natasha41575 natasha41575 left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cleanly and nicely done! Thanks. I see @koba1t left some comments, so I'm adding a hold so you can take a look at those comments. Feel free to remove the hold when you want to merge.

/lgtm
/hold

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jan 17, 2023
@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jan 17, 2023
@k8s-ci-robot

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: KnVerey, natasha41575

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:
  • OWNERS [KnVerey,natasha41575]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@KnVerey

KnVerey commented Jan 18, 2023

Copy link
Copy Markdown
Contributor Author

/unhold

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jan 18, 2023
@k8s-ci-robot
k8s-ci-robot merged commit dbc11a4 into kubernetes-sigs:master Jan 18, 2023
@KnVerey
KnVerey deleted the repospec_separators branch January 18, 2023 01:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants