{-# LANGUAGE QuasiQuotes #-}
module Summoner.Template.Cabal
( cabalFile
) where
import NeatInterpolation (text)
import Summoner.GhcVer (GhcVer (..), cabalBaseVersions, showGhcVer)
import Summoner.License (LicenseName (..), cabalLicense)
import Summoner.Settings (CustomPrelude (..), Settings (..))
import Summoner.Text (intercalateMap, packageToModule)
import Summoner.Tree (TreeFs (..))
import qualified Data.Text as T
cabalFile :: Settings -> TreeFs
cabalFile Settings{..} = File (toString settingsRepo ++ ".cabal") cabalFileContent
where
cabalFileContent :: Text
cabalFileContent = T.concat
[ cabalHeader
, memptyIfFalse settingsGitHub sourceRepository
, memptyIfFalse settingsIsLib libraryStanza
, memptyIfFalse settingsIsExe $ executableStanza $ memptyIfFalse settingsIsLib $ ", " <> settingsRepo
, memptyIfFalse settingsTest $ testSuiteStanza $ memptyIfFalse settingsIsLib $ ", " <> settingsRepo
, memptyIfFalse settingsBench $ benchmarkStanza $ memptyIfFalse settingsIsLib $ ", " <> settingsRepo
]
cabalHeader :: Text
cabalHeader = unlines $
[ "cabal-version: 2.0"
, "name: " <> settingsRepo
, "version: 0.0.0"
, "synopsis: " <> settingsDescription
, "description: " <> settingsDescription ] ++
[ "homepage: " <> githubUrl | settingsGitHub ] ++
[ "bug-reports: " <> githubBugReports | settingsGitHub ] ++
( "license: " <> licenseName) :
[ "license-file: LICENSE" | settingsLicenseName /= None] ++
[ "author: " <> settingsFullName
, "maintainer: " <> settingsEmail
, "copyright: " <> settingsYear <> " " <> settingsFullName ] ++
[ "category: " <> settingsCategories | "" /= settingsCategories ] ++
[ "build-type: Simple"
, "extra-doc-files: README.md"
, " , CHANGELOG.md"
, "tested-with: " <> testedGhcs
]
githubUrl, githubBugReports :: Text
githubUrl = "https://github.com/" <> settingsOwner <> "/" <> settingsRepo
githubBugReports = githubUrl <> "/issues"
licenseName, libModuleName :: Text
licenseName = cabalLicense settingsLicenseName
libModuleName = packageToModule settingsRepo
testedGhcs :: Text
testedGhcs = intercalateMap ", " (mappend "GHC == " . showGhcVer) settingsTestedVersions
sourceRepository :: Text
sourceRepository =
[text|
$endLine
source-repository head
type: git
location: ${githubUrl}.git
|]
baseBounds :: Text
baseBounds = cabalBaseVersions settingsTestedVersions
libraryStanza :: Text
libraryStanza =
[text|
$endLine
library
hs-source-dirs: src
exposed-modules: $libModuleName
$preludeMod
build-depends: $settingsBaseType $baseBounds
$commaPreludeLibrary
ghc-options: -Wall
$ghcOptions
default-language: Haskell2010
|] <> defaultExtensions
executableStanza :: Text -> Text
executableStanza commaRepo =
[text|
$endLine
executable $settingsRepo
hs-source-dirs: app
main-is: Main.hs
build-depends: $settingsBaseType $baseBounds
$commaRepo
$commaPreludeLibrary
ghc-options: -Wall
-threaded
-rtsopts
-with-rtsopts=-N
$ghcOptions
default-language: Haskell2010
|] <> defaultExtensions
testSuiteStanza :: Text -> Text
testSuiteStanza commaRepo =
[text|
$endLine
test-suite ${settingsRepo}-test
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: Spec.hs
build-depends: $settingsBaseType $baseBounds
$commaRepo
$commaPreludeLibrary
ghc-options: -Wall
-threaded
-rtsopts
-with-rtsopts=-N
$ghcOptions
default-language: Haskell2010
|] <> defaultExtensions
benchmarkStanza :: Text -> Text
benchmarkStanza commaRepo =
[text|
$endLine
benchmark ${settingsRepo}-benchmark
type: exitcode-stdio-1.0
hs-source-dirs: benchmark
main-is: Main.hs
build-depends: $settingsBaseType $baseBounds
, gauge
$commaRepo
$commaPreludeLibrary
ghc-options: -Wall
-threaded
-rtsopts
-with-rtsopts=-N
$ghcOptions
default-language: Haskell2010
|] <> defaultExtensions
preludeMod, commaPreludeLibrary :: Text
(preludeMod, commaPreludeLibrary) = case settingsPrelude of
Nothing -> ("", "")
Just CustomPrelude{..} -> ("Prelude", ", " <> cpPackage)
defaultExtensions :: Text
defaultExtensions = case settingsExtensions of
[] -> ""
xs -> " default-extensions: "
<> T.intercalate "\n " xs
<> "\n"
ghcOptions :: Text
ghcOptions = case settingsWarnings of
[] -> defaultWarnings
xs -> T.intercalate "\n" xs
defaultWarnings :: Text
defaultWarnings =
[text|
-Wincomplete-uni-patterns
-Wincomplete-record-updates
-Wcompat
-Widentities
$versionWarnings
|]
versionWarnings :: Text
versionWarnings
= memptyIfFalse (settingsTestedVersions `hasLeast` Ghc801)
"-Wredundant-constraints\n"
<> memptyIfFalse (settingsTestedVersions `hasLeast` Ghc822)
"-fhide-source-paths\n"
<> memptyIfFalse (settingsTestedVersions `hasLeast` Ghc843)
[text|
-Wmissing-export-lists
-Wpartial-fields
|]
where
hasLeast :: [GhcVer] -> GhcVer -> Bool
hasLeast list el = all (>= el) list