Re: [Haskell-cafe] Install a script with Cabal?

2012-06-05 Thread Ketil Malde
Rogan Creswick cresw...@gmail.com writes:

 I have a small project that installs a couple of Haskell tools and a
 script that uses these. Cabal will of course build and install the
 Haskell programs, but how can I get Cabal to install the script as
 well? There's a host of UserHooks available¹, but it'd probably be
 better to have an example than to try to experiment with the right
 configuration.

 I don't have an example handy, but I think you'll want preInts,
 instHook, or postInst.  I'd probably go with postInst unless you need
 data provided by instHook's type that isn't passed to preInst or
 postInst.

I found an example¹ using copyHook. However, this seems to be the wrong
thing, at least I am unable to get cabal to ever call this hook (or
preCopy, etc).

 LocalBuildInfo /probably/ has the details you need (eg: installDirTemplates).

I just printed out the contents of LocalBuildInfo, but that's 33 pages
(I counted) of output.  Redirected to a file, it makes it easier to
search to find the relevant needles in this haystack.

Okay, looking at installDirTemplates, I see `bindir` can extract this
data member.  It's of course an InstallDirTemplate, not a FilePath, but
I found 'fromPathTemplate', which has the right type.  Except it only
dumps the template, with $prefix and all.

Hoogle doesn't seem to know about any of the Cabal stuff, Hayoo has a *very*
annoying behavior where it cleans out everything you did if you use the
back button, and the source links it advertises seem to point into
the wide blue 404.  But using the latter, I managed to find a link to
'substPathTemplate', worked out that the PackageIdentifier it needs is a
member of PackageDescription, and tried to use that.  Except it gives
the same result, and doesn't appear to substitute anything.  I guess the
fact that it is undocumented is a hint that it's the wrong thing to use.

Reading some more, maybe 'absoluteInstallDirs' is what I'm looking for?
In addition to the usual heap of huge config structs, it needs a
CopyDest, though.  Since I have no idea what to use, I just put
NoCopyDest there.  Does that make sense?  Okay, it works now, in the
sense that I ran it once on my laptop, and it copied the file to
~/.cabal/bin.  Here is the code, comments welcome:

  #!/usr/bin/env runhaskell

  import Distribution.Simple (defaultMainWithHooks, 
simpleUserHooks,UserHooks(..))
  import Distribution.Simple.Setup (InstallFlags,CopyDest(..))
  import Distribution.Simple.Utils (rawSystemExit)
  import Distribution.PackageDescription (PackageDescription())
  import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), 
InstallDirs(..), absoluteInstallDirs)
  import Distribution.Verbosity (normal)

  main :: IO ()
  main = defaultMainWithHooks simpleUserHooks
  { instHook = \pd lbi uh ifs - myinst pd lbi uh ifs  instHook 
simpleUserHooks pd lbi uh ifs }

  myinst :: PackageDescription - LocalBuildInfo - UserHooks - InstallFlags 
- IO ()
  myinst pd lbi _uh _fs = do
  let bin = bindir $ absoluteInstallDirs pd lbi NoCopyDest
  rawSystemExit normal cp [asmeval, bin]

PS: This was a rather frustrating excercise, and after wallowing through
a wilderness of modules, types, records and functions, I can't help but
feel that Cabal is a bit overengineered. Surely including a script or
similar in a package isn't all that outlandish? Could there conceivably
have been a simpler way?  Or at least, better documented?  I suspect the
fact that - with the sole exception of the link below -- I could find *no*
examples to help me out indicates that it is a bit too complicated.

-k

¹ http://blog.ezyang.com/2010/06/setting-up-cabal-the-ffi-and-c2hs/
-- 
If I haven't seen further, it is by standing in the footprints of giants

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Install a script with Cabal?

2012-06-05 Thread Ivan Perez
I spent quite some time going through the cabal docs to generate some
files automatically with hails. I totally feel your pain :)

What I'm going to suggest is not really a solution to your problem,
but since modifying the hooks to install specific programs is not the
best solution either, you might want to try and write your script in
Haskell (using HSH, for instance). That way you would have a
multi-platform script that can be installed just like any other
Haskell program.

Regarding the general problem, the best I can think of would be adding
a field Bin-files: to the cabal file format, and have Cabal process
it properly. Maybe some of the maintainers of cabal can comment on
that.

Two more suggestions. If you are going to modify the hooks:
1) Do not call cp directly. Use copyFile if possible. cp is *nix dependent.
2) Read the name of the file to be copied from a configuration file.
It is much more likely that others (and you) will be able to reuse
your code if you do.

Cheers,
Ivan.

[1] http://hackage.haskell.org/package/HSH

On 5 June 2012 12:28, Ketil Malde ke...@malde.org wrote:
 Rogan Creswick cresw...@gmail.com writes:

 I have a small project that installs a couple of Haskell tools and a
 script that uses these. Cabal will of course build and install the
 Haskell programs, but how can I get Cabal to install the script as
 well? There's a host of UserHooks available¹, but it'd probably be
 better to have an example than to try to experiment with the right
 configuration.

 I don't have an example handy, but I think you'll want preInts,
 instHook, or postInst.  I'd probably go with postInst unless you need
 data provided by instHook's type that isn't passed to preInst or
 postInst.

 I found an example¹ using copyHook. However, this seems to be the wrong
 thing, at least I am unable to get cabal to ever call this hook (or
 preCopy, etc).

 LocalBuildInfo /probably/ has the details you need (eg: installDirTemplates).

 I just printed out the contents of LocalBuildInfo, but that's 33 pages
 (I counted) of output.  Redirected to a file, it makes it easier to
 search to find the relevant needles in this haystack.

 Okay, looking at installDirTemplates, I see `bindir` can extract this
 data member.  It's of course an InstallDirTemplate, not a FilePath, but
 I found 'fromPathTemplate', which has the right type.  Except it only
 dumps the template, with $prefix and all.

 Hoogle doesn't seem to know about any of the Cabal stuff, Hayoo has a *very*
 annoying behavior where it cleans out everything you did if you use the
 back button, and the source links it advertises seem to point into
 the wide blue 404.  But using the latter, I managed to find a link to
 'substPathTemplate', worked out that the PackageIdentifier it needs is a
 member of PackageDescription, and tried to use that.  Except it gives
 the same result, and doesn't appear to substitute anything.  I guess the
 fact that it is undocumented is a hint that it's the wrong thing to use.

 Reading some more, maybe 'absoluteInstallDirs' is what I'm looking for?
 In addition to the usual heap of huge config structs, it needs a
 CopyDest, though.  Since I have no idea what to use, I just put
 NoCopyDest there.  Does that make sense?  Okay, it works now, in the
 sense that I ran it once on my laptop, and it copied the file to
 ~/.cabal/bin.  Here is the code, comments welcome:

  #!/usr/bin/env runhaskell

  import Distribution.Simple (defaultMainWithHooks, 
 simpleUserHooks,UserHooks(..))
  import Distribution.Simple.Setup (InstallFlags,CopyDest(..))
  import Distribution.Simple.Utils (rawSystemExit)
  import Distribution.PackageDescription (PackageDescription())
  import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), 
 InstallDirs(..), absoluteInstallDirs)
  import Distribution.Verbosity (normal)

  main :: IO ()
  main = defaultMainWithHooks simpleUserHooks
      { instHook = \pd lbi uh ifs - myinst pd lbi uh ifs  instHook 
 simpleUserHooks pd lbi uh ifs }

  myinst :: PackageDescription - LocalBuildInfo - UserHooks - InstallFlags 
 - IO ()
  myinst pd lbi _uh _fs = do
      let bin = bindir $ absoluteInstallDirs pd lbi NoCopyDest
      rawSystemExit normal cp [asmeval, bin]

 PS: This was a rather frustrating excercise, and after wallowing through
 a wilderness of modules, types, records and functions, I can't help but
 feel that Cabal is a bit overengineered. Surely including a script or
 similar in a package isn't all that outlandish? Could there conceivably
 have been a simpler way?  Or at least, better documented?  I suspect the
 fact that - with the sole exception of the link below -- I could find *no*
 examples to help me out indicates that it is a bit too complicated.

 -k

 ¹ http://blog.ezyang.com/2010/06/setting-up-cabal-the-ffi-and-c2hs/
 --
 If I haven't seen further, it is by standing in the footprints of giants

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 

Re: [Haskell-cafe] Install a script with Cabal?

2012-06-05 Thread Rogan Creswick
On Tue, Jun 5, 2012 at 4:28 AM, Ketil Malde ke...@malde.org wrote:
 Rogan Creswick cresw...@gmail.com writes:

 I have a small project that installs a couple of Haskell tools and a
 script that uses these. Cabal will of course build and install the
 Haskell programs, but how can I get Cabal to install the script as
 well? There's a host of UserHooks available¹, but it'd probably be
 better to have an example than to try to experiment with the right
 configuration.

 I don't have an example handy, but I think you'll want preInts,
 instHook, or postInst.  I'd probably go with postInst unless you need
 data provided by instHook's type that isn't passed to preInst or
 postInst.

 I found an example¹ using copyHook. However, this seems to be the wrong
 thing, at least I am unable to get cabal to ever call this hook (or
 preCopy, etc).

I'm not sure if/when copy hooks are used during the typical cabal
configure/build/install process; I suspect they are not used.  There
is, however, a `cabal copy` command, which I believe does.  Not that
that helps you right now, but that may explain the behavior you saw.

 LocalBuildInfo /probably/ has the details you need (eg: installDirTemplates).

This was harder than I thought.

Here's an example (I hacked an example on to the cabal-dev Setup.hs,
so there are extra imports you won't necessarily need -- full Setup.hs
is in the linked gist, the email only contains the relevant exceprts):

Gist:  https://gist.github.com/2876277

main = defaultMainWithHooks $
   simpleUserHooks { hookedPrograms = [cabalInstallProgram]
   , postInst = postInstCp (postInst simpleUserHooks)
   }

type PostInstHook = Args - InstallFlags - PackageDescription -
LocalBuildInfo - IO ()

postInstCp :: PostInstHook - Args - InstallFlags -
PackageDescription - LocalBuildInfo - IO ()
postInstCp oldHook args iflags pDesc lbi = do
  let -- The filename to copy from:
  inFile :: FilePath
  inFile = srcFileName.sh

  -- The filename to copy to:
  outFile :: FilePath
  outFile = destFileName.sh

  prefix = fromFlag $ installDistPref iflags

  -- Make a concrete binDir from the LocalBuildInfo  PackageDescription:
  instBinDir :: FilePath
  instBinDir = bindir $ absoluteInstallDirs pDesc lbi
   (fromFlag $ copyDest
defaultCopyFlags)

  -- layer of indirection, in case we wanted to get a specific
  -- src directory from the cabal file:
  src :: FilePath
  src = inFile

  -- qualify the destination.
  dest :: FilePath
  dest = instBinDir / outFile

  -- Do the copy, creating outFile in the bin dir:
  copyFile src dest

  -- now invoke the old hook:
  oldHook args iflags pDesc lbi


--Rogan


 I just printed out the contents of LocalBuildInfo, but that's 33 pages
 (I counted) of output.  Redirected to a file, it makes it easier to
 search to find the relevant needles in this haystack.

 Okay, looking at installDirTemplates, I see `bindir` can extract this
 data member.  It's of course an InstallDirTemplate, not a FilePath, but
 I found 'fromPathTemplate', which has the right type.  Except it only
 dumps the template, with $prefix and all.

 Hoogle doesn't seem to know about any of the Cabal stuff, Hayoo has a *very*
 annoying behavior where it cleans out everything you did if you use the
 back button, and the source links it advertises seem to point into
 the wide blue 404.  But using the latter, I managed to find a link to
 'substPathTemplate', worked out that the PackageIdentifier it needs is a
 member of PackageDescription, and tried to use that.  Except it gives
 the same result, and doesn't appear to substitute anything.  I guess the
 fact that it is undocumented is a hint that it's the wrong thing to use.

 Reading some more, maybe 'absoluteInstallDirs' is what I'm looking for?
 In addition to the usual heap of huge config structs, it needs a
 CopyDest, though.  Since I have no idea what to use, I just put
 NoCopyDest there.  Does that make sense?  Okay, it works now, in the
 sense that I ran it once on my laptop, and it copied the file to
 ~/.cabal/bin.  Here is the code, comments welcome:

  #!/usr/bin/env runhaskell

  import Distribution.Simple (defaultMainWithHooks, 
 simpleUserHooks,UserHooks(..))
  import Distribution.Simple.Setup (InstallFlags,CopyDest(..))
  import Distribution.Simple.Utils (rawSystemExit)
  import Distribution.PackageDescription (PackageDescription())
  import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..), 
 InstallDirs(..), absoluteInstallDirs)
  import Distribution.Verbosity (normal)

  main :: IO ()
  main = defaultMainWithHooks simpleUserHooks
      { instHook = \pd lbi uh ifs - myinst pd lbi uh ifs  instHook 
 simpleUserHooks pd lbi uh ifs }

  myinst :: PackageDescription - LocalBuildInfo - UserHooks - InstallFlags 
 - IO ()
  myinst pd lbi _uh _fs = do
      let bin = bindir $ absoluteInstallDirs pd lbi NoCopyDest
      

Re: [Haskell-cafe] Install a script with Cabal?

2012-03-21 Thread Rogan Creswick
On Tue, Mar 20, 2012 at 1:45 AM, Ketil Malde ke...@malde.org wrote:

 I have a small project that installs a couple of Haskell tools and a
 script that uses these.  Cabal will of course build and install the
 Haskell programs, but how can I get Cabal to install the script as
 well?  There's a host of UserHooks available¹, but it'd probably be
 better to have an example than to try to experiment with the right
 configuration.

I don't have an example handy, but I think you'll want preInts,
instHook, or postInst.  I'd probably go with postInst unless you need
data provided by instHook's type that isn't passed to preInst or
postInst.

LocalBuildInfo /probably/ has the details you need (eg: installDirTemplates).

Don't forget to invoke the default hook as part of your
re-implementation -- if you override instHook, for example, you need
to invoke the instHook that *would have* happened, or no installation
will take place.

--Rogan


 -k

 ¹ 
 http://www.haskell.org/cabal/release/cabal-latest/doc/API/Cabal/Distribution-Simple.html#t%3AUserHooks
 --
 If I haven't seen further, it is by standing in the footprints of giants

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Install a script with Cabal?

2012-03-20 Thread Ketil Malde

Hi,

I have a small project that installs a couple of Haskell tools and a
script that uses these.  Cabal will of course build and install the
Haskell programs, but how can I get Cabal to install the script as
well?  There's a host of UserHooks available¹, but it'd probably be
better to have an example than to try to experiment with the right
configuration.

-k

¹ 
http://www.haskell.org/cabal/release/cabal-latest/doc/API/Cabal/Distribution-Simple.html#t%3AUserHooks
-- 
If I haven't seen further, it is by standing in the footprints of giants

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe