getopt-generics 0.11.0.3 → 0.12
raw patch · 18 files changed
+125/−203 lines, 18 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- System.Console.GetOpt.Generics: class HasDatatypeInfo a
- WithCli: class (AllF [k] (All k f) xss, SListI [k] xss) => All2 (f :: k -> Constraint) (xss :: [[k]])
- WithCli: class HasDatatypeInfo a
+ System.Console.GetOpt.Generics: type GCode a = ToSumCode (Rep a) ([] [*])
+ System.Console.GetOpt.Generics: type GDatatypeInfo a = GDatatypeInfo' (Rep a)
- System.Console.GetOpt.Generics: class All [*] (SListI *) (Code a) => Generic a where type family Code a :: [[*]]
+ System.Console.GetOpt.Generics: class Generic a
- System.Console.GetOpt.Generics: getArguments :: (Generic a, HasDatatypeInfo a, All2 HasArguments (Code a)) => IO a
+ System.Console.GetOpt.Generics: getArguments :: (Generic a, GTo a, GDatatypeInfo a, All2 HasArguments (GCode a)) => IO a
- System.Console.GetOpt.Generics: modifiedGetArguments :: (Generic a, HasDatatypeInfo a, All2 HasArguments (Code a)) => [Modifier] -> IO a
+ System.Console.GetOpt.Generics: modifiedGetArguments :: (Generic a, GTo a, GDatatypeInfo a, All2 HasArguments (GCode a)) => [Modifier] -> IO a
- System.Console.GetOpt.Generics: parseArguments :: (Generic a, HasDatatypeInfo a, All2 HasArguments (Code a)) => String -> [Modifier] -> [String] -> Result a
+ System.Console.GetOpt.Generics: parseArguments :: (Generic a, GTo a, GDatatypeInfo a, All2 HasArguments (GCode a)) => String -> [Modifier] -> [String] -> Result a
- WithCli: class All [*] (SListI *) (Code a) => Generic a where type family Code a :: [[*]]
+ WithCli: class Generic a
Files
- docs/CustomOptionRecord.hs +3/−7
- docs/RecordType.hs +3/−7
- docs/SimpleRecord.hs +3/−7
- docs/Test02.hs +3/−8
- docs/Test03.hs +4/−14
- docs/Test04.hs +4/−13
- getopt-generics.cabal +2/−2
- src/System/Console/GetOpt/Generics.hs +16/−17
- src/WithCli.hs +4/−8
- src/WithCli/HasArguments.hs +10/−13
- src/WithCli/Parser.hs +0/−1
- test/DocsSpec.hs +54/−0
- test/ExamplesSpec.hs +0/−51
- test/ModifiersSpec/RenameOptionsSpec.hs +2/−9
- test/ModifiersSpec/UseForPositionalArgumentsSpec.hs +2/−9
- test/System/Console/GetOpt/Generics/ModifierSpec.hs +3/−10
- test/System/Console/GetOpt/GenericsSpec.hs +6/−25
- test/Util.hs +6/−2
docs/CustomOptionRecord.hs view
@@ -1,11 +1,10 @@+{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE TypeFamilies #-} module CustomOptionRecord where -import qualified GHC.Generics-import WithCli+import WithCli data File = File FilePath deriving (Show, Typeable)@@ -18,11 +17,8 @@ = Options { file :: File }- deriving (Show, GHC.Generics.Generic)+ deriving (Show, Generic, HasArguments) -instance Generic Options-instance HasDatatypeInfo Options-instance HasArguments Options instance HasArguments File where argumentsParser = atomicArgumentsParser
docs/RecordType.hs view
@@ -2,10 +2,9 @@ module RecordType where -import qualified GHC.Generics-import System.Console.GetOpt.Generics+import System.Console.GetOpt.Generics --- All you have to do is to define a type and derive some instances:+-- All you have to do is to define a type and derive an instance for Generic: data Options = Options {@@ -13,10 +12,7 @@ daemonize :: Bool, config :: Maybe FilePath }- deriving (Show, GHC.Generics.Generic)--instance Generic Options-instance HasDatatypeInfo Options+ deriving (Show, Generic) -- Then you can use `getArguments` to create a command-line argument parser:
docs/SimpleRecord.hs view
@@ -1,9 +1,9 @@+{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} module SimpleRecord where -import qualified GHC.Generics-import System.Console.GetOpt.Generics+import WithCli data Options = Options {@@ -11,11 +11,7 @@ daemonize :: Bool, config :: Maybe FilePath }- deriving (Show, GHC.Generics.Generic)--instance Generic Options-instance HasDatatypeInfo Options-instance HasArguments Options+ deriving (Show, Generic, HasArguments) main :: IO () main = withCli run
docs/Test02.hs view
@@ -1,10 +1,9 @@+{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE TypeFamilies #-} module Test02 where -import qualified GHC.Generics-import WithCli+import WithCli data Options = Options {@@ -13,11 +12,7 @@ config :: Maybe FilePath, args :: [String] }- deriving (Show, GHC.Generics.Generic)--instance Generic Options-instance HasDatatypeInfo Options-instance HasArguments Options+ deriving (Show, Generic, HasArguments) main :: IO () main = withCli run
docs/Test03.hs view
@@ -1,11 +1,9 @@-{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE FlexibleInstances #-} module Test03 where -import qualified GHC.Generics-import WithCli+import WithCli main :: IO () main = withCli run@@ -18,18 +16,10 @@ = A { aa :: String }- deriving (Show, GHC.Generics.Generic)--instance Generic A-instance HasDatatypeInfo A-instance HasArguments A+ deriving (Show, Generic, HasArguments) data B = B { bb :: String }- deriving (Show, GHC.Generics.Generic)--instance Generic B-instance HasDatatypeInfo B-instance HasArguments B+ deriving (Show, Generic, HasArguments)
docs/Test04.hs view
@@ -1,10 +1,9 @@-{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} module Test04 where -import qualified GHC.Generics-import WithCli+import WithCli main :: IO () main = withCli run@@ -17,18 +16,10 @@ = A { aa :: String }- deriving (Show, GHC.Generics.Generic)--instance Generic A-instance HasDatatypeInfo A-instance HasArguments A+ deriving (Show, Generic, HasArguments) data B = B { bb :: String }- deriving (Show, GHC.Generics.Generic)--instance Generic B-instance HasDatatypeInfo B-instance HasArguments B+ deriving (Show, Generic, HasArguments)
getopt-generics.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack name: getopt-generics-version: 0.11.0.3+version: 0.12 synopsis: Create command line interfaces with ease description: Create command line interfaces with ease category: Console, System@@ -95,7 +95,7 @@ WithCli.Normalize WithCli.Parser WithCli.Result- ExamplesSpec+ DocsSpec ModifiersSpec ModifiersSpec.RenameOptionsSpec ModifiersSpec.UseForPositionalArgumentsSpec
src/System/Console/GetOpt/Generics.hs view
@@ -1,7 +1,8 @@ {-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-}-{-# LANGUAGE FlexibleContexts #-} module System.Console.GetOpt.Generics ( -- * Simple IO API@@ -18,21 +19,23 @@ -- * Pure API parseArguments, Result(..),- -- * Re-exports from "Generics.SOP"- Generics.SOP.Generic,- HasDatatypeInfo,- Code,+ -- * Re-exports+ GHC.Generic,+ GDatatypeInfo,+ GCode, All2, ) where +import qualified GHC.Generics as GHC import Generics.SOP+import Generics.SOP.GGP import System.Environment +import System.Console.GetOpt.Generics.Modifier import WithCli-import WithCli.Parser import WithCli.HasArguments+import WithCli.Parser import WithCli.Result-import System.Console.GetOpt.Generics.Modifier -- | Parses command line arguments (gotten from 'withArgs') and returns the -- parsed value. This function should be enough for simple use-cases.@@ -48,10 +51,9 @@ -- > -- > module RecordType where -- >--- > import qualified GHC.Generics--- > import System.Console.GetOpt.Generics+-- > import System.Console.GetOpt.Generics -- >--- > -- All you have to do is to define a type and derive some instances:+-- > -- All you have to do is to define a type and derive an instance for Generic: -- > -- > data Options -- > = Options {@@ -59,10 +61,7 @@ -- > daemonize :: Bool, -- > config :: Maybe FilePath -- > }--- > deriving (Show, GHC.Generics.Generic)--- >--- > instance Generic Options--- > instance HasDatatypeInfo Options+-- > deriving (Show, Generic) -- > -- > -- Then you can use `getArguments` to create a command-line argument parser: -- >@@ -97,12 +96,12 @@ -- ### End ### -getArguments :: forall a . (Generic a, HasDatatypeInfo a, All2 HasArguments (Code a)) =>+getArguments :: forall a . (GHC.Generic a, GTo a, GDatatypeInfo a, All2 HasArguments (GCode a)) => IO a getArguments = modifiedGetArguments [] -- | Like 'getArguments` but allows you to pass in 'Modifier's.-modifiedGetArguments :: forall a . (Generic a, HasDatatypeInfo a, All2 HasArguments (Code a)) =>+modifiedGetArguments :: forall a . (GHC.Generic a, GTo a, GDatatypeInfo a, All2 HasArguments (GCode a)) => [Modifier] -> IO a modifiedGetArguments modifiers = do args <- getArgs@@ -112,7 +111,7 @@ -- | Pure variant of 'modifiedGetArguments'. -- -- Does not throw any exceptions.-parseArguments :: forall a . (Generic a, HasDatatypeInfo a, All2 HasArguments (Code a)) =>+parseArguments :: forall a . (GHC.Generic a, GTo a, GDatatypeInfo a, All2 HasArguments (GCode a)) => String -- ^ Name of the program (e.g. from 'getProgName'). -> [Modifier] -- ^ List of 'Modifier's to manually tweak the command line interface. -> [String] -- ^ List of command line arguments to parse (e.g. from 'getArgs').
src/WithCli.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE DataKinds #-} {-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE LambdaCase #-}@@ -15,10 +14,7 @@ withCliModified, Modifier(..), -- * Useful Re-exports- SOP.Generic,- SOP.HasDatatypeInfo,- SOP.Code,- SOP.All2,+ GHC.Generic, Typeable, Proxy(..), ) where@@ -27,7 +23,7 @@ import Data.Proxy import Data.Typeable-import qualified Generics.SOP as SOP+import qualified GHC.Generics as GHC import System.Environment import System.Console.GetOpt.Generics.Modifier@@ -88,12 +84,12 @@ -- ### End ### -withCli :: forall main . WithCli main => main -> IO ()+withCli :: WithCli main => main -> IO () withCli = withCliModified [] -- | This is a variant of 'withCli' that allows to tweak the generated -- command line interface by providing a list of 'Modifier's.-withCliModified :: forall main . WithCli main => [Modifier] -> main -> IO ()+withCliModified :: WithCli main => [Modifier] -> main -> IO () withCliModified mods main = do args <- getArgs modifiers <- handleResult (mkModifiers mods)
src/WithCli/HasArguments.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE DataKinds #-} {-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveFunctor #-}@@ -31,14 +30,16 @@ import Data.List.Compat import Data.Proxy import Data.Traversable+import qualified GHC.Generics as GHC import Generics.SOP as SOP+import Generics.SOP.GGP as SOP import System.Console.GetOpt import Text.Read import System.Console.GetOpt.Generics.Modifier-import WithCli.Parser-import WithCli.Normalize import WithCli.Argument+import WithCli.Normalize+import WithCli.Parser import WithCli.Result parseArgumentResult :: forall a . Argument a => Maybe String -> String -> Result a@@ -61,10 +62,10 @@ -- ### Start "docs/SimpleRecord.hs" "module SimpleRecord where\n\n" Haddock ### -- |+-- > {-# LANGUAGE DeriveAnyClass #-} -- > {-# LANGUAGE DeriveGeneric #-} -- >--- > import qualified GHC.Generics--- > import System.Console.GetOpt.Generics+-- > import WithCli -- > -- > data Options -- > = Options {@@ -72,11 +73,7 @@ -- > daemonize :: Bool, -- > config :: Maybe FilePath -- > }--- > deriving (Show, GHC.Generics.Generic)--- >--- > instance Generic Options--- > instance HasDatatypeInfo Options--- > instance HasArguments Options+-- > deriving (Show, Generic, HasArguments) -- > -- > main :: IO () -- > main = withCli run@@ -113,7 +110,7 @@ class HasArguments a where argumentsParser :: Modifiers -> Maybe String -> Result (Parser Unnormalized a) default argumentsParser ::- (SOP.Generic a, SOP.HasDatatypeInfo a, All2 HasArguments (Code a)) =>+ (GHC.Generic a, GTo a, SOP.GDatatypeInfo a, All2 HasArguments (GCode a)) => Modifiers -> Maybe String -> Result (Parser Unnormalized a) argumentsParser = const . genericParser@@ -278,10 +275,10 @@ -- * generic HasArguments genericParser :: forall a .- (Generic a, HasDatatypeInfo a, All2 HasArguments (Code a)) =>+ (GHC.Generic a, GTo a, GDatatypeInfo a, All2 HasArguments (GCode a)) => Modifiers -> Result (Parser Unnormalized a)-genericParser modifiers = fmap (fmap to) $ case datatypeInfo (Proxy :: Proxy a) of+genericParser modifiers = fmap (fmap gto) $ case gdatatypeInfo (Proxy :: Proxy a) of ADT _ typeName (constructorInfo :* Nil) -> case constructorInfo of (Record _ fields) ->
src/WithCli/Parser.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE NamedFieldPuns #-}
+ test/DocsSpec.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE CPP #-}++module DocsSpec where++import Prelude ()+import Prelude.Compat++import Control.Monad+import System.FilePath+import Test.Hspec++import ShellProtocol++import qualified Test01+import qualified CustomOption+import qualified RecordType+import qualified Simple+#if MIN_VERSION_base(4,8,0)+import qualified Test02+import qualified Test03+import qualified Test04+import qualified SimpleRecord+import qualified CustomOptionRecord+#endif++examples :: [(IO (), String)]+examples =+ (Test01.main, "Test01") :+ (CustomOption.main, "CustomOption") :+ (RecordType.main, "RecordType") :+ (Simple.main, "Simple") :+#if MIN_VERSION_base(4,8,0)+ (Test02.main, "Test02") :+ (Test03.main, "Test03") :+ (Test04.main, "Test04") :+ (SimpleRecord.main, "SimpleRecord") :+ (CustomOptionRecord.main, "CustomOptionRecord") :+#endif+ []++main :: IO ()+main = hspec spec++spec :: Spec+spec = do+ describe "shell protocols" $ do+ forM_ examples $ \ (program, name) ->+ it name $ do+ test program name++test :: IO () -> String -> IO ()+test program name = do+ protocol <- readFile ("docs" </> name <.> "shell-protocol")+ testShellProtocol program protocol
− test/ExamplesSpec.hs
@@ -1,51 +0,0 @@--module ExamplesSpec where--import Prelude ()-import Prelude.Compat--import Control.Monad-import System.FilePath-import Test.Hspec--import ShellProtocol--import qualified CustomOption-import qualified CustomOptionRecord-import qualified RecordType-import qualified Simple-import qualified SimpleRecord-import qualified Test01-import qualified Test02-import qualified Test03-import qualified Test04--examples :: [(IO (), String)]-examples =- (Test01.main, "Test01") :- (Test02.main, "Test02") :- (Test03.main, "Test03") :- (Test04.main, "Test04") :-- (Simple.main, "Simple") :- (SimpleRecord.main, "SimpleRecord") :- (RecordType.main, "RecordType") :- (SimpleRecord.main, "SimpleRecord") :- (CustomOption.main, "CustomOption") :- (CustomOptionRecord.main, "CustomOptionRecord") :- []--main :: IO ()-main = hspec spec--spec :: Spec-spec = do- describe "shell protocols" $ do- forM_ examples $ \ (program, name) ->- it name $ do- test program name--test :: IO () -> String -> IO ()-test program name = do- protocol <- readFile ("docs" </> name <.> "shell-protocol")- testShellProtocol program protocol
test/ModifiersSpec/RenameOptionsSpec.hs view
@@ -4,7 +4,6 @@ import Data.Char import Data.List-import qualified GHC.Generics import Test.Hspec import System.Console.GetOpt.Generics@@ -15,10 +14,7 @@ foo :: Int, bar :: Int }- deriving (Eq, Show, GHC.Generics.Generic)--instance Generic Foo-instance HasDatatypeInfo Foo+ deriving (Eq, Show, Generic) data CommonPrefixes = CP {@@ -26,10 +22,7 @@ prefixBar :: Int, notPrefixBaz :: Int }- deriving (Eq, Show, GHC.Generics.Generic)--instance Generic CommonPrefixes-instance HasDatatypeInfo CommonPrefixes+ deriving (Eq, Show, Generic) spec :: Spec spec = do
test/ModifiersSpec/UseForPositionalArgumentsSpec.hs view
@@ -4,7 +4,6 @@ module ModifiersSpec.UseForPositionalArgumentsSpec where import Data.List-import qualified GHC.Generics as GHC import System.Environment import Test.Hspec @@ -16,10 +15,7 @@ positionalArguments :: [String], someFlag :: Bool }- deriving (GHC.Generic, Show, Eq)--instance Generic WithPositionalArguments-instance HasDatatypeInfo WithPositionalArguments+ deriving (Generic, Show, Eq) data WithMultiplePositionalArguments = WithMultiplePositionalArguments {@@ -27,10 +23,7 @@ positionalArgumentsB :: [String], someOtherFlag :: Bool }- deriving (GHC.Generic, Show, Eq)--instance Generic WithMultiplePositionalArguments-instance HasDatatypeInfo WithMultiplePositionalArguments+ deriving (Generic, Show, Eq) spec :: Spec spec = do
test/System/Console/GetOpt/Generics/ModifierSpec.hs view
@@ -2,10 +2,9 @@ module System.Console.GetOpt.Generics.ModifierSpec where -import qualified GHC.Generics-import Generics.SOP import Test.Hspec +import System.Console.GetOpt.Generics import System.Console.GetOpt.Generics.Modifier import Util @@ -25,17 +24,11 @@ = Foo { bar :: String }- deriving (GHC.Generics.Generic)--instance Generic Foo-instance HasDatatypeInfo Foo+ deriving (Generic) data Overlap = Overlap { foo :: String, fooo :: String }- deriving (GHC.Generics.Generic)--instance Generic Overlap-instance HasDatatypeInfo Overlap+ deriving (Generic)
test/System/Console/GetOpt/GenericsSpec.hs view
@@ -11,7 +11,6 @@ import Control.Exception import Data.Foldable (forM_) import Data.List (isPrefixOf, isSuffixOf)-import qualified GHC.Generics as GHC import System.Environment import System.Exit import System.IO@@ -36,18 +35,12 @@ baz :: String, bool :: Bool }- deriving (GHC.Generic, Show, Eq)--instance Generic Foo-instance HasDatatypeInfo Foo+ deriving (Generic, Show, Eq) data NotAllowed = NotAllowed1 | NotAllowed2- deriving (GHC.Generic, Show, Eq)--instance Generic NotAllowed-instance HasDatatypeInfo NotAllowed+ deriving (Generic, Show, Eq) part1 :: Spec part1 = do@@ -126,10 +119,7 @@ = ListOptions { multiple :: [Int] }- deriving (GHC.Generic, Show, Eq)--instance Generic ListOptions-instance HasDatatypeInfo ListOptions+ deriving (Generic, Show, Eq) part2 :: Spec part2 = do@@ -147,10 +137,7 @@ = CamelCaseOptions { camelCase :: String }- deriving (GHC.Generic, Show, Eq)--instance Generic CamelCaseOptions-instance HasDatatypeInfo CamelCaseOptions+ deriving (Generic, Show, Eq) part3 :: Spec part3 = do@@ -174,10 +161,7 @@ = WithUnderscore { _withUnderscore :: String }- deriving (GHC.Generic, Show, Eq)--instance Generic WithUnderscore-instance HasDatatypeInfo WithUnderscore+ deriving (Generic, Show, Eq) part4 :: Spec part4 = do@@ -188,10 +172,7 @@ data WithoutSelectors = WithoutSelectors String Bool Int- deriving (Eq, Show, GHC.Generic)--instance Generic WithoutSelectors-instance HasDatatypeInfo WithoutSelectors+ deriving (Eq, Show, Generic) part5 :: Spec part5 = do
test/Util.hs view
@@ -1,16 +1,20 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeFamilies #-} module Util where +import qualified GHC.Generics as GHC+import Generics.SOP.GGP+ import System.Console.GetOpt.Generics import System.Console.GetOpt.Generics.Modifier -parse :: (Generic a, HasDatatypeInfo a, All2 HasArguments (Code a)) =>+parse :: (GHC.Generic a, GTo a, GDatatypeInfo a, All2 HasArguments (GCode a)) => String -> Result a parse = modsParse [] -modsParse :: (Generic a, HasDatatypeInfo a, All2 HasArguments (Code a)) =>+modsParse :: (GHC.Generic a, GTo a, GDatatypeInfo a, All2 HasArguments (GCode a)) => [Modifier] -> String -> Result a modsParse modifiers = parseArguments "prog-name" modifiers . words