Skip to content

Commit

Permalink
[#345] Use mixins approach for a custom prelude by default (#415)
Browse files Browse the repository at this point in the history
* [#345] Use `mixins` approach for a custom prelude by default

Resolves #345

* Remove Prelude module generation
  • Loading branch information
chshersh authored Feb 21, 2020
1 parent 25ced7e commit e1c7b55
Show file tree
Hide file tree
Showing 17 changed files with 39 additions and 68 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ The changelog is available [on GitHub][2].
ghc-options: -Wmissing-deriving-strategies
```

(by [@chshersh](https://github.com/chshersh))
* [#345](https://github.com/kowainik/summoner/issues/345):
Apply `mixins` approach for using alternative preludes instead of
the `base-noprelude` trick. Now it looks like this in the `.cabal`
file:

```haskell
mixins: base hiding (Prelude)
, relude (Relude as Prelude)
```
(by [@chshersh](https://github.com/chshersh))
* Use `colourista` for pretty terminal formatting.
(by [@chshersh](https://github.com/chshersh))
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ Features related to the structure and content of the generated projects.
+ Ability to pick stanzas (library, executable, test-suite, benchmark).
+ Usage of [common stanza](https://vrom911.github.io/blog/common-stanzas) to reduce `.cabal` file's boilerplate.
+ Option to include an alternative prelude, if desired. The project would then
use [`base-noprelude` technique](http://hackage.haskell.org/package/Prelude),
and the `Prelude` module would be added to the library target.
use the [`mixins` technique](https://www.reddit.com/r/haskelltil/comments/9qa366/easy_way_to_replace_default_prelude_with_the/).
+ Whole Hackage-upload checklist support (exhaustive `.cabal` file, PVP versioning, GHC options, conventional meta files).
+ Support for multiple GHC versions, with thoughtful reflection on project meta, base versions (e.g. `base >= 4.9 && < 4.12`), etc.
+ Ability to create runnable Haskell scripts.
Expand Down
3 changes: 0 additions & 3 deletions summoner-cli/src/Summoner/Project.hs
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,6 @@ generateProject isOffline projectName Config{..} = do
settingsTest <- decisionToBool cTest (mkDefaultYesNoPrompt "tests")
settingsBench <- decisionToBool cBench (mkDefaultYesNoPrompt "benchmarks")
settingsPrelude <- if settingsIsLib then getPrelude else pure Nothing
let settingsBaseType = case settingsPrelude of
Nothing -> "base"
Just _ -> "base-noprelude"

let settingsExtensions = cExtensions
let settingsGhcOptions = cGhcOptions
Expand Down
1 change: 0 additions & 1 deletion summoner-cli/src/Summoner/Settings.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ data Settings = Settings
, settingsTest :: !Bool -- ^ add tests
, settingsBench :: !Bool -- ^ add benchmarks
, settingsTestedVersions :: ![GhcVer] -- ^ GHC versions
, settingsBaseType :: !Text -- ^ Base library to use
, settingsPrelude :: !(Maybe CustomPrelude) -- ^ custom prelude to be used
, settingsExtensions :: ![Text] -- ^ default extensions
, settingsGhcOptions :: ![Text] -- ^ default GHC options
Expand Down
21 changes: 13 additions & 8 deletions summoner-cli/src/Summoner/Template/Cabal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,8 @@ cabalFile Settings{..} = File (toString settingsRepo ++ ".cabal") cabalFileConte
[text|
$endLine
common common-options
build-depends: $settingsBaseType $baseBounds
$commaPreludeLibrary

build-depends: base $baseBounds
$customPrelude
$ghcOptions

default-language: Haskell2010
Expand Down Expand Up @@ -138,7 +137,6 @@ cabalFile Settings{..} = File (toString settingsRepo ++ ".cabal") cabalFileConte
import: common-options
hs-source-dirs: src
exposed-modules: $libModuleName
$preludeMod
|]

executableStanza :: Text
Expand Down Expand Up @@ -195,10 +193,17 @@ cabalFile Settings{..} = File (toString settingsRepo ++ ".cabal") cabalFileConte
-with-rtsopts=-N
|]

preludeMod, commaPreludeLibrary :: Text
(preludeMod, commaPreludeLibrary) = case settingsPrelude of
Nothing -> ("", "")
Just CustomPrelude{..} -> ("Prelude", ", " <> cpPackage)
customPrelude :: Text
customPrelude = case settingsPrelude of
Nothing -> ""
Just CustomPrelude{..} ->
" , " <> cpPackage <> "\n" <>
[text|
$endLine
mixins: base hiding (Prelude)
, $cpPackage ($cpModule as Prelude)
$endLine
|]

defaultExtensions :: Text
defaultExtensions = case settingsExtensions of
Expand Down
22 changes: 4 additions & 18 deletions summoner-cli/src/Summoner/Template/Haskell.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,17 @@ module Summoner.Template.Haskell

import NeatInterpolation (text)

import Summoner.CustomPrelude (CustomPrelude (..))
import Summoner.Settings (Settings (..))
import Summoner.Text (packageToModule)
import Summoner.Tree (TreeFs (..))


haskellFiles :: Settings -> [TreeFs]
haskellFiles Settings{..} = concat
[ [ Dir "src" $ libFile : preludeFile | settingsIsLib ]
, [ Dir "app" [exeFile] | settingsIsExe ]
, [ Dir "test" [testFile] | settingsTest ]
, [ Dir "benchmark" [benchmarkFile] | settingsBench ]
[ [ Dir "src" [libFile] | settingsIsLib ]
, [ Dir "app" [exeFile] | settingsIsExe ]
, [ Dir "test" [testFile] | settingsTest ]
, [ Dir "benchmark" [benchmarkFile] | settingsBench ]
] ++ maybeToList (File ".stylish-haskell.yaml" <$> settingsStylish)
where
libFile :: TreeFs
Expand Down Expand Up @@ -54,19 +53,6 @@ haskellFiles Settings{..} = concat
licenseName :: Text
licenseName = show settingsLicenseName

preludeFile :: [TreeFs]
preludeFile = maybeToList $
settingsPrelude <&> \CustomPrelude{..} -> File "Prelude.hs"
[text|
-- | Uses [$cpPackage](https://hackage.haskell.org/package/${cpPackage}) as default Prelude.

module Prelude
( module $cpModule
) where

import $cpModule
|]

exeFile :: TreeFs
exeFile = File "Main.hs" $ if settingsIsLib then createExe else createOnlyExe

Expand Down
9 changes: 2 additions & 7 deletions summoner-cli/src/Summoner/Template/Stack.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module Summoner.Template.Stack
) where

import Summoner.Default (defaultGHC)
import Summoner.GhcVer (GhcVer (..), baseVer, latestLts, showGhcVer)
import Summoner.GhcVer (GhcVer (..), latestLts, showGhcVer)
import Summoner.Settings (Settings (..))
import Summoner.Tree (TreeFs (..))

Expand All @@ -22,14 +22,9 @@ stackFiles Settings{..} = map createStackYaml settingsTestedVersions
-- create @stack.yaml@ file with LTS corresponding to specified ghc version
createStackYaml :: GhcVer -> TreeFs
createStackYaml ghcV = File (toString $ "stack" <> ver <> ".yaml")
$ "resolver: " <> latestLts ghcV <> extraDeps
$ "resolver: " <> latestLts ghcV <> "\n"
where
ver :: Text
ver = if ghcV == defaultGHC
then ""
else "-" <> showGhcVer ghcV

extraDeps :: Text
extraDeps = case settingsPrelude of
Nothing -> ""
Just _ -> "\n\nextra-deps: [base-noprelude-" <> baseVer ghcV <> "]"
2 changes: 0 additions & 2 deletions summoner-cli/test/Test/Golden.hs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ fullProject = Settings
, settingsTest = True
, settingsBench = True
, settingsTestedVersions = [Ghc802 .. defaultGHC]
, settingsBaseType = "base-noprelude"
, settingsPrelude = Just $ CustomPrelude "relude" "Relude"
, settingsExtensions = ["ConstraintKinds", "LambdaCase", "OverloadedStrings"]
, settingsGitignore = [".secret"]
Expand Down Expand Up @@ -144,7 +143,6 @@ smallProject = Settings
, settingsTest = False
, settingsBench = False
, settingsTestedVersions = [defaultGHC]
, settingsBaseType = "base"
, settingsPrelude = Nothing
, settingsExtensions = []
, settingsGhcOptions = []
Expand Down
8 changes: 5 additions & 3 deletions summoner-cli/test/golden/fullProject/fullProject.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ source-repository head
location: https://github.com/kowainik/fullProject.git

common common-options
build-depends: base-noprelude >= 4.9.1.0 && < 4.14
build-depends: base >= 4.9.1.0 && < 4.14
, relude


mixins: base hiding (Prelude)
, relude (Relude as Prelude)

ghc-options: -Wcompat
-Widentities

Expand All @@ -40,7 +43,6 @@ library
import: common-options
hs-source-dirs: src
exposed-modules: FullProject
Prelude

executable fullProject
import: common-options
Expand Down
7 changes: 0 additions & 7 deletions summoner-cli/test/golden/fullProject/src/Prelude.hs

This file was deleted.

2 changes: 0 additions & 2 deletions summoner-cli/test/golden/fullProject/stack-8.0.2.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
resolver: lts-9.21

extra-deps: [base-noprelude-4.9.1.0]
2 changes: 0 additions & 2 deletions summoner-cli/test/golden/fullProject/stack-8.2.2.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
resolver: lts-11.22

extra-deps: [base-noprelude-4.10.1.0]
2 changes: 0 additions & 2 deletions summoner-cli/test/golden/fullProject/stack-8.4.4.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
resolver: lts-12.26

extra-deps: [base-noprelude-4.11.1.0]
2 changes: 0 additions & 2 deletions summoner-cli/test/golden/fullProject/stack-8.6.5.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
resolver: lts-14.27

extra-deps: [base-noprelude-4.12.0.0]
2 changes: 0 additions & 2 deletions summoner-cli/test/golden/fullProject/stack.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
resolver: lts-15.0

extra-deps: [base-noprelude-4.13.0.0]
3 changes: 1 addition & 2 deletions summoner-cli/test/golden/smallProject/smallProject.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ tested-with: GHC == 8.8.2

common common-options
build-depends: base ^>= 4.13.0.0



ghc-options: -Wall
-Wcompat
-Widentities
Expand Down
8 changes: 3 additions & 5 deletions summoner-tui/src/Summoner/Tui/Kit.hs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ summonKitToSettings sk = Settings
, settingsTest = sk ^. projectMeta . test
, settingsBench = sk ^. projectMeta . bench
, settingsTestedVersions = sortNub $ defaultGHC : (sk ^. projectMeta . ghcs)
, settingsBaseType = baseT
, settingsPrelude = cP
, settingsExtensions = sk ^. extensions
, settingsGhcOptions = sk ^. ghcOptions
Expand All @@ -198,14 +197,13 @@ summonKitToSettings sk = Settings
isGitHub :: Bool
isGitHub = sk ^. gitHub . enabled

baseT :: Text
cP :: Maybe CustomPrelude
(baseT, cP) =
cP =
let cpPackage = T.strip $ sk ^. projectMeta . preludeName
cpModule = T.strip $ sk ^. projectMeta . preludeModule
in if ("" /= cpPackage) && ("" /= cpModule)
then ("base-noprelude", Just CustomPrelude{..})
else ("base", Nothing)
then Just CustomPrelude{..}
else Nothing

-- | Gets 'Settings' on successful application complition.
finalSettings :: SummonKit -> IO Settings
Expand Down

0 comments on commit e1c7b55

Please sign in to comment.