
At 20:18 2004-06-04 -0400, Isaac Jones
Hi Arie,
Hi Isaac,
I'm afraid you must misunderstand something. A makefile is not the interface. The interface is the Setup script and the arguments to it (install, build, etc).
OK. As I understand it, Marcus creates a Setup.lhs that merely passes its arguments to a makefile. All the relevant information is contained in that makefile. Is that makefile supposed to be platform independent? (And with platform independent I mean really independent, so no emulation (Cygwin, for example) is needed.)
Do you mean by 'interface' the way in which a user invokes the installation? I would like to be able to choose whether I type "make install" myself,
I don't understand; the "choice" of how to install the system is not made by you (Joe, Bob, or Sam), the installer, but rather by the author (Angela or Marcus).
As I see it, the author (Angela or Marcus) decides what needs to be done to perform the installation, but the user (Joe, Bob or Sam) decides how the installation is performed. (See below for more about this distinction.)
Alex' idea of an installation data structure suits that wish perfectly. As mentioned before, it would be particularly nice to know what files/directories are to be modified or added.
Package managers such as dpkg typically handle this kind of thing. If you use one of those, you'll still have this ability for packages installed via dpkg.
Still, I think that that information should be directly available from the installation file, without actually performing the installation.
Distribution.Simple provides some mechanisms for making Angela's life easier, especially with very simple libraries. Now say Angela has a library that uses Distribution.Simple, but she's altered it to utilize the Happy preprocessor, and (let's say) Distribution.Simple doesn't know anything about Happy. Now Angela can add a "system" call to her Setup file to preprocess what she needs to, and continue using the rest of the Distribution.Simple mechanism she was using before.
In the StaticSetup scheme, Angela is out of luck. She can't change the behavior of StaticSetup to do the right thing, so she has to get rid of her build system altogether and start from scratch with makefiles or something. This is what we want to avoid.
If the preprocessor is to be executed by the user,
Which user are you referring to? We gave them all names :)
That would be Bob or Sam (Joe doesn't seem too involved in the entire package system).
If the installer system, provided by Angela, can perform arbitrary IO actions, then you have lost the property of knowing which files it installs.
That's right. However, I imagine that the IO action contains a String field with a message from Angela, explaining what the IO action does. If the setup contains no IO actions, then the user (Bob or Sam) can be sure that nothing unexpected can happen. If the setup does contain IO actions, then the user (Bob or Sam) may be made aware of that so he can decide if he wants to continue.
This package structure may be distributed: 1. as haskell source code alone, to allow users to install the package with their own customised installer or a default ghc installer;
How does the user customize an installer for darcs?
I am not familiar at all with darcs. What makes it a special case? In general, an installer can be written from scratch (in haskell), derived from another installer (by editing it's source code) or customised (by parametrising or configuring an existing installer).
2. in source form with an installer that the user may or may not use; 3. compiled by the author with her installer to produce a binary executable installer.
Our system covers 2 and 3.
Suppose that, for any reason, someone (Sam, say) does not want to run the supplied installer (supplied by Angela, that is). With the your system, Sam can find out what must be done to install the package - only by extracting the necessary information from Setup.lhs (case 2), which can be very hard if Angela did not comment her code very well; - not at all (case 3). Right?
Notice that an 'installer' in this context is a haskell program, typically run with hugs or ghci (unless dynamic linking will be widely supported), that merely has a Setup () as a parameter and interprets
I'm confused by who is providing this installer, and how this Setup structure gets provided to an executable.
The installer can be provided by Angela, if she thinks Bob or Sam will like her installer or does not have an installer at hand (which is unlikely, but hey). Often, the installer will be the one supplied by the compiler that Bob or Sam uses. Configuration options (of the installer) can be saved for installation of other packages. Some people will want to hack on an existing installer or write one from scratch. Maybe Sam wants to create an installer for Bob to automate installations as much as possible, or Bob wants to have an installer that does exactly what he tells it to do, and nothing more. The Setup structure can be interpreted/executed (by Bob or Sam) by loading both the installer and the module containing the Setup structure in Hugs or GHCi and issuing the right command ("Install.install angela'sSetup" or "Install.install (defaultOptions { path = "/usr/local/" }) angela'sSetup" or something like that). If dynamic linking is an option, that can be used as well: in that case the Setup is compiled and linked (by Bob or Sam) with the (probably already compiled) installer. Angela can also compile her Setup structure with her installer to produce an executable (installer and Setup in one file).
Why ask the user if they want to authorize the IO parts? They will have to read the code to find out what the IO actions do.
As said above, a message (written by Angela) can be included in the IO construct to inform the user (Bob or Sam) about its purpose. Perhaps there are some common tasks that need to be done using an IO construct? In that case we could catch their presence in a datatype to enable further automation (although it would be preferable to keep as much as possible out of the IO part): ioTask :: IOTaskType -> IO -> String -> Setup () ioTask taskType task comment = ... data IOTaskType = FiddleWithKernel | Other (I don't know if the IOTaskType is a useful addition; it is not essential to this approach.)
I'm afraid I do not completely understand your approach. Most especially, I'm confused about what it buys you that our approach does not. I do suspect that we're losing support for Marcus, which is not acceptable.
In my approach there is a clear distinction between what needs to be done (this is contained in the Setup monad) and how it is done (this is directed by the installer). It keeps information in a useful, non-opaque form as long as possible, allowing for more flexibility in the installation.
Further, I think that once you completely understand our approach, you'll like it. Please provide suggestions for the proposal for bits which are unclear.
That is probably true. One aspect that is unclear to me is how version management is facilitated. However, it may be wise to let that rest for a while.
peace,
isaac
Greetings, Arie