module Lorentz.ContractRegistry
( ContractInfo (..)
, ContractRegistry (..)
, getContract
, printContractFromRegistryDoc
, (?::)
, CmdLnArgs (..)
, argParser
) where
import qualified Data.Map as Map
import qualified Data.Text.Lazy.IO as TL
import Fmt (Buildable(..), blockListF, nameF, (+|), (|+))
import qualified Options.Applicative as Opt
import Lorentz.Base
import Lorentz.Constraints
import Lorentz.Doc
import Util.IO
data ContractInfo =
forall cp st.
(NiceParameterFull cp, NiceStorage st) =>
ContractInfo
{ ciContract :: Contract cp st
, ciIsDocumented :: Bool
}
(?::) :: Text -> a -> (Text, a)
(?::) = (,)
newtype ContractRegistry = ContractRegistry
{ unContractRegistry :: Map Text ContractInfo }
getContract :: Text -> ContractRegistry -> Either String ContractInfo
getContract name registry =
case Map.lookup name (unContractRegistry registry) of
Nothing ->
Left $ "No contract with name '" +| name |+ "' found\n" +| registry |+ ""
Just c -> Right c
instance Buildable ContractRegistry where
build registry =
nameF "Available contracts" (blockListF $ keys (unContractRegistry registry))
printContractFromRegistryDoc :: Text -> ContractRegistry -> Maybe FilePath -> IO ()
printContractFromRegistryDoc name contracts mOutput = do
ContractInfo{..} <- either die pure $ getContract name contracts
let writeFunc = case mOutput of
Nothing -> TL.putStrLn
Just "def" -> writeFileUtf8 $ toString name <> ".md"
Just output -> writeFileUtf8 output
if ciIsDocumented
then writeFunc $ contractDocToMarkdown $ buildLorentzDoc ciContract
else die "This contract is not documented"
data CmdLnArgs
= List
| Print Text (Maybe FilePath) Bool
| Document Text (Maybe FilePath)
argParser :: Opt.Parser CmdLnArgs
argParser = Opt.subparser $ mconcat
[ listSubCmd
, printSubCmd
, documentSubCmd
]
where
mkCommandParser commandName parser desc =
Opt.command commandName $
Opt.info (Opt.helper <*> parser) $
Opt.progDesc desc
listSubCmd =
mkCommandParser "list"
(pure List)
"Show all available contracts"
printSubCmd =
mkCommandParser "print"
(Print <$> printOptions <*> outputOptions <*> onelineOption)
"Dump a contract in form of Michelson code"
documentSubCmd =
mkCommandParser "document"
(Document <$> printOptions <*> outputOptions)
"Dump contract documentation in Markdown"
printOptions = Opt.strOption $ mconcat
[ Opt.short 'n'
, Opt.long "name"
, Opt.metavar "IDENTIFIER"
, Opt.help "Name of a contract returned by `list` command."
]
outputOptions = optional . Opt.strOption $ mconcat
[ Opt.short 'o'
, Opt.long "output"
, Opt.metavar "FILEPATH"
, Opt.help "File to use as output. If not specified, stdout is used."
]
onelineOption :: Opt.Parser Bool
onelineOption = Opt.switch (
Opt.long "oneline" <>
Opt.help "Force single line output")