on master help sign in
Start cleaning up command line errors
6b8e824Evan Czaplicki
ui/terminal/src/CommandLine/Args.hs+2−2
@@ -62,7 +62,7 @@ data MakeFlags =
62 { _warn :: Bool
62 { _warn :: Bool
63 , _debug :: Bool
63 , _debug :: Bool
64 , _output :: Maybe Flags.Output
64 , _output :: Maybe Flags.Output
65− , _server :: Bool
65+-- , _server :: Bool
66 }
66 }
67
67
68
68
@@ -72,7 +72,7 @@ makeFlags =
72 |-- onOff "warn" "Report warnings to improve code quality."
72 |-- onOff "warn" "Report warnings to improve code quality."
73 |-- onOff "debug" "Generate programs in debug mode."
73 |-- onOff "debug" "Generate programs in debug mode."
74 |-- flag "output" output "Specify the name of the resulting JS file (use --output=/dev/null for no output)"
74 |-- flag "output" output "Specify the name of the resulting JS file (use --output=/dev/null for no output)"
75− |-- onOff "server" "Generate JS for server-side rendering."
75+-- |-- onOff "server" "Generate JS for server-side rendering."
76
76
77
77
78output :: Parser Flags.Output
78output :: Parser Flags.Output
ui/terminal/src/CommandLine/Args/Internal.hs+85−90
@@ -1,5 +1,6 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE GADTs #-}
2{-# LANGUAGE GADTs #-}
3+{-# LANGUAGE OverloadedStrings #-}
3module CommandLine.Args.Internal
4module CommandLine.Args.Internal
4 ( get
5 ( get
5 , Flags, noFlags, flags, (|--)
6 , Flags, noFlags, flags, (|--)
@@ -12,16 +13,15 @@ module CommandLine.Args.Internal
12 )
13 )
13 where
14 where
14
15
16+
17+import Data.Monoid ((<>))
15import qualified Data.Char as Char
18import qualified Data.Char as Char
16import qualified Data.List as List
19import qualified Data.List as List
17import GHC.IO.Handle (hIsTerminalDevice)
20import GHC.IO.Handle (hIsTerminalDevice)
18import System.Environment (getArgs)
21import System.Environment (getArgs)
19import System.Exit (exitFailure)
22import System.Exit (exitFailure)
20import System.IO (hPutStrLn, stderr)
23import System.IO (hPutStrLn, stderr)
21−import Text.PrettyPrint.ANSI.Leijen
24+import qualified Text.PrettyPrint.ANSI.Leijen as P
22− ( Doc, (<>), comma, displayIO, fillSep, green
23− , plain, red, renderPretty, text, vcat
24− )
25
25
26import Elm.Utils (nearbyNames)
26import Elm.Utils (nearbyNames)
27
27
@@ -667,23 +667,21 @@ failure :: Error -> IO a
667failure err =
667failure err =
668 do let doc = toDoc err
668 do let doc = toDoc err
669 isTerminal <- hIsTerminalDevice stderr
669 isTerminal <- hIsTerminalDevice stderr
670− displayIO stderr $ renderPretty 1 80 $
670+ P.displayIO stderr $ P.renderPretty 1 80 $
671− if isTerminal then doc else plain doc
671+ if isTerminal then doc else P.plain doc
672 hPutStrLn stderr ""
672 hPutStrLn stderr ""
673 exitFailure
673 exitFailure
674
674
675
675
676−toDoc :: Error -> Doc
676+toDoc :: Error -> P.Doc
677toDoc err =
677toDoc err =
678 case err of
678 case err of
679 BadCommand badName suggestions lastSuggestion ->
679 BadCommand badName suggestions lastSuggestion ->
680− fillSep $
680+ P.fillSep $
681− [ text "There is no"
681+ ["There","is","no",toRed badName,"command.","Try"
682− , code badName
683− , text "command."
684− , text "Did you mean"
685 ]
682 ]
686− ++ oxfordify (map code suggestions) "or" (code lastSuggestion <> text "?")
683+ ++ oxfordify (map toGreen suggestions) "or" (toGreen lastSuggestion)
684+ ++ ["instead?"]
687
685
688 NoCommand (BadArgs argError) ->
686 NoCommand (BadArgs argError) ->
689 argErrorToDoc Nothing argError
687 argErrorToDoc Nothing argError
@@ -698,31 +696,41 @@ toDoc err =
698 flagErrorToDoc (Just name) flagError
696 flagErrorToDoc (Just name) flagError
699
697
700
698
699+toRed :: String -> P.Doc
700+toRed str =
701+ P.red (P.text str)
702+
703+
704+toGreen :: String -> P.Doc
705+toGreen str =
706+ P.green (P.text str)
707+
708+
701
709
702-- ARG FAILURE
710-- ARG FAILURE
703
711
704
712
705−argErrorToDoc :: Maybe String -> ArgError -> Doc
713+argErrorToDoc :: Maybe String -> ArgError -> P.Doc
706argErrorToDoc maybeCommand argError =
714argErrorToDoc maybeCommand argError =
707 case argError of
715 case argError of
708 NoneOf argErrors ->
716 NoneOf argErrors ->
709− text $ "TODO - " ++ show (map (argErrorToDoc maybeCommand) argErrors)
717+ P.text $ "TODO - " ++ show (map (argErrorToDoc maybeCommand) argErrors)
710
718
711 MissingArg (ParserInfo tipe) ->
719 MissingArg (ParserInfo tipe) ->
712− text $ "TODO - " ++ tipe
720+ P.text $ "TODO - " ++ tipe
713
721
714 BadArg chunk _parserError ->
722 BadArg chunk _parserError ->
715− text $ "TODO - " ++ chunk
723+ P.text $ "TODO - " ++ chunk
716
724
717 ExtraArgs extraChunks ->
725 ExtraArgs extraChunks ->
718− text $ "TODO - " ++ show extraChunks
726+ P.text $ "TODO - " ++ show extraChunks
719
727
720
728
721
729
722-- FLAG FAILURE
730-- FLAG FAILURE
723
731
724
732
725−flagErrorToDoc :: Maybe String -> FlagError -> Doc
733+flagErrorToDoc :: Maybe String -> FlagError -> P.Doc
726flagErrorToDoc maybeCommand flagError =
734flagErrorToDoc maybeCommand flagError =
727 case flagError of
735 case flagError of
728 BadOnOff name value ->
736 BadOnOff name value ->
@@ -731,121 +739,108 @@ flagErrorToDoc maybeCommand flagError =
731 "--" ++ name ++ "=" ++ value
739 "--" ++ name ++ "=" ++ value
732 in
740 in
733 if null value then
741 if null value then
742+ flagErrorToDocHelp
734− flagErrorToDocHelp "This on/off flag has a trailing equals sign:" chunk
743+ "This on/off flag has a trailing equals sign:"
744+ chunk
735− [ fillSep
745+ [ P.fillSep
736− [ text "Just get rid of the equals sign, like this:"
746+ ["Just","get","rid","of","the","equals","sign,","like","this:"
737− , green (text ("--" ++ name))
747+ , toGreen ("--" ++ name)
738 ]
748 ]
739 ]
749 ]
740
750
741 else
751 else
752+ flagErrorToDocHelp
742− flagErrorToDocHelp "This on/off flag was given a value:" chunk
753+ "This on/off flag was given a value:"
754+ chunk
743− [ text "An on/off flag either exists or not, no need for an equals sign and value."
755+ [ "An on/off flag either exists or not, no need for an equals sign and value.\n\
744− , text "Maybe you want this instead?"
756+ \Maybe you want this instead?"
745− , text ""
757+ , P.indent 4 (toGreen ("--" ++ name))
746− , text " " <> green (text ("--" ++ name))
747− , text ""
748 ]
758 ]
749
759
750 BadFlag name (ParserInfo tipe) Nothing ->
760 BadFlag name (ParserInfo tipe) Nothing ->
751 flagErrorToDocHelp
761 flagErrorToDocHelp
752 "This flag cannot appear without a value:"
762 "This flag cannot appear without a value:"
753 ("--" ++ name)
763 ("--" ++ name)
754− [ text $ "It needs a " ++ tipe ++ " value."
764+ [ P.fillSep ["It","needs","a",toGreen tipe,"value."]
755 ]
765 ]
756
766
757 BadFlag name (ParserInfo tipe) (Just (value, parserError)) ->
767 BadFlag name (ParserInfo tipe) (Just (value, parserError)) ->
758 flagErrorToDocHelp
768 flagErrorToDocHelp
759 "This flag was given a bad value:"
769 "This flag was given a bad value:"
760 ("--" ++ name ++ "=" ++ value)
770 ("--" ++ name ++ "=" ++ value)
761− [ fillSep $ map text $ words $
771+ [ P.fillSep $
762− "I need a " ++ tipe ++ " value, but "
772+ ["I","need","a",toGreen tipe,"value,","but"
773+ ]
763 ++
774 ++
764 case parserError of
775 case parserError of
765 Expecting expectedType ->
776 Expecting expectedType ->
766− value ++ " is not a valid " ++ expectedType ++ "."
777+ [P.text value,"is","not","a","valid",P.text expectedType <> "."]
767 ]
778 ]
768
779
769 Unrecognized chunk [] ->
780 Unrecognized chunk [] ->
770− let
771− explanation =
772− case maybeCommand of
773− Nothing ->
774− "I am not expecting any flags."
775−
776− Just command ->
777− "The `" ++ command ++ "` command does not expect any flags."
778− in
779− flagErrorToDocHelp "Get rid of this flag:" chunk $
781+ flagErrorToDocHelp
782+ "Get rid of this flag:"
783+ chunk
780− [ fillSep (map text (words explanation))
784+ [ P.fillSep $ map P.text $ words $
785+ case maybeCommand of
786+ Nothing ->
787+ "I am not expecting any flags."
788+
789+ Just command ->
790+ "The `" ++ command ++ "` command does not expect any flags."
781 ]
791 ]
782
792
783 Unrecognized chunk info ->
793 Unrecognized chunk info ->
784 case takeWhile ('=' /=) (dropWhile ('-' ==) chunk) of
794 case takeWhile ('=' /=) (dropWhile ('-' ==) chunk) of
785 "" ->
795 "" ->
796+ flagErrorToDocHelp
786− flagErrorToDocHelp "This is not a valid flag:" chunk
797+ "This is not a valid flag:"
798+ chunk
787− [ text "Valid flags look like --output=FILE"
799+ [ P.fillSep ["Valid","flags","look","like",P.green "--output=FILE"]
788 ]
800 ]
789
801
790 name ->
802 name ->
791 let
803 let
792− suggestions =
793− nearbyNames id name (map fst info)
804+ closeNames = nearbyNames id name (map fst info)
805+ suggestions = if null closeNames then map fst info else closeNames
806+ toFlag str = toGreen ("--" ++ str)
794 in
807 in
808+ flagErrorToDocHelp
795− flagErrorToDocHelp "I do not recognize this flag:" chunk $
809+ "I do not recognize this flag:"
796− unrecognizedExplanation $
810+ chunk
797− if null suggestions then map fst info else suggestions
811+ (
812+ case suggestions of
813+ [] ->
814+ []
815+
816+ [suggestion] ->
817+ [ P.fillSep ["Looks","like","a","typo.","Maybe","you","want",toFlag suggestion,"instead?"]
818+ ]
819+
820+ _ ->
821+ [ P.fillSep ["Maybe","you","want","one","of","these","instead?"]
822+ , P.indent 4 (P.vcat (map toFlag suggestions))
823+ ]
824+ )
798
825
799
826
800−flagErrorToDocHelp :: String -> String -> [Doc] -> Doc
827+flagErrorToDocHelp :: String -> String -> [P.Doc] -> P.Doc
801flagErrorToDocHelp summary original explanation =
828flagErrorToDocHelp summary original explanation =
802− vcat $
829+ P.vcat $ concatMap (\d -> [d,""]) $
803− [ text summary
830+ [ P.fillSep (map P.text (words summary))
804− , text ""
805− , text " " <> red (text original)
831+ , P.indent 4 (toRed original)
806− , text ""
807 ]
832 ]
808 ++ explanation
833 ++ explanation
809
834
810
835
811−unrecognizedExplanation :: [String] -> [Doc]
812−unrecognizedExplanation suggestions =
813− let
814− toBullet name =
815− text " " <> green (text ("--" ++ name))
816− in
817− case suggestions of
818− [] ->
819− []
820−
821− [suggestion] ->
822− [ text "Looks like a typo. Maybe you want:"
823− , text ""
824− , toBullet suggestion
825− , text ""
826− ]
827−
828− _ ->
829− [ text "Maybe you want one of these?"
830− , text ""
831− ]
832− ++ map toBullet suggestions
833− ++ [ text "" ]
834−
835−
836−code :: String -> Doc
837−code str =
838− red (text str)
839−
840−
841−oxfordify :: [Doc] -> String -> Doc -> [Doc]
836+oxfordify :: [P.Doc] -> String -> P.Doc -> [P.Doc]
842oxfordify chunks conjuction lastChunk =
837oxfordify chunks conjuction lastChunk =
843 case chunks of
838 case chunks of
844 [] ->
839 [] ->
845 [ lastChunk ]
840 [ lastChunk ]
846
841
847 [chunk] ->
842 [chunk] ->
848− [ chunk, text conjuction, lastChunk ]
843+ [ chunk, P.text conjuction, lastChunk ]
849
844
850 _ ->
845 _ ->
851− map (<> comma) chunks ++ [ text conjuction, lastChunk ]
846+ map (<> P.comma) chunks ++ [ P.text conjuction, lastChunk ]
ui/terminal/src/Make.hs+2−2
@@ -27,9 +27,9 @@ run paths flags =
27
27
28-- TODO figure out --warn flag
28-- TODO figure out --warn flag
29toOptions :: Args.MakeFlags -> Flags.Options
29toOptions :: Args.MakeFlags -> Flags.Options
30−toOptions (Args.MakeFlags _warn debug output server) =
30+toOptions (Args.MakeFlags _warn debug output) =
31 let
31 let
32 mode = if debug then Obj.Debug else Obj.Prod
32 mode = if debug then Obj.Debug else Obj.Prod
33− target = if server then Obj.Server else Obj.Client
33+ target = if False then Obj.Server else Obj.Client
34 in
34 in
35 Flags.Options mode target output
35 Flags.Options mode target output