blob: 29de8df2584dac2bd9654228aed246cd0bf1bef6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
-- | Maintainer: Sean Whitton <spwhitton@spwhitton.name>
module Propellor.Property.Locale where
import Propellor.Base
import Propellor.Property.File
import Data.List (isPrefixOf)
type Locale = String
type LocaleVariable = String
-- | Select a locale for a list of global locale variables.
--
-- A locale variable is of the form @LC_BLAH@, @LANG@ or @LANGUAGE@. See
-- @locale(5)@. One might say
--
-- > & "en_GB.UTF-8" `Locale.selectedFor` ["LC_PAPER", "LC_MONETARY"]
--
-- to select the British English locale for paper size and currency conventions.
--
-- Note that reverting this property does not make a locale unavailable. That's
-- because it might be required for other Locale.selectedFor statements.
selectedFor :: Locale -> [LocaleVariable] -> RevertableProperty NoInfo
locale `selectedFor` vars = select <!> deselect
where
select = check (not <$> isselected) select'
`requires` available locale
`describe` (locale ++ " locale selected")
select' = cmdProperty "update-locale" selectArgs
`assume` MadeChange
deselect = check isselected deselect'
`describe` (locale ++ " locale deselected")
deselect' = cmdProperty "update-locale" vars
`assume` MadeChange
selectArgs = zipWith (++) vars (repeat ('=':locale))
isselected = locale `isSelectedFor` vars
isSelectedFor :: Locale -> [LocaleVariable] -> IO Bool
locale `isSelectedFor` vars = do
ls <- catchDefaultIO [] $ lines <$> readFile "/etc/default/locale"
return $ and $ map (\v -> v ++ "=" ++ locale `elem` ls) vars
-- | Ensures a locale is generated (or, if reverted, ensure it's not).
--
-- Fails if a locale is not available to be generated. That is, a commented out
-- entry for the locale and an accompanying charset must be present in
-- /etc/locale.gen.
--
-- Per Debian bug #684134 we cannot ensure a locale is generated by means of
-- Apt.reConfigure. So localeAvailable edits /etc/locale.gen manually.
available :: Locale -> RevertableProperty NoInfo
available locale = (ensureAvailable <!> ensureUnavailable)
where
f = "/etc/locale.gen"
desc = (locale ++ " locale generated")
ensureAvailable =
property desc $ (lines <$> (liftIO $ readFile f))
>>= \locales ->
if locale `presentIn` locales
then ensureProperty $
fileProperty desc (foldr uncomment []) f
`onChange` regenerate
else return FailedChange -- locale unavailable for generation
ensureUnavailable =
fileProperty (locale ++ " locale not generated") (foldr comment []) f
`onChange` regenerate
uncomment l ls =
if ("# " ++ locale) `isPrefixOf` l
then drop 2 l : ls
else l:ls
comment l ls =
if locale `isPrefixOf` l
then ("# " ++ l) : ls
else l:ls
l `presentIn` ls = any (l `isPrefix`) ls
l `isPrefix` x = (l `isPrefixOf` x) || (("# " ++ l) `isPrefixOf` x)
regenerate = cmdProperty "dpkg-reconfigure"
["-f", "noninteractive", "locales"]
`assume` MadeChange
|