@@ -30,7 +30,8 @@ import Distribution.Client.HashValue
30
30
import Distribution.Client.NixStyleOptions
31
31
( NixStyleFlags (.. ) )
32
32
import Distribution.Client.ProjectConfig
33
- ( ProjectConfig (.. ), ProjectConfigShared (.. ), withProjectOrGlobalConfig )
33
+ ( ProjectConfig (.. ), ProjectConfigShared (.. )
34
+ , parseProjectConfig , reportParseResult , withProjectOrGlobalConfig )
34
35
import Distribution.Client.ProjectFlags
35
36
( flagIgnoreProject )
36
37
import Distribution.Client.Setup
@@ -46,7 +47,7 @@ import Distribution.Fields
46
47
import Distribution.PackageDescription.FieldGrammar
47
48
( executableFieldGrammar )
48
49
import Distribution.PackageDescription.PrettyPrint
49
- ( showGenericPackageDescription , writeGenericPackageDescription )
50
+ ( showGenericPackageDescription )
50
51
import Distribution.Parsec
51
52
( Position (.. ) )
52
53
import Distribution.Simple.Flag
@@ -56,7 +57,7 @@ import Distribution.Simple.PackageDescription
56
57
import Distribution.Simple.Setup
57
58
( Flag (.. ) )
58
59
import Distribution.Simple.Utils
59
- ( createDirectoryIfMissingVerbose , createTempDirectory , die' , handleDoesNotExist , readUTF8File , warn )
60
+ ( createDirectoryIfMissingVerbose , createTempDirectory , die' , handleDoesNotExist , readUTF8File , warn , writeUTF8File )
60
61
import qualified Distribution.SPDX.License as SPDX
61
62
import Distribution.Solver.Types.SourcePackage as SP
62
63
( SourcePackage (.. ) )
@@ -214,10 +215,13 @@ withContextAndSelectors noTargets kind flags@NixStyleFlags {..} targetStrings gl
214
215
let projectRoot = distProjectRootDirectory $ distDirLayout ctx
215
216
writeFile (projectRoot </> " scriptlocation" ) =<< canonicalizePath script
216
217
217
- executable <- readScriptBlockFromScript verbosity =<< BS. readFile script
218
+ scriptContents <- BS. readFile script
219
+ executable <- readExecutableBlockFromScript verbosity scriptContents
220
+ projectCfg <- readProjectBlockFromScript verbosity (takeFileName script) scriptContents
218
221
219
222
let executable' = executable & L. buildInfo . L. defaultLanguage %~ maybe (Just Haskell2010 ) Just
220
- return (ScriptContext script executable', ctx, defaultTarget)
223
+ ctx' = ctx & lProjectConfig %~ (<> projectCfg)
224
+ return (ScriptContext script executable', ctx', defaultTarget)
221
225
else reportTargetSelectorProblems verbosity err
222
226
223
227
withTemporaryTempDirectory :: (IO FilePath -> IO a ) -> IO a
@@ -236,17 +240,18 @@ withTemporaryTempDirectory act = newEmptyMVar >>= \m -> bracket (getMkTmp m) (rm
236
240
-- | Add the 'SourcePackage' to the context and use it to write a .cabal file.
237
241
updateContextAndWriteProjectFile' :: ProjectBaseContext -> SourcePackage (PackageLocation (Maybe FilePath )) -> IO ProjectBaseContext
238
242
updateContextAndWriteProjectFile' ctx srcPkg = do
239
- let projectRoot = distProjectRootDirectory $ distDirLayout ctx
240
- projectFile = projectRoot </> fakePackageCabalFileName
241
- writeProjectFile = writeGenericPackageDescription (projectRoot </> fakePackageCabalFileName) (srcpkgDescription srcPkg)
242
- projectFileExists <- doesFileExist projectFile
243
+ let projectRoot = distProjectRootDirectory $ distDirLayout ctx
244
+ packageFile = projectRoot </> fakePackageCabalFileName
245
+ contents = showGenericPackageDescription (srcpkgDescription srcPkg)
246
+ writePackageFile = writeUTF8File packageFile contents
243
247
-- TODO This is here to prevent reconfiguration of cached repl packages.
244
248
-- It's worth investigating why it's needed in the first place.
245
- if projectFileExists then do
246
- contents <- force <$> readUTF8File projectFile
247
- when (contents /= showGenericPackageDescription (srcpkgDescription srcPkg))
248
- writeProjectFile
249
- else writeProjectFile
249
+ packageFileExists <- doesFileExist packageFile
250
+ if packageFileExists then do
251
+ cached <- force <$> readUTF8File packageFile
252
+ when (cached /= contents)
253
+ writePackageFile
254
+ else writePackageFile
250
255
return (ctx & lLocalPackages %~ (++ [SpecificSourcePackage srcPkg]))
251
256
252
257
-- | Add add the executable metadata to the context and write a .cabal file.
@@ -283,26 +288,41 @@ parseScriptBlock str =
283
288
readScriptBlock :: Verbosity -> BS. ByteString -> IO Executable
284
289
readScriptBlock verbosity = parseString parseScriptBlock verbosity " script block"
285
290
286
- -- | Extract the first encountered script metadata block started end
287
- -- terminated by the bellow tokens or die.
291
+ -- | Extract the first encountered executable metadata block started and
292
+ -- terminated by the below tokens or die.
288
293
--
289
294
-- * @{- cabal:@
290
295
--
291
296
-- * @-}@
292
297
--
293
298
-- Return the metadata.
294
- readScriptBlockFromScript :: Verbosity -> BS. ByteString -> IO Executable
295
- readScriptBlockFromScript verbosity str = do
296
- str' <- case extractScriptBlock str of
299
+ readExecutableBlockFromScript :: Verbosity -> BS. ByteString -> IO Executable
300
+ readExecutableBlockFromScript verbosity str = do
301
+ str' <- case extractScriptBlock " cabal " str of
297
302
Left e -> die' verbosity $ " Failed extracting script block: " ++ e
298
303
Right x -> return x
299
304
when (BS. all isSpace str') $ warn verbosity " Empty script block"
300
305
readScriptBlock verbosity str'
301
306
307
+ -- | Extract the first encountered project metadata block started and
308
+ -- terminated by the below tokens.
309
+ --
310
+ -- * @{- project:@
311
+ --
312
+ -- * @-}@
313
+ --
314
+ -- Return the metadata.
315
+ readProjectBlockFromScript :: Verbosity -> String -> BS. ByteString -> IO ProjectConfig
316
+ readProjectBlockFromScript verbosity scriptName str = do
317
+ case extractScriptBlock " project" str of
318
+ Left _ -> return mempty
319
+ Right x -> reportParseResult verbosity " script" scriptName
320
+ $ parseProjectConfig scriptName x
321
+
302
322
-- | Extract the first encountered script metadata block started end
303
323
-- terminated by the tokens
304
324
--
305
- -- * @{- cabal :@
325
+ -- * @{- <header> :@
306
326
--
307
327
-- * @-}@
308
328
--
@@ -311,8 +331,8 @@ readScriptBlockFromScript verbosity str = do
311
331
--
312
332
-- In case of missing or unterminated blocks a 'Left'-error is
313
333
-- returned.
314
- extractScriptBlock :: BS. ByteString -> Either String BS. ByteString
315
- extractScriptBlock str = goPre (BS. lines str)
334
+ extractScriptBlock :: BS. ByteString -> BS. ByteString -> Either String BS. ByteString
335
+ extractScriptBlock header str = goPre (BS. lines str)
316
336
where
317
337
isStartMarker = (== startMarker) . stripTrailSpace
318
338
isEndMarker = (== endMarker) . stripTrailSpace
@@ -330,8 +350,8 @@ extractScriptBlock str = goPre (BS.lines str)
330
350
| otherwise = goBody (l: acc) ls
331
351
332
352
startMarker , endMarker :: BS. ByteString
333
- startMarker = fromString " {- cabal :"
334
- endMarker = fromString " -}"
353
+ startMarker = " {- " <> header <> " :"
354
+ endMarker = " -}"
335
355
336
356
-- | The base for making a 'SourcePackage' for a fake project.
337
357
-- It needs a 'Distribution.Types.Library.Library' or 'Executable' depending on the command.
@@ -362,6 +382,10 @@ lLocalPackages :: Lens' ProjectBaseContext [PackageSpecifier UnresolvedSourcePac
362
382
lLocalPackages f s = fmap (\ x -> s { localPackages = x }) (f (localPackages s))
363
383
{-# inline lLocalPackages #-}
364
384
385
+ lProjectConfig :: Lens' ProjectBaseContext ProjectConfig
386
+ lProjectConfig f s = fmap (\ x -> s { projectConfig = x }) (f (projectConfig s))
387
+ {-# inline lProjectConfig #-}
388
+
365
389
-- Character classes
366
390
-- Transcribed from "templates/Lexer.x"
367
391
ccSpace , ccCtrlchar , ccPrintable , ccSymbol' , ccParen , ccNamecore :: Set Char
0 commit comments