From b1f0bd05941f5d8c42a28d33316a0a0452a62476 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 2 Feb 2017 15:40:30 -0400 Subject: Added Propellor.Property.File.configFileName and related functions to generate good filenames for config directories. spwhitton has a branch that could use this, and there are several places in propellor that do something ad-hoc that would have been better implemented using this. I was not able to switch any of the existing ad-hoc stuff, but this can be used going forward for new stuff. This commit was sponsored by Anthony DeRobertis on Patreon. --- src/Propellor/Property/File.hs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'src/Propellor/Property/File.hs') diff --git a/src/Propellor/Property/File.hs b/src/Propellor/Property/File.hs index 95fc6f81..fe2b1057 100644 --- a/src/Propellor/Property/File.hs +++ b/src/Propellor/Property/File.hs @@ -8,6 +8,7 @@ import Utility.FileMode import qualified Data.ByteString.Lazy as L import System.Posix.Files import System.Exit +import Data.Char type Line = String @@ -221,3 +222,42 @@ viaStableTmp a f = bracketIO setup cleanup go go tmpfile = do a tmpfile liftIO $ rename tmpfile f + +-- | Generates a base configuration file name from a String, which +-- can be put in a configuration directory, such as +-- /etc/apt/sources.list.d/ +-- +-- The generated file name is limited to using ASCII alphanumerics, +-- '_' and '.', so that programs that only accept a limited set of +-- characters will accept it. Any other characters will be encoded +-- in escaped form. +-- +-- Some file extensions, such as ".dpkg-new" may be filtered out by +-- programs that use configuration directories. To avoid such problems, +-- it's a good idea to add an static prefix and extension to the +-- result of this function. For example: +-- +-- > aptSource foo = "/etc/apt/sources.list.d" "propellor_" ++ configFileName foo <.> ".conf" +configFileName :: String -> FilePath +configFileName = concatMap escape + where + escape c + | isAscii c && isAlphaNum c = [c] + | c == '.' = [c] + | otherwise = '_' : show (ord c) + +-- | Applies configFileName to any value that can be shown. +showConfigFileName :: Show v => v -> FilePath +showConfigFileName = configFileName . show + +-- | Inverse of showConfigFileName. +readConfigFileName :: Read v => FilePath -> Maybe v +readConfigFileName = readish . unescape + where + unescape [] = [] + unescape ('_':cs) = case break (not . isDigit) cs of + ([], _) -> '_' : unescape cs + (ns, cs') -> case readish ns of + Nothing -> '_' : ns ++ unescape cs' + Just n -> chr n : unescape cs' + unescape (c:cs) = c : unescape cs -- cgit v1.2.3