module Hadolint.Rule where
import Control.DeepSeq (NFData)
import Data.Default
import Data.String (IsString (..))
import Data.Text (Text, unpack)
import GHC.Generics (Generic)
import Language.Docker.Syntax
import Prettyprinter (Pretty, pretty)
import qualified Control.Foldl as Foldl
import qualified Data.Map as Map
import qualified Data.Sequence as Seq
import qualified Data.Text as Text
import qualified Data.YAML as Yaml
infixl 0 |>
(|>) :: a -> (a -> b) -> b
a
x |> :: a -> (a -> b) -> b
|> a -> b
f = a -> b
f a
x
data DLSeverity
= DLErrorC
| DLWarningC
| DLInfoC
| DLStyleC
| DLIgnoreC
deriving (DLSeverity -> DLSeverity -> Bool
(DLSeverity -> DLSeverity -> Bool)
-> (DLSeverity -> DLSeverity -> Bool) -> Eq DLSeverity
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DLSeverity -> DLSeverity -> Bool
$c/= :: DLSeverity -> DLSeverity -> Bool
== :: DLSeverity -> DLSeverity -> Bool
$c== :: DLSeverity -> DLSeverity -> Bool
Eq, Eq DLSeverity
Eq DLSeverity
-> (DLSeverity -> DLSeverity -> Ordering)
-> (DLSeverity -> DLSeverity -> Bool)
-> (DLSeverity -> DLSeverity -> Bool)
-> (DLSeverity -> DLSeverity -> Bool)
-> (DLSeverity -> DLSeverity -> Bool)
-> (DLSeverity -> DLSeverity -> DLSeverity)
-> (DLSeverity -> DLSeverity -> DLSeverity)
-> Ord DLSeverity
DLSeverity -> DLSeverity -> Bool
DLSeverity -> DLSeverity -> Ordering
DLSeverity -> DLSeverity -> DLSeverity
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: DLSeverity -> DLSeverity -> DLSeverity
$cmin :: DLSeverity -> DLSeverity -> DLSeverity
max :: DLSeverity -> DLSeverity -> DLSeverity
$cmax :: DLSeverity -> DLSeverity -> DLSeverity
>= :: DLSeverity -> DLSeverity -> Bool
$c>= :: DLSeverity -> DLSeverity -> Bool
> :: DLSeverity -> DLSeverity -> Bool
$c> :: DLSeverity -> DLSeverity -> Bool
<= :: DLSeverity -> DLSeverity -> Bool
$c<= :: DLSeverity -> DLSeverity -> Bool
< :: DLSeverity -> DLSeverity -> Bool
$c< :: DLSeverity -> DLSeverity -> Bool
compare :: DLSeverity -> DLSeverity -> Ordering
$ccompare :: DLSeverity -> DLSeverity -> Ordering
$cp1Ord :: Eq DLSeverity
Ord, Int -> DLSeverity -> ShowS
[DLSeverity] -> ShowS
DLSeverity -> String
(Int -> DLSeverity -> ShowS)
-> (DLSeverity -> String)
-> ([DLSeverity] -> ShowS)
-> Show DLSeverity
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DLSeverity] -> ShowS
$cshowList :: [DLSeverity] -> ShowS
show :: DLSeverity -> String
$cshow :: DLSeverity -> String
showsPrec :: Int -> DLSeverity -> ShowS
$cshowsPrec :: Int -> DLSeverity -> ShowS
Show, (forall x. DLSeverity -> Rep DLSeverity x)
-> (forall x. Rep DLSeverity x -> DLSeverity) -> Generic DLSeverity
forall x. Rep DLSeverity x -> DLSeverity
forall x. DLSeverity -> Rep DLSeverity x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DLSeverity x -> DLSeverity
$cfrom :: forall x. DLSeverity -> Rep DLSeverity x
Generic, DLSeverity -> ()
(DLSeverity -> ()) -> NFData DLSeverity
forall a. (a -> ()) -> NFData a
rnf :: DLSeverity -> ()
$crnf :: DLSeverity -> ()
NFData)
instance Yaml.FromYAML DLSeverity where
parseYAML :: Node Pos -> Parser DLSeverity
parseYAML = (DLSeverity -> Parser DLSeverity) -> Node Pos -> Parser DLSeverity
forall a. (DLSeverity -> Parser a) -> Node Pos -> Parser a
withSeverity DLSeverity -> Parser DLSeverity
forall (f :: * -> *) a. Applicative f => a -> f a
pure
withSeverity ::
(DLSeverity -> Yaml.Parser a) ->
Yaml.Node Yaml.Pos ->
Yaml.Parser a
withSeverity :: (DLSeverity -> Parser a) -> Node Pos -> Parser a
withSeverity DLSeverity -> Parser a
f v :: Node Pos
v@(Yaml.Scalar Pos
_ (Yaml.SStr Text
b)) =
case Text -> Either String DLSeverity
readEitherSeverity Text
b of
Right DLSeverity
s -> DLSeverity -> Parser a
f DLSeverity
s
Left String
_ -> String -> Node Pos -> Parser a
forall a. String -> Node Pos -> Parser a
Yaml.typeMismatch String
"severity" Node Pos
v
withSeverity DLSeverity -> Parser a
_ Node Pos
v = String -> Node Pos -> Parser a
forall a. String -> Node Pos -> Parser a
Yaml.typeMismatch String
"severity" Node Pos
v
readEitherSeverity :: Text -> Either String DLSeverity
readEitherSeverity :: Text -> Either String DLSeverity
readEitherSeverity Text
"error" = DLSeverity -> Either String DLSeverity
forall a b. b -> Either a b
Right DLSeverity
DLErrorC
readEitherSeverity Text
"warning" = DLSeverity -> Either String DLSeverity
forall a b. b -> Either a b
Right DLSeverity
DLWarningC
readEitherSeverity Text
"info" = DLSeverity -> Either String DLSeverity
forall a b. b -> Either a b
Right DLSeverity
DLInfoC
readEitherSeverity Text
"style" = DLSeverity -> Either String DLSeverity
forall a b. b -> Either a b
Right DLSeverity
DLStyleC
readEitherSeverity Text
"ignore" = DLSeverity -> Either String DLSeverity
forall a b. b -> Either a b
Right DLSeverity
DLIgnoreC
readEitherSeverity Text
"none" = DLSeverity -> Either String DLSeverity
forall a b. b -> Either a b
Right DLSeverity
DLIgnoreC
readEitherSeverity Text
t = String -> Either String DLSeverity
forall a b. a -> Either a b
Left (String
"Invalid severity: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
unpack Text
t)
readMaybeSeverity :: Text -> Maybe DLSeverity
readMaybeSeverity :: Text -> Maybe DLSeverity
readMaybeSeverity Text
"error" = DLSeverity -> Maybe DLSeverity
forall a. a -> Maybe a
Just DLSeverity
DLErrorC
readMaybeSeverity Text
"warning" = DLSeverity -> Maybe DLSeverity
forall a. a -> Maybe a
Just DLSeverity
DLWarningC
readMaybeSeverity Text
"info" = DLSeverity -> Maybe DLSeverity
forall a. a -> Maybe a
Just DLSeverity
DLInfoC
readMaybeSeverity Text
"style" = DLSeverity -> Maybe DLSeverity
forall a. a -> Maybe a
Just DLSeverity
DLStyleC
readMaybeSeverity Text
"ignore" = DLSeverity -> Maybe DLSeverity
forall a. a -> Maybe a
Just DLSeverity
DLIgnoreC
readMaybeSeverity Text
"none" = DLSeverity -> Maybe DLSeverity
forall a. a -> Maybe a
Just DLSeverity
DLIgnoreC
readMaybeSeverity Text
_ = Maybe DLSeverity
forall a. Maybe a
Nothing
instance Semigroup DLSeverity where DLSeverity
_ <> :: DLSeverity -> DLSeverity -> DLSeverity
<> DLSeverity
s2 = DLSeverity
s2
instance Monoid DLSeverity where mempty :: DLSeverity
mempty = DLSeverity
DLIgnoreC
instance Default DLSeverity where
def :: DLSeverity
def = DLSeverity
DLInfoC
instance Pretty DLSeverity where
pretty :: DLSeverity -> Doc ann
pretty DLSeverity
DLErrorC = Doc ann
"error"
pretty DLSeverity
DLWarningC = Doc ann
"warning"
pretty DLSeverity
DLInfoC = Doc ann
"info"
pretty DLSeverity
DLStyleC = Doc ann
"style"
pretty DLSeverity
DLIgnoreC = Doc ann
"ignore"
newtype RuleCode = RuleCode {RuleCode -> Text
unRuleCode :: Text}
deriving (RuleCode -> RuleCode -> Bool
(RuleCode -> RuleCode -> Bool)
-> (RuleCode -> RuleCode -> Bool) -> Eq RuleCode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RuleCode -> RuleCode -> Bool
$c/= :: RuleCode -> RuleCode -> Bool
== :: RuleCode -> RuleCode -> Bool
$c== :: RuleCode -> RuleCode -> Bool
Eq, Eq RuleCode
Eq RuleCode
-> (RuleCode -> RuleCode -> Ordering)
-> (RuleCode -> RuleCode -> Bool)
-> (RuleCode -> RuleCode -> Bool)
-> (RuleCode -> RuleCode -> Bool)
-> (RuleCode -> RuleCode -> Bool)
-> (RuleCode -> RuleCode -> RuleCode)
-> (RuleCode -> RuleCode -> RuleCode)
-> Ord RuleCode
RuleCode -> RuleCode -> Bool
RuleCode -> RuleCode -> Ordering
RuleCode -> RuleCode -> RuleCode
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: RuleCode -> RuleCode -> RuleCode
$cmin :: RuleCode -> RuleCode -> RuleCode
max :: RuleCode -> RuleCode -> RuleCode
$cmax :: RuleCode -> RuleCode -> RuleCode
>= :: RuleCode -> RuleCode -> Bool
$c>= :: RuleCode -> RuleCode -> Bool
> :: RuleCode -> RuleCode -> Bool
$c> :: RuleCode -> RuleCode -> Bool
<= :: RuleCode -> RuleCode -> Bool
$c<= :: RuleCode -> RuleCode -> Bool
< :: RuleCode -> RuleCode -> Bool
$c< :: RuleCode -> RuleCode -> Bool
compare :: RuleCode -> RuleCode -> Ordering
$ccompare :: RuleCode -> RuleCode -> Ordering
$cp1Ord :: Eq RuleCode
Ord)
instance Show RuleCode where
show :: RuleCode -> String
show RuleCode
rc = Text -> String
forall a. Show a => a -> String
show (RuleCode -> Text
unRuleCode RuleCode
rc)
instance IsString RuleCode where
fromString :: String -> RuleCode
fromString = Text -> RuleCode
RuleCode (Text -> RuleCode) -> (String -> Text) -> String -> RuleCode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
Text.pack
instance Pretty RuleCode where
pretty :: RuleCode -> Doc ann
pretty RuleCode
rc = String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (String -> Doc ann) -> String -> Doc ann
forall a b. (a -> b) -> a -> b
$ RuleCode -> String
forall a. Show a => a -> String
show RuleCode
rc
data CheckFailure = CheckFailure
{ CheckFailure -> RuleCode
code :: RuleCode,
CheckFailure -> DLSeverity
severity :: DLSeverity,
CheckFailure -> Text
message :: Text.Text,
CheckFailure -> Int
line :: Linenumber
}
deriving (Int -> CheckFailure -> ShowS
[CheckFailure] -> ShowS
CheckFailure -> String
(Int -> CheckFailure -> ShowS)
-> (CheckFailure -> String)
-> ([CheckFailure] -> ShowS)
-> Show CheckFailure
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CheckFailure] -> ShowS
$cshowList :: [CheckFailure] -> ShowS
show :: CheckFailure -> String
$cshow :: CheckFailure -> String
showsPrec :: Int -> CheckFailure -> ShowS
$cshowsPrec :: Int -> CheckFailure -> ShowS
Show, CheckFailure -> CheckFailure -> Bool
(CheckFailure -> CheckFailure -> Bool)
-> (CheckFailure -> CheckFailure -> Bool) -> Eq CheckFailure
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CheckFailure -> CheckFailure -> Bool
$c/= :: CheckFailure -> CheckFailure -> Bool
== :: CheckFailure -> CheckFailure -> Bool
$c== :: CheckFailure -> CheckFailure -> Bool
Eq)
instance Ord CheckFailure where
CheckFailure
a compare :: CheckFailure -> CheckFailure -> Ordering
`compare` CheckFailure
b = CheckFailure -> Int
line CheckFailure
a Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` CheckFailure -> Int
line CheckFailure
b
type Failures = Seq.Seq CheckFailure
data State a = State
{ State a -> Failures
failures :: Failures,
State a -> a
state :: a
}
deriving (Int -> State a -> ShowS
[State a] -> ShowS
State a -> String
(Int -> State a -> ShowS)
-> (State a -> String) -> ([State a] -> ShowS) -> Show (State a)
forall a. Show a => Int -> State a -> ShowS
forall a. Show a => [State a] -> ShowS
forall a. Show a => State a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [State a] -> ShowS
$cshowList :: forall a. Show a => [State a] -> ShowS
show :: State a -> String
$cshow :: forall a. Show a => State a -> String
showsPrec :: Int -> State a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> State a -> ShowS
Show)
type LabelName = Text.Text
data LabelType
= Email
| GitHash
| RawText
| Rfc3339
| SemVer
| Spdx
| Url
deriving (LabelType -> LabelType -> Bool
(LabelType -> LabelType -> Bool)
-> (LabelType -> LabelType -> Bool) -> Eq LabelType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LabelType -> LabelType -> Bool
$c/= :: LabelType -> LabelType -> Bool
== :: LabelType -> LabelType -> Bool
$c== :: LabelType -> LabelType -> Bool
Eq, Int -> LabelType -> ShowS
[LabelType] -> ShowS
LabelType -> String
(Int -> LabelType -> ShowS)
-> (LabelType -> String)
-> ([LabelType] -> ShowS)
-> Show LabelType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LabelType] -> ShowS
$cshowList :: [LabelType] -> ShowS
show :: LabelType -> String
$cshow :: LabelType -> String
showsPrec :: Int -> LabelType -> ShowS
$cshowsPrec :: Int -> LabelType -> ShowS
Show)
readEitherLabelType :: Text -> Either Text LabelType
readEitherLabelType :: Text -> Either Text LabelType
readEitherLabelType Text
"email" = LabelType -> Either Text LabelType
forall a b. b -> Either a b
Right LabelType
Email
readEitherLabelType Text
"hash" = LabelType -> Either Text LabelType
forall a b. b -> Either a b
Right LabelType
GitHash
readEitherLabelType Text
"text" = LabelType -> Either Text LabelType
forall a b. b -> Either a b
Right LabelType
RawText
readEitherLabelType Text
"rfc3339" = LabelType -> Either Text LabelType
forall a b. b -> Either a b
Right LabelType
Rfc3339
readEitherLabelType Text
"semver" = LabelType -> Either Text LabelType
forall a b. b -> Either a b
Right LabelType
SemVer
readEitherLabelType Text
"spdx" = LabelType -> Either Text LabelType
forall a b. b -> Either a b
Right LabelType
Spdx
readEitherLabelType Text
"url" = LabelType -> Either Text LabelType
forall a b. b -> Either a b
Right LabelType
Url
readEitherLabelType Text
"" = LabelType -> Either Text LabelType
forall a b. b -> Either a b
Right LabelType
RawText
readEitherLabelType Text
t = Text -> Either Text LabelType
forall a b. a -> Either a b
Left (Text
"invalid label type: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
t)
instance Yaml.FromYAML LabelType where
parseYAML :: Node Pos -> Parser LabelType
parseYAML = (LabelType -> Parser LabelType) -> Node Pos -> Parser LabelType
forall a. (LabelType -> Parser a) -> Node Pos -> Parser a
withLabelType LabelType -> Parser LabelType
forall (f :: * -> *) a. Applicative f => a -> f a
pure
withLabelType :: (LabelType -> Yaml.Parser a) -> Yaml.Node Yaml.Pos -> Yaml.Parser a
withLabelType :: (LabelType -> Parser a) -> Node Pos -> Parser a
withLabelType LabelType -> Parser a
f v :: Node Pos
v@(Yaml.Scalar Pos
_ (Yaml.SStr Text
b)) =
case Text -> Either Text LabelType
readEitherLabelType Text
b of
Right LabelType
lt -> LabelType -> Parser a
f LabelType
lt
Left Text
_ -> String -> Node Pos -> Parser a
forall a. String -> Node Pos -> Parser a
Yaml.typeMismatch String
"labeltype" Node Pos
v
withLabelType LabelType -> Parser a
_ Node Pos
v = String -> Node Pos -> Parser a
forall a. String -> Node Pos -> Parser a
Yaml.typeMismatch String
"labeltype" Node Pos
v
instance Pretty LabelType where
pretty :: LabelType -> Doc ann
pretty LabelType
RawText = Doc ann
"text"
pretty LabelType
Url = Doc ann
"url"
pretty LabelType
Spdx = Doc ann
"spdx"
pretty LabelType
GitHash = Doc ann
"hash"
pretty LabelType
Rfc3339 = Doc ann
"rfc3339"
pretty LabelType
SemVer = Doc ann
"semver"
pretty LabelType
Email = Doc ann
"email"
type LabelSchema = Map.Map LabelName LabelType
withLineNumber ::
(Linenumber -> t1 -> Instruction args -> t2) ->
t1 ->
InstructionPos args ->
t2
withLineNumber :: (Int -> t1 -> Instruction args -> t2)
-> t1 -> InstructionPos args -> t2
withLineNumber Int -> t1 -> Instruction args -> t2
f t1
state InstructionPos {Instruction args
$sel:instruction:InstructionPos :: forall args. InstructionPos args -> Instruction args
instruction :: Instruction args
instruction, Int
$sel:lineNumber:InstructionPos :: forall args. InstructionPos args -> Int
lineNumber :: Int
lineNumber} =
Int -> t1 -> Instruction args -> t2
f Int
lineNumber t1
state Instruction args
instruction
addFail :: CheckFailure -> State a -> State a
addFail :: CheckFailure -> State a -> State a
addFail CheckFailure
failure state :: State a
state@(State Failures
fails a
_) =
State a
state
{ failures :: Failures
failures =
Failures
fails
Failures -> CheckFailure -> Failures
forall a. Seq a -> a -> Seq a
Seq.|> CheckFailure
failure
}
emptyState :: a -> State a
emptyState :: a -> State a
emptyState = Failures -> a -> State a
forall a. Failures -> a -> State a
State Failures
forall a. Seq a
Seq.empty
simpleState :: State ()
simpleState :: State ()
simpleState = Failures -> () -> State ()
forall a. Failures -> a -> State a
State Failures
forall a. Seq a
Seq.empty ()
modify :: (a -> a) -> State a -> State a
modify :: (a -> a) -> State a -> State a
modify a -> a
f s :: State a
s@(State Failures
_ a
st) = State a
s {state :: a
state = a -> a
f a
st}
replaceWith :: a -> State a -> State a
replaceWith :: a -> State a -> State a
replaceWith a
newState State a
s = State a
s {state :: a
state = a
newState}
type Rule args = Foldl.Fold (InstructionPos args) Failures
simpleRule ::
RuleCode ->
DLSeverity ->
Text.Text ->
(Instruction args -> Bool) ->
Rule args
simpleRule :: RuleCode
-> DLSeverity -> Text -> (Instruction args -> Bool) -> Rule args
simpleRule RuleCode
code DLSeverity
severity Text
message Instruction args -> Bool
checker = (Int -> State () -> Instruction args -> State ())
-> State () -> Rule args
forall a args.
(Int -> State a -> Instruction args -> State a)
-> State a -> Rule args
customRule Int -> State () -> Instruction args -> State ()
forall a. Int -> State a -> Instruction args -> State a
step State ()
simpleState
where
step :: Int -> State a -> Instruction args -> State a
step Int
line State a
s Instruction args
instr
| Instruction args -> Bool
checker Instruction args
instr = State a
s
| Bool
otherwise = State a
s State a -> (State a -> State a) -> State a
forall a b. a -> (a -> b) -> b
|> CheckFailure -> State a -> State a
forall a. CheckFailure -> State a -> State a
addFail (RuleCode -> DLSeverity -> Text -> Int -> CheckFailure
CheckFailure RuleCode
code DLSeverity
severity Text
message Int
line)
customRule ::
(Linenumber -> State a -> Instruction args -> State a) ->
State a ->
Rule args
customRule :: (Int -> State a -> Instruction args -> State a)
-> State a -> Rule args
customRule Int -> State a -> Instruction args -> State a
step State a
initial = (Int -> State a -> Instruction args -> State a)
-> State a -> (State a -> Failures) -> Rule args
forall a args.
(Int -> State a -> Instruction args -> State a)
-> State a -> (State a -> Failures) -> Rule args
veryCustomRule Int -> State a -> Instruction args -> State a
step State a
initial State a -> Failures
forall a. State a -> Failures
failures
veryCustomRule ::
(Linenumber -> State a -> Instruction args -> State a) ->
State a ->
(State a -> Failures) ->
Rule args
veryCustomRule :: (Int -> State a -> Instruction args -> State a)
-> State a -> (State a -> Failures) -> Rule args
veryCustomRule Int -> State a -> Instruction args -> State a
step = (State a -> InstructionPos args -> State a)
-> State a -> (State a -> Failures) -> Rule args
forall a b x. (x -> a -> x) -> x -> (x -> b) -> Fold a b
Foldl.Fold ((Int -> State a -> Instruction args -> State a)
-> State a -> InstructionPos args -> State a
forall t1 args t2.
(Int -> t1 -> Instruction args -> t2)
-> t1 -> InstructionPos args -> t2
withLineNumber Int -> State a -> Instruction args -> State a
step)
foldArguments :: (a -> b) -> Arguments a -> b
foldArguments :: (a -> b) -> Arguments a -> b
foldArguments a -> b
applyRule Arguments a
args =
case Arguments a
args of
ArgumentsText a
as -> a -> b
applyRule a
as
ArgumentsList a
as -> a -> b
applyRule a
as
aliasMustBe :: (Text.Text -> Bool) -> Instruction a -> Bool
aliasMustBe :: (Text -> Bool) -> Instruction a -> Bool
aliasMustBe Text -> Bool
predicate Instruction a
fromInstr =
case Instruction a
fromInstr of
From BaseImage {$sel:alias:BaseImage :: BaseImage -> Maybe ImageAlias
alias = Just (ImageAlias Text
as)} -> Text -> Bool
predicate Text
as
Instruction a
_ -> Bool
True
archiveFileFormatExtensions :: [Text.Text]
archiveFileFormatExtensions :: [Text]
archiveFileFormatExtensions =
[ Text
".tar",
Text
".Z",
Text
".bz2",
Text
".gz",
Text
".lz",
Text
".lzma",
Text
".tZ",
Text
".tb2",
Text
".tbz",
Text
".tbz2",
Text
".tgz",
Text
".tlz",
Text
".tpz",
Text
".txz",
Text
".xz"
]
dropQuotes :: Text -> Text
dropQuotes :: Text -> Text
dropQuotes = (Char -> Bool) -> Text -> Text
Text.dropAround Char -> Bool
quotes
where
quotes :: Char -> Bool
quotes Char
'\"' = Bool
True
quotes Char
'\'' = Bool
True
quotes Char
_ = Bool
False