diff --git a/cardano-cli/src/Cardano/CLI/EraBased/TextView/Command.hs b/cardano-cli/src/Cardano/CLI/EraBased/TextView/Command.hs index 63777e0f2f..2b1c414262 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/TextView/Command.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/TextView/Command.hs @@ -3,20 +3,30 @@ module Cardano.CLI.EraBased.TextView.Command ( TextViewCmds (..) + , TextViewDecodeCborCmdArgs (..) , renderTextViewCmds ) where import Cardano.Api.Shelley +import Cardano.CLI.Type.Common (FormatCbor, FormatText) + import Data.Text (Text) +import Vary + +newtype TextViewCmds era + = TextViewDecodeCborCmd TextViewDecodeCborCmdArgs + deriving Show -data TextViewCmds era - = TextViewInfo - !FilePath - (Maybe (File () Out)) +data TextViewDecodeCborCmdArgs + = TextViewDecodeCborCmdArgs + { inputFile :: !FilePath + , outputFormat :: !(Vary [FormatCbor, FormatText]) + , mOutFile :: Maybe (File () Out) + } deriving Show renderTextViewCmds :: TextViewCmds era -> Text renderTextViewCmds = \case - TextViewInfo _ _ -> "text-view decode-cbor" + TextViewDecodeCborCmd _ -> "text-view decode-cbor" diff --git a/cardano-cli/src/Cardano/CLI/EraBased/TextView/Option.hs b/cardano-cli/src/Cardano/CLI/EraBased/TextView/Option.hs index a28dfbbe7d..611913557b 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/TextView/Option.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/TextView/Option.hs @@ -10,8 +10,10 @@ where import Cardano.CLI.EraBased.Common.Option import Cardano.CLI.EraBased.TextView.Command +import Cardano.CLI.Option.Flag import Cardano.CLI.Parser +import Data.Function ((&)) import Options.Applicative hiding (help, str) import Options.Applicative qualified as Opt @@ -28,9 +30,20 @@ pTextViewCmds = , "are stored on disk as TextView files." ] ) - [ Just $ - Opt.hsubparser $ - commandWithMetavar "decode-cbor" $ - Opt.info (TextViewInfo <$> pCBORInFile <*> pMaybeOutputFile) $ - Opt.progDesc "Print a TextView file as decoded CBOR." + [ Just + . Opt.hsubparser + . commandWithMetavar "decode-cbor" + $ Opt.info + ( fmap + TextViewDecodeCborCmd + $ TextViewDecodeCborCmdArgs + <$> pCBORInFile + <*> pFormatFlags + "text view info output format" + [ flagFormatCbor + , flagFormatText & setDefault + ] + <*> pMaybeOutputFile + ) + $ Opt.progDesc "Print a TextView file as decoded CBOR." ] diff --git a/cardano-cli/src/Cardano/CLI/EraBased/TextView/Run.hs b/cardano-cli/src/Cardano/CLI/EraBased/TextView/Run.hs index 865152dec1..f412397861 100644 --- a/cardano-cli/src/Cardano/CLI/EraBased/TextView/Run.hs +++ b/cardano-cli/src/Cardano/CLI/EraBased/TextView/Run.hs @@ -1,5 +1,8 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE LambdaCase #-} +{-# LANGUAGE NamedFieldPuns #-} + +{- HLINT ignore "Redundant id" -} module Cardano.CLI.EraBased.TextView.Run ( runTextViewCmds @@ -10,23 +13,42 @@ where import Cardano.Api import Cardano.CLI.EraBased.TextView.Command -import Cardano.CLI.Helper (pPrintCBOR) +import Cardano.CLI.Helper (cborToText) +import Cardano.CLI.Type.Common import Cardano.CLI.Type.Error.TextViewFileError import Data.ByteString.Lazy.Char8 qualified as LBS +import Data.Function ((&)) +import Data.Text.Encoding qualified as Text +import System.IO qualified as IO +import Vary qualified runTextViewCmds :: TextViewCmds era -> ExceptT TextViewFileError IO () runTextViewCmds = \case - TextViewInfo fpath mOutfile -> runTextViewInfoCmd fpath mOutfile + TextViewDecodeCborCmd cmd -> runTextViewInfoCmd cmd runTextViewInfoCmd :: () - => FilePath - -> Maybe (File () Out) + => TextViewDecodeCborCmdArgs -> ExceptT TextViewFileError IO () -runTextViewInfoCmd fpath mOutFile = do - tv <- firstExceptT TextViewReadFileError $ newExceptT (readTextEnvelopeFromFile fpath) - let lbCBOR = LBS.fromStrict (textEnvelopeRawCBOR tv) - case mOutFile of - Just (File oFpath) -> liftIO $ LBS.writeFile oFpath lbCBOR - Nothing -> firstExceptT TextViewCBORPrettyPrintError $ pPrintCBOR lbCBOR +runTextViewInfoCmd + TextViewDecodeCborCmdArgs + { inputFile + , outputFormat + , mOutFile + } = do + tv <- firstExceptT TextViewReadFileError $ newExceptT (readTextEnvelopeFromFile inputFile) + let lbCBOR = LBS.fromStrict (textEnvelopeRawCBOR tv) + + outputContent <- + outputFormat + & ( id + . Vary.on (\FormatCbor -> pure lbCBOR) + . Vary.on (\FormatText -> LBS.fromStrict . Text.encodeUtf8 <$> cborToText lbCBOR) + $ Vary.exhaustiveCase + ) + & firstExceptT TextViewCBORPrettyPrintError + + let writeOutput = maybe (LBS.hPut IO.stdout) (LBS.writeFile . unFile) mOutFile + + liftIO $ writeOutput outputContent diff --git a/cardano-cli/src/Cardano/CLI/Helper.hs b/cardano-cli/src/Cardano/CLI/Helper.hs index 7a05c7ea10..8f7cfce653 100644 --- a/cardano-cli/src/Cardano/CLI/Helper.hs +++ b/cardano-cli/src/Cardano/CLI/Helper.hs @@ -6,6 +6,7 @@ module Cardano.CLI.Helper ( HelpersError (..) + , cborToText , printWarning , deprecationWarning , ensureNewFile @@ -106,6 +107,25 @@ pPrintCBOR bs = do unless (LB.null remaining) $ pPrintCBOR remaining +cborToText :: LB.ByteString -> ExceptT HelpersError IO Text +cborToText bs = do + as <- cborToTextList bs + let cs = filter (not . Text.null) as + pure $ mconcat $ fmap (<> "\n") cs + +cborToTextList :: LB.ByteString -> ExceptT HelpersError IO [Text] +cborToTextList bs = do + case deserialiseFromBytes decodeTerm bs of + Left err -> left $ CBORPrettyPrintError err + Right (remaining, decodedVal) -> do + let text = Text.pack . prettyHexEnc $ encodeTerm decodedVal + + if LB.null remaining + then pure [text] + else do + extraText <- cborToTextList remaining + pure $ text : extraText + readCBOR :: FilePath -> ExceptT HelpersError IO LB.ByteString readCBOR fp = handleIOExceptT diff --git a/cardano-cli/test/cardano-cli-golden/Test/Golden/Shelley/TextView/DecodeCbor.hs b/cardano-cli/test/cardano-cli-golden/Test/Golden/Shelley/TextView/DecodeCbor.hs index 636226cd54..1c6a198a81 100644 --- a/cardano-cli/test/cardano-cli-golden/Test/Golden/Shelley/TextView/DecodeCbor.hs +++ b/cardano-cli/test/cardano-cli-golden/Test/Golden/Shelley/TextView/DecodeCbor.hs @@ -22,6 +22,7 @@ hprop_golden_shelleyTextViewDecodeCbor = propertyOnce $ H.moduleWorkspace "tmp" [ "latest" , "text-view" , "decode-cbor" + , "--output-text" , "--file" , unsignedTxFile ] diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help.cli index f6af207feb..89a44b633c 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help.cli @@ -2622,6 +2622,9 @@ Usage: cardano-cli conway text-view decode-cbor are stored on disk as TextView files. Usage: cardano-cli conway text-view decode-cbor --in-file FILEPATH + [ --output-cbor + | --output-text + ] [--out-file FILEPATH] Print a TextView file as decoded CBOR. @@ -4855,6 +4858,9 @@ Usage: cardano-cli latest text-view decode-cbor are stored on disk as TextView files. Usage: cardano-cli latest text-view decode-cbor --in-file FILEPATH + [ --output-cbor + | --output-text + ] [--out-file FILEPATH] Print a TextView file as decoded CBOR. diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help/conway_text-view_decode-cbor.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help/conway_text-view_decode-cbor.cli index be5cbad0c2..c7156f9a08 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help/conway_text-view_decode-cbor.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help/conway_text-view_decode-cbor.cli @@ -1,9 +1,15 @@ Usage: cardano-cli conway text-view decode-cbor --in-file FILEPATH + [ --output-cbor + | --output-text + ] [--out-file FILEPATH] Print a TextView file as decoded CBOR. Available options: --in-file FILEPATH CBOR input file. + --output-cbor Format text view info output format to BASE16 CBOR. + --output-text Format text view info output format to TEXT + (default). --out-file FILEPATH Optional output file. Default is to write to stdout. -h,--help Show this help text diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/help/latest_text-view_decode-cbor.cli b/cardano-cli/test/cardano-cli-golden/files/golden/help/latest_text-view_decode-cbor.cli index 1934caf32e..76cc0a6ff2 100644 --- a/cardano-cli/test/cardano-cli-golden/files/golden/help/latest_text-view_decode-cbor.cli +++ b/cardano-cli/test/cardano-cli-golden/files/golden/help/latest_text-view_decode-cbor.cli @@ -1,9 +1,15 @@ Usage: cardano-cli latest text-view decode-cbor --in-file FILEPATH + [ --output-cbor + | --output-text + ] [--out-file FILEPATH] Print a TextView file as decoded CBOR. Available options: --in-file FILEPATH CBOR input file. + --output-cbor Format text view info output format to BASE16 CBOR. + --output-text Format text view info output format to TEXT + (default). --out-file FILEPATH Optional output file. Default is to write to stdout. -h,--help Show this help text