人気ブログランキング | 話題のタグを見る

Distribution.Simple.Setup

前へ 目次 次へ

参照: cabal-instsll 関連のリンク Distribution.Simple.Commnad Distribution.Simple.Setup

前回の commandShowOptions 関数の調査の過程で、CommandUI が1つの Cabal サブコマンドに対応し、そのコマンド・ライン・オプションの情報を全てもっていること。また、コマンド・ライン・オプションのコントロールにそのサブコマンドに特有のフラグが使われていることがわかった。

そういう目で見ると、Distribution.Simple.Setup モジュールがそのような Cabal のサブコマンドの CommandUI と フラグの定義を集めたものであることが見えてきた。

以下に Distribution.Simple.Commnad で定義されている名前を抜き出してみたが、CommnadUI とフラグの定義でほぼ全てが埋まっているのが分かるだろう。

data GlobalFlags
emptyGlobalFlags :: GlobalFlags
defaultGlobalFlags :: GlobalFlags
globalCommand :: CommandUI GlobalFlags

data ConfigFlags
emptyConfigFlags :: ConfigFlags
defaultConfigFlags :: ProgramConfiguration -> ConfigFlags
configureCommand :: ProgramConfiguration -> CommandUI ConfigFlags

data CopyFlags
emptyCopyFlags :: CopyFlags
defaultCopyFlags :: CopyFlags
copyCommand :: CommandUI CopyFlags

data InstallFlags
emptyInstallFlags :: InstallFlags
defaultInstallFlags :: InstallFlags
installCommand :: CommandUI InstallFlags

data HaddockFlags
emptyHaddockFlags :: HaddockFlags
defaultHaddockFlags :: HaddockFlags
haddockCommand :: CommandUI HaddockFlags

data HscolourFlags
emptyHscolourFlags :: HscolourFlags
defaultHscolourFlags :: HscolourFlags
hscolourCommand :: CommandUI HscolourFlags

data BuildFlags
emptyBuildFlags :: BuildFlags
defaultBuildFlags :: BuildFlags
buildCommand :: ProgramConfiguration -> CommandUI BuildFlags

data CleanFlags
emptyCleanFlags :: CleanFlags
defaultCleanFlags :: CleanFlags
cleanCommand :: CommandUI CleanFlags

data RegisterFlags
emptyRegisterFlags :: RegisterFlags
defaultRegisterFlags :: RegisterFlags
registerCommand :: CommandUI RegisterFlags
unregisterCommand :: CommandUI RegisterFlags

data SDistFlags
emptySDistFlags :: SDistFlags
defaultSDistFlags :: SDistFlags
sdistCommand :: CommandUI SDistFlags

data TestFlags
emptyTestFlags :: TestFlags
defaultTestFlags :: TestFlags
testCommand :: CommandUI TestFlags

data TestShowDetails

data BenchmarkFlags
emptyBenchmarkFlags :: BenchmarkFlags
defaultBenchmarkFlags :: BenchmarkFlags
benchmarkCommand :: CommandUI BenchmarkFlags

data CopyDest

configureArgs :: Bool -> ConfigFlags -> [String]
configureOptions :: ShowOrParseArgs -> [OptionField ConfigFlags]
configureCCompiler :: Verbosity -> ProgramConfiguration -> IO (FilePath, [String])
configureLinker :: Verbosity -> ProgramConfiguration -> IO (FilePath, [String])
installDirsOptions :: [OptionField (InstallDirs (Flag PathTemplate))]

data Flag a
toFlag :: a -> Flag a
fromFlag :: Flag a -> a
fromFlagOrDefault :: a -> Flag a -> a
flagToMaybe :: Flag a -> Maybe a
flagToList :: Flag a -> [a]
boolOpt :: SFlags -> SFlags -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) a
boolOpt' :: OptFlags -> OptFlags -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) a
trueArg :: SFlags -> LFlags -> Description -> (b -> Flag Bool) -> (Flag Bool -> b -> b) -> OptDescr b
falseArg :: SFlags -> LFlags -> Description -> (b -> Flag Bool) -> (Flag Bool -> b -> b) -> OptDescr b
optionVerbosity :: (flags -> Flag Verbosity) -> (Flag Verbosity -> flags -> flags) -> OptionField flags

これらの CommandUI 抽象とフラグの内容は ghci で簡単に調べることができる。たとえば InstallFlags の構成を知ろうと思ったら :info コマンドを使う。

Prelude> :set prompt "ghci> "
ghci> import Distribution.Simple.Command
ghci> import Distribution.Simple.Setup

ghci> :info InstallFlags
data InstallFlags
  = InstallFlags {installPackageDB :: Flag
                                        Distribution.Simple.Compiler.PackageDB,
                  installDistPref :: Flag FilePath,
                  installUseWrapper :: Flag Bool,
                  installInPlace :: Flag Bool,
                  installVerbosity :: Flag Distribution.Verbosity.Verbosity}
        -- Defined in `Distribution.Simple.Setup'
instance Show InstallFlags
  -- Defined in `Distribution.Simple.Setup'

InstallFlags は Show クラスのインスタンスなのがわかるので、defaultInstallFlags を表示してみる。

ghci> defaultInstallFlags
InstallFlags {installPackageDB = NoFlag, installDistPref = Flag "dist", installUseWrapper = Flag False, installInPlace = Flag False, installVerbosity = Flag Normal}

CommandUI 型の詳細を知りたい場合も :info コマンドを使う。

ghci> :info CommandUI
data CommandUI flags
  = CommandUI {commandName :: String,
               commandSynopsis :: String,
               commandUsage :: String -> String,
               commandDescription :: Maybe (String -> String),
               commandDefaultFlags :: flags,
               commandOptions :: ShowOrParseArgs -> [OptionField flags]}
        -- Defined in `Distribution.Simple.Command'

installCommnad のコマンド名を知りたいときは commandName アクセサを使う。

ghci> commandName installCommand
"install"

installCommand のオプションが defaultInstallFlags ではどのように設定されているかを見るには commnadShowOptions 関数を使う。

ghci> commandShowOptions installCommand defaultInstallFlags
["--verbose=1","--builddir=dist","--disable-shell-wrappers"]

また、Distribution.Simple.Setup では CommandUI とflags 以外に Flag 型が定義されているが、つぎのような構成になっている。

ghci> :info Flag
data Flag a = Flag a | NoFlag
  -- Defined in `Distribution.Simple.Setup'
instance Bounded a => Bounded (Flag a)
  -- Defined in `Distribution.Simple.Setup'
instance Enum a => Enum (Flag a)
  -- Defined in `Distribution.Simple.Setup'
instance Eq a => Eq (Flag a)
  -- Defined in `Distribution.Simple.Setup'
instance Functor Flag -- Defined in `Distribution.Simple.Setup'
instance Read a => Read (Flag a)
  -- Defined in `Distribution.Simple.Setup'
instance Show a => Show (Flag a)
  -- Defined in `Distribution.Simple.Setup'

フラグには色々な型があったり、そもそもフラグがない場合もあるので、それらを統一的に扱うためのラッパーが Flag 型だ。Haskell のリストでは、要素の型はひとつだけしか許されていないが、このような代数的データ型を定義することによっていろいろな型のデータを混在させることができる。

Flag 型は Show クラスのインスタンスなので、show 関数で文字列に変換できる。したがって、ghci で値を簡単に表示できる。その他にもいろいろなクラスのインスタンスとして宣言されている。

ghci> Flag "foo"
Flag "foo"

toFlag などの関数は、Flag 型のパラメータをラッピングしたり、取り出したりする関数だ。

ghci> toFlag "bar"
Flag "bar"
ghci> fromFlag (Flag "baz")
"baz"

これで、CommandUI flags 型 と flags の使い方がわかったし、Distribution.Simple.Setup モジュールに何が定義されているかの概要がつかめたので、次回の記事では、再び Distribution.Simple.Commnad に定義されているデータ型の解明に挑戦する。
by tnomura9 | 2014-01-09 20:36 | Haskell | Comments(0)
<< CommandParse flags commandShowOptions >>