Program.hs 6.78 KB
Newer Older
ijones's avatar
ijones committed
1
2
-----------------------------------------------------------------------------
-- |
3
-- Module      :  Distribution.Simple.Program
4
-- Copyright   :  Isaac Jones 2006, Duncan Coutts 2007-2009
5
--
Duncan Coutts's avatar
Duncan Coutts committed
6
7
-- Maintainer  :  cabal-devel@haskell.org
-- Portability :  portable
ijones's avatar
ijones committed
8
--
Duncan Coutts's avatar
Duncan Coutts committed
9
10
11
12
13
14
15
16
17
18
19
20
21
-- This provides an abstraction which deals with configuring and running
-- programs. A 'Program' is a static notion of a known program. A
-- 'ConfiguredProgram' is a 'Program' that has been found on the current
-- machine and is ready to be run (possibly with some user-supplied default
-- args). Configuring a program involves finding its location and if necessary
-- finding its version. There is also a 'ProgramConfiguration' type which holds
-- configured and not-yet configured programs. It is the parameter to lots of
-- actions elsewhere in Cabal that need to look up and run programs. If we had
-- a Cabal monad, the 'ProgramConfiguration' would probably be a reader or
-- state component of it. 
--
-- The module also defines all the known built-in 'Program's and the
-- 'defaultProgramConfiguration' which contains them all.
ijones's avatar
ijones committed
22
23
24
25
26
27
28
29
30
31
32
33
34
--
-- One nice thing about using it is that any program that is
-- registered with Cabal will get some \"configure\" and \".cabal\"
-- helpers like --with-foo-args --foo-path= and extra-foo-args.
--
-- There's also good default behavior for trying to find \"foo\" in
-- PATH, being able to override its location, etc.
--
-- There's also a hook for adding programs in a Setup.lhs script.  See
-- hookedPrograms in 'Distribution.Simple.UserHooks'.  This gives a
-- hook user the ability to get the above flags and such so that they
-- don't have to write all the PATH logic inside Setup.lhs.

35
module Distribution.Simple.Program (
36
37
38
    -- * Program and functions for constructing them
      Program(..)
    , simpleProgram
39
    , findProgramOnPath
40
41
42
43
44
45
46
    , findProgramVersion

    -- * Configured program and related functions
    , ConfiguredProgram(..)
    , programPath
    , ProgArg
    , ProgramLocation(..)
47
48
    , runProgram
    , getProgramOutput
49

50
51
52
53
54
55
56
57
    -- * Program invocations
    , ProgramInvocation(..)
    , emptyProgramInvocation
    , simpleProgramInvocation
    , programInvocation
    , runProgramInvocation
    , getProgramInvocationOutput

58
59
60
61
62
63
64
    -- * The collection of unconfigured and configured progams
    , builtinPrograms

    -- * The collection of configured programs we can run
    , ProgramConfiguration
    , emptyProgramConfiguration
    , defaultProgramConfiguration
65
    , restoreProgramConfiguration
66
    , addKnownProgram
67
    , addKnownPrograms
68
    , lookupKnownProgram
69
70
    , knownPrograms
    , userSpecifyPath
71
    , userSpecifyPaths
72
73
    , userMaybeSpecifyPath
    , userSpecifyArgs
74
    , userSpecifyArgss
75
    , userSpecifiedArgs
76
77
    , lookupProgram
    , updateProgram
78
    , configureProgram
79
    , configureAllKnownPrograms
80
    , reconfigurePrograms
81
    , requireProgram
82
    , requireProgramVersion
83
84
    , runDbProgram
    , getDbProgramOutput
85
86
87
88

    -- * Programs that Cabal knows about
    , ghcProgram
    , ghcPkgProgram
89
90
    , lhcProgram
    , lhcPkgProgram
91
92
93
94
95
    , nhcProgram
    , hmakeProgram
    , jhcProgram
    , hugsProgram
    , ffihugsProgram
Duncan Coutts's avatar
Duncan Coutts committed
96
    , gccProgram
97
98
    , ranlibProgram
    , arProgram
99
    , stripProgram
100
101
102
103
104
105
106
107
108
109
110
    , happyProgram
    , alexProgram
    , hsc2hsProgram
    , c2hsProgram
    , cpphsProgram
    , hscolourProgram
    , haddockProgram
    , greencardProgram
    , ldProgram
    , tarProgram
    , cppProgram
111
    , pkgConfigProgram
112
113
114
115
116
117
118

    -- * deprecated
    , rawSystemProgram
    , rawSystemProgramStdout
    , rawSystemProgramConf
    , rawSystemProgramStdoutConf

119
    ) where
ijones's avatar
ijones committed
120

121
122
123
124
import Distribution.Simple.Program.Types
import Distribution.Simple.Program.Run
import Distribution.Simple.Program.Db
import Distribution.Simple.Program.Builtin
125

126
import Distribution.Simple.Utils
127
         ( die, findProgramOnPath, findProgramVersion )
128
import Distribution.Verbosity
129
         ( Verbosity )
130
131


132
-- | Runs the given configured program.
133
--
134
135
136
137
138
139
runProgram :: Verbosity          -- ^Verbosity
           -> ConfiguredProgram  -- ^The program to run
           -> [ProgArg]          -- ^Any /extra/ arguments to add
           -> IO ()
runProgram verbosity prog args =
  runProgramInvocation verbosity (programInvocation prog args)
140

141

142
-- | Runs the given configured program and gets the output.
143
--
144
145
146
147
148
149
getProgramOutput :: Verbosity          -- ^Verbosity
                 -> ConfiguredProgram  -- ^The program to run
                 -> [ProgArg]          -- ^Any /extra/ arguments to add
                 -> IO String
getProgramOutput verbosity prog args =
  getProgramInvocationOutput verbosity (programInvocation prog args)
150

151

152
-- | Looks up the given program in the program database and runs it.
153
--
154
155
156
157
158
159
160
runDbProgram :: Verbosity  -- ^verbosity
             -> Program    -- ^The program to run
             -> ProgramDb  -- ^look up the program here
             -> [ProgArg]  -- ^Any /extra/ arguments to add
             -> IO ()
runDbProgram verbosity prog programDb args =
  case lookupProgram prog programDb of
161
    Nothing             -> die notFound
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
    Just configuredProg -> runProgram verbosity configuredProg args
 where
   notFound = "The program " ++ programName prog
           ++ " is required but it could not be found"

-- | Looks up the given program in the program database and runs it.
--
getDbProgramOutput :: Verbosity  -- ^verbosity
                   -> Program    -- ^The program to run
                   -> ProgramDb  -- ^look up the program here
                   -> [ProgArg]  -- ^Any /extra/ arguments to add
                   -> IO String
getDbProgramOutput verbosity prog programDb args =
  case lookupProgram prog programDb of
    Nothing             -> die notFound
    Just configuredProg -> getProgramOutput verbosity configuredProg args
 where
   notFound = "The program " ++ programName prog
           ++ " is required but it could not be found"
181
182


183
184
---------------------
-- Deprecated aliases
185
--
ijones's avatar
ijones committed
186

187
188
189
rawSystemProgram :: Verbosity -> ConfiguredProgram
                 -> [ProgArg] -> IO ()
rawSystemProgram = runProgram
ekarttun's avatar
ekarttun committed
190

191
192
193
rawSystemProgramStdout :: Verbosity -> ConfiguredProgram
                       -> [ProgArg] -> IO String
rawSystemProgramStdout = getProgramOutput
194

195
196
197
rawSystemProgramConf :: Verbosity  -> Program -> ProgramConfiguration
                     -> [ProgArg] -> IO ()
rawSystemProgramConf = runDbProgram
David Himmelstrup's avatar
David Himmelstrup committed
198

199
200
201
rawSystemProgramStdoutConf :: Verbosity -> Program -> ProgramConfiguration
                           -> [ProgArg] -> IO String
rawSystemProgramStdoutConf = getDbProgramOutput
ijones's avatar
ijones committed
202

203
type ProgramConfiguration = ProgramDb
204

205
206
207
emptyProgramConfiguration, defaultProgramConfiguration :: ProgramConfiguration
emptyProgramConfiguration   = emptyProgramDb
defaultProgramConfiguration = defaultProgramDb
208

209
210
211
restoreProgramConfiguration :: [Program] -> ProgramConfiguration
                                         -> ProgramConfiguration
restoreProgramConfiguration = restoreProgramDb