Skip to content
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

reconsider removal of System.PosixCompat.User #3

Open
joeyh opened this issue Mar 31, 2023 · 21 comments
Open

reconsider removal of System.PosixCompat.User #3

joeyh opened this issue Mar 31, 2023 · 21 comments

Comments

@joeyh
Copy link
Contributor

joeyh commented Mar 31, 2023

System.PosixCompat.User actally had useful purposes despite not doing anything useful on Windows. Here's how I depend on it in git-annex:

I have a custom Setup.hs, which hooks into cabal to install additional files in the user's home directory.

To get the home directory, I need to use System.Posix.User, so would need a Setup-Depends: unix in the cabal file. But that would prevent building on windows! So instead I Setup-Depends: unix-compat. Then the code that gets the user's home directory is #ifdefed to avoid using getEffectiveUserID on Windows.

Note that cabal does not allow using if(! os(windows)) in the custom-setup block. If it did, I could simply depend on unix conditionally. (Cabal says: invalid subsection "if")

I am going to have to pin unix-compat at an old version, or remove functionality from my custom Setup if this change is not reverted.

github-actions bot pushed a commit to datalad/git-annex that referenced this issue Mar 31, 2023
Which removed System.PosixCompat.User.
See haskell-pkg-janitors/unix-compat#3

Sponsored-by: Noam Kremen on Patreon
@mitchellwrosen
Copy link
Member

I'm not sure reintroducing the module is the correct solution here. If I understand correctly, this seems more like a missing feature of cabal.

@andreasabel
Copy link
Member

@joeyh wrote:

To get the home directory, I need to use System.Posix.User, so would need a Setup-Depends: unix in the cabal file. But that would prevent building on windows! So instead I Setup-Depends: unix-compat. Then the code that gets the user's home directory is #ifdefed to avoid using getEffectiveUserID on Windows.

Is it this code here?
https://github.com/datalad/git-annex/blob/2b40fa51d32a1103d3d56e422a60024cf9270b7b/Build/DesktopFile.hs#L26-L39

@mitchellwrosen wrote:

I'm not sure reintroducing the module is the correct solution here. If I understand correctly, this seems more like a missing feature of cabal.

Note that for a new feature in cabal to become effective one has to allow several years (as one usually cannot assume the latest Cabal is installed).
We need a migration plan that works in the current ecosystem.

@mitchellwrosen
Copy link
Member

I suppose that is true.

Suppose, though, that unix-compat never exported a broken and useless System.PosixCompat.User in the first place. How would this custom setup in git-annex work, then?

It seems to me that the suggestion to add the module at that point, just so it can then be ignored with some careful CPP, would be the "ill-considered" move here ;)

Any suggestions besides adding it back?

@andreasabel
Copy link
Member

Interestingly, when @bringert added System.PosixCompat.User originally (16 years ago), it provided little functionality for OSs apart from Unix: bfb738a

Added System.PosixCompat.User. The portable implementations are just stubs.

So maybe the intention was from the beginning that these operations are available statically (= at compile-time) on all OSs, but dynamically (= at runtime) only on Unix.

@bringert
Copy link
Contributor

bringert commented Apr 1, 2023

I don't remember exactly why I created this, but I seem to recall that the intention was as @andreasabel suggests, for some use case similar to what @joeyh describes.

@mitchellwrosen
Copy link
Member

mitchellwrosen commented Apr 1, 2023

My understanding is the purpose of this package is to assist Haskell package authors write cross-platform code with as little CPP as possible. Probably most of these users are more familiar with the unix APIs, and want their code to "just work" on Windows without having to own a Windows box or VM to test on.

That's also what's implied by the package description (emphasis mine):

This package provides portable implementations of parts of the unix package.

So, if indeed this module was added to support @joeyh's use case some 16 years ago, I think it should have come with a big disclaimer:

WARNING: this module is almost certainly NOT useful to you. It does NOT provide portable implementations of API you see. It exists ONLY because cabal does not currently allow you to conditionally depend on a package in a custom-setup stanza. If you do not need to depend on unix-compat in a custom Setup.hs file, then you do not want to use this module.

Because as of version 0.6, the last version that shipped with this module exposed, the description was:

This module makes the operations exported by System.Posix.User available on all platforms. On POSIX systems it re-exports operations from System.Posix.User. On other platforms it provides dummy implementations.

That, to me, sounds like "we've added this module because it exists in unix; maybe Windows will have an API like this some day, but for now, we'll just throw exceptions". I believe this package is much better without such dummy implementations. I could be wrong about that, but that's what motivated the deletion.

Are there any other suggestions besides adding the module back? It really seems better to me that users depend on unix, not unix-compat, if they need unix-specific APIs. Then no user will be duped into thinking they are shipping working cross-platform code by using a package whose purpose is to provide working cross-platform code.

That cabal doesn't let you do that in a Setup.hs is unfortunate, but I'm sure there's another way to accomplish this, possibly involving a makefile or some such. Right? Or am I mistaken? I certainly could be.

@mitchellwrosen
Copy link
Member

I might even suggest another package like unix-uncompat to house such modules for @joeyh's use case.

@andreasabel
Copy link
Member

andreasabel commented Apr 2, 2023

unix-incompat ;-) I agree that this might be better to split out such functionality.

@joeyh
Copy link
Contributor Author

joeyh commented Apr 13, 2023

@andreasabel good sleuthing, that is the code in question

@joeyh
Copy link
Contributor Author

joeyh commented Apr 13, 2023

Note that other parts of unix-compat also contain such stubs, for example createSymbolicLink. I don't use those, but I assume there is some use case for them.

I think my experience is it's a mixed bag to provide these -- I have had to take care to not use things like createSymbolicLink on Windows, even though the code would compile.

A unix-incompat would pose its own challange for me, because I keep git-annex buildable on Debian stable, which includes unix-compat but of course not yet unix-incompat. And the Custom-Setup block does not seem to allow using flags or some other mechanism to select between the old unix-compat and unix-incompat.

My suggestion would be to revert this change for now and split the package at a more measured pace if possible. (Although waiting for Debian stable to include something is a bit of an ask I know.)

@joeyh
Copy link
Contributor Author

joeyh commented Apr 13, 2023

Rather than splitting the package, why not move the problimatic functions into new modules in unix-compat?

eg System.PosixCompat.User.Unportable

@mitchellwrosen
Copy link
Member

Note that other parts of unix-compat also contain such stubs, for example createSymbolicLink.

Indeed; no complete inspection and overhaul was performed in the 0.6 -> 0.7 update; just the main one that was a little blocked up, due to indecisions around how exactly to support the type that was changed in System.Posix.User.

I feel, for the same reasons as stated above, this package ought not to export createSymbolicLink, nor anything else that either throws an exception or does nothing at all pure ().

I don't use those, but I assume there is some use case for them.

If there are use cases for them, let's please identify them and write them down! We've discovered one so far: cabal does not support conditional dependencies in setup-depends (btw, do you agree this is more of a missing cabal feature than a unix-compat infelicity?). But I'd like to understand the purpose of such stubs before just taking it for granted that they should exist.

A unix-incompat would pose its own challange for me, because I keep git-annex buildable on Debian stable, which includes unix-compat but of course not yet unix-incompat.

Out of curiosity, how long might a new package like unix-incompat take to appear in Debian stable? Ditto for a new version of unix-compat. I want to understand if the suggestion to add back a module to unix-compat to solve this issue is because the package turnaround time for appearing in Debian stable is longer.

@joeyh
Copy link
Contributor Author

joeyh commented May 29, 2023

Generally it takes a couple of years.

@mitchellwrosen
Copy link
Member

mitchellwrosen commented May 29, 2023

I see. Well, to summarize my thoughts: I'm not personally keen on reintroducing the module here. The motivating use case as I understand it is too narrow.

To reiterate, I feel:

  • Packages that need some generic functionality that happens to require platform-specific APIs (like filesystem access) ought to rely on unix-compat, if we are able to put together a shim of those APIs with the same semantics.
  • Packages that need some platform-specific functionality ought not to rely on unix-compat, but rather unix, Win32, etc.

However, I'm not the sole maintainer here. Just a janitor, and one who's particularly uninterested in whatever happens to unix-compat, to be honest. I only got involved here to unblock myself on a warp upgrade many months ago, and warp has since dropped its dependency on unix-compat, so I have no more skin in this game.

unix-compat-0.7, happily, unblocked the ecosystem. It was previously abandoned, and had some miscellaneous open PRs like this one that puzzled over exactly how to make unix-compat compatible with unix-2.8.

@joeyh, you are also a janitor with commit bits. Please don't take my protestations as gatekeeping; if you put together a new release of unix-compat to your satisfaction I can help release it to Hackage. I might suggest you bump the lower bound on unix to >= 2.8, rather than try to maintain compatibility with pre- and post-2.8 with CPP, as was done in the linked PR. That might break someone else's workflow, though... ;)

@Profpatsch
Copy link

The motivating use case as I understand it is too narrow.

A compiling git-annex is a narrow use-case for you? I beg your pardon?

sternenseemann added a commit to NixOS/nixpkgs that referenced this issue Jul 4, 2023
git-annex needs the removed System.PosixCompat.User module
haskell-pkg-janitors/unix-compat#3
@ulysses4ever
Copy link

There's a workaround for conditionals in custom-setup: have you considered applying it, @joeyh?

@mitchellwrosen
Copy link
Member

@Profpatsch Thanks for your concern, could you provide a suggestion to move forward?

rvl pushed a commit to rvl/nixpkgs that referenced this issue Jul 20, 2023
git-annex needs the removed System.PosixCompat.User module
haskell-pkg-janitors/unix-compat#3
rvl pushed a commit to rvl/nixpkgs that referenced this issue Jul 25, 2023
git-annex needs the removed System.PosixCompat.User module
haskell-pkg-janitors/unix-compat#3
@joeyh
Copy link
Contributor Author

joeyh commented Aug 1, 2023

There's a workaround for conditionals in custom-setup: have you considered applying it, @joeyh?

Abstracting code into a separate package and depending on that package is exactly what we've been doing. unix-compat was that package.

@Profpatsch
Copy link

@Profpatsch Thanks for your concern, could you provide a suggestion to move forward?

Yeah, just put the module back to unbreak the ecosystem. Things can be reverted.

@joeyh
Copy link
Contributor Author

joeyh commented Aug 1, 2023

While I'd agree with reverting this, one thing I'd forgotten is that cabal v2 doesn't support Setup files running any post-install hooks apparently. Which means there is much less scope for setup files to do things that need unix-compat. Not that there's no scope left, but in this case the only benefit of git-annex's Setup using unix-compat was to be able to do some things when used with cabal v1-install, which was not worth continuing to support.

github-actions bot pushed a commit to datalad/git-annex that referenced this issue Aug 1, 2023
…-shell and git-remote-tor-annex symlinks

Anything still relying on that, eg via cabal v1-install will need to
change to using make install-home. Which was added back in 2019 in
6491b62 because cabal new-build
(now the default) already didn't use Setup in a way that let its
installation of those things work.

Notably this means Setup does not need to depend on unix-compat, which is
useful because in 0.7 it removed System.PosixCompat.User, which Setup
needed to determine where to install the desktop files. See
haskell-pkg-janitors/unix-compat#3
@Profpatsch
Copy link

I’ve submitted a patch. It’s a simple revert (but with CHANGELOG change), somebody might want to check whether that’s what we want

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants