-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
x/tools/txtar: implement fs.FS #44158
Comments
SGTM. No need for a proposal. |
I’m on paternity leave now so I can only type with my left thumb during the day. (Gotta keep the bottle in my right hand.) I’ll try to send out a CL as soon as I can but it may not be until next month. |
Hate to be a broken record on this particular thing, but I'm pretty sure thanks to #40067, this can't happen until The (This could certainly be implemented in some other repo/module and work fine, though. golang-migrate has done this for now to support |
For this kind of use--implementing the interface--the relevant code can be protected by a build tag. |
Yes, that's correct. My interpretation of Ian's comment was that all of the bits and pieces that make up the IMO #40067 is going to gate quite a few users for the much-anticipated |
Yes, that's correct. It is unfortunately not possible to implement the Probably the cleanest solution in the short term is to put the |
Even a new package won't work, it'd need to be another module; #40067 affects modules, as the tooling refuses to continue once it detects that a module it's downloaded contains a package it can't resolve. |
@zikaeroh, I believe you are mistaken. Neither |
It would mean that users would be unable to run |
I was basing my experience on #40067 (comment), but I can see how that list of packages means I was indirectly importing it. I'll have to make a minimal example to look at the edge cases. I guess this is overall better than "it's impossible", but this behavior is a little infectious in nature and non-obvious that there's a different set of checks that aren't aware of build tags or new packages. |
The separate package thing will only work if nothing imports it, at which point I may as well just publish the package on my own account and wait until Go 1.16 is the lowest supported version to comeback and add it to x/tools. |
I couldn't quite tell what the status was here, and I wanted this for my own purposes, so I put together an extremely quick and dirty bridge package: https://github.com/josharian/txtarfs. I look forward to txtar directly supporting fs.FS in the future. |
I was wrong about it infecting the whole module (@bcmills was of course correct); |
Oh, I'm a liar, that was added to an existing package and I didn't notice when I read the CL, so it doesn't serve as a working example (and probably should be added to #40067...). |
With #44557 fixed and now backported, nothing stops adding io/fs and embed to existing packages anymore (other than waiting for patch release adoption). |
If it's possible to make this change now, @josharian do you want to just submit your txtarfs as a CL? |
It's kind of a hack, and it allocates unnecessarily, and it creates a new thing instead of just using the txtar directly as an fs.FS. So I think it's not worth upstreaming—it'd be better to do properly. |
I started working on an implementation, and getting the directory stuff right basically requires reimplementing MapFS, so I don't think there's actually that much to be gained by doing it "right". I would change |
I see. Pity. Feel free to steal code wholesale from txtarfs as you please. If you want to credit me, you can add a "Co-authored-by: " trailer to the git commit. |
The big thing we need to decide here is whether Archive has an fs.FS returning method or Archive is an fs.FS itself. There are pros and cons to either. Returning an fs.FS leaves the door open to future optimizations. Being an fs.FS makes some of the code simpler at the cost of not leaving room for future optimizations. |
I think txtar.Archive should just be an FS, the same way that zip.Reader is. It can still have its own unexported cache supporting the FS operations. The only tricky part would be if users expected to be able to change a.File[i].Name and expect to see those changes reflected immediately in future uses of the Archive as an FS. I am inclined to define that the Archive must not be modified after being used an FS. The alternative is that we have a relatively expensive O(N) method a.FS() returning an FS, but people may well expect that to be cheap, using it for things like a.FS().ReadFile("name"), and be surprised that it's O(N) and not O(1). |
On the other hand, we've resisted adding any methods at all to Archive so far, so maybe we should continue that. A top-level function is less likely to be expected to be "cheap" than a method too, so that resolves that problem.
|
That works for me. |
Implementing this, I notice we have filepath.IsLocal, but not path.IsLocal. We should probably also have path.IsLocal which would just be the same as Unix filepath.IsLocal. |
Fixes golang/go#44158 From implementation copied with permission from https://github.com/josharian/txtarfs/blob/main/txtarfs_test.go golang/go#44158 (comment)
Have all remaining concerns about this proposal been addressed? Add the following to package txtar:
|
Reading that doc comment makes me wonder whether we should copy the file contents too. Txtar files aren’t likely to be massive, and it makes the API much cleaner. |
But if they were massive, it'd be weird to make a full copy of all the content. |
If there are a lot of files, the current implementation will be slow because it has to iterate a MapFS. I think copying probably makes the most sense. |
I hear you, Russ, but it feels weird to copy some but not all of it. I won’t die on this hill, though—happy to have this available any which way. |
Would it feel less weird if we pass the |
If FS takes an Archive then you have to explain why Format takes an *Archive. |
@josharian How about this:
We can even have the implementation save integer indexes into the archive and double-check the ones it is implicitly using during each FS operation, and return ErrModified if it sees a modification. |
Based on the discussion above, this proposal seems like a likely accept. The new API is:
|
No change in consensus, so accepted. 🎉 The new API is:
|
Change https://go.dev/cl/598756 mentions this issue: |
The implementation would be pretty simple, and it would let you use txtar format for templates and http.FileServers.
The text was updated successfully, but these errors were encountered: