{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE NoMonomorphismRestriction #-}

module Language.Docker.PrettyPrint where

import Data.List.NonEmpty as NonEmpty (NonEmpty (..), toList)
import Data.Set (Set)
import Data.String (fromString)
import Data.Text (Text)
import Prettyprinter
import Prettyprinter.Internal (Doc (Empty))
import Prettyprinter.Render.Text (renderLazy)
import Language.Docker.Syntax
import Prelude hiding ((<>), (>>))
import qualified Data.Set as Set
import qualified Data.Text as Text
import qualified Data.Text.Lazy as L
import qualified Data.Text.Lazy.Builder as B

data EscapeAccum
  = EscapeAccum
      { EscapeAccum -> Builder
buffer :: !B.Builder,
        EscapeAccum -> Int
count :: !Int,
        EscapeAccum -> Bool
escaping :: !Bool
      }

-- | Pretty print a 'Dockerfile' to a 'Text'
prettyPrint :: Dockerfile -> L.Text
prettyPrint :: Dockerfile -> Text
prettyPrint = forall ann. SimpleDocStream ann -> Text
renderLazy forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutPretty LayoutOptions
opts forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall ann. Dockerfile -> Doc ann
prettyPrintDockerfile
  where
    opts :: LayoutOptions
opts = PageWidth -> LayoutOptions
LayoutOptions PageWidth
Unbounded

prettyPrintDockerfile :: [InstructionPos Text] -> Doc ann
prettyPrintDockerfile :: forall ann. Dockerfile -> Doc ann
prettyPrintDockerfile Dockerfile
instr = forall ann. Dockerfile -> Doc ann
doPrint Dockerfile
instr forall a. Semigroup a => a -> a -> a
<> Doc ann
"\n"
  where
    doPrint :: Dockerfile -> Doc ann
doPrint Dockerfile
ips =
      let ?esc = forall args. [InstructionPos args] -> Char
findEscapeChar Dockerfile
ips
       in (forall ann. [Doc ann] -> Doc ann
vsep forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall ann. (?esc::Char) => InstructionPos Text -> Doc ann
prettyPrintInstructionPos ) Dockerfile
ips

findEscapeChar ::  [InstructionPos args] -> Char
findEscapeChar :: forall args. [InstructionPos args] -> Char
findEscapeChar [] = Char
defaultEsc
findEscapeChar (InstructionPos args
i:[InstructionPos args]
is) =
  case InstructionPos args
i of
    InstructionPos {$sel:instruction:InstructionPos :: forall args. InstructionPos args -> Instruction args
instruction = (Pragma (Escape (EscapeChar Char
c)))} -> Char
c
    InstructionPos {$sel:instruction:InstructionPos :: forall args. InstructionPos args -> Instruction args
instruction = (Pragma PragmaDirective
_)} -> forall args. [InstructionPos args] -> Char
findEscapeChar [InstructionPos args]
is
    InstructionPos args
_ -> Char
defaultEsc

-- | Pretty print a 'InstructionPos' to a 'Doc'
prettyPrintInstructionPos :: (?esc :: Char) => InstructionPos Text -> Doc ann
prettyPrintInstructionPos :: forall ann. (?esc::Char) => InstructionPos Text -> Doc ann
prettyPrintInstructionPos (InstructionPos Instruction Text
i Text
_ Int
_) = forall ann. (?esc::Char) => Instruction Text -> Doc ann
prettyPrintInstruction Instruction Text
i

prettyPrintImage :: Image -> Doc ann
prettyPrintImage :: forall ann. Image -> Doc ann
prettyPrintImage (Image Maybe Registry
Nothing Text
name) = forall a ann. Pretty a => a -> Doc ann
pretty Text
name
prettyPrintImage (Image (Just (Registry Text
reg)) Text
name) = forall a ann. Pretty a => a -> Doc ann
pretty Text
reg forall a. Semigroup a => a -> a -> a
<> Doc ann
"/" forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty Text
name

prettyPrintBaseImage :: BaseImage -> Doc ann
prettyPrintBaseImage :: forall ann. BaseImage -> Doc ann
prettyPrintBaseImage BaseImage {Maybe Text
Maybe ImageAlias
Maybe Digest
Maybe Tag
Image
$sel:platform:BaseImage :: BaseImage -> Maybe Text
$sel:alias:BaseImage :: BaseImage -> Maybe ImageAlias
$sel:digest:BaseImage :: BaseImage -> Maybe Digest
$sel:tag:BaseImage :: BaseImage -> Maybe Tag
$sel:image:BaseImage :: BaseImage -> Image
platform :: Maybe Text
alias :: Maybe ImageAlias
digest :: Maybe Digest
tag :: Maybe Tag
image :: Image
..} = do
  forall {a} {ann}. Pretty a => Maybe a -> Doc ann
prettyPlatform Maybe Text
platform
  forall ann. Image -> Doc ann
prettyPrintImage Image
image
  forall {ann}. Maybe Tag -> Doc ann
prettyTag Maybe Tag
tag
  forall {ann}. Maybe Digest -> Doc ann
prettyDigest Maybe Digest
digest
  forall {ann}. Maybe ImageAlias -> Doc ann
prettyAlias Maybe ImageAlias
alias
  where
    >> :: a -> a -> a
(>>) = forall a. Semigroup a => a -> a -> a
(<>)
    prettyPlatform :: Maybe a -> Doc ann
prettyPlatform Maybe a
maybePlatform =
      case Maybe a
maybePlatform of
        Maybe a
Nothing -> forall a. Monoid a => a
mempty
        Just a
p -> Doc ann
"--platform=" forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty a
p forall a. Semigroup a => a -> a -> a
<> Doc ann
" "
    prettyTag :: Maybe Tag -> Doc ann
prettyTag Maybe Tag
maybeTag =
      case Maybe Tag
maybeTag of
        Maybe Tag
Nothing -> forall a. Monoid a => a
mempty
        Just (Tag Text
p) -> Doc ann
":" forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty Text
p
    prettyAlias :: Maybe ImageAlias -> Doc ann
prettyAlias Maybe ImageAlias
maybeAlias =
      case Maybe ImageAlias
maybeAlias of
        Maybe ImageAlias
Nothing -> forall a. Monoid a => a
mempty
        Just (ImageAlias Text
a) -> Doc ann
" AS " forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty Text
a
    prettyDigest :: Maybe Digest -> Doc ann
prettyDigest Maybe Digest
maybeDigest =
      case Maybe Digest
maybeDigest of
        Maybe Digest
Nothing -> forall a. Monoid a => a
mempty
        Just (Digest Text
d) -> Doc ann
"@" forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty Text
d

prettyPrintPairs :: (?esc :: Char) => Pairs -> Doc ann
prettyPrintPairs :: forall ann. (?esc::Char) => Pairs -> Doc ann
prettyPrintPairs Pairs
ps = forall ann. Doc ann -> Doc ann
align forall a b. (a -> b) -> a -> b
$ forall {t :: * -> *} {a} {ann}.
(Foldable t, Pretty a, ?esc::a) =>
t (Doc ann) -> Doc ann
sepLine forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall ann. (?esc::Char) => (Text, Text) -> Doc ann
prettyPrintPair Pairs
ps
  where
    sepLine :: t (Doc ann) -> Doc ann
sepLine = forall (t :: * -> *) ann.
Foldable t =>
(Doc ann -> Doc ann -> Doc ann) -> t (Doc ann) -> Doc ann
concatWith (\Doc ann
x Doc ann
y -> Doc ann
x forall a. Semigroup a => a -> a -> a
<> Doc ann
" " forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty ?esc::a
?esc forall a. Semigroup a => a -> a -> a
<> forall ann. Doc ann
line forall a. Semigroup a => a -> a -> a
<> Doc ann
y)

prettyPrintPair :: (?esc :: Char) => (Text, Text) -> Doc ann
prettyPrintPair :: forall ann. (?esc::Char) => (Text, Text) -> Doc ann
prettyPrintPair (Text
k, Text
v) = forall a ann. Pretty a => a -> Doc ann
pretty Text
k forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty Char
'=' forall a. Semigroup a => a -> a -> a
<> forall ann. (?esc::Char) => Text -> Doc ann
doubleQoute Text
v

prettyPrintArguments :: (?esc :: Char) => Arguments Text -> Doc ann
prettyPrintArguments :: forall ann. (?esc::Char) => Arguments Text -> Doc ann
prettyPrintArguments (ArgumentsList Text
as) = forall ann. (?esc::Char) => [Text] -> Doc ann
prettyPrintJSON (Text -> [Text]
Text.words Text
as)
prettyPrintArguments (ArgumentsText Text
as) = forall ann. [Doc ann] -> Doc ann
hsep (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {a} {a} {ann}.
(Eq a, IsString a, ?esc::a, Pretty a, Pretty a) =>
a -> Doc ann
helper (Text -> [Text]
Text.words Text
as))
  where
    helper :: a -> Doc ann
helper a
"&&" = forall a ann. Pretty a => a -> Doc ann
pretty ?esc::a
?esc forall a. Semigroup a => a -> a -> a
<> Doc ann
"\n &&"
    helper a
a = forall a ann. Pretty a => a -> Doc ann
pretty a
a

prettyPrintJSON :: (?esc :: Char) => [Text] -> Doc ann
prettyPrintJSON :: forall ann. (?esc::Char) => [Text] -> Doc ann
prettyPrintJSON [Text]
args = forall ann. [Doc ann] -> Doc ann
list (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall ann. (?esc::Char) => Text -> Doc ann
doubleQoute [Text]
args)

doubleQoute :: (?esc :: Char) => Text -> Doc ann
doubleQoute :: forall ann. (?esc::Char) => Text -> Doc ann
doubleQoute Text
w = forall ann. Doc ann -> Doc ann -> Doc ann -> Doc ann
enclose forall ann. Doc ann
dquote forall ann. Doc ann
dquote (forall a ann. Pretty a => a -> Doc ann
pretty ((?esc::Char) => Text -> Text
escapeQuotes Text
w))

escapeQuotes :: (?esc :: Char) => Text -> L.Text
escapeQuotes :: (?esc::Char) => Text -> Text
escapeQuotes Text
text =
  case forall a. (Char -> a -> a) -> a -> Text -> a
Text.foldr (?esc::Char) => Char -> EscapeAccum -> EscapeAccum
accumulate (Builder -> Int -> Bool -> EscapeAccum
EscapeAccum forall a. Monoid a => a
mempty Int
0 Bool
False) Text
text of
    EscapeAccum Builder
buffer Int
_ Bool
False -> Builder -> Text
B.toLazyText Builder
buffer
    EscapeAccum Builder
buffer Int
count Bool
True ->
      case Int
count forall a. Integral a => a -> a -> a
`mod` Int
2 of
        Int
0 -> Builder -> Text
B.toLazyText (Char -> Builder
B.singleton ?esc::Char
?esc forall a. Semigroup a => a -> a -> a
<> Builder
buffer)
        Int
_ -> Builder -> Text
B.toLazyText Builder
buffer
  where
    accumulate :: Char -> EscapeAccum -> EscapeAccum
accumulate Char
'"' EscapeAccum {Builder
buffer :: Builder
$sel:buffer:EscapeAccum :: EscapeAccum -> Builder
buffer, $sel:escaping:EscapeAccum :: EscapeAccum -> Bool
escaping = Bool
False} =
      Builder -> Int -> Bool -> EscapeAccum
EscapeAccum (Char -> Builder
B.singleton Char
'"' forall a. Semigroup a => a -> a -> a
<> Builder
buffer) Int
0 Bool
True
    accumulate Char
c EscapeAccum {Builder
buffer :: Builder
$sel:buffer:EscapeAccum :: EscapeAccum -> Builder
buffer, $sel:escaping:EscapeAccum :: EscapeAccum -> Bool
escaping = Bool
True, Int
count :: Int
$sel:count:EscapeAccum :: EscapeAccum -> Int
count}
      | Char
c forall a. Eq a => a -> a -> Bool
== ?esc::Char
?esc = Builder -> Int -> Bool -> EscapeAccum
EscapeAccum (Char -> Builder
B.singleton ?esc::Char
?esc forall a. Semigroup a => a -> a -> a
<> Builder
buffer) (Int
count forall a. Num a => a -> a -> a
+ Int
1) Bool
True
      | forall a. Integral a => a -> Bool
even Int
count = Builder -> Int -> Bool -> EscapeAccum
EscapeAccum (Char -> Builder
B.singleton Char
c forall a. Semigroup a => a -> a -> a
<> Char -> Builder
B.singleton ?esc::Char
?esc forall a. Semigroup a => a -> a -> a
<> Builder
buffer) Int
0 Bool
False
      | Bool
otherwise = Builder -> Int -> Bool -> EscapeAccum
EscapeAccum (Char -> Builder
B.singleton Char
c forall a. Semigroup a => a -> a -> a
<> Builder
buffer) Int
0 Bool
False -- It was already escaped
    accumulate Char
c EscapeAccum {Builder
buffer :: Builder
$sel:buffer:EscapeAccum :: EscapeAccum -> Builder
buffer, $sel:escaping:EscapeAccum :: EscapeAccum -> Bool
escaping = Bool
False} =
      Builder -> Int -> Bool -> EscapeAccum
EscapeAccum (Char -> Builder
B.singleton Char
c forall a. Semigroup a => a -> a -> a
<> Builder
buffer) Int
0 Bool
False

prettyPrintPortSpec :: PortSpec -> Doc ann
prettyPrintPortSpec :: forall ann. PortSpec -> Doc ann
prettyPrintPortSpec (PortSpec Port
port) = forall a ann. Pretty a => a -> Doc ann
pretty Port
port
prettyPrintPortSpec (PortRangeSpec PortRange
portrange) = forall a ann. Pretty a => a -> Doc ann
pretty PortRange
portrange

prettyPrintFileList :: NonEmpty SourcePath -> TargetPath -> Doc ann
prettyPrintFileList :: forall ann. NonEmpty SourcePath -> TargetPath -> Doc ann
prettyPrintFileList NonEmpty SourcePath
sources (TargetPath Text
dest) =
  let ending :: a
ending =
        case (Text -> Text -> Bool
Text.isSuffixOf Text
"/" Text
dest, NonEmpty SourcePath
sources) of
          (Bool
True, NonEmpty SourcePath
_) -> a
"" -- If the target ends with / then no extra ending is needed
          (Bool
_, SourcePath
_fst :| SourcePath
_snd : [SourcePath]
_) -> a
"/" -- More than one source means that the target should end in /
          (Bool, NonEmpty SourcePath)
_ -> a
""
   in forall ann. [Doc ann] -> Doc ann
hsep forall a b. (a -> b) -> a -> b
$ [forall a ann. Pretty a => a -> Doc ann
pretty Text
s | SourcePath Text
s <- forall a. NonEmpty a -> [a]
toList NonEmpty SourcePath
sources] forall a. [a] -> [a] -> [a]
++ [forall a ann. Pretty a => a -> Doc ann
pretty Text
dest forall a. Semigroup a => a -> a -> a
<> forall {a}. IsString a => a
ending]

prettyPrintChown :: Chown -> Doc ann
prettyPrintChown :: forall ann. Chown -> Doc ann
prettyPrintChown Chown
chown =
  case Chown
chown of
    Chown Text
c -> Doc ann
"--chown=" forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty Text
c
    Chown
NoChown -> forall a. Monoid a => a
mempty

prettyPrintChmod :: Chmod -> Doc ann
prettyPrintChmod :: forall ann. Chmod -> Doc ann
prettyPrintChmod Chmod
chmod =
  case Chmod
chmod of
    Chmod Text
c -> Doc ann
"--chmod=" forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty Text
c
    Chmod
NoChmod -> forall a. Monoid a => a
mempty

prettyPrintLink :: Link -> Doc ann
prettyPrintLink :: forall ann. Link -> Doc ann
prettyPrintLink Link
link =
  case Link
link of
    Link
Link -> Doc ann
"--link"
    Link
NoLink -> forall a. Monoid a => a
mempty

prettyPrintCopySource :: CopySource -> Doc ann
prettyPrintCopySource :: forall ann. CopySource -> Doc ann
prettyPrintCopySource CopySource
source =
  case CopySource
source of
    CopySource Text
c -> Doc ann
"--from=" forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty Text
c
    CopySource
NoSource -> forall a. Monoid a => a
mempty

prettyPrintDuration :: Text -> Maybe Duration -> Doc ann
prettyPrintDuration :: forall ann. Text -> Maybe Duration -> Doc ann
prettyPrintDuration Text
flagName = forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {ann}. Duration -> Doc ann
pp
  where
    pp :: Duration -> Doc ann
pp (Duration DiffTime
d) = forall a ann. Pretty a => a -> Doc ann
pretty Text
flagName forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty (forall a. Show a => a -> String
show DiffTime
d)

prettyPrintRetries :: Maybe Retries -> Doc ann
prettyPrintRetries :: forall ann. Maybe Retries -> Doc ann
prettyPrintRetries = forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {ann}. Retries -> Doc ann
pp
  where
    pp :: Retries -> Doc ann
pp (Retries Int
r) = Doc ann
"--retries=" forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty Int
r

prettyPrintRunMount :: (?esc :: Char) => Set RunMount -> Doc ann
prettyPrintRunMount :: forall ann. (?esc::Char) => Set RunMount -> Doc ann
prettyPrintRunMount Set RunMount
set =
  forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl forall a. Semigroup a => a -> a -> a
(<>) Doc ann
"" (forall a b. (a -> b) -> [a] -> [b]
map forall {ann}. (?esc::Char) => RunMount -> Doc ann
printSingleMount (forall a. Set a -> [a]
Set.toList Set RunMount
set))
  where
    printSingleMount :: RunMount -> Doc ann
printSingleMount RunMount
mount = Doc ann
"--mount="
      forall a. Semigroup a => a -> a -> a
<> case RunMount
mount of
        BindMount BindOpts {Maybe Bool
Maybe Text
Maybe SourcePath
TargetPath
$sel:bReadOnly:BindOpts :: BindOpts -> Maybe Bool
$sel:bFromImage:BindOpts :: BindOpts -> Maybe Text
$sel:bSource:BindOpts :: BindOpts -> Maybe SourcePath
$sel:bTarget:BindOpts :: BindOpts -> TargetPath
bReadOnly :: Maybe Bool
bFromImage :: Maybe Text
bSource :: Maybe SourcePath
bTarget :: TargetPath
..} ->
          Doc ann
"type=bind"
            forall a. Semigroup a => a -> a -> a
<> forall {ann}. (?esc::Char) => TargetPath -> Doc ann
printTarget TargetPath
bTarget
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {ann}. (?esc::Char) => SourcePath -> Doc ann
printSource Maybe SourcePath
bSource
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall ann. (?esc::Char) => Text -> Doc ann
printFromImage Maybe Text
bFromImage
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {a}. IsString a => Bool -> a
printReadOnly Maybe Bool
bReadOnly
        CacheMount CacheOpts {Maybe Bool
Maybe Text
Maybe CacheSharing
Maybe SourcePath
TargetPath
$sel:cGid:CacheOpts :: CacheOpts -> Maybe Text
$sel:cUid:CacheOpts :: CacheOpts -> Maybe Text
$sel:cMode:CacheOpts :: CacheOpts -> Maybe Text
$sel:cSource:CacheOpts :: CacheOpts -> Maybe SourcePath
$sel:cFromImage:CacheOpts :: CacheOpts -> Maybe Text
$sel:cReadOnly:CacheOpts :: CacheOpts -> Maybe Bool
$sel:cCacheId:CacheOpts :: CacheOpts -> Maybe Text
$sel:cSharing:CacheOpts :: CacheOpts -> Maybe CacheSharing
$sel:cTarget:CacheOpts :: CacheOpts -> TargetPath
cGid :: Maybe Text
cUid :: Maybe Text
cMode :: Maybe Text
cSource :: Maybe SourcePath
cFromImage :: Maybe Text
cReadOnly :: Maybe Bool
cCacheId :: Maybe Text
cSharing :: Maybe CacheSharing
cTarget :: TargetPath
..} ->
          Doc ann
"type=cache"
            forall a. Semigroup a => a -> a -> a
<> forall {ann}. (?esc::Char) => TargetPath -> Doc ann
printTarget TargetPath
cTarget
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {a}. (Semigroup a, IsString a) => CacheSharing -> a
printSharing Maybe CacheSharing
cSharing
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall ann. (?esc::Char) => Text -> Doc ann
printId Maybe Text
cCacheId
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall ann. (?esc::Char) => Text -> Doc ann
printFromImage Maybe Text
cFromImage
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {ann}. (?esc::Char) => SourcePath -> Doc ann
printSource Maybe SourcePath
cSource
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {a} {ann}. Pretty a => a -> Doc ann
printMode Maybe Text
cMode
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {a} {ann}. Pretty a => a -> Doc ann
printUid Maybe Text
cUid
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {a} {ann}. Pretty a => a -> Doc ann
printGid Maybe Text
cGid
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {a}. IsString a => Bool -> a
printReadOnly Maybe Bool
cReadOnly
        SshMount SecretOpts {Maybe Bool
Maybe Text
Maybe TargetPath
Maybe SourcePath
$sel:sGid:SecretOpts :: SecretOpts -> Maybe Text
$sel:sUid:SecretOpts :: SecretOpts -> Maybe Text
$sel:sMode:SecretOpts :: SecretOpts -> Maybe Text
$sel:sSource:SecretOpts :: SecretOpts -> Maybe SourcePath
$sel:sIsRequired:SecretOpts :: SecretOpts -> Maybe Bool
$sel:sCacheId:SecretOpts :: SecretOpts -> Maybe Text
$sel:sTarget:SecretOpts :: SecretOpts -> Maybe TargetPath
sGid :: Maybe Text
sUid :: Maybe Text
sMode :: Maybe Text
sSource :: Maybe SourcePath
sIsRequired :: Maybe Bool
sCacheId :: Maybe Text
sTarget :: Maybe TargetPath
..} ->
          Doc ann
"type=ssh"
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {ann}. (?esc::Char) => TargetPath -> Doc ann
printTarget Maybe TargetPath
sTarget
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall ann. (?esc::Char) => Text -> Doc ann
printId Maybe Text
sCacheId
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {ann}. (?esc::Char) => SourcePath -> Doc ann
printSource Maybe SourcePath
sSource
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {a} {ann}. Pretty a => a -> Doc ann
printMode Maybe Text
sMode
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {a} {ann}. Pretty a => a -> Doc ann
printUid Maybe Text
sUid
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {a} {ann}. Pretty a => a -> Doc ann
printGid Maybe Text
sGid
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {a}. (IsString a, Monoid a) => Bool -> a
printRequired Maybe Bool
sIsRequired
        SecretMount SecretOpts {Maybe Bool
Maybe Text
Maybe TargetPath
Maybe SourcePath
sGid :: Maybe Text
sUid :: Maybe Text
sMode :: Maybe Text
sSource :: Maybe SourcePath
sIsRequired :: Maybe Bool
sCacheId :: Maybe Text
sTarget :: Maybe TargetPath
$sel:sGid:SecretOpts :: SecretOpts -> Maybe Text
$sel:sUid:SecretOpts :: SecretOpts -> Maybe Text
$sel:sMode:SecretOpts :: SecretOpts -> Maybe Text
$sel:sSource:SecretOpts :: SecretOpts -> Maybe SourcePath
$sel:sIsRequired:SecretOpts :: SecretOpts -> Maybe Bool
$sel:sCacheId:SecretOpts :: SecretOpts -> Maybe Text
$sel:sTarget:SecretOpts :: SecretOpts -> Maybe TargetPath
..} ->
          Doc ann
"type=secret"
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {ann}. (?esc::Char) => TargetPath -> Doc ann
printTarget Maybe TargetPath
sTarget
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall ann. (?esc::Char) => Text -> Doc ann
printId Maybe Text
sCacheId
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {ann}. (?esc::Char) => SourcePath -> Doc ann
printSource Maybe SourcePath
sSource
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {a} {ann}. Pretty a => a -> Doc ann
printMode Maybe Text
sMode
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {a} {ann}. Pretty a => a -> Doc ann
printUid Maybe Text
sUid
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {a} {ann}. Pretty a => a -> Doc ann
printGid Maybe Text
sGid
            forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall {a}. (IsString a, Monoid a) => Bool -> a
printRequired Maybe Bool
sIsRequired
        TmpfsMount TmpOpts {TargetPath
$sel:tTarget:TmpOpts :: TmpOpts -> TargetPath
tTarget :: TargetPath
..} -> Doc ann
"type=tmpfs" forall a. Semigroup a => a -> a -> a
<> forall {ann}. (?esc::Char) => TargetPath -> Doc ann
printTarget TargetPath
tTarget
    printQuotable :: Text -> Doc ann
printQuotable Text
str
      | (Char -> Bool) -> Text -> Bool
Text.any (forall a. Eq a => a -> a -> Bool
== Char
'"') Text
str = forall ann. (?esc::Char) => Text -> Doc ann
doubleQoute Text
str
      | Bool
otherwise = forall a ann. Pretty a => a -> Doc ann
pretty Text
str
    printTarget :: TargetPath -> Doc ann
printTarget (TargetPath Text
t) = Doc ann
",target=" forall a. Semigroup a => a -> a -> a
<> forall ann. (?esc::Char) => Text -> Doc ann
printQuotable Text
t
    printSource :: SourcePath -> Doc ann
printSource (SourcePath Text
s) = Doc ann
",source=" forall a. Semigroup a => a -> a -> a
<> forall ann. (?esc::Char) => Text -> Doc ann
printQuotable Text
s
    printFromImage :: Text -> Doc ann
printFromImage Text
f = Doc ann
",from=" forall a. Semigroup a => a -> a -> a
<> forall ann. (?esc::Char) => Text -> Doc ann
printQuotable Text
f
    printSharing :: CacheSharing -> a
printSharing CacheSharing
sharing = a
",sharing="
      forall a. Semigroup a => a -> a -> a
<> case CacheSharing
sharing of
        CacheSharing
Shared -> a
"shared"
        CacheSharing
Private -> a
"private"
        CacheSharing
Locked -> a
"locked"
    printId :: Text -> Doc ann
printId Text
i = Doc ann
",id=" forall a. Semigroup a => a -> a -> a
<> forall ann. (?esc::Char) => Text -> Doc ann
printQuotable Text
i
    printMode :: a -> Doc ann
printMode a
m = Doc ann
",mode=" forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty a
m
    printUid :: a -> Doc ann
printUid a
uid = Doc ann
",uid=" forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty a
uid
    printGid :: a -> Doc ann
printGid a
gid = Doc ann
",gid=" forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty a
gid
    printReadOnly :: Bool -> a
printReadOnly Bool
True = a
",ro"
    printReadOnly Bool
False = a
",rw"
    printRequired :: Bool -> a
printRequired Bool
True = a
",required"
    printRequired Bool
False = forall a. Monoid a => a
mempty

prettyPrintRunNetwork :: Maybe RunNetwork -> Doc ann
prettyPrintRunNetwork :: forall ann. Maybe RunNetwork -> Doc ann
prettyPrintRunNetwork Maybe RunNetwork
Nothing = forall a. Monoid a => a
mempty
prettyPrintRunNetwork (Just RunNetwork
NetworkHost) = Doc ann
"--network=host"
prettyPrintRunNetwork (Just RunNetwork
NetworkNone) = Doc ann
"--network=none"
prettyPrintRunNetwork (Just RunNetwork
NetworkDefault) = Doc ann
"--network=default"

prettyPrintRunSecurity :: Maybe RunSecurity -> Doc ann
prettyPrintRunSecurity :: forall ann. Maybe RunSecurity -> Doc ann
prettyPrintRunSecurity Maybe RunSecurity
Nothing = forall a. Monoid a => a
mempty
prettyPrintRunSecurity (Just RunSecurity
Sandbox) = Doc ann
"--security=sandbox"
prettyPrintRunSecurity (Just RunSecurity
Insecure) = Doc ann
"--security=insecure"

prettyPrintPragma :: PragmaDirective -> Doc ann
prettyPrintPragma :: forall ann. PragmaDirective -> Doc ann
prettyPrintPragma (Escape (EscapeChar Char
esc)) = Doc ann
"escape = " forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty Char
esc
prettyPrintPragma (Syntax (SyntaxImage Image
img)) = Doc ann
"syntax = " forall a. Semigroup a => a -> a -> a
<> forall ann. Image -> Doc ann
prettyPrintImage Image
img

prettyPrintInstruction :: (?esc :: Char) => Instruction Text -> Doc ann
prettyPrintInstruction :: forall ann. (?esc::Char) => Instruction Text -> Doc ann
prettyPrintInstruction Instruction Text
i =
  case Instruction Text
i of
    Maintainer Text
m -> do
      Doc ann
"MAINTAINER"
      forall a ann. Pretty a => a -> Doc ann
pretty Text
m
    Arg Text
a Maybe Text
Nothing -> do
      Doc ann
"ARG"
      forall a ann. Pretty a => a -> Doc ann
pretty Text
a
    Arg Text
k (Just Text
v) -> do
      Doc ann
"ARG"
      forall a ann. Pretty a => a -> Doc ann
pretty Text
k forall a. Semigroup a => a -> a -> a
<> Doc ann
"=" forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty Text
v
    Entrypoint Arguments Text
e -> do
      Doc ann
"ENTRYPOINT"
      forall ann. (?esc::Char) => Arguments Text -> Doc ann
prettyPrintArguments Arguments Text
e
    Stopsignal Text
s -> do
      Doc ann
"STOPSIGNAL"
      forall a ann. Pretty a => a -> Doc ann
pretty Text
s
    Workdir Text
w -> do
      Doc ann
"WORKDIR"
      forall a ann. Pretty a => a -> Doc ann
pretty Text
w
    Expose (Ports [PortSpec]
ps) -> do
      Doc ann
"EXPOSE"
      forall ann. [Doc ann] -> Doc ann
hsep (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall ann. PortSpec -> Doc ann
prettyPrintPortSpec [PortSpec]
ps)
    Volume Text
dir -> do
      Doc ann
"VOLUME"
      forall a ann. Pretty a => a -> Doc ann
pretty Text
dir
    Run (RunArgs Arguments Text
c RunFlags {Set RunMount
$sel:mount:RunFlags :: RunFlags -> Set RunMount
mount :: Set RunMount
mount, Maybe RunNetwork
$sel:network:RunFlags :: RunFlags -> Maybe RunNetwork
network :: Maybe RunNetwork
network, Maybe RunSecurity
$sel:security:RunFlags :: RunFlags -> Maybe RunSecurity
security :: Maybe RunSecurity
security}) -> do
      Doc ann
"RUN"
      forall ann. (?esc::Char) => Set RunMount -> Doc ann
prettyPrintRunMount Set RunMount
mount
      forall ann. Maybe RunNetwork -> Doc ann
prettyPrintRunNetwork Maybe RunNetwork
network
      forall ann. Maybe RunSecurity -> Doc ann
prettyPrintRunSecurity Maybe RunSecurity
security
      forall ann. (?esc::Char) => Arguments Text -> Doc ann
prettyPrintArguments Arguments Text
c
    Copy
      CopyArgs {NonEmpty SourcePath
$sel:sourcePaths:CopyArgs :: CopyArgs -> NonEmpty SourcePath
sourcePaths :: NonEmpty SourcePath
sourcePaths, TargetPath
$sel:targetPath:CopyArgs :: CopyArgs -> TargetPath
targetPath :: TargetPath
targetPath}
      CopyFlags {Chmod
$sel:chmodFlag:CopyFlags :: CopyFlags -> Chmod
chmodFlag :: Chmod
chmodFlag, Chown
$sel:chownFlag:CopyFlags :: CopyFlags -> Chown
chownFlag :: Chown
chownFlag, Link
$sel:linkFlag:CopyFlags :: CopyFlags -> Link
linkFlag :: Link
linkFlag, CopySource
$sel:sourceFlag:CopyFlags :: CopyFlags -> CopySource
sourceFlag :: CopySource
sourceFlag} -> do
        Doc ann
"COPY"
        forall ann. Chown -> Doc ann
prettyPrintChown Chown
chownFlag
        forall ann. Chmod -> Doc ann
prettyPrintChmod Chmod
chmodFlag
        forall ann. Link -> Doc ann
prettyPrintLink Link
linkFlag
        forall ann. CopySource -> Doc ann
prettyPrintCopySource CopySource
sourceFlag
        forall ann. NonEmpty SourcePath -> TargetPath -> Doc ann
prettyPrintFileList NonEmpty SourcePath
sourcePaths TargetPath
targetPath
    Cmd Arguments Text
c -> do
      Doc ann
"CMD"
      forall ann. (?esc::Char) => Arguments Text -> Doc ann
prettyPrintArguments Arguments Text
c
    Label Pairs
l -> do
      Doc ann
"LABEL"
      forall ann. (?esc::Char) => Pairs -> Doc ann
prettyPrintPairs Pairs
l
    Env Pairs
ps -> do
      Doc ann
"ENV"
      forall ann. (?esc::Char) => Pairs -> Doc ann
prettyPrintPairs Pairs
ps
    User Text
u -> do
      Doc ann
"USER"
      forall a ann. Pretty a => a -> Doc ann
pretty Text
u
    Pragma PragmaDirective
p -> do
      forall a ann. Pretty a => a -> Doc ann
pretty Char
'#'
      forall ann. PragmaDirective -> Doc ann
prettyPrintPragma PragmaDirective
p
    Comment Text
s -> do
      forall a ann. Pretty a => a -> Doc ann
pretty Char
'#'
      forall a ann. Pretty a => a -> Doc ann
pretty Text
s
    OnBuild Instruction Text
i' -> do
      Doc ann
"ONBUILD"
      forall ann. (?esc::Char) => Instruction Text -> Doc ann
prettyPrintInstruction Instruction Text
i'
    From BaseImage
b -> do
      Doc ann
"FROM"
      forall ann. BaseImage -> Doc ann
prettyPrintBaseImage BaseImage
b
    Add
      AddArgs {NonEmpty SourcePath
$sel:sourcePaths:AddArgs :: AddArgs -> NonEmpty SourcePath
sourcePaths :: NonEmpty SourcePath
sourcePaths, TargetPath
$sel:targetPath:AddArgs :: AddArgs -> TargetPath
targetPath :: TargetPath
targetPath}
      AddFlags {Chown
$sel:chownFlag:AddFlags :: AddFlags -> Chown
chownFlag :: Chown
chownFlag, Chmod
$sel:chmodFlag:AddFlags :: AddFlags -> Chmod
chmodFlag :: Chmod
chmodFlag, Link
$sel:linkFlag:AddFlags :: AddFlags -> Link
linkFlag :: Link
linkFlag} -> do
        Doc ann
"ADD"
        forall ann. Chown -> Doc ann
prettyPrintChown Chown
chownFlag
        forall ann. Chmod -> Doc ann
prettyPrintChmod Chmod
chmodFlag
        forall ann. Link -> Doc ann
prettyPrintLink Link
linkFlag
        forall ann. NonEmpty SourcePath -> TargetPath -> Doc ann
prettyPrintFileList NonEmpty SourcePath
sourcePaths TargetPath
targetPath
    Shell Arguments Text
args -> do
      Doc ann
"SHELL"
      forall ann. (?esc::Char) => Arguments Text -> Doc ann
prettyPrintArguments Arguments Text
args
    Healthcheck Check Text
NoCheck -> Doc ann
"HEALTHCHECK NONE"
    Healthcheck (Check CheckArgs {Maybe Retries
Maybe Duration
Arguments Text
$sel:retries:CheckArgs :: forall args. CheckArgs args -> Maybe Retries
$sel:startPeriod:CheckArgs :: forall args. CheckArgs args -> Maybe Duration
$sel:timeout:CheckArgs :: forall args. CheckArgs args -> Maybe Duration
$sel:interval:CheckArgs :: forall args. CheckArgs args -> Maybe Duration
$sel:checkCommand:CheckArgs :: forall args. CheckArgs args -> Arguments args
retries :: Maybe Retries
startPeriod :: Maybe Duration
timeout :: Maybe Duration
interval :: Maybe Duration
checkCommand :: Arguments Text
..}) -> do
      Doc ann
"HEALTHCHECK"
      forall ann. Text -> Maybe Duration -> Doc ann
prettyPrintDuration Text
"--interval=" Maybe Duration
interval
      forall ann. Text -> Maybe Duration -> Doc ann
prettyPrintDuration Text
"--timeout=" Maybe Duration
timeout
      forall ann. Text -> Maybe Duration -> Doc ann
prettyPrintDuration Text
"--start-period=" Maybe Duration
startPeriod
      forall ann. Maybe Retries -> Doc ann
prettyPrintRetries Maybe Retries
retries
      Doc ann
"CMD"
      forall ann. (?esc::Char) => Arguments Text -> Doc ann
prettyPrintArguments Arguments Text
checkCommand
  where
    >> :: Doc ann -> Doc ann -> Doc ann
(>>) = forall ann. Doc ann -> Doc ann -> Doc ann
spaceCat

spaceCat :: Doc ann -> Doc ann -> Doc ann
spaceCat :: forall ann. Doc ann -> Doc ann -> Doc ann
spaceCat Doc ann
a Doc ann
Empty = Doc ann
a
spaceCat Doc ann
Empty Doc ann
b = Doc ann
b
spaceCat Doc ann
a Doc ann
b = Doc ann
a forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
b