packages feed

bamse-0.9.4: Bamse/Package.hs

--------------------------------------------------------------------
-- |
-- Module      : Bamse.Package
-- Description : Description of an MSI package/product.
-- Copyright   : (c) Sigbjorn Finne, 2004-2009
-- License     : BSD3
--
-- Maintainer  : Sigbjorn Finne <sof@forkIO.com>
-- Stability   : provisional
-- Portability : portable
--
-- Meta information describing an MSI package/product.
-- Whatever the front-end, this is what a package spec
-- boils down to.
-- 
--------------------------------------------------------------------
module Bamse.Package
	( module Bamse.Package
	, module Bamse.GhcPackage
	, module Bamse.Dialog
	, module Bamse.Util.Dir
	) where

import Bamse.Util.Dir
import Bamse.Dialog
import Bamse.GhcPackage

-- 
-- | The functions provided by a template are parameterised over
-- the context the installer eventually runs in. Apart from 
-- having access to the toplevel directory of the distribution/install
-- tree, these functions also have access to the directory of
-- the installer tool itself (useful for getting at standard files
-- like icons etc.) plus a install-specific outside of the distribution
-- tree which may contain useful installer specific files/data.
-- 
data InstallEnv
 = InstallEnv 
 	   { toolDir  :: FilePath -- where installer tool lives 
	   , srcDir   :: FilePath -- path to toplevel directory of files to be distributed.
	   , distDir  :: FilePath -- user-supplied path to directory containing installer
	   	 		 -- template specific files.
	   , outFile  :: FilePath -- file to output installer as.
	   , userOpts :: [(String,String)] -- invocation-time (name,value) pairs
	   }
   deriving Show

data Package
 = Package { name           :: String
 	   , title          :: String
	      -- productVersion format:
	      --   major.minor.build[.whatever]
	      -- 
	   , productVersion :: String
 	   , author         :: String
	   , comment        :: String
	   }

type FeatureName = String

type Feature = ( FeatureName -- feature id/name
	       , String      -- feature descriptive name
	       )

data PackageData
 = PackageData { p_files   	        :: DirTree
 	       , p_fileMap              :: InstallEnv -> IO DirTree
	       , p_distFileMap          :: Maybe (FilePath -> Maybe FilePath)
	       , p_defOutFile           :: FilePath
 	       , p_pkgInfo     	        :: Package
	       , p_webSite 	        :: String
	       , p_bannerBitmap	        :: InstallEnv -> Maybe FilePath
	       , p_bgroundBitmap        :: InstallEnv -> Maybe FilePath
	       , p_registry	        :: [RegEntry]
	       , p_baseFeature          :: Feature
	       , p_features	        :: [Tree Feature]
	       , p_featureMap           :: Maybe (FilePath -> FeatureName)
	       , p_startMenu	        :: InstallEnv -> (String, [Shortcut])
	       , p_desktopShortcuts     :: InstallEnv -> [Shortcut]
	       , p_extensions	        :: InstallEnv -> [Extension]
	       , p_verbs		:: [Verb]
	       , p_license	        :: InstallEnv -> Maybe FilePath
	       , p_userRegistration     :: Bool
	       , p_defaultInstallFolder :: Maybe String
	       , p_userInstall          :: Bool
	       , p_dialogs		:: [Dialog]
	       , p_finalMessage         :: Maybe String
	       , p_notForAll            :: Bool
	       , p_services             :: [Service]
	       , p_productGUID          :: String -- expected form: "{...}"
	       , p_revisionGUID         :: String -- ditto
	       , p_nestedInstalls       :: [(FilePath, Maybe String)]
--	       , p_ghcPackage           :: Maybe GhcPackage
	       , p_cabalPackage         :: Maybe CabalPackage
	       , p_assemblies           :: [Assembly]
	       , p_ienv                 :: InstallEnv
	       , p_verbose              :: Bool
	       }

defPackageData :: PackageData
defPackageData 
  = PackageData { p_files                = fieldError "files"
  	        , p_fileMap              = fieldError "fileMap"
		, p_distFileMap          = fieldError "distFileMap"
		, p_defOutFile           = fieldError "defOutFile"
		, p_pkgInfo              = fieldError "pkgInfo"
		, p_webSite              = fieldError "webSite"
		, p_bannerBitmap         = fieldError "bannerBitmap"
		, p_bgroundBitmap        = fieldError "bgroundBitmap"
		, p_registry             = fieldError "registry"
		, p_baseFeature          = fieldError "baseFeature"
		, p_features             = fieldError "features"
		, p_featureMap           = fieldError "featureMap"
		, p_startMenu            = fieldError "startMenu"
		, p_desktopShortcuts     = fieldError "desktopShortcuts"
		, p_extensions           = fieldError "extensions"
		, p_verbs                = fieldError "verbs"
		, p_license              = fieldError "license"
		, p_userRegistration     = fieldError "userRegistration"
		, p_defaultInstallFolder = fieldError "defaultInstallFolder"
		, p_userInstall          = fieldError "userInstall"
		, p_dialogs              = fieldError "dialogs"
		, p_finalMessage         = fieldError "finalMessage"
		, p_notForAll            = fieldError "notForAll"
		, p_services             = fieldError "services"
		, p_productGUID          = fieldError "productGUID"
		, p_revisionGUID         = fieldError "revisionGUID"
--		, p_ghcPackage           = fieldError "ghcPackage"
		, p_cabalPackage         = fieldError "cabalPackage"
		, p_assemblies           = []
		, p_nestedInstalls       = fieldError "nestedInstalls"
		, p_ienv                 = fieldError "ienv"
		, p_verbose              = fieldError "verbose"
		}
 where
  fieldError f = error ("defPackageData.p_" ++ f ++ ": not filled in")

minimalPackageData :: PackageData
minimalPackageData = pkg
 where
  pkg =
    PackageData { p_files                = fieldError "files"
  	        , p_fileMap              = fieldError "fileMap"
		, p_distFileMap          = Nothing
		, p_defOutFile           = fieldError "defOutFile"
		, p_pkgInfo              = fieldError "pkgInfo"
		, p_webSite              = ""
		, p_bannerBitmap         = \ _ienv -> Nothing
		, p_bgroundBitmap        = \ _ienv -> Nothing
		, p_registry             = []
		, p_baseFeature          = fieldError "baseFeature"
		, p_features             = []
		, p_featureMap           = Nothing
		, p_startMenu            = \ _ienv -> ("",[])
		, p_desktopShortcuts     = \ _ienv -> []
		, p_extensions           = \ _ienv -> []
		, p_verbs                = []
		, p_license              = \ _ienv -> Nothing
		, p_userRegistration     = False
		, p_defaultInstallFolder = Nothing
		, p_userInstall          = True
		, p_dialogs              = []
		, p_finalMessage         = Nothing
		, p_notForAll            = False
		, p_services             = []
		, p_productGUID          = fieldError "productGUID"
		, p_revisionGUID         = fieldError "revisionGUID"
		, p_cabalPackage         = fieldError "cabalPackage"
		, p_assemblies           = []
		, p_nestedInstalls       = []
		, p_ienv                 = fieldError "ienv"
		, p_verbose              = False
		}

  fieldError f = error ("minimalPackageData.p_" ++ f ++ ": not filled in")

-- various supporting types that don't quite belong here..
data Shortcut
 = Shortcut
      { scut_name   :: String   -- name
      , scut_target :: String   -- target app
      , scut_args   :: String   -- arguments
      , scut_desc   :: String   -- description
      , scut_icon   :: Maybe FilePath -- icon file
      , scut_istate :: Int      -- initial state
      , scut_wdir   :: String   -- working dir.
      }

type Extension
  = ( String		-- progID,       "HaskellFile"
    , String		-- application,  "hugs.exe"
    , String		-- icon,         "icon.exe"
    , String		-- the extension "lhs"
    )

type Verb
  = ( String		-- file extension it applies to
    , String		-- name of shell extension
    , String		-- label to use in context menus
    , String		-- arguments
    )

--
-- Type: RegEntry
--
-- Purpose: describe a Registry entry to be installed and, quite
--          possibly, removed during uninstallation.
-- 
data RegEntry
 = RegEntry String 	   -- hive name		 "HKLM" => HKEY_LOCAL_MACHINE etc.
 	    String 	   -- key within hive    "Software\\Haskell\\Hugs"
	    KeyAction

data KeyAction
 = CreateKey  Bool  			-- True => delete on uninstall.
 | CreateName (Maybe String) String 	-- Nothing => default (unnamed) name/entry for key.
 | DeleteKey  Bool			-- True  => delete key on _install_
                                        -- False => delete key on _uninstall_
 | DeleteName Bool String               -- True  => delete name on _install_
                                        -- False => delete name on _uninstall_
 

--
-- Type: Service
-- 
-- Purpose: User-level type that describes how an NT Service
--          is to be installed.
--
data Service
 = Service { serv_name     :: String
 	   , serv_dispName :: String
	   	-- ToDo: add custom/ad-hoc data types for the next three?
	   , serv_type     :: Int
	   , serv_start    :: Int
	   , serv_error    :: Int
	   , serv_user_pwd :: Maybe (String,String)
	   , serv_args     :: [String]
	   , serv_binary   :: FilePath
	   , serv_descr    :: String
	   }

-- for use with feature trees.
data Tree a
 = Leaf a
 | Node a [Tree a]


-- | @Assembly@ defines a reference to a local DLL that you
-- want to be treated as an assembly (and installed/registered as such.)
data Assembly
 = Assembly
      { assem_dll       :: FilePath
      , assem_manifest  :: Maybe FilePath -- optional; preferably embedded in the assembly DLL as resource..
      , assem_privatePath :: Maybe FilePath -- if you don't want to install into GAC; untested..
      , assem_name      :: String
      , assem_version   :: String
      , assem_culture   :: String
      , assem_publicKey :: String
      , assem_win32     :: Bool
      }

emptyAssembly :: Assembly
emptyAssembly = Assembly
      { assem_dll         = ""
      , assem_manifest    = Nothing
      , assem_privatePath = Nothing
      , assem_name        = ""
      , assem_version     = "0.0.0.0"
      , assem_culture     = "" -- neutral
      , assem_publicKey   = ""
      , assem_win32       = False -- MSIL in other words.
      }