{-# LANGUAGE DeriveGeneric #-} module Puppet.Language.NativeTypes.Package ( nativePackage ) where import qualified Data.HashMap.Strict as HM import qualified Data.HashSet as Set import Puppet.Language.NativeTypes.Helpers nativePackage :: (NativeTypeName, NativeTypeMethods) nativePackage = ("package", nativetypemethods parameterfunctions (getFeature >=> checkFeatures)) -- Features are abilities that some providers may not support. data PackagingFeatures = Holdable | InstallOptions | Installable | Purgeable | UninstallOptions | Uninstallable | Upgradeable | Versionable deriving (Show, Eq, Generic) instance Pretty PackagingFeatures where pretty = ppline . show instance Hashable PackagingFeatures isFeatureSupported :: HashMap Text (HashSet PackagingFeatures) isFeatureSupported = HM.fromList [ ("aix", Set.fromList [Installable, Uninstallable, Upgradeable, Versionable]) , ("appdmg", Set.fromList [Installable]) , ("apple", Set.fromList [Installable]) , ("apt", Set.fromList [Holdable, InstallOptions, Installable, Purgeable, Uninstallable, Upgradeable, Versionable]) , ("aptitude", Set.fromList [Holdable, Installable, Purgeable, Uninstallable, Upgradeable, Versionable]) , ("aptrpm", Set.fromList [Installable, Purgeable, Uninstallable, Upgradeable, Versionable]) , ("blastwave", Set.fromList [Installable, Uninstallable, Upgradeable]) , ("dpkg", Set.fromList [Holdable, Installable, Purgeable, Uninstallable, Upgradeable]) , ("fink", Set.fromList [Holdable, Installable, Purgeable, Uninstallable, Upgradeable, Versionable]) , ("freebsd", Set.fromList [Installable, Uninstallable]) , ("gem", Set.fromList [Installable, Uninstallable, Upgradeable, Versionable]) , ("hpux", Set.fromList [Installable, Uninstallable]) , ("macports", Set.fromList [Installable, Uninstallable, Upgradeable, Versionable]) , ("msi", Set.fromList [InstallOptions, Installable, UninstallOptions, Uninstallable]) , ("nim", Set.fromList [Installable, Uninstallable, Upgradeable, Versionable]) , ("openbsd", Set.fromList [Installable, Uninstallable, Versionable]) , ("pacman", Set.fromList [Installable, Uninstallable, Upgradeable]) , ("pip", Set.fromList [Installable, Uninstallable, Upgradeable, Versionable]) , ("pkg", Set.fromList [Holdable, Installable, Uninstallable, Upgradeable, Versionable]) , ("pkgdmg", Set.fromList [Installable]) , ("pkgin", Set.fromList [Installable, Uninstallable]) , ("pkgutil", Set.fromList [Installable, Uninstallable, Upgradeable]) , ("portage", Set.fromList [Installable, Uninstallable, Upgradeable, Versionable]) , ("ports", Set.fromList [Installable, Uninstallable, Upgradeable]) , ("portupgrade", Set.fromList [Installable, Uninstallable, Upgradeable]) , ("rpm", Set.fromList [Installable, Uninstallable, Upgradeable, Versionable]) , ("rug", Set.fromList [Installable, Uninstallable, Upgradeable, Versionable]) , ("sun", Set.fromList [InstallOptions, Installable, Uninstallable, Upgradeable]) , ("sunfreeware", Set.fromList [Installable, Uninstallable, Upgradeable]) , ("up2date", Set.fromList [Installable, Uninstallable, Upgradeable]) , ("urpmi", Set.fromList [Installable, Uninstallable, Upgradeable, Versionable]) , ("windows", Set.fromList [InstallOptions, Installable, UninstallOptions, Uninstallable]) , ("yum", Set.fromList [Installable, Purgeable, Uninstallable, Upgradeable, Versionable]) , ("zypper", Set.fromList [Installable, Uninstallable, Upgradeable, Versionable]) ] parameterfunctions :: [(Text, [Text -> NativeTypeValidate])] parameterfunctions = [("adminfile" , [string, fullyQualified]) ,("allowcdrom" , [string, values ["true","false"]]) ,("configfiles" , [string, values ["keep","replace"]]) --,("ensure" , [defaultvalue "present", string, values ["present","absent","latest","held","purged","installed"]]) ,("ensure" , [defaultvalue "present", string]) ,("flavor" , []) ,("install_options" , [rarray]) ,("name" , [nameval]) ,("provider" , [defaultvalue "apt", string]) ,("responsefile" , [string, fullyQualified]) ,("source" , [string]) ,("uninstall_options", [rarray]) ] getFeature :: Resource -> Either PrettyError (HashSet PackagingFeatures, Resource) getFeature res = case res ^. rattributes . at "provider" of Just (PString x) -> case HM.lookup x isFeatureSupported of Just s -> Right (s, res) Nothing -> Left $ PrettyError ("Do not know provider" <+> ppline x) _ -> Left "Can't happen at Puppet.NativeTypes.Package" checkFeatures :: (HashSet PackagingFeatures, Resource) -> Either PrettyError Resource checkFeatures = checkAdminFile >=> checkEnsure >=> checkParam "install_options" InstallOptions >=> checkParam "uninstall_options" UninstallOptions >=> decap where checkFeature :: HashSet PackagingFeatures -> Resource -> PackagingFeatures -> Either PrettyError (HashSet PackagingFeatures, Resource) checkFeature s r f = if Set.member f s then Right (s, r) else Left $ PrettyError ("Feature" <+> pretty f <+> "is required for the current configuration") checkParam :: Text -> PackagingFeatures -> (HashSet PackagingFeatures, Resource) -> Either PrettyError (HashSet PackagingFeatures, Resource) checkParam pn f (s,r) = if has (ix pn) (r ^. rattributes) then checkFeature s r f else Right (s,r) checkAdminFile :: (HashSet PackagingFeatures, Resource) -> Either PrettyError (HashSet PackagingFeatures, Resource) checkAdminFile = Right -- TODO, check that it only works for aix checkEnsure :: (HashSet PackagingFeatures, Resource) -> Either PrettyError (HashSet PackagingFeatures, Resource) checkEnsure (s, res) = case res ^. rattributes . at "ensure" of Just (PString "latest") -> checkFeature s res Installable Just (PString "purged") -> checkFeature s res Purgeable Just (PString "absent") -> checkFeature s res Uninstallable Just (PString "installed") -> checkFeature s res Installable Just (PString "present") -> checkFeature s res Installable Just (PString "held") -> checkFeature s res Installable >> checkFeature s res Holdable _ -> checkFeature s res Versionable decap :: (HashSet PackagingFeatures, Resource) -> Either PrettyError Resource decap = Right . snd