@@ -61,6 +61,7 @@ module Hpack.Config (
61
61
, Section (.. )
62
62
, Library (.. )
63
63
, Executable (.. )
64
+ , ForeignLibrary (.. )
64
65
, Conditional (.. )
65
66
, Cond (.. )
66
67
, Flag (.. )
@@ -167,6 +168,7 @@ package name version = Package {
167
168
, packageCustomSetup = Nothing
168
169
, packageLibrary = Nothing
169
170
, packageInternalLibraries = mempty
171
+ , packageForeignLibraries = mempty
170
172
, packageExecutables = mempty
171
173
, packageTests = mempty
172
174
, packageBenchmarks = mempty
@@ -176,6 +178,7 @@ package name version = Package {
176
178
renamePackage :: String -> Package -> Package
177
179
renamePackage name p@ Package {.. } = p {
178
180
packageName = name
181
+ , packageForeignLibraries = fmap (renameDependencies packageName name) packageForeignLibraries
179
182
, packageExecutables = fmap (renameDependencies packageName name) packageExecutables
180
183
, packageTests = fmap (renameDependencies packageName name) packageTests
181
184
, packageBenchmarks = fmap (renameDependencies packageName name) packageBenchmarks
@@ -194,6 +197,7 @@ renameDependencies old new sect@Section{..} = sect {sectionDependencies = (Depen
194
197
packageDependencies :: Package -> [(String , DependencyInfo )]
195
198
packageDependencies Package {.. } = nub . sortBy (comparing (lexicographically . fst )) $
196
199
(concatMap deps packageExecutables)
200
+ ++ (concatMap deps packageForeignLibraries)
197
201
++ (concatMap deps packageTests)
198
202
++ (concatMap deps packageBenchmarks)
199
203
++ maybe [] deps packageLibrary
@@ -237,6 +241,27 @@ instance Semigroup LibrarySection where
237
241
, librarySectionSignatures = librarySectionSignatures a <> librarySectionSignatures b
238
242
}
239
243
244
+ data ForeignLibrarySection = ForeignLibrarySection {
245
+ foreignLibrarySectionType :: Last String
246
+ , foreignLibrarySectionLibVersionInfo :: Last String
247
+ , foreignLibrarySectionOptions :: Maybe (List String )
248
+ , foreignLibrarySectionOtherModules :: Maybe (List Module )
249
+ , foreignLibrarySectionGeneratedOtherModules :: Maybe (List Module )
250
+ } deriving (Eq , Show , Generic , FromValue )
251
+
252
+ instance Monoid ForeignLibrarySection where
253
+ mempty = ForeignLibrarySection mempty mempty Nothing Nothing Nothing
254
+ mappend = (<>)
255
+
256
+ instance Semigroup ForeignLibrarySection where
257
+ a <> b = ForeignLibrarySection {
258
+ foreignLibrarySectionType = foreignLibrarySectionType a <> foreignLibrarySectionType b
259
+ , foreignLibrarySectionLibVersionInfo = foreignLibrarySectionLibVersionInfo a <> foreignLibrarySectionLibVersionInfo b
260
+ , foreignLibrarySectionOptions = foreignLibrarySectionOptions a <> foreignLibrarySectionOptions b
261
+ , foreignLibrarySectionOtherModules = foreignLibrarySectionOtherModules a <> foreignLibrarySectionOtherModules b
262
+ , foreignLibrarySectionGeneratedOtherModules = foreignLibrarySectionGeneratedOtherModules a <> foreignLibrarySectionGeneratedOtherModules b
263
+ }
264
+
240
265
data ExecutableSection = ExecutableSection {
241
266
executableSectionMain :: Alias 'True " main-is" (Last FilePath )
242
267
, executableSectionOtherModules :: Maybe (List Module )
@@ -570,10 +595,12 @@ type SectionConfigWithDefaults asmSources cSources cxxSources jsSources a = Prod
570
595
571
596
type PackageConfigWithDefaults asmSources cSources cxxSources jsSources = PackageConfig_
572
597
(SectionConfigWithDefaults asmSources cSources cxxSources jsSources LibrarySection )
598
+ (SectionConfigWithDefaults asmSources cSources cxxSources jsSources ForeignLibrarySection )
573
599
(SectionConfigWithDefaults asmSources cSources cxxSources jsSources ExecutableSection )
574
600
575
601
type PackageConfig asmSources cSources cxxSources jsSources = PackageConfig_
576
602
(WithCommonOptions asmSources cSources cxxSources jsSources LibrarySection )
603
+ (WithCommonOptions asmSources cSources cxxSources jsSources ForeignLibrarySection )
577
604
(WithCommonOptions asmSources cSources cxxSources jsSources ExecutableSection )
578
605
579
606
data PackageVersion = PackageVersion { unPackageVersion :: String }
@@ -584,7 +611,7 @@ instance FromValue PackageVersion where
584
611
String s -> return (T. unpack s)
585
612
_ -> typeMismatch " Number or String" v
586
613
587
- data PackageConfig_ library executable = PackageConfig {
614
+ data PackageConfig_ library foreignLib executable = PackageConfig {
588
615
packageConfigName :: Maybe String
589
616
, packageConfigVersion :: Maybe PackageVersion
590
617
, packageConfigSynopsis :: Maybe String
@@ -611,6 +638,8 @@ data PackageConfig_ library executable = PackageConfig {
611
638
, packageConfigCustomSetup :: Maybe CustomSetupSection
612
639
, packageConfigLibrary :: Maybe library
613
640
, packageConfigInternalLibraries :: Maybe (Map String library )
641
+ , packageConfigForeignLibraries :: Maybe (Map String foreignLib )
642
+ , packageConfigForeignLibrary :: Maybe foreignLib
614
643
, packageConfigExecutable :: Maybe executable
615
644
, packageConfigExecutables :: Maybe (Map String executable )
616
645
, packageConfigTests :: Maybe (Map String executable )
@@ -639,13 +668,17 @@ traversePackageConfig :: Traversal PackageConfig
639
668
traversePackageConfig t p@ PackageConfig {.. } = do
640
669
library <- traverse (traverseWithCommonOptions t) packageConfigLibrary
641
670
internalLibraries <- traverseNamedConfigs t packageConfigInternalLibraries
671
+ foreignLibrary <- traverse (traverseWithCommonOptions t) packageConfigForeignLibrary
672
+ foreignLibraries <- traverseNamedConfigs t packageConfigForeignLibraries
642
673
executable <- traverse (traverseWithCommonOptions t) packageConfigExecutable
643
674
executables <- traverseNamedConfigs t packageConfigExecutables
644
675
tests <- traverseNamedConfigs t packageConfigTests
645
676
benchmarks <- traverseNamedConfigs t packageConfigBenchmarks
646
677
return p {
647
678
packageConfigLibrary = library
648
679
, packageConfigInternalLibraries = internalLibraries
680
+ , packageConfigForeignLibrary = foreignLibrary
681
+ , packageConfigForeignLibraries = foreignLibraries
649
682
, packageConfigExecutable = executable
650
683
, packageConfigExecutables = executables
651
684
, packageConfigTests = tests
@@ -739,6 +772,7 @@ addPathsModuleToGeneratedModules pkg
739
772
| otherwise = pkg {
740
773
packageLibrary = fmap mapLibrary <$> packageLibrary pkg
741
774
, packageInternalLibraries = fmap mapLibrary <$> packageInternalLibraries pkg
775
+ , packageForeignLibraries = fmap mapForeignLibrary <$> packageForeignLibraries pkg
742
776
, packageExecutables = fmap mapExecutable <$> packageExecutables pkg
743
777
, packageTests = fmap mapExecutable <$> packageTests pkg
744
778
, packageBenchmarks = fmap mapExecutable <$> packageBenchmarks pkg
@@ -755,6 +789,15 @@ addPathsModuleToGeneratedModules pkg
755
789
where
756
790
generatedModules = libraryGeneratedModules lib
757
791
792
+ mapForeignLibrary :: ForeignLibrary -> ForeignLibrary
793
+ mapForeignLibrary foreignLibrary
794
+ | pathsModule `elem` foreignLibraryOtherModules foreignLibrary = foreignLibrary {
795
+ foreignLibraryGeneratedModules = if pathsModule `elem` generatedModules then generatedModules else pathsModule : generatedModules
796
+ }
797
+ | otherwise = foreignLibrary
798
+ where
799
+ generatedModules = foreignLibraryGeneratedModules foreignLibrary
800
+
758
801
mapExecutable :: Executable -> Executable
759
802
mapExecutable executable
760
803
| pathsModule `elem` executableOtherModules executable = executable {
@@ -836,6 +879,7 @@ ensureRequiredCabalVersion inferredLicense pkg@Package{..} = pkg {
836
879
, makeVersion [3 ,14 ] <$ guard (not (null packageExtraFiles))
837
880
, packageLibrary >>= libraryCabalVersion
838
881
, internalLibsCabalVersion packageInternalLibraries
882
+ , foreignLibsCabalVersion packageForeignLibraries
839
883
, executablesCabalVersion packageExecutables
840
884
, executablesCabalVersion packageTests
841
885
, executablesCabalVersion packageBenchmarks
@@ -859,6 +903,15 @@ ensureRequiredCabalVersion inferredLicense pkg@Package{..} = pkg {
859
903
where
860
904
versions = libraryCabalVersion <$> Map. elems internalLibraries
861
905
906
+ foreignLibsCabalVersion :: Map String (Section ForeignLibrary ) -> Maybe CabalVersion
907
+ foreignLibsCabalVersion = foldr max Nothing . map foreignLibCabalVersion . Map. elems
908
+
909
+ foreignLibCabalVersion :: Section ForeignLibrary -> Maybe CabalVersion
910
+ foreignLibCabalVersion sect = maximum [
911
+ makeVersion [2 ,0 ] <$ guard (foreignLibraryHasGeneratedModules sect)
912
+ , sectionCabalVersion (concatMap getForeignLibraryModules) sect
913
+ ]
914
+
862
915
executablesCabalVersion :: Map String (Section Executable ) -> Maybe CabalVersion
863
916
executablesCabalVersion = foldr max Nothing . map executableCabalVersion . Map. elems
864
917
@@ -868,6 +921,9 @@ ensureRequiredCabalVersion inferredLicense pkg@Package{..} = pkg {
868
921
, sectionCabalVersion (concatMap getExecutableModules) sect
869
922
]
870
923
924
+ foreignLibraryHasGeneratedModules :: Section ForeignLibrary -> Bool
925
+ foreignLibraryHasGeneratedModules = any (not . null . foreignLibraryGeneratedModules)
926
+
871
927
executableHasGeneratedModules :: Section Executable -> Bool
872
928
executableHasGeneratedModules = any (not . null . executableGeneratedModules)
873
929
@@ -1034,6 +1090,7 @@ data Package = Package {
1034
1090
, packageCustomSetup :: Maybe CustomSetup
1035
1091
, packageLibrary :: Maybe (Section Library )
1036
1092
, packageInternalLibraries :: Map String (Section Library )
1093
+ , packageForeignLibraries :: Map String (Section ForeignLibrary )
1037
1094
, packageExecutables :: Map String (Section Executable )
1038
1095
, packageTests :: Map String (Section Executable )
1039
1096
, packageBenchmarks :: Map String (Section Executable )
@@ -1054,6 +1111,14 @@ data Library = Library {
1054
1111
, librarySignatures :: [String ]
1055
1112
} deriving (Eq , Show )
1056
1113
1114
+ data ForeignLibrary = ForeignLibrary {
1115
+ foreignLibraryType :: Maybe String
1116
+ , foreignLibraryLibVersionInfo :: Maybe String
1117
+ , foreignLibraryOptions :: Maybe [String ]
1118
+ , foreignLibraryOtherModules :: [Module ]
1119
+ , foreignLibraryGeneratedModules :: [Module ]
1120
+ } deriving (Eq , Show )
1121
+
1057
1122
data Executable = Executable {
1058
1123
executableMain :: Maybe FilePath
1059
1124
, executableOtherModules :: [Module ]
@@ -1177,13 +1242,17 @@ expandSectionDefaults
1177
1242
expandSectionDefaults formatYamlParseError userDataDir dir p@ PackageConfig {.. } = do
1178
1243
library <- traverse (expandDefaults formatYamlParseError userDataDir dir) packageConfigLibrary
1179
1244
internalLibraries <- traverse (traverse (expandDefaults formatYamlParseError userDataDir dir)) packageConfigInternalLibraries
1245
+ foreignLibrary <- traverse (expandDefaults formatYamlParseError userDataDir dir) packageConfigForeignLibrary
1246
+ foreignLibraries <- traverse (traverse (expandDefaults formatYamlParseError userDataDir dir)) packageConfigForeignLibraries
1180
1247
executable <- traverse (expandDefaults formatYamlParseError userDataDir dir) packageConfigExecutable
1181
1248
executables <- traverse (traverse (expandDefaults formatYamlParseError userDataDir dir)) packageConfigExecutables
1182
1249
tests <- traverse (traverse (expandDefaults formatYamlParseError userDataDir dir)) packageConfigTests
1183
1250
benchmarks <- traverse (traverse (expandDefaults formatYamlParseError userDataDir dir)) packageConfigBenchmarks
1184
1251
return p{
1185
1252
packageConfigLibrary = library
1186
1253
, packageConfigInternalLibraries = internalLibraries
1254
+ , packageConfigForeignLibrary = foreignLibrary
1255
+ , packageConfigForeignLibraries = foreignLibraries
1187
1256
, packageConfigExecutable = executable
1188
1257
, packageConfigExecutables = executables
1189
1258
, packageConfigTests = tests
@@ -1241,25 +1310,28 @@ type GlobalOptions = CommonOptions AsmSources CSources CxxSources JsSources Empt
1241
1310
1242
1311
toPackage_ :: (MonadIO m , Warnings m , State m ) => FilePath -> Product GlobalOptions (PackageConfig AsmSources CSources CxxSources JsSources ) -> m Package
1243
1312
toPackage_ dir (Product g PackageConfig {.. }) = do
1313
+ foreignLibraryMap <- toExecutableMap packageName packageConfigForeignLibraries packageConfigForeignLibrary
1244
1314
executableMap <- toExecutableMap packageName packageConfigExecutables packageConfigExecutable
1245
1315
let
1246
1316
globalVerbatim = commonOptionsVerbatim g
1247
1317
globalOptions = g {commonOptionsVerbatim = Nothing }
1248
1318
1249
- executableNames = maybe [] Map. keys executableMap
1319
+ componentNames = maybe [] Map. keys executableMap ++ maybe [] Map. keys foreignLibraryMap
1250
1320
1251
1321
toSect :: (Warnings m , Monoid a ) => WithCommonOptions AsmSources CSources CxxSources JsSources a -> m (Section a )
1252
- toSect = toSection packageName executableNames . first ((mempty <$ globalOptions) <> )
1322
+ toSect = toSection packageName componentNames . first ((mempty <$ globalOptions) <> )
1253
1323
1254
1324
toSections :: (Warnings m , Monoid a ) => Maybe (Map String (WithCommonOptions AsmSources CSources CxxSources JsSources a )) -> m (Map String (Section a ))
1255
1325
toSections = maybe (return mempty ) (traverse toSect)
1256
1326
1257
1327
toLib = toLibrary dir packageName
1328
+ toForeignLibraries = toSections >=> traverse (toForeignLibrary dir packageName)
1258
1329
toExecutables = toSections >=> traverse (toExecutable dir packageName)
1259
1330
1260
1331
mLibrary <- traverse (toSect >=> toLib) packageConfigLibrary
1261
1332
internalLibraries <- toSections packageConfigInternalLibraries >>= traverse toLib
1262
1333
1334
+ foreignLibraries <- toForeignLibraries foreignLibraryMap
1263
1335
executables <- toExecutables executableMap
1264
1336
tests <- toExecutables packageConfigTests
1265
1337
benchmarks <- toExecutables packageConfigBenchmarks
@@ -1269,6 +1341,7 @@ toPackage_ dir (Product g PackageConfig{..}) = do
1269
1341
missingSourceDirs <- liftIO $ nub . sort <$> filterM (fmap not <$> doesDirectoryExist . (dir </> )) (
1270
1342
maybe [] sectionSourceDirs mLibrary
1271
1343
++ concatMap sectionSourceDirs internalLibraries
1344
+ ++ concatMap sectionSourceDirs foreignLibraries
1272
1345
++ concatMap sectionSourceDirs executables
1273
1346
++ concatMap sectionSourceDirs tests
1274
1347
++ concatMap sectionSourceDirs benchmarks
@@ -1328,6 +1401,7 @@ toPackage_ dir (Product g PackageConfig{..}) = do
1328
1401
, packageCustomSetup = mCustomSetup
1329
1402
, packageLibrary = mLibrary
1330
1403
, packageInternalLibraries = internalLibraries
1404
+ , packageForeignLibraries = foreignLibraries
1331
1405
, packageExecutables = executables
1332
1406
, packageTests = tests
1333
1407
, packageBenchmarks = benchmarks
@@ -1437,6 +1511,9 @@ getMentionedLibraryModules (LibrarySection _ _ exposedModules generatedExposedMo
1437
1511
getLibraryModules :: Library -> [Module ]
1438
1512
getLibraryModules Library {.. } = libraryExposedModules ++ libraryOtherModules
1439
1513
1514
+ getForeignLibraryModules :: ForeignLibrary -> [Module ]
1515
+ getForeignLibraryModules ForeignLibrary {.. } = foreignLibraryOtherModules
1516
+
1440
1517
getExecutableModules :: Executable -> [Module ]
1441
1518
getExecutableModules Executable {.. } = executableOtherModules
1442
1519
@@ -1522,6 +1599,27 @@ fromLibrarySectionPlain LibrarySection{..} = Library {
1522
1599
, librarySignatures = fromMaybeList librarySectionSignatures
1523
1600
}
1524
1601
1602
+ getMentionedForeignLibraryModules :: ForeignLibrarySection -> [Module ]
1603
+ getMentionedForeignLibraryModules (ForeignLibrarySection _ _ _ otherModules generatedModules)=
1604
+ fromMaybeList (otherModules <> generatedModules)
1605
+
1606
+ toForeignLibrary :: (MonadIO m , State m ) => FilePath -> String -> Section ForeignLibrarySection -> m (Section ForeignLibrary )
1607
+ toForeignLibrary dir packageName_ =
1608
+ inferModules dir packageName_ getMentionedForeignLibraryModules getForeignLibraryModules fromForeignLibrarySection (fromForeignLibrarySection [] )
1609
+ where
1610
+ fromForeignLibrarySection :: [Module ] -> [Module ] -> ForeignLibrarySection -> ForeignLibrary
1611
+ fromForeignLibrarySection pathsModule inferableModules ForeignLibrarySection {.. } =
1612
+ (ForeignLibrary
1613
+ (getLast foreignLibrarySectionType)
1614
+ (getLast foreignLibrarySectionLibVersionInfo)
1615
+ (fromList <$> foreignLibrarySectionOptions)
1616
+ (otherModules ++ generatedModules)
1617
+ generatedModules
1618
+ )
1619
+ where
1620
+ otherModules = maybe (inferableModules ++ pathsModule) fromList foreignLibrarySectionOtherModules
1621
+ generatedModules = maybe [] fromList foreignLibrarySectionGeneratedOtherModules
1622
+
1525
1623
getMentionedExecutableModules :: ExecutableSection -> [Module ]
1526
1624
getMentionedExecutableModules (ExecutableSection (Alias (Last main)) otherModules generatedModules)=
1527
1625
maybe id (:) (toModule . Path. fromFilePath <$> main) $ fromMaybeList (otherModules <> generatedModules)
0 commit comments