packages feed

propellor 5.3.5 → 5.3.6

raw patch · 36 files changed

+339/−133 lines, 36 filesdep ~basePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: base

API changes (from Hackage documentation)

- Propellor.Property.SiteSpecific.JoeySites: homePowerMonitor :: IsContext c => User -> [Host] -> c -> (SshKeyType, PubKeyText) -> Property (HasInfo + DebianLike)
- Propellor.Types: instance (GHC.Base.Monoid (Propellor.Types.Property setupmetatypes), GHC.Base.Monoid (Propellor.Types.Property undometatypes)) => GHC.Base.Monoid (Propellor.Types.RevertableProperty setupmetatypes undometatypes)
+ Propellor.PrivData: instance Data.Semigroup.Semigroup Propellor.PrivData.PrivInfo
+ Propellor.Property.Ccache: instance Data.Semigroup.Semigroup Propellor.Property.Ccache.Limit
+ Propellor.Property.Conductor: instance Data.Semigroup.Semigroup Propellor.Property.Conductor.ConductorFor
+ Propellor.Property.Conductor: instance Data.Semigroup.Semigroup Propellor.Property.Conductor.NotConductorFor
+ Propellor.Property.Conductor: instance Data.Semigroup.Semigroup Propellor.Property.Conductor.Orchestrated
+ Propellor.Property.Debootstrap: instance Data.Semigroup.Semigroup Propellor.Property.Debootstrap.DebootstrapConfig
+ Propellor.Property.DiskImage.PartSpec: instance Data.Semigroup.Semigroup Propellor.Property.DiskImage.PartSpec.PartInfo
+ Propellor.Property.DiskImage.PartSpec: instance Data.Semigroup.Semigroup Propellor.Property.DiskImage.PartSpec.PartLocation
+ Propellor.Property.Firewall: instance Data.Semigroup.Semigroup Propellor.Property.Firewall.Rules
+ Propellor.Property.FreeBSD.Pkg: instance Data.Semigroup.Semigroup Propellor.Property.FreeBSD.Pkg.PkgUpdate
+ Propellor.Property.FreeBSD.Pkg: instance Data.Semigroup.Semigroup Propellor.Property.FreeBSD.Pkg.PkgUpgrade
+ Propellor.Property.FreeBSD.Poudriere: instance Data.Semigroup.Semigroup Propellor.Property.FreeBSD.Poudriere.PoudriereConfigured
+ Propellor.Property.Installer.Target: instance Data.Semigroup.Semigroup Propellor.Property.Installer.Target.TargetFilled
+ Propellor.Property.Mount: instance Data.Semigroup.Semigroup Propellor.Property.Mount.MountOpts
+ Propellor.Property.Parted: instance Data.Semigroup.Semigroup Propellor.Property.Parted.DiskPart
+ Propellor.Property.Parted.Types: instance Data.Semigroup.Semigroup Propellor.Property.Parted.Types.PartSize
+ Propellor.Property.Parted.Types: instance Data.Semigroup.Semigroup Propellor.Property.Parted.Types.PartTable
+ Propellor.Property.SiteSpecific.JoeySites: homePower :: IsContext c => User -> [Host] -> c -> (SshKeyType, PubKeyText) -> Property (HasInfo + DebianLike)
+ Propellor.Property.Ssh: instance Data.Semigroup.Semigroup Propellor.Property.Ssh.HostKeyInfo
+ Propellor.Property.Ssh: instance Data.Semigroup.Semigroup Propellor.Property.Ssh.UserKeyInfo
+ Propellor.Types: instance forall k (metatypes :: k). Propellor.Types.Singletons.SingI metatypes => Data.Semigroup.Semigroup (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes metatypes))
+ Propellor.Types: instance forall k1 k2 (setupmetatypes :: k2) (undometatypes :: k1). (Data.Semigroup.Semigroup (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes setupmetatypes)), Data.Semigroup.Semigroup (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes undometatypes)), Propellor.Types.Singletons.SingI setupmetatypes, Propellor.Types.Singletons.SingI undometatypes) => Data.Semigroup.Semigroup (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes setupmetatypes) (Propellor.Types.MetaTypes.MetaTypes undometatypes))
+ Propellor.Types: instance forall k1 k2 (setupmetatypes :: k2) (undometatypes :: k1). (GHC.Base.Monoid (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes setupmetatypes)), GHC.Base.Monoid (Propellor.Types.Property (Propellor.Types.MetaTypes.MetaTypes undometatypes)), Propellor.Types.Singletons.SingI setupmetatypes, Propellor.Types.Singletons.SingI undometatypes) => GHC.Base.Monoid (Propellor.Types.RevertableProperty (Propellor.Types.MetaTypes.MetaTypes setupmetatypes) (Propellor.Types.MetaTypes.MetaTypes undometatypes))
+ Propellor.Types.Chroot: instance Data.Semigroup.Semigroup Propellor.Types.Chroot.ChrootCfg
+ Propellor.Types.Chroot: instance Data.Semigroup.Semigroup Propellor.Types.Chroot.ChrootInfo
+ Propellor.Types.Core: instance Data.Semigroup.Semigroup (Propellor.Types.Core.Propellor Propellor.Types.Result.Result)
+ Propellor.Types.Dns: instance Data.Semigroup.Semigroup Propellor.Types.Dns.AliasesInfo
+ Propellor.Types.Dns: instance Data.Semigroup.Semigroup Propellor.Types.Dns.DnsInfoPropagated
+ Propellor.Types.Dns: instance Data.Semigroup.Semigroup Propellor.Types.Dns.DnsInfoUnpropagated
+ Propellor.Types.Dns: instance Data.Semigroup.Semigroup Propellor.Types.Dns.NamedConfMap
+ Propellor.Types.Docker: instance Data.Semigroup.Semigroup Propellor.Types.Docker.DockerInfo
+ Propellor.Types.Info: instance Data.Semigroup.Semigroup (Propellor.Types.Info.InfoVal v)
+ Propellor.Types.Info: instance Data.Semigroup.Semigroup Propellor.Types.Info.Info
+ Propellor.Types.Result: instance Data.Semigroup.Semigroup Propellor.Types.Result.Result
- Propellor.Property.Schroot: overlaysInTmpfs :: Property (HasInfo + DebianLike)
+ Propellor.Property.Schroot: overlaysInTmpfs :: RevertableProperty (HasInfo + DebianLike) UnixLike

Files

CHANGELOG view
@@ -1,3 +1,19 @@+propellor (5.3.6) unstable; urgency=medium++  * Fix build with ghc 8.4, which broke due to the Semigroup Monoid change.+  * Dropped support for building propellor with ghc 7 (as in debian+    oldstable), to avoid needing to depend on the semigroups transitional+    package, but also because it's just too old to be worth supporting.+  * stack.yaml: Updated to lts-9.21.+  * Make Schroot.overlaysInTmpfs revertable+    Thanks, Sean Whitton+  * Update shim each time propellor is run in a container, to deal with+    library version changes.+  * Unbound: Added support for various DNS record types.+    Thanks, Félix Sipma.++ -- Joey Hess <id@joeyh.name>  Wed, 09 May 2018 16:24:37 -0400+ propellor (5.3.5) unstable; urgency=medium    * Apt.stdSourcesList now adds stable-updates suite
README.md view
@@ -56,4 +56,4 @@ 7. Write some neat new properties and send patches!  (Want to get your feet wet with propellor before plunging in?-[try this|http://propellor.branchable.com/forum/Simple_quickstart_without_git__44___SSH__44___GPG])+[try this](http://propellor.branchable.com/forum/Simple_quickstart_without_git__44___SSH__44___GPG])
debian/changelog view
@@ -1,3 +1,19 @@+propellor (5.3.6) unstable; urgency=medium++  * Fix build with ghc 8.4, which broke due to the Semigroup Monoid change.+  * Dropped support for building propellor with ghc 7 (as in debian+    oldstable), to avoid needing to depend on the semigroups transitional+    package, but also because it's just too old to be worth supporting.+  * stack.yaml: Updated to lts-9.21.+  * Make Schroot.overlaysInTmpfs revertable+    Thanks, Sean Whitton+  * Update shim each time propellor is run in a container, to deal with+    library version changes.+  * Unbound: Added support for various DNS record types.+    Thanks, Félix Sipma.++ -- Joey Hess <id@joeyh.name>  Wed, 09 May 2018 16:24:37 -0400+ propellor (5.3.5) unstable; urgency=medium    * Apt.stdSourcesList now adds stable-updates suite
doc/README.mdwn view
@@ -56,4 +56,4 @@ 7. Write some neat new properties and send patches!  (Want to get your feet wet with propellor before plunging in?-[try this|http://propellor.branchable.com/forum/Simple_quickstart_without_git__44___SSH__44___GPG])+[try this](http://propellor.branchable.com/forum/Simple_quickstart_without_git__44___SSH__44___GPG])
joeyconfig.hs view
@@ -99,9 +99,10 @@ clam = host "clam.kitenet.net" $ props 	& standardSystem Unstable X86_64 		["Unreliable server. Anything here may be lost at any time!" ]-	& ipv4 "45.62.211.94"+	& ipv4 "64.137.164.186"  	& CloudAtCost.decruft+	& User.hasPassword (User "root") 	& Ssh.hostKeys hostContext 		[ (SshDsa, "ssh-dss AAAAB3NzaC1kc3MAAACBAI3WUq0RaigLlcUivgNG4sXpso2ORZkMvfqKz6zkc60L6dpxvWDNmZVEH8hEjxRSYG07NehcuOgQqeyFnS++xw1hdeGjf37JqCUH49i02lra3Zxv8oPpRxyeqe5MmuzUJhlWvBdlc3O/nqZ4bTUfnxMzSYWyy6++s/BpSHttZplNAAAAFQC1DE0vzgVeNAv9smHLObQWZFe2VQAAAIBECtpJry3GC8NVTFsTHDGWksluoFPIbKiZUFFztZGdM0AO2VwAbiJ6Au6M3VddGFANgTlni6d2/9yS919zO90TaFoIjywZeXhxE2CSuRfU7sx2hqDBk73jlycem/ER0sanFhzpHVpwmLfWneTXImWyq37vhAxatJANOtbj81vQ3AAAAIBV3lcyTT9xWg1Q4vERJbvyF8mCliwZmnIPa7ohveKkxlcgUk5d6dnaqFfjVaiXBPN3Qd08WXoQ/a9k3chBPT9nW2vWgzzM8l36j2MbHLmaxGwevAc9+vx4MXqvnGHzd2ex950mC33ct3j0fzMZlO6vqEsgD4CYmiASxhfefj+JCQ==") 		, (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJybAjUPUWIhvVMmer8K5ZgdfI54DM6vc8Mzw+5KmVKL0TwkvzbR1HAB4heyMGtN1F8YzkWhsI3/Txh+MQUJ+i4u8SvSYc6D1q3j3ZyCi06wZ3DJS25tZrOM/thOOA1DFA4Hhb0uI/1Kg8PguNNNSMXn8F7q3F6cFQizYgszs6z6ktiST/BTC+IXWovhcnn2vQXXU8FTcTsqBFqA5dEjZbp1WDzqp3km84ZyXGmoVlpqzXeMvlkWTIshYiQjXIwPOkALzlGYjp1lw1OaxPVI1IGFcgCbIWQQWoCReb+genX2VaR+odAYXjaOdRx0lQj7UCPTBCpqMyzBMLtT5Yiaqh")@@ -175,6 +176,7 @@ honeybee = host "honeybee.kitenet.net" $ props 	& standardSystem Testing ARMHF 		[ "Home router and arm git-annex build box." ]+	& Apt.removed ["rsyslog"] 	 	& cubietech_Cubietruck 	& hasPartition@@ -195,7 +197,7 @@ 		[ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIS/hDYq1MAxfOBf49htym3BOYlx4Gk9SDpiHjv7u6IC") 		] -	& JoeySites.homePowerMonitor+	& JoeySites.homePower 		(User "joey") 		hosts 		(Context "homepower.joeyh.name")
propellor.cabal view
@@ -1,6 +1,6 @@ Name: propellor-Version: 5.3.5-Cabal-Version: >= 1.20+Version: 5.3.6+Cabal-Version: 1.20 License: BSD2 Maintainer: Joey Hess <id@joeyh.name> Author: Joey Hess@@ -45,7 +45,7 @@   Build-Depends:     -- propellor needs to support the ghc shipped in Debian stable,     -- and also only depends on packages in Debian stable.-    base >= 4.5, base < 5,+    base >= 4.9, base < 5,     directory, filepath, IfElse, process, bytestring, hslogger, split,     unix, unix-compat, ansi-terminal, containers (>= 0.5), network, async,     time, mtl, transformers, exceptions (>= 0.6), stm, text, hashable@@ -232,9 +232,7 @@   Default-Language: Haskell98   Hs-Source-Dirs: executables   Main-Is: propellor-config.hs-  GHC-Options: -threaded -Wall -fno-warn-tabs -O0-  if impl(ghc >= 8.0)-    GHC-Options: -fno-warn-redundant-constraints+  GHC-Options: -threaded -Wall -fno-warn-tabs   Default-Extensions: TypeOperators   Build-Depends: propellor, base @@ -242,6 +240,7 @@   Default-Language: Haskell98   Hs-Source-Dirs: executables   Main-Is: wrapper.hs+  GHC-Options: -threaded -Wall -fno-warn-tabs   Build-Depends: propellor, base  source-repository head
src/Propellor/DotDir.hs view
@@ -271,7 +271,7 @@ 		, "  Main-Is: config.hs" 		, "  GHC-Options: -threaded -Wall -fno-warn-tabs -O0" 		, "  Extensions: TypeOperators"-		, "  Build-Depends: propellor >= 3.0, base >= 3"+		, "  Build-Depends: propellor >= 3.0, base >= 4.9" 		] 	configcontent = 		[ "-- This is the main configuration file for Propellor, and is used to build"@@ -316,7 +316,7 @@ 		]  stackResolver :: String-stackResolver = "lts-8.22"+stackResolver = "lts-9.21"  fullClone :: IO Result fullClone = do@@ -446,9 +446,6 @@ 					) 			Nothing -> return mref --- And, if there's a remote named "upstream"--- that does not point at the distrepo, the user must have set that up--- and is not using the distrepo, so do nothing. warnoutofdate :: Bool -> IO () warnoutofdate havebranch = warningMessage $ unlines 	[ "** Your ~/.propellor/ is out of date.."
src/Propellor/PrivData.hs view
@@ -37,6 +37,7 @@ import qualified Data.ByteString.Lazy as L import Control.Applicative import Data.Monoid+import Data.Semigroup as Sem import Prelude  import Propellor.Types@@ -279,7 +280,7 @@  newtype PrivInfo = PrivInfo 	{ fromPrivInfo :: S.Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext) }-	deriving (Eq, Ord, Show, Typeable, Monoid)+	deriving (Eq, Ord, Show, Typeable, Sem.Semigroup, Monoid)  -- PrivInfo always propagates out of containers, so that propellor -- can see which hosts need it.
src/Propellor/Property/Ccache.hs view
@@ -14,6 +14,7 @@ import Utility.FileMode import Utility.DataUnits import System.Posix.Files+import qualified Data.Semigroup as Sem  -- | Limits on the size of a ccache data Limit@@ -25,9 +26,12 @@ 	| NoLimit 	| Limit :+ Limit +instance Sem.Semigroup Limit where+	(<>) = (:+)+ instance Monoid Limit where 	mempty  = NoLimit-	mappend = (:+)+	mappend = (Sem.<>)  -- | A string that will be parsed to get a data size. --
src/Propellor/Property/Chroot.hs view
@@ -169,10 +169,7 @@ propellChroot c@(Chroot loc _ _ _) mkproc systemdonly = property (chrootDesc c "provisioned") $ do 	let d = localdir </> shimdir c 	let me = localdir </> "propellor"-	shim <- liftIO $ ifM (doesDirectoryExist d)-		( pure (Shim.file me d)-		, Shim.setup me Nothing d-		)+	shim <- liftIO $ Shim.setup me Nothing d 	ifM (liftIO $ bindmount shim) 		( chainprovision shim 		, return FailedChange
src/Propellor/Property/Conductor.hs view
@@ -81,6 +81,7 @@ import qualified Propellor.Property.Ssh as Ssh  import qualified Data.Set as S+import qualified Data.Semigroup as Sem  -- | Class of things that can be conducted. --@@ -313,9 +314,9 @@ -- A Host's Info indicates when it's a conductor for hosts, and when it's -- stopped being a conductor. newtype ConductorFor = ConductorFor [Host]-	deriving (Typeable, Monoid)+	deriving (Typeable, Sem.Semigroup, Monoid) newtype NotConductorFor = NotConductorFor [Host]-	deriving (Typeable, Monoid)+	deriving (Typeable, Sem.Semigroup, Monoid)  instance Show ConductorFor where 	show (ConductorFor l) = "ConductorFor " ++ show (map hostName l)@@ -329,7 +330,7 @@  -- Added to Info when a host has been orchestrated. newtype Orchestrated = Orchestrated Any-	deriving (Typeable, Monoid, Show)+	deriving (Typeable, Sem.Semigroup, Monoid, Show) instance IsInfo Orchestrated where 	propagateInfo _ = PropagateInfo False 
src/Propellor/Property/Debootstrap.hs view
@@ -19,12 +19,13 @@  import Data.List import Data.Char+import qualified Data.Semigroup as Sem import System.Posix.Directory import System.Posix.Files  type Url = String --- | A monoid for debootstrap configuration.+-- | A data type for debootstrap configuration. -- mempty is a default debootstrapped system. data DebootstrapConfig 	= DefaultConfig@@ -35,9 +36,12 @@ 	| DebootstrapConfig :+ DebootstrapConfig 	deriving (Show) +instance Sem.Semigroup DebootstrapConfig where+	(<>) = (:+)+ instance Monoid DebootstrapConfig where 	mempty  = DefaultConfig-	mappend = (:+)+	mappend = (Sem.<>)  toParams :: DebootstrapConfig -> [CommandParam] toParams DefaultConfig = []
src/Propellor/Property/DiskImage/PartSpec.hs view
@@ -43,6 +43,7 @@  import Data.List (sortBy) import Data.Ord+import qualified Data.Semigroup as Sem  -- | Specifies a partition with a given filesystem. --@@ -110,7 +111,7 @@ 	| AdjustPartSpecInfo MountPoint (PartSpec PartLocation -> PartSpec PartLocation)  newtype PartInfo = PartInfo [PartInfoVal]-	deriving (Monoid, Typeable)+	deriving (Monoid, Sem.Semigroup, Typeable)  instance IsInfo PartInfo where 	propagateInfo _ = PropagateInfo False@@ -183,9 +184,12 @@ data PartLocation = Beginning | Middle | End 	deriving (Eq, Ord) +instance Sem.Semigroup PartLocation where+	_ <> b = b+ instance Monoid PartLocation where 	mempty = Middle-	mappend _ b = b+	mappend = (Sem.<>)  partLocation :: PartSpec PartLocation -> PartLocation -> PartSpec PartLocation partLocation (mp, o, p, _) l = (mp, o, p, l)
src/Propellor/Property/Firewall.hs view
@@ -18,6 +18,7 @@ ) where  import Data.Monoid+import qualified Data.Semigroup as Sem import Data.Char import Data.List @@ -199,6 +200,9 @@  infixl 0 :- +instance Sem.Semigroup Rules where+	(<>) = (:-)+ instance Monoid Rules where 	mempty  = Everything-	mappend = (:-)+	mappend = (Sem.<>)
src/Propellor/Property/FreeBSD/Pkg.hs view
@@ -9,6 +9,8 @@ import Propellor.Base import Propellor.Types.Info +import qualified Data.Semigroup as Sem+ noninteractiveEnv :: [([Char], [Char])] noninteractiveEnv = [("ASSUME_ALWAYS_YES", "yes")] @@ -37,7 +39,7 @@ 		lines <$> readProcessEnv p a (Just noninteractiveEnv)  newtype PkgUpdate = PkgUpdate String-	deriving (Typeable, Monoid, Show)+	deriving (Typeable, Sem.Semigroup, Monoid, Show) instance IsInfo PkgUpdate where 	propagateInfo _ = PropagateInfo False @@ -54,7 +56,7 @@ 			`setInfoProperty` (toInfo (PkgUpdate ""))  newtype PkgUpgrade = PkgUpgrade String-	deriving (Typeable, Monoid, Show)+	deriving (Typeable, Sem.Semigroup, Monoid, Show)  instance IsInfo PkgUpgrade where 	propagateInfo _ = PropagateInfo False
src/Propellor/Property/FreeBSD/Poudriere.hs view
@@ -8,17 +8,18 @@  import Propellor.Base import Propellor.Types.Info-import Data.List- import qualified Propellor.Property.FreeBSD.Pkg as Pkg import qualified Propellor.Property.ZFS as ZFS import qualified Propellor.Property.File as File +import Data.List+import qualified Data.Semigroup as Sem+ poudriereConfigPath :: FilePath poudriereConfigPath = "/usr/local/etc/poudriere.conf"  newtype PoudriereConfigured = PoudriereConfigured String-	deriving (Typeable, Monoid, Show)+	deriving (Typeable, Sem.Semigroup, Monoid, Show)  instance IsInfo PoudriereConfigured where 	propagateInfo _ = PropagateInfo False
src/Propellor/Property/Installer/Target.hs view
@@ -112,6 +112,7 @@ import Data.Char import Data.Ord import Data.Ratio+import qualified Data.Semigroup as Sem import System.Process (readProcess)  -- | Partition table for the target disk.@@ -438,9 +439,12 @@ data TargetFilled = TargetFilled (Ratio Integer) 	deriving (Show, Eq) +instance Sem.Semigroup TargetFilled where+	TargetFilled n <> TargetFilled m = TargetFilled (n+m) + instance Monoid TargetFilled where 	mempty = TargetFilled (0 % 1)-	mappend (TargetFilled n) (TargetFilled m) = TargetFilled (n+m)+	mappend = (Sem.<>)  newtype TargetFilledHandle = TargetFilledHandle Integer 
src/Propellor/Property/List.hs view
@@ -20,6 +20,7 @@ import Propellor.Exception  import Data.Monoid+import Prelude  toProps :: [Property (MetaTypes metatypes)] -> Props (MetaTypes metatypes) toProps ps = Props (map toChildProperty ps)
src/Propellor/Property/Mount.hs view
@@ -10,6 +10,7 @@ import Utility.Path  import Data.List+import qualified Data.Semigroup as Sem  -- | type of filesystem to mount ("auto" to autodetect) type FsType = String@@ -24,7 +25,7 @@ -- -- For default mount options, use `mempty`. newtype MountOpts = MountOpts [String]-	deriving Monoid+	deriving (Sem.Semigroup, Monoid)  class ToMountOpts a where 	toMountOpts :: a -> MountOpts
src/Propellor/Property/Parted.hs view
@@ -42,6 +42,7 @@ import Utility.DataUnits  import System.Posix.Files+import qualified Data.Semigroup as Sem import Data.List (genericLength)  data Eep = YesReallyDeleteDiskContents@@ -178,16 +179,21 @@  data DiskSpaceUse = Percent Int | RemainingSpace +instance Sem.Semigroup DiskPart where+	FixedDiskPart <> FixedDiskPart = FixedDiskPart+	DynamicDiskPart (Percent a) <> DynamicDiskPart (Percent b) =+		DynamicDiskPart (Percent (a + b))+	DynamicDiskPart RemainingSpace <> DynamicDiskPart RemainingSpace = +		DynamicDiskPart RemainingSpace+	DynamicDiskPart (Percent a) <> _ = DynamicDiskPart (Percent a)+	_ <> DynamicDiskPart (Percent b) = DynamicDiskPart (Percent b)+	DynamicDiskPart RemainingSpace <> _ = DynamicDiskPart RemainingSpace+	_ <> DynamicDiskPart RemainingSpace = DynamicDiskPart RemainingSpace+ instance Monoid DiskPart   where 	mempty = FixedDiskPart-	mappend FixedDiskPart FixedDiskPart = FixedDiskPart-	mappend (DynamicDiskPart (Percent a)) (DynamicDiskPart (Percent b)) = DynamicDiskPart (Percent (a + b))-	mappend (DynamicDiskPart RemainingSpace) (DynamicDiskPart RemainingSpace) = DynamicDiskPart RemainingSpace-	mappend (DynamicDiskPart (Percent a)) _ = DynamicDiskPart (Percent a)-	mappend _ (DynamicDiskPart (Percent b)) = DynamicDiskPart (Percent b)-	mappend (DynamicDiskPart RemainingSpace) _ = DynamicDiskPart RemainingSpace-	mappend _ (DynamicDiskPart RemainingSpace) = DynamicDiskPart RemainingSpace+	mappend = (Sem.<>)  -- | Make a partition use some percentage of the size of the disk -- (less all fixed size partitions), or the remaining space in the disk.
src/Propellor/Property/Parted/Types.hs view
@@ -4,6 +4,9 @@ import Utility.DataUnits  import Data.Char+import qualified Data.Semigroup as Sem+import Data.Monoid+import Prelude  class PartedVal a where 	pval :: a -> String@@ -19,14 +22,17 @@ data PartTable = PartTable TableType Alignment [Partition] 	deriving (Show) -instance Monoid PartTable where-	-- | default TableType is MSDOS, with a `safeAlignment`.-	mempty = PartTable MSDOS safeAlignment []+instance Sem.Semigroup PartTable where 	-- | uses the TableType of the second parameter 	-- and the larger alignment,-	mappend (PartTable _l1 a1 ps1) (PartTable l2 a2 ps2) =+	PartTable _l1 a1 ps1 <> PartTable l2 a2 ps2 = 		PartTable l2 (max a1 a2) (ps1 ++ ps2) +instance Monoid PartTable where+	-- | default TableType is MSDOS, with a `safeAlignment`.+	mempty = PartTable MSDOS safeAlignment []+	mappend = (Sem.<>)+ -- | A partition on the disk. data Partition = Partition 	{ partType :: PartType@@ -80,11 +86,14 @@ fromPartSize (MegaBytes b) = b * 1000000 fromPartSize (Bytes n) = n +instance Sem.Semigroup PartSize where+	MegaBytes a <> MegaBytes b = MegaBytes (a + b)+	Bytes a <> b = Bytes (a + fromPartSize b)+	a <> Bytes b = Bytes (b + fromPartSize a)+ instance Monoid PartSize where 	mempty = MegaBytes 0-	mappend (MegaBytes a) (MegaBytes b) = MegaBytes (a + b)-	mappend (Bytes a) b = Bytes (a + fromPartSize b)-	mappend a (Bytes b) = Bytes (b + fromPartSize a)+	mappend = (Sem.<>)  reducePartSize :: PartSize -> PartSize -> PartSize reducePartSize (MegaBytes a) (MegaBytes b) = MegaBytes (a - b)
src/Propellor/Property/Schroot.hs view
@@ -32,8 +32,8 @@ -- Implicitly sets 'useOverlays' info property. -- -- Shell script from <https://wiki.debian.org/sbuild>.-overlaysInTmpfs :: Property (HasInfo + DebianLike)-overlaysInTmpfs = go `requires` installed+overlaysInTmpfs :: RevertableProperty (HasInfo + DebianLike) UnixLike+overlaysInTmpfs = (go `requires` installed) <!> undo   where 	f = "/etc/schroot/setup.d/04tmpfs" 	go :: Property (HasInfo + UnixLike)@@ -58,6 +58,7 @@ 			, "fi" 			] 		`onChange` (f `File.mode` combineModes (readModes ++ executeModes))+	undo = File.notPresent f  installed :: Property DebianLike installed = Apt.installed ["schroot"]
src/Propellor/Property/SiteSpecific/JoeySites.hs view
@@ -909,20 +909,23 @@ 	& "/etc/systemd/logind.conf" `ConfFile.containsIniSetting` 		("Login", "LidSwitchIgnoreInhibited", "no") --- My home power monitor.-homePowerMonitor :: IsContext c => User -> [Host] -> c -> (SshKeyType, Ssh.PubKeyText) -> Property (HasInfo + DebianLike)-homePowerMonitor user hosts ctx sshkey = propertyList "home power monitor" $ props+homePower :: IsContext c => User -> [Host] -> c -> (SshKeyType, Ssh.PubKeyText) -> Property (HasInfo + DebianLike)+homePower user hosts ctx sshkey = propertyList "home power" $ props 	& Apache.installed 	& Apt.installed ["python", "python-pymodbus", "rrdtool", "rsync"] 	& File.ownerGroup "/var/www/html" user (userGroup user)-	& Git.cloned user "git://git.kitenet.net/joey/homepower" d Nothing-	& buildpoller+	& Git.cloned user "https://git.joeyh.name/git/joey/homepower.git" d Nothing+	& Git.cloned user "https://git.joeyh.name/git/reactive-banana-automation.git" (d </> "reactive-banana-automation") Nothing+	& build 	& Systemd.enabled setupservicename 		`requires` setupserviceinstalled 		`onChange` Systemd.started setupservicename-	& Systemd.enabled servicename-		`requires` serviceinstalled-		`onChange` Systemd.started servicename+	& Systemd.enabled pollerservicename+		`requires` pollerserviceinstalled+		`onChange` Systemd.started pollerservicename+	& Systemd.enabled controllerservicename+		`requires` controllerserviceinstalled+		`onChange` Systemd.started controllerservicename 	& User.hasGroup user (Group "dialout") 	& Group.exists (Group "gpio") Nothing 	& User.hasGroup user (Group "gpio")@@ -936,27 +939,57 @@   where 	d = "/var/www/html/homepower" 	sshkeyfile = d </> ".ssh/key"-	buildpoller = userScriptProperty (User "joey")-		[ "cd " ++ d+	build = userScriptProperty (User "joey")+		[ "cd " ++ d </> "reactive-banana-automation"+		, "cabal install"+		, "cd " ++ d 		, "make" 		] 		`assume` MadeChange-		`requires` Apt.installed ["ghc", "make"]-	servicename = "homepower"-	servicefile = "/etc/systemd/system/" ++ servicename ++ ".service"-	serviceinstalled = servicefile `File.hasContent`+		`requires` Apt.installed+			[ "ghc", "cabal-install", "make"+			, "libghc-http-types-dev"+			, "libghc-stm-dev"+			, "libghc-aeson-dev"+			, "libghc-wai-dev"+			, "libghc-warp-dev"+			, "libghc-http-client-dev"+			, "libghc-reactive-banana-dev"+			, "libghc-hinotify-dev"+			]+	pollerservicename = "homepower"+	pollerservicefile = "/etc/systemd/system/" ++ pollerservicename ++ ".service"+	pollerserviceinstalled = pollerservicefile `File.hasContent` 		[ "[Unit]"-		, "Description=home power monitor"+		, "Description=home power poller" 		, "" 		, "[Service]" 		, "ExecStart=" ++ d ++ "/poller" 		, "WorkingDirectory=" ++ d 		, "User=joey" 		, "Group=joey"+		, "Restart=always" 		, "" 		, "[Install]" 		, "WantedBy=multi-user.target"+		, "WantedBy=homepower-controller.target" 		]+	controllerservicename = "homepower-controller"+	controllerservicefile = "/etc/systemd/system/" ++ controllerservicename ++ ".service"+	controllerserviceinstalled = controllerservicefile `File.hasContent`+		[ "[Unit]"+		, "Description=home power controller"+		, ""+		, "[Service]"+		, "ExecStart=" ++ d ++ "/controller"+		, "WorkingDirectory=" ++ d+		, "User=joey"+		, "Group=joey"+		, "Restart=always"+		, ""+		, "[Install]"+		, "WantedBy=multi-user.target"+		] 	setupservicename = "homepower-setup" 	setupservicefile = "/etc/systemd/system/" ++ setupservicename ++ ".service" 	setupserviceinstalled = setupservicefile `File.hasContent`@@ -976,7 +1009,7 @@ 		] 	-- Any changes to the rsync command will need my .authorized_keys 	-- rsync server command to be updated too.-	rsynccommand = "rsync -e 'ssh -i" ++ sshkeyfile ++ "' -avz rrds/recent/ joey@kitenet.net:/srv/web/homepower.joeyh.name/rrds/recent/"+	rsynccommand = "rsync -e 'ssh -i" ++ sshkeyfile ++ "' -avz rrds/ joey@kitenet.net:/srv/web/homepower.joeyh.name/rrds/"  -- My home router, running hostapd and dnsmasq for wlan0, -- with eth0 connected to a satellite modem, and a fallback ppp connection.@@ -1007,7 +1040,9 @@ 		, "bogus-priv" 		, "interface=wlan0" 		, "domain=kitenet.net"-		, "dhcp-range=10.1.1.100,10.1.1.150,24h"+		-- lease time is short because the homepower+		-- controller wants to know when clients disconnect+		, "dhcp-range=10.1.1.100,10.1.1.150,10m" 		, "no-hosts" 		, "address=/honeybee.kitenet.net/10.1.1.1" 		, "address=/house.kitenet.net/10.1.1.1"@@ -1074,7 +1109,7 @@ 	, "bsdgames", "nethack-console" 	, "xmonad", "libghc-xmonad-dev", "libghc-xmonad-contrib-dev" 	, "ttf-bitstream-vera"-	, "mairix", "offlineimap", "mutt"+	, "mairix", "offlineimap", "mutt", "slrn" 	, "mtr", "nmap", "whois", "wireshark", "tcpdump", "iftop" 	, "pmount", "tree", "pv" 	, "arbtt", "hledger", "bc"@@ -1105,7 +1140,8 @@ 	[ "build-essential", "debhelper", "devscripts" 	, "ghc", "cabal-install", "haskell-stack" 	, "hothasktags", "hdevtools", "hlint"-	, "gdb", "dpkg-repack", "lintian"+	, "gdb", "time"+	, "dpkg-repack", "lintian" 	, "pristine-tar", "github-backup" 	] 
src/Propellor/Property/Ssh.hs view
@@ -45,6 +45,7 @@ import System.PosixCompat import qualified Data.Map as M import qualified Data.Set as S+import qualified Data.Semigroup as Sem import Data.List  installed :: Property UnixLike@@ -229,13 +230,16 @@ instance IsInfo HostKeyInfo where 	propagateInfo _ = PropagateInfo False -instance Monoid HostKeyInfo where-	mempty = HostKeyInfo M.empty-	mappend (HostKeyInfo old) (HostKeyInfo new) =+instance Sem.Semigroup HostKeyInfo where+	HostKeyInfo old <> HostKeyInfo new = 		-- new first because union prefers values from the first 		-- parameter when there is a duplicate key 		HostKeyInfo (new `M.union` old) +instance Monoid HostKeyInfo where+	mempty = HostKeyInfo M.empty+	mappend = (Sem.<>)+ userPubKeys :: User -> [(SshKeyType, PubKeyText)] -> Property (HasInfo + UnixLike) userPubKeys u@(User n) l = pureInfoProperty ("ssh pubkey for " ++ n) $ 	UserKeyInfo (M.singleton u (S.fromList l))@@ -250,10 +254,13 @@ instance IsInfo UserKeyInfo where 	propagateInfo _ = PropagateInfo False +instance Sem.Semigroup UserKeyInfo where+	UserKeyInfo old <> UserKeyInfo new =+		UserKeyInfo (M.unionWith S.union old new)+ instance Monoid UserKeyInfo where 	mempty = UserKeyInfo M.empty-	mappend (UserKeyInfo old) (UserKeyInfo new) =-		UserKeyInfo (M.unionWith S.union old new)+	mappend = (Sem.<>)  -- | Sets up a user with the specified public keys, and the corresponding -- private keys from the privdata.
src/Propellor/Property/Unbound.hs view
@@ -64,6 +64,10 @@ -- | Provided a [UnboundSection], a [UnboundZone] and a [UnboundHost], -- cachingDnsServer ensure unbound is configured accordingly. --+-- Be carefull with CNAMEs, unbound is not a primary DNS server, so it will+-- resolve these by itself. For a locally served zone, you probably want A/AAAA+-- records instead.+-- -- Example property: -- -- > cachingDnsServer@@ -115,13 +119,47 @@  genRecord :: BindDomain -> Record -> Maybe String genRecord dom (Address addr) = Just $ genAddressNoTtl dom addr-genRecord dom (MX priority dest) = Just $ genMX dom priority dest-genRecord dom (PTR revip) = Just $ genPTR dom revip-genRecord _ (CNAME _) = Nothing-genRecord _ (NS _) = Nothing-genRecord _ (TXT _) = Nothing-genRecord _ (SRV _ _ _ _) = Nothing-genRecord _ (SSHFP _ _ _) = Nothing+genRecord dom (MX priority dest) = Just $ unwords+	[ dValue dom+	, "MX"+	, val priority+	, dValue dest+	]+genRecord dom (PTR revip) = Just $ unwords+	[ revip ++ "."+	, "PTR"+	, dValue dom+	]+genRecord dom (CNAME dest) = Just $ unwords+	[ dValue dom+	, "CNAME"+	, dValue dest+	]+genRecord dom (NS serv) = Just $ unwords+	[ dValue dom+	, "NS"+	, dValue serv+	]+genRecord dom (TXT txt) = Just $ unwords+	[ dValue dom+	, "TXT"+	, txt+	]+genRecord dom (SRV priority weight port target) = Just $ unwords+	[ dValue dom+	, "SRV"+	, val priority+	, val weight+	, val port+	, dValue target+	]+genRecord dom (SSHFP algo hash fingerprint) = Just $ unwords+	[ dValue dom+	, "SSHFP"+	, val algo+	, val hash+	, fingerprint+	] genRecord _ (INCLUDE _) = Nothing  genAddressNoTtl :: BindDomain -> IPAddr -> String@@ -133,10 +171,10 @@ 	IPv6 _ -> genAddress' "AAAA" dom ttl addr  genAddress' :: String -> BindDomain -> Maybe Int -> IPAddr -> String-genAddress' recordtype dom ttl addr = dValue dom ++ " " ++ maybe "" (\ttl' -> val ttl' ++ " ") ttl ++ "IN " ++ recordtype ++ " " ++ val addr--genMX :: BindDomain -> Int -> BindDomain -> String-genMX dom priority dest = dValue dom ++ " " ++ "MX" ++ " " ++ val priority ++ " " ++ dValue dest--genPTR :: BindDomain -> ReverseIP -> String-genPTR dom revip = revip ++ ". " ++ "PTR" ++ " " ++ dValue dom+genAddress' recordtype dom ttl addr = unwords $+	[ dValue dom ]+	++ maybe [] (\ttl' -> [val ttl']) ttl +++	[ "IN"+	, recordtype+	, val addr+	]
src/Propellor/Shim.hs view
@@ -16,11 +16,18 @@ -- | Sets up a shimmed version of the program, in a directory, and -- returns its path. --+-- If the shim was already set up, it's refreshed, in case newer+-- versions of libraries are needed.+-- -- Propellor may be running from an existing shim, in which case it's -- simply reused. setup :: FilePath -> Maybe FilePath -> FilePath -> IO FilePath-setup propellorbin propellorbinpath dest = checkAlreadyShimmed shim $ do+setup propellorbin propellorbinpath dest = checkAlreadyShimmed propellorbin $ do 	createDirectoryIfMissing True dest++	-- Remove all old libraries inside dest, but do not delete the+	-- directory itself, since it may be bind-mounted inside a chroot.+	mapM_ nukeFile =<< dirContentsRecursive dest  	libs <- parseLdd <$> readProcess "ldd" [propellorbin] 	glibclibs <- glibcLibs
src/Propellor/Types.hs view
@@ -43,6 +43,7 @@ 	, module Propellor.Types.ZFS 	) where +import qualified Data.Semigroup as Sem import Data.Monoid import Control.Applicative import Prelude@@ -212,14 +213,13 @@ instance TightenTargets Property where 	tightenTargets (Property _ d a i c) = Property sing d a i c --- | Any type of Property is a monoid. When properties x and y are+-- | Any type of Property is a Semigroup. When properties x and y are -- appended together, the resulting property has a description like -- "x and y". Note that when x fails to be ensured, it will not -- try to ensure y.-instance SingI metatypes => Monoid (Property (MetaTypes metatypes))+instance SingI metatypes => Sem.Semigroup (Property (MetaTypes metatypes))   where-	mempty = Property sing "noop property" Nothing mempty mempty-	mappend (Property _ d1 a1 i1 c1) (Property _ d2 a2 i2 c2) =+	Property _ d1 a1 i1 c1 <> Property _ d2 a2 i2 c2 = 	  	Property sing d (a1 <> a2) (i1 <> i2) (c1 <> c2) 	  where 		-- Avoid including "noop property" in description@@ -230,16 +230,35 @@ 			(Nothing, Just _) -> d2 			(Nothing, Nothing) -> d1 --- | Any type of RevertableProperty is a monoid. When revertable +-- | Any type of Property is a Monoid.+instance SingI metatypes => Monoid (Property (MetaTypes metatypes))+  where+	-- | A property that does nothing.+	mempty = Property sing "noop property" Nothing mempty mempty+	mappend = (Sem.<>)++-- | Any type of RevertableProperty is a Semigroup. When revertable  -- properties x and y are appended together, the resulting revertable -- property has a description like "x and y". -- Note that when x fails to be ensured, it will not try to ensure y. instance-	( Monoid (Property setupmetatypes)-	, Monoid (Property undometatypes)+	( Sem.Semigroup (Property (MetaTypes setupmetatypes))+	, Sem.Semigroup (Property (MetaTypes undometatypes))+	, SingI setupmetatypes+	, SingI undometatypes 	)-	=> Monoid (RevertableProperty setupmetatypes undometatypes)+	=> Sem.Semigroup (RevertableProperty (MetaTypes setupmetatypes) (MetaTypes undometatypes))   where-	mempty = RevertableProperty mempty mempty-	mappend (RevertableProperty s1 u1) (RevertableProperty s2 u2) =+	RevertableProperty s1 u1 <> RevertableProperty s2 u2 = 		RevertableProperty (s1 <> s2) (u2 <> u1)++instance+	( Monoid (Property (MetaTypes setupmetatypes))+	, Monoid (Property (MetaTypes undometatypes))+	, SingI setupmetatypes+	, SingI undometatypes+	)+	=> Monoid (RevertableProperty (MetaTypes setupmetatypes) (MetaTypes undometatypes))+  where+	mempty = RevertableProperty mempty mempty+	mappend = (Sem.<>)
src/Propellor/Types/Chroot.hs view
@@ -6,8 +6,10 @@ import Propellor.Types.Empty import Propellor.Types.Info -import Data.Monoid+import qualified Data.Semigroup as Sem import qualified Data.Map as M+import Data.Monoid+import Prelude  data ChrootInfo = ChrootInfo 	{ _chroots :: M.Map FilePath Host@@ -18,13 +20,16 @@ instance IsInfo ChrootInfo where 	propagateInfo _ = PropagateInfo False -instance Monoid ChrootInfo where-	mempty = ChrootInfo mempty mempty-	mappend old new = ChrootInfo+instance Sem.Semigroup ChrootInfo where+	old <> new = ChrootInfo 		{ _chroots = M.union (_chroots old) (_chroots new) 		, _chrootCfg = _chrootCfg old <> _chrootCfg new 		} +instance Monoid ChrootInfo where+	mempty = ChrootInfo mempty mempty+	mappend = (Sem.<>)+ instance Empty ChrootInfo where 	isEmpty i = and 		[ isEmpty (_chroots i)@@ -36,12 +41,15 @@ 	| SystemdNspawnCfg [(String, Bool)] 	deriving (Show, Eq) +instance Sem.Semigroup ChrootCfg where+	v <> NoChrootCfg = v+	NoChrootCfg <> v = v+	SystemdNspawnCfg l1 <> SystemdNspawnCfg l2 =+		SystemdNspawnCfg (l1 <> l2)+ instance Monoid ChrootCfg where 	mempty = NoChrootCfg-	mappend v NoChrootCfg = v-	mappend NoChrootCfg v = v-	mappend (SystemdNspawnCfg l1) (SystemdNspawnCfg l2) =-		SystemdNspawnCfg (l1 <> l2)+	mappend = (Sem.<>)  instance Empty ChrootCfg where 	isEmpty c= c == NoChrootCfg
src/Propellor/Types/Core.hs view
@@ -10,6 +10,7 @@ import Propellor.Types.Result  import Data.Monoid+import qualified Data.Semigroup as Sem import "mtl" Control.Monad.RWS.Strict import Control.Monad.Catch import Control.Applicative@@ -50,15 +51,18 @@  -- | When two actions are appended together, the second action -- is only run if the first action does not fail.-instance Monoid (Propellor Result) where-	mempty = return NoChange-	mappend x y = do+instance Sem.Semigroup (Propellor Result) where+	x <> y = do 		rx <- x 		case rx of 			FailedChange -> return FailedChange 			_ -> do 				ry <- y 				return (rx <> ry)+	+instance Monoid (Propellor Result) where+	mempty = return NoChange+	mappend = (Sem.<>)  -- | An action that Propellor runs at the end, after trying to satisfy all -- properties. It's passed the combined Result of the entire Propellor run.
src/Propellor/Types/Dns.hs view
@@ -12,6 +12,7 @@ import Data.Word import qualified Data.Map as M import qualified Data.Set as S+import qualified Data.Semigroup as Sem import Data.List import Data.Monoid import Prelude@@ -26,7 +27,7 @@ 	val (IPv6 addr) = addr  newtype AliasesInfo = AliasesInfo (S.Set HostName)-	deriving (Show, Eq, Ord, Monoid, Typeable)+	deriving (Show, Eq, Ord, Sem.Semigroup, Monoid, Typeable)  instance IsInfo AliasesInfo where 	propagateInfo _ = PropagateInfo False@@ -42,7 +43,7 @@ -- of the containers in the host be reflected in the DNS. newtype DnsInfoPropagated = DnsInfoPropagated 	{ fromDnsInfoPropagated :: S.Set Record }-	deriving (Show, Eq, Ord, Monoid, Typeable)+	deriving (Show, Eq, Ord, Sem.Semigroup, Monoid, Typeable)  toDnsInfoPropagated :: S.Set Record -> DnsInfoPropagated toDnsInfoPropagated = DnsInfoPropagated@@ -55,7 +56,7 @@ -- the host. newtype DnsInfoUnpropagated = DnsInfoUnpropagated 	{ fromDnsInfoUnpropagated :: S.Set Record }-	deriving (Show, Eq, Ord, Monoid, Typeable)+	deriving (Show, Eq, Ord, Sem.Semigroup, Monoid, Typeable)  toDnsInfoUnpropagated :: S.Set Record -> DnsInfoUnpropagated toDnsInfoUnpropagated = DnsInfoUnpropagated@@ -183,14 +184,17 @@ -- | Adding a Master NamedConf stanza for a particulr domain always -- overrides an existing Secondary stanza for that domain, while a -- Secondary stanza is only added when there is no existing Master stanza.-instance Monoid NamedConfMap where-	mempty = NamedConfMap M.empty-	mappend (NamedConfMap old) (NamedConfMap new) = NamedConfMap $+instance Sem.Semigroup NamedConfMap where+	NamedConfMap old <> NamedConfMap new = NamedConfMap $ 		M.unionWith combiner new old 	  where 		combiner n o = case (confDnsServerType n, confDnsServerType o) of 			(Secondary, Master) -> o 			_  -> n++instance Monoid NamedConfMap where+	mempty = NamedConfMap M.empty+	mappend = (Sem.<>)  instance Empty NamedConfMap where 	isEmpty (NamedConfMap m) = isEmpty m
src/Propellor/Types/Docker.hs view
@@ -6,8 +6,10 @@ import Propellor.Types.Empty import Propellor.Types.Info -import Data.Monoid+import qualified Data.Semigroup as Sem import qualified Data.Map as M+import Data.Monoid+import Prelude  data DockerInfo = DockerInfo 	{ _dockerRunParams :: [DockerRunParam]@@ -18,12 +20,15 @@ instance IsInfo DockerInfo where 	propagateInfo _ = PropagateInfo False -instance Monoid DockerInfo where-	mempty = DockerInfo mempty mempty-	mappend old new = DockerInfo+instance Sem.Semigroup DockerInfo where+	old <> new = DockerInfo 		{ _dockerRunParams = _dockerRunParams old <> _dockerRunParams new 		, _dockerContainers = M.union (_dockerContainers old) (_dockerContainers new) 		}++instance Monoid DockerInfo where+	mempty = DockerInfo mempty mempty+	mappend = (Sem.<>)  instance Empty DockerInfo where 	isEmpty i = and
src/Propellor/Types/Info.hs view
@@ -17,6 +17,7 @@ import Data.Dynamic import Data.Maybe import Data.Monoid+import qualified Data.Semigroup as Sem import qualified Data.Typeable as T import Prelude @@ -25,7 +26,7 @@ -- Many different types of data can be contained in the same Info value -- at the same time. See `toInfo` and `fromInfo`. newtype Info = Info [InfoEntry]-	deriving (Monoid, Show)+	deriving (Sem.Semigroup, Monoid, Show)  data InfoEntry where 	InfoEntry :: (IsInfo v, Typeable v) => v -> InfoEntry@@ -80,10 +81,13 @@ data InfoVal v = NoInfoVal | InfoVal v 	deriving (Typeable, Show) +instance Sem.Semigroup (InfoVal v) where+	_ <> v@(InfoVal _) = v+	v <> NoInfoVal = v+ instance Monoid (InfoVal v) where 	mempty = NoInfoVal-	mappend _ v@(InfoVal _) = v-	mappend v NoInfoVal = v+	mappend = (Sem.<>)  instance (Typeable v, Show v) => IsInfo (InfoVal v) where 	propagateInfo _ = PropagateInfo False
src/Propellor/Types/MetaTypes.hs view
@@ -66,7 +66,7 @@ type MetaTypes = Sing  -- This boilerplate would not be needed if the singletons library were--- used. However, we're targeting too old a version of ghc to use it yet.+-- used. data instance Sing (x :: MetaType) where 	OSDebianS :: Sing ('Targeting 'OSDebian) 	OSBuntishS :: Sing ('Targeting 'OSBuntish)
src/Propellor/Types/Result.hs view
@@ -1,6 +1,7 @@ module Propellor.Types.Result where  import System.Console.ANSI+import qualified Data.Semigroup as Sem import Data.Monoid import Prelude @@ -8,14 +9,16 @@ data Result = NoChange | MadeChange | FailedChange 	deriving (Read, Show, Eq) +instance Sem.Semigroup Result where+	FailedChange <> _ = FailedChange+	_ <> FailedChange = FailedChange+	MadeChange <> _ = MadeChange+	_ <> MadeChange = MadeChange+	NoChange <> NoChange = NoChange+ instance Monoid Result where 	mempty = NoChange--	mappend FailedChange _ = FailedChange-	mappend _ FailedChange = FailedChange-	mappend MadeChange _ = MadeChange-	mappend _ MadeChange = MadeChange-	mappend NoChange NoChange = NoChange+	mappend = (Sem.<>)  class ToResult t where 	toResult :: t -> Result
src/Propellor/Types/ResultCheck.hs view
@@ -14,6 +14,7 @@ import Utility.Monad  import Data.Monoid+import Prelude  -- | This is a `Property` but its `Result` is not accurate; in particular -- it may return `NoChange` despite having made a change. 
stack.yaml view
@@ -1,4 +1,4 @@ # When updating the resolver here, also update stackResolver in Propellor.DotDir-resolver: lts-8.22+resolver: lts-9.21 packages: - '.'