diff --git a/cli/elm.json b/cli/elm.json index dc2378d..e9cd43c 100644 --- a/cli/elm.json +++ b/cli/elm.json @@ -21,6 +21,7 @@ "mdgriffith/elm-codegen": "6.0.1", "miniBill/elm-fast-dict": "1.2.4", "robinheghan/murmur3": "1.0.0", + "the-sett/elm-pretty-printer": "3.3.0", "wolfadex/elm-ansi": "3.0.1", "wolfadex/elm-open-api": "2.0.0" }, @@ -60,7 +61,6 @@ "rtfeldman/elm-iso8601-date-strings": "1.1.4", "stil4m/elm-syntax": "7.3.9", "stil4m/structured-writer": "1.0.3", - "the-sett/elm-pretty-printer": "3.3.0", "the-sett/elm-syntax-dsl": "6.0.3", "zwilias/elm-utf-tools": "2.0.1" } diff --git a/cli/review/suppressed/NoInternalImports.json b/cli/review/suppressed/NoInternalImports.json index ff8a17e..9898a85 100644 --- a/cli/review/suppressed/NoInternalImports.json +++ b/cli/review/suppressed/NoInternalImports.json @@ -3,6 +3,6 @@ "automatically created by": "elm-review suppress", "learn more": "elm-review suppress --help", "suppressions": [ - { "count": 3, "filePath": "src/Cli.elm" } + { "count": 2, "filePath": "src/Cli.elm" } ] } diff --git a/cli/src/Cli.elm b/cli/src/Cli.elm index e853ae5..af56e12 100644 --- a/cli/src/Cli.elm +++ b/cli/src/Cli.elm @@ -18,20 +18,18 @@ import Elm import FastDict import FastSet import FatalError exposing (FatalError) -import IndentedString exposing (IndentedString) import Json.Decode import Json.Encode import Json.Value -import List.Extra import OpenApi import OpenApi.Common.Internal import OpenApi.Config import OpenApi.Generate import Pages.Script import Pages.Script.Spinner +import Pretty import Regex exposing (Regex) import Result.Extra -import Set import String.Extra import Url import UrlPath @@ -983,6 +981,11 @@ yamlToJsonValueDecoder = ] +width : Int +width = + 120 + + generateFilesFromOpenApiSpecs : List ( OpenApi.Config.Generate, OpenApi.OpenApi ) -> @@ -1002,7 +1005,7 @@ generateFilesFromOpenApiSpecs configs = (\err -> err |> messageToString - |> IndentedString.toString + |> Pretty.pretty width |> FatalError.fromString ) |> BackendTask.fromResult @@ -1155,10 +1158,6 @@ printSuccessMessageAndWarnings : -> BackendTask.BackendTask FatalError.FatalError () printSuccessMessageAndWarnings ( outputPaths, { requiredPackages, warnings } ) = let - indentBy : Int -> String -> String - indentBy amount input = - String.repeat amount " " ++ input - allRequiredPackages : List String allRequiredPackages = requiredPackages @@ -1168,9 +1167,9 @@ printSuccessMessageAndWarnings ( outputPaths, { requiredPackages, warnings } ) = |> FastSet.insert "elm/bytes" |> FastSet.toList - toInstall : String -> String + toInstall : String -> Pretty.Doc () toInstall dependency = - "elm install " ++ dependency + Pretty.string ("elm install " ++ dependency) toSentence : List String -> String toSentence links = @@ -1185,61 +1184,75 @@ printSuccessMessageAndWarnings ( outputPaths, { requiredPackages, warnings } ) = , url = "https://package.elm-lang.org/packages/" ++ dependency ++ "/latest/" } - warningTask : BackendTask.BackendTask FatalError.FatalError () - warningTask = + warningString : Pretty.Doc () + warningString = let len : Int len = List.length warnings in if len == 0 then - BackendTask.succeed () + Pretty.empty else let - warningTasks : List (BackendTask FatalError ()) - warningTasks = + joined : Pretty.Doc () + joined = warnings |> Dict.Extra.groupBy .message |> Dict.toList - |> List.map logWarning + |> List.map warningToString + |> Pretty.lines - countMessage : String + countMessage : Pretty.Doc () countMessage = if len == 1 then - "\nGenerated 1" ++ Ansi.Color.fontColor Ansi.Color.yellow " warning" ++ "." + [ "" + , "Generated 1" ++ Ansi.Color.fontColor Ansi.Color.yellow " warning" ++ "." + ] + |> List.map Pretty.string + |> Pretty.lines else - "\nGenerated " ++ String.fromInt len ++ Ansi.Color.fontColor Ansi.Color.yellow " warnings" ++ "." + [ "" + , "Generated " ++ String.fromInt len ++ Ansi.Color.fontColor Ansi.Color.yellow " warnings" ++ "." + ] + |> List.map Pretty.string + |> Pretty.lines in - (Pages.Script.log "" :: warningTasks ++ [ Pages.Script.log countMessage ]) - |> BackendTask.doEach + [ Pretty.string "" + , joined + , countMessage + ] + |> Pretty.lines - successTask : BackendTask.BackendTask error () + successTask : Pretty.Doc () successTask = - [ [ "" - , "🎉 SDK generated:" - , "" + [ [ Pretty.string "" + , Pretty.string "🎉 SDK generated:" + , Pretty.string "" ] + |> Pretty.lines , outputPaths - |> List.map (indentBy 4) - , [ "" - , "" - , "You'll also need " ++ toSentence allRequiredPackages ++ " installed. Try running:" - , "" + |> List.map (\path -> Pretty.string path |> Pretty.indent 4) + |> Pretty.lines + , [ Pretty.string "" + , Pretty.string "" + , Pretty.string ("You'll also need " ++ toSentence allRequiredPackages ++ " installed. Try running:") + , Pretty.string "" ] + |> Pretty.lines , allRequiredPackages |> List.map (\requiredPackage -> toInstall requiredPackage - |> indentBy 4 + |> Pretty.indent 4 ) + |> Pretty.lines ] - |> List.concat - |> List.map Pages.Script.log - |> BackendTask.doEach + |> Pretty.lines in - BackendTask.doEach [ successTask, warningTask ] + Pages.Script.log (Pretty.pretty width (Pretty.lines [ successTask, warningString ])) elmCodegenWarningToMessage : ( String, List { declaration : String, warning : String } ) -> List OpenApi.Generate.Message @@ -1247,60 +1260,60 @@ elmCodegenWarningToMessage ( path, warnings ) = List.map (\warning -> { message = warning.warning - , details = [] , path = [ path, warning.declaration ] + , details = Pretty.empty } ) warnings -messageToString : OpenApi.Generate.Message -> List IndentedString +messageToString : OpenApi.Generate.Message -> Pretty.Doc () messageToString { path, message, details } = - [ IndentedString.fromString ("Error! " ++ message) + [ Pretty.string ("Error! " ++ message) , if List.isEmpty path then - [] + Pretty.empty else - IndentedString.fromString ("Path: " ++ String.join " -> " path) - , if List.isEmpty details then - [] + Pretty.string ("Path: " ++ String.join " -> " path) + , if details == Pretty.empty then + Pretty.empty else - IndentedString.indent 2 (IndentedString.fromString "Details:") - ++ IndentedString.indent 4 details + [ Pretty.string "Details:" + , details + ] + |> Pretty.lines + |> Pretty.nest 2 ] - |> List.concat + |> Pretty.lines -logWarning : ( String, List OpenApi.Generate.Message ) -> BackendTask.BackendTask FatalError.FatalError () -logWarning ( message, messages ) = +warningToString : ( String, List OpenApi.Generate.Message ) -> Pretty.Doc () +warningToString ( message, messages ) = let - firstLine : String + firstLine : Pretty.Doc () firstLine = - Ansi.Color.fontColor Ansi.Color.brightYellow "Warning: " ++ message + Pretty.string (Ansi.Color.fontColor Ansi.Color.brightYellow "Warning: " ++ message) - paths : List String + paths : List (Pretty.Doc ()) paths = messages |> List.map (\{ path, details } -> - (if List.isEmpty path then + if List.isEmpty path then details - else - IndentedString.fromString (Ansi.Font.bold "at " ++ String.join " -> " path) - ++ IndentedString.indent 2 details - ) - |> IndentedString.indent 2 + else + [ Pretty.string (Ansi.Font.bold "at " ++ String.join " -> " path) + , details + ] + |> Pretty.lines + |> Pretty.nest 2 ) - |> List.Extra.removeWhen List.isEmpty - |> List.map IndentedString.toString - |> Set.fromList - |> Set.toList in (firstLine :: paths) - |> List.map Pages.Script.log - |> BackendTask.doEach + |> Pretty.lines + |> Pretty.nest 2 diff --git a/elm.json b/elm.json index 5cc648d..c9b96c8 100644 --- a/elm.json +++ b/elm.json @@ -19,6 +19,7 @@ "mdgriffith/elm-codegen": "6.0.1 <= v < 7.0.0", "miniBill/elm-fast-dict": "1.2.0 <= v < 2.0.0", "robinheghan/murmur3": "1.0.0 <= v < 2.0.0", + "the-sett/elm-pretty-printer": "3.3.0 <= v < 4.0.0", "wolfadex/elm-open-api": "2.0.0 <= v < 3.0.0" }, "test-dependencies": { diff --git a/review/suppressed/NoMissingTypeExpose.json b/review/suppressed/NoMissingTypeExpose.json index d1bab4d..56dc427 100644 --- a/review/suppressed/NoMissingTypeExpose.json +++ b/review/suppressed/NoMissingTypeExpose.json @@ -4,6 +4,6 @@ "learn more": "elm-review suppress --help", "suppressions": [ { "count": 4, "filePath": "src/OpenApi/Config.elm" }, - { "count": 2, "filePath": "src/OpenApi/Generate.elm" } + { "count": 1, "filePath": "src/OpenApi/Generate.elm" } ] } diff --git a/review/suppressed/NoUnused.Exports.json b/review/suppressed/NoUnused.Exports.json index f251531..179de1b 100644 --- a/review/suppressed/NoUnused.Exports.json +++ b/review/suppressed/NoUnused.Exports.json @@ -3,7 +3,6 @@ "automatically created by": "elm-review suppress", "learn more": "elm-review suppress --help", "suppressions": [ - { "count": 1, "filePath": "src/IndentedString.elm" }, { "count": 1, "filePath": "src/OpenApi/Common/Internal.elm" } ] } diff --git a/src/CliMonad.elm b/src/CliMonad.elm index ca7b8dc..5f98004 100644 --- a/src/CliMonad.elm +++ b/src/CliMonad.elm @@ -33,17 +33,17 @@ import FastSet import Gen.Debug import Gen.Json.Decode import Gen.Json.Encode -import IndentedString exposing (IndentedString) import Json.Encode import OpenApi exposing (OpenApi) import OpenApi.Config +import Pretty import String.Extra type alias Message = { message : String , path : Path - , details : List IndentedString + , details : Pretty.Doc () } @@ -241,7 +241,14 @@ withWarning message (CliMonad f) = Result.map (\( res, output, cache2 ) -> ( res - , { output | warnings = { path = [], message = message, details = [] } :: output.warnings } + , { output + | warnings = + { path = [] + , message = message + , details = Pretty.empty + } + :: output.warnings + } , cache2 ) ) @@ -249,14 +256,21 @@ withWarning message (CliMonad f) = ) -withExtendedWarning : { message : String, details : List IndentedString } -> CliMonad a -> CliMonad a +withExtendedWarning : { message : String, details : Pretty.Doc () } -> CliMonad a -> CliMonad a withExtendedWarning { message, details } (CliMonad f) = CliMonad (\input cache -> Result.map (\( res, output, cache2 ) -> ( res - , { output | warnings = { path = [], message = message, details = details } :: output.warnings } + , { output + | warnings = + { path = [] + , message = message + , details = details + } + :: output.warnings + } , cache2 ) ) @@ -276,7 +290,14 @@ todoWithDefault default message = if generateTodos then Ok ( default - , { emptyOutput | warnings = [ { path = [], message = message, details = [] } ] } + , { emptyOutput + | warnings = + [ { path = [] + , message = message + , details = Pretty.empty + } + ] + } , cache ) @@ -284,14 +305,14 @@ todoWithDefault default message = Err { path = [] , message = "Todo: " ++ message - , details = [] + , details = Pretty.empty } ) fail : String -> CliMonad a fail message = - CliMonad (\_ _ -> Err { path = [], message = message, details = [] }) + CliMonad (\_ _ -> Err { path = [], message = message, details = Pretty.empty }) succeed : a -> CliMonad a @@ -544,7 +565,7 @@ errorToWarning (CliMonad f) = Err { path, message } -> ( Nothing - , { emptyOutput | warnings = [ { path = path, message = message, details = [] } ] } + , { emptyOutput | warnings = [ { path = path, message = message, details = Pretty.empty } ] } , cache ) |> Ok @@ -622,7 +643,7 @@ enumName variants = | warnings = [ { path = [] , message = message - , details = [] + , details = Pretty.empty } ] } @@ -735,7 +756,7 @@ withFormat basicType maybeFormatName getter default = | warnings = [ { message = firstLine ++ "\n" ++ secondLine , path = [ "format" ] - , details = [] + , details = Pretty.empty } ] } diff --git a/src/IndentedString.elm b/src/IndentedString.elm deleted file mode 100644 index df75897..0000000 --- a/src/IndentedString.elm +++ /dev/null @@ -1,35 +0,0 @@ -module IndentedString exposing (IndentedString, fromString, indent, listItem, toString) - - -type IndentedString - = IndentedString Int String - - -fromString : String -> List IndentedString -fromString input = - input - |> String.lines - |> List.map (IndentedString 0) - - -indent : Int -> List IndentedString -> List IndentedString -indent i ls = - List.map (\(IndentedString j l) -> IndentedString (i + j) l) ls - - -toString : List IndentedString -> String -toString ls = - ls - |> List.map (\(IndentedString i l) -> String.repeat i " " ++ l) - |> String.join "\n" - - -listItem : String -> List IndentedString -> List IndentedString -listItem s ls = - case ls of - [] -> - [] - - (IndentedString j h) :: t -> - IndentedString j (s ++ " " ++ h) - :: indent (String.length s + 1) t diff --git a/src/OpenApi/Generate.elm b/src/OpenApi/Generate.elm index c3e7029..32ac5f2 100644 --- a/src/OpenApi/Generate.elm +++ b/src/OpenApi/Generate.elm @@ -36,7 +36,6 @@ import Gen.Maybe import Gen.String import Gen.Task import Gen.Url.Builder -import IndentedString exposing (IndentedString) import Json.Schema.Definitions import JsonSchema.Generate import List.Extra @@ -56,6 +55,7 @@ import OpenApi.Schema import OpenApi.SecurityRequirement import OpenApi.SecurityScheme import OpenApi.Server +import Pretty import Regex exposing (Regex) import SchemaUtils import String.Extra @@ -70,7 +70,7 @@ type alias Mime = type alias Message = { message : String , path : Path - , details : List IndentedString + , details : Pretty.Doc () } @@ -214,7 +214,7 @@ extractEnums openApi = Err { message = e , path = [ name, "Extracting enums" ] - , details = [] + , details = Pretty.empty } _ -> diff --git a/src/SchemaUtils.elm b/src/SchemaUtils.elm index d0fc9f7..63b245e 100644 --- a/src/SchemaUtils.elm +++ b/src/SchemaUtils.elm @@ -34,7 +34,6 @@ import Gen.List import Gen.Maybe import Gen.Result import Gen.String -import IndentedString exposing (IndentedString) import IntersectionResult exposing (IntersectionResult) import Json.Decode import Json.Encode @@ -48,6 +47,7 @@ import OpenApi import OpenApi.Common.Internal import OpenApi.Components import OpenApi.Schema +import Pretty import Result.Extra import Set exposing (Set) @@ -257,7 +257,7 @@ schemaToType seen schema = (\disjoint -> let onIntersection : - { a | leftSchema : List IndentedString, rightSchema : List IndentedString } + { a | leftSchema : Pretty.Doc (), rightSchema : Pretty.Doc () } -> Maybe Json.Encode.Value -> CliMonad { type_ : Common.Type, documentation : Maybe String } onIntersection collision value = @@ -273,31 +273,35 @@ schemaToType seen schema = Nothing -> let - formatSchema : List IndentedString -> List IndentedString + formatSchema : Pretty.Doc () -> Pretty.Doc () formatSchema s = - s - |> IndentedString.listItem "-" + Pretty.string "- " + |> Pretty.a s + |> Pretty.nest 2 - details : List IndentedString + details : Pretty.Doc () details = case value of Just found -> - [ IndentedString.fromString "Clash between" + [ Pretty.string "Clash between" , formatSchema collision.leftSchema , formatSchema collision.rightSchema - , IndentedString.fromString "Possible clashing value:" - , IndentedString.fromString (Json.Encode.encode 2 found) - |> IndentedString.indent 2 + , Pretty.string "Possible clashing value:" + , Json.Encode.encode 2 found + |> String.lines + |> List.map Pretty.string + |> Pretty.lines + |> Pretty.indent 2 ] - |> List.concat + |> Pretty.lines Nothing -> - [ IndentedString.fromString "Clash between" + [ Pretty.string "Clash between" , formatSchema collision.leftSchema , formatSchema collision.rightSchema - , IndentedString.fromString "Could not build a clashing value" + , Pretty.string "Could not build a clashing value" ] - |> List.concat + |> Pretty.lines in CliMonad.succeed { type_ = Common.Value @@ -532,13 +536,13 @@ areAllArrays schemas = type SchemaIntersectionResult = NoSchemaIntersection | SchemaMayIntersect - { leftSchema : List IndentedString - , rightSchema : List IndentedString + { leftSchema : Pretty.Doc () + , rightSchema : Pretty.Doc () } | FoundSchemaIntersection - { leftSchema : List IndentedString + { leftSchema : Pretty.Doc () , value : Json.Encode.Value - , rightSchema : List IndentedString + , rightSchema : Pretty.Doc () } @@ -550,9 +554,9 @@ schemaIntersection seen schemas = case ( l, r ) of ( Json.Schema.Definitions.BooleanSchema lb, Json.Schema.Definitions.BooleanSchema rb ) -> if lb == rb then - { leftSchema = IndentedString.fromString "bool" + { leftSchema = Pretty.string "bool" , value = Json.Encode.bool lb - , rightSchema = IndentedString.fromString "bool" + , rightSchema = Pretty.string "bool" } |> FoundSchemaIntersection |> CliMonad.succeed @@ -634,16 +638,16 @@ schemaIntersection seen schemas = go (LazyList.uniquePairs lazyList) NoSchemaIntersection -describeSubSchema : Json.Schema.Definitions.SubSchema -> CliMonad (List IndentedString) +describeSubSchema : Json.Schema.Definitions.SubSchema -> CliMonad (Pretty.Doc ()) describeSubSchema subSchema = let - sourceToString : Json.Decode.Value -> List IndentedString + sourceToString : Json.Decode.Value -> Pretty.Doc () sourceToString source = source |> Json.Decode.decodeValue removeDocumentation |> Result.withDefault subSchema.source |> Json.Encode.encode 0 - |> IndentedString.fromString + |> Pretty.string in case subSchema.ref of Nothing -> @@ -663,8 +667,8 @@ describeSubSchema subSchema = Json.Schema.Definitions.BooleanSchema b -> Json.Encode.bool b in - IndentedString.fromString (ref ++ ":") - ++ sourceToString source + Pretty.string (ref ++ ": ") + |> Pretty.a (sourceToString source) )