Where should cabal install to by default?

Hi folks, cabal-install is supposed to make things simpler for users, especially new users. It's partly successful at that currently. Many users do not know ghc-pkg even exists for example (not that it was a design goal but it seems to be a consequence). On the other hand we're currently failing users by not making programs they install work by default. Currently cabal-install installs all binaries to ~/.cabal/bin by default. It does per-user installs by default and uses ~/.cabal as its prefix. Obviously ~/.cabal/bin is not on the $PATH, so users who install say, yi or whatever find that typing yi at the prompt does not do anything even though they just installed it. That's a failure on our part. It should work, and if we cannot make it work by default then we need to tell users what they need to do to make it work. So I'd like to discuss what defaults we should use. For reference, these are the features that are implemented right now that we have to play with: * We can do per-user or global installs (affects which package db we use but it also changes the default prefix) * We can set any --prefix we like * We can use versioned binaries (ie adding -$version suffixes) * We can add symlinks to binaries in some other directory * We can use a commend like sudo to do the install phase We can control all these features in the ~/.cabal/config file. When cabal-install is first run it creates a default ~/.cabal/config file. So the question is what default it should set and how we report failure cases to the user. We do not have to use the same defaults on every platform. If we can get away with it I think it's much nicer not to make it interactive. Here's a couple suggestions: For unix systems, do per-user installs to --prefix=~/.cabal but if ~/bin exists then add symlinks there. Or perhaps if ~/bin is not a convention on that unix platform (eg OSX) then do global installs by default to /usr/local and use sudo for the install phase (we know that OS X comes with sudo where as it may or may not on other unix systems). Duncan

Duncan Coutts wrote:
... For unix systems, do per-user installs to --prefix=~/.cabal but if ~/bin exists then add symlinks there.
just a reminder for anyone: if a directory is not already in $PATH then it's annoying to change $PATH; older shell sessions won't be updated automatically with the new $PATH, at least. Makes it a little harder to give the user advice on what to do, in the cases in which we have to resort to merely giving advice. -Isaac

On Sun, 2008-08-03 at 15:44 -0400, Isaac Dupree wrote:
Duncan Coutts wrote:
... For unix systems, do per-user installs to --prefix=~/.cabal but if ~/bin exists then add symlinks there.
just a reminder for anyone: if a directory is not already in $PATH then it's annoying to change $PATH; older shell sessions won't be updated automatically with the new $PATH, at least. Makes it a little harder to give the user advice on what to do, in the cases in which we have to resort to merely giving advice.
And many new users don't know what a path is or how to change one. I'd like to avoid new users seeing: $ cabal install xmonad cabal: this didn't do what you expected, to fix it change the foo setting in your bar file. It's not friendly. Actually at the moment it's worse though: $ cabal install xmonad [.. lots of build output .. ] $ xmonad bash: xmonad: command not found # user gives up, assuming cabal is borked Duncan

On 04/08/2008, at 06:19, Duncan Coutts wrote:
And many new users don't know what a path is or how to change one.
I'd like to avoid new users seeing:
$ cabal install xmonad cabal: this didn't do what you expected, to fix it change the foo setting in your bar file.
It's not friendly.
Actually at the moment it's worse though: $ cabal install xmonad [.. lots of build output .. ] $ xmonad bash: xmonad: command not found # user gives up, assuming cabal is borked
I don't think it's realistic to expect that things will magically work for people who don't know what they are doing. In fact, I can't imagine that there are a lot of people who would use cabal-install and not know about paths. IMO, the goal should rather be to make installation simple for those who do know what they are doing and also to prevent users from shooting themselves in the foot as much as possible. That said, I would prefer installs to be global by default and to go into the same directory/tree in which cabal-install itself lives. Also, I don't think cabal-install itself should somehow invoke sudo. IMO, local installs shouldn't have a default location; rather, the user would be required to specify one in the prefs file or when invoking cabal-install. Roman

Roman Leshchinskiy wrote:
On 04/08/2008, at 06:19, Duncan Coutts wrote:
And many new users don't know what a path is or how to change one.
I'd like to avoid new users seeing:
$ cabal install xmonad cabal: this didn't do what you expected, to fix it change the foo setting in your bar file.
It's not friendly.
Actually at the moment it's worse though: $ cabal install xmonad [.. lots of build output .. ] $ xmonad bash: xmonad: command not found # user gives up, assuming cabal is borked
I don't think it's realistic to expect that things will magically work for people who don't know what they are doing. In fact, I can't imagine that there are a lot of people who would use cabal-install and not know about paths. IMO, the goal should rather be to make installation simple for those who do know what they are doing and also to prevent users from shooting themselves in the foot as much as possible.
That said, I would prefer installs to be global by default and to go into the same directory/tree in which cabal-install itself lives. Also, I don't think cabal-install itself should somehow invoke sudo. IMO, local installs shouldn't have a default location; rather, the user would be required to specify one in the prefs file or when invoking cabal-install.
Roman
I agree with Roman. Programs should not invoke sudo for users (If I need root access, I want to ask for it), and the default should be global rather than guessing a local path. With these two together you get a much deserved permission error if you simply run the program without configuring it or explicitly using root, which is the same as most other install tools and very sane, in my opinion. _____ Justin Bogner

Duncan Coutts:
cabal-install is supposed to make things simpler for users, especially new users. It's partly successful at that currently. Many users do not know ghc-pkg even exists for example (not that it was a design goal but it seems to be a consequence). On the other hand we're currently failing users by not making programs they install work by default.
Currently cabal-install installs all binaries to ~/.cabal/bin by default. It does per-user installs by default and uses ~/.cabal as its prefix.
Obviously ~/.cabal/bin is not on the $PATH, so users who install say, yi or whatever find that typing yi at the prompt does not do anything even though they just installed it. That's a failure on our part. It should work, and if we cannot make it work by default then we need to tell users what they need to do to make it work.
So I'd like to discuss what defaults we should use.
For reference, these are the features that are implemented right now that we have to play with: * We can do per-user or global installs (affects which package db we use but it also changes the default prefix) * We can set any --prefix we like * We can use versioned binaries (ie adding -$version suffixes) * We can add symlinks to binaries in some other directory * We can use a commend like sudo to do the install phase
We can control all these features in the ~/.cabal/config file.
When cabal-install is first run it creates a default ~/.cabal/config file. So the question is what default it should set and how we report failure cases to the user. We do not have to use the same defaults on every platform.
If we can get away with it I think it's much nicer not to make it interactive.
Here's a couple suggestions:
For unix systems, do per-user installs to --prefix=~/.cabal but if ~/ bin exists then add symlinks there.
Or perhaps if ~/bin is not a convention on that unix platform (eg OSX) then do global installs by default to /usr/local and use sudo for the install phase (we know that OS X comes with sudo where as it may or may not on other unix systems).
Just some random remarks: * Hiding installed files in a . directory is very bad style IMHO. I think that should never happen. Independent of whether you install right into /usr/local/bin or whether you symlink or whatever. You might install files under /usr/local/lib/cabal and then symlink, but probably its nicer to installto /usr/local/lib/<package>-<version> and then symlink. * On OS X, its not generally appropriate to install into /usr/local either. Each user has ~/Applications and ~/Library directories that are usually used for per-user installs. Just generally using sudo and put binaries into /usr/local is also bad because not every user will have admin rights on the machine. * ~/.cabal is bad on Mac OS, too. Preferences ought to go into ~/ Library/Preferences/ * Versioning should be the default (and not optional). Manuel

On 2008 Aug 3, at 21:56, Manuel M T Chakravarty wrote:
Duncan Coutts:
Obviously ~/.cabal/bin is not on the $PATH, so users who install say, yi or whatever find that typing yi at the prompt does not do anything even though they just installed it. That's a failure on our part. It should work, and if we cannot make it work by default then we need to tell users what they need to do to make it work.
Grins and giggles: check the user's $PATH for directories under $HOME and use the first one found?
* Hiding installed files in a . directory is very bad style IMHO. I think that should never happen. Independent of whether you install right into /usr/local/bin or whether you symlink
Even if I tell it to? Also, you might want to avoid StarOffice (and perhaps OpenOffice still does it these days).
or whatever. You might install files under /usr/local/lib/cabal and then symlink, but probably its nicer to installto /usr/local/lib/ <package>-<version> and then symlink.
You're missing a key point: *user installs should not require root*. /usr/local is used for global installs, not for per-user installs.
* On OS X, its not generally appropriate to install into /usr/local either. Each user has ~/Applications and ~/Library directories that are usually used for per-user installs. Just
Those are valid only for OSX applications; Unixy stuff goes elsewhere. By convention Fink uses /sw, MacPorts uses /opt/local, and /usr/local is left for packages not owned by either; this makes it a good place to install Cabalized programs (globally).
* ~/.cabal is bad on Mac OS, too. Preferences ought to go into ~/ Library/Preferences/
Again, not for Unixy stuff, only for full OSX applications and frameworks. Try "ls -a" sometime. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On Mon, 2008-08-04 at 11:56 +1000, Manuel M T Chakravarty wrote:
Just some random remarks:
Thanks for the useful feedback on OSX conventions. I was unaware about several of them.
* Hiding installed files in a . directory is very bad style IMHO. I think that should never happen.
Just on OSX or on Unix too? On Linux I'm not sure where else we could put things that's per-user. People seem to object strenuously to programs automatically putting files in any dir other than ~/.progname (or one or two other .files established by specification or convention).
Independent of whether you install right into /usr/local/bin or whether you symlink or whatever. You might install files under /usr/local/lib/cabal and then symlink, but probably its nicer to installto /usr/local/lib/<package>-<version> and then symlink.
For global installs we use prefx=/usr/local at the moment, so that mean /usr/local/lib/<package>-<version> for libs and /usr/local/bin for binaries. I've just implemented the symlinking feature so we could change the default on global installs to use the version suffix on binaries and symlink back into /usr/local/bin. Or do you mean we should install binaries into /usr/local/lib(exec?)/<package>-<version> and then symlink into /usr/local/bin. That would also be reasonable I suppose, though then the versioned binaries are not on the path.
* On OS X, its not generally appropriate to install into /usr/local either. Each user has ~/Applications and ~/Library directories that are usually used for per-user installs. Just generally using sudo and put binaries into /usr/local is also bad because not every user will have admin rights on the machine.
Oh, great. I didn't know OS X had a standard location for per-user installs. That's excellent. So is there a preferred layout for those dirs? I'm guessing there probably is.
* ~/.cabal is bad on Mac OS, too. Preferences ought to go into ~/ Library/Preferences/
Ok. BTW, in that case we should probably fix System.Directory.getAppUserDataDirectory to follow the system convention on OSX. Currently it uses $HOME/.appname on all unix systems (and the Windows convention on Windows). If necessary we may want to split getAppUserDataDirectory into a variant for config and another for data. Since cabal-install is a program should it still be using ~/Library/Preferences/ or is there are corresponding ~/Applications/Preferences/ ? Where would be appropriate for cabal-install put its download cache and build logs?
* Versioning should be the default (and not optional).
Well, it's always configurable (distros that allow only a single version of a program probably would not want it for example), but yes, I think it's a pretty sensible default configuration. We version libs of course, but up 'til now all binaries have been unversioned. We recently added support for arbitrary program prefixes and suffixes (which can include program $version var) and adding unversioned symlinks into some other dir. It's less clear what we'd do on windows if we want versioned binaries since there are no links. Duncan

Duncan Coutts wrote:
Manuel M T Chakravarty wrote:
* On OS X, its not generally appropriate to install into /usr/local either. Each user has ~/Applications and ~/Library directories that are usually used for per-user installs. Just generally using sudo and put binaries into /usr/local is also bad because not every user will have admin rights on the machine.
Oh, great. I didn't know OS X had a standard location for per-user installs. That's excellent. So is there a preferred layout for those dirs? I'm guessing there probably is.
~/Applications seems to be new in OS X 10.5, I sure don't have it in 10.4. But it seems sensible nonetheless. (And it's documented here http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/Arti... ) Note however that the ~/Applications directory is not directly comparable to a UNIX /bin . That's because applications in Mac OS X have binaries, data and all other batteries included in one folder, the "application bundle". For instance, the Thunderbird application is really a folder "Thunderbird.app" and looks something like this ~/Applications/Thunderbird.app/Contents/Info.plist ~/Applications/Thunderbird.app/Contents/MacOS/thunderbird-bin -- binary ~/Applications/Thunderbird.app/Contents/MacOS/ ... ~/Applications/Thunderbird.app/Contents/PkgInfo ~/Applications/Thunderbird.app/Contents/Resources/thunderbird.icns -- icons ~/Applications/Thunderbird.app/Contents/en.lproj/ -- language specific ... etc Bare-bones UNIX binaries like cabal-install itself and those produced by cabal don't really fit that scheme. That's why Mac OS X has a standard UNIX-style tree in /usr/local . Not sure what to do with per-user cabal, I'd make a fresh UNIX-tree at ~/Applications/Cabal/ or even ~/Applications/Haskell/ so we have ~/Applications/Cabal/bin ~/Applications/Cabal/lib ~/Applications/Cabal/share etc.
* ~/.cabal is bad on Mac OS, too. Preferences ought to go into ~/ Library/Preferences/
Ok. BTW, in that case we should probably fix System.Directory.getAppUserDataDirectory to follow the system convention on OSX. Currently it uses $HOME/.appname on all unix systems (and the Windows convention on Windows). If necessary we may want to split getAppUserDataDirectory into a variant for config and another for data.
System.Directory.getAppUserDataDirectory should return ./Progname.app/Contents/Resources for programs that are packaged as OS X application bundle. Of course, that doesn't apply to most UNIX software... However, configuration files are to go in ~/Library/Preferences/ which is sufficiently similar to /etc .
Since cabal-install is a program should it still be using ~/Library/Preferences/ or is there are corresponding ~/Applications/Preferences/ ? Where would be appropriate for cabal-install put its download cache and build logs?
The ~/Library/ folder is more like /usr/etc and /usr/share than /usr/lib , so it works for both executable and shared libraries. ~/Library/Preferences/ for configuration files. ~/Library/Application Support/ for application data that you don't need to run the application. Like examples files or clip arts. ~/Library/Caches/ for cache files. ~/Library/Logs/ for logs. Some documentation from Apple: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/Arti... http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/Arti... Regards, apfelmus

Duncan Coutts wrote:
On Linux I'm not sure where else we could put things that's per-user. People seem to object strenuously to programs automatically putting files in any dir other than ~/.progname (or one or two other .files established by specification or convention).
just a thought: If you're into this standard http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html , we could use $XDG_CACHE_HOME/cabal or $XDG_DATA_HOME/cabal by default (depending whether you think what Cabal installs is just a cache, or not) ( the default values to use for those if not defined are $HOME/.cache and $HOME/.local/share ). Various things, not all X-related, use that convention/standard; the search-paths ($XDG_DATA_DIRS, $XDG_CONFIG_DIRS) can come in handy to separate my own configuration from whatever's been thrown in dot-dirs too. -Isaac

On Mon, Aug 4, 2008 at 3:40 PM, Isaac Dupree
Duncan Coutts wrote:
On Linux I'm not sure where else we could put things that's per-user. People seem to object strenuously to programs automatically putting files in any dir other than ~/.progname (or one or two other .files established by specification or convention).
just a thought:
If you're into this standard http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html , we could use $XDG_CACHE_HOME/cabal or $XDG_DATA_HOME/cabal by default (depending whether you think what Cabal installs is just a cache, or not) ( the default values to use for those if not defined are $HOME/.cache and $HOME/.local/share ). Various things, not all X-related, use that convention/standard; the search-paths ($XDG_DATA_DIRS, $XDG_CONFIG_DIRS) can come in handy to separate my own configuration from whatever's been thrown in dot-dirs too.
-Isaac
FWIW, Python recently went through this exercise and produced http://python.org/dev/peps/pep-0370/, which does use the $HOME/.local directory. I don't know how much that should affect Cabal's choice, but it's a bit of prior art if you're interested. Jeffrey

Jeffrey Yasskin wrote:
FWIW, Python recently went through this exercise and produced http://python.org/dev/peps/pep-0370/, which does use the $HOME/.local directory. I don't know how much that should affect Cabal's choice, but it's a bit of prior art if you're interested.
It seems $HOME/.local/bin is shared between all programs, unlike e.g. $HOME/.local/lib/python2.6/ ? Of course this is how /usr/local works already. But I wonder if we should put the actual binaries somewhere else, and just put symlinks in that "bin" directory. What if the pythoners accidentally call some program "happy" and it conflicts with the binary derived from haskell's Hackage? (Of course that would be a problem for other reasons, but it's worse if it requires overwriting unknown binaries with binaries rather than symlinks vs. symlinks.) -Isaac

Duncan Coutts:
On Mon, 2008-08-04 at 11:56 +1000, Manuel M T Chakravarty wrote:
Just some random remarks:
Thanks for the useful feedback on OSX conventions. I was unaware about several of them.
Also have a look at http://developer.apple.com/tools/installerpolicy.html In particular, it says If your software is multi-platform, try to accomodate your Mac OS X users by not using /etc, /usr/local, and so on, unless your software is only accessible via the command-line. So, the appropriate install location is also dependent on the type of application.
* Hiding installed files in a . directory is very bad style IMHO. I think that should never happen.
Just on OSX or on Unix too? On Linux I'm not sure where else we could put things that's per-user. People seem to object strenuously to programs automatically putting files in any dir other than ~/.progname (or one or two other .files established by specification or convention).
I think an installer is in a somewhat special situation here. It's not that creating files is a side-effect that the user doesn't care about. Installing files is the primary purpose of an installer. And whenever programs are to automagically appear in the PATH, you either have to modify the contents of one of the directories in the PATH or you have to alter the PATH setting (which is worse).
Independent of whether you install right into /usr/local/bin or whether you symlink or whatever. You might install files under /usr/local/lib/cabal and then symlink, but probably its nicer to installto /usr/local/lib/<package>-<version> and then symlink.
For global installs we use prefx=/usr/local at the moment, so that mean /usr/local/lib/<package>-<version> for libs and /usr/local/bin for binaries. I've just implemented the symlinking feature so we could change the default on global installs to use the version suffix on binaries and symlink back into /usr/local/bin.
Or do you mean we should install binaries into /usr/local/lib(exec?)/<package>-<version> and then symlink into /usr/local/bin. That would also be reasonable I suppose, though then the versioned binaries are not on the path.
I'd prefer to only put symlinks into /usr/local/bin or similar. It makes it easier to remove things. You can still put symlinks to versioned binaries there. (That's what the Mac OS installer for GHC does, for example.)
* On OS X, its not generally appropriate to install into /usr/local either. Each user has ~/Applications and ~/Library directories that are usually used for per-user installs. Just generally using sudo and put binaries into /usr/local is also bad because not every user will have admin rights on the machine.
Oh, great. I didn't know OS X had a standard location for per-user installs. That's excellent. So is there a preferred layout for those dirs? I'm guessing there probably is.
OS X has this concept of bundles. The idea is that all installes that come with an application are in one directory (instead of scattered across the system). So, in /Applications and ~/Applications, there is just one dir per app. Applications that need to store data, do that in again just one dir under ~/Library and they may have another dir with preferences under ~/Library/Preferences. For example, the version of Emacs I am using, AquaEmacs, uses ~/ Library/Preferences/Aquamacs\ Emacs instead of .emacs.
* ~/.cabal is bad on Mac OS, too. Preferences ought to go into ~/ Library/Preferences/
Ok. BTW, in that case we should probably fix System.Directory.getAppUserDataDirectory to follow the system convention on OSX. Currently it uses $HOME/.appname on all unix systems (and the Windows convention on Windows). If necessary we may want to split getAppUserDataDirectory into a variant for config and another for data.
Since cabal-install is a program should it still be using ~/Library/Preferences/ or is there are corresponding ~/Applications/Preferences/ ? Where would be appropriate for cabal-install put its download cache and build logs?
There is no ~/Applications/Preferences, only ~/Library/Preferences. However, to be fair, some command-line applications with a Unix origin use '.appname' (eg, ghc). Manuel
participants (8)
-
apfelmus
-
Brandon S. Allbery KF8NH
-
Duncan Coutts
-
Isaac Dupree
-
Jeffrey Yasskin
-
Justin Bogner
-
Manuel M T Chakravarty
-
Roman Leshchinskiy