packages feed

bamse-0.9.4: examples/Cabal.hs

{- |
 Module      : Cabal
 Description : Building an installer from your Cabal project.
 Copyright   : (c) Sigbjorn Finne, 2009
 License     : BSD3

  Generating an MSI installer from your Cabal-built Haskell library or 
  application.
  
  This is an example of how to take the contents of your Cabal
  <http://haskell.org/Cabal/> project and box it up in Windows
  Installer form. Along with details specifying the properties
  of your package (name, author, project web site etc.) you also
  list the files you want to include. Given those two pieces, the
  Bamse builder goes to work, outputting in the end a working MSI
  that's ready for distribution.
-}
module Main where

import Bamse.Package
import Bamse.PackageUtils ( dropDirPrefix )
import Bamse.Builder
import Data.List ( isPrefixOf )
import System.FilePath

--import Debug.Trace

-- | @main@ kicks off the party. To see what command-line options
-- it supports, invoke it with @--help@.
--
-- Typical invocation:
--
-- >  foo$ genCabal --generate-guids -o myInstaller.msi c:/path/to/the/top/of/my/cabal/pkg
-- >  # if you want to re-generate the MSI (but not update its product etc. GUIDs.)
-- >  foo$ genCabal -u -o myInstaller.msi c:/path/to/the/top/of/my/cabal/pkg
main :: IO ()
main = do
  genBuilder pkgCabal
  -- alternatively, supply the command-line arguments directly:
  -- (this is something you want to do when integrating the Bamse library
  -- into your application directly.)
  -- genBuilderArgs pkgCabal ["--generate-guids", "-o", "c:/public/deploy/myInst.msi"]

-- | @pkgCabal@ is the toplevel 'Bamse.Package.PackageData' value, containing
-- all the interesting bits of info that make up an MSI (as seen/supported by Bamse..)
-- We /derive/ it from 'Bamse.Package.minimalPackageData', which supplies default
-- values for most MSI package properties. Here we simply override with the portions
-- relevant to our Cabal example. For more comprehensive and demanding installers,
-- please consult 'Bamse.Package.PackageData' or see the @templates/@ directory for
-- live examples of other installer specifications.
pkgCabal :: PackageData
pkgCabal = minimalPackageData
   { p_fileMap          = dirTree
   , p_defOutFile       = defaultOutputFile
   , p_pkgInfo          = cabalPkgInfo
   , p_webSite          = webSite
   , p_baseFeature      = baseFeature
   , p_desktopShortcuts = \ _ienv -> []
       -- Note: this needs to be a .rtf file holding your license. If you
       -- supply one (after having generated the RTF via wordpad or some such..),
       -- the installer will include in its UI a user-agreement form displaying
       -- the license text.
   , p_license          = \ _ -> Nothing 
       -- Somewhat confusing perhaps, but this field is used to control the
       -- on-install running of Cabal itself, letting you automatically install
       -- (and possibly) the Cabal package at install-time. (The user is given
       -- a choice whether or not to do this in the UI.) We want to do this,
       -- but only allow the @install@ step; no support for building from source.
   , p_cabalPackage     = Just cabalPackage
   }

--
-- The rest of this module supplies the definitions of the fields that we
-- filled in for @pkgCabal'

-- 
-- First, some overall package information:
--
pkgName :: String
pkgName = "MyPackage"

pkgVersion :: String
pkgVersion = "1.2.0" --   major.minor.build[.whatever]

pkgAuthor :: String
pkgAuthor = "Kap. Abel"

cabalPkgInfo :: Package
cabalPkgInfo = 
  Package { name    = pkgName
          , title   = pkgName  -- will show up in UI.
	  , productVersion = pkgVersion
	  , author  = pkgAuthor
	  , comment = "This is an example package"
	  }

-- | @dirTree@ is the function that walks over the directory
-- you point the MSI generator at when running, returning the
-- files and directories to include in the generated MSI.
-- 
-- This particular one will include anything inside the build @dist/@
-- directory + the .cabal, LICENSE and Setup.hs files. We
-- don't consider including the sources here, but doing so
-- is an easy extension (see @templates/@ for examples of this.)
-- 
dirTree :: InstallEnv -> IO DirTree
dirTree ienv = findFiles ofInterest topDir
 where
  topDir = srcDir ienv
  ofInterest f = {-trace (show (f_local,res)) -}res
    
   where
    f_local = dropDirPrefix topDir f
    res = 
       null f_local || 
       "dist"  `isPrefixOf` f_local || 
       takeExtension f_local == ".cabal" || 
       f_local `elem` package_files

    package_files = ["Setup.hs", "LICENSE", "README", "custWrap.exe"]

-- | Extra Cabal specific information used to direct installation
-- of the package on the user's machine.
cabalPackage :: CabalPackage
cabalPackage = CabalPackage
  { cabal_packageName   = name cabalPkgInfo
  , cabal_forGhcVersion = "6.10.1"
  , cabal_packageFile   = Just (name cabalPkgInfo ++ ".cabal")
  , cabal_pkgCmdLine    = Nothing
  , cabal_fromSource    = False -- don't support from source building via the MSI.
  }

-- | When invoked the MSI generator can emit the MSI into a default output file.
-- (the @-o@ option is what you would normally use to override this.)
defaultOutputFile :: FilePath
defaultOutputFile = name cabalPkgInfo ++ '-':map subst (productVersion cabalPkgInfo) ++ ".msi"
 where
  subst '.' = '-'
  subst ch  = ch

-- | @webSite@ contains the URL for the package itself.
-- If that doesn't apply to you, its Hackage URL would be good.
webSite :: {-URL-}String
webSite = "http://www.haskell.org/cabal"

-- | @baseFeature@ is a mostly-internal name, but you need to supply
-- a name. Defaults to @cabalPkgInfo.name@
baseFeature :: Feature
baseFeature = (name cabalPkgInfo, name cabalPkgInfo ++ " package for GHC")