-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Path casts #2077
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
Path casts #2077
Conversation
@nathanhammond is attempting to deploy a commit to the Vercel Team on Vercel. A member of the Team first needs to authorize 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.
Notes to reviewers.
turbopath.AnchoredSystemPath(filepath.Join("..", "root.json")), | ||
turbopath.AnchoredSystemPath("child.json"), | ||
turbopath.AnchoredSystemPath(filepath.Join("grandchild", "grandchild.json")), | ||
turbopath.AnchoredUnixPath("../root.json").ToSystemPath(), |
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 actually breaks one of the rules intended to exist for Anchored(System|Unix)Paths
: that they're io/fs
safe. I'm not going to address this now because it's an issue with our entire hashing story.
packageJSONs := make(map[interface{}]*fs.PackageJSON) | ||
graph := &dag.AcyclicGraph{} | ||
graph.Add("@foo/bar") | ||
packageJSONs["@foo/bar"] = &fs.PackageJSON{ | ||
Name: "@foo/bar", | ||
Dir: turbopath.AnchoredSystemPath(filepath.Join(root, "packages", "bar")), | ||
Dir: rootPath.UntypedJoin("packages", "bar"), |
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 is actually a problem; we're alternately supplying this with Anchored
and Absolute
paths. We still need to address this (which is why this PR presently is in Draft).
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.
Okay, I've confirmed that this is definitely supposed to be a Anchored
100% of the time: https://github.com/vercel/turborepo/blob/main/cli/internal/run/run.go#L906
I'm changing all instances of this to match.
@@ -57,28 +57,28 @@ func TestResolvePackages(t *testing.T) { | |||
graph.Connect(dag.BasicEdge("app2-a", "libC")) | |||
packagesInfos := map[interface{}]*fs.PackageJSON{ | |||
"app0": { | |||
Dir: turbopath.AnchoredSystemPath(filepath.FromSlash("app/app0")), | |||
Dir: turbopath.AnchoredUnixPath("app/app0").ToSystemPath(), |
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 should be our preferred pattern for creating AnchoredSystemPath
s in tests: use AnchoredUnixPath
and then convert it to an AnchoredSystemPath
.
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.
Do we want a SystemPathFromUnixString
to avoid forgetful devs (me) from trying to directly create a system path from a string with unix separators?
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 want to write a linter that checks for \
in strings passed to Unix
, and either of \
or /
in strings passed to System
. Creating a function will not prevent us from making mistakes as we have seen multiple clever ways of accidentally failing this in just my last two PRs.
Problem: low priority.
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.
(On numerous occasions we have failed to satisfy the XTypeFromYSource
constraint, so we should stop relying on fallible humans to do the right thing.)
prefix := pkgName + "/" | ||
prefixLen := len(prefix) |
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 test was accidentally platform dependent, but the upstream code appears to have gracefully handled the garbage in.
if err != nil { | ||
t.Fatalf("failed to calculate manual hashes: %v", err) | ||
} | ||
for path, spec := range files { | ||
if strings.HasPrefix(path.ToString(), prefix.ToString()) { | ||
if path.ToSystemPath().HasPrefix(pkgName) { |
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 was previously comparing an AnchoredUnixPath
and an AnchoredSystemPath
. 🤦♂️
So now we have a utility function to stop doing that.
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
7a88dd4
to
06cfeb9
Compare
Both of the exceptions in the lockfile files will be fixed up when I properly add patch support to Yarn 2+ and revamp the pnpm patch support. I'm pretty sure |
|
||
// otherPath is definitely shorter than p. | ||
// We need to confirm that p[len(otherPath)] is a system separator. | ||
return os.IsPathSeparator(p[prefixLen]) |
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.
Won't this return true for "foo/bar".HasPrefix("baz/")
or for any prefix that has a length that happens to line up with a path separator?
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.
Yup. Totally missed a step here.
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.
Only thing I think needs to get fixed is the implementation of HasPrefix
@@ -25,9 +25,9 @@ func (p AnchoredUnixPath) ToUnixPath() AnchoredUnixPath { | |||
} | |||
|
|||
// RelativeTo calculates the relative path between two `AnchoredUnixPath`s. | |||
func (p AnchoredUnixPath) RelativeTo(basePath AnchoredUnixPath) (AnchoredUnixPath, error) { | |||
func (p AnchoredUnixPath) RelativeTo(basePath AnchoredUnixPath) (AnchoredSystemPath, error) { |
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.
It looks like the callsites immediately convert to AnchoredUnixPath
. Maybe this function should do that, rather than change types?
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.
The correct answer here is actually to avoid triggering FromSlash
or ToSlash
as those calls are cross-platform unsafe. It's usually not a problem because most people on POSIX systems don't create file names like this\is\going\to\go\badly.txt
but it's an unfortunate edge case.
I want to actually fix this, but it's not something I can justify doing in our current world.
In the mean time I'm going to drop this function and address the call sites with string manipulation.
2291653
to
07927ed
Compare
@gsoltis (correctly! as proven by this PR) has a vendetta against casts.
This PR removes most casts to
turbopath.*
in the repository with explicit exceptions for strings andt.TempDir()
.The regex used to identify casts, of which, 100% have been manually reviewed:
turbopath\.(Absolute|Anchored|Relative)(Unix|System)Path\(
Of the remaining 13 that do not fall into the above
"string"
ort.TempDir()
exceptions, 7 fall outside of thefs
package:turbopath\.(Absolute|Anchored|Relative)(Unix|System)Path\((?!("|t\.TempDir))
Of these 7:
berry
andpnpm
patches. I'll pass that off to @chris-olszewski since I'm not 100% certain that I can safely slapturbopath.AnchoredUnixPathFromUpstream()
on them.