Skip to content

Commit e24dd87

Browse files
Refactor the code, add TODOs
1 parent 3d45808 commit e24dd87

File tree

2 files changed

+118
-46
lines changed

2 files changed

+118
-46
lines changed

src/Streamly/Coreutils/Chmod.hs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,19 @@
5151
-- the owner? But we cannot do the same on windows.
5252

5353
module Streamly.Coreutils.Chmod
54-
( chmod
54+
(
55+
-- * Roles
56+
Role (..)
57+
58+
-- * Permissions
59+
, Permissions
60+
, setReadable
61+
, setWritable
62+
, setExecutable
63+
, reset
64+
65+
-- * Chmod
66+
, chmod
5567
)
5668
where
5769

@@ -63,7 +75,7 @@ modifyBit :: Bool -> Posix.FileMode -> Posix.FileMode -> Posix.FileMode
6375
modifyBit False b m = m .&. complement b
6476
modifyBit True b m = m .|. b
6577

66-
chmodWith :: UserType -> Permissions -> FilePath -> IO ()
78+
chmodWith :: Role -> Permissions -> FilePath -> IO ()
6779
chmodWith utype (Permissions r w e) path = do
6880
case utype of
6981
Owner -> setOwnerPermissions
@@ -108,8 +120,16 @@ chmodWith utype (Permissions r w e) path = do
108120
setGroupPermissions
109121
setOthersPermissions
110122

111-
-- | Supports only override permissions bits
112-
-- >> chmod [perm|a=rwx|] "a.txt"
123+
-- | Change the file permission modes for specified roles using the specified
124+
-- permission modifier functions.
125+
--
126+
-- You can use the @mode@ quasiquoter to build the mode conveniently, for
127+
-- example:
128+
--
129+
-- >> chmod [mode|a=rwx|] "a.txt"
113130
--
114-
chmod :: UserTypePerm -> FilePath -> IO ()
115-
chmod pat = chmodWith (utype pat) (permssions pat)
131+
chmod :: [(Role, Permissions -> Permissions)] -> FilePath -> IO ()
132+
-- To implement this, get the file mode. Transform the FileMode using the roles
133+
-- and permissions, and then use a single setFileMode call to set the mode in
134+
-- the end.
135+
chmod pat = undefined

src/Streamly/Coreutils/StringQ.hs

Lines changed: 92 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@
99
--
1010
-- change file mode bits.
1111

12+
-- XXX Rename to "Permissions" or "AccessControl"
13+
1214
module Streamly.Coreutils.StringQ
1315
(
14-
perm
15-
, UserType(..)
16+
Role(..)
1617
, Permissions(..)
17-
, UserTypePerm(..)
18+
, setReadable
19+
, setWritable
20+
, setExecutable
21+
, reset
1822
)
1923
where
2024

@@ -31,9 +35,63 @@ import Streamly.Internal.Data.Parser (Parser)
3135
import qualified Streamly.Internal.Data.Fold as Fold
3236
import qualified Streamly.Internal.Data.Parser as Parser
3337
import qualified Streamly.Internal.Data.Stream.IsStream as Stream
34-
import qualified Streamly.Internal.Unicode.Char.Parser as Parser
38+
import qualified Streamly.Internal.Unicode.Parser as Parser
39+
40+
-------------------------------------------------------------------------------
41+
-- Permissions
42+
-------------------------------------------------------------------------------
43+
44+
-- | Permissions for access control
45+
data Permissions = Permissions
46+
{ readable :: Bool
47+
, writable :: Bool
48+
, executable :: Bool
49+
-- , searchable :: Bool -- for portability, keep it separate
50+
} deriving (Eq, Ord, Read, Show, Data)
3551

36-
strParser :: MonadCatch m => Parser m Char String
52+
{-
53+
defaultPermissions =
54+
Permissions
55+
{ readable = False
56+
, writable = False
57+
, executable = False
58+
}
59+
-}
60+
61+
-- | Enable @read@ permission.
62+
setReadable :: Bool -> Permissions -> Permissions
63+
setReadable x perms = perms { readable = x }
64+
65+
-- | Enable @write@ permission.
66+
setWritable :: Bool -> Permissions -> Permissions
67+
setWritable x perms = perms { writable = x }
68+
69+
-- | Enable @execute@ permission.
70+
setExecutable :: Bool -> Permissions -> Permissions
71+
setExecutable x perms = perms { executable = x }
72+
73+
-- | Disable all permissions.
74+
reset :: Permissions -> Permissions
75+
reset = setReadable False . setWritable False . setExecutable False
76+
77+
-------------------------------------------------------------------------------
78+
-- Roles
79+
-------------------------------------------------------------------------------
80+
81+
-- | Roles to whom access is granted.
82+
data Role =
83+
Owner
84+
| Group
85+
| Others
86+
| All
87+
deriving (Eq, Ord, Read, Show, Data)
88+
89+
-------------------------------------------------------------------------------
90+
-- Mode parser
91+
-------------------------------------------------------------------------------
92+
93+
{-
94+
strParser :: MonadCatch m => Parser Char m String
3795
strParser =
3896
let ut = Parser.char 'u'
3997
<|> Parser.char 'g'
@@ -57,33 +115,7 @@ expandVars ln =
57115
Left _ -> fail "Parsing of perm quoted string failed."
58116
Right _ -> return ()
59117
60-
data Permissions = Permissions
61-
{ readable :: Bool
62-
, writable :: Bool
63-
, executable :: Bool
64-
} deriving (Eq, Ord, Read, Show, Data)
65-
66-
data UserType =
67-
Owner
68-
| Group
69-
| Others
70-
| All
71-
deriving (Eq, Ord, Read, Show, Data)
72-
73-
data UserTypePerm =
74-
UserTypePerm
75-
{ utype :: UserType
76-
, permssions :: Permissions
77-
} deriving (Eq, Ord, Read, Show, Data)
78-
79-
instance Default Permissions where
80-
def = Permissions
81-
{ readable = False
82-
, writable = False
83-
, executable = False
84-
}
85-
86-
parseExpr :: MonadIO m => String -> m UserTypePerm
118+
parseExpr :: MonadIO m => String -> m [(Role, Permissions)]
87119
parseExpr s = do
88120
liftIO $ expandVars s
89121
let ut = head s
@@ -119,15 +151,35 @@ quoteExprPat s = do
119151
expr <- parseExpr s
120152
dataToPatQ (const Nothing) expr
121153
122-
perm :: QuasiQuoter
123-
perm =
154+
-- TODO: perms can have a single letter from the set ugo, in that case the
155+
-- existing permissions are copied from that role.
156+
157+
-- When we get a "=" use 'reset', when we get a '+' use an operation with
158+
-- argument True, else use False.
159+
160+
-- | The format of a symbolic mode is [roles][-+=][perms...], where roles is
161+
-- either zero or more letters from the set ugoa. perms is either zero or more
162+
-- letters from the set rwxXst. Multiple symbolic modes can be given, separated
163+
-- by commas.
164+
--
165+
-- Examples:
166+
--
167+
-- @
168+
-- -
169+
-- -rwx
170+
-- g-rx
171+
-- g-x+r
172+
-- go-x+rw
173+
-- go-x+rw,u+r
174+
-- @
175+
--
176+
-- If the role is omitted it is assumed to be 'a'.
177+
mode :: QuasiQuoter
178+
mode =
124179
QuasiQuoter
125180
{ quoteExp = quoteExprExp
126181
, quotePat = quoteExprPat
127-
, quoteType = notSupported
128-
, quoteDec = notSupported
182+
, quoteType = error "mode: quoteType not supported."
183+
, quoteDec = error "mode: quoteDec not supported."
129184
}
130-
131-
where
132-
133-
notSupported = error "perm: Not supported."
185+
-}

0 commit comments

Comments
 (0)