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

module Language.Docker.PrettyPrint where

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

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

instance Pretty (Arguments Text) where
  pretty :: Arguments Text -> Doc ann
pretty = Arguments Text -> Doc ann
forall ann. Arguments Text -> Doc ann
prettyPrintArguments

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

prettyPrintDockerfile :: Pretty (Arguments args) => [InstructionPos args] -> Doc ann
prettyPrintDockerfile :: [InstructionPos args] -> Doc ann
prettyPrintDockerfile [InstructionPos args]
instr = [InstructionPos args] -> Doc ann
forall args ann.
Pretty (Arguments args) =>
[InstructionPos args] -> Doc ann
doPrint [InstructionPos args]
instr Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"\n"
  where
    doPrint :: [InstructionPos args] -> Doc ann
doPrint = [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vsep ([Doc ann] -> Doc ann)
-> ([InstructionPos args] -> [Doc ann])
-> [InstructionPos args]
-> Doc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InstructionPos args -> Doc ann)
-> [InstructionPos args] -> [Doc ann]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap InstructionPos args -> Doc ann
forall args ann.
Pretty (Arguments args) =>
InstructionPos args -> Doc ann
prettyPrintInstructionPos

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

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

prettyPrintBaseImage :: BaseImage -> Doc ann
prettyPrintBaseImage :: 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
  Maybe Text -> Doc ann
forall a ann. Pretty a => Maybe a -> Doc ann
prettyPlatform Maybe Text
platform
  Image -> Doc ann
forall ann. Image -> Doc ann
prettyPrintImage Image
image
  Maybe Tag -> Doc ann
forall ann. Maybe Tag -> Doc ann
prettyTag Maybe Tag
tag
  Maybe Digest -> Doc ann
forall ann. Maybe Digest -> Doc ann
prettyDigest Maybe Digest
digest
  Maybe ImageAlias -> Doc ann
forall ann. Maybe ImageAlias -> Doc ann
prettyAlias Maybe ImageAlias
alias
  where
    >> :: a -> a -> a
(>>) = 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 -> Doc ann
forall a. Monoid a => a
mempty
        Just a
p -> Doc ann
"--platform=" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty a
p Doc ann -> Doc ann -> Doc ann
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 -> Doc ann
forall a. Monoid a => a
mempty
        Just (Tag Text
p) -> Doc ann
":" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
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 -> Doc ann
forall a. Monoid a => a
mempty
        Just (ImageAlias Text
a) -> Doc ann
" AS " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
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 -> Doc ann
forall a. Monoid a => a
mempty
        Just (Digest Text
d) -> Doc ann
"@" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Text
d

prettyPrintPairs :: Pairs -> Doc ann
prettyPrintPairs :: Pairs -> Doc ann
prettyPrintPairs Pairs
ps = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
align (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ [Doc ann] -> Doc ann
forall (t :: * -> *) ann. Foldable t => t (Doc ann) -> Doc ann
sepLine ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ ((Text, Text) -> Doc ann) -> Pairs -> [Doc ann]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text, Text) -> Doc ann
forall ann. (Text, Text) -> Doc ann
prettyPrintPair Pairs
ps
  where
    sepLine :: t (Doc ann) -> Doc ann
sepLine = (Doc ann -> Doc ann -> Doc ann) -> t (Doc ann) -> Doc ann
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 Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
" \\" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
forall ann. Doc ann
line Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
y)

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

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

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

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

escapeQuotes :: Text -> L.Text
escapeQuotes :: Text -> Text
escapeQuotes Text
text =
  case (Char -> EscapeAccum -> EscapeAccum)
-> EscapeAccum -> Text -> EscapeAccum
forall a. (Char -> a -> a) -> a -> Text -> a
Text.foldr Char -> EscapeAccum -> EscapeAccum
accumulate (Builder -> Int -> Bool -> EscapeAccum
EscapeAccum Builder
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 Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
2 of
        Int
0 -> Builder -> Text
B.toLazyText (Char -> Builder
B.singleton Char
'\\' Builder -> Builder -> Builder
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
'"' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
buffer) Int
0 Bool
True
    accumulate Char
'\\' 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} =
      Builder -> Int -> Bool -> EscapeAccum
EscapeAccum (Char -> Builder
B.singleton Char
'\\' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
buffer) (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) 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}
      | Int
count Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Builder -> Int -> Bool -> EscapeAccum
EscapeAccum (Char -> Builder
B.singleton Char
c Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Char -> Builder
B.singleton Char
'\\' Builder -> Builder -> Builder
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 Builder -> Builder -> Builder
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 Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
buffer) Int
0 Bool
False

prettyPrintPort :: Port -> Doc ann
prettyPrintPort :: Port -> Doc ann
prettyPrintPort (PortStr Text
str) = Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Text
str
prettyPrintPort (PortRange Int
start Int
stop Protocol
TCP) = Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
start Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"-" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
stop
prettyPrintPort (PortRange Int
start Int
stop Protocol
UDP) = Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
start Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"-" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
stop Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"/udp"
prettyPrintPort (Port Int
num Protocol
TCP) = Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
num Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"/tcp"
prettyPrintPort (Port Int
num Protocol
UDP) = Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Int
num Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"/udp"

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

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

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

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

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

prettyPrintRunMount :: Maybe RunMount -> Doc ann
prettyPrintRunMount :: Maybe RunMount -> Doc ann
prettyPrintRunMount Maybe RunMount
Nothing = Doc ann
forall a. Monoid a => a
mempty
prettyPrintRunMount (Just RunMount
mount) = Doc ann
"--mount="
  Doc ann -> Doc ann -> Doc ann
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"
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> TargetPath -> Doc ann
forall ann. TargetPath -> Doc ann
printTarget TargetPath
bTarget
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (SourcePath -> Doc ann) -> Maybe SourcePath -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty SourcePath -> Doc ann
forall ann. SourcePath -> Doc ann
printSource Maybe SourcePath
bSource
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Text -> Doc ann) -> Maybe Text -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Text -> Doc ann
forall ann. Text -> Doc ann
printFromImage Maybe Text
bFromImage
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Bool -> Doc ann) -> Maybe Bool -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Bool -> Doc ann
forall p. IsString p => Bool -> p
printReadOnly Maybe Bool
bReadOnly
    CacheMount CacheOpts {Maybe Bool
Maybe Integer
Maybe Text
Maybe CacheSharing
Maybe SourcePath
TargetPath
$sel:cGid:CacheOpts :: CacheOpts -> Maybe Integer
$sel:cUid:CacheOpts :: CacheOpts -> Maybe Integer
$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 Integer
cUid :: Maybe Integer
cMode :: Maybe Text
cSource :: Maybe SourcePath
cFromImage :: Maybe Text
cReadOnly :: Maybe Bool
cCacheId :: Maybe Text
cSharing :: Maybe CacheSharing
cTarget :: TargetPath
..} ->
      Doc ann
"type=cache"
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> TargetPath -> Doc ann
forall ann. TargetPath -> Doc ann
printTarget TargetPath
cTarget
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
-> (CacheSharing -> Doc ann) -> Maybe CacheSharing -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty CacheSharing -> Doc ann
forall a. (Semigroup a, IsString a) => CacheSharing -> a
printSharing Maybe CacheSharing
cSharing
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Text -> Doc ann) -> Maybe Text -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Text -> Doc ann
forall ann. Text -> Doc ann
printId Maybe Text
cCacheId
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Text -> Doc ann) -> Maybe Text -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Text -> Doc ann
forall ann. Text -> Doc ann
printFromImage Maybe Text
cFromImage
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (SourcePath -> Doc ann) -> Maybe SourcePath -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty SourcePath -> Doc ann
forall ann. SourcePath -> Doc ann
printSource Maybe SourcePath
cSource
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Text -> Doc ann) -> Maybe Text -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
printMode Maybe Text
cMode
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Integer -> Doc ann) -> Maybe Integer -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Integer -> Doc ann
forall a ann. Pretty a => a -> Doc ann
printUid Maybe Integer
cUid
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Integer -> Doc ann) -> Maybe Integer -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Integer -> Doc ann
forall a ann. Pretty a => a -> Doc ann
printGid Maybe Integer
cGid
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Bool -> Doc ann) -> Maybe Bool -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Bool -> Doc ann
forall p. IsString p => Bool -> p
printReadOnly Maybe Bool
cReadOnly
    SshMount SecretOpts {Maybe Bool
Maybe Integer
Maybe Text
Maybe TargetPath
Maybe SourcePath
$sel:sGid:SecretOpts :: SecretOpts -> Maybe Integer
$sel:sUid:SecretOpts :: SecretOpts -> Maybe Integer
$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 Integer
sUid :: Maybe Integer
sMode :: Maybe Text
sSource :: Maybe SourcePath
sIsRequired :: Maybe Bool
sCacheId :: Maybe Text
sTarget :: Maybe TargetPath
..} ->
      Doc ann
"type=ssh"
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (TargetPath -> Doc ann) -> Maybe TargetPath -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty TargetPath -> Doc ann
forall ann. TargetPath -> Doc ann
printTarget Maybe TargetPath
sTarget
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Text -> Doc ann) -> Maybe Text -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Text -> Doc ann
forall ann. Text -> Doc ann
printId Maybe Text
sCacheId
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (SourcePath -> Doc ann) -> Maybe SourcePath -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty SourcePath -> Doc ann
forall ann. SourcePath -> Doc ann
printSource Maybe SourcePath
sSource
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Text -> Doc ann) -> Maybe Text -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
printMode Maybe Text
sMode
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Integer -> Doc ann) -> Maybe Integer -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Integer -> Doc ann
forall a ann. Pretty a => a -> Doc ann
printUid Maybe Integer
sUid
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Integer -> Doc ann) -> Maybe Integer -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Integer -> Doc ann
forall a ann. Pretty a => a -> Doc ann
printGid Maybe Integer
sGid
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Bool -> Doc ann) -> Maybe Bool -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Bool -> Doc ann
forall p. (IsString p, Monoid p) => Bool -> p
printRequired Maybe Bool
sIsRequired
    SecretMount SecretOpts {Maybe Bool
Maybe Integer
Maybe Text
Maybe TargetPath
Maybe SourcePath
sGid :: Maybe Integer
sUid :: Maybe Integer
sMode :: Maybe Text
sSource :: Maybe SourcePath
sIsRequired :: Maybe Bool
sCacheId :: Maybe Text
sTarget :: Maybe TargetPath
$sel:sGid:SecretOpts :: SecretOpts -> Maybe Integer
$sel:sUid:SecretOpts :: SecretOpts -> Maybe Integer
$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"
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (TargetPath -> Doc ann) -> Maybe TargetPath -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty TargetPath -> Doc ann
forall ann. TargetPath -> Doc ann
printTarget Maybe TargetPath
sTarget
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Text -> Doc ann) -> Maybe Text -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Text -> Doc ann
forall ann. Text -> Doc ann
printId Maybe Text
sCacheId
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (SourcePath -> Doc ann) -> Maybe SourcePath -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty SourcePath -> Doc ann
forall ann. SourcePath -> Doc ann
printSource Maybe SourcePath
sSource
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Text -> Doc ann) -> Maybe Text -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
printMode Maybe Text
sMode
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Integer -> Doc ann) -> Maybe Integer -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Integer -> Doc ann
forall a ann. Pretty a => a -> Doc ann
printUid Maybe Integer
sUid
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Integer -> Doc ann) -> Maybe Integer -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Integer -> Doc ann
forall a ann. Pretty a => a -> Doc ann
printGid Maybe Integer
sGid
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann -> (Bool -> Doc ann) -> Maybe Bool -> Doc ann
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc ann
forall a. Monoid a => a
mempty Bool -> Doc ann
forall p. (IsString p, Monoid p) => Bool -> p
printRequired Maybe Bool
sIsRequired
    TmpfsMount TmpOpts {TargetPath
$sel:tTarget:TmpOpts :: TmpOpts -> TargetPath
tTarget :: TargetPath
..} -> Doc ann
"type=tmpfs" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> TargetPath -> Doc ann
forall ann. TargetPath -> Doc ann
printTarget TargetPath
tTarget
  where
    printQuotable :: Text -> Doc ann
printQuotable Text
str
      | (Char -> Bool) -> Text -> Bool
Text.any (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'"') Text
str = Text -> Doc ann
forall ann. Text -> Doc ann
doubleQoute Text
str
      | Bool
otherwise = Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Text
str
    printTarget :: TargetPath -> Doc ann
printTarget (TargetPath Text
t) = Doc ann
",target=" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall ann. Text -> Doc ann
printQuotable Text
t
    printSource :: SourcePath -> Doc ann
printSource (SourcePath Text
s) = Doc ann
",source=" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall ann. Text -> Doc ann
printQuotable Text
s
    printFromImage :: Text -> Doc ann
printFromImage Text
f = Doc ann
",from=" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall ann. Text -> Doc ann
printQuotable Text
f
    printSharing :: CacheSharing -> a
printSharing CacheSharing
sharing = a
",sharing="
      a -> a -> a
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=" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall ann. Text -> Doc ann
printQuotable Text
i
    printMode :: a -> Doc ann
printMode a
m = Doc ann
",mode=" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty a
m
    printUid :: a -> Doc ann
printUid a
uid = Doc ann
",uid=" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty a
uid
    printGid :: a -> Doc ann
printGid a
gid = Doc ann
",gid=" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty a
gid
    printReadOnly :: Bool -> p
printReadOnly Bool
True = p
",ro"
    printReadOnly Bool
False = p
",rw"
    printRequired :: Bool -> p
printRequired Bool
True = p
",required"
    printRequired Bool
False = p
forall a. Monoid a => a
mempty

prettyPrintRunNetwork :: Maybe RunNetwork -> Doc ann
prettyPrintRunNetwork :: Maybe RunNetwork -> Doc ann
prettyPrintRunNetwork Maybe RunNetwork
Nothing = Doc ann
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 :: Maybe RunSecurity -> Doc ann
prettyPrintRunSecurity Maybe RunSecurity
Nothing = Doc ann
forall a. Monoid a => a
mempty
prettyPrintRunSecurity (Just RunSecurity
Sandbox) = Doc ann
"--security=sandbox"
prettyPrintRunSecurity (Just RunSecurity
Insecure) = Doc ann
"--security=insecure"

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

spaceCat :: Doc ann -> Doc ann -> Doc ann
spaceCat :: 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 Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
b