summaryrefslogtreecommitdiff
path: root/src/Propellor/Property/File.hs
diff options
context:
space:
mode:
authorJoey Hess2017-02-02 15:40:30 -0400
committerJoey Hess2017-02-02 15:40:37 -0400
commitb1f0bd05941f5d8c42a28d33316a0a0452a62476 (patch)
treeb3174ebe6ef98712aee8851ec70e1ae5804a9428 /src/Propellor/Property/File.hs
parent5c170d3f8021b2120d3147103e23baf7bac6cc76 (diff)
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.
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 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