summaryrefslogtreecommitdiff
path: root/src/Propellor/Property/File.hs
diff options
context:
space:
mode:
authorSean Whitton2017-02-02 15:44:00 -0700
committerSean Whitton2017-02-02 15:44:00 -0700
commit967b58752ce1b932882b61ca138c29cf82cc377c (patch)
tree0dc4b3caa06f89db19357e3edcd893c0e6ce68e9 /src/Propellor/Property/File.hs
parent74e3e1f84cf2408bc822c48f810f37baa5cfffad (diff)
parentf861070a3ad159a60961292ccdb53e30524968cd (diff)
Merge remote-tracking branch 'upstream/master' into pin
Diffstat (limited to 'src/Propellor/Property/File.hs')
-rw-r--r--src/Propellor/Property/File.hs40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/Propellor/Property/File.hs b/src/Propellor/Property/File.hs
index 9f73b14a..869fa48b 100644
--- a/src/Propellor/Property/File.hs
+++ b/src/Propellor/Property/File.hs
@@ -9,6 +9,7 @@ import qualified Data.ByteString.Lazy as L
import Data.List (isInfixOf, isPrefixOf)
import System.Posix.Files
import System.Exit
+import Data.Char
type Line = String
@@ -244,3 +245,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 ".old" 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:
+--
+-- > aptConf foo = "/etc/apt/apt.conf.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