@@ -85,12 +85,15 @@ module Distribution.Simple.Command
85
85
import Distribution.Compat.Prelude hiding (get )
86
86
import Prelude ()
87
87
88
+ import Control.Exception (try )
88
89
import qualified Data.Array as Array
89
90
import qualified Data.List as List
90
91
import Distribution.Compat.Lens (ALens' , (#~) , (^#) )
91
92
import qualified Distribution.GetOpt as GetOpt
92
93
import Distribution.ReadE
93
94
import Distribution.Simple.Utils
95
+ import System.Directory (findExecutable )
96
+ import System.Process (callProcess )
94
97
95
98
data CommandUI flags = CommandUI
96
99
{ commandName :: String
@@ -596,11 +599,13 @@ data CommandParse flags
596
599
| CommandList [String ]
597
600
| CommandErrors [String ]
598
601
| CommandReadyToGo flags
602
+ | CommandDelegate
599
603
instance Functor CommandParse where
600
604
fmap _ (CommandHelp help) = CommandHelp help
601
605
fmap _ (CommandList opts) = CommandList opts
602
606
fmap _ (CommandErrors errs) = CommandErrors errs
603
607
fmap f (CommandReadyToGo flags) = CommandReadyToGo (f flags)
608
+ fmap _ CommandDelegate = CommandDelegate
604
609
605
610
data CommandType = NormalCommand | HiddenCommand
606
611
data Command action
@@ -631,25 +636,38 @@ commandsRun
631
636
:: CommandUI a
632
637
-> [Command action ]
633
638
-> [String ]
634
- -> CommandParse (a , CommandParse action )
639
+ -> IO ( CommandParse (a , CommandParse action ) )
635
640
commandsRun globalCommand commands args =
636
641
case commandParseArgs globalCommand True args of
637
- CommandHelp help -> CommandHelp help
638
- CommandList opts -> CommandList (opts ++ commandNames)
639
- CommandErrors errs -> CommandErrors errs
642
+ CommandDelegate -> pure CommandDelegate
643
+ CommandHelp help -> pure $ CommandHelp help
644
+ CommandList opts -> pure $ CommandList (opts ++ commandNames)
645
+ CommandErrors errs -> pure $ CommandErrors errs
640
646
CommandReadyToGo (mkflags, args') -> case args' of
641
- (" help" : cmdArgs) -> handleHelpCommand cmdArgs
647
+ (" help" : cmdArgs) -> pure $ handleHelpCommand cmdArgs
642
648
(name : cmdArgs) -> case lookupCommand name of
643
649
[Command _ _ action _] ->
644
- CommandReadyToGo (flags, action cmdArgs)
645
- _ -> CommandReadyToGo (flags, badCommand name)
646
- [] -> CommandReadyToGo (flags, noCommand)
650
+ pure $ CommandReadyToGo (flags, action cmdArgs)
651
+ _ -> do
652
+ mCommand <- findExecutable $ " cabal-" <> name
653
+ case mCommand of
654
+ Just exec -> callExternal flags exec cmdArgs
655
+ Nothing -> pure $ CommandReadyToGo (flags, badCommand name)
656
+ [] -> pure $ CommandReadyToGo (flags, noCommand)
647
657
where
648
658
flags = mkflags (commandDefaultFlags globalCommand)
649
659
where
650
660
lookupCommand cname =
651
661
[ cmd | cmd@ (Command cname' _ _ _) <- commands', cname' == cname
652
662
]
663
+
664
+ callExternal :: a -> String -> [String ] -> IO (CommandParse (a , CommandParse action ))
665
+ callExternal flags exec cmdArgs = do
666
+ result <- try $ callProcess exec cmdArgs
667
+ case result of
668
+ Left ex -> pure $ CommandErrors [" Error executing external command: " ++ show (ex :: SomeException )]
669
+ Right _ -> pure $ CommandReadyToGo (flags, CommandDelegate )
670
+
653
671
noCommand = CommandErrors [" no command given (try --help)\n " ]
654
672
655
673
-- Print suggested command if edit distance is < 5
@@ -679,6 +697,7 @@ commandsRun globalCommand commands args =
679
697
-- furthermore, support "prog help command" as "prog command --help"
680
698
handleHelpCommand cmdArgs =
681
699
case commandParseArgs helpCommandUI True cmdArgs of
700
+ CommandDelegate -> CommandDelegate
682
701
CommandHelp help -> CommandHelp help
683
702
CommandList list -> CommandList (list ++ commandNames)
684
703
CommandErrors _ -> CommandHelp globalHelp
0 commit comments