{-# LANGUAGE StandaloneDeriving #-}

-- | Command line options for nix-style / v2 commands.
--
-- The commands take a lot of the same options, which affect how install plan
-- is constructed.
module Distribution.Client.NixStyleOptions
  ( NixStyleFlags (..)
  , nixStyleOptions
  , defaultNixStyleFlags
  , updNixStyleCommonSetupFlags
  ) where

import Distribution.Client.Compat.Prelude
import Prelude ()

import Distribution.Simple.Command (OptionField (..), ShowOrParseArgs)
import Distribution.Simple.Setup
  ( BenchmarkFlags (benchmarkCommonFlags)
  , CommonSetupFlags (..)
  , HaddockFlags (..)
  , TestFlags (testCommonFlags)
  )
import Distribution.Solver.Types.ConstraintSource (ConstraintSource (..))

import Distribution.Client.ProjectFlags
  ( ProjectFlags (..)
  , defaultProjectFlags
  , projectFlagsOptions
  )
import Distribution.Client.Setup
  ( ConfigExFlags
  , ConfigFlags (..)
  , InstallFlags (..)
  , benchmarkOptions
  , configureExOptions
  , configureOptions
  , haddockOptions
  , installOptions
  , liftOptions
  , testOptions
  )

data NixStyleFlags a = NixStyleFlags
  { forall a. NixStyleFlags a -> ConfigFlags
configFlags :: ConfigFlags
  , forall a. NixStyleFlags a -> ConfigExFlags
configExFlags :: ConfigExFlags
  , forall a. NixStyleFlags a -> InstallFlags
installFlags :: InstallFlags
  , forall a. NixStyleFlags a -> HaddockFlags
haddockFlags :: HaddockFlags
  , forall a. NixStyleFlags a -> TestFlags
testFlags :: TestFlags
  , forall a. NixStyleFlags a -> BenchmarkFlags
benchmarkFlags :: BenchmarkFlags
  , forall a. NixStyleFlags a -> ProjectFlags
projectFlags :: ProjectFlags
  , forall a. NixStyleFlags a -> a
extraFlags :: a
  }

nixStyleOptions
  :: (ShowOrParseArgs -> [OptionField a])
  -> ShowOrParseArgs
  -> [OptionField (NixStyleFlags a)]
nixStyleOptions :: forall a.
(ShowOrParseArgs -> [OptionField a])
-> ShowOrParseArgs -> [OptionField (NixStyleFlags a)]
nixStyleOptions ShowOrParseArgs -> [OptionField a]
commandOptions ShowOrParseArgs
showOrParseArgs =
  (NixStyleFlags a -> ConfigFlags)
-> (ConfigFlags -> NixStyleFlags a -> NixStyleFlags a)
-> [OptionField ConfigFlags]
-> [OptionField (NixStyleFlags a)]
forall b a.
(b -> a) -> (a -> b -> b) -> [OptionField a] -> [OptionField b]
liftOptions
    NixStyleFlags a -> ConfigFlags
forall a. NixStyleFlags a -> ConfigFlags
configFlags
    ConfigFlags -> NixStyleFlags a -> NixStyleFlags a
forall {a}. ConfigFlags -> NixStyleFlags a -> NixStyleFlags a
set1
    -- Note: [Hidden Flags]
    -- We reuse the configure options from v1 commands which on their turn
    -- reuse the ones from Cabal) but we hide some of them in v2 commands.
    ( (OptionField ConfigFlags -> Bool)
-> [OptionField ConfigFlags] -> [OptionField ConfigFlags]
forall a. (a -> Bool) -> [a] -> [a]
filter
        ( ( String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem`
              [ String
"cabal-file"
              , String
"constraint"
              , String
"dependency"
              , String
"promised-dependency"
              , String
"exact-configuration"
              ]
          )
            (String -> Bool)
-> (OptionField ConfigFlags -> String)
-> OptionField ConfigFlags
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OptionField ConfigFlags -> String
forall a. OptionField a -> String
optionName
        )
        ([OptionField ConfigFlags] -> [OptionField ConfigFlags])
-> [OptionField ConfigFlags] -> [OptionField ConfigFlags]
forall a b. (a -> b) -> a -> b
$ ShowOrParseArgs -> [OptionField ConfigFlags]
configureOptions ShowOrParseArgs
showOrParseArgs
    )
    [OptionField (NixStyleFlags a)]
-> [OptionField (NixStyleFlags a)]
-> [OptionField (NixStyleFlags a)]
forall a. [a] -> [a] -> [a]
++ (NixStyleFlags a -> ConfigExFlags)
-> (ConfigExFlags -> NixStyleFlags a -> NixStyleFlags a)
-> [OptionField ConfigExFlags]
-> [OptionField (NixStyleFlags a)]
forall b a.
(b -> a) -> (a -> b -> b) -> [OptionField a] -> [OptionField b]
liftOptions
      NixStyleFlags a -> ConfigExFlags
forall a. NixStyleFlags a -> ConfigExFlags
configExFlags
      ConfigExFlags -> NixStyleFlags a -> NixStyleFlags a
forall {a}. ConfigExFlags -> NixStyleFlags a -> NixStyleFlags a
set2
      ( ShowOrParseArgs -> ConstraintSource -> [OptionField ConfigExFlags]
configureExOptions
          ShowOrParseArgs
showOrParseArgs
          ConstraintSource
ConstraintSourceCommandlineFlag
      )
    [OptionField (NixStyleFlags a)]
-> [OptionField (NixStyleFlags a)]
-> [OptionField (NixStyleFlags a)]
forall a. [a] -> [a] -> [a]
++ (NixStyleFlags a -> InstallFlags)
-> (InstallFlags -> NixStyleFlags a -> NixStyleFlags a)
-> [OptionField InstallFlags]
-> [OptionField (NixStyleFlags a)]
forall b a.
(b -> a) -> (a -> b -> b) -> [OptionField a] -> [OptionField b]
liftOptions
      NixStyleFlags a -> InstallFlags
forall a. NixStyleFlags a -> InstallFlags
installFlags
      InstallFlags -> NixStyleFlags a -> NixStyleFlags a
forall {a}. InstallFlags -> NixStyleFlags a -> NixStyleFlags a
set3
      -- hide "target-package-db" and "symlink-bindir" flags from the
      -- install options.
      -- "symlink-bindir" is obsoleted by "installdir" in ClientInstallFlags
      ( (OptionField InstallFlags -> Bool)
-> [OptionField InstallFlags] -> [OptionField InstallFlags]
forall a. (a -> Bool) -> [a] -> [a]
filter
          ( (String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [String
"target-package-db", String
"symlink-bindir"])
              (String -> Bool)
-> (OptionField InstallFlags -> String)
-> OptionField InstallFlags
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OptionField InstallFlags -> String
forall a. OptionField a -> String
optionName
          )
          ([OptionField InstallFlags] -> [OptionField InstallFlags])
-> [OptionField InstallFlags] -> [OptionField InstallFlags]
forall a b. (a -> b) -> a -> b
$ ShowOrParseArgs -> [OptionField InstallFlags]
installOptions ShowOrParseArgs
showOrParseArgs
      )
    [OptionField (NixStyleFlags a)]
-> [OptionField (NixStyleFlags a)]
-> [OptionField (NixStyleFlags a)]
forall a. [a] -> [a] -> [a]
++ (NixStyleFlags a -> HaddockFlags)
-> (HaddockFlags -> NixStyleFlags a -> NixStyleFlags a)
-> [OptionField HaddockFlags]
-> [OptionField (NixStyleFlags a)]
forall b a.
(b -> a) -> (a -> b -> b) -> [OptionField a] -> [OptionField b]
liftOptions
      NixStyleFlags a -> HaddockFlags
forall a. NixStyleFlags a -> HaddockFlags
haddockFlags
      HaddockFlags -> NixStyleFlags a -> NixStyleFlags a
forall {a}. HaddockFlags -> NixStyleFlags a -> NixStyleFlags a
set4
      -- hide "verbose" and "builddir" flags from the
      -- haddock options.
      ( (OptionField HaddockFlags -> Bool)
-> [OptionField HaddockFlags] -> [OptionField HaddockFlags]
forall a. (a -> Bool) -> [a] -> [a]
filter
          ( (String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [String
"v", String
"verbose", String
"builddir"])
              (String -> Bool)
-> (OptionField HaddockFlags -> String)
-> OptionField HaddockFlags
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OptionField HaddockFlags -> String
forall a. OptionField a -> String
optionName
          )
          ([OptionField HaddockFlags] -> [OptionField HaddockFlags])
-> [OptionField HaddockFlags] -> [OptionField HaddockFlags]
forall a b. (a -> b) -> a -> b
$ ShowOrParseArgs -> [OptionField HaddockFlags]
haddockOptions ShowOrParseArgs
showOrParseArgs
      )
    [OptionField (NixStyleFlags a)]
-> [OptionField (NixStyleFlags a)]
-> [OptionField (NixStyleFlags a)]
forall a. [a] -> [a] -> [a]
++ (NixStyleFlags a -> TestFlags)
-> (TestFlags -> NixStyleFlags a -> NixStyleFlags a)
-> [OptionField TestFlags]
-> [OptionField (NixStyleFlags a)]
forall b a.
(b -> a) -> (a -> b -> b) -> [OptionField a] -> [OptionField b]
liftOptions NixStyleFlags a -> TestFlags
forall a. NixStyleFlags a -> TestFlags
testFlags TestFlags -> NixStyleFlags a -> NixStyleFlags a
forall {a}. TestFlags -> NixStyleFlags a -> NixStyleFlags a
set5 (ShowOrParseArgs -> [OptionField TestFlags]
testOptions ShowOrParseArgs
showOrParseArgs)
    [OptionField (NixStyleFlags a)]
-> [OptionField (NixStyleFlags a)]
-> [OptionField (NixStyleFlags a)]
forall a. [a] -> [a] -> [a]
++ (NixStyleFlags a -> BenchmarkFlags)
-> (BenchmarkFlags -> NixStyleFlags a -> NixStyleFlags a)
-> [OptionField BenchmarkFlags]
-> [OptionField (NixStyleFlags a)]
forall b a.
(b -> a) -> (a -> b -> b) -> [OptionField a] -> [OptionField b]
liftOptions NixStyleFlags a -> BenchmarkFlags
forall a. NixStyleFlags a -> BenchmarkFlags
benchmarkFlags BenchmarkFlags -> NixStyleFlags a -> NixStyleFlags a
forall {a}. BenchmarkFlags -> NixStyleFlags a -> NixStyleFlags a
set6 (ShowOrParseArgs -> [OptionField BenchmarkFlags]
benchmarkOptions ShowOrParseArgs
showOrParseArgs)
    [OptionField (NixStyleFlags a)]
-> [OptionField (NixStyleFlags a)]
-> [OptionField (NixStyleFlags a)]
forall a. [a] -> [a] -> [a]
++ (NixStyleFlags a -> ProjectFlags)
-> (ProjectFlags -> NixStyleFlags a -> NixStyleFlags a)
-> [OptionField ProjectFlags]
-> [OptionField (NixStyleFlags a)]
forall b a.
(b -> a) -> (a -> b -> b) -> [OptionField a] -> [OptionField b]
liftOptions NixStyleFlags a -> ProjectFlags
forall a. NixStyleFlags a -> ProjectFlags
projectFlags ProjectFlags -> NixStyleFlags a -> NixStyleFlags a
forall {a}. ProjectFlags -> NixStyleFlags a -> NixStyleFlags a
set7 (ShowOrParseArgs -> [OptionField ProjectFlags]
projectFlagsOptions ShowOrParseArgs
showOrParseArgs)
    [OptionField (NixStyleFlags a)]
-> [OptionField (NixStyleFlags a)]
-> [OptionField (NixStyleFlags a)]
forall a. [a] -> [a] -> [a]
++ (NixStyleFlags a -> a)
-> (a -> NixStyleFlags a -> NixStyleFlags a)
-> [OptionField a]
-> [OptionField (NixStyleFlags a)]
forall b a.
(b -> a) -> (a -> b -> b) -> [OptionField a] -> [OptionField b]
liftOptions NixStyleFlags a -> a
forall a. NixStyleFlags a -> a
extraFlags a -> NixStyleFlags a -> NixStyleFlags a
forall {a} {a}. a -> NixStyleFlags a -> NixStyleFlags a
set8 (ShowOrParseArgs -> [OptionField a]
commandOptions ShowOrParseArgs
showOrParseArgs)
  where
    set1 :: ConfigFlags -> NixStyleFlags a -> NixStyleFlags a
set1 ConfigFlags
x NixStyleFlags a
flags = NixStyleFlags a
flags{configFlags = x}
    set2 :: ConfigExFlags -> NixStyleFlags a -> NixStyleFlags a
set2 ConfigExFlags
x NixStyleFlags a
flags = NixStyleFlags a
flags{configExFlags = x}
    set3 :: InstallFlags -> NixStyleFlags a -> NixStyleFlags a
set3 InstallFlags
x NixStyleFlags a
flags = NixStyleFlags a
flags{installFlags = x}
    set4 :: HaddockFlags -> NixStyleFlags a -> NixStyleFlags a
set4 HaddockFlags
x NixStyleFlags a
flags = NixStyleFlags a
flags{haddockFlags = x}
    set5 :: TestFlags -> NixStyleFlags a -> NixStyleFlags a
set5 TestFlags
x NixStyleFlags a
flags = NixStyleFlags a
flags{testFlags = x}
    set6 :: BenchmarkFlags -> NixStyleFlags a -> NixStyleFlags a
set6 BenchmarkFlags
x NixStyleFlags a
flags = NixStyleFlags a
flags{benchmarkFlags = x}
    set7 :: ProjectFlags -> NixStyleFlags a -> NixStyleFlags a
set7 ProjectFlags
x NixStyleFlags a
flags = NixStyleFlags a
flags{projectFlags = x}
    set8 :: a -> NixStyleFlags a -> NixStyleFlags a
set8 a
x NixStyleFlags a
flags = NixStyleFlags a
flags{extraFlags = x}

defaultNixStyleFlags :: a -> NixStyleFlags a
defaultNixStyleFlags :: forall a. a -> NixStyleFlags a
defaultNixStyleFlags a
x =
  NixStyleFlags
    { configFlags :: ConfigFlags
configFlags = ConfigFlags
forall a. Monoid a => a
mempty
    , configExFlags :: ConfigExFlags
configExFlags = ConfigExFlags
forall a. Monoid a => a
mempty
    , installFlags :: InstallFlags
installFlags = InstallFlags
forall a. Monoid a => a
mempty
    , haddockFlags :: HaddockFlags
haddockFlags = HaddockFlags
forall a. Monoid a => a
mempty
    , testFlags :: TestFlags
testFlags = TestFlags
forall a. Monoid a => a
mempty
    , benchmarkFlags :: BenchmarkFlags
benchmarkFlags = BenchmarkFlags
forall a. Monoid a => a
mempty
    , projectFlags :: ProjectFlags
projectFlags = ProjectFlags
defaultProjectFlags
    , extraFlags :: a
extraFlags = a
x
    }

updNixStyleCommonSetupFlags
  :: (CommonSetupFlags -> CommonSetupFlags)
  -> NixStyleFlags a
  -> NixStyleFlags a
updNixStyleCommonSetupFlags :: forall a.
(CommonSetupFlags -> CommonSetupFlags)
-> NixStyleFlags a -> NixStyleFlags a
updNixStyleCommonSetupFlags CommonSetupFlags -> CommonSetupFlags
setFlag NixStyleFlags a
nixFlags =
  NixStyleFlags a
nixFlags
    { configFlags =
        let flags = NixStyleFlags a -> ConfigFlags
forall a. NixStyleFlags a -> ConfigFlags
configFlags NixStyleFlags a
nixFlags
            common = ConfigFlags -> CommonSetupFlags
configCommonFlags ConfigFlags
flags
         in flags{configCommonFlags = setFlag common}
    , haddockFlags =
        let flags = NixStyleFlags a -> HaddockFlags
forall a. NixStyleFlags a -> HaddockFlags
haddockFlags NixStyleFlags a
nixFlags
            common = HaddockFlags -> CommonSetupFlags
haddockCommonFlags HaddockFlags
flags
         in flags{haddockCommonFlags = setFlag common}
    , testFlags =
        let flags = NixStyleFlags a -> TestFlags
forall a. NixStyleFlags a -> TestFlags
testFlags NixStyleFlags a
nixFlags
            common = TestFlags -> CommonSetupFlags
testCommonFlags TestFlags
flags
         in flags{testCommonFlags = setFlag common}
    , benchmarkFlags =
        let flags = NixStyleFlags a -> BenchmarkFlags
forall a. NixStyleFlags a -> BenchmarkFlags
benchmarkFlags NixStyleFlags a
nixFlags
            common = BenchmarkFlags -> CommonSetupFlags
benchmarkCommonFlags BenchmarkFlags
flags
         in flags{benchmarkCommonFlags = setFlag common}
    }