Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PLT-6750: Parsing pretty printed Marlowe contracts #687

Merged
merged 23 commits into from Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7136ffa
PLT-6750: Parsing pretty printed Marlowe contracts
yveshauser Aug 11, 2023
aac789f
PLT-6750: Reading stdin in case no file is specified
yveshauser Aug 11, 2023
19ccba5
PLT-6750: Small cleanups
yveshauser Aug 11, 2023
b85b4db
PLT-6750: Minor cleanups
yveshauser Aug 11, 2023
89b39e3
PLT-6750: Case and Bound might be in parentheses as well
yveshauser Aug 11, 2023
ef9d275
PLT-6750: Property based test for pretty printing/parsing
yveshauser Aug 11, 2023
e5f3c73
PLT-6750: Corrected name
yveshauser Aug 12, 2023
bcd0660
PLT-6750: Renaming command to format
yveshauser Aug 14, 2023
a252dbc
PLT-6750: Renamed command
yveshauser Aug 14, 2023
63d9435
PLT-6750: Improved comments in code
yveshauser Aug 16, 2023
b9becdc
PLT-3391: Added Yaml as format for a Marlowe contract
yveshauser Aug 17, 2023
e2cd1f9
PLT-6750: Adjusted comments
yveshauser Aug 17, 2023
fb62706
PLT-6750: Generic not needed
yveshauser Aug 17, 2023
f17d656
PLT-6750: Change format name
yveshauser Aug 17, 2023
39674bd
PLT-6750: changelog
yveshauser Aug 17, 2023
b74d695
Update marlowe-cli/src/Language/Marlowe/CLI/Format.hs
yveshauser Aug 17, 2023
9801a10
Update marlowe-cli/command/Language/Marlowe/CLI/Command/Format.hs
yveshauser Aug 17, 2023
74b36f7
Update marlowe-cli/src/Language/Marlowe/CLI/Format.hs
yveshauser Aug 17, 2023
5884af8
Update marlowe-cli/tests/Spec/Format.hs
yveshauser Aug 17, 2023
6728c4b
Update marlowe-cli/command/Language/Marlowe/CLI/Command.hs
yveshauser Aug 18, 2023
08f39a2
PLT-6750: Addressed review feedback
yveshauser Aug 18, 2023
02dc224
PLT-6750: Addressing review feedback
yveshauser Aug 18, 2023
a6ae00b
PLT-6750: JSON is a subset of YAML
yveshauser Aug 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 40 additions & 0 deletions marlowe-cli/changelog.d/20230817_095044_yves.hauser_PLT_6750.md
@@ -0,0 +1,40 @@
<!--
A new scriv changelog fragment.

Uncomment the section that is right (remove the HTML comment wrapper).
-->

<!--
### Removed

- A bullet item for the Removed category.

-->
### Added

- Format conversion with `marlowe-cli format`

<!--
### Changed

- A bullet item for the Changed category.

-->
<!--
### Deprecated

- A bullet item for the Deprecated category.

-->
<!--
### Fixed

- A bullet item for the Fixed category.

-->
<!--
### Security

- A bullet item for the Security category.

-->
7 changes: 7 additions & 0 deletions marlowe-cli/command/Language/Marlowe/CLI/Command.hs
Expand Up @@ -27,6 +27,7 @@ import Cardano.Api (AlonzoEra, BabbageEra, IsShelleyBasedEra, NetworkId, ScriptD
import Control.Monad.Except (MonadError, MonadIO, liftIO, runExceptT)
import Data.Foldable (Foldable (fold), asum)
import Language.Marlowe.CLI.Command.Contract (ContractCommand, parseContractCommand, runContractCommand)
import Language.Marlowe.CLI.Command.Format (FormatCommand, parseFormatCommand, runFormatCommand)
import Language.Marlowe.CLI.Command.Input (InputCommand, parseInputCommand, runInputCommand)
import Language.Marlowe.CLI.Command.Role (RoleCommand, parseRoleCommand, runRoleCommand)
import Language.Marlowe.CLI.Command.Run (RunCommand, parseRunCommand, runRunCommand)
Expand Down Expand Up @@ -67,6 +68,8 @@ data Command era
UtilCommand (UtilCommand era)
| -- | Test-related commands.
TestCommand (TestCommand era)
| -- | Format-related commands.
FormatCommand FormatCommand

data SomeCommand = forall era. SomeCommand (ScriptDataSupportedInEra era) (Command era)

Expand Down Expand Up @@ -112,6 +115,7 @@ runCommand era cmd = flip runReaderT CliEnv{..} case cmd of
TemplateCommand command outputFiles -> runTemplateCommand command outputFiles
TransactionCommand command -> runTransactionCommand command
UtilCommand command -> runUtilCommand command
FormatCommand command -> runFormatCommand command

-- | Command parseCommand for the tool version.
mkCommandParser
Expand Down Expand Up @@ -182,6 +186,9 @@ mkCommandParser networkId socketPath version = do
, O.command "test" $
O.info (TestCommand <$> testCommandParser) $
O.progDesc "Run test scenario described using yaml based DSL."
, O.command "format" $
O.info (FormatCommand <$> parseFormatCommand) $
O.progDesc "Convert between formats and pretty-print Marlowe contracts."
]
, O.hsubparser $
fold
Expand Down
144 changes: 144 additions & 0 deletions marlowe-cli/command/Language/Marlowe/CLI/Command/Format.hs
@@ -0,0 +1,144 @@
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}

-----------------------------------------------------------------------------
--
-- Module : Language.Marlowe.CLI.Command.Format
-- License : Apache 2.0
--
-- Stability : Experimental
-- Portability : Portable
--
-----------------------------------------------------------------------------

-- | Format Marlowe contracts in the CLI tool.
module Language.Marlowe.CLI.Command.Format (
-- * Marlowe CLI Commands
FormatCommand (..),
runFormatCommand,
parseFormatCommand,
) where

import Control.Monad.Except (MonadError, MonadIO (..))
import Data.Char (toUpper)
import Language.Marlowe.CLI.Format (
maybeWriteJson,
maybeWritePretty,
maybeWriteYaml,
readContractJson,
readContractPretty,
readContractYaml,
)
import Language.Marlowe.CLI.Types (CliError (..))
import Options.Applicative qualified as O
import System.FilePath (takeExtension)

-- | Marlowe CLI options for formatting contracts.
data FormatCommand
= -- | Format a contract.
Format
{ inputFile :: Maybe FilePath
-- ^ The Marlowe file containing the contract to be formatted.
, outputFile :: Maybe FilePath
-- ^ The output file for the formatted Marlowe contract.
, inFormat :: Maybe Format
-- ^ Format of the input Marlowe contract.
, outFormat :: Maybe Format
-- ^ Format of the output Marlowe contract.
}
deriving stock (Eq, Show)

-- | Format a Marlowe contract.
runFormatCommand
:: (MonadError CliError m)
=> (MonadIO m)
=> FormatCommand
-- ^ The command.
-> m ()
-- ^ Action for runninng the command.
runFormatCommand Format{..} =
do
contract <- case inFormat of
Just Json -> readContractJson inputFile
yveshauser marked this conversation as resolved.
Show resolved Hide resolved
Just Yaml -> readContractYaml inputFile
Just Pretty -> readContractPretty inputFile
Nothing ->
case inputFile of
Just fileName ->
case takeExtension fileName of
".json" -> readContractJson inputFile
".yaml" -> readContractYaml inputFile
".marlowe" -> readContractPretty inputFile
_ -> readContractJson inputFile
Nothing -> readContractJson inputFile
case outFormat of
Just Json -> maybeWriteJson outputFile contract
Just Yaml -> maybeWriteYaml outputFile contract
Just Pretty -> maybeWritePretty outputFile contract
Nothing ->
case outputFile of
Just fileName ->
case takeExtension fileName of
".json" -> maybeWriteJson outputFile contract
".yaml" -> maybeWriteYaml outputFile contract
".marlowe" -> maybeWritePretty outputFile contract
_ -> maybeWriteJson outputFile contract
Nothing -> maybeWriteJson outputFile contract

-- | Parser for format commands.
parseFormatCommand :: O.Parser FormatCommand
parseFormatCommand =
Format
<$> inFile
<*> outFile
<*> inFormatParser
<*> outFormatParser
where
inFile =
O.optional . O.strOption $
mconcat
[ O.long "in-file"
, O.metavar "MARLOWE_FILE"
, O.help "The Marlowe file containing the contract. If omitted, the Marlowe contract is read from stdin."
palas marked this conversation as resolved.
Show resolved Hide resolved
]
outFile =
O.optional . O.strOption $
mconcat
[ O.long "out-file"
, O.metavar "MARLOWE_FILE"
, O.help "The Marlowe file the output contract is written to. If omitted, the Marlowe contract is written to stdout."
]
inFormatParser =
O.optional . O.option formatReader $
mconcat
[ O.long "in-format"
, O.metavar "FORMAT"
, O.help $
"The format of the input Marlowe contract. Known formats are: Json (default), Yaml, Marlowe. "
<> "If omitted and in-file is specified, the format is inferred from the file extension."
]
outFormatParser =
O.optional . O.option formatReader $
mconcat
[ O.long "out-format"
, O.metavar "FORMAT"
, O.help $
"The format of the output Marlowe contract. Known formats are: Json (default), Yaml, Marlowe. "
<> "If omitted and out-file is specified, the format is inferred from the file extension."
]

data Format = Json | Yaml | Pretty
deriving stock (Eq, Read, Show)

formatReader :: O.ReadM Format
formatReader = readFormat =<< O.str
where
readFormat arg =
case map toUpper arg of
"JSON" -> return Json
"YAML" -> return Yaml
"MARLOWE" -> return Pretty
_ -> O.readerError $ "cannot parse argument '" <> arg <> "'. Valid are: json, yaml, marlowe. Default: json"
14 changes: 13 additions & 1 deletion marlowe-cli/marlowe-cli.cabal
Expand Up @@ -74,6 +74,7 @@ library
Language.Marlowe.CLI.Data.Foldable
Language.Marlowe.CLI.Examples
Language.Marlowe.CLI.Export
Language.Marlowe.CLI.Format
Language.Marlowe.CLI.IO
Language.Marlowe.CLI.Merkle
Language.Marlowe.CLI.Orphans
Expand Down Expand Up @@ -107,10 +108,12 @@ library
, errors
, extra
, marlowe-cardano
, megaparsec
yveshauser marked this conversation as resolved.
Show resolved Hide resolved
, memory
, mtl
, ouroboros-consensus
, ouroboros-network
, parser-combinators
, plutus-core
, plutus-ledger
, plutus-ledger-ada
Expand Down Expand Up @@ -221,6 +224,7 @@ library command
exposed-modules:
Language.Marlowe.CLI.Command
Language.Marlowe.CLI.Command.Contract
Language.Marlowe.CLI.Command.Format
Language.Marlowe.CLI.Command.Input
Language.Marlowe.CLI.Command.Parse
Language.Marlowe.CLI.Command.Role
Expand All @@ -238,6 +242,7 @@ library command
, cardano-api
, cardano-slotting
, containers
, filepath
, marlowe-actus
, marlowe-cardano
, marlowe-cli:{marlowe-cli, cli-test}
Expand Down Expand Up @@ -278,17 +283,24 @@ test-suite marlowe-cli-test
hs-source-dirs: tests
type: exitcode-stdio-1.0
main-is: Spec.hs
other-modules: Spec.Analysis
other-modules:
Spec.Analysis
Spec.Format

build-depends:
, aeson
, base >=4.9 && <5
, cardano-api
, containers
, marlowe-cardano
, marlowe-cli
, marlowe-test
, megaparsec
, mtl
, plutus-ledger-api
, plutus-ledger-slot
, plutus-tx
, tasty
, tasty-hunit
, tasty-quickcheck
, text