Skip to content

Commit ae00b17

Browse files
committed
cabal-doctest: Add support for --list-options
1 parent fc1e0d2 commit ae00b17

File tree

3 files changed

+34
-23
lines changed

3 files changed

+34
-23
lines changed

src/Cabal/Options.hs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,26 @@ replOnlyOptions = Set.fromList [
3636

3737
rejectUnsupportedOptions :: [String] -> IO ()
3838
rejectUnsupportedOptions args = case getOpt' Permute options args of
39-
(_, _, unsupported : _, _) -> die $ "Error: cabal: unrecognized 'doctest' option `" <> unsupported <> "'"
39+
(xs, _, _, _) | ListOptions `elem` xs -> do
40+
let
41+
names :: [String]
42+
names = concat [map (\ c -> ['-', c]) short ++ map ("--" <> ) long | Option short long _ _ <- documentedOptions]
43+
putStr (unlines names)
44+
exitSuccess
45+
(_, _, unsupported : _, _) -> do
46+
die $ "Error: cabal: unrecognized 'doctest' option `" <> unsupported <> "'"
4047
_ -> pass
4148

42-
data Argument = Argument {
43-
argumentName :: String
44-
, argumentValue :: Maybe String
45-
}
49+
data Argument = Argument String (Maybe String) | ListOptions
50+
deriving (Eq, Show)
4651

4752
options :: [OptDescr Argument]
48-
options = map toOptDescr Repl.options
53+
options =
54+
Option [] ["list-options"] (NoArg ListOptions) ""
55+
: documentedOptions
56+
57+
documentedOptions :: [OptDescr Argument]
58+
documentedOptions = map toOptDescr Repl.options
4959
where
5060
toOptDescr :: Repl.Option -> OptDescr Argument
5161
toOptDescr (Repl.Option long short arg help) = Option (maybeToList short) [long] (toArgDescr long arg) help
@@ -57,17 +67,8 @@ options = map toOptDescr Repl.options
5767
Repl.OptionalArgument name -> OptArg argument name
5868
where
5969
argument :: Maybe String -> Argument
60-
argument argumentValue = Argument {
61-
argumentName = "--" <> long
62-
, argumentValue
63-
}
70+
argument value = Argument ("--" <> long) value
6471

6572
discardReplOptions :: [String] -> [String]
6673
discardReplOptions args = case getOpt Permute options args of
67-
(xs, _, _) -> concatMap values (filter (not . isReplOnlyOption) xs)
68-
where
69-
isReplOnlyOption :: Argument -> Bool
70-
isReplOnlyOption arg = Set.member (argumentName arg) replOnlyOptions
71-
72-
values :: Argument -> [String]
73-
values (Argument name value) = name : maybeToList value
74+
(xs, _, _) -> concat [name : maybeToList value | Argument name value <- xs, Set.notMember name replOnlyOptions]

test/Cabal/OptionsSpec.hs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ import System.IO
99
import System.IO.Silently
1010
import System.Exit
1111
import System.Process
12+
import Data.Set ((\\))
1213
import qualified Data.Set as Set
1314

15+
import qualified Cabal.ReplOptionsSpec as Repl
16+
1417
import Cabal.Options
1518

1619
spec :: Spec
@@ -19,7 +22,7 @@ spec = do
1922
it "is the set of options that are unique to 'cabal repl'" $ do
2023
build <- Set.fromList . lines <$> readProcess "cabal" ["build", "--list-options"] ""
2124
repl <- Set.fromList . lines <$> readProcess "cabal" ["repl", "--list-options"] ""
22-
Set.toList replOnlyOptions `shouldMatchList` Set.toList (Set.difference repl build)
25+
Set.toList replOnlyOptions `shouldMatchList` Set.toList (repl \\ build)
2326

2427
describe "rejectUnsupportedOptions" $ do
2528
it "produces error messages that are consistent with 'cabal repl'" $ do
@@ -34,6 +37,13 @@ spec = do
3437
#endif
3538
shouldFail "doctest" $ rejectUnsupportedOptions ["--installdir"]
3639

40+
context "with --list-options" $ do
41+
it "lists supported command-line options" $ do
42+
repl <- Set.fromList . lines <$> readProcess "cabal" ["repl", "--list-options"] ""
43+
doctest <- Set.fromList . lines <$> capture_ (rejectUnsupportedOptions ["--list-options"] `shouldThrow` (== ExitSuccess))
44+
Set.toList (doctest \\ repl) `shouldMatchList` []
45+
Set.toList (repl \\ doctest) `shouldMatchList` Set.toList Repl.unsupported
46+
3747
describe "discardReplOptions" $ do
3848
it "discards 'cabal repl'-only options" $ do
3949
discardReplOptions [

test/Cabal/ReplOptionsSpec.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{-# LANGUAGE LambdaCase #-}
22
{-# LANGUAGE ViewPatterns #-}
3-
module Cabal.ReplOptionsSpec (spec) where
3+
module Cabal.ReplOptionsSpec (spec, unsupported) where
44

55
import Imports
66

@@ -28,6 +28,9 @@ undocumented = Set.fromList [
2828
, "--haddock-hyperlinked-source"
2929
]
3030

31+
unsupported :: Set String
32+
unsupported = undocumented <> Set.fromList (map ("--" <>) phony)
33+
3134
spec :: Spec
3235
spec = do
3336
describe "options" $ do
@@ -37,15 +40,12 @@ spec = do
3740

3841
it "is consistent with 'cabal repl --list-options'" $ do
3942
let
40-
exclude :: Set String
41-
exclude = undocumented <> Set.fromList (map ("--" <>) phony)
42-
4343
optionNames :: Option -> [String]
4444
optionNames option = reverse $ "--" <> optionName option : case optionShortName option of
4545
Nothing -> []
4646
Just c -> [['-', c]]
4747

48-
repl <- filter (`Set.notMember` exclude) . lines <$> readProcess "cabal" ["repl", "--list-options"] ""
48+
repl <- filter (`Set.notMember` unsupported) . lines <$> readProcess "cabal" ["repl", "--list-options"] ""
4949
concatMap optionNames options `shouldBe` repl
5050

5151
parseOptions :: String -> [Option]

0 commit comments

Comments
 (0)