@@ -10,7 +10,6 @@ module Stack.Build.Source
10
10
, loadCommonPackage
11
11
, loadLocalPackage
12
12
, loadSourceMap
13
- , getLocalFlags
14
13
, addUnlistedToBuildCache
15
14
, hashSourceMapData
16
15
) where
@@ -32,12 +31,12 @@ import Stack.Package
32
31
import Stack.PackageFile ( getPackageFile )
33
32
import Stack.Prelude
34
33
import Stack.SourceMap
35
- ( DumpedGlobalPackage , checkFlagsUsedThrowing
36
- , getCompilerInfo , immutableLocSha , mkProjectPackage
37
- , pruneGlobals
34
+ ( DumpedGlobalPackage , getCompilerInfo , immutableLocSha
35
+ , mkProjectPackage , pruneGlobals
38
36
)
39
37
import Stack.Types.ApplyGhcOptions ( ApplyGhcOptions (.. ) )
40
38
import Stack.Types.ApplyProgOptions ( ApplyProgOptions (.. ) )
39
+ import Stack.Types.Build.Exception ( BuildPrettyException (.. ) )
41
40
import Stack.Types.BuildConfig
42
41
( BuildConfig (.. ), HasBuildConfig (.. ) )
43
42
import Stack.Types.BuildOpts ( BuildOpts (.. ), TestOpts (.. ) )
@@ -69,7 +68,7 @@ import Stack.Types.SourceMap
69
68
, SMActual (.. ), SMTargets (.. ), SourceMap (.. )
70
69
, SourceMapHash (.. ), Target (.. ), ppGPD , ppRoot
71
70
)
72
- import Stack.Types.UnusedFlags ( FlagSource (.. ) )
71
+ import Stack.Types.UnusedFlags ( FlagSource (.. ), UnusedFlags ( .. ) )
73
72
import System.FilePath ( takeFileName )
74
73
import System.IO.Error ( isDoesNotExistError )
75
74
@@ -93,51 +92,25 @@ localDependencies = do
93
92
94
93
-- | Given the parsed targets and build command line options constructs a source
95
94
-- map
96
- loadSourceMap :: HasBuildConfig env
97
- => SMTargets
98
- -> BuildOptsCLI
99
- -> SMActual DumpedGlobalPackage
100
- -> RIO env SourceMap
95
+ loadSourceMap ::
96
+ forall env . HasBuildConfig env
97
+ => SMTargets
98
+ -> BuildOptsCLI
99
+ -> SMActual DumpedGlobalPackage
100
+ -> RIO env SourceMap
101
101
loadSourceMap targets boptsCli sma = do
102
- bconfig <- view buildConfigL
102
+ logDebug " Applying and checking flags"
103
+ let errsPackages = mapMaybe checkPackage packagesWithCliFlags
104
+ eProject <- mapM applyOptsFlagsPP (M. toList sma. project)
105
+ eDeps <- mapM applyOptsFlagsDep (M. toList targetsAndSmaDeps)
106
+ let (errsProject, project') = partitionEithers eProject
107
+ (errsDeps, deps') = partitionEithers eDeps
108
+ errs = errsPackages <> errsProject <> errsDeps
109
+ unless (null errs) $ prettyThrowM $ InvalidFlagSpecification errs
103
110
let compiler = sma. compiler
104
- project = M. map applyOptsFlagsPP sma. project
105
- bopts = bconfig. config. build
106
- applyOptsFlagsPP p@ ProjectPackage { projectCommon = c } = p
107
- { projectCommon = applyOptsFlags (M. member c. name targets. targets) True c }
108
- deps0 = targets. deps <> sma. deps
109
- deps = M. map applyOptsFlagsDep deps0
110
- applyOptsFlagsDep d@ DepPackage { depCommon = c } = d
111
- { depCommon = applyOptsFlags (M. member c. name targets. deps) False c }
112
- applyOptsFlags isTarget isProjectPackage common =
113
- let name = common. name
114
- flags = getLocalFlags boptsCli name
115
- ghcOptions =
116
- generalGhcOptions bconfig boptsCli isTarget isProjectPackage
117
- cabalConfigOpts =
118
- generalCabalConfigOpts bconfig boptsCli common. name isTarget isProjectPackage
119
- in common
120
- { flags =
121
- if M. null flags
122
- then common. flags
123
- else flags
124
- , ghcOptions =
125
- ghcOptions ++ common. ghcOptions
126
- , cabalConfigOpts =
127
- cabalConfigOpts ++ common. cabalConfigOpts
128
- , buildHaddocks =
129
- if isTarget
130
- then bopts. buildHaddocks
131
- else shouldHaddockDeps bopts
132
- }
133
- packageCliFlags = Map. fromList $
134
- mapMaybe maybeProjectFlags $
135
- Map. toList boptsCli. flags
136
- maybeProjectFlags (ACFByName name, fs) = Just (name, fs)
137
- maybeProjectFlags _ = Nothing
111
+ project = M. fromList project'
112
+ deps = M. fromList deps'
138
113
globalPkgs = pruneGlobals sma. globals (Map. keysSet deps)
139
- logDebug " Checking flags"
140
- checkFlagsUsedThrowing packageCliFlags FSCommandLine project deps
141
114
logDebug " SourceMap constructed"
142
115
pure SourceMap
143
116
{ targets
@@ -146,6 +119,90 @@ loadSourceMap targets boptsCli sma = do
146
119
, deps
147
120
, globalPkgs
148
121
}
122
+ where
123
+ cliFlags = boptsCli. flags
124
+ targetsAndSmaDeps = targets. deps <> sma. deps
125
+ packagesWithCliFlags = mapMaybe maybeProjectWithCliFlags $ Map. toList cliFlags
126
+ where
127
+ maybeProjectWithCliFlags (ACFByName name, _) = Just name
128
+ maybeProjectWithCliFlags _ = Nothing
129
+ checkPackage :: PackageName -> Maybe UnusedFlags
130
+ checkPackage name =
131
+ let maybeCommon =
132
+ fmap (. projectCommon) (Map. lookup name sma. project)
133
+ <|> fmap (. depCommon) (Map. lookup name targetsAndSmaDeps)
134
+ in maybe
135
+ (Just $ UFNoPackage FSCommandLine name)
136
+ (const Nothing )
137
+ maybeCommon
138
+ applyOptsFlagsPP ::
139
+ (a , ProjectPackage )
140
+ -> RIO env (Either UnusedFlags (a , ProjectPackage ))
141
+ applyOptsFlagsPP (name, p@ ProjectPackage { projectCommon = common }) = do
142
+ let isTarget = M. member common. name targets. targets
143
+ eCommon <- applyOptsFlags isTarget True common
144
+ pure $ (\ common' -> (name, p { projectCommon = common' })) <$> eCommon
145
+ applyOptsFlagsDep ::
146
+ (a , DepPackage )
147
+ -> RIO env (Either UnusedFlags (a , DepPackage ))
148
+ applyOptsFlagsDep (name, d@ DepPackage { depCommon = common }) = do
149
+ let isTarget = M. member common. name targets. deps
150
+ eCommon <- applyOptsFlags isTarget False common
151
+ pure $ (\ common' -> (name, d { depCommon = common' })) <$> eCommon
152
+ applyOptsFlags ::
153
+ Bool
154
+ -> Bool
155
+ -> CommonPackage
156
+ -> RIO env (Either UnusedFlags CommonPackage )
157
+ applyOptsFlags isTarget isProjectPackage common = do
158
+ let name = common. name
159
+ cliFlagsByName = Map. findWithDefault Map. empty (ACFByName name) cliFlags
160
+ cliFlagsAll =
161
+ Map. findWithDefault Map. empty ACFAllProjectPackages cliFlags
162
+ noOptsToApply = Map. null cliFlagsByName && Map. null cliFlagsAll
163
+ (flags, unusedByName, pkgFlags) <- if noOptsToApply
164
+ then
165
+ pure (Map. empty, Set. empty, Set. empty)
166
+ else do
167
+ gpd <-
168
+ -- This action is expensive. We want to avoid it if we can.
169
+ liftIO common. gpd
170
+ let pkgFlags = Set. fromList $ map C. flagName $ C. genPackageFlags gpd
171
+ unusedByName = Map. keysSet $ Map. withoutKeys cliFlagsByName pkgFlags
172
+ cliFlagsAllRelevant =
173
+ Map. filterWithKey (\ k _ -> k `Set.member` pkgFlags) cliFlagsAll
174
+ flags = cliFlagsByName <> cliFlagsAllRelevant
175
+ pure (flags, unusedByName, pkgFlags)
176
+ if Set. null unusedByName
177
+ -- All flags are defined, nothing to do
178
+ then do
179
+ bconfig <- view buildConfigL
180
+ let bopts = bconfig. config. build
181
+ ghcOptions =
182
+ generalGhcOptions bconfig boptsCli isTarget isProjectPackage
183
+ cabalConfigOpts = generalCabalConfigOpts
184
+ bconfig
185
+ boptsCli
186
+ name
187
+ isTarget
188
+ isProjectPackage
189
+ pure $ Right common
190
+ { flags =
191
+ if M. null flags
192
+ then common. flags
193
+ else flags
194
+ , ghcOptions =
195
+ ghcOptions ++ common. ghcOptions
196
+ , cabalConfigOpts =
197
+ cabalConfigOpts ++ common. cabalConfigOpts
198
+ , buildHaddocks =
199
+ if isTarget
200
+ then bopts. buildHaddocks
201
+ else shouldHaddockDeps bopts
202
+ }
203
+ -- Error about the undefined flags
204
+ else
205
+ pure $ Left $ UFFlagsNotDefined FSCommandLine name pkgFlags unusedByName
149
206
150
207
-- | Get a 'SourceMapHash' for a given 'SourceMap'
151
208
--
@@ -207,18 +264,6 @@ depPackageHashableContent dp =
207
264
<> getUtf8Builder (mconcat ghcOptions)
208
265
<> getUtf8Builder (mconcat cabalConfigOpts)
209
266
210
- -- | All flags for a project package.
211
- getLocalFlags ::
212
- BuildOptsCLI
213
- -> PackageName
214
- -> Map FlagName Bool
215
- getLocalFlags boptsCli name = Map. unions
216
- [ Map. findWithDefault Map. empty (ACFByName name) cliFlags
217
- , Map. findWithDefault Map. empty ACFAllProjectPackages cliFlags
218
- ]
219
- where
220
- cliFlags = boptsCli. flags
221
-
222
267
-- | Get the options to pass to @./Setup.hs configure@
223
268
generalCabalConfigOpts ::
224
269
BuildConfig
0 commit comments