From f8dc9b294dbc114255129113f84fabde6dac46cc Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Sun, 16 Aug 2015 17:47:21 -0700 Subject: ConfFile.containsIniPair property plus scaffolding for other generic conf file properties (cherry picked from commit 86b077b7a21efd5484dfaeee3c31fc5f3c151f6c) --- src/Propellor/Property/ConfFile.hs | 72 ++++++++++++++++++++++++++++++++++++++ src/Propellor/Property/LightDM.hs | 4 +-- 2 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 src/Propellor/Property/ConfFile.hs (limited to 'src/Propellor/Property') diff --git a/src/Propellor/Property/ConfFile.hs b/src/Propellor/Property/ConfFile.hs new file mode 100644 index 00000000..72996c74 --- /dev/null +++ b/src/Propellor/Property/ConfFile.hs @@ -0,0 +1,72 @@ +module Propellor.Property.ConfFile (containsIniPair) where + +import Propellor +import Propellor.Property.File + +import Data.List (isPrefixOf, foldl') + +type SectionStart = Line -> Bool -- ^ find the line that is the start of the + -- wanted section (eg, == "") +type SectionPast = Line -> Bool -- ^ find a line that indicates we are past + -- the section (eg, a new section header) +type AdjustSection = [Line] -> [Line] -- ^ run on all lines in the section, + -- including the SectionStart line and any + -- SectionEnd line; can add/delete/modify + -- lines, or even delete entire section +type InsertSection = [Line] -> [Line] -- ^ if SectionStart does not find the + -- section in the file, this is used to + -- insert the section somewhere within it + +adjustSection + :: String + -> SectionStart + -> SectionPast + -> AdjustSection + -> InsertSection + -> FilePath + -> Property NoInfo +adjustSection desc start past adjust insert f = + fileProperty desc go f + where + go ls = let (pre, wanted, post) = foldl' find ([], [], []) ls + in if null wanted + then insert ls + else pre ++ (adjust wanted) ++ post + find (pre, wanted, post) l + | null wanted && null post && (not . start) l = + (pre ++ [l], wanted, post) + | (start l && null wanted && null post) + || ((not . null) wanted && null post && (not . past) l) = + (pre, wanted ++ [l], post) + | otherwise = (pre, wanted, post ++ [l]) + +iniHeader :: String -> String +iniHeader header = '[' : header ++ "]" + +adjustIniSection + :: String + -> String + -> AdjustSection + -> InsertSection + -> FilePath + -> Property NoInfo +adjustIniSection desc header = + adjustSection + desc + (== iniHeader header) + ("[" `isPrefixOf`) + +containsIniPair :: FilePath -> (String, String, String) -> Property NoInfo +containsIniPair f (header, key, value) = + adjustIniSection + (f ++ " section [" ++ header ++ "] contains " ++ key ++ "=" ++ value) + header + go + (++ [confheader, confline]) + f + where + confheader = iniHeader header + confline = key ++ "=" ++ value + go [] = [confline] + go (l:ls) = if isKeyVal l then confline : ls else l : (go ls) + isKeyVal x = (filter (/= ' ') . takeWhile (/= '=')) x `elem` [key, '#':key] diff --git a/src/Propellor/Property/LightDM.hs b/src/Propellor/Property/LightDM.hs index b3756f6e..09f7165d 100644 --- a/src/Propellor/Property/LightDM.hs +++ b/src/Propellor/Property/LightDM.hs @@ -3,10 +3,10 @@ module Propellor.Property.LightDM where import Propellor -import qualified Propellor.Property.File as File +import qualified Propellor.Property.ConfFile as ConfFile -- | Configures LightDM to skip the login screen and autologin as a user. autoLogin :: User -> Property NoInfo -autoLogin (User u) = "/etc/lightdm/lightdm.conf" `File.containsConfPair` +autoLogin (User u) = "/etc/lightdm/lightdm.conf" `ConfFile.containsIniPair` ("SeatDefaults", "autologin-user", u) `describe` "lightdm autologin" -- cgit v1.2.3