docopt 0.7.0.7 → 0.7.0.8
raw patch · 8 files changed
+120/−92 lines, 8 filesdep ~ansi-terminaldep ~containersdep ~parsecnew-uploaderPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: ansi-terminal, containers, parsec, template-haskell
API changes (from Hackage documentation)
- System.Console.Docopt: data ParseError
+ System.Console.Docopt: data () => ParseError
- System.Console.Docopt.NoTH: data ParseError
+ System.Console.Docopt.NoTH: data () => ParseError
Files
- CHANGELOG.md +18/−12
- System/Console/Docopt/OptParse.hs +13/−11
- System/Console/Docopt/ParseUtils.hs +3/−4
- System/Console/Docopt/Public.hs +7/−1
- System/Console/Docopt/QQ/Instances.hs +5/−1
- System/Console/Docopt/UsageParse.hs +35/−28
- docopt.cabal +29/−30
- test/LangAgnosticTests.hs +10/−5
CHANGELOG.md view
@@ -1,30 +1,36 @@-### 0.7.0.7 (unreleased)+### 0.7.0.8 +- Add support for `containers-0.7` [#58](https://github.com/docopt/docopt.hs/pull/58), [#60](https://github.com/docopt/docopt.hs/pull/60)++- Extend Template Haskell Quasi-quotation support to GHC 8.0-8.6. Template Haskell support is no longer optional. The package now supports all GHC's from 8.0 to 9.8. [#56](https://github.com/docopt/docopt.hs/pull/56), [#58](https://github.com/docopt/docopt.hs/pull/58)++### 0.7.0.7+ - update bounds, fix warnings, require ghc 8.0+ ### 0.7.0.6 -- Fixes issue causing compilation error to happen with ghc-8.8.2 [#33][#34]+- Fixes issue causing compilation error to happen with ghc-8.8.2 [#33](https://github.com/docopt/docopt.hs/issues/33), [#34](https://github.com/docopt/docopt.hs/pull/34) ### 0.7.0.5 -- Fix an issue where in some cases pattern lines were matched out of order [#16]-- Strip leading & trailing newlines from usage, for quasiquoter ease [#28]-- Fix tests run against latest aeson 1.0.2.0 [#29]+- Fix an issue where in some cases pattern lines were matched out of order [#16](https://github.com/docopt/docopt.hs/issues/16)+- Strip leading & trailing newlines from usage, for quasiquoter ease [#28](https://github.com/docopt/docopt.hs/issues/28)+- Fix tests run against latest aeson 1.0.2.0 [#29](https://github.com/docopt/docopt.hs/issues/29) ### 0.7.0.4 -- Fix the test suite when run from a distributed tarball [#21]+- Fix the test suite when run from a distributed tarball [#21](https://github.com/docopt/docopt.hs/pull/21) - Make the test suite more developer-friendly ### 0.7.0.3 -- Fix `isPresent` treatment of repeatable arguments/options [#15]-- Fix build failure for stackage inclusion [#20]+- Fix `isPresent` treatment of repeatable arguments/options [#15](https://github.com/docopt/docopt.hs/issues/15)+- Fix build failure for stackage inclusion [#20](https://github.com/docopt/docopt.hs/pull/20) ### 0.7.0.2 -- Minor docs/README tweaks [#13]+- Minor docs/README tweaks [#13](https://github.com/docopt/docopt.hs/issues/13) ### 0.7.0.1 @@ -32,13 +38,13 @@ # 0.7.0.0 -- Add usage parsing QuasiQuoters [#7]+- Add usage parsing QuasiQuoters [#7](https://github.com/docopt/docopt.hs/pull/7) - Add `docopt` usage parsing QuasiQuoter - Add `docoptFile` usage parsing QuasiQuoter - Add `System.Docopt.NoTH` module - Add `parseUsage` - Add `parseUsageOrExit`-- New API organization [#10]+- New API organization [#10](https://github.com/docopt/docopt.hs/issues/10) - Remove `optionsWithUsage` - Remove `optionsWithUsageDebug` - Remove `optionsWithUsageFile`@@ -59,7 +65,7 @@ ### 0.6.0.2 -- Make `argument` not require its named option wrapped in angle brackets. [#4, #5]+- Make `argument` not require its named option wrapped in angle brackets. [#4](https://github.com/docopt/docopt.hs/pull/4), [#5](https://github.com/docopt/docopt.hs/pull/5) ### 0.6.0.1
System/Console/Docopt/OptParse.hs view
@@ -1,3 +1,5 @@+{-# OPTIONS_GHC -Wno-unused-do-bind #-}+ module System.Console.Docopt.OptParse where @@ -15,7 +17,7 @@ -- @fmt@ is the OptPattern together with metadata to tell the parser how to parse args. -- Together, these let @buildOptParser@ build a parsec parser that can be applied to an argv. buildOptParser :: String -> OptFormat -> CharParser OptParserState ()-buildOptParser delim fmt@(pattern, infomap) =+buildOptParser delim (pattern, infomap) = let -- Helpers argDelim = (try $ string delim) <?> "space between arguments"@@ -124,7 +126,7 @@ unorderedSynParser = buildOptParser delim (Unordered oneOfSyns, infomap) in unorderedSynParser <?> humanize o- o@(Argument name) ->+ o@(Argument _name) -> do val <- try $ many1 (notFollowedBy argDelim >> anyChar) updateSt_saveOccurrence o val updateSt_inShortOptStack False@@ -157,7 +159,7 @@ Just oldval -> newval `updateFrom` oldval updateFrom newval oldval = Just $ case oldval of MultiValue vs -> MultiValue $ newval : vs- Value v -> Value newval+ Value _v -> Value newval NoValue -> Value newval Counted n -> Counted (n+1) Present -> Present@@ -185,10 +187,10 @@ optInitialValue info opt = let repeatable = isRepeated info in case opt of- Command name -> Just $ if repeatable then Counted 0 else NotPresent- Argument name -> Just $ if repeatable then MultiValue [] else NoValue- AnyOption -> Nothing -- no storable value for [options] shortcut- _ -> case expectsVal info of+ Command _name -> Just $ if repeatable then Counted 0 else NotPresent+ Argument _name -> Just $ if repeatable then MultiValue [] else NoValue+ AnyOption -> Nothing -- no storable value for [options] shortcut+ _ -> case expectsVal info of True -> Just $ if repeatable then MultiValue [] else NoValue False -> Just $ if repeatable then Counted 0 else NotPresent @@ -196,10 +198,10 @@ optDefaultValue info opt = let repeatable = isRepeated info in case opt of- Command name -> Just $ if repeatable then Counted 0 else NotPresent- Argument name -> Just $ if repeatable then MultiValue [] else NoValue- AnyOption -> Nothing -- no storable value for [options] shortcut- _ -> case expectsVal info of+ Command _name -> Just $ if repeatable then Counted 0 else NotPresent+ Argument _name -> Just $ if repeatable then MultiValue [] else NoValue+ AnyOption -> Nothing -- no storable value for [options] shortcut+ _ -> case expectsVal info of True -> case defaultVal info of Just dval -> Just $ if repeatable then MultiValue $ reverse $ words dval
System/Console/Docopt/ParseUtils.hs view
@@ -31,8 +31,7 @@ caseInsensitive = mapM (\c -> char (toLower c) <|> char (toUpper c)) lookAhead_ :: CharParser u a -> CharParser u ()-lookAhead_ p = do lookAhead p- return ()+lookAhead_ p = lookAhead p >> return () isNotFollowedBy :: Show a => CharParser u a -> CharParser u Bool isNotFollowedBy p = option False (notFollowedBy p >> return True)@@ -77,8 +76,8 @@ rest <- manyTill p end return $ first : rest --- |@skipUntil p@ ignores everything that comes before `p`.--- Returns what `p` returns.+-- |@skipUntil p@ ignores everything that comes before @p@.+-- Returns what @p@ returns. skipUntil :: Show a => CharParser u a -> CharParser u () skipUntil p = skipMany (notFollowedBy p >> anyChar)
System/Console/Docopt/Public.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE CPP #-}+ module System.Console.Docopt.Public ( -- * Command line arguments parsers@@ -42,6 +44,10 @@ import System.Exit +#if !MIN_VERSION_base(4,13,0)+import Control.Monad.Fail (MonadFail)+#endif+ import Data.Map as M hiding (null) import Data.Maybe (fromMaybe) import System.Console.Docopt.Types@@ -101,7 +107,7 @@ -- > Usage: -- > prog <required> ----- then @getArg args (argument \'required\')@ is guaranteed to be a 'Just'.+-- then @getArg args (argument "required")@ is guaranteed to be a 'Just'. getArg :: Arguments -> Option -> Maybe String getArg args opt = case opt `M.lookup` args of
System/Console/Docopt/QQ/Instances.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveLift#-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE FlexibleInstances #-}@@ -9,7 +10,10 @@ import System.Console.Docopt.Types import Language.Haskell.TH.Syntax (Lift)-import Data.Map.Internal (Map(..)) +#if !MIN_VERSION_containers(0,6,6)+import Data.Map.Internal (Map(..)) deriving instance Lift (Map Option OptionInfo)+#endif+ deriving instance Lift (Docopt)
System/Console/Docopt/UsageParse.hs view
@@ -1,3 +1,5 @@+{-# OPTIONS_GHC -Wno-unused-do-bind #-}+ module System.Console.Docopt.UsageParse where @@ -71,9 +73,9 @@ firstPairs = map (\x -> (x,False)) firstChars lastPair = (lastChar, lastExpectsVal) saveOptionsExpectVal ShortOption (firstPairs ++ [lastPair])- case length chars of- 0 -> fail ""- 1 -> return $ Atom . ShortOption $ head chars+ case chars of+ [] -> fail ""+ [c] -> return $ Atom . ShortOption $ c _ -> return $ Unordered $ map (Atom . ShortOption) chars pLongOption :: CharParser OptInfoMap (Name, Bool)@@ -97,9 +99,9 @@ pArgument :: CharParser OptInfoMap String pArgument = try bracketStyle <|> try upperStyle where bracketStyle = do- open <- char '<'+ _open <- char '<' name <- many $ oneOf alphanumSpecial- close <- char '>'+ _close <- char '>' return name upperStyle = do first <- oneOf uppers@@ -156,7 +158,7 @@ -- * Option Synonyms & Defaults Parsers -- | Succeeds only on the first line of an option explanation--- (one whose first non-space character is '-')+-- (one whose first non-space character is @\'-\'@) begOptionLine :: CharParser OptInfoMap String begOptionLine = inlineSpaces >> lookAhead (char '-') >> return "-" @@ -224,15 +226,16 @@ expectSynonyms oim (Unordered exs) = Unordered $ map (expectSynonyms oim) exs expectSynonyms oim (Optional ex) = Optional $ expectSynonyms oim ex expectSynonyms oim (Repeated ex) = Repeated $ expectSynonyms oim ex-expectSynonyms oim a@(Atom atom) = case atom of- e@(Command ex) -> a- e@(Argument ex) -> a- e@AnyOption -> flatten $ Unordered $ nub $ map Atom $ concatMap synonyms (M.elems oim)- e@(LongOption ex) ->+expectSynonyms oim a@(Atom atom) =+ case atom of+ Command _ex -> a+ Argument _ex -> a+ AnyOption -> flatten $ Unordered $ nub $ map Atom $ concatMap synonyms (M.elems oim)+ e@(LongOption _ex) -> case synonyms <$> e `M.lookup` oim of Just syns -> flatten . OneOf $ map Atom syns Nothing -> a- e@(ShortOption c) ->+ e@(ShortOption _c) -> case synonyms <$> e `M.lookup` oim of Just syns -> flatten . OneOf $ map Atom syns Nothing -> a@@ -244,8 +247,8 @@ (OneOf ps) -> canRepeatInside ps (Unordered ps) -> canRepeatInside ps || (atomicOccurrences ps > 1) (Optional p) -> canRepeat p target- (Repeated p) -> target `elem` atoms pat- (Atom a) -> False+ (Repeated _p) -> target `elem` atoms pat+ (Atom _a) -> False where canRepeatInside = any (`canRepeat` target) atomicOccurrences ps = length $ filter (== target) $ atoms $ Sequence ps @@ -253,22 +256,25 @@ -- | Compare on specificity of parsers built from optA and optB, -- so we can be sure the parser tries the most-specific first, where possible. -- E.g.--- LongOption "option" > ShortOption 'o' == True--- Command "cmd" > Argument "arg" == True+--+-- @+-- LongOption "option" > ShortOption \'o\' == True+-- Command "cmd" > Argument "arg" == True+-- @ compareOptSpecificity :: Option -> Option -> Ordering compareOptSpecificity optA optB = case optA of LongOption a -> case optB of LongOption b -> comparingFirst length a b _ -> GT ShortOption a -> case optB of- LongOption b -> LT+ LongOption _b -> LT ShortOption b -> compare a b _ -> GT Command a -> case optB of- LongOption b -> LT- ShortOption b -> LT- Command b -> comparingFirst length a b- _ -> GT+ LongOption _b -> LT+ ShortOption _b -> LT+ Command b -> comparingFirst length a b+ _ -> GT Argument a -> case optB of AnyOption -> GT Argument b -> comparingFirst length a b@@ -307,12 +313,13 @@ representativeAtom :: OptPattern -> Option representativeAtom p = case p of- Sequence ps -> if null ps then AnyOption else representativeAtom $ head ps- OneOf ps -> maximumBy compareOptSpecificity . map representativeAtom $ ps- Unordered ps -> maximumBy compareOptSpecificity . map representativeAtom $ ps- Optional p -> representativeAtom p- Repeated p -> representativeAtom p- Atom a -> a+ Sequence [] -> AnyOption+ Sequence (p:_) -> representativeAtom p+ OneOf ps -> maximumBy compareOptSpecificity . map representativeAtom $ ps+ Unordered ps -> maximumBy compareOptSpecificity . map representativeAtom $ ps+ Optional p -> representativeAtom p+ Repeated p -> representativeAtom p+ Atom a -> a maxLength :: OptPattern -> Int maxLength p = case p of@@ -325,5 +332,5 @@ LongOption o -> length o ShortOption _ -> 1 Command c -> length c- Argument a -> 100+ Argument _a -> 100 AnyOption -> 0
docopt.cabal view
@@ -1,13 +1,25 @@ name: docopt-version: 0.7.0.7+version: 0.7.0.8 synopsis: A command-line interface parser that will make you smile description: Docopt parses command-line interface usage text that adheres to a familiar syntax, and from it builds a command-line argument parser that will ensure your program is invoked correctly with the available options specified in the usage text. This allows the developer to write a usage text and get an argument parser for free. license: MIT license-file: LICENSE.txt author: Ryan Artecona-maintainer: ryanartecona@gmail.com+maintainer: QBayLogic B.V. <devops@qbaylogic.com> copyright: (c) 2013-2015 Ryan Artecona+tested-with:+ GHC == 8.0.2,+ GHC == 8.2.2,+ GHC == 8.4.4,+ GHC == 8.6.5,+ GHC == 8.8.4,+ GHC == 8.10.7,+ GHC == 9.0.2,+ GHC == 9.2.8,+ GHC == 9.4.7,+ GHC == 9.6.3,+ GHC == 9.8.1 category: Console @@ -27,14 +39,14 @@ type: git location: https://github.com/docopt/docopt.hs.git -flag template-haskell- default: True- manual: True- description:- Build with QuasiQuoter usage parsers, which requires Template Haskell+source-repository this+ type: git+ location: https://github.com/docopt/docopt.hs.git+ tag: v0.7.0.8 library exposed-modules: System.Console.Docopt.NoTH+ System.Console.Docopt other-modules: System.Console.Docopt.ApplicativeParsec System.Console.Docopt.ParseUtils@@ -42,22 +54,15 @@ System.Console.Docopt.UsageParse System.Console.Docopt.OptParse System.Console.Docopt.Public+ System.Console.Docopt.QQ+ System.Console.Docopt.QQ.Instances build-depends: base >= 4.9 && < 5.0, parsec >= 3.1.14 && < 3.2,- containers >= 0.6.2 && < 0.7-- ghc-options: -Wall- -fno-warn-unused-binds- -fno-warn-unused-do-bind- -fno-warn-unused-matches- -fno-warn-name-shadowing+ containers >= 0.6.2 && < 0.8,+ template-haskell >= 2.11.0 && < 2.22 - if impl(ghc >= 6.10) && flag(template-haskell)- exposed-modules: System.Console.Docopt- other-modules: System.Console.Docopt.QQ- System.Console.Docopt.QQ.Instances- build-depends: template-haskell >= 2.15.0 && < 2.18+ ghc-options: -Wall -Wno-name-shadowing default-language: Haskell2010 @@ -66,25 +71,19 @@ hs-source-dirs: ./, test main-is: LangAgnosticTests.hs - ghc-options: -Wall- -fno-warn-unused-binds- -fno-warn-unused-do-bind- -fno-warn-unused-matches- -fno-warn-name-shadowing- -fno-warn-orphans+ ghc-options: -Wall -Wno-name-shadowing build-depends: base,- parsec >= 3.1.14 && < 3.2,- containers >= 0.6.2 && < 0.7,+ parsec,+ containers, docopt, HUnit, split,- ansi-terminal,+ ansi-terminal >= 0.4, aeson, bytestring, text,- template-haskell >= 2.15.0 && < 2.18-+ template-haskell other-modules: System.Console.Docopt System.Console.Docopt.ApplicativeParsec
test/LangAgnosticTests.hs view
@@ -1,5 +1,8 @@ {-# LANGUAGE FlexibleInstances #-} +-- TODO: Remove orphan instances?+{-# OPTIONS_GHC -Wno-orphans #-}+ import Control.Monad ( (>=>) ) import System.Exit import System.Console.ANSI@@ -104,18 +107,20 @@ -> ((Int, Int) -> Bool) -> IO [Test] testsFromDocoptSpecFile name testFile ignore =- let notCommentLine x = null x || ('#' /= head x)+ let notCommentLine x = case x of {[] -> True; (c:_) -> '#' /= c} testFileClean = unlines $ filter notCommentLine $ lines testFile caseGroups = filter (not . null) $ splitOn "r\"\"\"" testFileClean in return . (:[]) . TestLabel name . test $ zip caseGroups [(1 :: Int)..] >>= \(caseGroup, icg) -> do - let [usage, rawCases] = splitOn "\"\"\"" caseGroup+ let (usage, rawCases) = case splitOn "\"\"\"" caseGroup of+ [u, r] -> (u, r)+ _ -> error $ "Unexpected format of 'caseGroup': " ++ caseGroup cases = filter (/= "\n") $ splitOn "$ " rawCases let (optFormat, docParseMsg) = case runParser pDocopt M.empty "Usage" usage of- Left e -> ((Sequence [], M.empty), "Couldn't parse usage text")+ Left _e -> ((Sequence [], M.empty), "Couldn't parse usage text") Right o -> (o, "") let groupDescLines = [@@ -131,9 +136,9 @@ let (cmdline, rawTarget_) = break (== '\n') testcase rawTarget = filter (/= '\n') rawTarget_ maybeTargetJSON = decode (BS.pack rawTarget) :: Maybe Value- rawArgs = tail $ words cmdline+ rawArgs = drop 1 (words cmdline) - let (parsedArgs, argParseMsg) = case getArguments optFormat rawArgs of+ let (parsedArgs, _argParseMsg) = case getArguments optFormat rawArgs of Left e -> (M.empty, "Parse Error: " ++ red (show e) ++ "\n") Right a -> (a, "")